github.com/status-im/status-go@v1.1.0/api/defaults.go (about)

     1  package api
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/json"
     6  	"math/big"
     7  	"path/filepath"
     8  
     9  	"github.com/status-im/status-go/account/generator"
    10  	"github.com/status-im/status-go/eth-node/types"
    11  	"github.com/status-im/status-go/multiaccounts/settings"
    12  	"github.com/status-im/status-go/params"
    13  	"github.com/status-im/status-go/protocol"
    14  	"github.com/status-im/status-go/protocol/encryption/multidevice"
    15  	"github.com/status-im/status-go/protocol/identity/alias"
    16  	"github.com/status-im/status-go/protocol/protobuf"
    17  	"github.com/status-im/status-go/protocol/requests"
    18  )
    19  
    20  const (
    21  	pathWalletRoot           = "m/44'/60'/0'/0"
    22  	pathEIP1581              = "m/43'/60'/1581'"
    23  	pathDefaultChat          = pathEIP1581 + "/0'/0"
    24  	pathEncryption           = pathEIP1581 + "/1'/0"
    25  	pathDefaultWallet        = pathWalletRoot + "/0"
    26  	defaultMnemonicLength    = 12
    27  	shardsTestClusterID      = 16
    28  	walletAccountDefaultName = "Account 1"
    29  
    30  	DefaultKeystoreRelativePath       = "keystore"
    31  	DefaultKeycardPairingDataFile     = "/ethereum/mainnet_rpc/keycard/pairings.json"
    32  	DefaultDataDir                    = "/ethereum/mainnet_rpc"
    33  	DefaultNodeName                   = "StatusIM"
    34  	DefaultLogFile                    = "geth.log"
    35  	DefaultLogLevel                   = "ERROR"
    36  	DefaultMaxPeers                   = 20
    37  	DefaultMaxPendingPeers            = 20
    38  	DefaultListenAddr                 = ":0"
    39  	DefaultMaxMessageDeliveryAttempts = 3
    40  	DefaultVerifyTransactionChainID   = 1
    41  	DefaultCurrentNetwork             = "mainnet_rpc"
    42  )
    43  
    44  var (
    45  	paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet, pathEncryption}
    46  
    47  	DefaultFleet = params.FleetStatusProd
    48  
    49  	overrideApiConfig = overrideApiConfigProd
    50  )
    51  
    52  func defaultSettings(keyUID string, address string, derivedAddresses map[string]generator.AccountInfo) (*settings.Settings, error) {
    53  	chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
    54  
    55  	s := &settings.Settings{}
    56  	s.BackupEnabled = true
    57  	logLevel := "INFO"
    58  	s.LogLevel = &logLevel
    59  	s.ProfilePicturesShowTo = settings.ProfilePicturesShowToEveryone
    60  	s.ProfilePicturesVisibility = settings.ProfilePicturesVisibilityEveryone
    61  	s.KeyUID = keyUID
    62  	s.Address = types.HexToAddress(address)
    63  	s.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address)
    64  	s.URLUnfurlingMode = settings.URLUnfurlingAlwaysAsk
    65  
    66  	// Set chat key & name
    67  	name, err := alias.GenerateFromPublicKeyString(chatKeyString)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	s.Name = name
    72  	s.PublicKey = chatKeyString
    73  
    74  	s.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address)
    75  	s.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address)
    76  
    77  	signingPhrase, err := buildSigningPhrase()
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	s.SigningPhrase = signingPhrase
    82  
    83  	s.SendPushNotifications = true
    84  	s.InstallationID = multidevice.GenerateInstallationID()
    85  	s.UseMailservers = true
    86  
    87  	s.PreviewPrivacy = true
    88  	s.PeerSyncingEnabled = false
    89  	s.Currency = "usd"
    90  	s.LinkPreviewRequestEnabled = true
    91  
    92  	visibleTokens := make(map[string][]string)
    93  	visibleTokens["mainnet"] = []string{"SNT"}
    94  	visibleTokensJSON, err := json.Marshal(visibleTokens)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	visibleTokenJSONRaw := json.RawMessage(visibleTokensJSON)
    99  	s.WalletVisibleTokens = &visibleTokenJSONRaw
   100  
   101  	// TODO: fix this
   102  	networks := make([]map[string]string, 0)
   103  	networksJSON, err := json.Marshal(networks)
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  	networkRawMessage := json.RawMessage(networksJSON)
   108  	s.Networks = &networkRawMessage
   109  	s.CurrentNetwork = DefaultCurrentNetwork
   110  
   111  	s.TokenGroupByCommunity = false
   112  	s.ShowCommunityAssetWhenSendingTokens = true
   113  	s.DisplayAssetsBelowBalance = false
   114  
   115  	s.TestNetworksEnabled = false
   116  
   117  	// Default user status
   118  	currentUserStatus, err := json.Marshal(protocol.UserStatus{
   119  		PublicKey:  chatKeyString,
   120  		StatusType: int(protobuf.StatusUpdate_AUTOMATIC),
   121  		Clock:      0,
   122  		CustomText: "",
   123  	})
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  	userRawMessage := json.RawMessage(currentUserStatus)
   128  	s.CurrentUserStatus = &userRawMessage
   129  
   130  	return s, nil
   131  }
   132  
   133  func SetDefaultFleet(nodeConfig *params.NodeConfig) error {
   134  	return SetFleet(DefaultFleet, nodeConfig)
   135  }
   136  
   137  func SetFleet(fleet string, nodeConfig *params.NodeConfig) error {
   138  	specifiedWakuV2Config := nodeConfig.WakuV2Config
   139  	nodeConfig.WakuV2Config = params.WakuV2Config{
   140  		Enabled:        true,
   141  		EnableDiscV5:   true,
   142  		DiscoveryLimit: 20,
   143  		Host:           "0.0.0.0",
   144  		AutoUpdate:     true,
   145  		// mobile may need override following options
   146  		LightClient:                            specifiedWakuV2Config.LightClient,
   147  		EnableStoreConfirmationForMessagesSent: specifiedWakuV2Config.EnableStoreConfirmationForMessagesSent,
   148  		EnableMissingMessageVerification:       specifiedWakuV2Config.EnableMissingMessageVerification,
   149  		Nameserver:                             specifiedWakuV2Config.Nameserver,
   150  	}
   151  
   152  	clusterConfig, err := params.LoadClusterConfigFromFleet(fleet)
   153  	if err != nil {
   154  		return err
   155  	}
   156  	nodeConfig.ClusterConfig = *clusterConfig
   157  	nodeConfig.ClusterConfig.Fleet = fleet
   158  	nodeConfig.ClusterConfig.WakuNodes = params.DefaultWakuNodes(fleet)
   159  	nodeConfig.ClusterConfig.DiscV5BootstrapNodes = params.DefaultDiscV5Nodes(fleet)
   160  
   161  	if fleet == params.FleetStatusProd {
   162  		nodeConfig.ClusterConfig.ClusterID = shardsTestClusterID
   163  	}
   164  
   165  	return nil
   166  }
   167  
   168  func buildWalletConfig(request *requests.WalletSecretsConfig, statusProxyEnabled bool) params.WalletConfig {
   169  	walletConfig := params.WalletConfig{
   170  		Enabled:        true,
   171  		AlchemyAPIKeys: make(map[uint64]string),
   172  	}
   173  
   174  	if request.StatusProxyStageName != "" {
   175  		walletConfig.StatusProxyStageName = request.StatusProxyStageName
   176  	}
   177  
   178  	if request.OpenseaAPIKey != "" {
   179  		walletConfig.OpenseaAPIKey = request.OpenseaAPIKey
   180  	}
   181  
   182  	if request.RaribleMainnetAPIKey != "" {
   183  		walletConfig.RaribleMainnetAPIKey = request.RaribleMainnetAPIKey
   184  	}
   185  
   186  	if request.RaribleTestnetAPIKey != "" {
   187  		walletConfig.RaribleTestnetAPIKey = request.RaribleTestnetAPIKey
   188  	}
   189  
   190  	if request.InfuraToken != "" {
   191  		walletConfig.InfuraAPIKey = request.InfuraToken
   192  	}
   193  
   194  	if request.InfuraSecret != "" {
   195  		walletConfig.InfuraAPIKeySecret = request.InfuraSecret
   196  	}
   197  
   198  	if request.AlchemyEthereumMainnetToken != "" {
   199  		walletConfig.AlchemyAPIKeys[mainnetChainID] = request.AlchemyEthereumMainnetToken
   200  	}
   201  	if request.AlchemyEthereumGoerliToken != "" {
   202  		walletConfig.AlchemyAPIKeys[goerliChainID] = request.AlchemyEthereumGoerliToken
   203  	}
   204  	if request.AlchemyEthereumSepoliaToken != "" {
   205  		walletConfig.AlchemyAPIKeys[sepoliaChainID] = request.AlchemyEthereumSepoliaToken
   206  	}
   207  	if request.AlchemyArbitrumMainnetToken != "" {
   208  		walletConfig.AlchemyAPIKeys[arbitrumChainID] = request.AlchemyArbitrumMainnetToken
   209  	}
   210  	if request.AlchemyArbitrumGoerliToken != "" {
   211  		walletConfig.AlchemyAPIKeys[arbitrumGoerliChainID] = request.AlchemyArbitrumGoerliToken
   212  	}
   213  	if request.AlchemyArbitrumSepoliaToken != "" {
   214  		walletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken
   215  	}
   216  	if request.AlchemyOptimismMainnetToken != "" {
   217  		walletConfig.AlchemyAPIKeys[optimismChainID] = request.AlchemyOptimismMainnetToken
   218  	}
   219  	if request.AlchemyOptimismGoerliToken != "" {
   220  		walletConfig.AlchemyAPIKeys[optimismGoerliChainID] = request.AlchemyOptimismGoerliToken
   221  	}
   222  	if request.AlchemyOptimismSepoliaToken != "" {
   223  		walletConfig.AlchemyAPIKeys[optimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken
   224  	}
   225  	if request.StatusProxyMarketUser != "" {
   226  		walletConfig.StatusProxyMarketUser = request.StatusProxyMarketUser
   227  	}
   228  	if request.StatusProxyMarketPassword != "" {
   229  		walletConfig.StatusProxyMarketPassword = request.StatusProxyMarketPassword
   230  	}
   231  	if request.StatusProxyBlockchainUser != "" {
   232  		walletConfig.StatusProxyBlockchainUser = request.StatusProxyBlockchainUser
   233  	}
   234  	if request.StatusProxyBlockchainPassword != "" {
   235  		walletConfig.StatusProxyBlockchainPassword = request.StatusProxyBlockchainPassword
   236  	}
   237  
   238  	walletConfig.StatusProxyEnabled = statusProxyEnabled
   239  
   240  	return walletConfig
   241  }
   242  
   243  func overrideApiConfigProd(nodeConfig *params.NodeConfig, config *requests.APIConfig) {
   244  	nodeConfig.APIModules = config.APIModules
   245  	nodeConfig.ConnectorConfig.Enabled = config.ConnectorEnabled
   246  
   247  	nodeConfig.HTTPEnabled = config.HTTPEnabled
   248  	nodeConfig.HTTPHost = config.HTTPHost
   249  	nodeConfig.HTTPPort = config.HTTPPort
   250  	nodeConfig.HTTPVirtualHosts = config.HTTPVirtualHosts
   251  
   252  	nodeConfig.WSEnabled = config.WSEnabled
   253  	nodeConfig.WSHost = config.WSHost
   254  	nodeConfig.WSPort = config.WSPort
   255  }
   256  
   257  func DefaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
   258  	// Set mainnet
   259  	nodeConfig := &params.NodeConfig{}
   260  	nodeConfig.RootDataDir = request.RootDataDir
   261  	nodeConfig.LogEnabled = request.LogEnabled
   262  	nodeConfig.LogFile = DefaultLogFile
   263  	nodeConfig.LogDir = request.LogFilePath
   264  	nodeConfig.LogLevel = DefaultLogLevel
   265  	nodeConfig.DataDir = DefaultDataDir
   266  	nodeConfig.ProcessBackedupMessages = false
   267  	nodeConfig.KeycardPairingDataFile = DefaultKeycardPairingDataFile
   268  	if request.KeycardPairingDataFile != nil {
   269  		nodeConfig.KeycardPairingDataFile = *request.KeycardPairingDataFile
   270  	}
   271  
   272  	if request.LogLevel != nil {
   273  		nodeConfig.LogLevel = *request.LogLevel
   274  		nodeConfig.LogEnabled = true
   275  	} else {
   276  		nodeConfig.LogEnabled = false
   277  	}
   278  
   279  	if request.TestOverrideNetworks != nil {
   280  		nodeConfig.Networks = request.TestOverrideNetworks
   281  	} else {
   282  		nodeConfig.Networks = BuildDefaultNetworks(&request.WalletSecretsConfig)
   283  	}
   284  
   285  	if request.NetworkID != nil {
   286  		nodeConfig.NetworkID = *request.NetworkID
   287  	} else {
   288  		nodeConfig.NetworkID = nodeConfig.Networks[0].ChainID
   289  	}
   290  
   291  	if request.UpstreamConfig != "" {
   292  		nodeConfig.UpstreamConfig = params.UpstreamRPCConfig{
   293  			Enabled: true,
   294  			URL:     request.UpstreamConfig,
   295  		}
   296  	} else {
   297  		nodeConfig.UpstreamConfig.URL = mainnet(request.WalletSecretsConfig.StatusProxyStageName).RPCURL
   298  		nodeConfig.UpstreamConfig.Enabled = true
   299  	}
   300  
   301  	nodeConfig.Name = DefaultNodeName
   302  	nodeConfig.NoDiscovery = true
   303  	nodeConfig.MaxPeers = DefaultMaxPeers
   304  	nodeConfig.MaxPendingPeers = DefaultMaxPendingPeers
   305  
   306  	nodeConfig.WalletConfig = buildWalletConfig(&request.WalletSecretsConfig, request.StatusProxyEnabled)
   307  
   308  	nodeConfig.LocalNotificationsConfig = params.LocalNotificationsConfig{Enabled: true}
   309  	nodeConfig.BrowsersConfig = params.BrowsersConfig{Enabled: true}
   310  	nodeConfig.PermissionsConfig = params.PermissionsConfig{Enabled: true}
   311  	nodeConfig.MailserversConfig = params.MailserversConfig{Enabled: true}
   312  
   313  	nodeConfig.ListenAddr = DefaultListenAddr
   314  
   315  	fleet := request.WakuV2Fleet
   316  	if fleet == "" {
   317  		fleet = DefaultFleet
   318  	}
   319  
   320  	err := SetFleet(fleet, nodeConfig)
   321  	if err != nil {
   322  		return nil, err
   323  	}
   324  
   325  	if request.WakuV2LightClient {
   326  		nodeConfig.WakuV2Config.LightClient = true
   327  	}
   328  
   329  	if request.WakuV2EnableMissingMessageVerification {
   330  		nodeConfig.WakuV2Config.EnableMissingMessageVerification = true
   331  	}
   332  
   333  	if request.WakuV2EnableStoreConfirmationForMessagesSent {
   334  		nodeConfig.WakuV2Config.EnableStoreConfirmationForMessagesSent = true
   335  	}
   336  
   337  	if request.WakuV2Nameserver != nil {
   338  		nodeConfig.WakuV2Config.Nameserver = *request.WakuV2Nameserver
   339  	}
   340  
   341  	if request.TelemetryServerURL != "" {
   342  		nodeConfig.WakuV2Config.TelemetryServerURL = request.TelemetryServerURL
   343  	}
   344  
   345  	nodeConfig.ShhextConfig = params.ShhextConfig{
   346  		InstallationID:             installationID,
   347  		MaxMessageDeliveryAttempts: DefaultMaxMessageDeliveryAttempts,
   348  		MailServerConfirmations:    true,
   349  		VerifyTransactionChainID:   DefaultVerifyTransactionChainID,
   350  		DataSyncEnabled:            true,
   351  		PFSEnabled:                 true,
   352  	}
   353  
   354  	if request.VerifyTransactionURL != nil {
   355  		nodeConfig.ShhextConfig.VerifyTransactionURL = *request.VerifyTransactionURL
   356  	} else {
   357  		nodeConfig.ShhextConfig.VerifyTransactionURL = mainnet(request.WalletSecretsConfig.StatusProxyStageName).FallbackURL
   358  	}
   359  
   360  	if request.VerifyENSURL != nil {
   361  		nodeConfig.ShhextConfig.VerifyENSURL = *request.VerifyENSURL
   362  	} else {
   363  		nodeConfig.ShhextConfig.VerifyENSURL = mainnet(request.WalletSecretsConfig.StatusProxyStageName).FallbackURL
   364  	}
   365  
   366  	if request.VerifyTransactionChainID != nil {
   367  		nodeConfig.ShhextConfig.VerifyTransactionChainID = *request.VerifyTransactionChainID
   368  	}
   369  
   370  	if request.VerifyENSContractAddress != nil {
   371  		nodeConfig.ShhextConfig.VerifyENSContractAddress = *request.VerifyENSContractAddress
   372  	}
   373  
   374  	if request.NetworkID != nil {
   375  		nodeConfig.NetworkID = *request.NetworkID
   376  	}
   377  
   378  	nodeConfig.TorrentConfig = params.TorrentConfig{
   379  		Enabled:    false,
   380  		Port:       0,
   381  		DataDir:    filepath.Join(nodeConfig.RootDataDir, params.ArchivesRelativePath),
   382  		TorrentDir: filepath.Join(nodeConfig.RootDataDir, params.TorrentTorrentsRelativePath),
   383  	}
   384  
   385  	if request.TorrentConfigEnabled != nil {
   386  		nodeConfig.TorrentConfig.Enabled = *request.TorrentConfigEnabled
   387  
   388  	}
   389  	if request.TorrentConfigPort != nil {
   390  		nodeConfig.TorrentConfig.Port = *request.TorrentConfigPort
   391  	}
   392  
   393  	if request.APIConfig != nil {
   394  		overrideApiConfig(nodeConfig, request.APIConfig)
   395  	}
   396  
   397  	for _, opt := range opts {
   398  		if err := opt(nodeConfig); err != nil {
   399  			return nil, err
   400  		}
   401  	}
   402  
   403  	return nodeConfig, nil
   404  }
   405  
   406  func DefaultKeystorePath(rootDataDir string, keyUID string) (string, string) {
   407  	relativePath := filepath.Join(DefaultKeystoreRelativePath, keyUID)
   408  	absolutePath := filepath.Join(rootDataDir, relativePath)
   409  	return relativePath, absolutePath
   410  }
   411  
   412  func buildSigningPhrase() (string, error) {
   413  	length := big.NewInt(int64(len(dictionary)))
   414  	a, err := rand.Int(rand.Reader, length)
   415  	if err != nil {
   416  		return "", err
   417  	}
   418  	b, err := rand.Int(rand.Reader, length)
   419  	if err != nil {
   420  		return "", err
   421  	}
   422  	c, err := rand.Int(rand.Reader, length)
   423  	if err != nil {
   424  		return "", err
   425  	}
   426  
   427  	return dictionary[a.Int64()] + " " + dictionary[b.Int64()] + " " + dictionary[c.Int64()], nil
   428  }
   429  
   430  func randomWalletEmoji() (string, error) {
   431  	count := big.NewInt(int64(len(animalsAndNatureEmojis)))
   432  	index, err := rand.Int(rand.Reader, count)
   433  	if err != nil {
   434  		return "", err
   435  	}
   436  	return animalsAndNatureEmojis[index.Int64()], nil
   437  }
   438  
   439  var animalsAndNatureEmojis = []string{
   440  	"đŸĩ", "🐒", "đŸĻ", "đŸĻ§", "đŸĻŖ", "đŸĻ", "đŸĻ›", "đŸĒ", "đŸĢ", "đŸĻ™",
   441  	"🐃", "🐂", "🐄", "🐎", "đŸĻ„", "đŸĻ“", "đŸĻŒ", "🐐", "🐏", "🐑",
   442  	"đŸĻ™", "🐘", "đŸĻŖ", "đŸĻ›", "đŸĻ", "đŸĻ’", "🐁", "🐀", "🐹", "🐰",
   443  	"🐇", "đŸŋī¸", "đŸĻ”", "đŸĻ‡", "đŸģ", "đŸģâ€â„ī¸", "🐨", "đŸŧ", "đŸĻĨ", "đŸĻĻ",
   444  	"đŸĻ¨", "đŸĻ˜", "đŸĻĄ", "🐾", "🐉", "🐲", "đŸŒĩ", "🎄", "🌲", "đŸŒŗ",
   445  	"🌴", "🌱", "đŸŒŋ", "â˜˜ī¸", "🍀", "🎍", "🎋", "🍃", "🍂", "🍁",
   446  	"🍄", "🐚", "đŸĒ¨", "🌾", "💐", "🌷", "🌹", "đŸĨ€", "đŸŒē", "🌸",
   447  	"đŸŒŧ", "đŸŒģ", "🌞", "🌝", "🌛", "🌜", "🌚", "🌕", "🌖", "🌗",
   448  	"🌘", "🌑", "🌒", "🌓", "🌔", "🌙", "🌎", "🌍", "🌏", "đŸĒ",
   449  	"đŸ’Ģ", "⭐", "🌟", "✨", "⚡", "â˜„ī¸", "đŸ’Ĩ", "đŸ”Ĩ", "đŸŒĒī¸", "🌈",
   450  	"â˜€ī¸", "đŸŒ¤ī¸", "⛅", "đŸŒĨī¸", "â˜ī¸", "đŸŒĻī¸", "đŸŒ§ī¸", "â›ˆī¸", "đŸŒŠī¸", "đŸŒ¨ī¸",
   451  	"â„ī¸", "â˜ƒī¸", "⛄", "đŸŒŦī¸", "💨", "💧", "đŸ’Ļ", "🌊",
   452  }