feat: obtain ENSUsername address from registry (#2792)

This commit is contained in:
Richard Ramos 2022-08-23 08:29:30 -04:00 committed by GitHub
parent ef21440e32
commit 92a622d6fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 39 deletions

View file

@ -40,12 +40,7 @@ func (c *ContractMaker) NewPublicResolver(chainID uint64, resolverAddress *commo
return resolver.NewPublicResolver(*resolverAddress, backend)
}
func (c *ContractMaker) NewUsernameRegistrar(chainID uint64) (*registrar.UsernameRegistrar, error) {
contractAddr, err := registrar.ContractAddress(chainID)
if err != nil {
return nil, err
}
func (c *ContractMaker) NewUsernameRegistrar(chainID uint64, contractAddr common.Address) (*registrar.UsernameRegistrar, error) {
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err

View file

@ -1,23 +0,0 @@
package registrar
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
var contractAddressByChainID = map[uint64]common.Address{
1: common.HexToAddress("0xDB5ac1a559b02E12F29fC0eC0e37Be8E046DEF49"), // mainnet
3: common.HexToAddress("0xdaae165beb8c06e0b7613168138ebba774aff071"), // ropsten
5: common.HexToAddress("0xD1f7416F91E7Eb93dD96A61F12FC092aD6B67B11"), //goerli
}
func ContractAddress(chainID uint64) (common.Address, error) {
addr, exists := contractAddressByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

View file

@ -584,6 +584,11 @@ func (b *StatusNode) Cleanup() error {
}
}
err := b.ensSrvc.Stop()
if err != nil {
return err
}
return nil
}

View file

@ -7,6 +7,7 @@ import (
"fmt"
"math/big"
"strings"
"sync"
"github.com/ipfs/go-cid"
"github.com/multiformats/go-multibase"
@ -20,6 +21,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/contracts"
"github.com/status-im/status-go/contracts/registrar"
@ -40,6 +42,9 @@ func NewAPI(rpcClient *rpc.Client, accountsManager *account.GethManager, rpcFilt
accountsManager: accountsManager,
rpcFiltersSrvc: rpcFiltersSrvc,
config: config,
addrPerChain: make(map[uint64]common.Address),
quit: make(chan struct{}),
}
}
@ -54,10 +59,22 @@ type API struct {
accountsManager *account.GethManager
rpcFiltersSrvc *rpcfilters.Service
config *params.NodeConfig
addrPerChain map[uint64]common.Address
addrPerChainMutex sync.Mutex
quitOnce sync.Once
quit chan struct{}
}
func (api *API) Stop() {
api.quitOnce.Do(func() {
close(api.quit)
})
}
func (api *API) GetRegistrarAddress(ctx context.Context, chainID uint64) (common.Address, error) {
return registrar.ContractAddress(chainID)
return api.usernameRegistrarAddr(ctx, chainID)
}
func (api *API) Resolver(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
@ -174,8 +191,65 @@ func (api *API) AddressOf(ctx context.Context, chainID uint64, username string)
return &addr, nil
}
func (api *API) usernameRegistrarAddr(ctx context.Context, chainID uint64) (common.Address, error) {
log.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, "stateofus.eth")
if err != nil {
return common.Address{}, err
}
api.addrPerChain[chainID] = *registryAddr
go func() {
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:
log.Info("quitting ens contract subscription")
sub.Unsubscribe()
return
case err := <-sub.Err():
if err != nil {
log.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
}
func (api *API) ExpireAt(ctx context.Context, chainID uint64, username string) (string, error) {
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID)
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
if err != nil {
return "", err
}
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr)
if err != nil {
return "", err
}
@ -190,7 +264,12 @@ func (api *API) ExpireAt(ctx context.Context, chainID uint64, username string) (
}
func (api *API) Price(ctx context.Context, chainID uint64) (string, error) {
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID)
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
if err != nil {
return "", err
}
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr)
if err != nil {
return "", err
}
@ -216,7 +295,12 @@ func (api *API) getSigner(chainID uint64, from types.Address, password string) b
}
func (api *API) Release(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, password string, username string) (string, error) {
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID)
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
if err != nil {
return "", err
}
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr)
if err != nil {
return "", err
}
@ -247,14 +331,14 @@ func (api *API) ReleaseEstimate(ctx context.Context, chainID uint64, txArgs tran
return 0, err
}
registrarAddress, err := registrar.ContractAddress(chainID)
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
if err != nil {
return 0, err
}
return ethClient.EstimateGas(ctx, ethereum.CallMsg{
From: common.Address(txArgs.From),
To: &registrarAddress,
To: &registryAddr,
Value: big.NewInt(0),
Data: data,
})
@ -284,7 +368,7 @@ func (api *API) Register(ctx context.Context, chainID uint64, txArgs transaction
return "", err
}
registrarAddress, err := registrar.ContractAddress(chainID)
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
if err != nil {
return "", err
}
@ -292,7 +376,7 @@ func (api *API) Register(ctx context.Context, chainID uint64, txArgs transaction
txOpts := txArgs.ToTransactOpts(api.getSigner(chainID, txArgs.From, password))
tx, err := snt.ApproveAndCall(
txOpts,
registrarAddress,
registryAddr,
price,
extraData,
)
@ -329,12 +413,12 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx
return ethereum.CallMsg{}, err
}
registrarAddress, err := registrar.ContractAddress(chainID)
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
if err != nil {
return ethereum.CallMsg{}, err
}
data, err := sntABI.Pack("approveAndCall", registrarAddress, price, extraData)
data, err := sntABI.Pack("approveAndCall", registryAddr, price, extraData)
if err != nil {
return ethereum.CallMsg{}, err
}

View file

@ -36,6 +36,7 @@ func (s *Service) Start() error {
// Stop a service.
func (s *Service) Stop() error {
s.api.Stop()
return nil
}