feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

1
vendor/github.com/status-im/status-go/api/.gitignore generated vendored Normal file
View File

@@ -0,0 +1 @@
accounts.sql*

42
vendor/github.com/status-im/status-go/api/app_state.go generated vendored Normal file
View File

@@ -0,0 +1,42 @@
package api
import (
"fmt"
"strings"
)
// appState represents if the app is in foreground, background or some other state
type appState string
func (a appState) String() string {
return string(a)
}
// Specific app states
// see https://facebook.github.io/react-native/docs/appstate.html
const (
appStateForeground = appState("active") // these constant values are kept in sync with React Native
appStateBackground = appState("background")
appStateInactive = appState("inactive")
appStateInvalid = appState("")
)
// validAppStates returns an immutable set of valid states.
func validAppStates() []appState {
return []appState{appStateInactive, appStateBackground, appStateForeground}
}
// parseAppState creates AppState from a string
func parseAppState(stateString string) (appState, error) {
// a bit of cleaning up
stateString = strings.ToLower(strings.TrimSpace(stateString))
for _, state := range validAppStates() {
if stateString == state.String() {
return state, nil
}
}
return appStateInvalid, fmt.Errorf("could not parse app state: %s", stateString)
}

57
vendor/github.com/status-im/status-go/api/backend.go generated vendored Normal file
View File

@@ -0,0 +1,57 @@
package api
import (
signercore "github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/personal"
"github.com/status-im/status-go/services/typeddata"
"github.com/status-im/status-go/transactions"
)
// StatusBackend defines the contract for the Status.im service
type StatusBackend interface {
// IsNodeRunning() bool // NOTE: Only used in tests
StartNode(config *params.NodeConfig) error // NOTE: Only used in canary
StartNodeWithKey(acc multiaccounts.Account, password string, keyHex string, conf *params.NodeConfig) error
StartNodeWithAccount(acc multiaccounts.Account, password string, conf *params.NodeConfig) error
StartNodeWithAccountAndInitialConfig(account multiaccounts.Account, password string, settings settings.Settings, conf *params.NodeConfig, subaccs []*accounts.Account) error
StopNode() error
// RestartNode() error // NOTE: Only used in tests
GetNodeConfig() (*params.NodeConfig, error)
UpdateRootDataDir(datadir string)
// SelectAccount(loginParams account.LoginParams) error
OpenAccounts() error
GetAccounts() ([]multiaccounts.Account, error)
LocalPairingStarted() error
// SaveAccount(account multiaccounts.Account) error
SaveAccountAndStartNodeWithKey(acc multiaccounts.Account, password string, settings settings.Settings, conf *params.NodeConfig, subaccs []*accounts.Account, keyHex string) error
Recover(rpcParams personal.RecoverParams) (types.Address, error)
Logout() error
CallPrivateRPC(inputJSON string) (string, error)
CallRPC(inputJSON string) (string, error)
HashTransaction(sendArgs transactions.SendTxArgs) (transactions.SendTxArgs, types.Hash, error)
HashTypedData(typed typeddata.TypedData) (types.Hash, error)
HashTypedDataV4(typed signercore.TypedData) (types.Hash, error)
ResetChainData() error
SendTransaction(sendArgs transactions.SendTxArgs, password string) (hash types.Hash, err error)
SendTransactionWithChainID(chainID uint64, sendArgs transactions.SendTxArgs, password string) (hash types.Hash, err error)
SendTransactionWithSignature(sendArgs transactions.SendTxArgs, sig []byte) (hash types.Hash, err error)
SignHash(hexEncodedHash string) (string, error)
SignMessage(rpcParams personal.SignParams) (types.HexBytes, error)
SignTypedData(typed typeddata.TypedData, address string, password string) (types.HexBytes, error)
SignTypedDataV4(typed signercore.TypedData, address string, password string) (types.HexBytes, error)
ConnectionChange(typ string, expensive bool)
AppStateChange(state string)
ExtractGroupMembershipSignatures(signaturePairs [][2]string) ([]string, error)
SignGroupMembership(content string) (string, error)
}

View File

