feat(rpc)_: integrate test.eth-rpc.status.im (#6329)

* feat(rpc)_: integrate test.eth-rpc.status.im

fixes #6327

* fix_: VerifyENSURL, VerifyTransactionURL initialization
* keep backward compatibility: restore support for the single-provider proxy
This commit is contained in:
Andrey Bocharnikov 2025-02-17 18:54:32 +04:00 committed by GitHub
parent 7e8a0bec00
commit 115fe9f73b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 210 additions and 96 deletions

View File

@ -2,6 +2,7 @@ package api
import ( import (
"fmt" "fmt"
"strings"
"github.com/status-im/status-go/params" "github.com/status-im/status-go/params"
"github.com/status-im/status-go/params/networkhelper" "github.com/status-im/status-go/params/networkhelper"
@ -19,6 +20,10 @@ const (
BaseSepoliaChainID uint64 = 84532 BaseSepoliaChainID uint64 = 84532
sntSymbol = "SNT" sntSymbol = "SNT"
sttSymbol = "STT" sttSymbol = "STT"
// Host suffixes for providers
SmartProxyHostSuffix = "eth-rpc.status.im"
ProxyHostSuffix = "api.status.im"
) )
// ProviderID represents the internal ID of a blockchain provider // ProviderID represents the internal ID of a blockchain provider
@ -26,6 +31,7 @@ type ProviderID = string
// Provider IDs // Provider IDs
const ( const (
StatusSmartProxy = "status-smart-proxy"
ProxyNodefleet = "proxy-nodefleet" ProxyNodefleet = "proxy-nodefleet"
ProxyInfura = "proxy-infura" ProxyInfura = "proxy-infura"
ProxyGrove = "proxy-grove" ProxyGrove = "proxy-grove"
@ -36,16 +42,32 @@ const (
DirectGrove = "direct-grove" DirectGrove = "direct-grove"
) )
// Direct proxy endpoint (1 endpoint per chain/network)
func proxyUrl(stageName, provider, chainName, networkName string) string { func proxyUrl(stageName, provider, chainName, networkName string) string {
return fmt.Sprintf("https://%s.api.status.im/%s/%s/%s/", stageName, provider, chainName, networkName) return fmt.Sprintf("https://%s.%s/%s/%s/%s/", stageName, ProxyHostSuffix, provider, chainName, networkName)
} }
func mainnet(stageName string) params.Network { // New eth-rpc-proxy endpoint (provider agnostic)
func getProxyHost(customUrl, stageName string) string {
if customUrl != "" {
return strings.TrimRight(customUrl, "/")
}
return fmt.Sprintf("https://%s.%s", stageName, SmartProxyHostSuffix)
}
// New eth-rpc-proxy endpoint with smart proxy URL
func smartProxyUrl(proxyHost, chainName, networkName string) string {
return fmt.Sprintf("%s/%s/%s/", proxyHost, chainName, networkName)
}
func mainnet(proxyHost, stageName string) params.Network {
const chainID = MainnetChainID const chainID = MainnetChainID
const chainName = "ethereum" const chainName = "ethereum"
const networkName = "mainnet" const networkName = "mainnet"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -73,12 +95,14 @@ func mainnet(stageName string) params.Network {
} }
} }
func sepolia(stageName string) params.Network { func sepolia(proxyHost, stageName string) params.Network {
const chainID = SepoliaChainID const chainID = SepoliaChainID
const chainName = "ethereum" const chainName = "ethereum"
const networkName = "sepolia" const networkName = "sepolia"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -106,12 +130,14 @@ func sepolia(stageName string) params.Network {
} }
} }
func optimism(stageName string) params.Network { func optimism(proxyHost, stageName string) params.Network {
const chainID = OptimismChainID const chainID = OptimismChainID
const chainName = "optimism" const chainName = "optimism"
const networkName = "mainnet" const networkName = "mainnet"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -139,12 +165,14 @@ func optimism(stageName string) params.Network {
} }
} }
func optimismSepolia(stageName string) params.Network { func optimismSepolia(proxyHost, stageName string) params.Network {
const chainID = OptimismSepoliaChainID const chainID = OptimismSepoliaChainID
const chainName = "optimism" const chainName = "optimism"
const networkName = "sepolia" const networkName = "sepolia"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -172,12 +200,14 @@ func optimismSepolia(stageName string) params.Network {
} }
} }
func arbitrum(stageName string) params.Network { func arbitrum(proxyHost, stageName string) params.Network {
const chainID = ArbitrumChainID const chainID = ArbitrumChainID
const chainName = "arbitrum" const chainName = "arbitrum"
const networkName = "mainnet" const networkName = "mainnet"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -205,12 +235,14 @@ func arbitrum(stageName string) params.Network {
} }
} }
func arbitrumSepolia(stageName string) params.Network { func arbitrumSepolia(proxyHost, stageName string) params.Network {
const chainID = ArbitrumSepoliaChainID const chainID = ArbitrumSepoliaChainID
const chainName = "arbitrum" const chainName = "arbitrum"
const networkName = "sepolia" const networkName = "sepolia"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -238,12 +270,14 @@ func arbitrumSepolia(stageName string) params.Network {
} }
} }
func base(stageName string) params.Network { func base(proxyHost, stageName string) params.Network {
const chainID = BaseChainID const chainID = BaseChainID
const chainName = "base" const chainName = "base"
const networkName = "mainnet" const networkName = "mainnet"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -270,12 +304,15 @@ func base(stageName string) params.Network {
RelatedChainID: BaseSepoliaChainID, RelatedChainID: BaseSepoliaChainID,
} }
} }
func baseSepolia(stageName string) params.Network {
func baseSepolia(proxyHost, stageName string) params.Network {
const chainID = BaseSepoliaChainID const chainID = BaseSepoliaChainID
const chainName = "base" const chainName = "base"
const networkName = "sepolia" const networkName = "sepolia"
rpcProviders := []params.RpcProvider{ rpcProviders := []params.RpcProvider{
// Smart proxy provider
*params.NewEthRpcProxyProvider(chainID, StatusSmartProxy, smartProxyUrl(proxyHost, chainName, networkName), false),
// Proxy providers // Proxy providers
*params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyNodefleet, proxyUrl(stageName, Nodefleet, chainName, networkName), false),
*params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false), *params.NewProxyProvider(chainID, ProxyInfura, proxyUrl(stageName, Infura, chainName, networkName), false),
@ -303,27 +340,48 @@ func baseSepolia(stageName string) params.Network {
} }
} }
func defaultNetworks(stageName string) []params.Network { func defaultNetworks(proxyHost, stageName string) []params.Network {
return []params.Network{ return []params.Network{
mainnet(stageName), mainnet(proxyHost, stageName),
sepolia(stageName), sepolia(proxyHost, stageName),
optimism(stageName), optimism(proxyHost, stageName),
optimismSepolia(stageName), optimismSepolia(proxyHost, stageName),
arbitrum(stageName), arbitrum(proxyHost, stageName),
arbitrumSepolia(stageName), arbitrumSepolia(proxyHost, stageName),
base(stageName), base(proxyHost, stageName),
baseSepolia(stageName), baseSepolia(proxyHost, stageName),
} }
} }
func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) []params.Network { func setRPCs(networks []params.Network, walletConfig *requests.WalletSecretsConfig) []params.Network {
authTokens := map[string]string{ authTokens := map[string]string{
"infura.io": request.InfuraToken, "infura.io": walletConfig.InfuraToken,
"grove.city": request.PoktToken, "grove.city": walletConfig.PoktToken,
} }
return networkhelper.OverrideDirectProvidersAuth(networks, authTokens) networks = networkhelper.OverrideDirectProvidersAuth(networks, authTokens)
// Apply auth for new smart proxy
hasSmartProxyCredentials := walletConfig.EthRpcProxyUser != "" && walletConfig.EthRpcProxyPassword != ""
networks = networkhelper.OverrideBasicAuth(
networks,
params.EmbeddedEthRpcProxyProviderType,
hasSmartProxyCredentials,
walletConfig.EthRpcProxyUser,
walletConfig.EthRpcProxyPassword)
// Apply auth for old proxy
hasOldProxyCredentials := walletConfig.StatusProxyBlockchainUser != "" && walletConfig.StatusProxyBlockchainPassword != ""
networks = networkhelper.OverrideBasicAuth(
networks,
params.EmbeddedProxyProviderType,
hasOldProxyCredentials,
walletConfig.StatusProxyBlockchainUser,
walletConfig.StatusProxyBlockchainPassword)
return networks
} }
func BuildDefaultNetworks(walletSecretsConfig *requests.WalletSecretsConfig) []params.Network { func BuildDefaultNetworks(walletSecretsConfig *requests.WalletSecretsConfig) []params.Network {
return setRPCs(defaultNetworks(walletSecretsConfig.StatusProxyStageName), walletSecretsConfig) proxyHost := getProxyHost(walletSecretsConfig.EthRpcProxyUrl, walletSecretsConfig.StatusProxyStageName)
return setRPCs(defaultNetworks(proxyHost, walletSecretsConfig.StatusProxyStageName), walletSecretsConfig)
} }

