2024-07-18 15:30:10 +00:00
|
|
|
package commands
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"errors"
|
|
|
|
"slices"
|
2024-07-26 20:00:12 +00:00
|
|
|
"strconv"
|
2024-07-18 15:30:10 +00:00
|
|
|
|
2024-07-26 16:18:01 +00:00
|
|
|
"github.com/status-im/status-go/services/connector/chainutils"
|
2024-07-18 15:30:10 +00:00
|
|
|
persistence "github.com/status-im/status-go/services/connector/database"
|
|
|
|
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
2024-08-15 11:49:29 +00:00
|
|
|
"github.com/status-im/status-go/signal"
|
2024-07-18 15:30:10 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2024-07-26 20:00:12 +00:00
|
|
|
func hexStringToUint64(s string) (uint64, error) {
|
|
|
|
if len(s) > 2 && s[:2] == "0x" {
|
|
|
|
value, err := strconv.ParseUint(s[2:], 16, 64)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return value, nil
|
|
|
|
}
|
|
|
|
return 0, ErrUnsupportedNetwork
|
|
|
|
}
|
|
|
|
|
2024-07-18 15:30:10 +00:00
|
|
|
func (r *RPCRequest) getChainID() (uint64, error) {
|
|
|
|
if r.Params == nil || len(r.Params) == 0 {
|
|
|
|
return 0, ErrEmptyRPCParams
|
|
|
|
}
|
|
|
|
|
2024-07-26 20:00:12 +00:00
|
|
|
chainIds := r.Params[0].(map[string]interface{})
|
|
|
|
|
|
|
|
for _, chainId := range chainIds {
|
|
|
|
return hexStringToUint64(chainId.(string))
|
2024-07-18 15:30:10 +00:00
|
|
|
}
|
2024-07-26 20:00:12 +00:00
|
|
|
|
|
|
|
return 0, nil
|
2024-07-18 15:30:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *SwitchEthereumChainCommand) getSupportedChainIDs() ([]uint64, error) {
|
2024-07-26 16:18:01 +00:00
|
|
|
return chainutils.GetSupportedChainIDs(c.NetworkManager)
|
2024-07-18 15:30:10 +00:00
|
|
|
}
|
|
|
|
|
2024-08-02 07:43:31 +00:00
|
|
|
func (c *SwitchEthereumChainCommand) Execute(request RPCRequest) (interface{}, error) {
|
2024-07-18 15:30:10 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-07-26 20:00:12 +00:00
|
|
|
if dApp == nil {
|
|
|
|
return "", ErrDAppIsNotPermittedByUser
|
|
|
|
}
|
|
|
|
|
2024-07-18 15:30:10 +00:00
|
|
|
dApp.ChainID = requestedChainID
|
|
|
|
|
|
|
|
err = persistence.UpsertDApp(c.Db, dApp)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2024-07-26 20:00:12 +00:00
|
|
|
chainId, err := chainutils.GetHexChainID(walletCommon.ChainID(dApp.ChainID).String())
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2024-08-15 11:49:29 +00:00
|
|
|
signal.SendConnectorDAppChainIdSwitched(signal.ConnectorDAppChainIdSwitchedSignal{
|
|
|
|
URL: request.URL,
|
|
|
|
ChainId: chainId,
|
|
|
|
})
|
|
|
|
|
2024-07-26 20:00:12 +00:00
|
|
|
return chainId, nil
|
2024-07-18 15:30:10 +00:00
|
|
|
}
|