diff --git a/cmd/bee/cmd/cmd.go b/cmd/bee/cmd/cmd.go index 81cdbad225c..525e1eeaee9 100644 --- a/cmd/bee/cmd/cmd.go +++ b/cmd/bee/cmd/cmd.go @@ -22,71 +22,71 @@ import ( ) const ( - optionNameDataDir = "data-dir" - optionNameCacheCapacity = "cache-capacity" - optionNameDBOpenFilesLimit = "db-open-files-limit" - optionNameDBBlockCacheCapacity = "db-block-cache-capacity" - optionNameDBWriteBufferSize = "db-write-buffer-size" - optionNameDBDisableSeeksCompaction = "db-disable-seeks-compaction" - optionNamePassword = "password" - optionNamePasswordFile = "password-file" - optionNameAPIAddr = "api-addr" - optionNameP2PAddr = "p2p-addr" - optionNameNATAddr = "nat-addr" - optionNameP2PWSEnable = "p2p-ws-enable" - optionNameDebugAPIEnable = "debug-api-enable" - optionNameDebugAPIAddr = "debug-api-addr" - optionNameBootnodes = "bootnode" - optionNameNetworkID = "network-id" - optionWelcomeMessage = "welcome-message" - optionCORSAllowedOrigins = "cors-allowed-origins" - optionNameTracingEnabled = "tracing-enable" - optionNameTracingEndpoint = "tracing-endpoint" - optionNameTracingHost = "tracing-host" - optionNameTracingPort = "tracing-port" - optionNameTracingServiceName = "tracing-service-name" - optionNameVerbosity = "verbosity" - optionNamePaymentThreshold = "payment-threshold" - optionNamePaymentTolerance = "payment-tolerance-percent" - optionNamePaymentEarly = "payment-early-percent" - optionNameResolverEndpoints = "resolver-options" - optionNameBootnodeMode = "bootnode-mode" - optionNameClefSignerEnable = "clef-signer-enable" - optionNameClefSignerEndpoint = "clef-signer-endpoint" - optionNameClefSignerEthereumAddress = "clef-signer-ethereum-address" - optionNameSwapEndpoint = "swap-endpoint" // deprecated: use rpc endpoint instead - optionNameBlockchainRpcEndpoint = "blockchain-rpc-endpoint" - optionNameSwapFactoryAddress = "swap-factory-address" - optionNameSwapInitialDeposit = "swap-initial-deposit" - optionNameSwapEnable = "swap-enable" - optionNameChequebookEnable = "chequebook-enable" - optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price" - optionNameFullNode = "full-node" - optionNamePostageContractAddress = "postage-stamp-address" - optionNamePostageContractStartBlock = "postage-stamp-start-block" - optionNamePriceOracleAddress = "price-oracle-address" - optionNameRedistributionAddress = "redistribution-address" - optionNameStakingAddress = "staking-address" - optionNameBlockTime = "block-time" - optionWarmUpTime = "warmup-time" - optionNameMainNet = "mainnet" - optionNameRetrievalCaching = "cache-retrieval" - optionNameDevReserveCapacity = "dev-reserve-capacity" - optionNameResync = "resync" - optionNamePProfBlock = "pprof-profile" - optionNamePProfMutex = "pprof-mutex" - optionNameStaticNodes = "static-nodes" - optionNameAllowPrivateCIDRs = "allow-private-cidrs" - optionNameSleepAfter = "sleep-after" - optionNameRestrictedAPI = "restricted" - optionNameTokenEncryptionKey = "token-encryption-key" - optionNameAdminPasswordHash = "admin-password" - optionNameUsePostageSnapshot = "use-postage-snapshot" - optionNameStorageIncentivesEnable = "storage-incentives-enable" - optionNameStateStoreCacheCapacity = "statestore-cache-capacity" - optionNameTargetNeighborhood = "target-neighborhood" - optionNameNeighborhoodSuggester = "neighborhood-suggester" - optionNameWithdrawalAddress = "withdrawal-address" + optionNameDataDir = "data-dir" + optionNameCacheCapacity = "cache-capacity" + optionNameDBOpenFilesLimit = "db-open-files-limit" + optionNameDBBlockCacheCapacity = "db-block-cache-capacity" + optionNameDBWriteBufferSize = "db-write-buffer-size" + optionNameDBDisableSeeksCompaction = "db-disable-seeks-compaction" + optionNamePassword = "password" + optionNamePasswordFile = "password-file" + optionNameAPIAddr = "api-addr" + optionNameP2PAddr = "p2p-addr" + optionNameNATAddr = "nat-addr" + optionNameP2PWSEnable = "p2p-ws-enable" + optionNameDebugAPIEnable = "debug-api-enable" + optionNameDebugAPIAddr = "debug-api-addr" + optionNameBootnodes = "bootnode" + optionNameNetworkID = "network-id" + optionWelcomeMessage = "welcome-message" + optionCORSAllowedOrigins = "cors-allowed-origins" + optionNameTracingEnabled = "tracing-enable" + optionNameTracingEndpoint = "tracing-endpoint" + optionNameTracingHost = "tracing-host" + optionNameTracingPort = "tracing-port" + optionNameTracingServiceName = "tracing-service-name" + optionNameVerbosity = "verbosity" + optionNamePaymentThreshold = "payment-threshold" + optionNamePaymentTolerance = "payment-tolerance-percent" + optionNamePaymentEarly = "payment-early-percent" + optionNameResolverEndpoints = "resolver-options" + optionNameBootnodeMode = "bootnode-mode" + optionNameClefSignerEnable = "clef-signer-enable" + optionNameClefSignerEndpoint = "clef-signer-endpoint" + optionNameClefSignerEthereumAddress = "clef-signer-ethereum-address" + optionNameSwapEndpoint = "swap-endpoint" // deprecated: use rpc endpoint instead + optionNameBlockchainRpcEndpoint = "blockchain-rpc-endpoint" + optionNameSwapFactoryAddress = "swap-factory-address" + optionNameSwapInitialDeposit = "swap-initial-deposit" + optionNameSwapEnable = "swap-enable" + optionNameChequebookEnable = "chequebook-enable" + optionNameSwapDeploymentGasPrice = "swap-deployment-gas-price" + optionNameFullNode = "full-node" + optionNamePostageContractAddress = "postage-stamp-address" + optionNamePostageContractStartBlock = "postage-stamp-start-block" + optionNamePriceOracleAddress = "price-oracle-address" + optionNameRedistributionAddress = "redistribution-address" + optionNameStakingAddress = "staking-address" + optionNameBlockTime = "block-time" + optionWarmUpTime = "warmup-time" + optionNameMainNet = "mainnet" + optionNameRetrievalCaching = "cache-retrieval" + optionNameDevReserveCapacity = "dev-reserve-capacity" + optionNameResync = "resync" + optionNamePProfBlock = "pprof-profile" + optionNamePProfMutex = "pprof-mutex" + optionNameStaticNodes = "static-nodes" + optionNameAllowPrivateCIDRs = "allow-private-cidrs" + optionNameSleepAfter = "sleep-after" + optionNameRestrictedAPI = "restricted" + optionNameTokenEncryptionKey = "token-encryption-key" + optionNameAdminPasswordHash = "admin-password" + optionNameUsePostageSnapshot = "use-postage-snapshot" + optionNameStorageIncentivesEnable = "storage-incentives-enable" + optionNameStateStoreCacheCapacity = "statestore-cache-capacity" + optionNameTargetNeighborhood = "target-neighborhood" + optionNameNeighborhoodSuggester = "neighborhood-suggester" + optionNameWhitelistedWithdrawalAddress = "withdrawal-address" ) // nolint:gochecknoinits @@ -305,7 +305,7 @@ func (c *command) setAllFlags(cmd *cobra.Command) { cmd.Flags().Uint64(optionNameStateStoreCacheCapacity, 100_000, "lru memory caching capacity in number of statestore entries") cmd.Flags().String(optionNameTargetNeighborhood, "", "neighborhood to target in binary format (ex: 111111001) for mining the initial overlay") cmd.Flags().String(optionNameNeighborhoodSuggester, "https://api.swarmscan.io/v1/network/neighborhoods/suggestion", "suggester for target neighborhood") - cmd.Flags().String(optionNameWithdrawalAddress, "", "Withdrawal target address") + cmd.Flags().String(optionNameWhitelistedWithdrawalAddress, "", "Withdrawal target address") } func newLogger(cmd *cobra.Command, verbosity string) (log.Logger, error) { diff --git a/cmd/bee/cmd/deploy.go b/cmd/bee/cmd/deploy.go index 2d6c9274116..7b3e8e57734 100644 --- a/cmd/bee/cmd/deploy.go +++ b/cmd/bee/cmd/deploy.go @@ -8,7 +8,6 @@ import ( "fmt" "strings" - "github.com/ethereum/go-ethereum/common" "github.com/ethersphere/bee/pkg/node" "github.com/ethersphere/bee/pkg/settlement/swap/erc20" "github.com/spf13/cobra" @@ -92,7 +91,6 @@ func (c *command) initDeployCmd() error { chainID, swapBackend, overlayEthAddress, - common.Address{}, // not required for deploy transactionService, chequebookFactory, swapInitialDeposit, diff --git a/cmd/bee/cmd/start.go b/cmd/bee/cmd/start.go index 85154e25e7d..1f343f20d39 100644 --- a/cmd/bee/cmd/start.go +++ b/cmd/bee/cmd/start.go @@ -340,7 +340,7 @@ func buildBeeNode(ctx context.Context, c *command, cmd *cobra.Command, logger lo StatestoreCacheCapacity: c.config.GetUint64(optionNameStateStoreCacheCapacity), TargetNeighborhood: c.config.GetString(optionNameTargetNeighborhood), NeighborhoodSuggester: c.config.GetString(optionNameNeighborhoodSuggester), - WithdrawalAddress: c.config.GetString(optionNameWithdrawalAddress), + WhitelistedWithdrawalAddress: c.config.GetStringSlice(optionNameWhitelistedWithdrawalAddress), }) return b, err diff --git a/pkg/api/api.go b/pkg/api/api.go index 0d9cdaab415..25ef0802692 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -197,6 +197,8 @@ type Service struct { erc20Service erc20.Service chainID int64 + whitelistedWithdrawalAddress []common.Address + preMapHooks map[string]func(v string) (string, error) validate *validator.Validate @@ -254,6 +256,7 @@ type ExtraOptions struct { func New( publicKey, pssPublicKey ecdsa.PublicKey, ethereumAddress common.Address, + whitelistedWithdrawalAddress []string, logger log.Logger, transaction transaction.Service, batchStore postage.Storer, @@ -303,6 +306,10 @@ func New( }) s.stamperStore = stamperStore + for _, v := range whitelistedWithdrawalAddress { + s.whitelistedWithdrawalAddress = append(s.whitelistedWithdrawalAddress, common.HexToAddress(v)) + } + return s } diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index cfa6794257d..5bc373da0ba 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -210,7 +210,7 @@ func newTestServer(t *testing.T, o testServerOptions) (*http.Client, *websocket. o.BeeMode = api.FullMode } - s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, o.Logger, transaction, o.BatchStore, o.BeeMode, true, true, backend, o.CORSAllowedOrigins, inmemstore.New()) + s := api.New(o.PublicKey, o.PSSPublicKey, o.EthereumAddress, nil, o.Logger, transaction, o.BatchStore, o.BeeMode, true, true, backend, o.CORSAllowedOrigins, inmemstore.New()) testutil.CleanupCloser(t, s) s.SetP2P(o.P2P) @@ -395,7 +395,7 @@ func TestParseName(t *testing.T) { pk, _ := crypto.GenerateSecp256k1Key() signer := crypto.NewDefaultSigner(pk) - s := api.New(pk.PublicKey, pk.PublicKey, common.Address{}, log, nil, nil, 1, false, false, nil, []string{"*"}, inmemstore.New()) + s := api.New(pk.PublicKey, pk.PublicKey, common.Address{}, nil, log, nil, nil, 1, false, false, nil, []string{"*"}, inmemstore.New()) s.Configure(signer, nil, nil, api.Options{}, api.ExtraOptions{Resolver: tC.res}, 1, nil) s.MountAPI() diff --git a/pkg/api/wallet.go b/pkg/api/wallet.go index 93f184c3eaa..c5e31a68734 100644 --- a/pkg/api/wallet.go +++ b/pkg/api/wallet.go @@ -9,6 +9,8 @@ import ( "math/big" "net/http" + "slices" + "github.com/ethereum/go-ethereum/common" "github.com/ethersphere/bee/pkg/bigint" "github.com/ethersphere/bee/pkg/jsonhttp" @@ -81,7 +83,12 @@ func (s *Service) walletWithdrawHandler(w http.ResponseWriter, r *http.Request) ctx := r.Context() var bzz bool // check if coin is xdai or bzz - // check whitelisted + + if !slices.Contains(s.whitelistedWithdrawalAddress, *path.Address) { + logger.Error(nil, "provided address not whitelisted") + jsonhttp.InternalServerError(w, "provided address not whitelisted") + return + } if bzz { currentBalance, err := s.erc20Service.BalanceOf(ctx, s.ethereumAddress) @@ -124,7 +131,7 @@ func (s *Service) walletWithdrawHandler(w http.ResponseWriter, r *http.Request) txHash, err := withdraw(ctx, s.chainBackend, *path.Address, queries.Amount) if err != nil { logger.Error(err, "withdraw") - jsonhttp.InternalServerError(w, "pending nonce") + jsonhttp.InternalServerError(w, "withdraw") return } diff --git a/pkg/node/chain.go b/pkg/node/chain.go index 08b04b3b86c..c4cab943207 100644 --- a/pkg/node/chain.go +++ b/pkg/node/chain.go @@ -131,7 +131,6 @@ func InitChequebookService( chainID int64, backend transaction.Backend, overlayEthAddress common.Address, - withdrawalAddress common.Address, transactionService transaction.Service, chequebookFactory chequebook.Factory, initialDeposit string, @@ -163,7 +162,6 @@ func InitChequebookService( backend, chainID, overlayEthAddress, - withdrawalAddress, chequeSigner, erc20Service, ) diff --git a/pkg/node/devnode.go b/pkg/node/devnode.go index 76b055b531f..cff06b2d711 100644 --- a/pkg/node/devnode.go +++ b/pkg/node/devnode.go @@ -202,7 +202,7 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { return nil, fmt.Errorf("debug api listener: %w", err) } - debugApiService = api.New(mockKey.PublicKey, mockKey.PublicKey, overlayEthAddress, logger, mockTransaction, batchStore, api.DevMode, true, true, chainBackend, o.CORSAllowedOrigins, inmemstore.New()) + debugApiService = api.New(mockKey.PublicKey, mockKey.PublicKey, overlayEthAddress, nil, logger, mockTransaction, batchStore, api.DevMode, true, true, chainBackend, o.CORSAllowedOrigins, inmemstore.New()) debugAPIServer := &http.Server{ IdleTimeout: 30 * time.Second, ReadHeaderTimeout: 3 * time.Second, @@ -398,7 +398,7 @@ func NewDevBee(logger log.Logger, o *DevOptions) (b *DevBee, err error) { }), ) - apiService := api.New(mockKey.PublicKey, mockKey.PublicKey, overlayEthAddress, logger, mockTransaction, batchStore, api.DevMode, true, true, chainBackend, o.CORSAllowedOrigins, inmemstore.New()) + apiService := api.New(mockKey.PublicKey, mockKey.PublicKey, overlayEthAddress, nil, logger, mockTransaction, batchStore, api.DevMode, true, true, chainBackend, o.CORSAllowedOrigins, inmemstore.New()) apiService.Configure(signer, authenticator, tracer, api.Options{ CORSAllowedOrigins: o.CORSAllowedOrigins, diff --git a/pkg/node/node.go b/pkg/node/node.go index 841800d8aea..bc6223d477c 100644 --- a/pkg/node/node.go +++ b/pkg/node/node.go @@ -172,7 +172,7 @@ type Options struct { StatestoreCacheCapacity uint64 TargetNeighborhood string NeighborhoodSuggester string - WithdrawalAddress string + WhitelistedWithdrawalAddress []string } const ( @@ -316,7 +316,6 @@ func NewBee( var ( chainBackend transaction.Backend overlayEthAddress common.Address - withdrawalAddress common.Address chainID int64 transactionService transaction.Service transactionMonitor transaction.Monitor @@ -423,6 +422,7 @@ func NewBee( *publicKey, pssPrivateKey.PublicKey, overlayEthAddress, + o.WhitelistedWithdrawalAddress, logger, transactionService, batchStore, @@ -462,6 +462,7 @@ func NewBee( *publicKey, pssPrivateKey.PublicKey, overlayEthAddress, + o.WhitelistedWithdrawalAddress, logger, transactionService, batchStore, @@ -527,8 +528,6 @@ func NewBee( erc20Service = erc20.New(transactionService, erc20Address) - withdrawalAddress = common.HexToAddress(o.WithdrawalAddress) - if o.ChequebookEnable && chainEnabled { chequebookService, err = InitChequebookService( ctx, @@ -538,7 +537,6 @@ func NewBee( chainID, chainBackend, overlayEthAddress, - withdrawalAddress, transactionService, chequebookFactory, o.SwapInitialDeposit, @@ -1099,7 +1097,7 @@ func NewBee( if o.APIAddr != "" { if apiService == nil { - apiService = api.New(*publicKey, pssPrivateKey.PublicKey, overlayEthAddress, logger, transactionService, batchStore, beeNodeMode, o.ChequebookEnable, o.SwapEnable, chainBackend, o.CORSAllowedOrigins, stamperStore) + apiService = api.New(*publicKey, pssPrivateKey.PublicKey, overlayEthAddress, o.WhitelistedWithdrawalAddress, logger, transactionService, batchStore, beeNodeMode, o.ChequebookEnable, o.SwapEnable, chainBackend, o.CORSAllowedOrigins, stamperStore) apiService.SetProbe(probe) apiService.SetRedistributionAgent(agent) } diff --git a/pkg/settlement/swap/chequebook/chequebook.go b/pkg/settlement/swap/chequebook/chequebook.go index 54b49110a95..85164228ddd 100644 --- a/pkg/settlement/swap/chequebook/chequebook.go +++ b/pkg/settlement/swap/chequebook/chequebook.go @@ -69,8 +69,7 @@ type service struct { lock sync.Mutex transactionService transaction.Service - address common.Address - withdrawalAddress common.Address + address common.Address contract *chequebookContract ownerAddress common.Address @@ -83,13 +82,12 @@ type service struct { } // New creates a new chequebook service for the provided chequebook contract. -func New(transactionService transaction.Service, address, ownerAddress, withdrawalAddress common.Address, store storage.StateStorer, chequeSigner ChequeSigner, erc20Service erc20.Service) (Service, error) { +func New(transactionService transaction.Service, address, ownerAddress common.Address, store storage.StateStorer, chequeSigner ChequeSigner, erc20Service erc20.Service) (Service, error) { return &service{ transactionService: transactionService, address: address, contract: newChequebookContract(address, transactionService), ownerAddress: ownerAddress, - withdrawalAddress: withdrawalAddress, erc20Service: erc20Service, store: store, chequeSigner: chequeSigner, @@ -329,15 +327,8 @@ func (s *service) Withdraw(ctx context.Context, amount *big.Int) (hash common.Ha return common.Hash{}, err } - var zeroAddress common.Address - - address := s.address - if s.withdrawalAddress != zeroAddress { - address = s.withdrawalAddress - } - request := &transaction.TxRequest{ - To: &address, + To: &s.address, Data: callData, GasPrice: sctx.GetGasPrice(ctx), GasLimit: 95000, diff --git a/pkg/settlement/swap/chequebook/chequebook_test.go b/pkg/settlement/swap/chequebook/chequebook_test.go index b00543c2d00..a50f401faf9 100644 --- a/pkg/settlement/swap/chequebook/chequebook_test.go +++ b/pkg/settlement/swap/chequebook/chequebook_test.go @@ -29,7 +29,6 @@ func TestChequebookAddress(t *testing.T) { transactionmock.New(), address, ownerAdress, - common.Address{}, nil, &chequeSignerMock{}, erc20mock.New(), @@ -55,7 +54,6 @@ func TestChequebookBalance(t *testing.T) { ), address, ownerAdress, - common.Address{}, nil, &chequeSignerMock{}, erc20mock.New(), @@ -86,7 +84,6 @@ func TestChequebookDeposit(t *testing.T) { transactionmock.New(), address, ownerAdress, - common.Address{}, nil, &chequeSignerMock{}, erc20mock.New( @@ -140,7 +137,6 @@ func TestChequebookWaitForDeposit(t *testing.T) { ), address, ownerAdress, - common.Address{}, nil, &chequeSignerMock{}, erc20mock.New(), @@ -174,7 +170,6 @@ func TestChequebookWaitForDepositReverted(t *testing.T) { ), address, ownerAdress, - common.Address{}, nil, &chequeSignerMock{}, erc20mock.New(), @@ -218,7 +213,6 @@ func TestChequebookIssue(t *testing.T) { ), address, ownerAdress, - common.Address{}, store, chequeSigner, erc20mock.New(), @@ -361,7 +355,6 @@ func TestChequebookIssueErrorSend(t *testing.T) { transactionmock.New(), address, ownerAdress, - common.Address{}, store, chequeSigner, erc20mock.New(), @@ -406,7 +399,6 @@ func TestChequebookIssueOutOfFunds(t *testing.T) { ), address, ownerAdress, - common.Address{}, store, &chequeSignerMock{}, erc20mock.New(), @@ -450,43 +442,6 @@ func TestChequebookWithdraw(t *testing.T) { ), address, ownerAdress, - common.Address{}, - store, - &chequeSignerMock{}, - erc20mock.New(), - ) - if err != nil { - t.Fatal(err) - } - - returnedTxHash, err := chequebookService.Withdraw(context.Background(), withdrawAmount) - if err != nil { - t.Fatal(err) - } - - if txHash != returnedTxHash { - t.Fatalf("returned wrong transaction hash. wanted %v, got %v", txHash, returnedTxHash) - } - }) - t.Run("target withdrawal address provided", func(t *testing.T) { - address := common.HexToAddress("0xabcd") - withdrawalAddress := common.HexToAddress("0xabef") - ownerAdress := common.HexToAddress("0xfff") - balance := big.NewInt(30) - withdrawAmount := big.NewInt(20) - txHash := common.HexToHash("0xdddd") - store := storemock.NewStateStore() - chequebookService, err := chequebook.New( - transactionmock.New( - transactionmock.WithABICallSequence( - transactionmock.ABICall(&chequebookABI, address, balance.FillBytes(make([]byte, 32)), "balance"), - transactionmock.ABICall(&chequebookABI, address, big.NewInt(0).FillBytes(make([]byte, 32)), "totalPaidOut"), - ), - transactionmock.WithABISend(&chequebookABI, txHash, withdrawalAddress, big.NewInt(0), "withdraw", withdrawAmount), - ), - address, - ownerAdress, - withdrawalAddress, store, &chequeSignerMock{}, erc20mock.New(), @@ -524,7 +479,6 @@ func TestChequebookWithdrawInsufficientFunds(t *testing.T) { ), address, ownerAdress, - common.Address{}, store, &chequeSignerMock{}, erc20mock.New(), diff --git a/pkg/settlement/swap/chequebook/init.go b/pkg/settlement/swap/chequebook/init.go index 1061eb356d5..19bfc3c56b0 100644 --- a/pkg/settlement/swap/chequebook/init.go +++ b/pkg/settlement/swap/chequebook/init.go @@ -128,7 +128,6 @@ func Init( swapBackend transaction.Backend, chainId int64, overlayEthAddress common.Address, - withdrawalAddress common.Address, chequeSigner ChequeSigner, erc20Service erc20.Service, ) (chequebookService Service, err error) { @@ -188,7 +187,7 @@ func Init( return nil, err } - chequebookService, err = New(transactionService, chequebookAddress, overlayEthAddress, withdrawalAddress, stateStore, chequeSigner, erc20Service) + chequebookService, err = New(transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service) if err != nil { return nil, err } @@ -209,7 +208,7 @@ func Init( logger.Info("successfully deposited to chequebook") } } else { - chequebookService, err = New(transactionService, chequebookAddress, overlayEthAddress, withdrawalAddress, stateStore, chequeSigner, erc20Service) + chequebookService, err = New(transactionService, chequebookAddress, overlayEthAddress, stateStore, chequeSigner, erc20Service) if err != nil { return nil, err }