mirror of
https://github.com/status-im/status-go.git
synced 2025-01-09 14:16:21 +00:00
e8e6ef352b
When adding an account via seed phrase, for a key pair that was previously deleted, suggested path should start from index 0. It was not like that before, this commit fixes that.
678 lines
23 KiB
Go
678 lines
23 KiB
Go
package accounts
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/status-im/status-go/appdatabase"
|
|
"github.com/status-im/status-go/eth-node/types"
|
|
"github.com/status-im/status-go/multiaccounts/common"
|
|
"github.com/status-im/status-go/multiaccounts/settings"
|
|
"github.com/status-im/status-go/params"
|
|
"github.com/status-im/status-go/t/helpers"
|
|
)
|
|
|
|
func setupTestDB(t *testing.T) (*Database, func()) {
|
|
db, stop, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "settings-tests-")
|
|
require.NoError(t, err)
|
|
d, err := NewDB(db)
|
|
require.NoError(t, err)
|
|
return d, func() { require.NoError(t, stop()) }
|
|
}
|
|
|
|
func TestGetAddresses(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
accounts := []*Account{
|
|
{Address: types.Address{0x01}, Chat: true, Wallet: true},
|
|
{Address: types.Address{0x02}},
|
|
}
|
|
require.NoError(t, db.SaveOrUpdateAccounts(accounts, false))
|
|
addresses, err := db.GetAddresses()
|
|
require.NoError(t, err)
|
|
require.Equal(t, []types.Address{{0x01}, {0x02}}, addresses)
|
|
}
|
|
|
|
func TestMoveWalletAccount(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
|
|
networks := json.RawMessage("{}")
|
|
setting := settings.Settings{
|
|
Networks: &networks,
|
|
}
|
|
config := params.NodeConfig{}
|
|
err := db.CreateSettings(setting, config)
|
|
require.NoError(t, err)
|
|
|
|
accounts := []*Account{
|
|
{Address: types.Address{0x01}, Type: AccountTypeWatch, Position: 0},
|
|
{Address: types.Address{0x02}, Type: AccountTypeWatch, Position: 1},
|
|
{Address: types.Address{0x03}, Type: AccountTypeWatch, Position: 2},
|
|
{Address: types.Address{0x04}, Type: AccountTypeWatch, Position: 3},
|
|
{Address: types.Address{0x05}, Type: AccountTypeWatch, Position: 4},
|
|
{Address: types.Address{0x06}, Type: AccountTypeWatch, Position: 5},
|
|
}
|
|
require.NoError(t, db.SaveOrUpdateAccounts(accounts, false))
|
|
dbAccounts, err := db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Len(t, dbAccounts, len(accounts))
|
|
for i := 0; i < len(accounts); i++ {
|
|
require.True(t, SameAccounts(accounts[i], dbAccounts[i]))
|
|
}
|
|
|
|
clock := uint64(1000)
|
|
err = db.MoveWalletAccount(-1, 4, clock)
|
|
require.ErrorIs(t, err, ErrMovingAccountToWrongPosition)
|
|
err = db.MoveWalletAccount(4, -1, clock)
|
|
require.ErrorIs(t, err, ErrMovingAccountToWrongPosition)
|
|
err = db.MoveWalletAccount(4, 4, clock)
|
|
require.ErrorIs(t, err, ErrMovingAccountToWrongPosition)
|
|
|
|
// Move down account from position 1 to position 4
|
|
err = db.MoveWalletAccount(1, 4, clock)
|
|
require.NoError(t, err)
|
|
|
|
// Expected after moving down
|
|
accounts = []*Account{
|
|
{Address: types.Address{0x01}, Type: AccountTypeWatch, Position: 0},
|
|
{Address: types.Address{0x03}, Type: AccountTypeWatch, Position: 1},
|
|
{Address: types.Address{0x04}, Type: AccountTypeWatch, Position: 2},
|
|
{Address: types.Address{0x05}, Type: AccountTypeWatch, Position: 3},
|
|
{Address: types.Address{0x02}, Type: AccountTypeWatch, Position: 4}, // acc with addr 0x02 is at position 4 (moved from position 1)
|
|
{Address: types.Address{0x06}, Type: AccountTypeWatch, Position: 5},
|
|
}
|
|
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
for i := 0; i < len(accounts); i++ {
|
|
require.True(t, SameAccounts(accounts[i], dbAccounts[i]))
|
|
}
|
|
|
|
// Check clock
|
|
dbClock, err := db.GetClockOfLastAccountsPositionChange()
|
|
require.NoError(t, err)
|
|
require.Equal(t, clock, dbClock)
|
|
|
|
// Move up account from position 5 to position 0
|
|
clock = 2000
|
|
err = db.MoveWalletAccount(5, 0, clock)
|
|
require.NoError(t, err)
|
|
|
|
// Expected after moving up
|
|
accounts = []*Account{
|
|
{Address: types.Address{0x06}, Type: AccountTypeWatch, Position: 0}, // acc with addr 0x06 is at position 0 (moved from position 5)
|
|
{Address: types.Address{0x01}, Type: AccountTypeWatch, Position: 1},
|
|
{Address: types.Address{0x03}, Type: AccountTypeWatch, Position: 2},
|
|
{Address: types.Address{0x04}, Type: AccountTypeWatch, Position: 3},
|
|
{Address: types.Address{0x05}, Type: AccountTypeWatch, Position: 4},
|
|
{Address: types.Address{0x02}, Type: AccountTypeWatch, Position: 5},
|
|
}
|
|
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
for i := 0; i < len(accounts); i++ {
|
|
require.True(t, SameAccounts(accounts[i], dbAccounts[i]))
|
|
}
|
|
|
|
// Check clock
|
|
dbClock, err = db.GetClockOfLastAccountsPositionChange()
|
|
require.NoError(t, err)
|
|
require.Equal(t, clock, dbClock)
|
|
}
|
|
|
|
func TestGetWalletAddress(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
address := types.Address{0x01}
|
|
_, err := db.GetWalletAddress()
|
|
require.Equal(t, err, sql.ErrNoRows)
|
|
require.NoError(t, db.SaveOrUpdateAccounts([]*Account{{Address: address, Wallet: true}}, false))
|
|
wallet, err := db.GetWalletAddress()
|
|
require.NoError(t, err)
|
|
require.Equal(t, address, wallet)
|
|
}
|
|
|
|
func TestGetChatAddress(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
address := types.Address{0x01}
|
|
_, err := db.GetChatAddress()
|
|
require.Equal(t, err, sql.ErrNoRows)
|
|
require.NoError(t, db.SaveOrUpdateAccounts([]*Account{{Address: address, Chat: true}}, false))
|
|
chat, err := db.GetChatAddress()
|
|
require.NoError(t, err)
|
|
require.Equal(t, address, chat)
|
|
}
|
|
|
|
func TestAddressExists(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
|
|
accounts := []*Account{
|
|
{Address: types.Address{0x01}, Chat: true, Wallet: true},
|
|
}
|
|
require.NoError(t, db.SaveOrUpdateAccounts(accounts, false))
|
|
|
|
exists, err := db.AddressExists(accounts[0].Address)
|
|
require.NoError(t, err)
|
|
require.True(t, exists)
|
|
}
|
|
|
|
func TestAddressDoesntExist(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
exists, err := db.AddressExists(types.Address{1, 1, 1})
|
|
require.NoError(t, err)
|
|
require.False(t, exists)
|
|
}
|
|
|
|
func TestWatchOnlyAccounts(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
|
|
// check the db
|
|
dbAccounts, err := db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, len(dbAccounts))
|
|
|
|
woAccounts := GetWatchOnlyAccountsForTest()
|
|
|
|
// try to save keypair with watch only accounts
|
|
kp := &Keypair{}
|
|
kp.Accounts = append(kp.Accounts, woAccounts...)
|
|
err = db.SaveOrUpdateKeypair(kp)
|
|
require.Error(t, err)
|
|
|
|
// check the db after that trying to save keypair with watch only accounts
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, len(dbAccounts))
|
|
|
|
// save watch only accounts
|
|
err = db.SaveOrUpdateAccounts(woAccounts, false)
|
|
require.NoError(t, err)
|
|
_, err = db.GetKeypairByKeyUID(woAccounts[0].KeyUID)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbKeypairNotFound)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(woAccounts), len(dbAccounts))
|
|
require.Equal(t, woAccounts[0].Address, dbAccounts[0].Address)
|
|
|
|
// try to save the same watch only account again
|
|
err = db.SaveOrUpdateAccounts(woAccounts[:1], false)
|
|
require.NoError(t, err)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(woAccounts), len(dbAccounts))
|
|
dbAcc, err := db.GetAccountByAddress(woAccounts[:1][0].Address)
|
|
require.NoError(t, err)
|
|
require.Equal(t, woAccounts[:1][0].Address, dbAcc.Address)
|
|
|
|
// try to save new watch only account
|
|
wo4 := &Account{
|
|
Address: types.Address{0x14},
|
|
Type: AccountTypeWatch,
|
|
Name: "WatchOnlyAcc4",
|
|
ColorID: common.CustomizationColorPrimary,
|
|
Emoji: "emoji-1",
|
|
}
|
|
err = db.SaveOrUpdateAccounts([]*Account{wo4}, false)
|
|
require.NoError(t, err)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(woAccounts)+1, len(dbAccounts))
|
|
dbAcc, err = db.GetAccountByAddress(wo4.Address)
|
|
require.NoError(t, err)
|
|
require.Equal(t, wo4.Address, dbAcc.Address)
|
|
|
|
// updated watch onl to save the same account after it's saved
|
|
wo4.Name = wo4.Name + "updated"
|
|
wo4.ColorID = common.CustomizationColorCamel
|
|
wo4.Emoji = wo4.Emoji + "updated"
|
|
err = db.SaveOrUpdateAccounts([]*Account{wo4}, false)
|
|
require.NoError(t, err)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(woAccounts)+1, len(dbAccounts))
|
|
dbAcc, err = db.GetAccountByAddress(wo4.Address)
|
|
require.NoError(t, err)
|
|
require.Equal(t, wo4.Address, dbAcc.Address)
|
|
|
|
// try to delete keypair for watch only account
|
|
err = db.RemoveKeypair(wo4.KeyUID, 0)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbKeypairNotFound)
|
|
|
|
// try to delete watch only account
|
|
err = db.RemoveAccount(wo4.Address, 0)
|
|
require.NoError(t, err)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(woAccounts), len(dbAccounts))
|
|
_, err = db.GetAccountByAddress(wo4.Address)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbAccountNotFound)
|
|
}
|
|
|
|
func TestUpdateKeypairName(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
|
|
kp := GetProfileKeypairForTest(true, false, false)
|
|
|
|
// check the db
|
|
dbAccounts, err := db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, len(dbAccounts))
|
|
|
|
// save keypair
|
|
err = db.SaveOrUpdateKeypair(kp)
|
|
require.NoError(t, err)
|
|
dbKeypairs, err := db.GetActiveKeypairs()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(dbKeypairs))
|
|
require.True(t, SameKeypairs(kp, dbKeypairs[0]))
|
|
|
|
// update keypair name
|
|
kp.Name = kp.Name + "updated"
|
|
kp.Accounts[0].Name = kp.Name
|
|
err = db.UpdateKeypairName(kp.KeyUID, kp.Name, kp.Clock, true)
|
|
require.NoError(t, err)
|
|
|
|
// check keypair
|
|
dbKp, err := db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
|
|
require.True(t, SameKeypairs(kp, dbKp))
|
|
}
|
|
|
|
func TestKeypairs(t *testing.T) {
|
|
keypairs := []*Keypair{
|
|
GetProfileKeypairForTest(true, true, true),
|
|
GetSeedImportedKeypair1ForTest(),
|
|
GetPrivKeyImportedKeypairForTest(), // in this context (when testing db functions) there is not limitations for private key imported keypair
|
|
}
|
|
|
|
for _, kp := range keypairs {
|
|
t.Run("test keypair "+kp.Name, func(t *testing.T) {
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
|
|
// check the db
|
|
dbKeypairs, err := db.GetActiveKeypairs()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, len(dbKeypairs))
|
|
dbAccounts, err := db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, len(dbAccounts))
|
|
|
|
expectedLastUsedDerivationIndex := uint64(len(kp.Accounts) - 1)
|
|
if kp.Type == KeypairTypeProfile {
|
|
expectedLastUsedDerivationIndex-- // subtract one more in case of profile keypair because of chat account
|
|
}
|
|
|
|
// save keypair
|
|
err = db.SaveOrUpdateKeypair(kp)
|
|
require.NoError(t, err)
|
|
dbKeypairs, err = db.GetActiveKeypairs()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(dbKeypairs))
|
|
dbKp, err := db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
|
|
kp.LastUsedDerivationIndex = expectedLastUsedDerivationIndex
|
|
require.Equal(t, kp.KeyUID, dbKp.KeyUID)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbAccounts))
|
|
|
|
// delete keypair
|
|
err = db.RemoveKeypair(kp.KeyUID, 0)
|
|
require.NoError(t, err)
|
|
_, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbKeypairNotFound)
|
|
|
|
// save keypair again to test the flow below
|
|
err = db.SaveOrUpdateKeypair(kp)
|
|
require.NoError(t, err)
|
|
dbKeypairs, err = db.GetActiveKeypairs()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(dbKeypairs))
|
|
|
|
ind := len(kp.Accounts) - 1
|
|
accToUpdate := kp.Accounts[ind]
|
|
|
|
// try to save the same account again
|
|
err = db.SaveOrUpdateAccounts([]*Account{accToUpdate}, false)
|
|
require.NoError(t, err)
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
|
|
require.Equal(t, kp.KeyUID, dbKp.KeyUID)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbAccounts))
|
|
|
|
// update an existing account
|
|
accToUpdate.Name = accToUpdate.Name + "updated"
|
|
accToUpdate.ColorID = common.CustomizationColorBrown
|
|
accToUpdate.Emoji = accToUpdate.Emoji + "updated"
|
|
|
|
err = db.SaveOrUpdateAccounts([]*Account{accToUpdate}, false)
|
|
require.NoError(t, err)
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbAccounts))
|
|
dbAcc, err := db.GetAccountByAddress(accToUpdate.Address)
|
|
require.NoError(t, err)
|
|
require.Equal(t, accToUpdate.Address, dbAcc.Address)
|
|
|
|
// update keypair name
|
|
kpToUpdate := kp
|
|
kpToUpdate.Name = kpToUpdate.Name + "updated"
|
|
err = db.SaveOrUpdateKeypair(kp)
|
|
require.NoError(t, err)
|
|
dbKeypairs, err = db.GetActiveKeypairs()
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, len(dbKeypairs))
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts), len(dbKp.Accounts))
|
|
require.Equal(t, kpToUpdate.KeyUID, dbKp.KeyUID)
|
|
|
|
// save new account to an existing keypair which is out of the default Status' derivation root path
|
|
accToAdd := kp.Accounts[ind]
|
|
accToAdd.Address = types.Address{0x08}
|
|
accToAdd.Path = "m/44'/60'/0'/0/10"
|
|
accToAdd.PublicKey = types.Hex2Bytes("0x000000008")
|
|
accToAdd.Name = "Generated Acc 8"
|
|
|
|
err = db.SaveOrUpdateAccounts([]*Account{accToAdd}, false)
|
|
require.NoError(t, err)
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts)+1, len(dbKp.Accounts))
|
|
require.Equal(t, kp.LastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts)+1, len(dbAccounts))
|
|
dbAcc, err = db.GetAccountByAddress(accToUpdate.Address)
|
|
require.NoError(t, err)
|
|
require.Equal(t, accToAdd.Address, dbAcc.Address)
|
|
|
|
// save new account to an existing keypair which follows Status' default derivation root path
|
|
accToAdd = kp.Accounts[ind]
|
|
accToAdd.Address = types.Address{0x09}
|
|
accToAdd.Path = "m/44'/60'/0'/0/3"
|
|
accToAdd.PublicKey = types.Hex2Bytes("0x000000009")
|
|
accToAdd.Name = "Generated Acc 9"
|
|
|
|
expectedLastUsedDerivationIndex = 3
|
|
if kp.Type == KeypairTypeSeed {
|
|
accToAdd.Path = "m/44'/60'/0'/0/2"
|
|
expectedLastUsedDerivationIndex = 2
|
|
} else if kp.Type == KeypairTypeKey {
|
|
accToAdd.Path = "m/44'/60'/0'/0/1"
|
|
expectedLastUsedDerivationIndex = 1
|
|
}
|
|
|
|
err = db.SaveOrUpdateAccounts([]*Account{accToAdd}, false)
|
|
require.NoError(t, err)
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts)+2, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts)+2, len(dbAccounts))
|
|
dbAcc, err = db.GetAccountByAddress(accToUpdate.Address)
|
|
require.NoError(t, err)
|
|
require.Equal(t, accToAdd.Address, dbAcc.Address)
|
|
|
|
// delete account
|
|
err = db.RemoveAccount(accToAdd.Address, 0)
|
|
require.NoError(t, err)
|
|
dbAccounts, err = db.GetActiveAccounts()
|
|
require.NoError(t, err)
|
|
require.Equal(t, len(kp.Accounts)+1, len(dbAccounts))
|
|
_, err = db.GetAccountByAddress(accToAdd.Address)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbAccountNotFound)
|
|
|
|
for _, acc := range dbAccounts {
|
|
err = db.RemoveAccount(acc.Address, 0)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
_, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbKeypairNotFound)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResolvingSuggestedDerivationPath(t *testing.T) {
|
|
kp := GetProfileKeypairForTest(true, true, true)
|
|
totalNumOfAccounts := len(kp.Accounts)
|
|
|
|
db, stop := setupTestDB(t)
|
|
defer stop()
|
|
|
|
// check the db
|
|
dbKp, err := db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbKeypairNotFound)
|
|
require.Nil(t, dbKp)
|
|
|
|
expectedLastUsedDerivationIndex := uint64(2)
|
|
|
|
// save keypair
|
|
err = db.SaveOrUpdateKeypair(kp)
|
|
require.NoError(t, err)
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, totalNumOfAccounts, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
|
|
// check number of addresses to generate
|
|
numOfAddresses, err := db.GetNumOfAddressesToGenerateForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, maxNumOfGeneratedAddresses, numOfAddresses)
|
|
|
|
// check suggested path
|
|
suggestedPath, err := db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+1), suggestedPath)
|
|
|
|
// prepare new account with the next suggested path
|
|
generatedWalletAccountThatWillBeRemovedLater := &Account{
|
|
Address: types.Address{0x05},
|
|
KeyUID: kp.KeyUID,
|
|
Wallet: false,
|
|
Chat: false,
|
|
Type: AccountTypeGenerated,
|
|
Path: suggestedPath,
|
|
PublicKey: types.Hex2Bytes("0x000000005"),
|
|
Name: "Generated Acc 4",
|
|
Emoji: "emoji-4",
|
|
ColorID: common.CustomizationColorPrimary,
|
|
Hidden: false,
|
|
Clock: 0,
|
|
Removed: false,
|
|
Operable: AccountFullyOperable,
|
|
ProdPreferredChainIDs: "1",
|
|
TestPreferredChainIDs: "5",
|
|
}
|
|
|
|
// add new account with the next suggested path
|
|
err = db.SaveOrUpdateAccounts([]*Account{generatedWalletAccountThatWillBeRemovedLater}, false)
|
|
require.NoError(t, err)
|
|
|
|
totalNumOfAccounts++
|
|
expectedLastUsedDerivationIndex++
|
|
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, totalNumOfAccounts, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
|
|
// check suggested path
|
|
suggestedPath, err = db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+1), suggestedPath)
|
|
|
|
customSuggestedPath := fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+1+1)
|
|
|
|
// prepare new account with the custom suggested path
|
|
generatedWalletAccount := &Account{
|
|
Address: types.Address{0x07},
|
|
KeyUID: kp.KeyUID,
|
|
Wallet: false,
|
|
Chat: false,
|
|
Type: AccountTypeGenerated,
|
|
Path: customSuggestedPath,
|
|
PublicKey: types.Hex2Bytes("0x000000007"),
|
|
Name: "Generated Acc 6",
|
|
Emoji: "emoji-6",
|
|
ColorID: common.CustomizationColorPrimary,
|
|
Hidden: false,
|
|
Clock: 0,
|
|
Removed: false,
|
|
Operable: AccountFullyOperable,
|
|
ProdPreferredChainIDs: "1",
|
|
TestPreferredChainIDs: "5",
|
|
}
|
|
|
|
// add new account with the next suggested path
|
|
err = db.SaveOrUpdateAccounts([]*Account{generatedWalletAccount}, false)
|
|
require.NoError(t, err)
|
|
|
|
totalNumOfAccounts++
|
|
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, totalNumOfAccounts, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
|
|
// check suggested path
|
|
suggestedPath, err = db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+1), suggestedPath)
|
|
|
|
// prepare new account with the next suggested path
|
|
generatedWalletAccount = &Account{
|
|
Address: types.Address{0x06},
|
|
KeyUID: kp.KeyUID,
|
|
Wallet: false,
|
|
Chat: false,
|
|
Type: AccountTypeGenerated,
|
|
Path: suggestedPath,
|
|
PublicKey: types.Hex2Bytes("0x000000006"),
|
|
Name: "Generated Acc 5",
|
|
Emoji: "emoji-5",
|
|
ColorID: common.CustomizationColorPrimary,
|
|
Hidden: false,
|
|
Clock: 0,
|
|
Removed: false,
|
|
Operable: AccountFullyOperable,
|
|
ProdPreferredChainIDs: "1",
|
|
TestPreferredChainIDs: "5",
|
|
}
|
|
|
|
// add new account with the next suggested path
|
|
err = db.SaveOrUpdateAccounts([]*Account{generatedWalletAccount}, false)
|
|
require.NoError(t, err)
|
|
|
|
totalNumOfAccounts++
|
|
expectedLastUsedDerivationIndex++
|
|
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, totalNumOfAccounts, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
|
|
// check suggested path
|
|
suggestedPath, err = db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+2), suggestedPath)
|
|
|
|
// prepare new account with the next suggested path
|
|
generatedWalletAccount = &Account{
|
|
Address: types.Address{0x08},
|
|
KeyUID: kp.KeyUID,
|
|
Wallet: false,
|
|
Chat: false,
|
|
Type: AccountTypeGenerated,
|
|
Path: suggestedPath,
|
|
PublicKey: types.Hex2Bytes("0x000000008"),
|
|
Name: "Generated Acc 7",
|
|
Emoji: "emoji-7",
|
|
ColorID: common.CustomizationColorPrimary,
|
|
Hidden: false,
|
|
Clock: 0,
|
|
Removed: false,
|
|
Operable: AccountFullyOperable,
|
|
ProdPreferredChainIDs: "1",
|
|
TestPreferredChainIDs: "5",
|
|
}
|
|
|
|
// add new account with the next suggested path
|
|
err = db.SaveOrUpdateAccounts([]*Account{generatedWalletAccount}, false)
|
|
require.NoError(t, err)
|
|
|
|
totalNumOfAccounts++
|
|
expectedLastUsedDerivationIndex += 2
|
|
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, totalNumOfAccounts, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
|
|
// check suggested path
|
|
suggestedPath, err = db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+1), suggestedPath)
|
|
|
|
// remove account
|
|
err = db.RemoveAccount(generatedWalletAccountThatWillBeRemovedLater.Address, 0)
|
|
require.NoError(t, err)
|
|
|
|
totalNumOfAccounts--
|
|
|
|
dbKp, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, totalNumOfAccounts, len(dbKp.Accounts))
|
|
require.Equal(t, expectedLastUsedDerivationIndex, dbKp.LastUsedDerivationIndex)
|
|
|
|
_, err = db.GetAccountByAddress(generatedWalletAccountThatWillBeRemovedLater.Address)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbAccountNotFound)
|
|
|
|
// check suggested path after removing account
|
|
suggestedPath, err = db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, expectedLastUsedDerivationIndex+1), suggestedPath)
|
|
|
|
// remove kaypair
|
|
err = db.RemoveKeypair(kp.KeyUID, 0)
|
|
require.NoError(t, err)
|
|
_, err = db.GetKeypairByKeyUID(kp.KeyUID)
|
|
require.Error(t, err)
|
|
require.True(t, err == ErrDbKeypairNotFound)
|
|
|
|
// check suggested path after removing keypair when adding the same keypair again
|
|
suggestedPath, err = db.ResolveSuggestedPathForKeypair(kp.KeyUID)
|
|
require.NoError(t, err)
|
|
require.Equal(t, fmt.Sprintf("%s%d", statusWalletRootPath, 0), suggestedPath)
|
|
}
|