status-go/account/generator/generator_test.go
Sale Djenic c1c7d2dbf6 fix: create acc from mnemonic endpoint extended
`CreateAccountFromMnemonic` function renamed to `createAccountFromMnemonicAndDeriveAccountsForPaths`
and extended in a way that it is able to derive accounts from passed mnemonic for the given paths, if paths is empty
only an account from the given mnemonic will be generated. This endpoint doesn't store anything anywhere.
2022-10-28 19:50:55 +02:00

160 lines
5.0 KiB
Go

package generator
import (
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/ethereum/go-ethereum/crypto"
)
var testAccount = struct {
mnemonic string
bip39Passphrase string
encriptionPassword string
extendedMasterKey string
bip44Key0 string
bip44PubKey0 string
bip44Address0 string
bip44Address1 string
}{
mnemonic: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
bip39Passphrase: "TREZOR",
encriptionPassword: "TEST_PASSWORD",
extendedMasterKey: "xprv9s21ZrQH143K3h3fDYiay8mocZ3afhfULfb5GX8kCBdno77K4HiA15Tg23wpbeF1pLfs1c5SPmYHrEpTuuRhxMwvKDwqdKiGJS9XFKzUsAF",
bip44Key0: "0x62f1d86b246c81bdd8f6c166d56896a4a5e1eddbcaebe06480e5c0bc74c28224",
bip44PubKey0: "0x04986dee3b8afe24cb8ccb2ac23dac3f8c43d22850d14b809b26d6b8aa5a1f47784152cd2c7d9edd0ab20392a837464b5a750b2a7f3f06e6a5756b5211b6a6ed05",
bip44Address0: "0x9c32F71D4DB8Fb9e1A58B0a80dF79935e7256FA6",
bip44Address1: "0x7AF7283bd1462C3b957e8FAc28Dc19cBbF2FAdfe",
}
const testAccountJSONFile = `{
"address":"9c32f71d4db8fb9e1a58b0a80df79935e7256fa6",
"crypto":
{
"cipher":"aes-128-ctr","ciphertext":"8055b65d5e41ef467c0cfe52ce6beda7f8dbe689221c6c43be9e9401bf173004",
"cipherparams":{"iv":"738f002e5e5343e0bb0e1050e098f721"},
"kdf":"scrypt",
"kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"9a54fbe1439ac567bd05039f76907b2c2846364a38b2f6813bcdac5ab0ec9d18"},
"mac":"79d817cd21afd4944e70d804d7871d10cbd15f25c6755416f780f81c1588677e"
},
"id":"6202ced9-f0cd-42e4-bf21-6029cca0ea91",
"version":3
}`
func TestGenerator_Generate(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
accountsInfo, err := g.Generate(12, 5, "")
assert.NoError(t, err)
assert.Equal(t, 5, len(g.accounts))
for _, info := range accountsInfo {
words := strings.Split(info.Mnemonic, " ")
assert.Equal(t, 12, len(words))
}
}
func TestGenerator_ImportPrivateKey(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
info, err := g.ImportPrivateKey(testAccount.bip44Key0)
assert.NoError(t, err)
assert.Equal(t, 1, len(g.accounts))
assert.Equal(t, testAccount.bip44PubKey0, info.PublicKey)
assert.Equal(t, testAccount.bip44Address0, info.Address)
}
func TestGenerator_CreateAccountFromMnemonicAndDeriveAccountsForPaths(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
info, err := g.CreateAccountFromMnemonicAndDeriveAccountsForPaths(testAccount.mnemonic, testAccount.bip39Passphrase, []string{})
assert.NoError(t, err)
assert.Equal(t, 0, len(g.accounts))
assert.Equal(t, 36, len(info.ID))
assert.Equal(t, 66, len(info.KeyUID))
}
func TestGenerator_ImportMnemonic(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
info, err := g.ImportMnemonic(testAccount.mnemonic, testAccount.bip39Passphrase)
assert.NoError(t, err)
assert.Equal(t, 1, len(g.accounts))
key := g.accounts[info.ID]
assert.Equal(t, testAccount.extendedMasterKey, key.extendedKey.String())
}
func TestGenerator_ImportJSONKey(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
// wrong password
_, err := g.ImportJSONKey(testAccountJSONFile, "wrong-password")
assert.Error(t, err)
// right password
info, err := g.ImportJSONKey(testAccountJSONFile, testAccount.encriptionPassword)
assert.NoError(t, err)
assert.Equal(t, 1, len(g.accounts))
assert.Equal(t, testAccount.bip44Address0, info.Address)
key := g.accounts[info.ID]
keyHex := fmt.Sprintf("0x%x", crypto.FromECDSA(key.privateKey))
assert.Equal(t, testAccount.bip44Key0, keyHex)
}
func TestGenerator_DeriveAddresses(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
info, err := g.ImportMnemonic(testAccount.mnemonic, testAccount.bip39Passphrase)
assert.NoError(t, err)
assert.Equal(t, 1, len(g.accounts))
path0 := "m/44'/60'/0'/0/0"
path1 := "m/44'/60'/0'/0/1"
addresses, err := g.DeriveAddresses(info.ID, []string{path0, path1})
assert.NoError(t, err)
assert.Equal(t, testAccount.bip44Address0, addresses[path0].Address)
assert.Equal(t, testAccount.bip44Address1, addresses[path1].Address)
}
func TestGenerator_DeriveAddresses_FromImportedPrivateKey(t *testing.T) {
g := New(nil)
assert.Equal(t, 0, len(g.accounts))
key, err := crypto.GenerateKey()
assert.NoError(t, err)
hex := fmt.Sprintf("%#x", crypto.FromECDSA(key))
info, err := g.ImportPrivateKey(hex)
assert.NoError(t, err)
assert.Equal(t, 1, len(g.accounts))
// normal imported accounts cannot derive child accounts,
// but only the address/pubblic key of the current key.
paths := []string{"", "m"}
for _, path := range paths {
addresses, err := g.DeriveAddresses(info.ID, []string{path})
assert.NoError(t, err)
expectedAddress := crypto.PubkeyToAddress(key.PublicKey).Hex()
assert.Equal(t, expectedAddress, addresses[path].Address)
}
// cannot derive other child keys from a normal key
_, err = g.DeriveAddresses(info.ID, []string{"m/0/1/2"})
assert.Equal(t, ErrAccountCannotDeriveChildKeys, err)
}