@@ -0,0 +1,258 @@
package api
import (
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/requests"
)
const (
mainnetChainID uint64 = 1
goerliChainID uint64 = 5
sepoliaChainID uint64 = 11155111
optimismChainID uint64 = 10
optimismGoerliChainID uint64 = 420
optimismSepoliaChainID uint64 = 11155420
arbitrumChainID uint64 = 42161
arbitrumGoerliChainID uint64 = 421613
arbitrumSepoliaChainID uint64 = 421614
sntSymbol = "SNT"
sttSymbol = "STT"
)
var ganacheTokenAddress = common.HexToAddress("0x8571Ddc46b10d31EF963aF49b6C7799Ea7eff818")
var mainnet = params.Network{
ChainID: mainnetChainID,
ChainName: "Ethereum Mainnet",
RPCURL: "https://eth-archival.rpc.grove.city/v1/",
FallbackURL: "https://mainnet.infura.io/v3/",
BlockExplorerURL: "https://etherscan.io/",
IconURL: "network/Network=Ethereum",
ChainColor: "#627EEA",
ShortName: "eth",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: false,
Layer: 1,
Enabled: true,
RelatedChainID: goerliChainID,
}
var goerli = params.Network{
ChainID: goerliChainID,
ChainName: "Ethereum Goerli",
RPCURL: "https://goerli-archival.rpc.grove.city/v1/",
FallbackURL: "https://goerli.infura.io/v3/",
BlockExplorerURL: "https://goerli.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "goEth",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 1,
Enabled: true,
RelatedChainID: mainnetChainID,
}
var sepolia = params.Network{
ChainID: sepoliaChainID,
ChainName: "Ethereum Sepolia",
RPCURL: "https://sepolia-archival.rpc.grove.city/v1/",
FallbackURL: "https://sepolia.infura.io/v3/",
BlockExplorerURL: "https://sepolia.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#51D0F0",
ShortName: "eth",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 1,
Enabled: true,
RelatedChainID: mainnetChainID,
}
var optimism = params.Network{
ChainID: optimismChainID,
ChainName: "Optimism",
RPCURL: "https://optimism-mainnet.rpc.grove.city/v1/",
FallbackURL: "https://optimism-mainnet.infura.io/v3/",
BlockExplorerURL: "https://optimistic.etherscan.io",
IconURL: "network/Network=Optimism",
ChainColor: "#E90101",
ShortName: "opt",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: false,
Layer: 2,
Enabled: true,
RelatedChainID: optimismGoerliChainID,
}
var optimismGoerli = params.Network{
ChainID: optimismGoerliChainID,
ChainName: "Optimism Goerli",
RPCURL: "https://optimism-goerli.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://goerli-optimism.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "goOpt",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: optimismChainID,
}
var optimismSepolia = params.Network{
ChainID: optimismSepoliaChainID,
ChainName: "Optimism Sepolia",
RPCURL: "https://optimism-sepolia.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://sepolia-optimism.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "opt",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: optimismChainID,
}
var arbitrum = params.Network{
ChainID: arbitrumChainID,
ChainName: "Arbitrum",
RPCURL: "https://arbitrum-one.rpc.grove.city/v1/",
FallbackURL: "https://arbitrum-mainnet.infura.io/v3/",
BlockExplorerURL: "https://arbiscan.io/",
IconURL: "network/Network=Arbitrum",
ChainColor: "#51D0F0",
ShortName: "arb",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: false,
Layer: 2,
Enabled: true,
RelatedChainID: arbitrumGoerliChainID,
}
var arbitrumGoerli = params.Network{
ChainID: arbitrumGoerliChainID,
ChainName: "Arbitrum Goerli",
RPCURL: "https://arbitrum-goerli.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://goerli.arbiscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "goArb",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: arbitrumChainID,
}
var arbitrumSepolia = params.Network{
ChainID: arbitrumSepoliaChainID,
ChainName: "Arbitrum Sepolia",
RPCURL: "https://arbitrum-sepolia.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://sepolia-explorer.arbitrum.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#51D0F0",
ShortName: "arb",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: arbitrumChainID,
}
var defaultNetworks = []params.Network{
mainnet,
goerli,
sepolia,
optimism,
optimismGoerli,
optimismSepolia,
arbitrum,
arbitrumGoerli,
arbitrumSepolia,
}
var mainnetGanacheTokenOverrides = params.TokenOverride{
Symbol: sntSymbol,
Address: ganacheTokenAddress,
}
var goerliGanacheTokenOverrides = params.TokenOverride{
Symbol: sttSymbol,
Address: ganacheTokenAddress,
}
func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) []params.Network {
var networksWithRPC []params.Network
for _, n := range networks {
if request.InfuraToken != "" {
if strings.Contains(n.RPCURL, "infura") {
n.RPCURL += request.InfuraToken
}
if strings.Contains(n.FallbackURL, "infura") {
n.FallbackURL += request.InfuraToken
}
}
if request.PoktToken != "" {
if strings.Contains(n.RPCURL, "grove") {
n.RPCURL += request.PoktToken
}
if strings.Contains(n.FallbackURL, "grove") {
n.FallbackURL += request.PoktToken
}
}
if request.GanacheURL != "" {
n.RPCURL = request.GanacheURL
n.FallbackURL = request.GanacheURL
if n.ChainID == mainnetChainID {
n.TokenOverrides = []params.TokenOverride{
mainnetGanacheTokenOverrides,
}
} else if n.ChainID == goerliChainID {
n.TokenOverrides = []params.TokenOverride{
goerliGanacheTokenOverrides,
}
}
}
networksWithRPC = append(networksWithRPC, n)
}
return networksWithRPC
}
func BuildDefaultNetworks(request *requests.CreateAccount) []params.Network {
return setRPCs(defaultNetworks, &request.WalletSecretsConfig)
}

