From b4f819d85ce37c01e186e518dfe23c3176831039 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Tue, 5 Nov 2024 12:05:23 +0100 Subject: [PATCH] chore(wallet)_: ens resolver identified under ens api New EnsResolver type identified and will be responsible for network calls, while ens api will use it (until mobile app switches to a new sending flow) and continue managing other (db) interactions. --- node/status_node_services.go | 2 +- services/ens/api.go | 401 ++++-------------- services/ens/ensresolver/resolver.go | 369 ++++++++++++++++ services/ens/strings.go | 54 --- services/wallet/common/const.go | 1 + services/wallet/common/helpers.go | 50 +++ .../wallet/requests/router_input_params.go | 3 +- .../pathprocessor/processor_ens_public_key.go | 16 +- .../pathprocessor/processor_ens_register.go | 18 +- .../pathprocessor/processor_ens_release.go | 14 +- services/wallet/router/router.go | 5 +- services/wallet/router/router_test.go | 2 +- services/wallet/service.go | 22 +- 13 files changed, 532 insertions(+), 425 deletions(-) create mode 100644 services/ens/ensresolver/resolver.go delete mode 100644 services/ens/strings.go diff --git a/node/status_node_services.go b/node/status_node_services.go index ee76a8354..cbd527ad0 100644 --- a/node/status_node_services.go +++ b/node/status_node_services.go @@ -593,7 +593,7 @@ func (b *StatusNode) walletService(accountsDB *accounts.Database, appDB *sql.DB, if b.walletSrvc == nil { b.walletSrvc = wallet.NewService( b.walletDB, accountsDB, appDB, b.rpcClient, accountsFeed, settingsFeed, b.gethAccountManager, b.transactor, b.config, - b.ensService(b.timeSourceNow()), + b.ensService(b.timeSourceNow()).API().EnsResolver(), b.pendingTracker, walletFeed, b.httpServer, diff --git a/services/ens/api.go b/services/ens/api.go index eae63a560..864bff819 100644 --- a/services/ens/api.go +++ b/services/ens/api.go @@ -9,50 +9,41 @@ import ( "math/big" "net/url" "strings" - "sync" "time" "github.com/ipfs/go-cid" "github.com/multiformats/go-multibase" "github.com/multiformats/go-multihash" "github.com/pkg/errors" - "github.com/wealdtech/go-ens/v3" "github.com/wealdtech/go-multicodec" "go.uber.org/zap" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/status-im/status-go/account" - gocommon "github.com/status-im/status-go/common" - "github.com/status-im/status-go/contracts" "github.com/status-im/status-go/contracts/registrar" "github.com/status-im/status-go/contracts/resolver" "github.com/status-im/status-go/contracts/snt" "github.com/status-im/status-go/logutils" "github.com/status-im/status-go/params" "github.com/status-im/status-go/rpc" + "github.com/status-im/status-go/services/ens/ensresolver" "github.com/status-im/status-go/services/utils" wcommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/transactions" ) -const StatusDomain = "stateofus.eth" - func NewAPI(rpcClient *rpc.Client, accountsManager *account.GethManager, pendingTracker *transactions.PendingTxTracker, config *params.NodeConfig, appDb *sql.DB, timeSource func() time.Time, syncUserDetailFunc *syncUsernameDetail) *API { return &API{ - contractMaker: &contracts.ContractMaker{ - RPCClient: rpcClient, - }, + ensResolver: ensresolver.NewEnsResolver(rpcClient), + accountsManager: accountsManager, pendingTracker: pendingTracker, config: config, - addrPerChain: make(map[uint64]common.Address), db: NewEnsDatabase(appDb), - quit: make(chan struct{}), timeSource: timeSource, syncUserDetailFunc: syncUserDetailFunc, } @@ -68,17 +59,11 @@ type URI struct { type syncUsernameDetail func(context.Context, *UsernameDetail) error type API struct { - contractMaker *contracts.ContractMaker + ensResolver *ensresolver.EnsResolver accountsManager *account.GethManager pendingTracker *transactions.PendingTxTracker config *params.NodeConfig - addrPerChain map[uint64]common.Address - addrPerChainMutex sync.Mutex - - quitOnce sync.Once - quit chan struct{} - db *Database syncUserDetailFunc *syncUsernameDetail @@ -86,9 +71,11 @@ type API struct { } func (api *API) Stop() { - api.quitOnce.Do(func() { - close(api.quit) - }) + api.ensResolver.Stop() +} + +func (api *API) EnsResolver() *ensresolver.EnsResolver { + return api.ensResolver } func (api *API) unixTime() uint64 { @@ -122,236 +109,52 @@ func (api *API) Remove(ctx context.Context, chainID uint64, username string) err } func (api *API) GetRegistrarAddress(ctx context.Context, chainID uint64) (common.Address, error) { - return api.usernameRegistrarAddr(ctx, chainID) + return api.ensResolver.GetRegistrarAddress(ctx, chainID) } func (api *API) Resolver(ctx context.Context, chainID uint64, username string) (*common.Address, error) { - err := ValidateENSUsername(username) - if err != nil { - return nil, err - } - - registry, err := api.contractMaker.NewRegistry(chainID) - if err != nil { - return nil, err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - resolver, err := registry.Resolver(callOpts, NameHash(username)) - if err != nil { - return nil, err - } - - return &resolver, nil + return api.ensResolver.Resolver(ctx, chainID, username) } func (api *API) GetName(ctx context.Context, chainID uint64, address common.Address) (string, error) { - backend, err := api.contractMaker.RPCClient.EthClient(chainID) - if err != nil { - return "", err - } - return ens.ReverseResolve(backend, address) + return api.ensResolver.GetName(ctx, chainID, address) } func (api *API) OwnerOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) { - err := ValidateENSUsername(username) - if err != nil { - return nil, err - } - - registry, err := api.contractMaker.NewRegistry(chainID) - if err != nil { - return nil, err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - owner, err := registry.Owner(callOpts, NameHash(username)) - if err != nil { - return nil, err - } - - return &owner, nil + return api.ensResolver.OwnerOf(ctx, chainID, username) } func (api *API) ContentHash(ctx context.Context, chainID uint64, username string) ([]byte, error) { - err := ValidateENSUsername(username) - if err != nil { - return nil, err - } - - resolverAddress, err := api.Resolver(ctx, chainID, username) - if err != nil { - return nil, err - } - - resolver, err := api.contractMaker.NewPublicResolver(chainID, resolverAddress) - if err != nil { - return nil, err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - contentHash, err := resolver.Contenthash(callOpts, NameHash(username)) - if err != nil { - return nil, nil - } - - return contentHash, nil + return api.ensResolver.ContentHash(ctx, chainID, username) } func (api *API) PublicKeyOf(ctx context.Context, chainID uint64, username string) (string, error) { - err := ValidateENSUsername(username) - if err != nil { - return "", err - } - - resolverAddress, err := api.Resolver(ctx, chainID, username) - if err != nil { - return "", err - } - - resolver, err := api.contractMaker.NewPublicResolver(chainID, resolverAddress) - if err != nil { - return "", err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - pubKey, err := resolver.Pubkey(callOpts, NameHash(username)) - if err != nil { - return "", err - } - return "0x04" + hex.EncodeToString(pubKey.X[:]) + hex.EncodeToString(pubKey.Y[:]), nil + return api.ensResolver.PublicKeyOf(ctx, chainID, username) } func (api *API) AddressOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) { - err := ValidateENSUsername(username) - if err != nil { - return nil, err - } - - resolverAddress, err := api.Resolver(ctx, chainID, username) - if err != nil { - return nil, err - } - - resolver, err := api.contractMaker.NewPublicResolver(chainID, resolverAddress) - if err != nil { - return nil, err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - addr, err := resolver.Addr(callOpts, NameHash(username)) - if err != nil { - return nil, err - } - - return &addr, nil -} - -func (api *API) usernameRegistrarAddr(ctx context.Context, chainID uint64) (common.Address, error) { - logutils.ZapLogger().Info("obtaining username registrar address") - api.addrPerChainMutex.Lock() - defer api.addrPerChainMutex.Unlock() - addr, ok := api.addrPerChain[chainID] - if ok { - return addr, nil - } - - registryAddr, err := api.OwnerOf(ctx, chainID, StatusDomain) - if err != nil { - return common.Address{}, err - } - - api.addrPerChain[chainID] = *registryAddr - - go func() { - defer gocommon.LogOnPanic() - registry, err := api.contractMaker.NewRegistry(chainID) - if err != nil { - return - } - - logs := make(chan *resolver.ENSRegistryWithFallbackNewOwner) - - sub, err := registry.WatchNewOwner(&bind.WatchOpts{}, logs, nil, nil) - if err != nil { - return - } - - for { - select { - case <-api.quit: - logutils.ZapLogger().Info("quitting ens contract subscription") - sub.Unsubscribe() - return - case err := <-sub.Err(): - if err != nil { - logutils.ZapLogger().Error("ens contract subscription error: " + err.Error()) - } - return - case vLog := <-logs: - api.addrPerChainMutex.Lock() - api.addrPerChain[chainID] = vLog.Owner - api.addrPerChainMutex.Unlock() - } - } - }() - - return *registryAddr, nil + return api.ensResolver.AddressOf(ctx, chainID, username) } func (api *API) ExpireAt(ctx context.Context, chainID uint64, username string) (string, error) { - registryAddr, err := api.usernameRegistrarAddr(ctx, chainID) - if err != nil { - return "", err - } - - registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr) - if err != nil { - return "", err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - expTime, err := registrar.GetExpirationTime(callOpts, UsernameToLabel(username)) - if err != nil { - return "", err - } - - return fmt.Sprintf("%x", expTime), nil + return api.ensResolver.ExpireAt(ctx, chainID, username) } func (api *API) Price(ctx context.Context, chainID uint64) (string, error) { - registryAddr, err := api.usernameRegistrarAddr(ctx, chainID) - if err != nil { - return "", err - } - - registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr) - if err != nil { - return "", err - } - - callOpts := &bind.CallOpts{Context: ctx, Pending: false} - price, err := registrar.GetPrice(callOpts) - if err != nil { - return "", err - } - - return fmt.Sprintf("%x", price), nil + return api.ensResolver.Price(ctx, chainID) } +// Deprecated: `Release` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) Release(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, password string, username string) (string, error) { - registryAddr, err := api.usernameRegistrarAddr(ctx, chainID) + registryAddr, err := api.ensResolver.GetRegistrarAddress(ctx, chainID) if err != nil { return "", err } - registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr) - if err != nil { - return "", err - } - - txOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password)) - tx, err := registrar.Release(txOpts, UsernameToLabel(username)) + signFn := utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password) + tx, err := api.ensResolver.Release(ctx, chainID, registryAddr, txArgs, username, signFn) if err != nil { return "", err } @@ -370,7 +173,7 @@ func (api *API) Release(ctx context.Context, chainID uint64, txArgs transactions return "", err } - err = api.Remove(ctx, chainID, fullDomainName(username)) + err = api.Remove(ctx, chainID, wcommon.FullDomainName(username)) if err != nil { logutils.ZapLogger().Warn("Releasing ENS username: transaction successful, but removing failed") @@ -379,13 +182,16 @@ func (api *API) Release(ctx context.Context, chainID uint64, txArgs transactions return tx.Hash().String(), nil } +// Deprecated: `ReleasePrepareTxCallMsg` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) ReleasePrepareTxCallMsg(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string) (ethereum.CallMsg, error) { registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI)) if err != nil { return ethereum.CallMsg{}, err } - data, err := registrarABI.Pack("release", UsernameToLabel(username)) + data, err := registrarABI.Pack("release", wcommon.UsernameToLabel(username)) if err != nil { return ethereum.CallMsg{}, err } @@ -402,6 +208,9 @@ func (api *API) ReleasePrepareTxCallMsg(ctx context.Context, chainID uint64, txA }, nil } +// Deprecated: `ReleasePrepareTx` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) ReleasePrepareTx(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string) (interface{}, error) { callMsg, err := api.ReleasePrepareTxCallMsg(ctx, chainID, txArgs, username) if err != nil { @@ -411,76 +220,30 @@ func (api *API) ReleasePrepareTx(ctx context.Context, chainID uint64, txArgs tra return toCallArg(callMsg), nil } +// Deprecated: `ReleaseEstimate` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) ReleaseEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string) (uint64, error) { - registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI)) + callMsg, err := api.ReleasePrepareTxCallMsg(ctx, chainID, txArgs, username) if err != nil { return 0, err } - data, err := registrarABI.Pack("release", UsernameToLabel(username)) - if err != nil { - return 0, err - } - - ethClient, err := api.contractMaker.RPCClient.EthClient(chainID) - if err != nil { - return 0, err - } - - registryAddr, err := api.usernameRegistrarAddr(ctx, chainID) - if err != nil { - return 0, err - } - - estimate, err := ethClient.EstimateGas(ctx, ethereum.CallMsg{ - From: common.Address(txArgs.From), - To: ®istryAddr, - Value: big.NewInt(0), - Data: data, - }) - if err != nil { - return 0, err - } - return estimate + 1000, nil + return api.ensResolver.ReleaseEstimate(ctx, chainID, callMsg) } +// Deprecated: `Register` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) Register(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, password string, username string, pubkey string) (string, error) { - snt, err := api.contractMaker.NewSNT(chainID) + registryAddr, err := api.ensResolver.GetRegistrarAddress(ctx, chainID) if err != nil { return "", err } - priceHex, err := api.Price(ctx, chainID) - if err != nil { - return "", err - } - price := new(big.Int) - price.SetString(priceHex, 16) - - registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI)) - if err != nil { - return "", err - } - - x, y := ExtractCoordinates(pubkey) - extraData, err := registrarABI.Pack("register", UsernameToLabel(username), common.Address(txArgs.From), x, y) - if err != nil { - return "", err - } - - registryAddr, err := api.usernameRegistrarAddr(ctx, chainID) - if err != nil { - return "", err - } - - txOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password)) - tx, err := snt.ApproveAndCall( - txOpts, - registryAddr, - price, - extraData, - ) + signFn := utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password) + tx, err := api.ensResolver.Register(ctx, chainID, registryAddr, txArgs, username, pubkey, signFn) if err != nil { return "", err } @@ -499,7 +262,7 @@ func (api *API) Register(ctx context.Context, chainID uint64, txArgs transaction return "", err } - err = api.Add(ctx, chainID, fullDomainName(username)) + err = api.Add(ctx, chainID, wcommon.FullDomainName(username)) if err != nil { logutils.ZapLogger().Warn("Registering ENS username: transaction successful, but adding failed") } @@ -507,6 +270,9 @@ func (api *API) Register(ctx context.Context, chainID uint64, txArgs transaction return tx.Hash().String(), nil } +// Deprecated: `RegisterPrepareTxCallMsg` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (ethereum.CallMsg, error) { priceHex, err := api.Price(ctx, chainID) if err != nil { @@ -520,8 +286,8 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx return ethereum.CallMsg{}, err } - x, y := ExtractCoordinates(pubkey) - extraData, err := registrarABI.Pack("register", UsernameToLabel(username), common.Address(txArgs.From), x, y) + x, y := wcommon.ExtractCoordinates(pubkey) + extraData, err := registrarABI.Pack("register", wcommon.UsernameToLabel(username), common.Address(txArgs.From), x, y) if err != nil { return ethereum.CallMsg{}, err } @@ -531,7 +297,7 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx return ethereum.CallMsg{}, err } - registryAddr, err := api.usernameRegistrarAddr(ctx, chainID) + registryAddr, err := api.ensResolver.GetRegistrarAddress(ctx, chainID) if err != nil { return ethereum.CallMsg{}, err } @@ -553,6 +319,9 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx }, nil } +// Deprecated: `RegisterPrepareTx` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) RegisterPrepareTx(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (interface{}, error) { callMsg, err := api.RegisterPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey) if err != nil { @@ -562,43 +331,29 @@ func (api *API) RegisterPrepareTx(ctx context.Context, chainID uint64, txArgs tr return toCallArg(callMsg), nil } +// Deprecated: `RegisterEstimate` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) RegisterEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (uint64, error) { - ethClient, err := api.contractMaker.RPCClient.EthClient(chainID) - if err != nil { - return 0, err - } - callMsg, err := api.RegisterPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey) if err != nil { return 0, err } - estimate, err := ethClient.EstimateGas(ctx, callMsg) - if err != nil { - return 0, err - } - return estimate + 1000, nil + return api.ensResolver.RegisterEstimate(ctx, chainID, callMsg) } +// Deprecated: `SetPubKey` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, password string, username string, pubkey string) (string, error) { - err := ValidateENSUsername(username) - if err != nil { - return "", err - } - resolverAddress, err := api.Resolver(ctx, chainID, username) if err != nil { return "", err } - resolver, err := api.contractMaker.NewPublicResolver(chainID, resolverAddress) - if err != nil { - return "", err - } - - x, y := ExtractCoordinates(pubkey) - txOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password)) - tx, err := resolver.SetPubkey(txOpts, NameHash(username), x, y) + signFn := utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password) + tx, err := api.ensResolver.SetPubKey(ctx, chainID, resolverAddress, txArgs, username, pubkey, signFn) if err != nil { return "", err } @@ -617,7 +372,7 @@ func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactio return "", err } - err = api.Add(ctx, chainID, fullDomainName(username)) + err = api.Add(ctx, chainID, wcommon.FullDomainName(username)) if err != nil { logutils.ZapLogger().Warn("Registering ENS username: transaction successful, but adding failed") @@ -626,19 +381,22 @@ func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactio return tx.Hash().String(), nil } +// Deprecated: `SetPubKeyPrepareTxCallMsg` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) SetPubKeyPrepareTxCallMsg(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (ethereum.CallMsg, error) { - err := ValidateENSUsername(username) + err := wcommon.ValidateENSUsername(username) if err != nil { return ethereum.CallMsg{}, err } - x, y := ExtractCoordinates(pubkey) + x, y := wcommon.ExtractCoordinates(pubkey) resolverABI, err := abi.JSON(strings.NewReader(resolver.PublicResolverABI)) if err != nil { return ethereum.CallMsg{}, err } - data, err := resolverABI.Pack("setPubkey", NameHash(username), x, y) + data, err := resolverABI.Pack("setPubkey", wcommon.NameHash(username), x, y) if err != nil { return ethereum.CallMsg{}, err } @@ -656,6 +414,9 @@ func (api *API) SetPubKeyPrepareTxCallMsg(ctx context.Context, chainID uint64, t }, nil } +// Deprecated: `SetPubKeyPrepareTx` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) SetPubKeyPrepareTx(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (interface{}, error) { callMsg, err := api.SetPubKeyPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey) if err != nil { @@ -665,22 +426,16 @@ func (api *API) SetPubKeyPrepareTx(ctx context.Context, chainID uint64, txArgs t return toCallArg(callMsg), nil } +// Deprecated: `SetPubKeyEstimate` was used before introducing a new, uniform, sending flow that uses router. +// Releasing ens username should start from calling `wallet_getSuggestedRoutesAsync` +// TODO: remove once mobile switches to a new sending flow. func (api *API) SetPubKeyEstimate(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string, pubkey string) (uint64, error) { - ethClient, err := api.contractMaker.RPCClient.EthClient(chainID) - if err != nil { - return 0, err - } - callMsg, err := api.SetPubKeyPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey) if err != nil { return 0, err } - estimate, err := ethClient.EstimateGas(ctx, callMsg) - if err != nil { - return 0, err - } - return estimate + 1000, nil + return api.ensResolver.SetPubKeyEstimate(ctx, chainID, callMsg) } func (api *API) ResourceURL(ctx context.Context, chainID uint64, username string) (*URI, error) { @@ -773,7 +528,3 @@ func toCallArg(msg ethereum.CallMsg) interface{} { } return arg } - -func fullDomainName(username string) string { - return username + "." + StatusDomain -} diff --git a/services/ens/ensresolver/resolver.go b/services/ens/ensresolver/resolver.go new file mode 100644 index 000000000..cdd4069bb --- /dev/null +++ b/services/ens/ensresolver/resolver.go @@ -0,0 +1,369 @@ +package ensresolver + +import ( + "context" + "encoding/hex" + "fmt" + "math/big" + "strings" + "sync" + + "github.com/wealdtech/go-ens/v3" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + gocommon "github.com/status-im/status-go/common" + "github.com/status-im/status-go/contracts" + "github.com/status-im/status-go/contracts/registrar" + "github.com/status-im/status-go/contracts/resolver" + "github.com/status-im/status-go/logutils" + "github.com/status-im/status-go/rpc" + walletCommon "github.com/status-im/status-go/services/wallet/common" + "github.com/status-im/status-go/transactions" +) + +func NewEnsResolver(rpcClient *rpc.Client) *EnsResolver { + return &EnsResolver{ + contractMaker: &contracts.ContractMaker{ + RPCClient: rpcClient, + }, + addrPerChain: make(map[uint64]common.Address), + + quit: make(chan struct{}), + } +} + +type EnsResolver struct { + contractMaker *contracts.ContractMaker + + addrPerChain map[uint64]common.Address + addrPerChainMutex sync.Mutex + + quitOnce sync.Once + quit chan struct{} +} + +func (e *EnsResolver) Stop() { + e.quitOnce.Do(func() { + close(e.quit) + }) +} + +func (e *EnsResolver) GetRegistrarAddress(ctx context.Context, chainID uint64) (common.Address, error) { + return e.usernameRegistrarAddr(ctx, chainID) +} + +func (e *EnsResolver) Resolver(ctx context.Context, chainID uint64, username string) (*common.Address, error) { + err := walletCommon.ValidateENSUsername(username) + if err != nil { + return nil, err + } + + registry, err := e.contractMaker.NewRegistry(chainID) + if err != nil { + return nil, err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + resolver, err := registry.Resolver(callOpts, walletCommon.NameHash(username)) + if err != nil { + return nil, err + } + + return &resolver, nil +} + +func (e *EnsResolver) GetName(ctx context.Context, chainID uint64, address common.Address) (string, error) { + backend, err := e.contractMaker.RPCClient.EthClient(chainID) + if err != nil { + return "", err + } + return ens.ReverseResolve(backend, address) +} + +func (e *EnsResolver) OwnerOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) { + err := walletCommon.ValidateENSUsername(username) + if err != nil { + return nil, err + } + + registry, err := e.contractMaker.NewRegistry(chainID) + if err != nil { + return nil, err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + owner, err := registry.Owner(callOpts, walletCommon.NameHash(username)) + if err != nil { + return nil, err + } + + return &owner, nil +} + +func (e *EnsResolver) ContentHash(ctx context.Context, chainID uint64, username string) ([]byte, error) { + err := walletCommon.ValidateENSUsername(username) + if err != nil { + return nil, err + } + + resolverAddress, err := e.Resolver(ctx, chainID, username) + if err != nil { + return nil, err + } + + resolver, err := e.contractMaker.NewPublicResolver(chainID, resolverAddress) + if err != nil { + return nil, err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + contentHash, err := resolver.Contenthash(callOpts, walletCommon.NameHash(username)) + if err != nil { + return nil, nil + } + + return contentHash, nil +} + +func (e *EnsResolver) PublicKeyOf(ctx context.Context, chainID uint64, username string) (string, error) { + err := walletCommon.ValidateENSUsername(username) + if err != nil { + return "", err + } + + resolverAddress, err := e.Resolver(ctx, chainID, username) + if err != nil { + return "", err + } + + resolver, err := e.contractMaker.NewPublicResolver(chainID, resolverAddress) + if err != nil { + return "", err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + pubKey, err := resolver.Pubkey(callOpts, walletCommon.NameHash(username)) + if err != nil { + return "", err + } + return "0x04" + hex.EncodeToString(pubKey.X[:]) + hex.EncodeToString(pubKey.Y[:]), nil +} + +func (e *EnsResolver) AddressOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) { + err := walletCommon.ValidateENSUsername(username) + if err != nil { + return nil, err + } + + resolverAddress, err := e.Resolver(ctx, chainID, username) + if err != nil { + return nil, err + } + + resolver, err := e.contractMaker.NewPublicResolver(chainID, resolverAddress) + if err != nil { + return nil, err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + addr, err := resolver.Addr(callOpts, walletCommon.NameHash(username)) + if err != nil { + return nil, err + } + + return &addr, nil +} + +func (e *EnsResolver) usernameRegistrarAddr(ctx context.Context, chainID uint64) (common.Address, error) { + logutils.ZapLogger().Info("obtaining username registrar address") + e.addrPerChainMutex.Lock() + defer e.addrPerChainMutex.Unlock() + addr, ok := e.addrPerChain[chainID] + if ok { + return addr, nil + } + + registryAddr, err := e.OwnerOf(ctx, chainID, walletCommon.StatusDomain) + if err != nil { + return common.Address{}, err + } + + e.addrPerChain[chainID] = *registryAddr + + go func() { + defer gocommon.LogOnPanic() + registry, err := e.contractMaker.NewRegistry(chainID) + if err != nil { + return + } + + logs := make(chan *resolver.ENSRegistryWithFallbackNewOwner) + + sub, err := registry.WatchNewOwner(&bind.WatchOpts{}, logs, nil, nil) + if err != nil { + return + } + + for { + select { + case <-e.quit: + logutils.ZapLogger().Info("quitting ens contract subscription") + sub.Unsubscribe() + return + case err := <-sub.Err(): + if err != nil { + logutils.ZapLogger().Error("ens contract subscription error: " + err.Error()) + } + return + case vLog := <-logs: + e.addrPerChainMutex.Lock() + e.addrPerChain[chainID] = vLog.Owner + e.addrPerChainMutex.Unlock() + } + } + }() + + return *registryAddr, nil +} + +func (e *EnsResolver) ExpireAt(ctx context.Context, chainID uint64, username string) (string, error) { + registryAddr, err := e.usernameRegistrarAddr(ctx, chainID) + if err != nil { + return "", err + } + + registrar, err := e.contractMaker.NewUsernameRegistrar(chainID, registryAddr) + if err != nil { + return "", err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + expTime, err := registrar.GetExpirationTime(callOpts, walletCommon.UsernameToLabel(username)) + if err != nil { + return "", err + } + + return fmt.Sprintf("%x", expTime), nil +} + +func (e *EnsResolver) Price(ctx context.Context, chainID uint64) (string, error) { + registryAddr, err := e.usernameRegistrarAddr(ctx, chainID) + if err != nil { + return "", err + } + + registrar, err := e.contractMaker.NewUsernameRegistrar(chainID, registryAddr) + if err != nil { + return "", err + } + + callOpts := &bind.CallOpts{Context: ctx, Pending: false} + price, err := registrar.GetPrice(callOpts) + if err != nil { + return "", err + } + + return fmt.Sprintf("%x", price), nil +} + +func (e *EnsResolver) Release(ctx context.Context, chainID uint64, registryAddress common.Address, txArgs transactions.SendTxArgs, username string, signFn bind.SignerFn) (*types.Transaction, error) { + registrar, err := e.contractMaker.NewUsernameRegistrar(chainID, registryAddress) + if err != nil { + return nil, err + } + + txOpts := txArgs.ToTransactOpts(signFn) + return registrar.Release(txOpts, walletCommon.UsernameToLabel(username)) +} + +func (e *EnsResolver) ReleaseEstimate(ctx context.Context, chainID uint64, callMsg ethereum.CallMsg) (uint64, error) { + ethClient, err := e.contractMaker.RPCClient.EthClient(chainID) + if err != nil { + return 0, err + } + + estimate, err := ethClient.EstimateGas(ctx, callMsg) + if err != nil { + return 0, err + } + return estimate + 1000, nil +} + +func (e *EnsResolver) Register(ctx context.Context, chainID uint64, registryAddress common.Address, txArgs transactions.SendTxArgs, username string, pubkey string, signFn bind.SignerFn) (*types.Transaction, error) { + snt, err := e.contractMaker.NewSNT(chainID) + if err != nil { + return nil, err + } + + priceHex, err := e.Price(ctx, chainID) + if err != nil { + return nil, err + } + price := new(big.Int) + price.SetString(priceHex, 16) + + registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI)) + if err != nil { + return nil, err + } + + x, y := walletCommon.ExtractCoordinates(pubkey) + extraData, err := registrarABI.Pack("register", walletCommon.UsernameToLabel(username), common.Address(txArgs.From), x, y) + if err != nil { + return nil, err + } + + txOpts := txArgs.ToTransactOpts(signFn) + return snt.ApproveAndCall( + txOpts, + registryAddress, + price, + extraData, + ) +} + +func (e *EnsResolver) RegisterEstimate(ctx context.Context, chainID uint64, callMsg ethereum.CallMsg) (uint64, error) { + ethClient, err := e.contractMaker.RPCClient.EthClient(chainID) + if err != nil { + return 0, err + } + + estimate, err := ethClient.EstimateGas(ctx, callMsg) + if err != nil { + return 0, err + } + return estimate + 1000, nil +} + +func (e *EnsResolver) SetPubKey(ctx context.Context, chainID uint64, resolverAddress *common.Address, txArgs transactions.SendTxArgs, username string, pubkey string, signFn bind.SignerFn) (*types.Transaction, error) { + err := walletCommon.ValidateENSUsername(username) + if err != nil { + return nil, err + } + + resolver, err := e.contractMaker.NewPublicResolver(chainID, resolverAddress) + if err != nil { + return nil, err + } + + x, y := walletCommon.ExtractCoordinates(pubkey) + txOpts := txArgs.ToTransactOpts(signFn) + return resolver.SetPubkey(txOpts, walletCommon.NameHash(username), x, y) +} + +func (e *EnsResolver) SetPubKeyEstimate(ctx context.Context, chainID uint64, callMsg ethereum.CallMsg) (uint64, error) { + ethClient, err := e.contractMaker.RPCClient.EthClient(chainID) + if err != nil { + return 0, err + } + + estimate, err := ethClient.EstimateGas(ctx, callMsg) + if err != nil { + return 0, err + } + return estimate + 1000, nil +} diff --git a/services/ens/strings.go b/services/ens/strings.go deleted file mode 100644 index 2e0e33753..000000000 --- a/services/ens/strings.go +++ /dev/null @@ -1,54 +0,0 @@ -package ens - -import ( - "encoding/hex" - "fmt" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -func NameHash(name string) common.Hash { - node := common.Hash{} - - if len(name) > 0 { - labels := strings.Split(name, ".") - - for i := len(labels) - 1; i >= 0; i-- { - labelSha := crypto.Keccak256Hash([]byte(labels[i])) - node = crypto.Keccak256Hash(node.Bytes(), labelSha.Bytes()) - } - } - - return node -} - -func ValidateENSUsername(username string) error { - if !strings.HasSuffix(username, ".eth") { - return fmt.Errorf("username must end with .eth") - } - - return nil -} - -func UsernameToLabel(username string) [32]byte { - usernameHashed := crypto.Keccak256([]byte(username)) - var label [32]byte - copy(label[:], usernameHashed) - - return label -} - -func ExtractCoordinates(pubkey string) ([32]byte, [32]byte) { - x, _ := hex.DecodeString(pubkey[4:68]) - y, _ := hex.DecodeString(pubkey[68:132]) - - var xByte [32]byte - copy(xByte[:], x) - - var yByte [32]byte - copy(yByte[:], y) - - return xByte, yByte -} diff --git a/services/wallet/common/const.go b/services/wallet/common/const.go index bae001ed4..d9c4703a5 100644 --- a/services/wallet/common/const.go +++ b/services/wallet/common/const.go @@ -13,6 +13,7 @@ type MultiTransactionIDType int64 const ( NoMultiTransactionID = MultiTransactionIDType(0) HexAddressLength = 42 + StatusDomain = "stateofus.eth" ) type ChainID uint64 diff --git a/services/wallet/common/helpers.go b/services/wallet/common/helpers.go index 02d18c994..c770d337d 100644 --- a/services/wallet/common/helpers.go +++ b/services/wallet/common/helpers.go @@ -1,12 +1,14 @@ package common import ( + "encoding/hex" "fmt" "math/big" "strings" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/status-im/status-go/contracts/ierc20" ) @@ -30,3 +32,51 @@ func GetTokenIdFromSymbol(symbol string) (*big.Int, error) { } return id, nil } + +func FullDomainName(username string) string { + return username + "." + StatusDomain +} + +func ExtractCoordinates(pubkey string) ([32]byte, [32]byte) { + x, _ := hex.DecodeString(pubkey[4:68]) + y, _ := hex.DecodeString(pubkey[68:132]) + + var xByte [32]byte + copy(xByte[:], x) + + var yByte [32]byte + copy(yByte[:], y) + + return xByte, yByte +} + +func NameHash(name string) common.Hash { + node := common.Hash{} + + if len(name) > 0 { + labels := strings.Split(name, ".") + + for i := len(labels) - 1; i >= 0; i-- { + labelSha := crypto.Keccak256Hash([]byte(labels[i])) + node = crypto.Keccak256Hash(node.Bytes(), labelSha.Bytes()) + } + } + + return node +} + +func ValidateENSUsername(username string) error { + if !strings.HasSuffix(username, ".eth") { + return fmt.Errorf("username must end with .eth") + } + + return nil +} + +func UsernameToLabel(username string) [32]byte { + usernameHashed := crypto.Keccak256([]byte(username)) + var label [32]byte + copy(label[:], usernameHashed) + + return label +} diff --git a/services/wallet/requests/router_input_params.go b/services/wallet/requests/router_input_params.go index 1130fdf33..b6bd28b56 100644 --- a/services/wallet/requests/router_input_params.go +++ b/services/wallet/requests/router_input_params.go @@ -6,7 +6,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/status-im/status-go/errors" - "github.com/status-im/status-go/services/ens" walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/services/wallet/router/fees" "github.com/status-im/status-go/services/wallet/router/pathprocessor" @@ -103,7 +102,7 @@ func (i *RouteInputParams) Validate() error { return ErrENSSetPubKeyRequiresUsernameAndPubKey } - if ens.ValidateENSUsername(i.Username) != nil { + if walletCommon.ValidateENSUsername(i.Username) != nil { return ErrENSSetPubKeyInvalidUsername } } diff --git a/services/wallet/router/pathprocessor/processor_ens_public_key.go b/services/wallet/router/pathprocessor/processor_ens_public_key.go index 72b47a3ed..709f8ec6d 100644 --- a/services/wallet/router/pathprocessor/processor_ens_public_key.go +++ b/services/wallet/router/pathprocessor/processor_ens_public_key.go @@ -14,7 +14,7 @@ import ( "github.com/status-im/status-go/contracts/resolver" "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/rpc" - "github.com/status-im/status-go/services/ens" + "github.com/status-im/status-go/services/ens/ensresolver" walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/transactions" ) @@ -22,16 +22,16 @@ import ( type ENSPublicKeyProcessor struct { contractMaker *contracts.ContractMaker transactor transactions.TransactorIface - ensService *ens.Service + ensResolver *ensresolver.EnsResolver } -func NewENSPublicKeyProcessor(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensService *ens.Service) *ENSPublicKeyProcessor { +func NewENSPublicKeyProcessor(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensResolver *ensresolver.EnsResolver) *ENSPublicKeyProcessor { return &ENSPublicKeyProcessor{ contractMaker: &contracts.ContractMaker{ RPCClient: rpcClient, }, - transactor: transactor, - ensService: ensService, + transactor: transactor, + ensResolver: ensResolver, } } @@ -57,8 +57,8 @@ func (s *ENSPublicKeyProcessor) PackTxInputData(params ProcessorInputParams) ([] return []byte{}, createENSPublicKeyErrorResponse(err) } - x, y := ens.ExtractCoordinates(params.PublicKey) - return resolverABI.Pack("setPubkey", ens.NameHash(params.Username), x, y) + x, y := walletCommon.ExtractCoordinates(params.PublicKey) + return resolverABI.Pack("setPubkey", walletCommon.NameHash(params.Username), x, y) } func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { @@ -120,7 +120,7 @@ func (s *ENSPublicKeyProcessor) CalculateAmountOut(params ProcessorInputParams) } func (s *ENSPublicKeyProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) { - addr, err := s.ensService.API().Resolver(context.Background(), params.FromChain.ChainID, params.Username) + addr, err := s.ensResolver.Resolver(context.Background(), params.FromChain.ChainID, params.Username) if err != nil { return common.Address{}, createENSPublicKeyErrorResponse(err) } diff --git a/services/wallet/router/pathprocessor/processor_ens_register.go b/services/wallet/router/pathprocessor/processor_ens_register.go index 895ca753a..9544e734e 100644 --- a/services/wallet/router/pathprocessor/processor_ens_register.go +++ b/services/wallet/router/pathprocessor/processor_ens_register.go @@ -16,7 +16,7 @@ import ( "github.com/status-im/status-go/contracts/snt" "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/rpc" - "github.com/status-im/status-go/services/ens" + "github.com/status-im/status-go/services/ens/ensresolver" walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/transactions" ) @@ -24,16 +24,16 @@ import ( type ENSRegisterProcessor struct { contractMaker *contracts.ContractMaker transactor transactions.TransactorIface - ensService *ens.Service + ensResolver *ensresolver.EnsResolver } -func NewENSRegisterProcessor(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensService *ens.Service) *ENSRegisterProcessor { +func NewENSRegisterProcessor(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensResolver *ensresolver.EnsResolver) *ENSRegisterProcessor { return &ENSRegisterProcessor{ contractMaker: &contracts.ContractMaker{ RPCClient: rpcClient, }, - transactor: transactor, - ensService: ensService, + transactor: transactor, + ensResolver: ensResolver, } } @@ -46,7 +46,7 @@ func (s *ENSRegisterProcessor) Name() string { } func (s *ENSRegisterProcessor) GetPriceForRegisteringEnsName(chainID uint64) (*big.Int, error) { - registryAddr, err := s.ensService.API().GetRegistrarAddress(context.Background(), chainID) + registryAddr, err := s.ensResolver.GetRegistrarAddress(context.Background(), chainID) if err != nil { return nil, createENSRegisterProcessorErrorResponse(err) } @@ -78,8 +78,8 @@ func (s *ENSRegisterProcessor) PackTxInputData(params ProcessorInputParams) ([]b return []byte{}, createENSRegisterProcessorErrorResponse(err) } - x, y := ens.ExtractCoordinates(params.PublicKey) - extraData, err := registrarABI.Pack("register", ens.UsernameToLabel(params.Username), params.FromAddr, x, y) + x, y := walletCommon.ExtractCoordinates(params.PublicKey) + extraData, err := registrarABI.Pack("register", walletCommon.UsernameToLabel(params.Username), params.FromAddr, x, y) if err != nil { return []byte{}, createENSRegisterProcessorErrorResponse(err) } @@ -89,7 +89,7 @@ func (s *ENSRegisterProcessor) PackTxInputData(params ProcessorInputParams) ([]b return []byte{}, createENSRegisterProcessorErrorResponse(err) } - registryAddr, err := s.ensService.API().GetRegistrarAddress(context.Background(), params.FromChain.ChainID) + registryAddr, err := s.ensResolver.GetRegistrarAddress(context.Background(), params.FromChain.ChainID) if err != nil { return []byte{}, createENSRegisterProcessorErrorResponse(err) } diff --git a/services/wallet/router/pathprocessor/processor_ens_release.go b/services/wallet/router/pathprocessor/processor_ens_release.go index eea13b6e2..16edd3ea0 100644 --- a/services/wallet/router/pathprocessor/processor_ens_release.go +++ b/services/wallet/router/pathprocessor/processor_ens_release.go @@ -14,7 +14,7 @@ import ( "github.com/status-im/status-go/contracts/registrar" "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/rpc" - "github.com/status-im/status-go/services/ens" + "github.com/status-im/status-go/services/ens/ensresolver" walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/transactions" ) @@ -22,16 +22,16 @@ import ( type ENSReleaseProcessor struct { contractMaker *contracts.ContractMaker transactor transactions.TransactorIface - ensService *ens.Service + ensResolver *ensresolver.EnsResolver } -func NewENSReleaseProcessor(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensService *ens.Service) *ENSReleaseProcessor { +func NewENSReleaseProcessor(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensResolver *ensresolver.EnsResolver) *ENSReleaseProcessor { return &ENSReleaseProcessor{ contractMaker: &contracts.ContractMaker{ RPCClient: rpcClient, }, - transactor: transactor, - ensService: ensService, + transactor: transactor, + ensResolver: ensResolver, } } @@ -58,7 +58,7 @@ func (s *ENSReleaseProcessor) PackTxInputData(params ProcessorInputParams) ([]by } name := getNameFromEnsUsername(params.Username) - return registrarABI.Pack("release", ens.UsernameToLabel(name)) + return registrarABI.Pack("release", walletCommon.UsernameToLabel(name)) } func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { @@ -120,7 +120,7 @@ func (s *ENSReleaseProcessor) CalculateAmountOut(params ProcessorInputParams) (* } func (s *ENSReleaseProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) { - addr, err := s.ensService.API().GetRegistrarAddress(context.Background(), params.FromChain.ChainID) + addr, err := s.ensResolver.GetRegistrarAddress(context.Background(), params.FromChain.ChainID) if err != nil { return common.Address{}, err } diff --git a/services/wallet/router/router.go b/services/wallet/router/router.go index 2d462a27e..f8c2800b6 100644 --- a/services/wallet/router/router.go +++ b/services/wallet/router/router.go @@ -16,7 +16,6 @@ import ( "github.com/status-im/status-go/logutils" "github.com/status-im/status-go/params" "github.com/status-im/status-go/rpc" - "github.com/status-im/status-go/services/ens" "github.com/status-im/status-go/services/wallet/async" "github.com/status-im/status-go/services/wallet/collectibles" walletCommon "github.com/status-im/status-go/services/wallet/common" @@ -68,7 +67,6 @@ type Router struct { marketManager *market.Manager collectiblesService *collectibles.Service collectiblesManager *collectibles.Manager - ensService *ens.Service feesManager *fees.FeeManager pathProcessors map[string]pathprocessor.PathProcessor scheduler *async.Scheduler @@ -88,7 +86,7 @@ type Router struct { } func NewRouter(rpcClient *rpc.Client, transactor *transactions.Transactor, tokenManager *token.Manager, marketManager *market.Manager, - collectibles *collectibles.Service, collectiblesManager *collectibles.Manager, ensService *ens.Service) *Router { + collectibles *collectibles.Service, collectiblesManager *collectibles.Manager) *Router { processors := make(map[string]pathprocessor.PathProcessor) return &Router{ @@ -97,7 +95,6 @@ func NewRouter(rpcClient *rpc.Client, transactor *transactions.Transactor, token marketManager: marketManager, collectiblesService: collectibles, collectiblesManager: collectiblesManager, - ensService: ensService, feesManager: &fees.FeeManager{ RPCClient: rpcClient, }, diff --git a/services/wallet/router/router_test.go b/services/wallet/router/router_test.go index 8dd1b5b70..36e2e929f 100644 --- a/services/wallet/router/router_test.go +++ b/services/wallet/router/router_test.go @@ -101,7 +101,7 @@ func setupRouter(t *testing.T) (*Router, func()) { } client, _ := rpc.NewClient(config) - router := NewRouter(client, nil, nil, nil, nil, nil, nil) + router := NewRouter(client, nil, nil, nil, nil, nil) transfer := pathprocessor.NewTransferProcessor(nil, nil) router.AddPathProcessor(transfer) diff --git a/services/wallet/service.go b/services/wallet/service.go index 18582ac78..a0000c7c9 100644 --- a/services/wallet/service.go +++ b/services/wallet/service.go @@ -19,7 +19,7 @@ import ( protocolCommon "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/rpc" "github.com/status-im/status-go/server" - "github.com/status-im/status-go/services/ens" + "github.com/status-im/status-go/services/ens/ensresolver" "github.com/status-im/status-go/services/wallet/activity" "github.com/status-im/status-go/services/wallet/balance" "github.com/status-im/status-go/services/wallet/blockchainstate" @@ -59,7 +59,7 @@ func NewService( gethManager *account.GethManager, transactor *transactions.Transactor, config *params.NodeConfig, - ens *ens.Service, + ensResolver *ensresolver.EnsResolver, pendingTxManager *transactions.PendingTxTracker, feed *event.Feed, mediaServer *server.MediaServer, @@ -190,8 +190,8 @@ func NewService( } router := router.NewRouter(rpcClient, transactor, tokenManager, marketManager, collectibles, - collectiblesManager, ens) - pathProcessors := buildPathProcessors(rpcClient, transactor, tokenManager, ens, featureFlags) + collectiblesManager) + pathProcessors := buildPathProcessors(rpcClient, transactor, tokenManager, ensResolver, featureFlags) for _, processor := range pathProcessors { router.AddPathProcessor(processor) } @@ -214,7 +214,6 @@ func NewService( gethManager: gethManager, marketManager: marketManager, transactor: transactor, - ens: ens, feed: feed, signals: signals, reader: reader, @@ -235,7 +234,7 @@ func buildPathProcessors( rpcClient *rpc.Client, transactor *transactions.Transactor, tokenManager *token.Manager, - ens *ens.Service, + ensResolver *ensresolver.EnsResolver, featureFlags *protocolCommon.FeatureFlags, ) []pathprocessor.PathProcessor { ret := make([]pathprocessor.PathProcessor, 0) @@ -261,13 +260,13 @@ func buildPathProcessors( paraswap := pathprocessor.NewSwapParaswapProcessor(rpcClient, transactor, tokenManager) ret = append(ret, paraswap) - ensRegister := pathprocessor.NewENSRegisterProcessor(rpcClient, transactor, ens) + ensRegister := pathprocessor.NewENSRegisterProcessor(rpcClient, transactor, ensResolver) ret = append(ret, ensRegister) - ensRelease := pathprocessor.NewENSReleaseProcessor(rpcClient, transactor, ens) + ensRelease := pathprocessor.NewENSReleaseProcessor(rpcClient, transactor, ensResolver) ret = append(ret, ensRelease) - ensPublicKey := pathprocessor.NewENSPublicKeyProcessor(rpcClient, transactor, ens) + ensPublicKey := pathprocessor.NewENSPublicKeyProcessor(rpcClient, transactor, ensResolver) ret = append(ret, ensPublicKey) buyStickers := pathprocessor.NewStickersBuyProcessor(rpcClient, transactor) @@ -294,7 +293,6 @@ type Service struct { collectibles *collectibles.Service gethManager *account.GethManager transactor *transactions.Transactor - ens *ens.Service feed *event.Feed signals *walletevent.SignalsTransmitter reader *Reader @@ -399,7 +397,3 @@ func (s *Service) GetCollectiblesService() *collectibles.Service { func (s *Service) GetCollectiblesManager() *collectibles.Manager { return s.collectiblesManager } - -func (s *Service) GetEnsService() *ens.Service { - return s.ens -}