status-go/services/connector/commands/switch_ethereum_chain.go
Mikhail Rogachev 4c6ca00520
Feat: implement connector service for browser plugin (#5433)
* feat(connector)_: impl `eth_requestAccounts` for browser plugin

* feat(connector)_: add impl for `wallet_switchEthereumChain` and `eth_chainId`

* feat(connector)_: add impl for `eth_sendTransaction`

* feat(connector)_: add a signal and an endpoint for wallet ui side

* chore_: refactor connector tests

* feat(connector)_: impl `eth_requestAccounts` with signal

* chore(connector)_: Add test, covering full transaction flow

And polish impl & test for connector endpoints

* fix(connector)_: temporary allow all origins for ws connection

* chore_: review fixes

* fix(connector)_: make user select chain id for dApp

* fix(connector)_: add requestID and fine tune endpoints

* chore(connector)_: naming fixes and tests improvments
2024-07-18 17:30:10 +02:00

95 lines
1.9 KiB
Go

package commands
import (
"database/sql"
"errors"
"slices"
persistence "github.com/status-im/status-go/services/connector/database"
walletCommon "github.com/status-im/status-go/services/wallet/common"
)
// errors
var (
ErrNoActiveNetworks = errors.New("no active networks")
ErrUnsupportedNetwork = errors.New("unsupported network")
ErrNoChainIDParamsFound = errors.New("no chain id in params found")
)
type SwitchEthereumChainCommand struct {
NetworkManager NetworkManagerInterface
Db *sql.DB
}
func (r *RPCRequest) getChainID() (uint64, error) {
if r.Params == nil || len(r.Params) == 0 {
return 0, ErrEmptyRPCParams
}
switch v := r.Params[0].(type) {
case float64:
return uint64(v), nil
case int:
return uint64(v), nil
case int64:
return uint64(v), nil
case uint64:
return v, nil
default:
return 0, ErrNoChainIDParamsFound
}
}
func (c *SwitchEthereumChainCommand) getSupportedChainIDs() ([]uint64, error) {
activeNetworks, err := c.NetworkManager.GetActiveNetworks()
if err != nil {
return nil, err
}
if len(activeNetworks) < 1 {
return nil, ErrNoActiveNetworks
}
chainIDs := make([]uint64, len(activeNetworks))
for i, network := range activeNetworks {
chainIDs[i] = network.ChainID
}
return chainIDs, nil
}
func (c *SwitchEthereumChainCommand) Execute(request RPCRequest) (string, error) {
err := request.Validate()
if err != nil {
return "", err
}
requestedChainID, err := request.getChainID()
if err != nil {
return "", err
}
chainIDs, err := c.getSupportedChainIDs()
if err != nil {
return "", err
}
if !slices.Contains(chainIDs, requestedChainID) {
return "", ErrUnsupportedNetwork
}
dApp, err := persistence.SelectDAppByUrl(c.Db, request.URL)
if err != nil {
return "", err
}
dApp.ChainID = requestedChainID
err = persistence.UpsertDApp(c.Db, dApp)
if err != nil {
return "", err
}
return walletCommon.ChainID(dApp.ChainID).String(), nil
}