936
vendor/github.com/status-im/status-go/api/defaults.go generated vendored Normal file
View File

@@ -0,0 +1,936 @@
package api
import (
"crypto/rand"
"encoding/json"
"math/big"
"github.com/google/uuid"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/requests"
)
const pathWalletRoot = "m/44'/60'/0'/0"
const pathEIP1581 = "m/43'/60'/1581'"
const pathDefaultChat = pathEIP1581 + "/0'/0"
const pathDefaultWallet = pathWalletRoot + "/0"
const defaultMnemonicLength = 12
const shardsTestClusterID = 16
const walletAccountDefaultName = "Account 1"
const keystoreRelativePath = "keystore"
const defaultKeycardPairingDataFile = "/ethereum/mainnet_rpc/keycard/pairings.json"
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet}
const (
statusProdFleet = "status.prod"
statusTestFleet = "status.test"
wakuv2ProdFleet = "wakuv2.prod"
wakuv2TestFleet = "wakuv2.test"
shardsTest = "shards.test"
)
var DefaultWakuNodes = map[string][]string{
statusProdFleet: []string{"enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"},
statusTestFleet: []string{"enrtree://AIO6LUM3IVWCU2KCPBBI6FEH2W42IGK3ASCZHZGG5TIXUR56OGQUO@test.status.nodes.status.im"},
wakuv2ProdFleet: []string{"enrtree://ANEDLO25QVUGJOUTQFRYKWX6P4Z4GKVESBMHML7DZ6YK4LGS5FC5O@prod.wakuv2.nodes.status.im"},
wakuv2TestFleet: []string{"enrtree://AO47IDOLBKH72HIZZOXQP6NMRESAN7CHYWIBNXDXWRJRZWLODKII6@test.wakuv2.nodes.status.im"},
shardsTest: []string{"enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.test.shards.nodes.status.im"},
}
var DefaultFleet = shardsTest
func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) {
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
s := &settings.Settings{}
s.Mnemonic = &generatedAccountInfo.Mnemonic
s.BackupEnabled = true
logLevel := "INFO"
s.LogLevel = &logLevel
s.ProfilePicturesShowTo = settings.ProfilePicturesShowToEveryone
s.ProfilePicturesVisibility = settings.ProfilePicturesVisibilityEveryone
s.KeyUID = generatedAccountInfo.KeyUID
s.Address = types.HexToAddress(generatedAccountInfo.Address)
s.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address)
s.URLUnfurlingMode = settings.URLUnfurlingAlwaysAsk
// Set chat key & name
name, err := alias.GenerateFromPublicKeyString(chatKeyString)
if err != nil {
return nil, err
}
s.Name = name
s.PublicKey = chatKeyString
s.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address)
s.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address)
s.Mnemonic = mnemonic
signingPhrase, err := buildSigningPhrase()
if err != nil {
return nil, err
}
s.SigningPhrase = signingPhrase
s.SendPushNotifications = true
s.InstallationID = uuid.New().String()
s.UseMailservers = 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 = "mainnet_rpc"
s.TokenGroupByCommunity = false
s.ShowCommunityAssetWhenSendingTokens = true
s.DisplayAssetsBelowBalance = false
// NOTE 9 decimals of precision. Default value is translated to 0.1
s.DisplayAssetsBelowBalanceThreshold = 100000000
return s, nil
}
func SetDefaultFleet(nodeConfig *params.NodeConfig) error {
return SetFleet(DefaultFleet, nodeConfig)
}
func SetFleet(fleet string, nodeConfig *params.NodeConfig) error {
nodeConfig.WakuV2Config = params.WakuV2Config{
Enabled: true,
EnableDiscV5: true,
DiscoveryLimit: 20,
Host: "0.0.0.0",
AutoUpdate: true,
PeerExchange: true,
}
clusterConfig, err := params.LoadClusterConfigFromFleet(fleet)
if err != nil {
return err
}
nodeConfig.ClusterConfig = *clusterConfig
nodeConfig.ClusterConfig.Fleet = fleet
nodeConfig.ClusterConfig.WakuNodes = DefaultWakuNodes[fleet]
nodeConfig.ClusterConfig.DiscV5BootstrapNodes = DefaultWakuNodes[fleet]
if fleet == shardsTest {
nodeConfig.ClusterConfig.ClusterID = shardsTestClusterID
nodeConfig.WakuV2Config.UseShardAsDefaultTopic = true
}
return nil
}
func buildWalletConfig(request *requests.WalletSecretsConfig) params.WalletConfig {
walletConfig := params.WalletConfig{
Enabled: true,
AlchemyAPIKeys: make(map[uint64]string),
}
if request.OpenseaAPIKey != "" {
walletConfig.OpenseaAPIKey = request.OpenseaAPIKey
}
if request.RaribleMainnetAPIKey != "" {
walletConfig.RaribleMainnetAPIKey = request.RaribleMainnetAPIKey
}
if request.RaribleTestnetAPIKey != "" {
walletConfig.RaribleTestnetAPIKey = request.RaribleTestnetAPIKey
}
if request.InfuraToken != "" {
walletConfig.InfuraAPIKey = request.InfuraToken
}
if request.InfuraSecret != "" {
walletConfig.InfuraAPIKeySecret = request.InfuraSecret
}
if request.AlchemyEthereumMainnetToken != "" {
walletConfig.AlchemyAPIKeys[mainnetChainID] = request.AlchemyEthereumMainnetToken
}
if request.AlchemyEthereumGoerliToken != "" {
walletConfig.AlchemyAPIKeys[goerliChainID] = request.AlchemyEthereumGoerliToken
}
if request.AlchemyEthereumSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[sepoliaChainID] = request.AlchemyEthereumSepoliaToken
}
if request.AlchemyArbitrumMainnetToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumChainID] = request.AlchemyArbitrumMainnetToken
}
if request.AlchemyArbitrumGoerliToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumGoerliChainID] = request.AlchemyArbitrumGoerliToken
}
if request.AlchemyArbitrumSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken
}
if request.AlchemyOptimismMainnetToken != "" {
walletConfig.AlchemyAPIKeys[optimismChainID] = request.AlchemyOptimismMainnetToken
}
if request.AlchemyOptimismGoerliToken != "" {
walletConfig.AlchemyAPIKeys[optimismGoerliChainID] = request.AlchemyOptimismGoerliToken
}
if request.AlchemyOptimismSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[optimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken
}
return walletConfig
}
func defaultNodeConfig(installationID string, request *requests.CreateAccount) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.NetworkID = request.NetworkID
nodeConfig.LogEnabled = request.LogEnabled
nodeConfig.LogFile = "geth.log"
nodeConfig.LogDir = request.LogFilePath
nodeConfig.LogLevel = "ERROR"
nodeConfig.DataDir = "/ethereum/mainnet_rpc"
nodeConfig.KeycardPairingDataFile = defaultKeycardPairingDataFile
if request.LogLevel != nil {
nodeConfig.LogLevel = *request.LogLevel
}
if request.UpstreamConfig != "" {
nodeConfig.UpstreamConfig = params.UpstreamRPCConfig{
Enabled: true,
URL: request.UpstreamConfig,
}
}
nodeConfig.Name = "StatusIM"
nodeConfig.Rendezvous = false
nodeConfig.NoDiscovery = true
nodeConfig.MaxPeers = 20
nodeConfig.MaxPendingPeers = 20
nodeConfig.WalletConfig = buildWalletConfig(&request.WalletSecretsConfig)
nodeConfig.LocalNotificationsConfig = params.LocalNotificationsConfig{Enabled: true}
nodeConfig.BrowsersConfig = params.BrowsersConfig{Enabled: true}
nodeConfig.PermissionsConfig = params.PermissionsConfig{Enabled: true}
nodeConfig.MailserversConfig = params.MailserversConfig{Enabled: true}
nodeConfig.ListenAddr = ":0"
err := SetDefaultFleet(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{
BackupDisabledDataDir: request.BackupDisabledDataDir,
InstallationID: installationID,
MaxMessageDeliveryAttempts: 6,
MailServerConfirmations: true,
VerifyTransactionChainID: 1,
DataSyncEnabled: true,
PFSEnabled: true,
}
if request.VerifyTransactionURL != nil {
nodeConfig.ShhextConfig.VerifyTransactionURL = *request.VerifyTransactionURL
}
if request.VerifyENSURL != nil {
nodeConfig.ShhextConfig.VerifyENSURL = *request.VerifyENSURL
}
if request.VerifyTransactionChainID != nil {
nodeConfig.ShhextConfig.VerifyTransactionChainID = *request.VerifyTransactionChainID
}
if request.VerifyENSContractAddress != nil {
nodeConfig.ShhextConfig.VerifyENSContractAddress = *request.VerifyENSContractAddress
}
if request.LogLevel != nil {
nodeConfig.LogLevel = *request.LogLevel
nodeConfig.LogEnabled = true
} else {
nodeConfig.LogEnabled = false
}
nodeConfig.Networks = BuildDefaultNetworks(request)
return nodeConfig, nil
}
func buildSigningPhrase() (string, error) {
length := big.NewInt(int64(len(dictionary)))
a, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
b, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
c, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
return dictionary[a.Int64()] + " " + dictionary[b.Int64()] + " " + dictionary[c.Int64()], nil
}
var dictionary = []string{
"acid",
"alto",
"apse",
"arch",
"area",
"army",
"atom",
"aunt",
"babe",
"baby",
"back",
"bail",
"bait",
"bake",
"ball",
"band",
"bank",
"barn",
"base",
"bass",
"bath",
"bead",
"beak",
"beam",
"bean",
"bear",
"beat",
"beef",
"beer",
"beet",
"bell",
"belt",
"bend",
"bike",
"bill",
"bird",
"bite",
"blow",
"blue",
"boar",
"boat",
"body",
"bolt",
"bomb",
"bone",
"book",
"boot",
"bore",
"boss",
"bowl",
"brow",
"bulb",
"bull",
"burn",
"bush",
"bust",
"cafe",
"cake",
"calf",
"call",
"calm",
"camp",
"cane",
"cape",
"card",
"care",
"carp",
"cart",
"case",
"cash",
"cast",
"cave",
"cell",
"cent",
"chap",
"chef",
"chin",
"chip",
"chop",
"chub",
"chug",
"city",
"clam",
"clef",
"clip",
"club",
"clue",
"coal",
"coat",
"code",
"coil",
"coin",
"coke",
"cold",
"colt",
"comb",
"cone",
"cook",
"cope",
"copy",
"cord",
"cork",
"corn",
"cost",
"crab",
"craw",
"crew",
"crib",
"crop",
"crow",
"curl",
"cyst",
"dame",
"dare",
"dark",
"dart",
"dash",
"data",
"date",
"dead",
"deal",
"dear",
"debt",
"deck",
"deep",
"deer",
"desk",
"dhow",
"diet",
"dill",
"dime",
"dirt",
"dish",
"disk",
"dock",
"doll",
"door",
"dory",
"drag",
"draw",
"drop",
"drug",
"drum",
"duck",
"dump",
"dust",
"duty",
"ease",
"east",
"eave",
"eddy",
"edge",
"envy",
"epee",
"exam",
"exit",
"face",
"fact",
"fail",
"fall",
"fame",
"fang",
"farm",
"fawn",
"fear",
"feed",
"feel",
"feet",
"file",
"fill",
"film",
"find",
"fine",
"fire",
"fish",
"flag",
"flat",
"flax",
"flow",
"foam",
"fold",
"font",
"food",
"foot",
"fork",
"form",
"fort",
"fowl",
"frog",
"fuel",
"full",
"gain",
"gale",
"galn",
"game",
"garb",
"gate",
"gear",
"gene",
"gift",
"girl",
"give",
"glad",
"glen",
"glue",
"glut",
"goal",
"goat",
"gold",
"golf",
"gong",
"good",
"gown",
"grab",
"gram",
"gray",
"grey",
"grip",
"grit",
"gyro",
"hail",
"hair",
"half",
"hall",
"hand",
"hang",
"harm",
"harp",
"hate",
"hawk",
"head",
"heat",
"heel",
"hell",
"helo",
"help",
"hemp",
"herb",
"hide",
"high",
"hill",
"hire",
"hive",
"hold",
"hole",
"home",
"hood",
"hoof",
"hook",
"hope",
"hops",
"horn",
"hose",
"host",
"hour",
"hunt",
"hurt",
"icon",
"idea",
"inch",
"iris",
"iron",
"item",
"jail",
"jeep",
"jeff",
"joey",
"join",
"joke",
"judo",
"jump",
"junk",
"jury",
"jute",
"kale",
"keep",
"kick",
"kill",
"kilt",
"kind",
"king",
"kiss",
"kite",
"knee",
"knot",
"lace",
"lack",
"lady",
"lake",
"lamb",
"lamp",
"land",
"lark",
"lava",
"lawn",
"lead",
"leaf",
"leek",
"lier",
"life",
"lift",
"lily",
"limo",
"line",
"link",
"lion",
"lisa",
"list",
"load",
"loaf",
"loan",
"lock",
"loft",
"long",
"look",
"loss",
"lout",
"love",
"luck",
"lung",
"lute",
"lynx",
"lyre",
"maid",
"mail",
"main",
"make",
"male",
"mall",
"manx",
"many",
"mare",
"mark",
"mask",
"mass",
"mate",
"math",
"meal",
"meat",
"meet",
"menu",
"mess",
"mice",
"midi",
"mile",
"milk",
"mime",
"mind",
"mine",
"mini",
"mint",
"miss",
"mist",
"moat",
"mode",
"mole",
"mood",
"moon",
"most",
"moth",
"move",
"mule",
"mutt",
"nail",
"name",
"neat",
"neck",
"need",
"neon",
"nest",
"news",
"node",
"nose",
"note",
"oboe",
"okra",
"open",
"oval",
"oven",
"oxen",
"pace",
"pack",
"page",
"pail",
"pain",
"pair",
"palm",
"pard",
"park",
"part",
"pass",
"past",
"path",
"peak",
"pear",
"peen",
"peer",
"pelt",
"perp",
"pest",
"pick",
"pier",
"pike",
"pile",
"pimp",
"pine",
"ping",
"pink",
"pint",
"pipe",
"piss",
"pith",
"plan",
"play",
"plot",
"plow",
"poem",
"poet",
"pole",
"polo",
"pond",
"pony",
"poof",
"pool",
"port",
"post",
"prow",
"pull",
"puma",
"pump",
"pupa",
"push",
"quit",
"race",
"rack",
"raft",
"rage",
"rail",
"rain",
"rake",
"rank",
"rate",
"read",
"rear",
"reef",
"rent",
"rest",
"rice",
"rich",
"ride",
"ring",
"rise",
"risk",
"road",
"robe",
"rock",
"role",
"roll",
"roof",
"room",
"root",
"rope",
"rose",
"ruin",
"rule",
"rush",
"ruth",
"sack",
"safe",
"sage",
"sail",
"sale",
"salt",
"sand",
"sari",
"sash",
"save",
"scow",
"seal",
"seat",
"seed",
"self",
"sell",
"shed",
"shin",
"ship",
"shoe",
"shop",
"shot",
"show",
"sick",
"side",
"sign",
"silk",
"sill",
"silo",
"sing",
"sink",
"site",
"size",
"skin",
"sled",
"slip",
"smog",
"snob",
"snow",
"soap",
"sock",
"soda",
"sofa",
"soft",
"soil",
"song",
"soot",
"sort",
"soup",
"spot",
"spur",
"stag",
"star",
"stay",
"stem",
"step",
"stew",
"stop",
"stud",
"suck",
"suit",
"swan",
"swim",
"tail",
"tale",
"talk",
"tank",
"tard",
"task",
"taxi",
"team",
"tear",
"teen",
"tell",
"temp",
"tent",
"term",
"test",
"text",
"thaw",
"tile",
"till",
"time",
"tire",
"toad",
"toga",
"togs",
"tone",
"tool",
"toot",
"tote",
"tour",
"town",
"tram",
"tray",
"tree",
"trim",
"trip",
"tuba",
"tube",
"tuna",
"tune",
"turn",
"tutu",
"twig",
"type",
"unit",
"user",
"vane",
"vase",
"vast",
"veal",
"veil",
"vein",
"vest",
"vibe",
"view",
"vise",
"wait",
"wake",
"walk",
"wall",
"wash",
"wasp",
"wave",
"wear",
"weed",
"week",
"well",
"west",
"whip",
"wife",
"will",
"wind",
"wine",
"wing",
"wire",
"wish",
"wolf",
"wood",
"wool",
"word",
"work",
"worm",
"wrap",
"wren",
"yard",
"yarn",
"yawl",
"year",
"yoga",
"yoke",
"yurt",
"zinc",
"zone",
}

