Files
Igor Sirotin c66ed5f558 refactor: move network defaults into the networks service (#7749)
params/networkdefaults holds the embedded network table and builds the
default network list. It belongs with the service that owns networks,
not in params.

Dissolved into the networks package rather than kept as a subpackage:
BuildDefaultNetworks reads better than defaults.BuildDefaultNetworks,
and the next commit unexports the helpers both halves share.
2026-08-26 18:05:03 +01:00

405 lines
13 KiB
Go

package backend
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
accscommon "github.com/status-im/status-go/internal/accounts-management/common"
"github.com/status-im/status-go/internal/accounts-management/generator"
"github.com/status-im/status-go/internal/crypto/types"
settings "github.com/status-im/status-go/internal/db/multiaccounts/settings"
"github.com/status-im/status-go/internal/logutils"
"github.com/status-im/status-go/internal/protocol"
"github.com/status-im/status-go/internal/protocol/identity/alias"
"github.com/status-im/status-go/internal/protocol/protobuf"
"github.com/status-im/status-go/internal/protocol/requests"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/pkg/messaging"
"github.com/status-im/status-go/pkg/services/networks"
walletcommon "github.com/status-im/status-go/pkg/services/wallet/common"
)
const (
defaultMnemonicLength = 12
walletAccountDefaultName = "Account 1"
walletAccountDefaultEmoji = "🛡️"
DefaultKeystoreRelativePath = "keystore"
DefaultKeycardPairingDataFileRelativePath = "/keycard/pairings.json"
DefaultAPILogFile = "api.log"
DefaultLogLevel = "ERROR"
DefaultCurrentNetwork = "mainnet_rpc"
DefaultMaxMessageDeliveryAttempts = 3
)
var (
paths = []string{accscommon.PathWalletRoot, accscommon.PathEIP1581Root, accscommon.PathEIP1581Chat, accscommon.PathDefaultWalletAccount, accscommon.PathEIP1581Encryption}
DefaultFleet = params.FleetStatusProd
)
func ResolveDefaultFleet() string {
if envFleet := os.Getenv("STATUS_FLEET"); envFleet != "" && params.IsFleetSupported(envFleet) {
return envFleet
}
return DefaultFleet
}
func defaultSettings(keyUID string, address string, derivedAddresses map[string]generator.AccountInfo) (*settings.Settings, error) {
chatKeyString := derivedAddresses[accscommon.PathEIP1581Chat].PublicKey
s := &settings.Settings{}
logLevel := "INFO"
s.LogLevel = &logLevel
s.ProfilePicturesShowTo = settings.ProfilePicturesShowToEveryone
s.ProfilePicturesVisibility = settings.ProfilePicturesVisibilityEveryone
s.KeyUID = keyUID
s.Address = types.HexToAddress(address)
s.WalletRootAddress = types.HexToAddress(derivedAddresses[accscommon.PathWalletRoot].Address)
s.URLUnfurlingMode = settings.URLUnfurlingAlwaysAsk
// Set the chat key and name
name, err := alias.GenerateFromPublicKeyString(chatKeyString)
if err != nil {
return nil, err
}
s.Name = name
s.PublicKey = chatKeyString
s.DappsAddress = types.HexToAddress(derivedAddresses[accscommon.PathDefaultWalletAccount].Address)
s.EIP1581Address = types.HexToAddress(derivedAddresses[accscommon.PathEIP1581Root].Address)
s.SendPushNotifications = true
s.InstallationID = messaging.GenerateInstallationID()
s.UseMailservers = true
s.AutoApplyKeypairMigrations = true
s.PreviewPrivacy = true
s.Currency = "usd"
s.LinkPreviewRequestEnabled = true
visibleTokens := make(map[string][]string)
visibleTokens["mainnet"] = []string{"SNT"}
visibleTokensJSON, err := json.Marshal(visibleTokens)
if err != nil {
return nil, err
}
visibleTokenJSONRaw := json.RawMessage(visibleTokensJSON)
s.WalletVisibleTokens = &visibleTokenJSONRaw
// TODO: fix this
networks := make([]map[string]string, 0)
networksJSON, err := json.Marshal(networks)
if err != nil {
return nil, err
}
networkRawMessage := json.RawMessage(networksJSON)
s.Networks = &networkRawMessage
s.CurrentNetwork = DefaultCurrentNetwork
s.TokenGroupByCommunity = false
s.ShowCommunityAssetWhenSendingTokens = true
s.DisplayAssetsBelowBalance = false
s.TestNetworksEnabled = false
s.AutoRefreshTokensEnabled = true
// Default user status
currentUserStatus, err := json.Marshal(protocol.UserStatus{
PublicKey: chatKeyString,
StatusType: int(protobuf.StatusUpdate_AUTOMATIC),
Clock: 0,
CustomText: "",
})
if err != nil {
return nil, err
}
userRawMessage := json.RawMessage(currentUserStatus)
s.CurrentUserStatus = &userRawMessage
return s, nil
}
func SetFleet(fleet string, nodeConfig *params.NodeConfig) error {
specifiedWakuV2Config := nodeConfig.WakuV2Config
nodeConfig.WakuV2Config = params.WakuV2Config{
Enabled: true,
DiscoveryLimit: 20,
Host: "0.0.0.0",
AutoUpdate: true,
// mobile may need to override the following options
LightClient: specifiedWakuV2Config.LightClient,
Nameserver: specifiedWakuV2Config.Nameserver,
}
if !params.IsFleetSupported(fleet) {
return fmt.Errorf("unknown fleet %s", fleet)
}
nodeConfig.ClusterConfig = params.DefaultClusterConfig(fleet)
return nil
}
func buildWalletConfig(walletRequest *requests.WalletConfig, request *requests.WalletSecretsConfig) params.WalletConfig {
walletConfig := params.WalletConfig{
Enabled: true,
EnableMercuryoProvider: true,
TokensListsAutoRefreshCheckInterval: walletRequest.TokensListsAutoRefreshCheckInterval,
TokensListsAutoRefreshInterval: walletRequest.TokensListsAutoRefreshInterval,
}
if request.StatusProxyStageName != "" {
walletConfig.StatusProxyStageName = request.StatusProxyStageName
}
if !request.RaribleMainnetAPIKey.Empty() {
walletConfig.RaribleMainnetAPIKey = request.RaribleMainnetAPIKey
}
if !request.RaribleTestnetAPIKey.Empty() {
walletConfig.RaribleTestnetAPIKey = request.RaribleTestnetAPIKey
}
if !request.InfuraToken.Empty() {
walletConfig.InfuraAPIKey = request.InfuraToken
}
if !request.PoktToken.Empty() {
walletConfig.PoktAPIKey = request.PoktToken
}
if !request.InfuraSecret.Empty() {
walletConfig.InfuraAPIKeySecret = request.InfuraSecret
}
if !request.AlchemyAPIKey.Empty() {
walletConfig.AlchemyAPIKey = request.AlchemyAPIKey
}
if !request.MarketDataProxyUser.Empty() {
walletConfig.MarketDataProxyConfig.User = request.MarketDataProxyUser
}
if !request.MarketDataProxyPassword.Empty() {
walletConfig.MarketDataProxyConfig.Password = request.MarketDataProxyPassword
}
if !request.MarketDataProxyUrl.Empty() {
walletConfig.MarketDataProxyConfig.UrlOverride = request.MarketDataProxyUrl
}
if !request.CoingeckoAPIKey.Empty() {
walletConfig.CoingeckoAPIKey = request.CoingeckoAPIKey
}
if !request.CoingeckoDemoAPIKey.Empty() {
walletConfig.CoingeckoDemoAPIKey = request.CoingeckoDemoAPIKey
}
if request.StatusProxyStageName != "" {
walletConfig.MarketDataProxyConfig.StageName = request.StatusProxyStageName
}
if walletRequest.MarketDataFullDataRefreshInterval != 0 {
walletConfig.MarketDataProxyConfig.FullDataRefreshInterval = walletRequest.MarketDataFullDataRefreshInterval
}
if walletRequest.MarketDataPriceRefreshInterval != 0 {
walletConfig.MarketDataProxyConfig.PriceRefreshInterval = walletRequest.MarketDataPriceRefreshInterval
}
if len(walletRequest.MulticallOverrides) > 0 {
walletConfig.MulticallOverrides = walletRequest.MulticallOverrides
}
if len(walletRequest.CommunityTokenDeployerOverrides) > 0 {
walletConfig.CommunityTokenDeployerOverrides = walletRequest.CommunityTokenDeployerOverrides
}
if len(walletRequest.CustomTokens) > 0 {
walletConfig.CustomTokens = walletRequest.CustomTokens
}
if !request.EthRpcProxyUrl.Empty() {
walletConfig.EthRpcProxyUrl = request.EthRpcProxyUrl
}
if !request.EthRpcProxyUser.Empty() {
walletConfig.EthRpcProxyUser = request.EthRpcProxyUser
}
if !request.EthRpcProxyPassword.Empty() {
walletConfig.EthRpcProxyPassword = request.EthRpcProxyPassword
}
walletConfig.EthRpcProxyUsePuzzleAuth = request.EthRpcProxyUsePuzzleAuth
// NftProxyConfig
if !request.NftProxyUrl.Empty() {
walletConfig.NftProxyConfig.UrlOverride = request.NftProxyUrl
}
if request.NftProxyStageName != "" {
walletConfig.NftProxyConfig.StageName = request.NftProxyStageName
}
if !request.NftProxyUser.Empty() {
walletConfig.NftProxyConfig.User = request.NftProxyUser
}
if !request.NftProxyPassword.Empty() {
walletConfig.NftProxyConfig.Password = request.NftProxyPassword
}
walletConfig.NftProxyConfig.UsePuzzleAuth = request.NftProxyUsePuzzleAuth
return walletConfig
}
func overrideApiConfig(nodeConfig *params.NodeConfig, config *requests.APIConfig) {
nodeConfig.APIModules = config.APIModules
nodeConfig.ConnectorConfig.Enabled = config.ConnectorEnabled
nodeConfig.HTTPEnabled = config.HTTPEnabled
nodeConfig.HTTPHost = config.HTTPHost
nodeConfig.HTTPPort = config.HTTPPort
nodeConfig.HTTPVirtualHosts = config.HTTPVirtualHosts
nodeConfig.WSEnabled = config.WSEnabled
nodeConfig.WSHost = config.WSHost
nodeConfig.WSPort = config.WSPort
}
// getMainnetRPCURL returns URL of the first provider with TokenAuth from mainnet network
func getMainnetRPCURL(networks []params.Network) string {
for _, network := range networks {
if network.ChainID != walletcommon.EthereumMainnet {
continue
}
for _, provider := range network.RpcProviders {
if provider.AuthType == params.TokenAuth && provider.Enabled {
return provider.GetFullURL().Reveal()
}
}
break
}
return ""
}
func DefaultNodeConfig(installationID, keyUID string, request *requests.CreateAccount) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.RootDataDir = request.RootDataDir
nodeConfig.LogEnabled = request.LogEnabled
nodeConfig.LogToStderr = request.LogToStderr
nodeConfig.LogFile = logutils.TruncateWithDot(keyUID) + ".log"
nodeConfig.LogDir = request.LogFilePath
nodeConfig.LogLevel = DefaultLogLevel
nodeConfig.KeycardPairingDataFile = filepath.Join(nodeConfig.RootDataDir, DefaultKeycardPairingDataFileRelativePath)
if request.KeycardPairingDataFile != nil {
nodeConfig.KeycardPairingDataFile = *request.KeycardPairingDataFile
}
if request.LogLevel != nil {
nodeConfig.LogLevel = *request.LogLevel
nodeConfig.LogEnabled = true
} else {
nodeConfig.LogEnabled = false
}
nodeConfig.WalletConfig = buildWalletConfig(&request.WalletConfig, &request.WalletSecretsConfig)
if request.TestOverrideNetworks != nil {
nodeConfig.Networks = request.TestOverrideNetworks
} else {
nodeConfig.Networks = networks.BuildDefaultNetworks(&nodeConfig.WalletConfig, request.ThirdpartyServicesEnabled)
}
if request.NetworkID != nil {
nodeConfig.NetworkID = *request.NetworkID
} else {
nodeConfig.NetworkID = nodeConfig.Networks[0].ChainID
}
nodeConfig.BrowsersConfig = params.BrowsersConfig{Enabled: true}
nodeConfig.PermissionsConfig = params.PermissionsConfig{Enabled: true}
fleet := request.WakuV2Fleet
if fleet == "" {
fleet = ResolveDefaultFleet()
}
err := SetFleet(fleet, nodeConfig)
if err != nil {
return nil, err
}
if request.WakuV2LightClient {
nodeConfig.WakuV2Config.LightClient = true
}
if request.WakuV2Nameserver != nil {
nodeConfig.WakuV2Config.Nameserver = *request.WakuV2Nameserver
}
nodeConfig.ShhextConfig = params.ShhextConfig{
InstallationID: installationID,
MailServerConfirmations: true,
MaxMessageDeliveryAttempts: DefaultMaxMessageDeliveryAttempts,
DataSyncEnabled: true,
PFSEnabled: true,
AllowForceCommunityMembersReevaluation: os.Getenv("STATUS_ALLOW_FORCE_REEVAL") == "1",
}
nodeConfig.ShhextConfig.VerifyENSURL = getMainnetRPCURL(nodeConfig.Networks)
if request.VerifyENSContractAddress != nil {
nodeConfig.ShhextConfig.VerifyENSContractAddress = *request.VerifyENSContractAddress
}
if request.NetworkID != nil {
nodeConfig.NetworkID = *request.NetworkID
}
nodeConfig.TorrentConfig = params.TorrentConfig{
Enabled: false,
Port: 0,
DataDir: filepath.Join(nodeConfig.RootDataDir, params.ArchivesRelativePath),
TorrentDir: filepath.Join(nodeConfig.RootDataDir, params.TorrentTorrentsRelativePath),
}
if request.TorrentConfigEnabled != nil {
nodeConfig.TorrentConfig.Enabled = *request.TorrentConfigEnabled
}
if request.TorrentConfigPort != nil {
nodeConfig.TorrentConfig.Port = *request.TorrentConfigPort
}
if request.LogosStorageConfigEnabled != nil {
nodeConfig.LogosStorageConfig.Enabled = *request.LogosStorageConfigEnabled
}
if request.LogosStorageConfigBootstrapNode != nil {
nodeConfig.LogosStorageConfig.NodeConfig.BootstrapNodes = []string{*request.LogosStorageConfigBootstrapNode}
}
nodeConfig.LogosStorageConfig = params.LogosStorageConfig{
Enabled: nodeConfig.LogosStorageConfig.Enabled,
NodeConfig: params.LogosStorageNodeConfig{
DataDir: filepath.Join(nodeConfig.RootDataDir, "logos-storage", "data"),
BlockRetries: params.DefaultLogosStorageBlockRetries,
MetricsEnabled: false,
LogFormat: "nocolors",
BootstrapNodes: nodeConfig.LogosStorageConfig.NodeConfig.BootstrapNodes,
},
}
if request.ImportInitialDelay != nil {
nodeConfig.ImportInitialDelay = *request.ImportInitialDelay
}
if request.MessageArchiveInterval != nil {
nodeConfig.MessageArchiveInterval = *request.MessageArchiveInterval
}
if request.APIConfig != nil {
overrideApiConfig(nodeConfig, request.APIConfig)
}
return nodeConfig, nil
}
func DefaultKeystorePath(rootDataDir string, keyUID string) (string, string) {
relativePath := filepath.Join(DefaultKeystoreRelativePath, keyUID)
absolutePath := filepath.Join(rootDataDir, relativePath)
return relativePath, absolutePath
}