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.
This commit is contained in:
parent
11cf42bedd
commit
b4f819d85c
|
@ -593,7 +593,7 @@ func (b *StatusNode) walletService(accountsDB *accounts.Database, appDB *sql.DB,
|
||||||
if b.walletSrvc == nil {
|
if b.walletSrvc == nil {
|
||||||
b.walletSrvc = wallet.NewService(
|
b.walletSrvc = wallet.NewService(
|
||||||
b.walletDB, accountsDB, appDB, b.rpcClient, accountsFeed, settingsFeed, b.gethAccountManager, b.transactor, b.config,
|
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,
|
b.pendingTracker,
|
||||||
walletFeed,
|
walletFeed,
|
||||||
b.httpServer,
|
b.httpServer,
|
||||||
|
|
|
@ -9,50 +9,41 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/multiformats/go-multibase"
|
"github.com/multiformats/go-multibase"
|
||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/wealdtech/go-ens/v3"
|
|
||||||
"github.com/wealdtech/go-multicodec"
|
"github.com/wealdtech/go-multicodec"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum"
|
"github.com/ethereum/go-ethereum"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
"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"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/status-im/status-go/account"
|
"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/registrar"
|
||||||
"github.com/status-im/status-go/contracts/resolver"
|
"github.com/status-im/status-go/contracts/resolver"
|
||||||
"github.com/status-im/status-go/contracts/snt"
|
"github.com/status-im/status-go/contracts/snt"
|
||||||
"github.com/status-im/status-go/logutils"
|
"github.com/status-im/status-go/logutils"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
"github.com/status-im/status-go/rpc"
|
"github.com/status-im/status-go/rpc"
|
||||||
|
"github.com/status-im/status-go/services/ens/ensresolver"
|
||||||
"github.com/status-im/status-go/services/utils"
|
"github.com/status-im/status-go/services/utils"
|
||||||
wcommon "github.com/status-im/status-go/services/wallet/common"
|
wcommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/transactions"
|
"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 {
|
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{
|
return &API{
|
||||||
contractMaker: &contracts.ContractMaker{
|
ensResolver: ensresolver.NewEnsResolver(rpcClient),
|
||||||
RPCClient: rpcClient,
|
|
||||||
},
|
|
||||||
accountsManager: accountsManager,
|
accountsManager: accountsManager,
|
||||||
pendingTracker: pendingTracker,
|
pendingTracker: pendingTracker,
|
||||||
config: config,
|
config: config,
|
||||||
addrPerChain: make(map[uint64]common.Address),
|
|
||||||
db: NewEnsDatabase(appDb),
|
db: NewEnsDatabase(appDb),
|
||||||
|
|
||||||
quit: make(chan struct{}),
|
|
||||||
timeSource: timeSource,
|
timeSource: timeSource,
|
||||||
syncUserDetailFunc: syncUserDetailFunc,
|
syncUserDetailFunc: syncUserDetailFunc,
|
||||||
}
|
}
|
||||||
|
@ -68,17 +59,11 @@ type URI struct {
|
||||||
type syncUsernameDetail func(context.Context, *UsernameDetail) error
|
type syncUsernameDetail func(context.Context, *UsernameDetail) error
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
contractMaker *contracts.ContractMaker
|
ensResolver *ensresolver.EnsResolver
|
||||||
accountsManager *account.GethManager
|
accountsManager *account.GethManager
|
||||||
pendingTracker *transactions.PendingTxTracker
|
pendingTracker *transactions.PendingTxTracker
|
||||||
config *params.NodeConfig
|
config *params.NodeConfig
|
||||||
|
|
||||||
addrPerChain map[uint64]common.Address
|
|
||||||
addrPerChainMutex sync.Mutex
|
|
||||||
|
|
||||||
quitOnce sync.Once
|
|
||||||
quit chan struct{}
|
|
||||||
|
|
||||||
db *Database
|
db *Database
|
||||||
syncUserDetailFunc *syncUsernameDetail
|
syncUserDetailFunc *syncUsernameDetail
|
||||||
|
|
||||||
|
@ -86,9 +71,11 @@ type API struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) Stop() {
|
func (api *API) Stop() {
|
||||||
api.quitOnce.Do(func() {
|
api.ensResolver.Stop()
|
||||||
close(api.quit)
|
}
|
||||||
})
|
|
||||||
|
func (api *API) EnsResolver() *ensresolver.EnsResolver {
|
||||||
|
return api.ensResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) unixTime() uint64 {
|
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) {
|
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) {
|
func (api *API) Resolver(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
|
||||||
err := ValidateENSUsername(username)
|
return api.ensResolver.Resolver(ctx, chainID, 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) GetName(ctx context.Context, chainID uint64, address common.Address) (string, error) {
|
func (api *API) GetName(ctx context.Context, chainID uint64, address common.Address) (string, error) {
|
||||||
backend, err := api.contractMaker.RPCClient.EthClient(chainID)
|
return api.ensResolver.GetName(ctx, chainID, address)
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return ens.ReverseResolve(backend, address)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) OwnerOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
|
func (api *API) OwnerOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
|
||||||
err := ValidateENSUsername(username)
|
return api.ensResolver.OwnerOf(ctx, chainID, 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) ContentHash(ctx context.Context, chainID uint64, username string) ([]byte, error) {
|
func (api *API) ContentHash(ctx context.Context, chainID uint64, username string) ([]byte, error) {
|
||||||
err := ValidateENSUsername(username)
|
return api.ensResolver.ContentHash(ctx, chainID, 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) PublicKeyOf(ctx context.Context, chainID uint64, username string) (string, error) {
|
func (api *API) PublicKeyOf(ctx context.Context, chainID uint64, username string) (string, error) {
|
||||||
err := ValidateENSUsername(username)
|
return api.ensResolver.PublicKeyOf(ctx, chainID, 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) AddressOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
|
func (api *API) AddressOf(ctx context.Context, chainID uint64, username string) (*common.Address, error) {
|
||||||
err := ValidateENSUsername(username)
|
return api.ensResolver.AddressOf(ctx, chainID, 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) ExpireAt(ctx context.Context, chainID uint64, username string) (string, error) {
|
func (api *API) ExpireAt(ctx context.Context, chainID uint64, username string) (string, error) {
|
||||||
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
|
return api.ensResolver.ExpireAt(ctx, chainID, username)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) Price(ctx context.Context, chainID uint64) (string, error) {
|
func (api *API) Price(ctx context.Context, chainID uint64) (string, error) {
|
||||||
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
|
return api.ensResolver.Price(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
registrar, err := api.contractMaker.NewUsernameRegistrar(chainID, registryAddr)
|
signFn := utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password)
|
||||||
if err != nil {
|
tx, err := api.ensResolver.Release(ctx, chainID, registryAddr, txArgs, username, signFn)
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
txOpts := txArgs.ToTransactOpts(utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password))
|
|
||||||
tx, err := registrar.Release(txOpts, UsernameToLabel(username))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -370,7 +173,7 @@ func (api *API) Release(ctx context.Context, chainID uint64, txArgs transactions
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.Remove(ctx, chainID, fullDomainName(username))
|
err = api.Remove(ctx, chainID, wcommon.FullDomainName(username))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logutils.ZapLogger().Warn("Releasing ENS username: transaction successful, but removing failed")
|
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
|
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) {
|
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))
|
registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := registrarABI.Pack("release", UsernameToLabel(username))
|
data, err := registrarABI.Pack("release", wcommon.UsernameToLabel(username))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
@ -402,6 +208,9 @@ func (api *API) ReleasePrepareTxCallMsg(ctx context.Context, chainID uint64, txA
|
||||||
}, nil
|
}, 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) {
|
func (api *API) ReleasePrepareTx(ctx context.Context, chainID uint64, txArgs transactions.SendTxArgs, username string) (interface{}, error) {
|
||||||
callMsg, err := api.ReleasePrepareTxCallMsg(ctx, chainID, txArgs, username)
|
callMsg, err := api.ReleasePrepareTxCallMsg(ctx, chainID, txArgs, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -411,76 +220,30 @@ func (api *API) ReleasePrepareTx(ctx context.Context, chainID uint64, txArgs tra
|
||||||
return toCallArg(callMsg), nil
|
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) {
|
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 {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := registrarABI.Pack("release", UsernameToLabel(username))
|
return api.ensResolver.ReleaseEstimate(ctx, chainID, callMsg)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
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 {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
priceHex, err := api.Price(ctx, chainID)
|
signFn := utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password)
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
tx, err := api.ensResolver.Register(ctx, chainID, registryAddr, txArgs, username, pubkey, signFn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -499,7 +262,7 @@ func (api *API) Register(ctx context.Context, chainID uint64, txArgs transaction
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.Add(ctx, chainID, fullDomainName(username))
|
err = api.Add(ctx, chainID, wcommon.FullDomainName(username))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logutils.ZapLogger().Warn("Registering ENS username: transaction successful, but adding failed")
|
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
|
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) {
|
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)
|
priceHex, err := api.Price(ctx, chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -520,8 +286,8 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
x, y := ExtractCoordinates(pubkey)
|
x, y := wcommon.ExtractCoordinates(pubkey)
|
||||||
extraData, err := registrarABI.Pack("register", UsernameToLabel(username), common.Address(txArgs.From), x, y)
|
extraData, err := registrarABI.Pack("register", wcommon.UsernameToLabel(username), common.Address(txArgs.From), x, y)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
@ -531,7 +297,7 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
registryAddr, err := api.usernameRegistrarAddr(ctx, chainID)
|
registryAddr, err := api.ensResolver.GetRegistrarAddress(ctx, chainID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
@ -553,6 +319,9 @@ func (api *API) RegisterPrepareTxCallMsg(ctx context.Context, chainID uint64, tx
|
||||||
}, nil
|
}, 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) {
|
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)
|
callMsg, err := api.RegisterPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -562,43 +331,29 @@ func (api *API) RegisterPrepareTx(ctx context.Context, chainID uint64, txArgs tr
|
||||||
return toCallArg(callMsg), nil
|
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) {
|
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)
|
callMsg, err := api.RegisterPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
return api.ensResolver.RegisterEstimate(ctx, chainID, callMsg)
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return estimate + 1000, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
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)
|
resolverAddress, err := api.Resolver(ctx, chainID, username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
resolver, err := api.contractMaker.NewPublicResolver(chainID, resolverAddress)
|
signFn := utils.GetSigner(chainID, api.accountsManager, api.config.KeyStoreDir, txArgs.From, password)
|
||||||
if err != nil {
|
tx, err := api.ensResolver.SetPubKey(ctx, chainID, resolverAddress, txArgs, username, pubkey, signFn)
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -617,7 +372,7 @@ func (api *API) SetPubKey(ctx context.Context, chainID uint64, txArgs transactio
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = api.Add(ctx, chainID, fullDomainName(username))
|
err = api.Add(ctx, chainID, wcommon.FullDomainName(username))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logutils.ZapLogger().Warn("Registering ENS username: transaction successful, but adding failed")
|
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
|
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) {
|
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 {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
x, y := ExtractCoordinates(pubkey)
|
x, y := wcommon.ExtractCoordinates(pubkey)
|
||||||
|
|
||||||
resolverABI, err := abi.JSON(strings.NewReader(resolver.PublicResolverABI))
|
resolverABI, err := abi.JSON(strings.NewReader(resolver.PublicResolverABI))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
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 {
|
if err != nil {
|
||||||
return ethereum.CallMsg{}, err
|
return ethereum.CallMsg{}, err
|
||||||
}
|
}
|
||||||
|
@ -656,6 +414,9 @@ func (api *API) SetPubKeyPrepareTxCallMsg(ctx context.Context, chainID uint64, t
|
||||||
}, nil
|
}, 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) {
|
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)
|
callMsg, err := api.SetPubKeyPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -665,22 +426,16 @@ func (api *API) SetPubKeyPrepareTx(ctx context.Context, chainID uint64, txArgs t
|
||||||
return toCallArg(callMsg), nil
|
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) {
|
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)
|
callMsg, err := api.SetPubKeyPrepareTxCallMsg(ctx, chainID, txArgs, username, pubkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
estimate, err := ethClient.EstimateGas(ctx, callMsg)
|
return api.ensResolver.SetPubKeyEstimate(ctx, chainID, callMsg)
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return estimate + 1000, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) ResourceURL(ctx context.Context, chainID uint64, username string) (*URI, error) {
|
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
|
return arg
|
||||||
}
|
}
|
||||||
|
|
||||||
func fullDomainName(username string) string {
|
|
||||||
return username + "." + StatusDomain
|
|
||||||
}
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
|
||||||
}
|
|
|
@ -13,6 +13,7 @@ type MultiTransactionIDType int64
|
||||||
const (
|
const (
|
||||||
NoMultiTransactionID = MultiTransactionIDType(0)
|
NoMultiTransactionID = MultiTransactionIDType(0)
|
||||||
HexAddressLength = 42
|
HexAddressLength = 42
|
||||||
|
StatusDomain = "stateofus.eth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ChainID uint64
|
type ChainID uint64
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/status-im/status-go/contracts/ierc20"
|
"github.com/status-im/status-go/contracts/ierc20"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,3 +32,51 @@ func GetTokenIdFromSymbol(symbol string) (*big.Int, error) {
|
||||||
}
|
}
|
||||||
return id, nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/status-im/status-go/errors"
|
"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"
|
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/fees"
|
||||||
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
"github.com/status-im/status-go/services/wallet/router/pathprocessor"
|
||||||
|
@ -103,7 +102,7 @@ func (i *RouteInputParams) Validate() error {
|
||||||
return ErrENSSetPubKeyRequiresUsernameAndPubKey
|
return ErrENSSetPubKeyRequiresUsernameAndPubKey
|
||||||
}
|
}
|
||||||
|
|
||||||
if ens.ValidateENSUsername(i.Username) != nil {
|
if walletCommon.ValidateENSUsername(i.Username) != nil {
|
||||||
return ErrENSSetPubKeyInvalidUsername
|
return ErrENSSetPubKeyInvalidUsername
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/status-im/status-go/contracts/resolver"
|
"github.com/status-im/status-go/contracts/resolver"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/rpc"
|
"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"
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/transactions"
|
"github.com/status-im/status-go/transactions"
|
||||||
)
|
)
|
||||||
|
@ -22,16 +22,16 @@ import (
|
||||||
type ENSPublicKeyProcessor struct {
|
type ENSPublicKeyProcessor struct {
|
||||||
contractMaker *contracts.ContractMaker
|
contractMaker *contracts.ContractMaker
|
||||||
transactor transactions.TransactorIface
|
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{
|
return &ENSPublicKeyProcessor{
|
||||||
contractMaker: &contracts.ContractMaker{
|
contractMaker: &contracts.ContractMaker{
|
||||||
RPCClient: rpcClient,
|
RPCClient: rpcClient,
|
||||||
},
|
},
|
||||||
transactor: transactor,
|
transactor: transactor,
|
||||||
ensService: ensService,
|
ensResolver: ensResolver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ func (s *ENSPublicKeyProcessor) PackTxInputData(params ProcessorInputParams) ([]
|
||||||
return []byte{}, createENSPublicKeyErrorResponse(err)
|
return []byte{}, createENSPublicKeyErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
x, y := ens.ExtractCoordinates(params.PublicKey)
|
x, y := walletCommon.ExtractCoordinates(params.PublicKey)
|
||||||
return resolverABI.Pack("setPubkey", ens.NameHash(params.Username), x, y)
|
return resolverABI.Pack("setPubkey", walletCommon.NameHash(params.Username), x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) {
|
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) {
|
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 {
|
if err != nil {
|
||||||
return common.Address{}, createENSPublicKeyErrorResponse(err)
|
return common.Address{}, createENSPublicKeyErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"github.com/status-im/status-go/contracts/snt"
|
"github.com/status-im/status-go/contracts/snt"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/rpc"
|
"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"
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/transactions"
|
"github.com/status-im/status-go/transactions"
|
||||||
)
|
)
|
||||||
|
@ -24,16 +24,16 @@ import (
|
||||||
type ENSRegisterProcessor struct {
|
type ENSRegisterProcessor struct {
|
||||||
contractMaker *contracts.ContractMaker
|
contractMaker *contracts.ContractMaker
|
||||||
transactor transactions.TransactorIface
|
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{
|
return &ENSRegisterProcessor{
|
||||||
contractMaker: &contracts.ContractMaker{
|
contractMaker: &contracts.ContractMaker{
|
||||||
RPCClient: rpcClient,
|
RPCClient: rpcClient,
|
||||||
},
|
},
|
||||||
transactor: transactor,
|
transactor: transactor,
|
||||||
ensService: ensService,
|
ensResolver: ensResolver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ func (s *ENSRegisterProcessor) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ENSRegisterProcessor) GetPriceForRegisteringEnsName(chainID uint64) (*big.Int, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, createENSRegisterProcessorErrorResponse(err)
|
return nil, createENSRegisterProcessorErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
@ -78,8 +78,8 @@ func (s *ENSRegisterProcessor) PackTxInputData(params ProcessorInputParams) ([]b
|
||||||
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
x, y := ens.ExtractCoordinates(params.PublicKey)
|
x, y := walletCommon.ExtractCoordinates(params.PublicKey)
|
||||||
extraData, err := registrarABI.Pack("register", ens.UsernameToLabel(params.Username), params.FromAddr, x, y)
|
extraData, err := registrarABI.Pack("register", walletCommon.UsernameToLabel(params.Username), params.FromAddr, x, y)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ func (s *ENSRegisterProcessor) PackTxInputData(params ProcessorInputParams) ([]b
|
||||||
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
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 {
|
if err != nil {
|
||||||
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
return []byte{}, createENSRegisterProcessorErrorResponse(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/status-im/status-go/contracts/registrar"
|
"github.com/status-im/status-go/contracts/registrar"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/rpc"
|
"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"
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
"github.com/status-im/status-go/transactions"
|
"github.com/status-im/status-go/transactions"
|
||||||
)
|
)
|
||||||
|
@ -22,16 +22,16 @@ import (
|
||||||
type ENSReleaseProcessor struct {
|
type ENSReleaseProcessor struct {
|
||||||
contractMaker *contracts.ContractMaker
|
contractMaker *contracts.ContractMaker
|
||||||
transactor transactions.TransactorIface
|
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{
|
return &ENSReleaseProcessor{
|
||||||
contractMaker: &contracts.ContractMaker{
|
contractMaker: &contracts.ContractMaker{
|
||||||
RPCClient: rpcClient,
|
RPCClient: rpcClient,
|
||||||
},
|
},
|
||||||
transactor: transactor,
|
transactor: transactor,
|
||||||
ensService: ensService,
|
ensResolver: ensResolver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ func (s *ENSReleaseProcessor) PackTxInputData(params ProcessorInputParams) ([]by
|
||||||
}
|
}
|
||||||
|
|
||||||
name := getNameFromEnsUsername(params.Username)
|
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) {
|
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) {
|
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 {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
"github.com/status-im/status-go/logutils"
|
"github.com/status-im/status-go/logutils"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
"github.com/status-im/status-go/rpc"
|
"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/async"
|
||||||
"github.com/status-im/status-go/services/wallet/collectibles"
|
"github.com/status-im/status-go/services/wallet/collectibles"
|
||||||
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||||
|
@ -68,7 +67,6 @@ type Router struct {
|
||||||
marketManager *market.Manager
|
marketManager *market.Manager
|
||||||
collectiblesService *collectibles.Service
|
collectiblesService *collectibles.Service
|
||||||
collectiblesManager *collectibles.Manager
|
collectiblesManager *collectibles.Manager
|
||||||
ensService *ens.Service
|
|
||||||
feesManager *fees.FeeManager
|
feesManager *fees.FeeManager
|
||||||
pathProcessors map[string]pathprocessor.PathProcessor
|
pathProcessors map[string]pathprocessor.PathProcessor
|
||||||
scheduler *async.Scheduler
|
scheduler *async.Scheduler
|
||||||
|
@ -88,7 +86,7 @@ type Router struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRouter(rpcClient *rpc.Client, transactor *transactions.Transactor, tokenManager *token.Manager, marketManager *market.Manager,
|
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)
|
processors := make(map[string]pathprocessor.PathProcessor)
|
||||||
|
|
||||||
return &Router{
|
return &Router{
|
||||||
|
@ -97,7 +95,6 @@ func NewRouter(rpcClient *rpc.Client, transactor *transactions.Transactor, token
|
||||||
marketManager: marketManager,
|
marketManager: marketManager,
|
||||||
collectiblesService: collectibles,
|
collectiblesService: collectibles,
|
||||||
collectiblesManager: collectiblesManager,
|
collectiblesManager: collectiblesManager,
|
||||||
ensService: ensService,
|
|
||||||
feesManager: &fees.FeeManager{
|
feesManager: &fees.FeeManager{
|
||||||
RPCClient: rpcClient,
|
RPCClient: rpcClient,
|
||||||
},
|
},
|
||||||
|
|
|
@ -101,7 +101,7 @@ func setupRouter(t *testing.T) (*Router, func()) {
|
||||||
}
|
}
|
||||||
client, _ := rpc.NewClient(config)
|
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)
|
transfer := pathprocessor.NewTransferProcessor(nil, nil)
|
||||||
router.AddPathProcessor(transfer)
|
router.AddPathProcessor(transfer)
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
protocolCommon "github.com/status-im/status-go/protocol/common"
|
protocolCommon "github.com/status-im/status-go/protocol/common"
|
||||||
"github.com/status-im/status-go/rpc"
|
"github.com/status-im/status-go/rpc"
|
||||||
"github.com/status-im/status-go/server"
|
"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/activity"
|
||||||
"github.com/status-im/status-go/services/wallet/balance"
|
"github.com/status-im/status-go/services/wallet/balance"
|
||||||
"github.com/status-im/status-go/services/wallet/blockchainstate"
|
"github.com/status-im/status-go/services/wallet/blockchainstate"
|
||||||
|
@ -59,7 +59,7 @@ func NewService(
|
||||||
gethManager *account.GethManager,
|
gethManager *account.GethManager,
|
||||||
transactor *transactions.Transactor,
|
transactor *transactions.Transactor,
|
||||||
config *params.NodeConfig,
|
config *params.NodeConfig,
|
||||||
ens *ens.Service,
|
ensResolver *ensresolver.EnsResolver,
|
||||||
pendingTxManager *transactions.PendingTxTracker,
|
pendingTxManager *transactions.PendingTxTracker,
|
||||||
feed *event.Feed,
|
feed *event.Feed,
|
||||||
mediaServer *server.MediaServer,
|
mediaServer *server.MediaServer,
|
||||||
|
@ -190,8 +190,8 @@ func NewService(
|
||||||
}
|
}
|
||||||
|
|
||||||
router := router.NewRouter(rpcClient, transactor, tokenManager, marketManager, collectibles,
|
router := router.NewRouter(rpcClient, transactor, tokenManager, marketManager, collectibles,
|
||||||
collectiblesManager, ens)
|
collectiblesManager)
|
||||||
pathProcessors := buildPathProcessors(rpcClient, transactor, tokenManager, ens, featureFlags)
|
pathProcessors := buildPathProcessors(rpcClient, transactor, tokenManager, ensResolver, featureFlags)
|
||||||
for _, processor := range pathProcessors {
|
for _, processor := range pathProcessors {
|
||||||
router.AddPathProcessor(processor)
|
router.AddPathProcessor(processor)
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,6 @@ func NewService(
|
||||||
gethManager: gethManager,
|
gethManager: gethManager,
|
||||||
marketManager: marketManager,
|
marketManager: marketManager,
|
||||||
transactor: transactor,
|
transactor: transactor,
|
||||||
ens: ens,
|
|
||||||
feed: feed,
|
feed: feed,
|
||||||
signals: signals,
|
signals: signals,
|
||||||
reader: reader,
|
reader: reader,
|
||||||
|
@ -235,7 +234,7 @@ func buildPathProcessors(
|
||||||
rpcClient *rpc.Client,
|
rpcClient *rpc.Client,
|
||||||
transactor *transactions.Transactor,
|
transactor *transactions.Transactor,
|
||||||
tokenManager *token.Manager,
|
tokenManager *token.Manager,
|
||||||
ens *ens.Service,
|
ensResolver *ensresolver.EnsResolver,
|
||||||
featureFlags *protocolCommon.FeatureFlags,
|
featureFlags *protocolCommon.FeatureFlags,
|
||||||
) []pathprocessor.PathProcessor {
|
) []pathprocessor.PathProcessor {
|
||||||
ret := make([]pathprocessor.PathProcessor, 0)
|
ret := make([]pathprocessor.PathProcessor, 0)
|
||||||
|
@ -261,13 +260,13 @@ func buildPathProcessors(
|
||||||
paraswap := pathprocessor.NewSwapParaswapProcessor(rpcClient, transactor, tokenManager)
|
paraswap := pathprocessor.NewSwapParaswapProcessor(rpcClient, transactor, tokenManager)
|
||||||
ret = append(ret, paraswap)
|
ret = append(ret, paraswap)
|
||||||
|
|
||||||
ensRegister := pathprocessor.NewENSRegisterProcessor(rpcClient, transactor, ens)
|
ensRegister := pathprocessor.NewENSRegisterProcessor(rpcClient, transactor, ensResolver)
|
||||||
ret = append(ret, ensRegister)
|
ret = append(ret, ensRegister)
|
||||||
|
|
||||||
ensRelease := pathprocessor.NewENSReleaseProcessor(rpcClient, transactor, ens)
|
ensRelease := pathprocessor.NewENSReleaseProcessor(rpcClient, transactor, ensResolver)
|
||||||
ret = append(ret, ensRelease)
|
ret = append(ret, ensRelease)
|
||||||
|
|
||||||
ensPublicKey := pathprocessor.NewENSPublicKeyProcessor(rpcClient, transactor, ens)
|
ensPublicKey := pathprocessor.NewENSPublicKeyProcessor(rpcClient, transactor, ensResolver)
|
||||||
ret = append(ret, ensPublicKey)
|
ret = append(ret, ensPublicKey)
|
||||||
|
|
||||||
buyStickers := pathprocessor.NewStickersBuyProcessor(rpcClient, transactor)
|
buyStickers := pathprocessor.NewStickersBuyProcessor(rpcClient, transactor)
|
||||||
|
@ -294,7 +293,6 @@ type Service struct {
|
||||||
collectibles *collectibles.Service
|
collectibles *collectibles.Service
|
||||||
gethManager *account.GethManager
|
gethManager *account.GethManager
|
||||||
transactor *transactions.Transactor
|
transactor *transactions.Transactor
|
||||||
ens *ens.Service
|
|
||||||
feed *event.Feed
|
feed *event.Feed
|
||||||
signals *walletevent.SignalsTransmitter
|
signals *walletevent.SignalsTransmitter
|
||||||
reader *Reader
|
reader *Reader
|
||||||
|
@ -399,7 +397,3 @@ func (s *Service) GetCollectiblesService() *collectibles.Service {
|
||||||
func (s *Service) GetCollectiblesManager() *collectibles.Manager {
|
func (s *Service) GetCollectiblesManager() *collectibles.Manager {
|
||||||
return s.collectiblesManager
|
return s.collectiblesManager
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) GetEnsService() *ens.Service {
|
|
||||||
return s.ens
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue