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 := ¶ms.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 }