github.com/ethersphere/bee/v2@v2.2.0/pkg/settlement/swap/chequebook/cheque.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package chequebook 6 7 import ( 8 "bytes" 9 "fmt" 10 "math/big" 11 12 "github.com/ethereum/go-ethereum/common" 13 "github.com/ethereum/go-ethereum/common/math" 14 "github.com/ethersphere/bee/v2/pkg/crypto" 15 "github.com/ethersphere/bee/v2/pkg/crypto/eip712" 16 ) 17 18 // Cheque represents a cheque for a SimpleSwap chequebook 19 type Cheque struct { 20 Chequebook common.Address 21 Beneficiary common.Address 22 CumulativePayout *big.Int 23 } 24 25 // SignedCheque represents a cheque together with its signature 26 type SignedCheque struct { 27 Cheque 28 Signature []byte 29 } 30 31 // chequebookDomain computes chainId-dependent EIP712 domain 32 func chequebookDomain(chainID int64) eip712.TypedDataDomain { 33 return eip712.TypedDataDomain{ 34 Name: "Chequebook", 35 Version: "1.0", 36 ChainId: math.NewHexOrDecimal256(chainID), 37 } 38 } 39 40 // ChequeTypes are the needed type descriptions for cheque signing 41 var ChequeTypes = eip712.Types{ 42 "EIP712Domain": eip712.EIP712DomainType, 43 "Cheque": []eip712.Type{ 44 { 45 Name: "chequebook", 46 Type: "address", 47 }, 48 { 49 Name: "beneficiary", 50 Type: "address", 51 }, 52 { 53 Name: "cumulativePayout", 54 Type: "uint256", 55 }, 56 }, 57 } 58 59 // ChequeSigner signs cheque 60 type ChequeSigner interface { 61 // Sign signs a cheque 62 Sign(cheque *Cheque) ([]byte, error) 63 } 64 65 type chequeSigner struct { 66 signer crypto.Signer // the underlying signer used 67 chainID int64 // the chainID used for EIP712 68 } 69 70 // NewChequeSigner creates a new cheque signer for the given chainID. 71 func NewChequeSigner(signer crypto.Signer, chainID int64) ChequeSigner { 72 return &chequeSigner{ 73 signer: signer, 74 chainID: chainID, 75 } 76 } 77 78 // eip712DataForCheque converts a cheque into the correct TypedData structure. 79 func eip712DataForCheque(cheque *Cheque, chainID int64) *eip712.TypedData { 80 return &eip712.TypedData{ 81 Domain: chequebookDomain(chainID), 82 Types: ChequeTypes, 83 Message: eip712.TypedDataMessage{ 84 "chequebook": cheque.Chequebook.Hex(), 85 "beneficiary": cheque.Beneficiary.Hex(), 86 "cumulativePayout": cheque.CumulativePayout.String(), 87 }, 88 PrimaryType: "Cheque", 89 } 90 } 91 92 // Sign signs a cheque. 93 func (s *chequeSigner) Sign(cheque *Cheque) ([]byte, error) { 94 return s.signer.SignTypedData(eip712DataForCheque(cheque, s.chainID)) 95 } 96 97 func (cheque *Cheque) String() string { 98 return fmt.Sprintf("Contract: %x Beneficiary: %x CumulativePayout: %v", cheque.Chequebook, cheque.Beneficiary, cheque.CumulativePayout) 99 } 100 101 func (cheque *Cheque) Equal(other *Cheque) bool { 102 if cheque.Beneficiary != other.Beneficiary { 103 return false 104 } 105 if cheque.CumulativePayout.Cmp(other.CumulativePayout) != 0 { 106 return false 107 } 108 return cheque.Chequebook == other.Chequebook 109 } 110 111 func (cheque *SignedCheque) Equal(other *SignedCheque) bool { 112 if !bytes.Equal(cheque.Signature, other.Signature) { 113 return false 114 } 115 return cheque.Cheque.Equal(&other.Cheque) 116 }