2484
vendor/github.com/status-im/status-go/api/geth_backend.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
package multiformat
import (
"crypto/elliptic"
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
bls12381 "github.com/kilic/bls12-381"
"github.com/multiformats/go-multibase"
"github.com/multiformats/go-varint"
)
const (
secp256k1KeyType = 0xe7
bls12p381g1KeyType = 0xea
bls12p381g2KeyType = 0xeb
legacyKeyLength = 132
)
// SerializePublicKey serialises a non-serialised multibase encoded multicodec identified EC public key
// For details on usage see specs https://specs.status.im/spec/2#public-key-serialization
func SerializePublicKey(key, outputBase string) (string, error) {
dKey, err := multibaseDecode(key)
if err != nil {
return "", err
}
kt, i, err := getPublicKeyType(dKey)
if err != nil {
return "", err
}
cpk, err := compressPublicKey(dKey[i:], kt)
if err != nil {
return "", err
}
cpk = prependKeyIdentifier(cpk, kt, i)
return multibaseEncode(outputBase, cpk)
}
// DeserializePublicKey deserialise a serialised multibase encoded multicodec identified EC public key
// For details on usage see specs https://specs.status.im/spec/2#public-key-serialization
func DeserializePublicKey(key, outputBase string) (string, error) {
cpk, err := multibaseDecode(key)
if err != nil {
return "", err
}
kt, i, err := getPublicKeyType(cpk)
if err != nil {
return "", err
}
pk, err := decompressPublicKey(cpk[i:], kt)
if err != nil {
return "", err
}
pk = prependKeyIdentifier(pk, kt, i)
return multibaseEncode(outputBase, pk)
}
// SerializeLegacyKey converts a secp251k1 uncompressed key to
// a base58 compressed key
func SerializeLegacyKey(key string) (string, error) {
if len(key) != legacyKeyLength {
return "", errors.New("invalid key length")
}
keyWithPrefix := fmt.Sprintf("0x%x01%s", secp256k1KeyType, key[2:])
return SerializePublicKey(keyWithPrefix, "z")
}
// DeserializeCompressedKey converts a base58 compressed key to
// a secp251k1 uncompressed key
func DeserializeCompressedKey(key string) (string, error) {
if len(key) == 0 {
return "", errors.New("invalid key length")
}
deserialisedKey, err := DeserializePublicKey(key, "f")
if err != nil {
return "", err
}
return "0x" + deserialisedKey[5:], nil
}
// getPublicKeyType wrapper for the `varint.FromUvarint()` func
func getPublicKeyType(key []byte) (uint64, int, error) {
return varint.FromUvarint(key)
}
// prependKeyIdentifier prepends an Unsigned Variable Integer (uvarint) to a given []byte
func prependKeyIdentifier(key []byte, kt uint64, ktl int) []byte {
buf := make([]byte, ktl)
varint.PutUvarint(buf, kt)
key = append(buf, key...)
return key
}
// compressPublicKey serves as logic switch function to parse key data for compression based on the given keyType
func compressPublicKey(key []byte, keyType uint64) ([]byte, error) {
switch keyType {
case secp256k1KeyType:
return compressSecp256k1PublicKey(key)
case bls12p381g1KeyType:
return compressBls12p381g1PublicKey(key)
case bls12p381g2KeyType:
return compressBls12p381g2PublicKey(key)
default:
return nil, fmt.Errorf("unsupported public key type '%X'", keyType)
}
}
// compressSecp256k1PublicKey is a dedicated key compression function for secp256k1 pks
func compressSecp256k1PublicKey(key []byte) ([]byte, error) {
x, y := elliptic.Unmarshal(secp256k1.S256(), key)
if err := isSecp256k1XYValid(key, x, y); err != nil {
return nil, err
}
cpk := secp256k1.CompressPubkey(x, y)
return cpk, nil
}
// compressBls12p381g1PublicKey is a dedicated key compression function for bls12 381 g1 pks
func compressBls12p381g1PublicKey(key []byte) ([]byte, error) {
g1 := bls12381.NewG1()
// Generate the G1 point
pg1, err := g1.FromBytes(key)
if err != nil {
return nil, err
}
cpk := g1.ToCompressed(pg1)
return cpk, nil
}
// compressBls12p381g1PublicKey is a dedicated key compression function for bls12 381 g2 pks
func compressBls12p381g2PublicKey(key []byte) ([]byte, error) {
g2 := bls12381.NewG2()
// Generate the G2 point
pg2, err := g2.FromBytes(key)
if err != nil {
return nil, err
}
cpk := g2.ToCompressed(pg2)
return cpk, nil
}
// decompressPublicKey serves as logic switch function to parse key data for decompression based on the given keyType
func decompressPublicKey(key []byte, keyType uint64) ([]byte, error) {
switch keyType {
case secp256k1KeyType:
return decompressSecp256k1PublicKey(key)
case bls12p381g1KeyType:
return decompressBls12p381g1PublicKey(key)
case bls12p381g2KeyType:
return decompressBls12p381g2PublicKey(key)
default:
return nil, fmt.Errorf("unsupported public key type '%X'", keyType)
}
}
// decompressSecp256k1PublicKey is a dedicated key decompression function for secp256k1 pks
func decompressSecp256k1PublicKey(key []byte) ([]byte, error) {
x, y := secp256k1.DecompressPubkey(key)
if err := isSecp256k1XYValid(key, x, y); err != nil {
return nil, err
}
k := elliptic.Marshal(secp256k1.S256(), x, y)
return k, nil
}
// isSecp256k1XYValid checks if a given x and y coordinate is nil, returns an error if either x or y is nil
// secp256k1.DecompressPubkey will not return an error if a compressed pk fails decompression and instead returns
// nil x, y coordinates
func isSecp256k1XYValid(key []byte, x, y *big.Int) error {
if x == nil || y == nil {
return fmt.Errorf("invalid public key format, '%b'", key)
}
return nil
}
// decompressBls12p381g1PublicKey is a dedicated key decompression function for bls12 381 g1 pks
func decompressBls12p381g1PublicKey(key []byte) ([]byte, error) {
g1 := bls12381.NewG1()
pg1, err := g1.FromCompressed(key)
if err != nil {
return nil, err
}
pk := g1.ToUncompressed(pg1)
return pk, nil
}
// decompressBls12p381g2PublicKey is a dedicated key decompression function for bls12 381 g2 pks
func decompressBls12p381g2PublicKey(key []byte) ([]byte, error) {
g2 := bls12381.NewG2()
pg2, err := g2.FromCompressed(key)
if err != nil {
return nil, err
}
pk := g2.ToUncompressed(pg2)
return pk, nil
}
// multibaseEncode wraps `multibase.Encode()` extending the base functionality to support `0x` prefixed strings
func multibaseEncode(base string, data []byte) (string, error) {
if base == "0x" {
base = "f"
}
return multibase.Encode(multibase.Encoding(base[0]), data)
}
// multibaseDecode wraps `multibase.Decode()` extending the base functionality to support `0x` prefixed strings
func multibaseDecode(data string) ([]byte, error) {
if data[0:2] == "0x" {
data = "f" + data[2:]
}
_, dd, err := multibase.Decode(data)
return dd, err
}

