mirror of
https://github.com/status-im/status-go.git
synced 2025-02-21 03:08:29 +00:00
feat(network)_: implement (de)activable networks
This commit is contained in:
parent
115fe9f73b
commit
c862b563c0
@ -92,6 +92,8 @@ func mainnet(proxyHost, stageName string) params.Network {
|
||||
Layer: 1,
|
||||
Enabled: true,
|
||||
RelatedChainID: SepoliaChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,10 +116,10 @@ func sepolia(proxyHost, stageName string) params.Network {
|
||||
|
||||
return params.Network{
|
||||
ChainID: chainID,
|
||||
ChainName: "Mainnet",
|
||||
ChainName: "Sepolia",
|
||||
RpcProviders: rpcProviders,
|
||||
BlockExplorerURL: "https://sepolia.etherscan.io/",
|
||||
IconURL: "network/Network=Ethereum",
|
||||
IconURL: "network/Network=Ethereum-test",
|
||||
ChainColor: "#627EEA",
|
||||
ShortName: "eth",
|
||||
NativeCurrencyName: "Ether",
|
||||
@ -127,6 +129,8 @@ func sepolia(proxyHost, stageName string) params.Network {
|
||||
Layer: 1,
|
||||
Enabled: true,
|
||||
RelatedChainID: MainnetChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,6 +166,8 @@ func optimism(proxyHost, stageName string) params.Network {
|
||||
Layer: 2,
|
||||
Enabled: true,
|
||||
RelatedChainID: OptimismSepoliaChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,10 +190,10 @@ func optimismSepolia(proxyHost, stageName string) params.Network {
|
||||
|
||||
return params.Network{
|
||||
ChainID: chainID,
|
||||
ChainName: "Optimism",
|
||||
ChainName: "Optimism Sepolia",
|
||||
RpcProviders: rpcProviders,
|
||||
BlockExplorerURL: "https://sepolia-optimism.etherscan.io/",
|
||||
IconURL: "network/Network=Optimism",
|
||||
IconURL: "network/Network=Optimism-test",
|
||||
ChainColor: "#E90101",
|
||||
ShortName: "oeth",
|
||||
NativeCurrencyName: "Ether",
|
||||
@ -197,6 +203,8 @@ func optimismSepolia(proxyHost, stageName string) params.Network {
|
||||
Layer: 2,
|
||||
Enabled: false,
|
||||
RelatedChainID: OptimismChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,6 +240,8 @@ func arbitrum(proxyHost, stageName string) params.Network {
|
||||
Layer: 2,
|
||||
Enabled: true,
|
||||
RelatedChainID: ArbitrumSepoliaChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,10 +264,10 @@ func arbitrumSepolia(proxyHost, stageName string) params.Network {
|
||||
|
||||
return params.Network{
|
||||
ChainID: chainID,
|
||||
ChainName: "Arbitrum",
|
||||
ChainName: "Arbitrum Sepolia",
|
||||
RpcProviders: rpcProviders,
|
||||
BlockExplorerURL: "https://sepolia-explorer.arbitrum.io/",
|
||||
IconURL: "network/Network=Arbitrum",
|
||||
IconURL: "network/Network=Arbitrum-test",
|
||||
ChainColor: "#51D0F0",
|
||||
ShortName: "arb1",
|
||||
NativeCurrencyName: "Ether",
|
||||
@ -267,6 +277,8 @@ func arbitrumSepolia(proxyHost, stageName string) params.Network {
|
||||
Layer: 2,
|
||||
Enabled: false,
|
||||
RelatedChainID: ArbitrumChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,6 +314,8 @@ func base(proxyHost, stageName string) params.Network {
|
||||
Layer: 2,
|
||||
Enabled: true,
|
||||
RelatedChainID: BaseSepoliaChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,10 +338,10 @@ func baseSepolia(proxyHost, stageName string) params.Network {
|
||||
|
||||
return params.Network{
|
||||
ChainID: chainID,
|
||||
ChainName: "Base",
|
||||
ChainName: "Base Sepolia",
|
||||
RpcProviders: rpcProviders,
|
||||
BlockExplorerURL: "https://sepolia.basescan.org/",
|
||||
IconURL: "network/Network=Base",
|
||||
IconURL: "network/Network=Base-test",
|
||||
ChainColor: "#0052FF",
|
||||
ShortName: "base",
|
||||
NativeCurrencyName: "Ether",
|
||||
@ -337,6 +351,8 @@ func baseSepolia(proxyHost, stageName string) params.Network {
|
||||
Layer: 2,
|
||||
Enabled: false,
|
||||
RelatedChainID: BaseChainID,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
ALTER TABLE networks ADD COLUMN is_active BOOLEAN DEFAULT true;
|
@ -0,0 +1 @@
|
||||
ALTER TABLE networks ADD COLUMN is_deactivatable BOOLEAN DEFAULT true;
|
@ -81,6 +81,8 @@ type Network struct {
|
||||
ShortName string `json:"shortName" validate:"omitempty,min=1"`
|
||||
TokenOverrides []TokenOverride `json:"tokenOverrides" validate:"omitempty,dive"`
|
||||
RelatedChainID uint64 `json:"relatedChainId" validate:"omitempty"`
|
||||
IsActive bool `json:"isActive"`
|
||||
IsDeactivatable bool `json:"isDeactivatable"`
|
||||
}
|
||||
|
||||
func (n *Network) DeepCopy() Network {
|
||||
|
@ -31,6 +31,7 @@ type NetworksPersistenceInterface interface {
|
||||
DeleteAllNetworks() error
|
||||
|
||||
GetRpcPersistence() RpcProvidersPersistenceInterface
|
||||
SetActive(chainID uint64, active bool) error
|
||||
SetEnabled(chainID uint64, enabled bool) error
|
||||
}
|
||||
|
||||
@ -60,7 +61,7 @@ func (n *NetworksPersistence) getNetworksWithoutProviders(onlyEnabled bool, chai
|
||||
q := sq.Select(
|
||||
"chain_id", "chain_name", "rpc_url", "fallback_url",
|
||||
"block_explorer_url", "icon_url", "native_currency_name", "native_currency_symbol", "native_currency_decimals",
|
||||
"is_test", "layer", "enabled", "chain_color", "short_name", "related_chain_id",
|
||||
"is_test", "layer", "enabled", "chain_color", "short_name", "related_chain_id", "is_active", "is_deactivatable",
|
||||
).
|
||||
From("networks").
|
||||
OrderBy("chain_id ASC")
|
||||
@ -90,7 +91,7 @@ func (n *NetworksPersistence) getNetworksWithoutProviders(onlyEnabled bool, chai
|
||||
&network.ChainID, &network.ChainName, &network.RPCURL, &network.FallbackURL,
|
||||
&network.BlockExplorerURL, &network.IconURL, &network.NativeCurrencyName, &network.NativeCurrencySymbol,
|
||||
&network.NativeCurrencyDecimals, &network.IsTest, &network.Layer, &network.Enabled, &network.ChainColor,
|
||||
&network.ShortName, &relatedChainID,
|
||||
&network.ShortName, &relatedChainID, &network.IsActive, &network.IsDeactivatable,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -228,21 +229,21 @@ func (n *NetworksPersistence) upsertNetwork(network *params.Network) error {
|
||||
Columns(
|
||||
"chain_id", "chain_name", "rpc_url", "original_rpc_url", "fallback_url", "original_fallback_url",
|
||||
"block_explorer_url", "icon_url", "native_currency_name", "native_currency_symbol", "native_currency_decimals",
|
||||
"is_test", "layer", "enabled", "chain_color", "short_name", "related_chain_id",
|
||||
"is_test", "layer", "enabled", "chain_color", "short_name", "related_chain_id", "is_active", "is_deactivatable",
|
||||
).
|
||||
Values(
|
||||
network.ChainID, network.ChainName, network.RPCURL, network.OriginalRPCURL, network.FallbackURL, network.OriginalFallbackURL,
|
||||
network.BlockExplorerURL, network.IconURL, network.NativeCurrencyName, network.NativeCurrencySymbol, network.NativeCurrencyDecimals,
|
||||
network.IsTest, network.Layer, network.Enabled, network.ChainColor, network.ShortName, network.RelatedChainID,
|
||||
network.IsTest, network.Layer, network.Enabled, network.ChainColor, network.ShortName, network.RelatedChainID, network.IsActive, network.IsDeactivatable,
|
||||
).
|
||||
Suffix("ON CONFLICT(chain_id) DO UPDATE SET " +
|
||||
"chain_name = excluded.chain_name, rpc_url = excluded.rpc_url, original_rpc_url = excluded.original_rpc_url, " +
|
||||
"fallback_url = excluded.fallback_url, original_fallback_url = excluded.original_fallback_url, " +
|
||||
"block_explorer_url = excluded.block_explorer_url, icon_url = excluded.icon_url, " +
|
||||
"native_currency_name = excluded.native_currency_name, native_currency_symbol = excluded.native_currency_symbol, " +
|
||||
"native_currency_decimals = excluded.native_currency_decimals, is_test = excluded.is_test, " +
|
||||
"layer = excluded.layer, enabled = excluded.enabled, chain_color = excluded.chain_color, " +
|
||||
"short_name = excluded.short_name, related_chain_id = excluded.related_chain_id")
|
||||
Suffix("ON CONFLICT(chain_id) DO UPDATE SET "+
|
||||
"chain_name = excluded.chain_name, rpc_url = excluded.rpc_url, original_rpc_url = excluded.original_rpc_url, "+
|
||||
"fallback_url = excluded.fallback_url, original_fallback_url = excluded.original_fallback_url, "+
|
||||
"block_explorer_url = excluded.block_explorer_url, icon_url = excluded.icon_url, "+
|
||||
"native_currency_name = excluded.native_currency_name, native_currency_symbol = excluded.native_currency_symbol, "+
|
||||
"native_currency_decimals = excluded.native_currency_decimals, is_test = excluded.is_test, "+
|
||||
"layer = excluded.layer, enabled = excluded.enabled, chain_color = excluded.chain_color, "+
|
||||
"short_name = excluded.short_name, related_chain_id = excluded.related_chain_id, is_active = excluded.is_active", "is_deactivatable = excluded.is_deactivatable")
|
||||
|
||||
query, args, err := q.ToSql()
|
||||
if err != nil {
|
||||
@ -281,6 +282,25 @@ func (n *NetworksPersistence) DeleteNetwork(chainID uint64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetActive updates the active status of a network.
|
||||
func (n *NetworksPersistence) SetActive(chainID uint64, active bool) error {
|
||||
q := sq.Update("networks").
|
||||
Set("is_active", active).
|
||||
Where(sq.Eq{"chain_id": chainID})
|
||||
|
||||
query, args, err := q.ToSql()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to build update query: %w", err)
|
||||
}
|
||||
|
||||
_, err = n.db.Exec(query, args...)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to execute update query for chain_id %d: %w", chainID, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetEnabled updates the enabled status of a network.
|
||||
func (n *NetworksPersistence) SetEnabled(chainID uint64, enabled bool) error {
|
||||
q := sq.Update("networks").
|
||||
|
@ -196,6 +196,31 @@ func (s *NetworksPersistenceTestSuite) TestValidationForNetworksAndProviders() {
|
||||
s.Require().Len(allNetworks, 0, "No invalid networks should be saved")
|
||||
}
|
||||
|
||||
func (s *NetworksPersistenceTestSuite) TestSetActive() {
|
||||
network := testutil.CreateNetwork(api.OptimismChainID, "Optimism Mainnet", DefaultProviders(api.OptimismChainID))
|
||||
s.addAndVerifyNetworks([]*params.Network{network})
|
||||
|
||||
// Deactivate the network
|
||||
err := s.networksPersistence.SetActive(network.ChainID, false)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Verify the network is deactivated
|
||||
updatedNetwork, err := s.networksPersistence.GetNetworkByChainID(network.ChainID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(updatedNetwork, 1)
|
||||
s.Require().False(updatedNetwork[0].IsActive)
|
||||
|
||||
// Activate the network
|
||||
err = s.networksPersistence.SetActive(network.ChainID, true)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Verify the network is enabled
|
||||
updatedNetwork, err = s.networksPersistence.GetNetworkByChainID(network.ChainID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(updatedNetwork, 1)
|
||||
s.Require().True(updatedNetwork[0].IsActive)
|
||||
}
|
||||
|
||||
func (s *NetworksPersistenceTestSuite) TestSetEnabled() {
|
||||
network := testutil.CreateNetwork(api.OptimismChainID, "Optimism Mainnet", DefaultProviders(api.OptimismChainID))
|
||||
s.addAndVerifyNetworks([]*params.Network{network})
|
||||
|
12
rpc/network/errors.go
Normal file
12
rpc/network/errors.go
Normal file
@ -0,0 +1,12 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"github.com/status-im/status-go/errors"
|
||||
)
|
||||
|
||||
// Abbreviation `NET` for the error code stands for Networks
|
||||
var (
|
||||
ErrNetworkNotDeactivatable = &errors.ErrorResponse{Code: errors.ErrorCode("NET-001"), Details: "network is not deactivatable"}
|
||||
ErrActiveNetworksLimitReached = &errors.ErrorResponse{Code: errors.ErrorCode("NET-002"), Details: "maximum number of active networks reached"}
|
||||
ErrUnsupportedChainId = &errors.ErrorResponse{Code: errors.ErrorCode("NET-003"), Details: "chainID is not supported"}
|
||||
)
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-go/errors"
|
||||
"github.com/status-im/status-go/logutils"
|
||||
"github.com/status-im/status-go/multiaccounts/accounts"
|
||||
"github.com/status-im/status-go/params"
|
||||
@ -15,6 +16,9 @@ import (
|
||||
)
|
||||
|
||||
//go:generate mockgen -package=mock -source=network.go -destination=mock/network.go
|
||||
|
||||
const MaxActiveNetworks = 5
|
||||
|
||||
type ManagerInterface interface {
|
||||
InitEmbeddedNetworks(networks []params.Network) error
|
||||
|
||||
@ -30,6 +34,7 @@ type ManagerInterface interface {
|
||||
GetTestNetworksEnabled() (bool, error)
|
||||
|
||||
SetUserRpcProviders(chainID uint64, providers []params.RpcProvider) error
|
||||
SetActive(chainID uint64, active bool) error
|
||||
SetEnabled(chainID uint64, enabled bool) error
|
||||
}
|
||||
|
||||
@ -67,7 +72,7 @@ func NewManager(db *sql.DB) *Manager {
|
||||
// Init initializes the nets, merges them with existing ones, and wraps the operation in a transaction.
|
||||
// We should store the following information in the DB:
|
||||
// - User's RPC providers
|
||||
// - Enabled state of the network
|
||||
// - Enabled and Active state of the network
|
||||
// Embedded RPC providers should only be stored in memory
|
||||
func (nm *Manager) InitEmbeddedNetworks(embeddedNetworks []params.Network) error {
|
||||
if embeddedNetworks == nil {
|
||||
@ -84,7 +89,7 @@ func (nm *Manager) InitEmbeddedNetworks(embeddedNetworks []params.Network) error
|
||||
|
||||
currentNetworks, err := txNetworksPersistence.GetAllNetworks()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error fetching current networks: %w", err)
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("error fetching current networks: %w", err))
|
||||
}
|
||||
|
||||
// Create a map for quick access to current networks
|
||||
@ -93,12 +98,13 @@ func (nm *Manager) InitEmbeddedNetworks(embeddedNetworks []params.Network) error
|
||||
currentNetworskMap[currentNetwork.ChainID] = *currentNetwork
|
||||
}
|
||||
|
||||
// Keep user's rpc providers and enabled state
|
||||
// Keep user's rpc providers, enabled and active state
|
||||
var updatedNetworks []params.Network
|
||||
for _, newNetwork := range embeddedNetworks {
|
||||
if existingNetwork, exists := currentNetworskMap[newNetwork.ChainID]; exists {
|
||||
newNetwork.RpcProviders = networkhelper.GetUserProviders(existingNetwork.RpcProviders)
|
||||
newNetwork.Enabled = existingNetwork.Enabled
|
||||
newNetwork.IsActive = existingNetwork.IsActive
|
||||
} else {
|
||||
newNetwork.RpcProviders = networkhelper.GetUserProviders(newNetwork.RpcProviders)
|
||||
}
|
||||
@ -108,32 +114,32 @@ func (nm *Manager) InitEmbeddedNetworks(embeddedNetworks []params.Network) error
|
||||
// Use SetNetworks to replace all networks in the database without embedded RPC providers
|
||||
err = txNetworksPersistence.SetNetworks(updatedNetworks)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error setting networks: %w", err)
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("error setting networks: %w", err))
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetEmbeddedProviders returns embedded providers for a given chainID.
|
||||
func (nm *Manager) getEmbeddedProviders(chainID uint64) []params.RpcProvider {
|
||||
func (nm *Manager) getEmbeddedNetwork(chainID uint64) *params.Network {
|
||||
for _, network := range nm.embeddedNetworks {
|
||||
if network.ChainID == chainID {
|
||||
return networkhelper.GetEmbeddedProviders(network.RpcProviders)
|
||||
return &network
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setEmbeddedProviders adds embedded providers to a network.
|
||||
func (nm *Manager) setNetworkEmbeddedProviders(network *params.Network) {
|
||||
network.RpcProviders = networkhelper.ReplaceEmbeddedProviders(
|
||||
network.RpcProviders, nm.getEmbeddedProviders(network.ChainID))
|
||||
}
|
||||
|
||||
func (nm *Manager) setEmbeddedProviders(networks []*params.Network) {
|
||||
// Set fields that must be taken from embedded networks.
|
||||
func (nm *Manager) setEmbeddedFields(networks []*params.Network) {
|
||||
for _, network := range networks {
|
||||
nm.setNetworkEmbeddedProviders(network)
|
||||
embeddedNetwork := nm.getEmbeddedNetwork(network.ChainID)
|
||||
if embeddedNetwork != nil {
|
||||
network.IsDeactivatable = embeddedNetwork.IsDeactivatable
|
||||
// Append embedded providers to the user providers
|
||||
network.RpcProviders = networkhelper.ReplaceEmbeddedProviders(
|
||||
network.RpcProviders, embeddedNetwork.RpcProviders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,11 +152,15 @@ func (nm *Manager) networkWithoutEmbeddedProviders(network *params.Network) *par
|
||||
|
||||
// Upsert adds or updates a network, synchronizing RPC providers, wrapped in a transaction.
|
||||
func (nm *Manager) Upsert(network *params.Network) error {
|
||||
// New networks are deactivated by default. They are also always deactivatable.
|
||||
network.IsActive = false
|
||||
network.IsDeactivatable = true
|
||||
|
||||
return persistence.ExecuteWithinTransaction(nm.db, func(tx *sql.Tx) error {
|
||||
txNetworksPersistence := persistence.NewNetworksPersistence(tx)
|
||||
err := txNetworksPersistence.UpsertNetwork(nm.networkWithoutEmbeddedProviders(network))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upsert network: %w", err)
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("failed to upsert network: %w", err))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -162,7 +172,7 @@ func (nm *Manager) Delete(chainID uint64) error {
|
||||
txNetworksPersistence := persistence.NewNetworksPersistence(tx)
|
||||
err := txNetworksPersistence.DeleteNetwork(chainID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete network: %w", err)
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("failed to delete network: %w", err))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -174,11 +184,39 @@ func (nm *Manager) SetUserRpcProviders(chainID uint64, userProviders []params.Rp
|
||||
return rpcPersistence.SetRpcProviders(chainID, networkhelper.GetUserProviders(userProviders))
|
||||
}
|
||||
|
||||
// SetActive updates the active status of a network
|
||||
func (nm *Manager) SetActive(chainID uint64, active bool) error {
|
||||
network := nm.Find(chainID)
|
||||
if network == nil {
|
||||
return ErrUnsupportedChainId
|
||||
}
|
||||
|
||||
// If trying to deactivate, check that it's deactivatable
|
||||
if !active && !network.IsDeactivatable {
|
||||
return ErrNetworkNotDeactivatable
|
||||
}
|
||||
|
||||
// If trying to activate, check that we haven't reached the limit for the corresponding mode
|
||||
activeNetworks, err := nm.getActiveNetworksForTestMode(network.IsTest)
|
||||
if err != nil {
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("failed to get active networks: %w", err))
|
||||
}
|
||||
if active && len(activeNetworks) >= MaxActiveNetworks {
|
||||
return ErrActiveNetworksLimitReached
|
||||
}
|
||||
|
||||
err = nm.networkPersistence.SetActive(chainID, active)
|
||||
if err != nil {
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("failed to persist active status: %w", err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetEnabled updates the enabled status of a network
|
||||
func (nm *Manager) SetEnabled(chainID uint64, enabled bool) error {
|
||||
err := nm.networkPersistence.SetEnabled(chainID, enabled)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set enabled status: %w", err)
|
||||
return errors.CreateErrorResponseFromError(fmt.Errorf("failed to set enabled status: %w", err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -191,7 +229,7 @@ func (nm *Manager) Find(chainID uint64) *params.Network {
|
||||
return nil
|
||||
}
|
||||
result := networks[0]
|
||||
nm.setNetworkEmbeddedProviders(result)
|
||||
nm.setEmbeddedFields([]*params.Network{result})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -201,7 +239,7 @@ func (nm *Manager) GetAll() ([]*params.Network, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nm.setEmbeddedProviders(networks)
|
||||
nm.setEmbeddedFields(networks)
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
@ -211,7 +249,7 @@ func (nm *Manager) Get(onlyEnabled bool) ([]*params.Network, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nm.setEmbeddedProviders(networks)
|
||||
nm.setEmbeddedFields(networks)
|
||||
return networks, nil
|
||||
}
|
||||
|
||||
@ -225,13 +263,7 @@ func (nm *Manager) GetTestNetworksEnabled() (result bool, err error) {
|
||||
return nm.accountsDB.GetTestNetworksEnabled()
|
||||
}
|
||||
|
||||
// GetActiveNetworks returns active networks based on the current mode (test/prod).
|
||||
func (nm *Manager) GetActiveNetworks() ([]*params.Network, error) {
|
||||
areTestNetworksEnabled, err := nm.GetTestNetworksEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (nm *Manager) getActiveNetworksForTestMode(areTestNetworksEnabled bool) ([]*params.Network, error) {
|
||||
networks, err := nm.GetAll()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -239,7 +271,7 @@ func (nm *Manager) GetActiveNetworks() ([]*params.Network, error) {
|
||||
|
||||
var availableNetworks []*params.Network
|
||||
for _, network := range networks {
|
||||
if network.IsTest == areTestNetworksEnabled {
|
||||
if network.IsActive && network.IsTest == areTestNetworksEnabled {
|
||||
availableNetworks = append(availableNetworks, network)
|
||||
}
|
||||
}
|
||||
@ -247,6 +279,16 @@ func (nm *Manager) GetActiveNetworks() ([]*params.Network, error) {
|
||||
return availableNetworks, nil
|
||||
}
|
||||
|
||||
// GetActiveNetworks returns active networks based on the current mode (test/prod).
|
||||
func (nm *Manager) GetActiveNetworks() ([]*params.Network, error) {
|
||||
areTestNetworksEnabled, err := nm.GetTestNetworksEnabled()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nm.getActiveNetworksForTestMode(areTestNetworksEnabled)
|
||||
}
|
||||
|
||||
func (nm *Manager) GetCombinedNetworks() ([]*CombinedNetwork, error) {
|
||||
networks, err := nm.Get(false)
|
||||
if err != nil {
|
||||
|
@ -44,7 +44,22 @@ func (s *NetworkManagerTestSuite) SetupTest() {
|
||||
*testutil.CreateNetwork(api.OptimismChainID, "Optimistic Ethereum", []params.RpcProvider{
|
||||
testutil.CreateProvider(api.OptimismChainID, "Infura Optimism", params.UserProviderType, true, "https://optimism.infura.io"),
|
||||
}),
|
||||
*testutil.CreateNetwork(api.OptimismSepoliaChainID, "Optimistic Sepolia", []params.RpcProvider{
|
||||
testutil.CreateProvider(api.OptimismSepoliaChainID, "Infura Optimism Sepolia", params.UserProviderType, true, "https://optimism-sepolia.infura.io"),
|
||||
}),
|
||||
*testutil.CreateNetwork(api.BaseChainID, "Base", []params.RpcProvider{
|
||||
testutil.CreateProvider(api.BaseChainID, "Infura Base", params.UserProviderType, true, "https://base.infura.io"),
|
||||
}),
|
||||
*testutil.CreateNetwork(api.BaseSepoliaChainID, "Base Sepolia", []params.RpcProvider{
|
||||
testutil.CreateProvider(api.BaseSepoliaChainID, "Infura Base Sepolia", params.UserProviderType, true, "https://base-sepolia.infura.io"),
|
||||
}),
|
||||
}
|
||||
// Make "Ethereum Mainnet" network not deactivatable
|
||||
initNetworks[0].IsDeactivatable = false
|
||||
|
||||
// Make "Optimistic Ethereum" network inactive by default
|
||||
initNetworks[2].IsActive = false
|
||||
|
||||
err = persistence.SetNetworks(initNetworks)
|
||||
s.Require().NoError(err)
|
||||
s.assertDbNetworks(initNetworks)
|
||||
@ -259,10 +274,15 @@ func (s *NetworkManagerTestSuite) TestLegacyFieldPopulationWithoutUserProviders(
|
||||
}
|
||||
|
||||
func (s *NetworkManagerTestSuite) TestUpsertNetwork() {
|
||||
chainID := uint64(999)
|
||||
|
||||
// Create a new network
|
||||
newNetwork := testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
|
||||
testutil.CreateProvider(api.MainnetChainID, "Infura Mainnet", params.EmbeddedProxyProviderType, true, "https://mainnet.infura.io"),
|
||||
newNetwork := testutil.CreateNetwork(chainID, "Ethereum Mainnet", []params.RpcProvider{
|
||||
testutil.CreateProvider(chainID, "Infura Mainnet", params.EmbeddedProxyProviderType, true, "https://mainnet.infura.io"),
|
||||
})
|
||||
// Check that these values are overriden for upserted networks
|
||||
newNetwork.IsActive = true
|
||||
newNetwork.IsDeactivatable = false
|
||||
|
||||
// Upsert the network
|
||||
err := s.manager.Upsert(newNetwork)
|
||||
@ -270,9 +290,76 @@ func (s *NetworkManagerTestSuite) TestUpsertNetwork() {
|
||||
|
||||
// Verify the network was upserted without embedded providers
|
||||
persistence := db.NewNetworksPersistence(s.db)
|
||||
chainID := api.MainnetChainID
|
||||
networks, err := persistence.GetNetworks(false, &chainID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(networks, 1)
|
||||
s.Require().Len(networkhelper.GetEmbeddedProviders(networks[0].RpcProviders), 0)
|
||||
s.Require().False(networks[0].IsActive)
|
||||
s.Require().True(networks[0].IsDeactivatable)
|
||||
}
|
||||
|
||||
func (s *NetworkManagerTestSuite) TestSetActive() {
|
||||
var err error
|
||||
var n *params.Network
|
||||
|
||||
// Check that the "Base" network is active by default
|
||||
n = s.manager.Find(api.BaseChainID)
|
||||
s.Require().NotNil(n)
|
||||
s.True(n.IsActive)
|
||||
|
||||
// Set the "Base" network to inactive
|
||||
err = s.manager.SetActive(api.BaseChainID, false)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Verify the network was set to inactive
|
||||
n = s.manager.Find(api.BaseChainID)
|
||||
s.Require().NotNil(n)
|
||||
s.False(n.IsActive)
|
||||
|
||||
// Set the "Base" network to active
|
||||
err = s.manager.SetActive(api.BaseChainID, true)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Verify the network was set to active
|
||||
n = s.manager.Find(api.BaseChainID)
|
||||
s.Require().NotNil(n)
|
||||
s.True(n.IsActive)
|
||||
}
|
||||
|
||||
func (s *NetworkManagerTestSuite) TestSetActiveNotDeactivatable() {
|
||||
var err error
|
||||
var n *params.Network
|
||||
|
||||
// Try to set Ethereum Mainnet to inactive (should fail)
|
||||
err = s.manager.SetActive(api.MainnetChainID, false)
|
||||
s.Require().Error(err)
|
||||
|
||||
// Verify the network was not set to inactive
|
||||
n = s.manager.Find(api.MainnetChainID)
|
||||
s.Require().NotNil(n)
|
||||
s.True(n.IsActive)
|
||||
}
|
||||
|
||||
func (s *NetworkManagerTestSuite) TestSetActiveMaxNumberOfActiveNetworks() {
|
||||
var err error
|
||||
var n *params.Network
|
||||
|
||||
// Check that we're at the limit of active networks
|
||||
activeNetworks, err := s.manager.GetActiveNetworks()
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(activeNetworks, network.MaxActiveNetworks)
|
||||
|
||||
// Check that the "Optimistic Ethereum" network is inactive by default
|
||||
n = s.manager.Find(api.OptimismChainID)
|
||||
s.Require().NotNil(n)
|
||||
s.False(n.IsActive)
|
||||
|
||||
// Try to set the "Optimistic Ethereum" network to active (should fail due to number networks active)
|
||||
err = s.manager.SetActive(api.OptimismChainID, true)
|
||||
s.Require().Error(err)
|
||||
|
||||
// Verify the network was not set to active
|
||||
n = s.manager.Find(api.OptimismChainID)
|
||||
s.Require().NotNil(n)
|
||||
s.False(n.IsActive)
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ func CreateNetwork(chainID uint64, chainName string, providers []params.RpcProvi
|
||||
ShortName: "eth",
|
||||
RelatedChainID: api.OptimismSepoliaChainID,
|
||||
RpcProviders: providers,
|
||||
IsActive: true,
|
||||
IsDeactivatable: true,
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +73,8 @@ func CompareNetworks(t require.TestingT, expected, actual *params.Network) {
|
||||
require.Equal(t, expected.ChainColor, actual.ChainColor)
|
||||
require.Equal(t, expected.ShortName, actual.ShortName)
|
||||
require.Equal(t, expected.RelatedChainID, actual.RelatedChainID)
|
||||
require.Equal(t, expected.IsActive, actual.IsActive)
|
||||
require.Equal(t, expected.IsDeactivatable, actual.IsDeactivatable)
|
||||
}
|
||||
|
||||
// Helper function to compare lists of providers
|
||||
|
@ -395,31 +395,47 @@ func (api *API) SearchCollections(ctx context.Context, chainID wcommon.ChainID,
|
||||
Collectibles API End
|
||||
*/
|
||||
|
||||
// @deprecated: Custom networks not currently supported. Change settings using specific API functions.
|
||||
func (api *API) AddEthereumChain(ctx context.Context, network params.Network) error {
|
||||
logutils.ZapLogger().Debug("call to AddEthereumChain")
|
||||
return api.s.rpcClient.NetworkManager.Upsert(&network)
|
||||
}
|
||||
|
||||
// @deprecated: Custom networks not currently supported. Change settings using specific API functions.
|
||||
func (api *API) DeleteEthereumChain(ctx context.Context, chainID uint64) error {
|
||||
logutils.ZapLogger().Debug("call to DeleteEthereumChain")
|
||||
return api.s.rpcClient.NetworkManager.Delete(chainID)
|
||||
}
|
||||
|
||||
func (api *API) SetChainUserRpcProviders(ctx context.Context, chainID uint64, rpcProviders []params.RpcProvider) error {
|
||||
logutils.ZapLogger().Debug("call to SetChainUserRpcProviders")
|
||||
return api.s.rpcClient.NetworkManager.SetUserRpcProviders(chainID, rpcProviders)
|
||||
}
|
||||
|
||||
// Active chains are the ones that are available for selection across the whole application
|
||||
// Providers are expected to be accessed only for active chains.
|
||||
func (api *API) SetChainActive(ctx context.Context, chainID uint64, active bool) error {
|
||||
logutils.ZapLogger().Debug("call to SetChainActive")
|
||||
return api.s.rpcClient.NetworkManager.SetActive(chainID, active)
|
||||
}
|
||||
|
||||
// Enabled chains are the ones taken into account when displaying balances, collectibles, activity, etc.
|
||||
func (api *API) SetChainEnabled(ctx context.Context, chainID uint64, enabled bool) error {
|
||||
logutils.ZapLogger().Debug("call to SetChainEnabled")
|
||||
return api.s.rpcClient.NetworkManager.SetEnabled(chainID, enabled)
|
||||
}
|
||||
|
||||
func (api *API) DeleteEthereumChain(ctx context.Context, chainID uint64) error {
|
||||
logutils.ZapLogger().Debug("call to DeleteEthereumChain")
|
||||
return api.s.rpcClient.NetworkManager.Delete(chainID)
|
||||
}
|
||||
|
||||
// @deprecated: Combined networks are not used anymore, use GetFlatEthereumChains instead
|
||||
func (api *API) GetEthereumChains(ctx context.Context) ([]*network.CombinedNetwork, error) {
|
||||
logutils.ZapLogger().Debug("call to GetEthereumChains")
|
||||
return api.s.rpcClient.NetworkManager.GetCombinedNetworks()
|
||||
}
|
||||
|
||||
func (api *API) GetFlatEthereumChains(ctx context.Context) ([]*params.Network, error) {
|
||||
logutils.ZapLogger().Debug("call to GetFlatEthereumChains")
|
||||
return api.s.rpcClient.NetworkManager.GetAll()
|
||||
}
|
||||
|
||||
// @deprecated
|
||||
func (api *API) FetchPrices(ctx context.Context, symbols []string, currencies []string) (map[string]map[string]float64, error) {
|
||||
logutils.ZapLogger().Debug("call to FetchPrices")
|
||||
|
Loading…
x
Reference in New Issue
Block a user