github.com/status-im/status-go@v1.1.0/account/generator/generator_test.go (about) 1 package generator 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 10 "github.com/ethereum/go-ethereum/crypto" 11 ) 12 13 var testAccount = struct { 14 mnemonic string 15 bip39Passphrase string 16 encriptionPassword string 17 extendedMasterKey string 18 bip44Key0 string 19 bip44PubKey0 string 20 bip44Address0 string 21 bip44Address1 string 22 }{ 23 mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about", 24 bip39Passphrase: "TREZOR", 25 encriptionPassword: "TEST_PASSWORD", 26 extendedMasterKey: "xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF", 27 bip44Key0: "0x62f1d86b246c81bdd8f6c166d56896a4a5e1eddbcaebe06480e5c0bc74c28224", 28 bip44PubKey0: "0x04986dee3b8afe24cb8ccb2ac23dac3f8c43d22850d14b809b26d6b8aa5a1f47784152cd2c7d9edd0ab20392a837464b5a750b2a7f3f06e6a5756b5211b6a6ed05", 29 bip44Address0: "0x9c32F71D4DB8Fb9e1A58B0a80dF79935e7256FA6", 30 bip44Address1: "0x7AF7283bd1462C3b957e8FAc28Dc19cBbF2FAdfe", 31 } 32 33 const testAccountJSONFile = `{ 34 "address":"9c32f71d4db8fb9e1a58b0a80df79935e7256fa6", 35 "crypto": 36 { 37 "cipher":"aes-128-ctr","ciphertext":"8055b65d5e41ef467c0cfe52ce6beda7f8dbe689221c6c43be9e9401bf173004", 38 "cipherparams":{"iv":"738f002e5e5343e0bb0e1050e098f721"}, 39 "kdf":"scrypt", 40 "kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"9a54fbe1439ac567bd05039f76907b2c2846364a38b2f6813bcdac5ab0ec9d18"}, 41 "mac":"79d817cd21afd4944e70d804d7871d10cbd15f25c6755416f780f81c1588677e" 42 }, 43 "id":"6202ced9-f0cd-42e4-bf21-6029cca0ea91", 44 "version":3 45 }` 46 47 const ( 48 path0 = "m/44'/60'/0'/0/0" 49 path1 = "m/44'/60'/0'/0/1" 50 ) 51 52 func TestGenerator_Generate(t *testing.T) { 53 g := New(nil) 54 assert.Equal(t, 0, len(g.accounts)) 55 56 accountsInfo, err := g.Generate(12, 5, "") 57 assert.NoError(t, err) 58 assert.Equal(t, 5, len(g.accounts)) 59 60 for _, info := range accountsInfo { 61 words := strings.Split(info.Mnemonic, " ") 62 assert.Equal(t, 12, len(words)) 63 } 64 } 65 66 func TestGenerator_CreateAccountFromPrivateKey(t *testing.T) { 67 g := New(nil) 68 assert.Equal(t, 0, len(g.accounts)) 69 70 info, err := g.CreateAccountFromPrivateKey(testAccount.bip44Key0) 71 72 assert.NoError(t, err) 73 assert.Equal(t, 0, len(g.accounts)) 74 assert.Equal(t, 66, len(info.KeyUID)) 75 } 76 77 func TestGenerator_ImportPrivateKey(t *testing.T) { 78 g := New(nil) 79 assert.Equal(t, 0, len(g.accounts)) 80 81 info, err := g.ImportPrivateKey(testAccount.bip44Key0) 82 assert.NoError(t, err) 83 assert.Equal(t, 1, len(g.accounts)) 84 85 assert.Equal(t, testAccount.bip44PubKey0, info.PublicKey) 86 assert.Equal(t, testAccount.bip44Address0, info.Address) 87 } 88 89 func TestGenerator_CreateAccountFromMnemonicAndDeriveAccountsForPaths(t *testing.T) { 90 g := New(nil) 91 assert.Equal(t, 0, len(g.accounts)) 92 93 info, err := g.CreateAccountFromMnemonicAndDeriveAccountsForPaths(testAccount.mnemonic, testAccount.bip39Passphrase, []string{path0, path1}) 94 95 assert.NoError(t, err) 96 assert.Equal(t, 0, len(g.accounts)) 97 assert.Equal(t, 66, len(info.KeyUID)) 98 99 assert.Equal(t, testAccount.bip44Address0, info.Derived[path0].Address) 100 assert.Equal(t, testAccount.bip44Address1, info.Derived[path1].Address) 101 } 102 103 func TestGenerator_ImportMnemonic(t *testing.T) { 104 g := New(nil) 105 assert.Equal(t, 0, len(g.accounts)) 106 107 info, err := g.ImportMnemonic(testAccount.mnemonic, testAccount.bip39Passphrase) 108 assert.NoError(t, err) 109 assert.Equal(t, 1, len(g.accounts)) 110 111 key := g.accounts[info.ID] 112 assert.Equal(t, testAccount.extendedMasterKey, key.extendedKey.String()) 113 } 114 115 func TestGenerator_ImportJSONKey(t *testing.T) { 116 g := New(nil) 117 assert.Equal(t, 0, len(g.accounts)) 118 119 // wrong password 120 _, err := g.ImportJSONKey(testAccountJSONFile, "wrong-password") 121 assert.Error(t, err) 122 123 // right password 124 info, err := g.ImportJSONKey(testAccountJSONFile, testAccount.encriptionPassword) 125 assert.NoError(t, err) 126 assert.Equal(t, 1, len(g.accounts)) 127 assert.Equal(t, testAccount.bip44Address0, info.Address) 128 129 key := g.accounts[info.ID] 130 keyHex := fmt.Sprintf("0x%x", crypto.FromECDSA(key.privateKey)) 131 assert.Equal(t, testAccount.bip44Key0, keyHex) 132 } 133 134 func TestGenerator_DeriveAddresses(t *testing.T) { 135 g := New(nil) 136 assert.Equal(t, 0, len(g.accounts)) 137 138 info, err := g.ImportMnemonic(testAccount.mnemonic, testAccount.bip39Passphrase) 139 assert.NoError(t, err) 140 assert.Equal(t, 1, len(g.accounts)) 141 142 addresses, err := g.DeriveAddresses(info.ID, []string{path0, path1}) 143 assert.NoError(t, err) 144 145 assert.Equal(t, testAccount.bip44Address0, addresses[path0].Address) 146 assert.Equal(t, testAccount.bip44Address1, addresses[path1].Address) 147 } 148 149 func TestGenerator_DeriveAddresses_FromImportedPrivateKey(t *testing.T) { 150 g := New(nil) 151 assert.Equal(t, 0, len(g.accounts)) 152 153 key, err := crypto.GenerateKey() 154 assert.NoError(t, err) 155 hex := fmt.Sprintf("%#x", crypto.FromECDSA(key)) 156 info, err := g.ImportPrivateKey(hex) 157 assert.NoError(t, err) 158 assert.Equal(t, 1, len(g.accounts)) 159 160 // normal imported accounts cannot derive child accounts, 161 // but only the address/pubblic key of the current key. 162 paths := []string{"", "m"} 163 for _, path := range paths { 164 addresses, err := g.DeriveAddresses(info.ID, []string{path}) 165 assert.NoError(t, err) 166 167 expectedAddress := crypto.PubkeyToAddress(key.PublicKey).Hex() 168 assert.Equal(t, expectedAddress, addresses[path].Address) 169 } 170 171 // cannot derive other child keys from a normal key 172 _, err = g.DeriveAddresses(info.ID, []string{"m/0/1/2"}) 173 assert.Equal(t, ErrAccountCannotDeriveChildKeys, err) 174 }