From 201afb96eee31a01ce1a3f76d93b5f1ec2962d67 Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Wed, 11 Dec 2024 00:05:00 +0000 Subject: [PATCH 1/2] feat/wallet-config-sensitive-string --- api/backend_test.go | 26 +++++---- api/default_networks.go | 2 +- api/defaults.go | 33 ++++++------ internal/security/sensitive_string_test.go | 7 +++ params/config.go | 53 +++++++------------ params/config_test.go | 6 ++- protocol/communities/manager_test.go | 3 +- protocol/requests/create_account.go | 39 +++++++------- rpc/client.go | 2 +- rpc/provider.go | 13 ++--- services/wallet/thirdparty/alchemy/client.go | 16 +++--- .../wallet/thirdparty/cryptocompare/client.go | 7 +-- services/wallet/thirdparty/http_client.go | 9 ++-- .../wallet/thirdparty/opensea/client_v2.go | 7 +-- .../wallet/thirdparty/opensea/http_client.go | 11 ++-- services/wallet/thirdparty/rarible/client.go | 21 ++++---- 16 files changed, 133 insertions(+), 122 deletions(-) diff --git a/api/backend_test.go b/api/backend_test.go index c3cfb700796..6e849bd3997 100644 --- a/api/backend_test.go +++ b/api/backend_test.go @@ -43,6 +43,8 @@ import ( "github.com/status-im/status-go/t/helpers" "github.com/status-im/status-go/t/utils" "github.com/status-im/status-go/walletdatabase" + "github.com/status-im/status-go/internal/security" + "github.com/brianvoe/gofakeit/v6" ) var ( @@ -1515,20 +1517,24 @@ func TestSetFleet(t *testing.T) { require.NoError(t, b.Logout()) } +func fakeToken() security.SensitiveString { + return security.NewSensitiveString(gofakeit.LetterN(10)) +} + func TestWalletConfigOnLoginAccount(t *testing.T) { utils.Init() password := "some-password2" // nolint: goconst tmpdir := t.TempDir() - poktToken := "grove-token" // nolint: goconst - infuraToken := "infura-token" // nolint: goconst - alchemyEthereumMainnetToken := "alchemy-ethereum-mainnet-token" - alchemyEthereumSepoliaToken := "alchemy-ethereum-sepolia-token" - alchemyArbitrumMainnetToken := "alchemy-arbitrum-mainnet-token" - alchemyArbitrumSepoliaToken := "alchemy-arbitrum-sepolia-token" - alchemyOptimismMainnetToken := "alchemy-optimism-mainnet-token" - alchemyOptimismSepoliaToken := "alchemy-optimism-sepolia-token" - raribleMainnetAPIKey := "rarible-mainnet-api-key" // nolint: gosec - raribleTestnetAPIKey := "rarible-testnet-api-key" // nolint: gosec + poktToken := "grove-token" // nolint: goconst + infuraToken := fakeToken() + alchemyEthereumMainnetToken := fakeToken() + alchemyEthereumSepoliaToken := fakeToken() + alchemyArbitrumMainnetToken := fakeToken() + alchemyArbitrumSepoliaToken := fakeToken() + alchemyOptimismMainnetToken := fakeToken() + alchemyOptimismSepoliaToken := fakeToken() + raribleMainnetAPIKey := fakeToken() + raribleTestnetAPIKey := fakeToken() b := NewGethStatusBackend(tt.MustCreateTestLogger()) createAccountRequest := &requests.CreateAccount{ diff --git a/api/default_networks.go b/api/default_networks.go index 32cd654f153..f617cebeefd 100644 --- a/api/default_networks.go +++ b/api/default_networks.go @@ -186,7 +186,7 @@ func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) [ ) appendToken := func(url string) string { - if strings.Contains(url, infura) && request.InfuraToken != "" { + if strings.Contains(url, infura) && !request.InfuraToken.Empty() { return url + request.InfuraToken } else if strings.Contains(url, grove) && request.PoktToken != "" { return url + request.PoktToken diff --git a/api/defaults.go b/api/defaults.go index 4982bda98b0..b964a52fcbc 100644 --- a/api/defaults.go +++ b/api/defaults.go @@ -15,6 +15,7 @@ import ( "github.com/status-im/status-go/protocol/identity/alias" "github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/requests" + "github.com/status-im/status-go/internal/security" ) const ( @@ -170,61 +171,61 @@ func SetFleet(fleet string, nodeConfig *params.NodeConfig) error { func buildWalletConfig(request *requests.WalletSecretsConfig, statusProxyEnabled bool) params.WalletConfig { walletConfig := params.WalletConfig{ Enabled: true, - AlchemyAPIKeys: make(map[uint64]string), + AlchemyAPIKeys: make(map[uint64]security.SensitiveString), } if request.StatusProxyStageName != "" { walletConfig.StatusProxyStageName = request.StatusProxyStageName } - if request.OpenseaAPIKey != "" { + if !request.OpenseaAPIKey.Empty() { walletConfig.OpenseaAPIKey = request.OpenseaAPIKey } - if request.RaribleMainnetAPIKey != "" { + if !request.RaribleMainnetAPIKey.Empty() { walletConfig.RaribleMainnetAPIKey = request.RaribleMainnetAPIKey } - if request.RaribleTestnetAPIKey != "" { + if !request.RaribleTestnetAPIKey.Empty() { walletConfig.RaribleTestnetAPIKey = request.RaribleTestnetAPIKey } - if request.InfuraToken != "" { + if !request.InfuraToken.Empty() { walletConfig.InfuraAPIKey = request.InfuraToken } - if request.InfuraSecret != "" { + if !request.InfuraSecret.Empty() { walletConfig.InfuraAPIKeySecret = request.InfuraSecret } - if request.AlchemyEthereumMainnetToken != "" { + if !request.AlchemyEthereumMainnetToken.Empty() { walletConfig.AlchemyAPIKeys[mainnetChainID] = request.AlchemyEthereumMainnetToken } - if request.AlchemyEthereumSepoliaToken != "" { + if !request.AlchemyEthereumSepoliaToken.Empty() { walletConfig.AlchemyAPIKeys[sepoliaChainID] = request.AlchemyEthereumSepoliaToken } - if request.AlchemyArbitrumMainnetToken != "" { + if !request.AlchemyArbitrumMainnetToken.Empty() { walletConfig.AlchemyAPIKeys[arbitrumChainID] = request.AlchemyArbitrumMainnetToken } - if request.AlchemyArbitrumSepoliaToken != "" { + if !request.AlchemyArbitrumSepoliaToken.Empty() { walletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken } - if request.AlchemyOptimismMainnetToken != "" { + if !request.AlchemyOptimismMainnetToken.Empty() { walletConfig.AlchemyAPIKeys[optimismChainID] = request.AlchemyOptimismMainnetToken } - if request.AlchemyOptimismSepoliaToken != "" { + if !request.AlchemyOptimismSepoliaToken.Empty() { walletConfig.AlchemyAPIKeys[optimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken } - if request.StatusProxyMarketUser != "" { + if !request.StatusProxyMarketUser.Empty() { walletConfig.StatusProxyMarketUser = request.StatusProxyMarketUser } - if request.StatusProxyMarketPassword != "" { + if !request.StatusProxyMarketPassword.Empty() { walletConfig.StatusProxyMarketPassword = request.StatusProxyMarketPassword } - if request.StatusProxyBlockchainUser != "" { + if !request.StatusProxyBlockchainUser.Empty() { walletConfig.StatusProxyBlockchainUser = request.StatusProxyBlockchainUser } - if request.StatusProxyBlockchainPassword != "" { + if !request.StatusProxyBlockchainPassword.Empty() { walletConfig.StatusProxyBlockchainPassword = request.StatusProxyBlockchainPassword } diff --git a/internal/security/sensitive_string_test.go b/internal/security/sensitive_string_test.go index dd843260cc8..159e30f653d 100644 --- a/internal/security/sensitive_string_test.go +++ b/internal/security/sensitive_string_test.go @@ -64,3 +64,10 @@ func TestCopySensitiveString(t *testing.T) { sCopy := s require.Equal(t, secretValue, sCopy.Reveal()) } + +func TestCopySensitiveString(t *testing.T) { + secretValue := gofakeit.LetterN(10) + s := NewSensitiveString(secretValue) + sCopy := s + require.Equal(t, secretValue, sCopy.Reveal()) +} diff --git a/params/config.go b/params/config.go index ca3ee5bf972..4a289bce1e9 100644 --- a/params/config.go +++ b/params/config.go @@ -25,6 +25,7 @@ import ( "github.com/status-im/status-go/static" wakucommon "github.com/status-im/status-go/waku/common" wakuv2common "github.com/status-im/status-go/wakuv2/common" + "github.com/status-im/status-go/internal/security" ) // ---------- @@ -303,10 +304,10 @@ type ProviderConfig struct { // URL sets the rpc upstream host address for communication with // a non-local infura endpoint. - User string `json:",omitempty"` - Password string `json:",omitempty"` - APIKey string `json:"APIKey,omitempty"` - APIKeySecret string `json:"APIKeySecret,omitempty"` + User security.SensitiveString `json:",omitempty"` + Password security.SensitiveString `json:",omitempty"` + APIKey security.SensitiveString `json:"APIKey,omitempty"` + APIKeySecret security.SensitiveString `json:"APIKeySecret,omitempty"` } // ---------- @@ -546,36 +547,20 @@ type Network struct { // WalletConfig extra configuration for wallet.Service. type WalletConfig struct { Enabled bool - OpenseaAPIKey string `json:"OpenseaAPIKey"` - RaribleMainnetAPIKey string `json:"RaribleMainnetAPIKey"` - RaribleTestnetAPIKey string `json:"RaribleTestnetAPIKey"` - AlchemyAPIKeys map[uint64]string `json:"AlchemyAPIKeys"` - InfuraAPIKey string `json:"InfuraAPIKey"` - InfuraAPIKeySecret string `json:"InfuraAPIKeySecret"` - StatusProxyMarketUser string `json:"StatusProxyMarketUser"` - StatusProxyMarketPassword string `json:"StatusProxyMarketPassword"` - StatusProxyBlockchainUser string `json:"StatusProxyBlockchainUser"` - StatusProxyBlockchainPassword string `json:"StatusProxyBlockchainPassword"` - StatusProxyEnabled bool `json:"StatusProxyEnabled"` - StatusProxyStageName string `json:"StatusProxyStageName"` - EnableCelerBridge bool `json:"EnableCelerBridge"` - EnableMercuryoProvider bool `json:"EnableMercuryoProvider"` -} - -// MarshalJSON custom marshalling to avoid exposing sensitive data in log, -// there's a function called `startNode` will log NodeConfig which include WalletConfig -func (wc WalletConfig) MarshalJSON() ([]byte, error) { - return json.Marshal(struct { - Enabled bool `json:"Enabled"` - StatusProxyEnabled bool `json:"StatusProxyEnabled"` - EnableCelerBridge bool `json:"EnableCelerBridge"` - EnableMercuryoProvider bool `json:"EnableMercuryoProvider"` - }{ - Enabled: wc.Enabled, - StatusProxyEnabled: wc.StatusProxyEnabled, - EnableCelerBridge: wc.EnableCelerBridge, - EnableMercuryoProvider: wc.EnableMercuryoProvider, - }) + OpenseaAPIKey security.SensitiveString `json:"OpenseaAPIKey"` + RaribleMainnetAPIKey security.SensitiveString `json:"RaribleMainnetAPIKey"` + RaribleTestnetAPIKey security.SensitiveString `json:"RaribleTestnetAPIKey"` + AlchemyAPIKeys map[uint64]security.SensitiveString `json:"AlchemyAPIKeys"` + InfuraAPIKey security.SensitiveString `json:"InfuraAPIKey"` + InfuraAPIKeySecret security.SensitiveString `json:"InfuraAPIKeySecret"` + StatusProxyMarketUser security.SensitiveString `json:"StatusProxyMarketUser"` + StatusProxyMarketPassword security.SensitiveString `json:"StatusProxyMarketPassword"` + StatusProxyBlockchainUser security.SensitiveString `json:"StatusProxyBlockchainUser"` + StatusProxyBlockchainPassword security.SensitiveString `json:"StatusProxyBlockchainPassword"` + StatusProxyEnabled bool `json:"StatusProxyEnabled"` + StatusProxyStageName string `json:"StatusProxyStageName"` + EnableCelerBridge bool `json:"EnableCelerBridge"` + EnableMercuryoProvider bool `json:"EnableMercuryoProvider"` } // LocalNotificationsConfig extra configuration for localnotifications.Service. diff --git a/params/config_test.go b/params/config_test.go index b61fc6149b6..2e3fcd143bb 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -15,6 +15,8 @@ import ( "github.com/status-im/status-go/params" "github.com/status-im/status-go/t/utils" + "github.com/status-im/status-go/internal/security" + "github.com/brianvoe/gofakeit/v6" ) func TestNewNodeConfigWithDefaults(t *testing.T) { @@ -315,8 +317,8 @@ func TestNodeConfigValidate(t *testing.T) { func TestMarshalWalletConfigJSON(t *testing.T) { walletConfig := params.WalletConfig{ - OpenseaAPIKey: "some-key", - RaribleMainnetAPIKey: "some-key2", + OpenseaAPIKey: security.NewSensitiveString(gofakeit.LetterN(10)), + RaribleMainnetAPIKey: security.NewSensitiveString(gofakeit.LetterN(10)), } bytes, err := json.Marshal(walletConfig) require.NoError(t, err) diff --git a/protocol/communities/manager_test.go b/protocol/communities/manager_test.go index 14fceb3cddd..2f1ad2e8157 100644 --- a/protocol/communities/manager_test.go +++ b/protocol/communities/manager_test.go @@ -36,6 +36,7 @@ import ( _ "github.com/mutecomm/go-sqlcipher/v4" // require go-sqlcipher that overrides default implementation "github.com/stretchr/testify/suite" "go.uber.org/zap" + "github.com/status-im/status-go/internal/security" ) func TestManagerSuite(t *testing.T) { @@ -220,7 +221,7 @@ func (s *ManagerSuite) setupManagerForTokenPermissions() (*Manager, *testCollect options := []ManagerOption{ WithWalletConfig(¶ms.WalletConfig{ - OpenseaAPIKey: "some-key", + OpenseaAPIKey: security.NewSensitiveString("some-key"), }), WithCollectiblesManager(cm), WithTokenManager(tm), diff --git a/protocol/requests/create_account.go b/protocol/requests/create_account.go index 80e23cd947a..e4c24e75923 100644 --- a/protocol/requests/create_account.go +++ b/protocol/requests/create_account.go @@ -5,6 +5,7 @@ import ( utils "github.com/status-im/status-go/common" "github.com/status-im/status-go/params" + "github.com/status-im/status-go/internal/security" ) var ErrCreateAccountInvalidDisplayName = errors.New("create-account: invalid display name") @@ -89,25 +90,25 @@ type CreateAccount struct { } type WalletSecretsConfig struct { - PoktToken string `json:"poktToken"` - InfuraToken string `json:"infuraToken"` - InfuraSecret string `json:"infuraSecret"` - OpenseaAPIKey string `json:"openseaApiKey"` - RaribleMainnetAPIKey string `json:"raribleMainnetApiKey"` - RaribleTestnetAPIKey string `json:"raribleTestnetApiKey"` - - AlchemyEthereumMainnetToken string `json:"alchemyEthereumMainnetToken"` - AlchemyEthereumSepoliaToken string `json:"alchemyEthereumSepoliaToken"` - AlchemyArbitrumMainnetToken string `json:"alchemyArbitrumMainnetToken"` - AlchemyArbitrumSepoliaToken string `json:"alchemyArbitrumSepoliaToken"` - AlchemyOptimismMainnetToken string `json:"alchemyOptimismMainnetToken"` - AlchemyOptimismSepoliaToken string `json:"alchemyOptimismSepoliaToken"` - - StatusProxyStageName string `json:"statusProxyStageName"` - StatusProxyMarketUser string `json:"statusProxyMarketUser"` - StatusProxyMarketPassword string `json:"statusProxyMarketPassword"` - StatusProxyBlockchainUser string `json:"statusProxyBlockchainUser"` - StatusProxyBlockchainPassword string `json:"statusProxyBlockchainPassword"` + PoktToken string `json:"poktToken"` + InfuraToken security.SensitiveString `json:"infuraToken"` + InfuraSecret security.SensitiveString `json:"infuraSecret"` + OpenseaAPIKey security.SensitiveString `json:"openseaApiKey"` + RaribleMainnetAPIKey security.SensitiveString `json:"raribleMainnetApiKey"` + RaribleTestnetAPIKey security.SensitiveString `json:"raribleTestnetApiKey"` + + AlchemyEthereumMainnetToken security.SensitiveString `json:"alchemyEthereumMainnetToken"` + AlchemyEthereumSepoliaToken security.SensitiveString `json:"alchemyEthereumSepoliaToken"` + AlchemyArbitrumMainnetToken security.SensitiveString `json:"alchemyArbitrumMainnetToken"` + AlchemyArbitrumSepoliaToken security.SensitiveString `json:"alchemyArbitrumSepoliaToken"` + AlchemyOptimismMainnetToken security.SensitiveString `json:"alchemyOptimismMainnetToken"` + AlchemyOptimismSepoliaToken security.SensitiveString `json:"alchemyOptimismSepoliaToken"` + + StatusProxyStageName string `json:"statusProxyStageName"` + StatusProxyMarketUser security.SensitiveString `json:"statusProxyMarketUser"` + StatusProxyMarketPassword security.SensitiveString `json:"statusProxyMarketPassword"` + StatusProxyBlockchainUser security.SensitiveString `json:"statusProxyBlockchainUser"` + StatusProxyBlockchainPassword security.SensitiveString `json:"statusProxyBlockchainPassword"` // Testing GanacheURL string `json:"ganacheURL"` diff --git a/rpc/client.go b/rpc/client.go index 574f5da7b9b..6724c6b4480 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -295,7 +295,7 @@ func (c *Client) getEthClients(network *params.Network) []ethclient.RPSLimitedEt // For now, we only support auth for status-proxy. var opts []gethrpc.ClientOption if provider.authenticationNeeded() { - authEncoded := base64.StdEncoding.EncodeToString([]byte(provider.Auth)) + authEncoded := base64.StdEncoding.EncodeToString([]byte(provider.Auth.Reveal())) opts = append(opts, gethrpc.WithHeaders(http.Header{ "Authorization": {"Basic " + authEncoded}, diff --git a/rpc/provider.go b/rpc/provider.go index 329388570cd..11b5be0bb96 100644 --- a/rpc/provider.go +++ b/rpc/provider.go @@ -8,6 +8,7 @@ import ( "go.uber.org/zap" "github.com/status-im/status-go/params" + "github.com/status-im/status-go/internal/security" ) const ( @@ -21,12 +22,12 @@ const ( type Provider struct { Key string URL string - Auth string + Auth security.SensitiveString Priority int } func (p Provider) authenticationNeeded() bool { - return len(p.Auth) > 0 + return !p.Auth.Empty() } func getProviderPriorityByURL(url string) int { @@ -58,7 +59,7 @@ func getProviderConfig(providerConfigs []params.ProviderConfig, providerName str return params.ProviderConfig{}, fmt.Errorf("provider config not found for provider: %s", providerName) } -func createProvider(key, url, credentials string, providers *[]Provider) { +func createProvider(key, url string, credentials security.SensitiveString, providers *[]Provider) { priority := getProviderPriorityByURL(url) *providers = append(*providers, Provider{ Key: key, @@ -78,12 +79,12 @@ func (c *Client) prepareProviders(network *params.Network) []Provider { } // Add main and fallback providers - createProvider(ProviderMain, network.RPCURL, "", &providers) - createProvider(ProviderFallback, network.FallbackURL, "", &providers) + createProvider(ProviderMain, network.RPCURL, security.NewSensitiveString(""), &providers) + createProvider(ProviderFallback, network.FallbackURL, security.NewSensitiveString(""), &providers) // If the proxy provider is enabled, add it and its fallback options if proxyProvider.Enabled { - credentials := proxyProvider.User + ":" + proxyProvider.Password + credentials := security.NewSensitiveString(proxyProvider.User.Reveal() + ":" + proxyProvider.Password.Reveal()) createProvider(ProviderStatusProxy, network.DefaultRPCURL, credentials, &providers) createProvider(ProviderStatusProxyFallback, network.DefaultFallbackURL, credentials, &providers) createProvider(ProviderStatusProxyFallback2, network.DefaultFallbackURL2, credentials, &providers) diff --git a/services/wallet/thirdparty/alchemy/client.go b/services/wallet/thirdparty/alchemy/client.go index 4fe3c6b0711..38b6ec5b2d6 100644 --- a/services/wallet/thirdparty/alchemy/client.go +++ b/services/wallet/thirdparty/alchemy/client.go @@ -19,6 +19,7 @@ import ( walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/services/wallet/connection" "github.com/status-im/status-go/services/wallet/thirdparty" + "github.com/status-im/status-go/internal/security" ) const nftMetadataBatchLimit = 100 @@ -56,14 +57,14 @@ func (o *Client) IsConnected() bool { return o.connectionStatus.IsConnected() } -func getAPIKeySubpath(apiKey string) string { - if apiKey == "" { - return "demo" +func getAPIKeySubpath(apiKey security.SensitiveString) security.SensitiveString { + if apiKey.Empty() { + return security.NewSensitiveString("demo") } return apiKey } -func getNFTBaseURL(chainID walletCommon.ChainID, apiKey string) (string, error) { +func getNFTBaseURL(chainID walletCommon.ChainID, apiKey security.SensitiveString) (string, error) { baseURL, err := getBaseURL(chainID) if err != nil { @@ -76,13 +77,14 @@ func getNFTBaseURL(chainID walletCommon.ChainID, apiKey string) (string, error) type Client struct { thirdparty.CollectibleContractOwnershipProvider client *http.Client - apiKeys map[uint64]string + apiKeys map[uint64]security.SensitiveString connectionStatus *connection.Status } -func NewClient(apiKeys map[uint64]string) *Client { +func NewClient(apiKeys map[uint64]security.SensitiveString) *Client { for _, chainID := range walletCommon.AllChainIDs() { - if apiKeys[uint64(chainID)] == "" { + key := apiKeys[uint64(chainID)] + if key.Empty() { logutils.ZapLogger().Warn("Alchemy API key not available for", zap.Stringer("chainID", chainID)) } } diff --git a/services/wallet/thirdparty/cryptocompare/client.go b/services/wallet/thirdparty/cryptocompare/client.go index 80163de33d4..12b2f83d2ef 100644 --- a/services/wallet/thirdparty/cryptocompare/client.go +++ b/services/wallet/thirdparty/cryptocompare/client.go @@ -9,6 +9,7 @@ import ( "github.com/status-im/status-go/services/wallet/thirdparty" "github.com/status-im/status-go/services/wallet/thirdparty/utils" + "github.com/status-im/status-go/internal/security" ) const baseID = "cryptocompare" @@ -37,8 +38,8 @@ type MarketValuesContainer struct { type Params struct { ID string URL string - User string - Password string + User security.SensitiveString + Password security.SensitiveString } type Client struct { @@ -57,7 +58,7 @@ func NewClient() *Client { func NewClientWithParams(params Params) *Client { var creds *thirdparty.BasicCreds - if params.User != "" { + if !params.User.Empty() { creds = &thirdparty.BasicCreds{ User: params.User, Password: params.Password, diff --git a/services/wallet/thirdparty/http_client.go b/services/wallet/thirdparty/http_client.go index 7c8ad826a2e..df12bf5cad2 100644 --- a/services/wallet/thirdparty/http_client.go +++ b/services/wallet/thirdparty/http_client.go @@ -8,14 +8,15 @@ import ( "net/http" netUrl "net/url" "time" + "github.com/status-im/status-go/internal/security" ) const requestTimeout = 5 * time.Second const maxNumOfRequestRetries = 5 type BasicCreds struct { - User string - Password string + User security.SensitiveString + Password security.SensitiveString } type HTTPClient struct { @@ -41,7 +42,7 @@ func (c *HTTPClient) DoGetRequest(ctx context.Context, url string, params netUrl } if creds != nil { - req.SetBasicAuth(creds.User, creds.Password) + req.SetBasicAuth(creds.User.Reveal(), creds.Password.Reveal()) } var resp *http.Response @@ -77,7 +78,7 @@ func (c *HTTPClient) DoPostRequest(ctx context.Context, url string, params map[s } if creds != nil { - req.SetBasicAuth(creds.User, creds.Password) + req.SetBasicAuth(creds.User.Reveal(), creds.Password.Reveal()) } req.Header.Set("Content-Type", "application/json") diff --git a/services/wallet/thirdparty/opensea/client_v2.go b/services/wallet/thirdparty/opensea/client_v2.go index b53ca75d7c0..9595d2644e4 100644 --- a/services/wallet/thirdparty/opensea/client_v2.go +++ b/services/wallet/thirdparty/opensea/client_v2.go @@ -14,6 +14,7 @@ import ( walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/services/wallet/connection" "github.com/status-im/status-go/services/wallet/thirdparty" + "github.com/status-im/status-go/internal/security" ) const assetLimitV2 = 50 @@ -53,14 +54,14 @@ func getV2URL(chainID walletCommon.ChainID, path string) (string, error) { type ClientV2 struct { client *HTTPClient - apiKey string + apiKey security.SensitiveString connectionStatus *connection.Status urlGetter urlGetter } // new opensea v2 client. -func NewClientV2(apiKey string, httpClient *HTTPClient) *ClientV2 { - if apiKey == "" { +func NewClientV2(apiKey security.SensitiveString, httpClient *HTTPClient) *ClientV2 { + if apiKey.Empty() { logutils.ZapLogger().Warn("OpenseaV2 API key not available") } diff --git a/services/wallet/thirdparty/opensea/http_client.go b/services/wallet/thirdparty/opensea/http_client.go index 60089b7ec8e..5ab4cb1b63b 100644 --- a/services/wallet/thirdparty/opensea/http_client.go +++ b/services/wallet/thirdparty/opensea/http_client.go @@ -11,6 +11,7 @@ import ( "go.uber.org/zap" "github.com/status-im/status-go/logutils" + "github.com/status-im/status-go/internal/security" ) const requestTimeout = 5 * time.Second @@ -30,7 +31,7 @@ func NewHTTPClient() *HTTPClient { } } -func (o *HTTPClient) doGetRequest(ctx context.Context, url string, apiKey string) ([]byte, error) { +func (o *HTTPClient) doGetRequest(ctx context.Context, url string, apiKey security.SensitiveString) ([]byte, error) { // Ensure only one thread makes a request at a time o.getRequestLock.Lock() defer o.getRequestLock.Unlock() @@ -39,7 +40,7 @@ func (o *HTTPClient) doGetRequest(ctx context.Context, url string, apiKey string statusCode := http.StatusOK // Try to do the request without an apiKey first - tmpAPIKey := "" + var tmpAPIKey security.SensitiveString for { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) @@ -49,8 +50,8 @@ func (o *HTTPClient) doGetRequest(ctx context.Context, url string, apiKey string req.Header.Set("Content-Type", "application/json") req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0") - if len(tmpAPIKey) > 0 { - req.Header.Set("X-API-KEY", tmpAPIKey) + if tmpAPIKey.Empty() { + req.Header.Set("X-API-KEY", tmpAPIKey.Reveal()) } resp, err := o.client.Do(req) @@ -82,7 +83,7 @@ func (o *HTTPClient) doGetRequest(ctx context.Context, url string, apiKey string // break and error case http.StatusForbidden: // Request requires an apiKey, set it and retry - if tmpAPIKey == "" && apiKey != "" { + if tmpAPIKey.Empty() && !apiKey.Empty() { tmpAPIKey = apiKey // sleep and retry time.Sleep(getRequestWaitTime) diff --git a/services/wallet/thirdparty/rarible/client.go b/services/wallet/thirdparty/rarible/client.go index a41fe5a9b20..658555bd4fc 100644 --- a/services/wallet/thirdparty/rarible/client.go +++ b/services/wallet/thirdparty/rarible/client.go @@ -20,6 +20,7 @@ import ( walletCommon "github.com/status-im/status-go/services/wallet/common" "github.com/status-im/status-go/services/wallet/connection" "github.com/status-im/status-go/services/wallet/thirdparty" + "github.com/status-im/status-go/internal/security" ) const ownedNFTLimit = 100 @@ -85,17 +86,17 @@ func getCollectionBaseURL(chainID walletCommon.ChainID) (string, error) { type Client struct { thirdparty.CollectibleContractOwnershipProvider client *http.Client - mainnetAPIKey string - testnetAPIKey string + mainnetAPIKey security.SensitiveString + testnetAPIKey security.SensitiveString connectionStatus *connection.Status } -func NewClient(mainnetAPIKey string, testnetAPIKey string) *Client { - if mainnetAPIKey == "" { +func NewClient(mainnetAPIKey security.SensitiveString, testnetAPIKey security.SensitiveString) *Client { + if mainnetAPIKey.Empty() { logutils.ZapLogger().Warn("Rarible API key not available for Mainnet") } - if testnetAPIKey == "" { + if testnetAPIKey.Empty() { logutils.ZapLogger().Warn("Rarible API key not available for Testnet") } @@ -107,14 +108,14 @@ func NewClient(mainnetAPIKey string, testnetAPIKey string) *Client { } } -func (o *Client) getAPIKey(chainID walletCommon.ChainID) string { +func (o *Client) getAPIKey(chainID walletCommon.ChainID) security.SensitiveString { if chainID.IsMainnet() { return o.mainnetAPIKey } return o.testnetAPIKey } -func (o *Client) doQuery(ctx context.Context, url string, apiKey string) (*http.Response, error) { +func (o *Client) doQuery(ctx context.Context, url string, apiKey security.SensitiveString) (*http.Response, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, err @@ -125,7 +126,7 @@ func (o *Client) doQuery(ctx context.Context, url string, apiKey string) (*http. return o.doWithRetries(req, apiKey) } -func (o *Client) doPostWithJSON(ctx context.Context, url string, payload any, apiKey string) (*http.Response, error) { +func (o *Client) doPostWithJSON(ctx context.Context, url string, payload any, apiKey security.SensitiveString) (*http.Response, error) { payloadJSON, err := json.Marshal(payload) if err != nil { return nil, err @@ -145,7 +146,7 @@ func (o *Client) doPostWithJSON(ctx context.Context, url string, payload any, ap return o.doWithRetries(req, apiKey) } -func (o *Client) doWithRetries(req *http.Request, apiKey string) (*http.Response, error) { +func (o *Client) doWithRetries(req *http.Request, apiKey security.SensitiveString) (*http.Response, error) { b := backoff.NewExponentialBackOff() b.InitialInterval = time.Millisecond * 1000 b.RandomizationFactor = 0.1 @@ -155,7 +156,7 @@ func (o *Client) doWithRetries(req *http.Request, apiKey string) (*http.Response b.Reset() - req.Header.Set("X-API-KEY", apiKey) + req.Header.Set("X-API-KEY", apiKey.Reveal()) op := func() (*http.Response, error) { resp, err := o.client.Do(req) From 96e808ef6bd95c7959b3becaf586f651cfebe78b Mon Sep 17 00:00:00 2001 From: Igor Sirotin Date: Wed, 11 Dec 2024 22:06:53 +0000 Subject: [PATCH 2/2] wip --- api/default_networks.go | 89 ++++++++++++++------------- internal/security/sensitive_string.go | 6 ++ params/config.go | 42 ++++++------- protocol/requests/create_account.go | 4 +- rpc/network/network.go | 35 ++++++++--- 5 files changed, 101 insertions(+), 75 deletions(-) diff --git a/api/default_networks.go b/api/default_networks.go index f617cebeefd..4227270987b 100644 --- a/api/default_networks.go +++ b/api/default_networks.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/status-im/status-go/params" "github.com/status-im/status-go/protocol/requests" + "github.com/status-im/status-go/internal/security" ) const ( @@ -26,12 +27,12 @@ func mainnet(stageName string) params.Network { return params.Network{ 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), - DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/ethereum/mainnet/", stageName), - RPCURL: "https://mainnet.infura.io/v3/", - FallbackURL: "https://eth-archival.rpc.grove.city/v1/", - BlockExplorerURL: "https://etherscan.io/", + DefaultRPCURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/nodefleet/ethereum/mainnet/", stageName)), + DefaultFallbackURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/infura/ethereum/mainnet/", stageName)), + DefaultFallbackURL2: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/grove/ethereum/mainnet/", stageName)), + RPCURL: security.NewSensitiveString("https://mainnet.infura.io/v3/"), + FallbackURL: security.NewSensitiveString("https://eth-archival.rpc.grove.city/v1/"), + BlockExplorerURL: security.NewSensitiveString("https://etherscan.io/"), IconURL: "network/Network=Ethereum", ChainColor: "#627EEA", ShortName: "eth", @@ -49,12 +50,12 @@ func sepolia(stageName string) params.Network { return params.Network{ 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), - DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/ethereum/sepolia/", stageName), - RPCURL: "https://sepolia.infura.io/v3/", - FallbackURL: "https://sepolia-archival.rpc.grove.city/v1/", - BlockExplorerURL: "https://sepolia.etherscan.io/", + DefaultRPCURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/nodefleet/ethereum/sepolia/", stageName)), + DefaultFallbackURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/infura/ethereum/sepolia/", stageName)), + DefaultFallbackURL2: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/grove/ethereum/sepolia/", stageName)), + RPCURL: security.NewSensitiveString("https://sepolia.infura.io/v3/"), + FallbackURL: security.NewSensitiveString("https://sepolia-archival.rpc.grove.city/v1/"), + BlockExplorerURL: security.NewSensitiveString("https://sepolia.etherscan.io/"), IconURL: "network/Network=Ethereum", ChainColor: "#627EEA", ShortName: "eth", @@ -72,12 +73,12 @@ func optimism(stageName string) params.Network { return params.Network{ 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), - DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/optimism/mainnet/", stageName), - RPCURL: "https://optimism-mainnet.infura.io/v3/", - FallbackURL: "https://optimism-archival.rpc.grove.city/v1/", - BlockExplorerURL: "https://optimistic.etherscan.io", + DefaultRPCURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/nodefleet/optimism/mainnet/", stageName)), + DefaultFallbackURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/infura/optimism/mainnet/", stageName)), + DefaultFallbackURL2: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/grove/optimism/mainnet/", stageName)), + RPCURL: security.NewSensitiveString("https://optimism-mainnet.infura.io/v3/"), + FallbackURL: security.NewSensitiveString("https://optimism-archival.rpc.grove.city/v1/"), + BlockExplorerURL: security.NewSensitiveString("https://optimistic.etherscan.io"), IconURL: "network/Network=Optimism", ChainColor: "#E90101", ShortName: "oeth", @@ -95,12 +96,12 @@ func optimismSepolia(stageName string) params.Network { return params.Network{ 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), - DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/optimism/sepolia/", stageName), - RPCURL: "https://optimism-sepolia.infura.io/v3/", - FallbackURL: "https://optimism-sepolia-archival.rpc.grove.city/v1/", - BlockExplorerURL: "https://sepolia-optimism.etherscan.io/", + DefaultRPCURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/nodefleet/optimism/sepolia/", stageName)), + DefaultFallbackURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/infura/optimism/sepolia/", stageName)), + DefaultFallbackURL2: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/grove/optimism/sepolia/", stageName)), + RPCURL: security.NewSensitiveString("https://optimism-sepolia.infura.io/v3/"), + FallbackURL: security.NewSensitiveString("https://optimism-sepolia-archival.rpc.grove.city/v1/"), + BlockExplorerURL: security.NewSensitiveString("https://sepolia-optimism.etherscan.io/"), IconURL: "network/Network=Optimism", ChainColor: "#E90101", ShortName: "oeth", @@ -118,12 +119,12 @@ func arbitrum(stageName string) params.Network { return params.Network{ 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), - DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/arbitrum/mainnet/", stageName), - RPCURL: "https://arbitrum-mainnet.infura.io/v3/", - FallbackURL: "https://arbitrum-one.rpc.grove.city/v1/", - BlockExplorerURL: "https://arbiscan.io/", + DefaultRPCURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/nodefleet/arbitrum/mainnet/", stageName)), + DefaultFallbackURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/infura/arbitrum/mainnet/", stageName)), + DefaultFallbackURL2: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/grove/arbitrum/mainnet/", stageName)), + RPCURL: security.NewSensitiveString("https://arbitrum-mainnet.infura.io/v3/"), + FallbackURL: security.NewSensitiveString("https://arbitrum-one.rpc.grove.city/v1/"), + BlockExplorerURL: security.NewSensitiveString("https://arbiscan.io/"), IconURL: "network/Network=Arbitrum", ChainColor: "#51D0F0", ShortName: "arb1", @@ -141,12 +142,12 @@ func arbitrumSepolia(stageName string) params.Network { return params.Network{ 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), - DefaultFallbackURL2: fmt.Sprintf("https://%s.api.status.im/grove/arbitrum/sepolia/", stageName), - RPCURL: "https://arbitrum-sepolia.infura.io/v3/", - FallbackURL: "https://arbitrum-sepolia-archival.rpc.grove.city/v1/", - BlockExplorerURL: "https://sepolia-explorer.arbitrum.io/", + DefaultRPCURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/nodefleet/arbitrum/sepolia/", stageName)), + DefaultFallbackURL: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/infura/arbitrum/sepolia/", stageName)), + DefaultFallbackURL2: security.NewSensitiveString(fmt.Sprintf("https://%s.api.status.im/grove/arbitrum/sepolia/", stageName)), + RPCURL: security.NewSensitiveString("https://arbitrum-sepolia.infura.io/v3/"), + FallbackURL: security.NewSensitiveString("https://arbitrum-sepolia-archival.rpc.grove.city/v1/"), + BlockExplorerURL: security.NewSensitiveString("https://sepolia-explorer.arbitrum.io/"), IconURL: "network/Network=Arbitrum", ChainColor: "#51D0F0", ShortName: "arb1", @@ -185,13 +186,15 @@ func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) [ grove = "grove.city/" ) - appendToken := func(url string) string { - if strings.Contains(url, infura) && !request.InfuraToken.Empty() { - return url + request.InfuraToken - } else if strings.Contains(url, grove) && request.PoktToken != "" { - return url + request.PoktToken + appendToken := func(url security.SensitiveString) security.SensitiveString { + urlRevealed := url.Reveal() + switch { + case strings.Contains(urlRevealed, infura) && !request.InfuraToken.Empty(): + urlRevealed += request.InfuraToken.Reveal() + case strings.Contains(urlRevealed, grove) && !request.PoktToken.Empty(): + urlRevealed += request.PoktToken.Reveal() } - return url + return security.NewSensitiveString(urlRevealed) } for _, n := range networks { @@ -201,7 +204,7 @@ func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) [ n.RPCURL = appendToken(n.RPCURL) n.FallbackURL = appendToken(n.FallbackURL) - if request.GanacheURL != "" { + if !request.GanacheURL.Empty() { n.RPCURL = request.GanacheURL n.FallbackURL = request.GanacheURL if n.ChainID == mainnetChainID { diff --git a/internal/security/sensitive_string.go b/internal/security/sensitive_string.go index 70387ed4e4a..0b29cde2a41 100644 --- a/internal/security/sensitive_string.go +++ b/internal/security/sensitive_string.go @@ -2,6 +2,7 @@ package security import ( "encoding/json" + "fmt" ) const RedactionPlaceholder = "***" @@ -20,6 +21,11 @@ func NewSensitiveString(value string) SensitiveString { return SensitiveString{value: value} } +func NewSensitiveStringPrintf(format string, args ...interface{}) SensitiveString { + str := fmt.Sprintf(format, args...) + return NewSensitiveString(str) +} + // String provides a redacted version of the sensitive string func (s SensitiveString) String() string { if s.value == "" { diff --git a/params/config.go b/params/config.go index 4a289bce1e9..6a6c64cecb2 100644 --- a/params/config.go +++ b/params/config.go @@ -521,27 +521,27 @@ type TokenOverride struct { } 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"` + ChainID uint64 `json:"chainId"` + ChainName string `json:"chainName"` + DefaultRPCURL security.SensitiveString `json:"defaultRpcUrl"` // proxy rpc url + DefaultFallbackURL security.SensitiveString `json:"defaultFallbackURL"` // proxy fallback url + DefaultFallbackURL2 security.SensitiveString `json:"defaultFallbackURL2"` // second proxy fallback url + RPCURL security.SensitiveString `json:"rpcUrl"` + OriginalRPCURL security.SensitiveString `json:"originalRpcUrl"` + FallbackURL security.SensitiveString `json:"fallbackURL"` + OriginalFallbackURL security.SensitiveString `json:"originalFallbackURL"` + BlockExplorerURL security.SensitiveString `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. diff --git a/protocol/requests/create_account.go b/protocol/requests/create_account.go index e4c24e75923..daea4d6995d 100644 --- a/protocol/requests/create_account.go +++ b/protocol/requests/create_account.go @@ -90,7 +90,7 @@ type CreateAccount struct { } type WalletSecretsConfig struct { - PoktToken string `json:"poktToken"` + PoktToken security.SensitiveString `json:"poktToken"` InfuraToken security.SensitiveString `json:"infuraToken"` InfuraSecret security.SensitiveString `json:"infuraSecret"` OpenseaAPIKey security.SensitiveString `json:"openseaApiKey"` @@ -111,7 +111,7 @@ type WalletSecretsConfig struct { StatusProxyBlockchainPassword security.SensitiveString `json:"statusProxyBlockchainPassword"` // Testing - GanacheURL string `json:"ganacheURL"` + GanacheURL security.SensitiveString `json:"ganacheURL"` } func (c *CreateAccount) Validate(validation *CreateAccountValidation) error { diff --git a/rpc/network/network.go b/rpc/network/network.go index dfab0efb839..bbfaf63255d 100644 --- a/rpc/network/network.go +++ b/rpc/network/network.go @@ -9,6 +9,7 @@ import ( "github.com/status-im/status-go/multiaccounts/accounts" "github.com/status-im/status-go/params" + "github.com/status-im/status-go/internal/security" ) var SepoliaChainIDs = []uint64{11155111, 421614, 11155420} @@ -193,9 +194,22 @@ func (nm *Manager) Init(networks []params.Network) error { func (nm *Manager) Upsert(network *params.Network) error { _, err := nm.db.Exec( "INSERT OR REPLACE INTO networks (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) 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.ChainID, + network.ChainName, + network.RPCURL.Reveal(), + network.OriginalRPCURL.Reveal(), + network.FallbackURL.Reveal(), + network.OriginalFallbackURL.Reveal(), + network.BlockExplorerURL.Reveal(), + network.IconURL, + network.NativeCurrencyName, + network.NativeCurrencySymbol, + network.NativeCurrencyDecimals, + network.IsTest, + network.Layer, + network.Enabled, + network.ChainColor, + network.ShortName, network.RelatedChainID, ) return err @@ -211,18 +225,21 @@ func (nm *Manager) UpdateRelatedChainID(chainID uint64, relatedChainID uint64) e return err } -func (nm *Manager) updateRPCURL(chainID uint64, rpcURL string) error { - _, err := nm.db.Exec(`UPDATE networks SET rpc_url = ? WHERE chain_id = ?`, rpcURL, chainID) +func (nm *Manager) updateRPCURL(chainID uint64, rpcURL security.SensitiveString) error { + _, err := nm.db.Exec(`UPDATE networks SET rpc_url = ? WHERE chain_id = ?`, rpcURL.Reveal(), chainID) return err } -func (nm *Manager) updateFallbackURL(chainID uint64, fallbackURL string) error { - _, err := nm.db.Exec(`UPDATE networks SET fallback_url = ? WHERE chain_id = ?`, fallbackURL, chainID) +func (nm *Manager) updateFallbackURL(chainID uint64, fallbackURL security.SensitiveString) error { + _, err := nm.db.Exec(`UPDATE networks SET fallback_url = ? WHERE chain_id = ?`, fallbackURL.Reveal(), chainID) return err } -func (nm *Manager) updateOriginalURLs(chainID uint64, originalRPCURL, OriginalFallbackURL string) error { - _, err := nm.db.Exec(`UPDATE networks SET original_rpc_url = ?, original_fallback_url = ? WHERE chain_id = ?`, originalRPCURL, OriginalFallbackURL, chainID) +func (nm *Manager) updateOriginalURLs(chainID uint64, originalRPCURL, OriginalFallbackURL security.SensitiveString) error { + _, err := nm.db.Exec(`UPDATE networks SET original_rpc_url = ?, original_fallback_url = ? WHERE chain_id = ?`, + originalRPCURL.Reveal(), + OriginalFallbackURL.Reveal(), + chainID) return err }