View File

@ -228,6 +228,8 @@ func buildWalletConfig(request *requests.WalletSecretsConfig, statusProxyEnabled
if request.StatusProxyMarketPassword != "" { if request.StatusProxyMarketPassword != "" {
walletConfig.StatusProxyMarketPassword = request.StatusProxyMarketPassword walletConfig.StatusProxyMarketPassword = request.StatusProxyMarketPassword
} }
// FIXME: remove when EthRpcProxy* is integrated
if request.StatusProxyBlockchainUser != "" { if request.StatusProxyBlockchainUser != "" {
walletConfig.StatusProxyBlockchainUser = request.StatusProxyBlockchainUser walletConfig.StatusProxyBlockchainUser = request.StatusProxyBlockchainUser
} }
@ -235,6 +237,16 @@ func buildWalletConfig(request *requests.WalletSecretsConfig, statusProxyEnabled
walletConfig.StatusProxyBlockchainPassword = request.StatusProxyBlockchainPassword walletConfig.StatusProxyBlockchainPassword = request.StatusProxyBlockchainPassword
} }
if request.EthRpcProxyUrl != "" {
walletConfig.EthRpcProxyUrl = request.EthRpcProxyUrl
}
if request.EthRpcProxyUser != "" {
walletConfig.EthRpcProxyUser = request.EthRpcProxyUser
}
if request.EthRpcProxyPassword != "" {
walletConfig.EthRpcProxyPassword = request.EthRpcProxyPassword
}
walletConfig.StatusProxyEnabled = statusProxyEnabled walletConfig.StatusProxyEnabled = statusProxyEnabled
return walletConfig return walletConfig
@ -254,6 +266,22 @@ func overrideApiConfigProd(nodeConfig *params.NodeConfig, config *requests.APICo
nodeConfig.WSPort = config.WSPort nodeConfig.WSPort = config.WSPort
} }
// getMainnetRPCURL retuevrns URL of the first provider with TokenAuth from mainnet network
func getMainnetRPCURL(networks []params.Network) string {
for _, network := range networks {
if network.ChainID != MainnetChainID {
continue
}
for _, provider := range network.RpcProviders {
if provider.AuthType == params.TokenAuth && provider.Enabled {
return provider.GetFullURL()
}
}
break
}
return ""
}
func DefaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) { func DefaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
// Set mainnet // Set mainnet
nodeConfig := &params.NodeConfig{} nodeConfig := &params.NodeConfig{}
@ -344,13 +372,13 @@ func DefaultNodeConfig(installationID string, request *requests.CreateAccount, o
if request.VerifyTransactionURL != nil { if request.VerifyTransactionURL != nil {
nodeConfig.ShhextConfig.VerifyTransactionURL = *request.VerifyTransactionURL nodeConfig.ShhextConfig.VerifyTransactionURL = *request.VerifyTransactionURL
} else { } else {
nodeConfig.ShhextConfig.VerifyTransactionURL = mainnet(request.WalletSecretsConfig.StatusProxyStageName).FallbackURL nodeConfig.ShhextConfig.VerifyTransactionURL = getMainnetRPCURL(nodeConfig.Networks)
} }
if request.VerifyENSURL != nil { if request.VerifyENSURL != nil {
nodeConfig.ShhextConfig.VerifyENSURL = *request.VerifyENSURL nodeConfig.ShhextConfig.VerifyENSURL = *request.VerifyENSURL
} else { } else {
nodeConfig.ShhextConfig.VerifyENSURL = mainnet(request.WalletSecretsConfig.StatusProxyStageName).FallbackURL nodeConfig.ShhextConfig.VerifyENSURL = getMainnetRPCURL(nodeConfig.Networks)
} }
if request.VerifyTransactionChainID != nil { if request.VerifyTransactionChainID != nil {

View File

@ -564,7 +564,7 @@ func (b *GethStatusBackend) updateAccountColorHashAndColorID(keyUID string, acco
} }
func (b *GethStatusBackend) overrideNetworks(conf *params.NodeConfig, request *requests.Login) { func (b *GethStatusBackend) overrideNetworks(conf *params.NodeConfig, request *requests.Login) {
conf.Networks = setRPCs(defaultNetworks(request.WalletSecretsConfig.StatusProxyStageName), &request.WalletSecretsConfig) conf.Networks = BuildDefaultNetworks(&request.WalletSecretsConfig)
} }
func (b *GethStatusBackend) LoginAccount(request *requests.Login) error { func (b *GethStatusBackend) LoginAccount(request *requests.Login) error {

View File

@ -11,8 +11,6 @@ import (
"reflect" "reflect"
"sync" "sync"
"github.com/status-im/status-go/params/networkhelper"
"github.com/syndtr/goleveldb/leveldb" "github.com/syndtr/goleveldb/leveldb"
"go.uber.org/zap" "go.uber.org/zap"
@ -338,20 +336,10 @@ func (n *StatusNode) setupRPCClient() (err error) {
return return
} }
// Proxy AuthConfigs should be passed not in wallet secrets config on login
// but some other way, as it's not wallet specific and should not be passed with login request
// but currently there is no other way to pass it
// (maybe move to default_networks.go)
networks := networkhelper.OverrideEmbeddedProxyProviders(
n.config.Networks,
n.config.WalletConfig.StatusProxyEnabled,
n.config.WalletConfig.StatusProxyBlockchainUser,
n.config.WalletConfig.StatusProxyBlockchainPassword)
config := rpc.ClientConfig{ config := rpc.ClientConfig{
Client: gethNodeClient, Client: gethNodeClient,
UpstreamChainID: n.config.NetworkID, UpstreamChainID: n.config.NetworkID,
Networks: networks, Networks: n.config.Networks,
DB: n.appDB, DB: n.appDB,
WalletFeed: &n.walletFeed, WalletFeed: &n.walletFeed,
} }
@ -360,9 +348,6 @@ func (n *StatusNode) setupRPCClient() (err error) {
return return
} }
n.rpcClient.Start(context.Background()) n.rpcClient.Start(context.Background())
if err != nil {
return
}
return return
} }

View File

@ -509,12 +509,17 @@ type WalletConfig struct {
InfuraAPIKeySecret string `json:"InfuraAPIKeySecret"` InfuraAPIKeySecret string `json:"InfuraAPIKeySecret"`
StatusProxyMarketUser string `json:"StatusProxyMarketUser"` StatusProxyMarketUser string `json:"StatusProxyMarketUser"`
StatusProxyMarketPassword string `json:"StatusProxyMarketPassword"` StatusProxyMarketPassword string `json:"StatusProxyMarketPassword"`
// FIXME: remove when EthRpcProxy* is integrated
StatusProxyBlockchainUser string `json:"StatusProxyBlockchainUser"` StatusProxyBlockchainUser string `json:"StatusProxyBlockchainUser"`
StatusProxyBlockchainPassword string `json:"StatusProxyBlockchainPassword"` StatusProxyBlockchainPassword string `json:"StatusProxyBlockchainPassword"`
StatusProxyEnabled bool `json:"StatusProxyEnabled"` StatusProxyEnabled bool `json:"StatusProxyEnabled"`
StatusProxyStageName string `json:"StatusProxyStageName"` StatusProxyStageName string `json:"StatusProxyStageName"`
EnableCelerBridge bool `json:"EnableCelerBridge"` EnableCelerBridge bool `json:"EnableCelerBridge"`
EnableMercuryoProvider bool `json:"EnableMercuryoProvider"` EnableMercuryoProvider bool `json:"EnableMercuryoProvider"`
EthRpcProxyUrl string `json:"EthRpcProxyUrl"`
EthRpcProxyUser string `json:"EthRpcProxyUser"`
EthRpcProxyPassword string `json:"EthRpcProxyPassword"`
} }
// MarshalJSON custom marshalling to avoid exposing sensitive data in log, // MarshalJSON custom marshalling to avoid exposing sensitive data in log,

View File

@ -1,6 +1,10 @@
package params package params
import "github.com/ethereum/go-ethereum/common" import (
"strings"
"github.com/ethereum/go-ethereum/common"
)
// RpcProviderAuthType defines the different types of authentication for RPC providers // RpcProviderAuthType defines the different types of authentication for RPC providers
type RpcProviderAuthType string type RpcProviderAuthType string
@ -16,6 +20,7 @@ type RpcProviderType string
const ( const (
EmbeddedProxyProviderType RpcProviderType = "embedded-proxy" // Proxy-based RPC provider EmbeddedProxyProviderType RpcProviderType = "embedded-proxy" // Proxy-based RPC provider
EmbeddedEthRpcProxyProviderType RpcProviderType = "embedded-eth-rpc-proxy" // EthRpcProxy-based RPC provider (smart proxy)
EmbeddedDirectProviderType RpcProviderType = "embedded-direct" // Direct RPC provider EmbeddedDirectProviderType RpcProviderType = "embedded-direct" // Direct RPC provider
UserProviderType RpcProviderType = "user" // User-defined RPC provider UserProviderType RpcProviderType = "user" // User-defined RPC provider
) )
@ -39,7 +44,7 @@ type RpcProvider struct {
// GetFullURL returns the URL with auth token if TokenAuth is used // GetFullURL returns the URL with auth token if TokenAuth is used
func (p RpcProvider) GetFullURL() string { func (p RpcProvider) GetFullURL() string {
if p.AuthType == TokenAuth && p.AuthToken != "" { if p.AuthType == TokenAuth && p.AuthToken != "" {
return p.URL + "/" + p.AuthToken return strings.TrimRight(p.URL, "/") + "/" + p.AuthToken
} }
return p.URL return p.URL
} }
@ -107,6 +112,10 @@ func NewProxyProvider(chainID uint64, name, url string, enableRpsLimiter bool) *
return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedProxyProviderType) return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedProxyProviderType)
} }
func NewEthRpcProxyProvider(chainID uint64, name, url string, enableRpsLimiter bool) *RpcProvider {
return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedEthRpcProxyProviderType)
}
func NewDirectProvider(chainID uint64, name, url string, enableRpsLimiter bool) *RpcProvider { func NewDirectProvider(chainID uint64, name, url string, enableRpsLimiter bool) *RpcProvider {
return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedDirectProviderType) return newRpcProvider(chainID, name, url, enableRpsLimiter, EmbeddedDirectProviderType)
} }