View File

@@ -0,0 +1,101 @@
package api
import (
"encoding/json"
"path/filepath"
"testing"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/stretchr/testify/require"
)
func setupWalletTest(t *testing.T, password string) (backend *GethStatusBackend, defersFunc func(), err error) {
tmpdir := t.TempDir()
defers := make([]func(), 0)
defersFunc = func() {
for _, f := range defers {
f()
}
}
if err != nil {
return
}
backend = NewGethStatusBackend()
backend.UpdateRootDataDir(tmpdir)
err = backend.AccountManager().InitKeystore(filepath.Join(tmpdir, "keystore"))
if err != nil {
return
}
// Create master account
const pathWalletRoot = "m/44'/60'/0'/0"
accs, err := backend.AccountManager().
AccountsGenerator().
GenerateAndDeriveAddresses(12, 1, "", []string{pathWalletRoot})
if err != nil {
return
}
masterAccInfo := accs[0]
_, err = backend.AccountManager().AccountsGenerator().StoreDerivedAccounts(masterAccInfo.ID, password, []string{pathWalletRoot})
if err != nil {
return
}
account := multiaccounts.Account{
Name: "foo",
Timestamp: 1,
KeycardPairing: "pairing",
KeyUID: masterAccInfo.KeyUID,
}
err = backend.ensureDBsOpened(account, password)
require.NoError(t, err)
walletRootAddress := masterAccInfo.Derived[pathWalletRoot].Address
config, err := params.NewNodeConfig(tmpdir, 178733)
require.NoError(t, err)
networks := json.RawMessage("{}")
s := settings.Settings{
Address: types.HexToAddress(walletRootAddress),
DisplayName: "UserDisplayName",
CurrentNetwork: "mainnet_rpc",
DappsAddress: types.HexToAddress(walletRootAddress),
EIP1581Address: types.HexToAddress(walletRootAddress),
InstallationID: "d3efcff6-cffa-560e-a547-21d3858cbc51",
KeyUID: account.KeyUID,
LatestDerivedPath: 0,
Name: "Jittery Cornflowerblue Kingbird",
Networks: &networks,
PhotoPath: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAjklEQVR4nOzXwQmFMBAAUZXUYh32ZB32ZB02sxYQQSZGsod55/91WFgSS0RM+SyjA56ZRZhFmEWYRRT6h+M6G16zrxv6fdJpmUWYRbxsYr13dKfanpN0WmYRZhGzXz6AWYRZRIfbaX26fT9Jk07LLMIsosPt9I/dTDotswizCG+nhFmEWYRZhFnEHQAA///z1CFkYamgfQAAAABJRU5ErkJggg==",
PreviewPrivacy: false,
PublicKey: masterAccInfo.PublicKey,
SigningPhrase: "yurt joey vibe",
WalletRootAddress: types.HexToAddress(walletRootAddress)}
err = backend.saveAccountsAndSettings(s, config, nil)
require.Error(t, err)
require.True(t, err == accounts.ErrKeypairWithoutAccounts)
// this is for StatusNode().Config() call inside of the getVerifiedWalletAccount
err = backend.StartNode(config)
require.NoError(t, err)
defers = append(defers, func() {
require.NoError(t, backend.StopNode())
})
return
}

