Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(config)_: rpc providers configuration #6151

Merged
merged 5 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions api/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1579,12 +1579,12 @@ func TestWalletConfigOnLoginAccount(t *testing.T) {
}

require.Equal(t, b.config.WalletConfig.InfuraAPIKey, infuraToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[mainnetChainID], alchemyEthereumMainnetToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[sepoliaChainID], alchemyEthereumSepoliaToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[arbitrumChainID], alchemyArbitrumMainnetToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID], alchemyArbitrumSepoliaToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[optimismChainID], alchemyOptimismMainnetToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[optimismSepoliaChainID], alchemyOptimismSepoliaToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[MainnetChainID], alchemyEthereumMainnetToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[SepoliaChainID], alchemyEthereumSepoliaToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[ArbitrumChainID], alchemyArbitrumMainnetToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[ArbitrumSepoliaChainID], alchemyArbitrumSepoliaToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[OptimismChainID], alchemyOptimismMainnetToken)
require.Equal(t, b.config.WalletConfig.AlchemyAPIKeys[OptimismSepoliaChainID], alchemyOptimismSepoliaToken)
require.Equal(t, b.config.WalletConfig.RaribleMainnetAPIKey, raribleMainnetAPIKey)
require.Equal(t, b.config.WalletConfig.RaribleTestnetAPIKey, raribleTestnetAPIKey)

Expand Down
38 changes: 19 additions & 19 deletions api/default_networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
)

