github.com/status-im/status-go@v1.1.0/transactions/types.go (about) 1 package transactions 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "math/big" 8 9 ethereum "github.com/ethereum/go-ethereum" 10 "github.com/ethereum/go-ethereum/accounts/abi/bind" 11 "github.com/ethereum/go-ethereum/common" 12 "github.com/ethereum/go-ethereum/common/hexutil" 13 14 "github.com/status-im/status-go/eth-node/types" 15 wallet_common "github.com/status-im/status-go/services/wallet/common" 16 ) 17 18 var ( 19 // ErrInvalidSendTxArgs is returned when the structure of SendTxArgs is ambigious. 20 ErrInvalidSendTxArgs = errors.New("transaction arguments are invalid") 21 // ErrUnexpectedArgs is returned when args are of unexpected length. 22 ErrUnexpectedArgs = errors.New("unexpected args") 23 //ErrInvalidTxSender is returned when selected account is different than From field. 24 ErrInvalidTxSender = errors.New("transaction can only be send by its creator") 25 //ErrAccountDoesntExist is sent when provided sub-account is not stored in database. 26 ErrAccountDoesntExist = errors.New("account doesn't exist") 27 ) 28 29 // PendingNonceProvider provides information about nonces. 30 type PendingNonceProvider interface { 31 PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) 32 } 33 34 // GasCalculator provides methods for estimating and pricing gas. 35 type GasCalculator interface { 36 ethereum.GasEstimator 37 ethereum.GasPricer 38 } 39 40 // SendTxArgs represents the arguments to submit a new transaction into the transaction pool. 41 // This struct is based on go-ethereum's type in internal/ethapi/api.go, but we have freedom 42 // over the exact layout of this struct. 43 type SendTxArgs struct { 44 From types.Address `json:"from"` 45 To *types.Address `json:"to"` 46 Gas *hexutil.Uint64 `json:"gas"` 47 GasPrice *hexutil.Big `json:"gasPrice"` 48 Value *hexutil.Big `json:"value"` 49 Nonce *hexutil.Uint64 `json:"nonce"` 50 MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` 51 MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` 52 // We keep both "input" and "data" for backward compatibility. 53 // "input" is a preferred field. 54 // see `vendor/github.com/ethereum/go-ethereum/internal/ethapi/api.go:1107` 55 Input types.HexBytes `json:"input"` 56 Data types.HexBytes `json:"data"` 57 58 // additional data 59 MultiTransactionID wallet_common.MultiTransactionIDType 60 Symbol string 61 } 62 63 // Valid checks whether this structure is filled in correctly. 64 func (args SendTxArgs) Valid() bool { 65 // if at least one of the fields is empty, it is a valid struct 66 if isNilOrEmpty(args.Input) || isNilOrEmpty(args.Data) { 67 return true 68 } 69 70 // we only allow both fields to present if they have the same data 71 return bytes.Equal(args.Input, args.Data) 72 } 73 74 // IsDynamicFeeTx checks whether dynamic fee parameters are set for the tx 75 func (args SendTxArgs) IsDynamicFeeTx() bool { 76 return args.MaxFeePerGas != nil && args.MaxPriorityFeePerGas != nil 77 } 78 79 // GetInput returns either Input or Data field's value dependent on what is filled. 80 func (args SendTxArgs) GetInput() types.HexBytes { 81 if !isNilOrEmpty(args.Input) { 82 return args.Input 83 } 84 85 return args.Data 86 } 87 88 func (args SendTxArgs) ToTransactOpts(signerFn bind.SignerFn) *bind.TransactOpts { 89 var gasFeeCap *big.Int 90 if args.MaxFeePerGas != nil { 91 gasFeeCap = (*big.Int)(args.MaxFeePerGas) 92 } 93 94 var gasTipCap *big.Int 95 if args.MaxPriorityFeePerGas != nil { 96 gasTipCap = (*big.Int)(args.MaxPriorityFeePerGas) 97 } 98 99 var nonce *big.Int 100 if args.Nonce != nil { 101 nonce = new(big.Int).SetUint64((uint64)(*args.Nonce)) 102 } 103 104 var gasPrice *big.Int 105 if args.GasPrice != nil { 106 gasPrice = (*big.Int)(args.GasPrice) 107 } 108 109 var gasLimit uint64 110 if args.Gas != nil { 111 gasLimit = uint64(*args.Gas) 112 } 113 114 var noSign = false 115 if signerFn == nil { 116 noSign = true 117 } 118 119 return &bind.TransactOpts{ 120 From: common.Address(args.From), 121 Signer: signerFn, 122 GasPrice: gasPrice, 123 GasLimit: gasLimit, 124 GasFeeCap: gasFeeCap, 125 GasTipCap: gasTipCap, 126 Nonce: nonce, 127 NoSign: noSign, 128 } 129 } 130 131 func isNilOrEmpty(bytes types.HexBytes) bool { 132 return len(bytes) == 0 133 }