View File

@ -93,28 +93,22 @@ func ReplaceEmbeddedProviders(currentProviders, newEmbeddedProviders []params.Rp
return append(userProviders, embeddedProviders...) return append(userProviders, embeddedProviders...)
} }
// OverrideEmbeddedProxyProviders updates all embedded-proxy providers in the given networks. // OverrideBasicAuth updates providers of the specified type in the given networks.
// It sets the `Enabled` flag and configures the `AuthLogin` and `AuthPassword` for each provider. // It sets the `Enabled` flag and configures the `AuthLogin` and `AuthPassword` for each matching provider.
func OverrideEmbeddedProxyProviders(networks []params.Network, enabled bool, user, password string) []params.Network { func OverrideBasicAuth(networks []params.Network, providerType params.RpcProviderType, enabled bool, user, password string) []params.Network {
updatedNetworks := make([]params.Network, len(networks)) updatedNetworks := DeepCopyNetworks(networks)
for i, network := range networks {
// Deep copy the network to avoid mutating the input slice
updatedNetwork := network
updatedProviders := make([]params.RpcProvider, len(network.RpcProviders))
// Update the embedded-proxy providers for i := range updatedNetworks {
for j, provider := range network.RpcProviders { network := &updatedNetworks[i]
if provider.Type == params.EmbeddedProxyProviderType { for j := range network.RpcProviders {
provider := &network.RpcProviders[j]
if provider.Type == providerType {
provider.Enabled = enabled provider.Enabled = enabled
provider.AuthType = params.BasicAuth provider.AuthType = params.BasicAuth
provider.AuthLogin = user provider.AuthLogin = user
provider.AuthPassword = password provider.AuthPassword = password
} }
updatedProviders[j] = provider
} }
updatedNetwork.RpcProviders = updatedProviders
updatedNetworks[i] = updatedNetwork
} }
return updatedNetworks return updatedNetworks

View File

@ -54,26 +54,31 @@ func TestMergeProvidersPreserveEnabledAndOrder(t *testing.T) {
// Assertions // Assertions
require.True(t, reflect.DeepEqual(mergedProviders, expectedProviders), "Merged providers should match the expected providers") require.True(t, reflect.DeepEqual(mergedProviders, expectedProviders), "Merged providers should match the expected providers")
} }
func TestUpdateEmbeddedProxyProviders(t *testing.T) {
func TestOverrideBasicAuth(t *testing.T) {
// Arrange: Create a sample list of networks with various provider types // Arrange: Create a sample list of networks with various provider types
networks := []params.Network{ networks := []params.Network{
*testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{ *testutil.CreateNetwork(api.MainnetChainID, "Ethereum Mainnet", []params.RpcProvider{
*params.NewUserProvider(api.MainnetChainID, "Provider1", "https://userprovider.example.com", true), *params.NewUserProvider(api.MainnetChainID, "Provider1", "https://userprovider.example.com", true),
*params.NewProxyProvider(api.MainnetChainID, "Provider2", "https://proxyprovider.example.com", true), *params.NewProxyProvider(api.MainnetChainID, "Provider2", "https://proxyprovider.example.com", true),
*params.NewEthRpcProxyProvider(api.MainnetChainID, "Provider3", "https://ethrpcproxy.example.com", true),
}), }),
*testutil.CreateNetwork(api.OptimismChainID, "Optimism", []params.RpcProvider{ *testutil.CreateNetwork(api.OptimismChainID, "Optimism", []params.RpcProvider{
*params.NewDirectProvider(api.OptimismChainID, "Provider3", "https://directprovider.example.com", true), *params.NewDirectProvider(api.OptimismChainID, "Provider4", "https://directprovider.example.com", true),
*params.NewProxyProvider(api.OptimismChainID, "Provider4", "https://proxyprovider2.example.com", true), *params.NewProxyProvider(api.OptimismChainID, "Provider5", "https://proxyprovider2.example.com", true),
*params.NewEthRpcProxyProvider(api.OptimismChainID, "Provider6", "https://ethrpcproxy2.example.com", true),
}), }),
} }
networks[0].RpcProviders[1].Enabled = false networks[0].RpcProviders[1].Enabled = false
networks[0].RpcProviders[2].Enabled = false
networks[1].RpcProviders[1].Enabled = false networks[1].RpcProviders[1].Enabled = false
networks[1].RpcProviders[2].Enabled = false
user := gofakeit.Username() user := gofakeit.Username()
password := gofakeit.LetterN(5) password := gofakeit.LetterN(5)
// Call the function to update embedded-proxy providers // Test updating EmbeddedProxyProviderType providers
updatedNetworks := networkhelper.OverrideEmbeddedProxyProviders(networks, true, user, password) updatedNetworks := networkhelper.OverrideBasicAuth(networks, params.EmbeddedProxyProviderType, true, user, password)
// Verify the networks // Verify the networks
for i, network := range updatedNetworks { for i, network := range updatedNetworks {
@ -96,6 +101,31 @@ func TestUpdateEmbeddedProxyProviders(t *testing.T) {
} }
} }
// Test updating EmbeddedEthRpcProxyProviderType providers
user2 := gofakeit.Username()
password2 := gofakeit.LetterN(5)
updatedNetworks = networkhelper.OverrideBasicAuth(networks, params.EmbeddedEthRpcProxyProviderType, true, user2, password2)
// Verify the networks
for i, network := range updatedNetworks {
networkCopy := network
expectedNetwork := &networks[i]
testutil.CompareNetworks(t, expectedNetwork, &networkCopy)
for j, provider := range networkCopy.RpcProviders {
expectedProvider := expectedNetwork.RpcProviders[j]
if provider.Type == params.EmbeddedEthRpcProxyProviderType {
assert.True(t, provider.Enabled, "Provider Enabled state should be overridden")
assert.Equal(t, user2, provider.AuthLogin, "Provider AuthLogin should be overridden")
assert.Equal(t, password2, provider.AuthPassword, "Provider AuthPassword should be overridden")
assert.Equal(t, params.BasicAuth, provider.AuthType, "Provider AuthType should be set to BasicAuth")
} else {
assert.Equal(t, expectedProvider.Enabled, provider.Enabled, "Provider Enabled state should remain unchanged")
assert.Equal(t, expectedProvider.AuthLogin, provider.AuthLogin, "Provider AuthLogin should remain unchanged")
assert.Equal(t, expectedProvider.AuthPassword, provider.AuthPassword, "Provider AuthPassword should remain unchanged")
}
}
}
} }
func TestOverrideDirectProvidersAuth(t *testing.T) { func TestOverrideDirectProvidersAuth(t *testing.T) {

View File

@ -108,8 +108,13 @@ type WalletSecretsConfig struct {
StatusProxyStageName string `json:"statusProxyStageName"` StatusProxyStageName string `json:"statusProxyStageName"`
StatusProxyMarketUser string `json:"statusProxyMarketUser"` StatusProxyMarketUser string `json:"statusProxyMarketUser"`
StatusProxyMarketPassword string `json:"statusProxyMarketPassword"` StatusProxyMarketPassword string `json:"statusProxyMarketPassword"`
// FIXME: remove when EthRpcProxy* is integrated
StatusProxyBlockchainUser string `json:"statusProxyBlockchainUser"` StatusProxyBlockchainUser string `json:"statusProxyBlockchainUser"`
StatusProxyBlockchainPassword string `json:"statusProxyBlockchainPassword"` StatusProxyBlockchainPassword string `json:"statusProxyBlockchainPassword"`
EthRpcProxyUrl string `json:"ethRpcProxyUrl"`
EthRpcProxyUser string `json:"ethRpcProxyUser"`
EthRpcProxyPassword string `json:"ethRpcProxyPassword"`
} }
func (c *CreateAccount) Validate(validation *CreateAccountValidation) error { func (c *CreateAccount) Validate(validation *CreateAccountValidation) error {

View File

@ -158,7 +158,7 @@ func TestGetClientsUsingCache(t *testing.T) {
Type: params.EmbeddedProxyProviderType, Type: params.EmbeddedProxyProviderType,
AuthType: params.BasicAuth, AuthType: params.BasicAuth,
AuthLogin: "incorrectUser", AuthLogin: "incorrectUser",
AuthPassword: "incorrectPwd", // will be replaced by correct values by OverrideEmbeddedProxyProviders AuthPassword: "incorrectPwd", // will be replaced by correct values by OverrideBasicAuth
Enabled: true, Enabled: true,
}) })
} }
@ -173,7 +173,7 @@ func TestGetClientsUsingCache(t *testing.T) {
}, },
} }
networks = networkhelper.OverrideEmbeddedProxyProviders(networks, true, user, password) networks = networkhelper.OverrideBasicAuth(networks, params.EmbeddedProxyProviderType, true, user, password)
config := ClientConfig{ config := ClientConfig{
Client: nil, Client: nil,

View File

@ -152,7 +152,7 @@ func TestAPI_GetAddressDetails(t *testing.T) {
}, },
} }
networks = networkhelper.OverrideEmbeddedProxyProviders(networks, true, gofakeit.Username(), gofakeit.LetterN(5)) networks = networkhelper.OverrideBasicAuth(networks, params.EmbeddedProxyProviderType, true, gofakeit.Username(), gofakeit.LetterN(5))
require.NotEmpty(t, networks) require.NotEmpty(t, networks)
config := rpc.ClientConfig{ config := rpc.ClientConfig{