const (
mainnetChainID uint64 = 1
sepoliaChainID uint64 = 11155111
optimismChainID uint64 = 10
optimismSepoliaChainID uint64 = 11155420
arbitrumChainID uint64 = 42161
arbitrumSepoliaChainID uint64 = 421614
MainnetChainID uint64 = 1
SepoliaChainID uint64 = 11155111
OptimismChainID uint64 = 10
OptimismSepoliaChainID uint64 = 11155420
ArbitrumChainID uint64 = 42161
ArbitrumSepoliaChainID uint64 = 421614
sntSymbol = "SNT"
sttSymbol = "STT"
)
Expand All @@ -24,7 +24,7 @@ var ganacheTokenAddress = common.HexToAddress("0x8571Ddc46b10d31EF963aF49b6C7799

func mainnet(stageName string) params.Network {
return params.Network{
ChainID: mainnetChainID,
ChainID: MainnetChainID,
ChainName: "Mainnet",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/ethereum/mainnet/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/ethereum/mainnet/", stageName),
Expand All @@ -41,13 +41,13 @@ func mainnet(stageName string) params.Network {
IsTest: false,
Layer: 1,
Enabled: true,
RelatedChainID: sepoliaChainID,
RelatedChainID: SepoliaChainID,
}
}

func sepolia(stageName string) params.Network {
return params.Network{
ChainID: sepoliaChainID,
ChainID: SepoliaChainID,
ChainName: "Mainnet",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/ethereum/sepolia/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/ethereum/sepolia/", stageName),
Expand All @@ -64,13 +64,13 @@ func sepolia(stageName string) params.Network {
IsTest: true,
Layer: 1,
Enabled: true,
RelatedChainID: mainnetChainID,
RelatedChainID: MainnetChainID,
}
}

func optimism(stageName string) params.Network {
return params.Network{
ChainID: optimismChainID,
ChainID: OptimismChainID,
ChainName: "Optimism",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/optimism/mainnet/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/optimism/mainnet/", stageName),
Expand All @@ -87,13 +87,13 @@ func optimism(stageName string) params.Network {
IsTest: false,
Layer: 2,
Enabled: true,
RelatedChainID: optimismSepoliaChainID,
RelatedChainID: OptimismSepoliaChainID,
}
}

func optimismSepolia(stageName string) params.Network {
return params.Network{
ChainID: optimismSepoliaChainID,
ChainID: OptimismSepoliaChainID,
ChainName: "Optimism",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/optimism/sepolia/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/optimism/sepolia/", stageName),
Expand All @@ -110,13 +110,13 @@ func optimismSepolia(stageName string) params.Network {
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: optimismChainID,
RelatedChainID: OptimismChainID,
}
}

func arbitrum(stageName string) params.Network {
return params.Network{
ChainID: arbitrumChainID,
ChainID: ArbitrumChainID,
ChainName: "Arbitrum",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/arbitrum/mainnet/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/arbitrum/mainnet/", stageName),
Expand All @@ -133,13 +133,13 @@ func arbitrum(stageName string) params.Network {
IsTest: false,
Layer: 2,
Enabled: true,
RelatedChainID: arbitrumSepoliaChainID,
RelatedChainID: ArbitrumSepoliaChainID,
}
}

func arbitrumSepolia(stageName string) params.Network {
return params.Network{
ChainID: arbitrumSepoliaChainID,
ChainID: ArbitrumSepoliaChainID,
ChainName: "Arbitrum",
DefaultRPCURL: fmt.Sprintf("https://%s.api.status.im/nodefleet/arbitrum/sepolia/", stageName),
DefaultFallbackURL: fmt.Sprintf("https://%s.api.status.im/infura/arbitrum/sepolia/", stageName),
Expand All @@ -156,7 +156,7 @@ func arbitrumSepolia(stageName string) params.Network {
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: arbitrumChainID,
RelatedChainID: ArbitrumChainID,
}
}

Expand Down Expand Up @@ -204,7 +204,7 @@ func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) [
if request.GanacheURL != "" {
n.RPCURL = request.GanacheURL
n.FallbackURL = request.GanacheURL
if n.ChainID == mainnetChainID {
if n.ChainID == MainnetChainID {
n.TokenOverrides = []params.TokenOverride{
mainnetGanacheTokenOverrides,
}
Expand Down
14 changes: 7 additions & 7 deletions api/default_networks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ func TestBuildDefaultNetworks(t *testing.T) {
for _, n := range actualNetworks {
var err error
switch n.ChainID {
case mainnetChainID:
case sepoliaChainID:
case optimismChainID:
case optimismSepoliaChainID:
case arbitrumChainID:
case arbitrumSepoliaChainID:
case MainnetChainID:
case SepoliaChainID:
case OptimismChainID:
case OptimismSepoliaChainID:
case ArbitrumChainID:
case ArbitrumSepoliaChainID:
default:
err = errors.Errorf("unexpected chain id: %d", n.ChainID)
}
Expand Down Expand Up @@ -70,7 +70,7 @@ func TestBuildDefaultNetworksGanache(t *testing.T) {
require.True(t, strings.Contains(n.FallbackURL, ganacheURL))
}

require.Equal(t, mainnetChainID, actualNetworks[0].ChainID)
require.Equal(t, MainnetChainID, actualNetworks[0].ChainID)

require.NotNil(t, actualNetworks[0].TokenOverrides)
require.Len(t, actualNetworks[0].TokenOverrides, 1)
Expand Down
12 changes: 6 additions & 6 deletions api/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,22 +198,22 @@ func buildWalletConfig(request *requests.WalletSecretsConfig, statusProxyEnabled
}

if request.AlchemyEthereumMainnetToken != "" {
walletConfig.AlchemyAPIKeys[mainnetChainID] = request.AlchemyEthereumMainnetToken
walletConfig.AlchemyAPIKeys[MainnetChainID] = request.AlchemyEthereumMainnetToken
}
if request.AlchemyEthereumSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[sepoliaChainID] = request.AlchemyEthereumSepoliaToken
walletConfig.AlchemyAPIKeys[SepoliaChainID] = request.AlchemyEthereumSepoliaToken
}
if request.AlchemyArbitrumMainnetToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumChainID] = request.AlchemyArbitrumMainnetToken
walletConfig.AlchemyAPIKeys[ArbitrumChainID] = request.AlchemyArbitrumMainnetToken
}
if request.AlchemyArbitrumSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken
walletConfig.AlchemyAPIKeys[ArbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken
}
if request.AlchemyOptimismMainnetToken != "" {
walletConfig.AlchemyAPIKeys[optimismChainID] = request.AlchemyOptimismMainnetToken
walletConfig.AlchemyAPIKeys[OptimismChainID] = request.AlchemyOptimismMainnetToken
}
if request.AlchemyOptimismSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[optimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken
walletConfig.AlchemyAPIKeys[OptimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken
}
if request.StatusProxyMarketUser != "" {
walletConfig.StatusProxyMarketUser = request.StatusProxyMarketUser
Expand Down
13 changes: 13 additions & 0 deletions appdatabase/migrations/sql/1733400346_add_rpc_providers.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS rpc_providers (
friofry marked this conversation as resolved.
Show resolved Hide resolved
id INTEGER PRIMARY KEY AUTOINCREMENT, -- Unique provider ID (sorting)
chain_id INTEGER NOT NULL CHECK (chain_id > 0), -- Chain ID for the network
name TEXT NOT NULL CHECK (LENGTH(name) > 0), -- Provider name
url TEXT NOT NULL CHECK (LENGTH(url) > 0), -- Provider URL
enable_rps_limiter BOOLEAN NOT NULL DEFAULT FALSE, -- Enable RPS limiter
type TEXT NOT NULL DEFAULT 'user', -- Provider type: embedded-proxy, embedded-direct, user
enabled BOOLEAN NOT NULL DEFAULT TRUE, -- Whether the provider is active or not
auth_type TEXT NOT NULL DEFAULT 'no-auth', -- Authentication type: no-auth, basic-auth, token-auth
auth_login TEXT, -- BasicAuth login (nullable)
auth_password TEXT, -- Password for BasicAuth (nullable)
auth_token TEXT -- Token for TokenAuth (nullable)
);
34 changes: 2 additions & 32 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"go.uber.org/zap"
validator "gopkg.in/go-playground/validator.v9"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/p2p/discv5"
"github.com/ethereum/go-ethereum/params"

Expand Down Expand Up @@ -482,7 +481,7 @@ type NodeConfig struct {
// (persistent storage of user's mailserver records).
MailserversConfig MailserversConfig

// Web3ProviderConfig extra configuration for provider.Service
// Web3ProviderConfig extra configuration for provider.Service.
// (desktop provider API)
Web3ProviderConfig Web3ProviderConfig

Expand Down Expand Up @@ -514,35 +513,6 @@ type NodeConfig struct {
ProcessBackedupMessages bool
}

type TokenOverride struct {
Symbol string `json:"symbol"`
Address common.Address `json:"address"`
}

type Network struct {
ChainID uint64 `json:"chainId"`
ChainName string `json:"chainName"`
DefaultRPCURL string `json:"defaultRpcUrl"` // proxy rpc url
DefaultFallbackURL string `json:"defaultFallbackURL"` // proxy fallback url
DefaultFallbackURL2 string `json:"defaultFallbackURL2"` // second proxy fallback url
RPCURL string `json:"rpcUrl"`
OriginalRPCURL string `json:"originalRpcUrl"`
FallbackURL string `json:"fallbackURL"`
OriginalFallbackURL string `json:"originalFallbackURL"`
BlockExplorerURL string `json:"blockExplorerUrl,omitempty"`
IconURL string `json:"iconUrl,omitempty"`
NativeCurrencyName string `json:"nativeCurrencyName,omitempty"`
NativeCurrencySymbol string `json:"nativeCurrencySymbol,omitempty"`
NativeCurrencyDecimals uint64 `json:"nativeCurrencyDecimals"`
IsTest bool `json:"isTest"`
Layer uint64 `json:"layer"`
Enabled bool `json:"enabled"`
ChainColor string `json:"chainColor"`
ShortName string `json:"shortName"`
TokenOverrides []TokenOverride `json:"tokenOverrides"`
RelatedChainID uint64 `json:"relatedChainId"`
}

// WalletConfig extra configuration for wallet.Service.
type WalletConfig struct {
Enabled bool
Expand Down Expand Up @@ -598,7 +568,7 @@ type MailserversConfig struct {
Enabled bool
}

// ProviderConfig extra configuration for provider.Service
// ProviderAuthConfig extra configuration for provider.Service
friofry marked this conversation as resolved.
Show resolved Hide resolved
type Web3ProviderConfig struct {
Enabled bool
}
Expand Down
95 changes: 95 additions & 0 deletions params/network_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package params

import "github.com/ethereum/go-ethereum/common"

// RpcProviderAuthType defines the different types of authentication for RPC providers
type RpcProviderAuthType string

const (
NoAuth RpcProviderAuthType = "no-auth" // No authentication
BasicAuth RpcProviderAuthType = "basic-auth" // HTTP Header "Authorization: Basic base64(username:password)"
TokenAuth RpcProviderAuthType = "token-auth" // URL Token-based authentication "https://api.example.com/YOUR_TOKEN"
)

// RpcProviderType defines the type of RPC provider
type RpcProviderType string

const (
EmbeddedProxyProviderType RpcProviderType = "embedded-proxy" // Proxy-based RPC provider
EmbeddedDirectProviderType RpcProviderType = "embedded-direct" // Direct RPC provider
UserProviderType RpcProviderType = "user" // User-defined RPC provider
)

// RpcProvider represents an RPC provider configuration with various options
type RpcProvider struct {
ID int64 `json:"id" validate:"omitempty"` // Auto-increment ID (for sorting order)
ChainID uint64 `json:"chainId" validate:"required,gt=0"` // Chain ID of the network
Name string `json:"name" validate:"required,min=1"` // Provider name for identification
URL string `json:"url" validate:"required,url"` // Current Provider URL
EnableRPSLimiter bool `json:"enableRpsLimiter"` // Enable RPC rate limiting for this provider
Type RpcProviderType `json:"type" validate:"required,oneof=embedded-proxy embedded-direct user"`
Enabled bool `json:"enabled"` // Whether the provider is enabled
// Authentication
AuthType RpcProviderAuthType `json:"authType" validate:"required,oneof=no-auth basic-auth token-auth"` // Type of authentication
AuthLogin string `json:"authLogin" validate:"omitempty,min=1"` // Login for BasicAuth (empty string if not used)
AuthPassword string `json:"authPassword" validate:"omitempty,min=1"` // Password for BasicAuth (empty string if not used)
AuthToken string `json:"authToken" validate:"omitempty,min=1"` // Token for TokenAuth (empty string if not used)
}

type TokenOverride struct {
Symbol string `json:"symbol"`
Address common.Address `json:"address"`
}

type Network struct {
ChainID uint64 `json:"chainId" validate:"required,gt=0"`
ChainName string `json:"chainName" validate:"required,min=1"`
RpcProviders []RpcProvider `json:"rpcProviders" validate:"dive,required"` // List of RPC providers, in the order in which they are accessed

// Deprecated fields (kept for backward compatibility)
// FIXME: Removal of deprecated fields in integration PR https://github.com/status-im/status-go/pull/6178
DefaultRPCURL string `json:"defaultRpcUrl" validate:"omitempty,url"` // Deprecated: proxy rpc url
DefaultFallbackURL string `json:"defaultFallbackURL" validate:"omitempty,url"` // Deprecated: proxy fallback url
DefaultFallbackURL2 string `json:"defaultFallbackURL2" validate:"omitempty,url"` // Deprecated: second proxy fallback url
RPCURL string `json:"rpcUrl" validate:"omitempty,url"` // Deprecated: direct rpc url
OriginalRPCURL string `json:"originalRpcUrl" validate:"omitempty,url"` // Deprecated: direct rpc url if user overrides RPCURL
FallbackURL string `json:"fallbackURL" validate:"omitempty,url"` // Deprecated
OriginalFallbackURL string `json:"originalFallbackURL" validate:"omitempty,url"` // Deprecated

BlockExplorerURL string `json:"blockExplorerUrl,omitempty" validate:"omitempty,url"`
IconURL string `json:"iconUrl,omitempty" validate:"omitempty"`
NativeCurrencyName string `json:"nativeCurrencyName,omitempty" validate:"omitempty,min=1"`
NativeCurrencySymbol string `json:"nativeCurrencySymbol,omitempty" validate:"omitempty,min=1"`
NativeCurrencyDecimals uint64 `json:"nativeCurrencyDecimals" validate:"omitempty"`
IsTest bool `json:"isTest"`
Layer uint64 `json:"layer" validate:"omitempty"`
Enabled bool `json:"enabled"`
ChainColor string `json:"chainColor" validate:"omitempty"`
ShortName string `json:"shortName" validate:"omitempty,min=1"`
TokenOverrides []TokenOverride `json:"tokenOverrides" validate:"omitempty,dive"`
RelatedChainID uint64 `json:"relatedChainId" validate:"omitempty"`
}

func newRpcProvider(chainID uint64, name, url string, enableRpsLimiter bool, providerType RpcProviderType) *RpcProvider {
return &RpcProvider{
ChainID: chainID,
Name: name,
URL: url,
EnableRPSLimiter: enableRpsLimiter,
Type: providerType,
Enabled: true,
AuthType: NoAuth,
}
}

func NewUserProvider(chainID uint64, name, url string, enableRpsLimiter bool) *RpcProvider {
return newRpcProvider(chainID, name, url, enableRpsLimiter, UserProviderType)
}

func NewProxyProvider(chainID uint64, name, url string, enableRpsLimiter bool) *RpcProvider {
return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedProxyProviderType)
}

func NewDirectProvider(chainID uint64, name, url string, enableRpsLimiter bool) *RpcProvider {
return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedDirectProviderType)
}
Loading
Loading