61
vendor/github.com/status-im/status-go/api/utils.go generated vendored Normal file
View File

@@ -0,0 +1,61 @@
package api
import (
"bytes"
"encoding/hex"
"strconv"
"strings"
"github.com/status-im/status-go/eth-node/crypto"
)
// RunAsync runs the specified function asynchronously.
func RunAsync(f func() error) <-chan error {
resp := make(chan error, 1)
go func() {
err := f()
resp <- err
close(resp)
}()
return resp
}
// HashMessage calculates the hash of a message to be safely signed by the keycard
// The hash is calulcated as
//
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
//
// This gives context to the signed message and prevents signing of transactions.
func HashMessage(message string) ([]byte, error) {
buf := bytes.NewBufferString("\x19Ethereum Signed Message:\n")
if value, ok := decodeHexStrict(message); ok {
if _, err := buf.WriteString(strconv.Itoa(len(value))); err != nil {
return nil, err
}
if _, err := buf.Write(value); err != nil {
return nil, err
}
} else {
if _, err := buf.WriteString(strconv.Itoa(len(message))); err != nil {
return nil, err
}
if _, err := buf.WriteString(message); err != nil {
return nil, err
}
}
return crypto.Keccak256(buf.Bytes()), nil
}
func decodeHexStrict(s string) ([]byte, bool) {
if !strings.HasPrefix(s, "0x") {
return nil, false
}
value, err := hex.DecodeString(s[2:])
if err != nil {
return nil, false
}
return value, true
}