Unlock wallet and chat keys (#1346)
* select account decrypting wallet and chat keys * adapt account tests to use chat and wallet account/keys * fix tests using chat address * changes after review * fix status service e2e tests * add account.Info struct returned when creating and recovering an account * use s.EqualValues to compare recovered accounts * return Info instead of *Info * add both address and walletAddress to responses * Update lib/types.go Co-Authored-By: gravityblast <andrea@gravityblast.com> * Update lib/types.go Co-Authored-By: gravityblast <andrea@gravityblast.com> * update comment to fix lint
This commit is contained in:
parent
6e88828d76
commit
4939268edf
|
@ -51,12 +51,13 @@ func NewManager(geth GethServiceProvider) *Manager {
|
|||
// BIP44-compatible keys are generated: CKD#1 is stored as account key, CKD#2 stored as sub-account root
|
||||
// Public key of CKD#1 is returned, with CKD#2 securely encoded into account key file (to be used for
|
||||
// sub-account derivations)
|
||||
func (m *Manager) CreateAccount(password string) (address, pubKey, mnemonic string, err error) {
|
||||
func (m *Manager) CreateAccount(password string) (Info, string, error) {
|
||||
info := Info{}
|
||||
// generate mnemonic phrase
|
||||
mn := extkeys.NewMnemonic()
|
||||
mnemonic, err = mn.MnemonicPhrase(extkeys.EntropyStrength128, extkeys.EnglishLanguage)
|
||||
mnemonic, err := mn.MnemonicPhrase(extkeys.EntropyStrength128, extkeys.EnglishLanguage)
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("can not create mnemonic seed: %v", err)
|
||||
return info, "", fmt.Errorf("can not create mnemonic seed: %v", err)
|
||||
}
|
||||
|
||||
// Generate extended master key (see BIP32)
|
||||
|
@ -66,16 +67,19 @@ func (m *Manager) CreateAccount(password string) (address, pubKey, mnemonic stri
|
|||
// for expert users, to be able to add a passphrase to the generation of the seed.
|
||||
extKey, err := extkeys.NewMaster(mn.MnemonicSeed(mnemonic, ""))
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("can not create master extended key: %v", err)
|
||||
return info, "", fmt.Errorf("can not create master extended key: %v", err)
|
||||
}
|
||||
|
||||
// import created key into account keystore
|
||||
address, pubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
|
||||
info.WalletAddress, info.WalletPubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return info, "", err
|
||||
}
|
||||
|
||||
return address, pubKey, mnemonic, nil
|
||||
info.ChatAddress = info.WalletAddress
|
||||
info.ChatPubKey = info.WalletPubKey
|
||||
|
||||
return info, mnemonic, nil
|
||||
}
|
||||
|
||||
// CreateChildAccount creates sub-account for an account identified by parent address.
|
||||
|
@ -140,21 +144,25 @@ func (m *Manager) CreateChildAccount(parentAddress, password string) (address, p
|
|||
|
||||
// RecoverAccount re-creates master key using given details.
|
||||
// Once master key is re-generated, it is inserted into keystore (if not already there).
|
||||
func (m *Manager) RecoverAccount(password, mnemonic string) (address, pubKey string, err error) {
|
||||
func (m *Manager) RecoverAccount(password, mnemonic string) (Info, error) {
|
||||
info := Info{}
|
||||
// re-create extended key (see BIP32)
|
||||
mn := extkeys.NewMnemonic()
|
||||
extKey, err := extkeys.NewMaster(mn.MnemonicSeed(mnemonic, ""))
|
||||
if err != nil {
|
||||
return "", "", ErrInvalidMasterKeyCreated
|
||||
return info, ErrInvalidMasterKeyCreated
|
||||
}
|
||||
|
||||
// import re-created key into account keystore
|
||||
address, pubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
|
||||
info.WalletAddress, info.WalletPubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
|
||||
if err != nil {
|
||||
return
|
||||
return info, err
|
||||
}
|
||||
|
||||
return address, pubKey, nil
|
||||
info.ChatAddress = info.WalletAddress
|
||||
info.ChatPubKey = info.WalletPubKey
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
// VerifyAccountPassword tries to decrypt a given account key file, with a provided password.
|
||||
|
@ -217,44 +225,22 @@ func (m *Manager) VerifyAccountPassword(keyStoreDir, address, password string) (
|
|||
|
||||
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
|
||||
// using provided password. Once verification is done, all previous identities are removed).
|
||||
func (m *Manager) SelectAccount(address, password string) error {
|
||||
func (m *Manager) SelectAccount(walletAddress, chatAddress, password string) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
|
||||
keyStore, err := m.geth.AccountKeyStore()
|
||||
selectedWalletAccount, err := m.unlockExtendedKey(walletAddress, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
account, err := ParseAccountString(address)
|
||||
if err != nil {
|
||||
return ErrAddressToAccountMappingFailure
|
||||
}
|
||||
|
||||
account, accountKey, err := keyStore.AccountDecryptedKey(account, password)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: %v", ErrAccountToKeyMappingFailure.Error(), err)
|
||||
}
|
||||
|
||||
// persist account key for easier recovery of currently selected key
|
||||
subAccounts, err := m.findSubAccounts(accountKey.ExtendedKey, accountKey.SubAccountIndex)
|
||||
selectedChatAccount, err := m.unlockExtendedKey(chatAddress, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.selectedWalletAccount = &SelectedExtKey{
|
||||
Address: account.Address,
|
||||
AccountKey: accountKey,
|
||||
SubAccounts: subAccounts,
|
||||
}
|
||||
|
||||
// Before completely decoupling the wallet and chat keys,
|
||||
// we have a selectedChatAccount with the same key used for the wallet.
|
||||
m.selectedChatAccount = &SelectedExtKey{
|
||||
Address: account.Address,
|
||||
AccountKey: accountKey,
|
||||
SubAccounts: subAccounts,
|
||||
}
|
||||
m.selectedWalletAccount = selectedWalletAccount
|
||||
m.selectedChatAccount = selectedChatAccount
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -428,5 +414,33 @@ func (m *Manager) AddressToDecryptedAccount(address, password string) (accounts.
|
|||
return accounts.Account{}, nil, ErrAddressToAccountMappingFailure
|
||||
}
|
||||
|
||||
return keyStore.AccountDecryptedKey(account, password)
|
||||
var key *keystore.Key
|
||||
|
||||
account, key, err = keyStore.AccountDecryptedKey(account, password)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s: %s", ErrAccountToKeyMappingFailure, err)
|
||||
}
|
||||
|
||||
return account, key, err
|
||||
}
|
||||
|
||||
func (m *Manager) unlockExtendedKey(address, password string) (*SelectedExtKey, error) {
|
||||
account, accountKey, err := m.AddressToDecryptedAccount(address, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// persist account key for easier recovery of currently selected key
|
||||
subAccounts, err := m.findSubAccounts(accountKey.ExtendedKey, accountKey.SubAccountIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
selectedExtendedKey := &SelectedExtKey{
|
||||
Address: account.Address,
|
||||
AccountKey: accountKey,
|
||||
SubAccounts: subAccounts,
|
||||
}
|
||||
|
||||
return selectedExtendedKey, nil
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/golang/mock/gomock"
|
||||
. "github.com/status-im/status-go/t/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
@ -32,7 +33,7 @@ func TestVerifyAccountPassword(t *testing.T) {
|
|||
require.NoError(t, ImportTestAccount(keyStoreDir, GetAccount1PKFile()))
|
||||
require.NoError(t, ImportTestAccount(keyStoreDir, GetAccount2PKFile()))
|
||||
|
||||
account1Address := gethcommon.BytesToAddress(gethcommon.FromHex(TestConfig.Account1.Address))
|
||||
account1Address := gethcommon.BytesToAddress(gethcommon.FromHex(TestConfig.Account1.WalletAddress))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -44,21 +45,21 @@ func TestVerifyAccountPassword(t *testing.T) {
|
|||
{
|
||||
"correct address, correct password (decrypt should succeed)",
|
||||
keyStoreDir,
|
||||
TestConfig.Account1.Address,
|
||||
TestConfig.Account1.WalletAddress,
|
||||
TestConfig.Account1.Password,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"correct address, correct password, non-existent key store",
|
||||
filepath.Join(keyStoreDir, "non-existent-folder"),
|
||||
TestConfig.Account1.Address,
|
||||
TestConfig.Account1.WalletAddress,
|
||||
TestConfig.Account1.Password,
|
||||
fmt.Errorf("cannot traverse key store folder: lstat %s/non-existent-folder: no such file or directory", keyStoreDir),
|
||||
},
|
||||
{
|
||||
"correct address, correct password, empty key store (pk is not there)",
|
||||
emptyKeyStoreDir,
|
||||
TestConfig.Account1.Address,
|
||||
TestConfig.Account1.WalletAddress,
|
||||
TestConfig.Account1.Password,
|
||||
fmt.Errorf("cannot locate account for address: %s", account1Address.Hex()),
|
||||
},
|
||||
|
@ -72,7 +73,7 @@ func TestVerifyAccountPassword(t *testing.T) {
|
|||
{
|
||||
"correct address, wrong password",
|
||||
keyStoreDir,
|
||||
TestConfig.Account1.Address,
|
||||
TestConfig.Account1.WalletAddress,
|
||||
"wrong password", // wrong password
|
||||
errors.New("could not decrypt key with given passphrase"),
|
||||
},
|
||||
|
@ -107,7 +108,7 @@ func TestVerifyAccountPasswordWithAccountBeforeEIP55(t *testing.T) {
|
|||
|
||||
accManager := NewManager(nil)
|
||||
|
||||
address := gethcommon.HexToAddress(TestConfig.Account3.Address)
|
||||
address := gethcommon.HexToAddress(TestConfig.Account3.WalletAddress)
|
||||
_, err = accManager.VerifyAccountPassword(keyStoreDir, address.Hex(), TestConfig.Account3.Password)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
@ -130,17 +131,25 @@ func TestManagerTestSuite(t *testing.T) {
|
|||
|
||||
// Initial test - create test account
|
||||
gethServiceProvider.EXPECT().AccountKeyStore().Return(keyStore, nil)
|
||||
addr, pubKey, mnemonic, err := accManager.CreateAccount(testPassword)
|
||||
accountInfo, mnemonic, err := accManager.CreateAccount(testPassword)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, addr)
|
||||
require.NotEmpty(t, pubKey)
|
||||
require.NotEmpty(t, accountInfo.WalletAddress)
|
||||
require.NotEmpty(t, accountInfo.WalletPubKey)
|
||||
require.NotEmpty(t, accountInfo.ChatAddress)
|
||||
require.NotEmpty(t, accountInfo.ChatPubKey)
|
||||
require.NotEmpty(t, mnemonic)
|
||||
|
||||
// Before the complete decoupling of the keys, wallet and chat keys are the same
|
||||
assert.Equal(t, accountInfo.WalletAddress, accountInfo.ChatAddress)
|
||||
assert.Equal(t, accountInfo.WalletPubKey, accountInfo.ChatPubKey)
|
||||
|
||||
s := &ManagerTestSuite{
|
||||
testAccount: testAccount{
|
||||
"test-password",
|
||||
addr,
|
||||
pubKey,
|
||||
accountInfo.WalletAddress,
|
||||
accountInfo.WalletPubKey,
|
||||
accountInfo.ChatAddress,
|
||||
accountInfo.ChatPubKey,
|
||||
mnemonic,
|
||||
},
|
||||
gethServiceProvider: gethServiceProvider,
|
||||
|
@ -167,10 +176,12 @@ type ManagerTestSuite struct {
|
|||
}
|
||||
|
||||
type testAccount struct {
|
||||
password string
|
||||
address string
|
||||
pubKey string
|
||||
mnemonic string
|
||||
password string
|
||||
walletAddress string
|
||||
walletPubKey string
|
||||
chatAddress string
|
||||
chatPubKey string
|
||||
mnemonic string
|
||||
}
|
||||
|
||||
// reinitMock is for reassigning a new mock node manager to account manager.
|
||||
|
@ -190,23 +201,25 @@ func (s *ManagerTestSuite) SetupTest() {
|
|||
func (s *ManagerTestSuite) TestCreateAccount() {
|
||||
// Don't fail on empty password
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(s.keyStore, nil)
|
||||
_, _, _, err := s.accManager.CreateAccount(s.password)
|
||||
_, _, err := s.accManager.CreateAccount(s.password)
|
||||
s.NoError(err)
|
||||
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(nil, errKeyStore)
|
||||
_, _, _, err = s.accManager.CreateAccount(s.password)
|
||||
_, _, err = s.accManager.CreateAccount(s.password)
|
||||
s.Equal(errKeyStore, err)
|
||||
}
|
||||
|
||||
func (s *ManagerTestSuite) TestRecoverAccount() {
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(s.keyStore, nil)
|
||||
addr, pubKey, err := s.accManager.RecoverAccount(s.password, s.mnemonic)
|
||||
accountInfo, err := s.accManager.RecoverAccount(s.password, s.mnemonic)
|
||||
s.NoError(err)
|
||||
s.Equal(s.address, addr)
|
||||
s.Equal(s.pubKey, pubKey)
|
||||
s.Equal(s.walletAddress, accountInfo.WalletAddress)
|
||||
s.Equal(s.walletPubKey, accountInfo.WalletPubKey)
|
||||
s.Equal(s.chatAddress, accountInfo.ChatAddress)
|
||||
s.Equal(s.chatPubKey, accountInfo.ChatPubKey)
|
||||
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(nil, errKeyStore)
|
||||
_, _, err = s.accManager.RecoverAccount(s.password, s.mnemonic)
|
||||
_, err = s.accManager.RecoverAccount(s.password, s.mnemonic)
|
||||
s.Equal(errKeyStore, err)
|
||||
}
|
||||
|
||||
|
@ -214,35 +227,48 @@ func (s *ManagerTestSuite) TestSelectAccount() {
|
|||
testCases := []struct {
|
||||
name string
|
||||
accountKeyStoreReturn []interface{}
|
||||
address string
|
||||
walletAddress string
|
||||
chatAddress string
|
||||
password string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
"success",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.chatAddress,
|
||||
s.password,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"fail_keyStore",
|
||||
[]interface{}{nil, errKeyStore},
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.chatAddress,
|
||||
s.password,
|
||||
errKeyStore,
|
||||
},
|
||||
{
|
||||
"fail_wrongAddress",
|
||||
"fail_wrongWalletAddress",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
"wrong-address",
|
||||
"wrong-wallet-address",
|
||||
s.chatAddress,
|
||||
s.password,
|
||||
ErrAddressToAccountMappingFailure,
|
||||
},
|
||||
{
|
||||
"fail_wrongChatAddress",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
s.walletAddress,
|
||||
"wrong-chat-address",
|
||||
s.password,
|
||||
ErrAddressToAccountMappingFailure,
|
||||
},
|
||||
{
|
||||
"fail_wrongPassword",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.chatAddress,
|
||||
"wrong-password",
|
||||
errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase"),
|
||||
},
|
||||
|
@ -252,15 +278,24 @@ func (s *ManagerTestSuite) TestSelectAccount() {
|
|||
s.T().Run(testCase.name, func(t *testing.T) {
|
||||
s.reinitMock()
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(testCase.accountKeyStoreReturn...).AnyTimes()
|
||||
err := s.accManager.SelectAccount(testCase.address, testCase.password)
|
||||
err := s.accManager.SelectAccount(testCase.walletAddress, testCase.chatAddress, testCase.password)
|
||||
s.Equal(testCase.expectedError, err)
|
||||
|
||||
selectedWalletAccount, err := s.accManager.SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
selectedChatAccount, err := s.accManager.SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
selectedWalletAccount, walletErr := s.accManager.SelectedWalletAccount()
|
||||
selectedChatAccount, chatErr := s.accManager.SelectedChatAccount()
|
||||
|
||||
s.Equal(selectedWalletAccount.AccountKey, selectedChatAccount.AccountKey)
|
||||
if testCase.expectedError == nil {
|
||||
s.Equal(selectedWalletAccount.AccountKey, selectedChatAccount.AccountKey)
|
||||
s.NoError(walletErr)
|
||||
s.NoError(chatErr)
|
||||
} else {
|
||||
s.Nil(selectedWalletAccount)
|
||||
s.Nil(selectedChatAccount)
|
||||
s.Equal(walletErr, ErrNoAccountSelected)
|
||||
s.Equal(chatErr, ErrNoAccountSelected)
|
||||
}
|
||||
|
||||
s.accManager.Logout()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -278,40 +313,45 @@ func (s *ManagerTestSuite) TestCreateChildAccount() {
|
|||
// Now, select the test account for rest of the test cases.
|
||||
s.reinitMock()
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
|
||||
err := s.accManager.SelectAccount(s.address, s.password)
|
||||
err := s.accManager.SelectAccount(s.walletAddress, s.chatAddress, s.password)
|
||||
s.NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
address string
|
||||
walletAddress string
|
||||
chatAddress string
|
||||
password string
|
||||
accountKeyStoreReturn []interface{}
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
"success",
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.chatAddress,
|
||||
s.password,
|
||||
[]interface{}{s.keyStore, nil},
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"fail_keyStore",
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.chatAddress,
|
||||
s.password,
|
||||
[]interface{}{nil, errKeyStore},
|
||||
errKeyStore,
|
||||
},
|
||||
{
|
||||
"fail_wrongAddress",
|
||||
"fail_wrongWalletAddress",
|
||||
"wrong-address",
|
||||
s.chatAddress,
|
||||
s.password,
|
||||
[]interface{}{s.keyStore, nil},
|
||||
ErrAddressToAccountMappingFailure,
|
||||
},
|
||||
{
|
||||
"fail_wrongPassword",
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.chatAddress,
|
||||
"wrong-password",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase"),
|
||||
|
@ -322,7 +362,7 @@ func (s *ManagerTestSuite) TestCreateChildAccount() {
|
|||
s.T().Run(testCase.name, func(t *testing.T) {
|
||||
s.reinitMock()
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(testCase.accountKeyStoreReturn...).AnyTimes()
|
||||
childAddr, childPubKey, err := s.accManager.CreateChildAccount(testCase.address, testCase.password)
|
||||
childAddr, childPubKey, err := s.accManager.CreateChildAccount(testCase.walletAddress, testCase.password)
|
||||
if testCase.expectedError != nil {
|
||||
s.Equal(testCase.expectedError, err)
|
||||
} else {
|
||||
|
@ -343,7 +383,7 @@ func (s *ManagerTestSuite) TestLogout() {
|
|||
func (s *ManagerTestSuite) TestAccounts() {
|
||||
// Select the test account
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(s.keyStore, nil).AnyTimes()
|
||||
err := s.accManager.SelectAccount(s.address, s.password)
|
||||
err := s.accManager.SelectAccount(s.walletAddress, s.chatAddress, s.password)
|
||||
s.NoError(err)
|
||||
|
||||
// Success
|
||||
|
@ -369,37 +409,37 @@ func (s *ManagerTestSuite) TestAddressToDecryptedAccount() {
|
|||
testCases := []struct {
|
||||
name string
|
||||
accountKeyStoreReturn []interface{}
|
||||
address string
|
||||
walletAddress string
|
||||
password string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
"success",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.password,
|
||||
nil,
|
||||
},
|
||||
{
|
||||
"fail_keyStore",
|
||||
[]interface{}{nil, errKeyStore},
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
s.password,
|
||||
errKeyStore,
|
||||
},
|
||||
{
|
||||
"fail_wrongAddress",
|
||||
"fail_wrongWalletAddress",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
"wrong-address",
|
||||
"wrong-wallet-address",
|
||||
s.password,
|
||||
ErrAddressToAccountMappingFailure,
|
||||
},
|
||||
{
|
||||
"fail_wrongPassword",
|
||||
[]interface{}{s.keyStore, nil},
|
||||
s.address,
|
||||
s.walletAddress,
|
||||
"wrong-password",
|
||||
errors.New("could not decrypt key with given passphrase"),
|
||||
errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase"),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -407,7 +447,7 @@ func (s *ManagerTestSuite) TestAddressToDecryptedAccount() {
|
|||
s.T().Run(testCase.name, func(t *testing.T) {
|
||||
s.reinitMock()
|
||||
s.gethServiceProvider.EXPECT().AccountKeyStore().Return(testCase.accountKeyStoreReturn...).AnyTimes()
|
||||
acc, key, err := s.accManager.AddressToDecryptedAccount(testCase.address, testCase.password)
|
||||
acc, key, err := s.accManager.AddressToDecryptedAccount(testCase.walletAddress, testCase.password)
|
||||
if testCase.expectedError != nil {
|
||||
s.Equal(testCase.expectedError, err)
|
||||
} else {
|
||||
|
|
|
@ -13,6 +13,14 @@ var (
|
|||
ErrInvalidAccountAddressOrKey = errors.New("cannot parse address or key to valid account address")
|
||||
)
|
||||
|
||||
// Info contains wallet and chat addresses and public keys of an account.
|
||||
type Info struct {
|
||||
WalletAddress string
|
||||
WalletPubKey string
|
||||
ChatAddress string
|
||||
ChatPubKey string
|
||||
}
|
||||
|
||||
// SelectedExtKey is a container for the selected (logged in) external account.
|
||||
type SelectedExtKey struct {
|
||||
Address common.Address
|
||||
|
|
|
@ -422,17 +422,18 @@ func (b *StatusBackend) reSelectAccount() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
|
||||
// using provided password. Once verification is done, decrypted key is injected into Whisper (as a single identity,
|
||||
// SelectAccount selects current wallet and chat accounts, by verifying that each address has corresponding account which can be decrypted
|
||||
// using provided password. Once verification is done, the decrypted chat key is injected into Whisper (as a single identity,
|
||||
// all previous identities are removed).
|
||||
func (b *StatusBackend) SelectAccount(address, password string) error {
|
||||
func (b *StatusBackend) SelectAccount(walletAddress, chatAddress, password string) error {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
err := b.accountManager.SelectAccount(address, password)
|
||||
err := b.accountManager.SelectAccount(walletAddress, chatAddress, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
chatAccount, err := b.accountManager.SelectedChatAccount()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -455,7 +456,7 @@ func (b *StatusBackend) SelectAccount(address, password string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := st.InitProtocol(address, password); err != nil {
|
||||
if err := st.InitProtocol(chatAddress, password); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,15 +138,15 @@ func TestBackendAccountsConcurrently(t *testing.T) {
|
|||
|
||||
var wgCreateAccounts sync.WaitGroup
|
||||
count := 3
|
||||
addressCh := make(chan [2]string, count) // use buffered channel to avoid blocking
|
||||
addressCh := make(chan [3]string, count) // use buffered channel to avoid blocking
|
||||
|
||||
// create new accounts concurrently
|
||||
for i := 0; i < count; i++ {
|
||||
wgCreateAccounts.Add(1)
|
||||
go func(pass string) {
|
||||
address, _, _, err := backend.AccountManager().CreateAccount(pass)
|
||||
accountInfo, _, err := backend.AccountManager().CreateAccount(pass)
|
||||
assert.NoError(t, err)
|
||||
addressCh <- [...]string{address, pass}
|
||||
addressCh <- [...]string{accountInfo.WalletAddress, accountInfo.ChatAddress, pass}
|
||||
wgCreateAccounts.Done()
|
||||
}("password-00" + string(i))
|
||||
}
|
||||
|
@ -159,8 +159,8 @@ func TestBackendAccountsConcurrently(t *testing.T) {
|
|||
|
||||
for tuple := range addressCh {
|
||||
wg.Add(1)
|
||||
go func(tuple [2]string) {
|
||||
assert.NoError(t, backend.SelectAccount(tuple[0], tuple[1]))
|
||||
go func(tuple [3]string) {
|
||||
assert.NoError(t, backend.SelectAccount(tuple[0], tuple[1], tuple[2]))
|
||||
wg.Done()
|
||||
}(tuple)
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ func CallPrivateRPC(inputJSON *C.char) *C.char {
|
|||
// just modified to handle the function arg passing
|
||||
//export CreateAccount
|
||||
func CreateAccount(password *C.char) *C.char {
|
||||
address, pubKey, mnemonic, err := statusBackend.AccountManager().CreateAccount(C.GoString(password))
|
||||
info, mnemonic, err := statusBackend.AccountManager().CreateAccount(C.GoString(password))
|
||||
|
||||
errString := ""
|
||||
if err != nil {
|
||||
|
@ -255,10 +255,14 @@ func CreateAccount(password *C.char) *C.char {
|
|||
}
|
||||
|
||||
out := AccountInfo{
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
Mnemonic: mnemonic,
|
||||
Error: errString,
|
||||
Address: info.WalletAddress,
|
||||
PubKey: info.WalletPubKey,
|
||||
WalletAddress: info.WalletAddress,
|
||||
WalletPubKey: info.WalletPubKey,
|
||||
ChatAddress: info.ChatAddress,
|
||||
ChatPubKey: info.ChatPubKey,
|
||||
Mnemonic: mnemonic,
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return C.CString(string(outBytes))
|
||||
|
@ -287,7 +291,7 @@ func CreateChildAccount(parentAddress, password *C.char) *C.char {
|
|||
//RecoverAccount re-creates master key using given details
|
||||
//export RecoverAccount
|
||||
func RecoverAccount(password, mnemonic *C.char) *C.char {
|
||||
address, pubKey, err := statusBackend.AccountManager().RecoverAccount(C.GoString(password), C.GoString(mnemonic))
|
||||
info, err := statusBackend.AccountManager().RecoverAccount(C.GoString(password), C.GoString(mnemonic))
|
||||
|
||||
errString := ""
|
||||
if err != nil {
|
||||
|
@ -296,10 +300,14 @@ func RecoverAccount(password, mnemonic *C.char) *C.char {
|
|||
}
|
||||
|
||||
out := AccountInfo{
|
||||
Address: address,
|
||||
PubKey: pubKey,
|
||||
Mnemonic: C.GoString(mnemonic),
|
||||
Error: errString,
|
||||
Address: info.WalletAddress,
|
||||
PubKey: info.WalletPubKey,
|
||||
WalletAddress: info.WalletAddress,
|
||||
WalletPubKey: info.WalletPubKey,
|
||||
ChatAddress: info.ChatAddress,
|
||||
ChatPubKey: info.ChatPubKey,
|
||||
Mnemonic: C.GoString(mnemonic),
|
||||
Error: errString,
|
||||
}
|
||||
outBytes, _ := json.Marshal(out)
|
||||
return C.CString(string(outBytes))
|
||||
|
@ -316,7 +324,7 @@ func VerifyAccountPassword(keyStoreDir, address, password *C.char) *C.char {
|
|||
// if verified, purges all the previous identities from Whisper, and injects verified key as shh identity
|
||||
//export Login
|
||||
func Login(address, password *C.char) *C.char {
|
||||
err := statusBackend.SelectAccount(C.GoString(address), C.GoString(password))
|
||||
err := statusBackend.SelectAccount(C.GoString(address), C.GoString(address), C.GoString(password))
|
||||
return makeJSONResponse(err)
|
||||
}
|
||||
|
||||
|
|
|
@ -26,13 +26,11 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/signal"
|
||||
. "github.com/status-im/status-go/t/utils" //nolint: golint
|
||||
"github.com/status-im/status-go/transactions"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const initJS = `
|
||||
|
@ -169,7 +167,7 @@ func testVerifyAccountPassword(t *testing.T) bool {
|
|||
|
||||
// rename account file (to see that file's internals reviewed, when locating account key)
|
||||
accountFilePathOriginal := filepath.Join(tmpDir, GetAccount1PKFile())
|
||||
accountFilePath := filepath.Join(tmpDir, "foo"+TestConfig.Account1.Address+"bar.pk")
|
||||
accountFilePath := filepath.Join(tmpDir, "foo"+TestConfig.Account1.WalletAddress+"bar.pk")
|
||||
if err := os.Rename(accountFilePathOriginal, accountFilePath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -177,7 +175,7 @@ func testVerifyAccountPassword(t *testing.T) bool {
|
|||
response := APIResponse{}
|
||||
rawResponse := VerifyAccountPassword(
|
||||
C.CString(tmpDir),
|
||||
C.CString(TestConfig.Account1.Address),
|
||||
C.CString(TestConfig.Account1.WalletAddress),
|
||||
C.CString(TestConfig.Account1.Password))
|
||||
|
||||
if err := json.Unmarshal([]byte(C.GoString(rawResponse)), &response); err != nil {
|
||||
|
@ -227,21 +225,21 @@ func testStopResumeNode(t *testing.T) bool { //nolint: gocyclo
|
|||
}
|
||||
|
||||
// create an account
|
||||
address1, pubKey1, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
account1, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
}
|
||||
t.Logf("account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
t.Logf("account created: {address: %s, key: %s}", account1.WalletAddress, account1.WalletPubKey)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasKeyPair(pubKey1) {
|
||||
if whisperService.HasKeyPair(account1.ChatPubKey) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
// select account
|
||||
loginResponse := APIResponse{}
|
||||
rawResponse := Login(C.CString(address1), C.CString(TestConfig.Account1.Password))
|
||||
rawResponse := Login(C.CString(account1.WalletAddress), C.CString(TestConfig.Account1.Password))
|
||||
|
||||
if err = json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount response (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -252,7 +250,7 @@ func testStopResumeNode(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasKeyPair(pubKey1) {
|
||||
if !whisperService.HasKeyPair(account1.ChatPubKey) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
|
@ -312,7 +310,7 @@ func testStopResumeNode(t *testing.T) bool { //nolint: gocyclo
|
|||
if err != nil {
|
||||
t.Errorf("whisper service not running: %v", err)
|
||||
}
|
||||
if !whisperService.HasKeyPair(pubKey1) {
|
||||
if !whisperService.HasKeyPair(account1.ChatPubKey) {
|
||||
t.Errorf("identity evicted from whisper on node restart: %v", err)
|
||||
}
|
||||
|
||||
|
@ -382,10 +380,17 @@ func testCreateChildAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("could not create account: %s", err)
|
||||
return false
|
||||
}
|
||||
address, pubKey, mnemonic := createAccountResponse.Address, createAccountResponse.PubKey, createAccountResponse.Mnemonic
|
||||
t.Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
|
||||
|
||||
acct, err := account.ParseAccountString(address)
|
||||
if createAccountResponse.Address != createAccountResponse.WalletAddress ||
|
||||
createAccountResponse.PubKey != createAccountResponse.WalletPubKey {
|
||||
t.Error("for backward compatibility pubkey/address should be equal to walletAddress/walletPubKey")
|
||||
}
|
||||
|
||||
walletAddress, walletPubKey, chatAddress, _, mnemonic := createAccountResponse.Address, createAccountResponse.PubKey,
|
||||
createAccountResponse.ChatAddress, createAccountResponse.ChatPubKey, createAccountResponse.Mnemonic
|
||||
t.Logf("Account created: {address: %s, key: %s, mnemonic:%s}", walletAddress, walletPubKey, mnemonic)
|
||||
|
||||
acct, err := account.ParseAccountString(walletAddress)
|
||||
if err != nil {
|
||||
t.Errorf("can not get account from address: %v", err)
|
||||
return false
|
||||
|
@ -417,7 +422,7 @@ func testCreateChildAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
return false
|
||||
}
|
||||
|
||||
err = statusBackend.SelectAccount(address, TestConfig.Account1.Password)
|
||||
err = statusBackend.SelectAccount(walletAddress, chatAddress, TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
|
@ -497,12 +502,12 @@ func testRecoverAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
keyStore, _ := statusBackend.StatusNode().AccountKeyStore()
|
||||
|
||||
// create an account
|
||||
address, pubKey, mnemonic, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, mnemonic, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
|
||||
t.Logf("Account created: {address: %s, key: %s, mnemonic:%s}", accountInfo.WalletAddress, accountInfo.WalletPubKey, mnemonic)
|
||||
|
||||
// try recovering using password + mnemonic
|
||||
recoverAccountResponse := AccountInfo{}
|
||||
|
@ -517,13 +522,25 @@ func testRecoverAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("recover account failed: %v", recoverAccountResponse.Error)
|
||||
return false
|
||||
}
|
||||
addressCheck, pubKeyCheck := recoverAccountResponse.Address, recoverAccountResponse.PubKey
|
||||
if address != addressCheck || pubKey != pubKeyCheck {
|
||||
t.Error("recover account details failed to pull the correct details")
|
||||
|
||||
if recoverAccountResponse.Address != recoverAccountResponse.WalletAddress ||
|
||||
recoverAccountResponse.PubKey != recoverAccountResponse.WalletPubKey {
|
||||
t.Error("for backward compatibility pubkey/address should be equal to walletAddress/walletPubKey")
|
||||
}
|
||||
|
||||
walletAddressCheck, walletPubKeyCheck := recoverAccountResponse.Address, recoverAccountResponse.PubKey
|
||||
chatAddressCheck, chatPubKeyCheck := recoverAccountResponse.ChatAddress, recoverAccountResponse.ChatPubKey
|
||||
|
||||
if accountInfo.WalletAddress != walletAddressCheck || accountInfo.WalletPubKey != walletPubKeyCheck {
|
||||
t.Error("recover wallet account details failed to pull the correct details")
|
||||
}
|
||||
|
||||
if accountInfo.ChatAddress != chatAddressCheck || accountInfo.ChatPubKey != chatPubKeyCheck {
|
||||
t.Error("recover chat account details failed to pull the correct details")
|
||||
}
|
||||
|
||||
// now test recovering, but make sure that account/key file is removed i.e. simulate recovering on a new device
|
||||
account, err := account.ParseAccountString(address)
|
||||
account, err := account.ParseAccountString(accountInfo.WalletAddress)
|
||||
if err != nil {
|
||||
t.Errorf("can not get account from address: %v", err)
|
||||
}
|
||||
|
@ -551,9 +568,14 @@ func testRecoverAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("recover account failed (for non-cached account): %v", recoverAccountResponse.Error)
|
||||
return false
|
||||
}
|
||||
addressCheck, pubKeyCheck = recoverAccountResponse.Address, recoverAccountResponse.PubKey
|
||||
if address != addressCheck || pubKey != pubKeyCheck {
|
||||
t.Error("recover account details failed to pull the correct details (for non-cached account)")
|
||||
walletAddressCheck, walletPubKeyCheck = recoverAccountResponse.Address, recoverAccountResponse.PubKey
|
||||
if accountInfo.WalletAddress != walletAddressCheck || accountInfo.WalletPubKey != walletPubKeyCheck {
|
||||
t.Error("recover wallet account details failed to pull the correct details (for non-cached account)")
|
||||
}
|
||||
|
||||
chatAddressCheck, chatPubKeyCheck = recoverAccountResponse.ChatAddress, recoverAccountResponse.ChatPubKey
|
||||
if accountInfo.ChatAddress != chatAddressCheck || accountInfo.ChatPubKey != chatPubKeyCheck {
|
||||
t.Error("recover chat account details failed to pull the correct details (for non-cached account)")
|
||||
}
|
||||
|
||||
// make sure that extended key exists and is imported ok too
|
||||
|
@ -579,9 +601,14 @@ func testRecoverAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("recover account failed (for non-cached account): %v", recoverAccountResponse.Error)
|
||||
return false
|
||||
}
|
||||
addressCheck, pubKeyCheck = recoverAccountResponse.Address, recoverAccountResponse.PubKey
|
||||
if address != addressCheck || pubKey != pubKeyCheck {
|
||||
t.Error("recover account details failed to pull the correct details (for non-cached account)")
|
||||
walletAddressCheck, walletPubKeyCheck = recoverAccountResponse.Address, recoverAccountResponse.PubKey
|
||||
if accountInfo.WalletAddress != walletAddressCheck || accountInfo.WalletPubKey != walletPubKeyCheck {
|
||||
t.Error("recover wallet account details failed to pull the correct details (for non-cached account)")
|
||||
}
|
||||
|
||||
chatAddressCheck, chatPubKeyCheck = recoverAccountResponse.ChatAddress, recoverAccountResponse.ChatPubKey
|
||||
if accountInfo.ChatAddress != chatAddressCheck || accountInfo.ChatPubKey != chatPubKeyCheck {
|
||||
t.Error("recover chat account details failed to pull the correct details (for non-cached account)")
|
||||
}
|
||||
|
||||
// time to login with recovered data
|
||||
|
@ -591,15 +618,15 @@ func testRecoverAccount(t *testing.T) bool { //nolint: gocyclo
|
|||
}
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasKeyPair(pubKeyCheck) {
|
||||
if whisperService.HasKeyPair(chatPubKeyCheck) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
err = statusBackend.SelectAccount(addressCheck, TestConfig.Account1.Password)
|
||||
err = statusBackend.SelectAccount(walletAddressCheck, chatAddressCheck, TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasKeyPair(pubKeyCheck) {
|
||||
if !whisperService.HasKeyPair(chatPubKeyCheck) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
|
@ -614,28 +641,28 @@ func testAccountSelect(t *testing.T) bool { //nolint: gocyclo
|
|||
}
|
||||
|
||||
// create an account
|
||||
address1, pubKey1, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo1, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
t.Logf("Account created: {address: %s, key: %s}", accountInfo1.WalletAddress, accountInfo1.WalletPubKey)
|
||||
|
||||
address2, pubKey2, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo2, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Error("Test failed: could not create account")
|
||||
return false
|
||||
}
|
||||
t.Logf("Account created: {address: %s, key: %s}", address2, pubKey2)
|
||||
t.Logf("Account created: {address: %s, key: %s}", accountInfo2.WalletAddress, accountInfo2.WalletPubKey)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
if whisperService.HasKeyPair(pubKey1) {
|
||||
if whisperService.HasKeyPair(accountInfo1.ChatPubKey) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
// try selecting with wrong password
|
||||
loginResponse := APIResponse{}
|
||||
rawResponse := Login(C.CString(address1), C.CString("wrongPassword"))
|
||||
rawResponse := Login(C.CString(accountInfo1.WalletAddress), C.CString("wrongPassword"))
|
||||
|
||||
if err = json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount response (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -648,7 +675,7 @@ func testAccountSelect(t *testing.T) bool { //nolint: gocyclo
|
|||
}
|
||||
|
||||
loginResponse = APIResponse{}
|
||||
rawResponse = Login(C.CString(address1), C.CString(TestConfig.Account1.Password))
|
||||
rawResponse = Login(C.CString(accountInfo1.WalletAddress), C.CString(TestConfig.Account1.Password))
|
||||
|
||||
if err = json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount response (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -659,17 +686,17 @@ func testAccountSelect(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasKeyPair(pubKey1) {
|
||||
if !whisperService.HasKeyPair(accountInfo1.ChatPubKey) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
if whisperService.HasKeyPair(pubKey2) {
|
||||
if whisperService.HasKeyPair(accountInfo2.ChatPubKey) {
|
||||
t.Error("identity already present in whisper")
|
||||
}
|
||||
|
||||
loginResponse = APIResponse{}
|
||||
rawResponse = Login(C.CString(address2), C.CString(TestConfig.Account1.Password))
|
||||
rawResponse = Login(C.CString(accountInfo2.WalletAddress), C.CString(TestConfig.Account1.Password))
|
||||
|
||||
if err = json.Unmarshal([]byte(C.GoString(rawResponse)), &loginResponse); err != nil {
|
||||
t.Errorf("cannot decode RecoverAccount response (%s): %v", C.GoString(rawResponse), err)
|
||||
|
@ -680,10 +707,10 @@ func testAccountSelect(t *testing.T) bool { //nolint: gocyclo
|
|||
t.Errorf("Test failed: could not select account: %v", loginResponse.Error)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasKeyPair(pubKey2) {
|
||||
if !whisperService.HasKeyPair(accountInfo2.ChatPubKey) {
|
||||
t.Errorf("identity not injected into whisper: %v", err)
|
||||
}
|
||||
if whisperService.HasKeyPair(pubKey1) {
|
||||
if whisperService.HasKeyPair(accountInfo1.ChatPubKey) {
|
||||
t.Error("identity should be removed, but it is still present in whisper")
|
||||
}
|
||||
|
||||
|
@ -698,25 +725,25 @@ func testAccountLogout(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// create an account
|
||||
address, pubKey, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, _, err := statusBackend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("could not create account: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
// make sure that identity doesn't exist (yet) in Whisper
|
||||
if whisperService.HasKeyPair(pubKey) {
|
||||
if whisperService.HasKeyPair(accountInfo.ChatPubKey) {
|
||||
t.Error("identity already present in whisper")
|
||||
return false
|
||||
}
|
||||
|
||||
// select/login
|
||||
err = statusBackend.SelectAccount(address, TestConfig.Account1.Password)
|
||||
err = statusBackend.SelectAccount(accountInfo.WalletAddress, accountInfo.ChatAddress, TestConfig.Account1.Password)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed: could not select account: %v", err)
|
||||
return false
|
||||
}
|
||||
if !whisperService.HasKeyPair(pubKey) {
|
||||
if !whisperService.HasKeyPair(accountInfo.ChatPubKey) {
|
||||
t.Error("identity not injected into whisper")
|
||||
return false
|
||||
}
|
||||
|
@ -735,7 +762,7 @@ func testAccountLogout(t *testing.T) bool {
|
|||
}
|
||||
|
||||
// now, logout and check if identity is removed indeed
|
||||
if whisperService.HasKeyPair(pubKey) {
|
||||
if whisperService.HasKeyPair(accountInfo.ChatPubKey) {
|
||||
t.Error("identity not cleared from whisper")
|
||||
return false
|
||||
}
|
||||
|
@ -752,14 +779,14 @@ func testSendTransaction(t *testing.T) bool {
|
|||
EnsureNodeSync(statusBackend.StatusNode().EnsureSync)
|
||||
|
||||
// log into account from which transactions will be sent
|
||||
if err := statusBackend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v. Error %q", TestConfig.Account1.Address, err)
|
||||
if err := statusBackend.SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v. Error %q", TestConfig.Account1.WalletAddress, err)
|
||||
return false
|
||||
}
|
||||
|
||||
args, err := json.Marshal(transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -791,16 +818,17 @@ func testSendTransactionInvalidPassword(t *testing.T) bool {
|
|||
|
||||
// log into account from which transactions will be sent
|
||||
if err := statusBackend.SelectAccount(
|
||||
TestConfig.Account1.Address,
|
||||
TestConfig.Account1.WalletAddress,
|
||||
TestConfig.Account1.ChatAddress,
|
||||
TestConfig.Account1.Password,
|
||||
); err != nil {
|
||||
t.Errorf("cannot select account: %v. Error %q", TestConfig.Account1.Address, err)
|
||||
t.Errorf("cannot select account: %v. Error %q", TestConfig.Account1.WalletAddress, err)
|
||||
return false
|
||||
}
|
||||
|
||||
args, err := json.Marshal(transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -826,14 +854,14 @@ func testFailedTransaction(t *testing.T) bool {
|
|||
EnsureNodeSync(statusBackend.StatusNode().EnsureSync)
|
||||
|
||||
// log into wrong account in order to get selectedAccount error
|
||||
if err := statusBackend.SelectAccount(TestConfig.Account2.Address, TestConfig.Account2.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v. Error %q", TestConfig.Account1.Address, err)
|
||||
if err := statusBackend.SelectAccount(TestConfig.Account2.WalletAddress, TestConfig.Account2.ChatAddress, TestConfig.Account2.Password); err != nil {
|
||||
t.Errorf("cannot select account: %v. Error %q", TestConfig.Account1.WalletAddress, err)
|
||||
return false
|
||||
}
|
||||
|
||||
args, err := json.Marshal(transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
12
lib/types.go
12
lib/types.go
|
@ -64,10 +64,14 @@ func (e APIError) Error() string {
|
|||
|
||||
// AccountInfo represents account's info.
|
||||
type AccountInfo struct {
|
||||
Address string `json:"address"`
|
||||
PubKey string `json:"pubkey"`
|
||||
Mnemonic string `json:"mnemonic"`
|
||||
Error string `json:"error"`
|
||||
Address string `json:"address"` // DEPRECATED
|
||||
PubKey string `json:"pubkey"` // DEPRECATED
|
||||
WalletAddress string `json:"walletAddress"`
|
||||
WalletPubKey string `json:"walletPubKey"`
|
||||
ChatAddress string `json:"chatAddress"`
|
||||
ChatPubKey string `json:"chatPubKey"`
|
||||
Mnemonic string `json:"mnemonic"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// NotifyResult is a JSON returned from notify message.
|
||||
|
|
|
@ -10,9 +10,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/status-im/status-go/params"
|
||||
|
||||
gethrpc "github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/status-im/status-go/params"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
accounts "github.com/ethereum/go-ethereum/accounts"
|
||||
keystore "github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
account "github.com/status-im/status-go/account"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
|
@ -90,28 +91,27 @@ func (mr *MockAccountManagerMockRecorder) AddressToDecryptedAccount(arg0, arg1 i
|
|||
}
|
||||
|
||||
// SelectAccount mocks base method
|
||||
func (m *MockAccountManager) SelectAccount(address, password string) error {
|
||||
func (m *MockAccountManager) SelectAccount(walletAddress, chatAddress, password string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "SelectAccount", address, password)
|
||||
ret := m.ctrl.Call(m, "SelectAccount", walletAddress, chatAddress, password)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// SelectAccount indicates an expected call of SelectAccount
|
||||
func (mr *MockAccountManagerMockRecorder) SelectAccount(address, password interface{}) *gomock.Call {
|
||||
func (mr *MockAccountManagerMockRecorder) SelectAccount(walletAddress, chatAddress, password interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectAccount", reflect.TypeOf((*MockAccountManager)(nil).SelectAccount), address, password)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectAccount", reflect.TypeOf((*MockAccountManager)(nil).SelectAccount), walletAddress, chatAddress, password)
|
||||
}
|
||||
|
||||
// CreateAccount mocks base method
|
||||
func (m *MockAccountManager) CreateAccount(password string) (string, string, string, error) {
|
||||
func (m *MockAccountManager) CreateAccount(password string) (account.Info, string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateAccount", password)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret0, _ := ret[0].(account.Info)
|
||||
ret1, _ := ret[1].(string)
|
||||
ret2, _ := ret[2].(string)
|
||||
ret3, _ := ret[3].(error)
|
||||
return ret0, ret1, ret2, ret3
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// CreateAccount indicates an expected call of CreateAccount
|
||||
|
|
|
@ -40,7 +40,7 @@ func (api *PublicAPI) Login(context context.Context, req LoginRequest) (res Logi
|
|||
return
|
||||
}
|
||||
|
||||
if err = api.s.am.SelectAccount(req.Addr, req.Password); err != nil {
|
||||
if err = api.s.am.SelectAccount(req.Addr, req.Addr, req.Password); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -54,18 +54,31 @@ type SignupRequest struct {
|
|||
|
||||
// SignupResponse : json response returned by status_signup.
|
||||
type SignupResponse struct {
|
||||
Address string `json:"address"`
|
||||
Pubkey string `json:"pubkey"`
|
||||
Mnemonic string `json:"mnemonic"`
|
||||
Address string `json:"address"`
|
||||
Pubkey string `json:"pubkey"`
|
||||
WalletAddress string `json:"walletAddress"`
|
||||
WalletPubkey string `json:"walletPubKey"`
|
||||
ChatAddress string `json:"chatAddress"`
|
||||
ChatPubkey string `json:"chatPubkey"`
|
||||
Mnemonic string `json:"mnemonic"`
|
||||
}
|
||||
|
||||
// Signup is an implementation of `status_signup` or `web3.status.signup` API
|
||||
func (api *PublicAPI) Signup(context context.Context, req SignupRequest) (res SignupResponse, err error) {
|
||||
if res.Address, res.Pubkey, res.Mnemonic, err = api.s.am.CreateAccount(req.Password); err != nil {
|
||||
accountInfo, mnemonic, err := api.s.am.CreateAccount(req.Password)
|
||||
if err != nil {
|
||||
err = errors.New("could not create the specified account : " + err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res.Address = accountInfo.WalletAddress
|
||||
res.Pubkey = accountInfo.WalletPubKey
|
||||
res.WalletAddress = accountInfo.WalletAddress
|
||||
res.WalletPubkey = accountInfo.WalletPubKey
|
||||
res.ChatAddress = accountInfo.ChatAddress
|
||||
res.ChatPubkey = accountInfo.ChatPubKey
|
||||
res.Mnemonic = mnemonic
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
|
@ -49,7 +50,7 @@ var logintests = []struct {
|
|||
}
|
||||
s.am.EXPECT().AddressToDecryptedAccount("address...", "password").Return(accounts.Account{}, &key, nil)
|
||||
s.w.EXPECT().AddKeyPair(key.PrivateKey).Return("addressKey", nil)
|
||||
s.am.EXPECT().SelectAccount("address...", "password").Return(nil)
|
||||
s.am.EXPECT().SelectAccount("address...", "address...", "password").Return(nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -85,7 +86,7 @@ var logintests = []struct {
|
|||
}
|
||||
s.am.EXPECT().AddressToDecryptedAccount("address...", "password").Return(accounts.Account{}, &key, nil)
|
||||
s.w.EXPECT().AddKeyPair(key.PrivateKey).Return("", nil)
|
||||
s.am.EXPECT().SelectAccount("address...", "password").Return(errors.New("foo"))
|
||||
s.am.EXPECT().SelectAccount("address...", "address...", "password").Return(errors.New("foo"))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -112,25 +113,31 @@ var signuptests = []struct {
|
|||
{
|
||||
name: "success signup",
|
||||
expectedResponse: SignupResponse{
|
||||
Address: "addr",
|
||||
Pubkey: "pubkey",
|
||||
Mnemonic: "mnemonic",
|
||||
WalletAddress: "addr",
|
||||
WalletPubkey: "pubkey",
|
||||
Mnemonic: "mnemonic",
|
||||
},
|
||||
expectedError: nil,
|
||||
prepareExpectations: func(s *StatusSuite) {
|
||||
s.am.EXPECT().CreateAccount("password").Return("addr", "pubkey", "mnemonic", nil)
|
||||
accountInfo := account.Info{
|
||||
WalletAddress: "addr",
|
||||
WalletPubKey: "pubkey",
|
||||
ChatAddress: "addr",
|
||||
ChatPubKey: "pubkey",
|
||||
}
|
||||
s.am.EXPECT().CreateAccount("password").Return(accountInfo, "mnemonic", nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "success signup",
|
||||
expectedResponse: SignupResponse{
|
||||
Address: "",
|
||||
Pubkey: "",
|
||||
Mnemonic: "",
|
||||
WalletAddress: "",
|
||||
WalletPubkey: "",
|
||||
Mnemonic: "",
|
||||
},
|
||||
expectedError: errors.New("could not create the specified account : foo"),
|
||||
prepareExpectations: func(s *StatusSuite) {
|
||||
s.am.EXPECT().CreateAccount("password").Return("", "", "", errors.New("foo"))
|
||||
s.am.EXPECT().CreateAccount("password").Return(account.Info{}, "", errors.New("foo"))
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -141,8 +148,8 @@ func (s *StatusSuite) TestSignup() {
|
|||
|
||||
var ctx context.Context
|
||||
res, err := s.api.Signup(ctx, SignupRequest{Password: "password"})
|
||||
s.Equal(t.expectedResponse.Address, res.Address, "failed scenario : "+t.name)
|
||||
s.Equal(t.expectedResponse.Pubkey, res.Pubkey, "failed scenario : "+t.name)
|
||||
s.Equal(t.expectedResponse.WalletAddress, res.WalletAddress, "failed scenario : "+t.name)
|
||||
s.Equal(t.expectedResponse.WalletPubkey, res.WalletPubkey, "failed scenario : "+t.name)
|
||||
s.Equal(t.expectedResponse.Mnemonic, res.Mnemonic, "failed scenario : "+t.name)
|
||||
s.Equal(t.expectedError, err, "failed scenario : "+t.name)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/status-im/status-go/account"
|
||||
)
|
||||
|
||||
// Make sure that Service implements node.Service interface.
|
||||
|
@ -21,8 +22,8 @@ type WhisperService interface {
|
|||
// AccountManager interface to manage account actions
|
||||
type AccountManager interface {
|
||||
AddressToDecryptedAccount(string, string) (accounts.Account, *keystore.Key, error)
|
||||
SelectAccount(address, password string) error
|
||||
CreateAccount(password string) (address, pubKey, mnemonic string, err error)
|
||||
SelectAccount(walletAddress, chatAddress, password string) error
|
||||
CreateAccount(password string) (accountInfo account.Info, mnemonic string, err error)
|
||||
}
|
||||
|
||||
// Service represents our own implementation of status status operations.
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
{
|
||||
"Account1": {
|
||||
"Address": "0xF35E0325dad87e2661c4eF951d58727e6d583d5c"
|
||||
"WalletAddress": "0xF35E0325dad87e2661c4eF951d58727e6d583d5c",
|
||||
"ChatAddress": "0xF35E0325dad87e2661c4eF951d58727e6d583d5c"
|
||||
},
|
||||
"Account2": {
|
||||
"Address": "0xA0a19221268d939c3a972bf5461dC10f7980E814"
|
||||
"WalletAddress": "0xA0a19221268d939c3a972bf5461dC10f7980E814",
|
||||
"ChatAddress": "0xA0a19221268d939c3a972bf5461dC10f7980E814"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
{
|
||||
"Account1": {
|
||||
"Address": "0xbF164ca341326a03b547c05B343b2E21eFAe24b9",
|
||||
"WalletAddress": "0xbF164ca341326a03b547c05B343b2E21eFAe24b9",
|
||||
"ChatAddress": "0xbF164ca341326a03b547c05B343b2E21eFAe24b9",
|
||||
"Password": "password"
|
||||
},
|
||||
"Account2": {
|
||||
"Address": "0x205a5d0E72ff65079FCaBB4A63E33d28aA6Def2C",
|
||||
"WalletAddress": "0x205a5d0E72ff65079FCaBB4A63E33d28aA6Def2C",
|
||||
"ChatAddress": "0x205a5d0E72ff65079FCaBB4A63E33d28aA6Def2C",
|
||||
"Password": "password"
|
||||
},
|
||||
"Account3": {
|
||||
"Address": "0x3ad34e698d4806afd08b359b920f5c6b62b68ee4",
|
||||
"WalletAddress": "0x3ad34e698d4806afd08b359b920f5c6b62b68ee4",
|
||||
"ChatAddress": "0x3ad34e698d4806afd08b359b920f5c6b62b68ee4",
|
||||
"Password": "password"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,19 +23,20 @@ func (s *AccountsTestSuite) TestRPCEthAccounts() {
|
|||
defer s.StopTestBackend()
|
||||
|
||||
// log into test account
|
||||
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err := s.Backend.SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
rpcClient := s.Backend.StatusNode().RPCClient()
|
||||
s.NotNil(rpcClient)
|
||||
|
||||
expectedResponse := `{"jsonrpc":"2.0","id":1,"result":["` + strings.ToLower(TestConfig.Account1.Address) + `"]}`
|
||||
expectedResponse := `{"jsonrpc":"2.0","id":1,"result":["` + strings.ToLower(TestConfig.Account1.WalletAddress) + `"]}`
|
||||
resp := rpcClient.CallRaw(`{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "eth_accounts",
|
||||
"params": []
|
||||
}`)
|
||||
|
||||
s.Equal(expectedResponse, resp)
|
||||
}
|
||||
|
||||
|
@ -50,13 +51,13 @@ func (s *AccountsTestSuite) TestRPCEthAccountsWithUpstream() {
|
|||
defer s.StopTestBackend()
|
||||
|
||||
// log into test account
|
||||
err = s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err = s.Backend.SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
rpcClient := s.Backend.StatusNode().RPCClient()
|
||||
s.NotNil(rpcClient)
|
||||
|
||||
expectedResponse := `{"jsonrpc":"2.0","id":1,"result":["` + strings.ToLower(TestConfig.Account1.Address) + `"]}`
|
||||
expectedResponse := `{"jsonrpc":"2.0","id":1,"result":["` + strings.ToLower(TestConfig.Account1.WalletAddress) + `"]}`
|
||||
resp := rpcClient.CallRaw(`{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
|
|
|
@ -30,7 +30,7 @@ func (s *AccountsTestSuite) TestAccountsList() {
|
|||
s.Zero(len(accounts), "accounts returned, while there should be none (we haven't logged in yet)")
|
||||
|
||||
// create an account
|
||||
address, _, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// ensure that there is still no accounts returned
|
||||
|
@ -39,15 +39,15 @@ func (s *AccountsTestSuite) TestAccountsList() {
|
|||
s.Zero(len(accounts), "accounts returned, while there should be none (we haven't logged in yet)")
|
||||
|
||||
// select account (sub-accounts will be created for this key)
|
||||
err = s.Backend.SelectAccount(address, TestConfig.Account1.Password)
|
||||
err = s.Backend.SelectAccount(accountInfo.WalletAddress, accountInfo.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err, "account selection failed")
|
||||
|
||||
// at this point main account should show up
|
||||
accounts, err = s.Backend.AccountManager().Accounts()
|
||||
s.NoError(err)
|
||||
s.Equal(1, len(accounts), "exactly single account is expected (main account)")
|
||||
s.Equal(accounts[0].Hex(), address,
|
||||
fmt.Sprintf("main account is not retured as the first key: got %s, expected %s", accounts[0].Hex(), "0x"+address))
|
||||
s.Equal(accounts[0].Hex(), accountInfo.WalletAddress,
|
||||
fmt.Sprintf("main account is not retured as the first key: got %s, expected %s", accounts[0].Hex(), "0x"+accountInfo.WalletAddress))
|
||||
|
||||
// create sub-account 1
|
||||
subAccount1, subPubKey1, err := s.Backend.AccountManager().CreateChildAccount("", TestConfig.Account1.Password)
|
||||
|
@ -57,7 +57,7 @@ func (s *AccountsTestSuite) TestAccountsList() {
|
|||
accounts, err = s.Backend.AccountManager().Accounts()
|
||||
s.NoError(err)
|
||||
s.Equal(2, len(accounts), "exactly 2 accounts are expected (main + sub-account 1)")
|
||||
s.Equal(accounts[0].Hex(), address, "main account is not retured as the first key")
|
||||
s.Equal(accounts[0].Hex(), accountInfo.WalletAddress, "main account is not retured as the first key")
|
||||
s.Equal(accounts[1].Hex(), subAccount1, "subAcount1 not returned")
|
||||
|
||||
// create sub-account 2, index automatically progresses
|
||||
|
@ -69,7 +69,7 @@ func (s *AccountsTestSuite) TestAccountsList() {
|
|||
accounts, err = s.Backend.AccountManager().Accounts()
|
||||
s.NoError(err)
|
||||
s.Equal(3, len(accounts), "unexpected number of accounts")
|
||||
s.Equal(accounts[0].Hex(), address, "main account is not retured as the first key")
|
||||
s.Equal(accounts[0].Hex(), accountInfo.WalletAddress, "main account is not retured as the first key")
|
||||
|
||||
subAccount1MatchesKey1 := accounts[1].Hex() != "0x"+subAccount1
|
||||
subAccount1MatchesKey2 := accounts[2].Hex() != "0x"+subAccount1
|
||||
|
@ -89,11 +89,12 @@ func (s *AccountsTestSuite) TestCreateChildAccount() {
|
|||
s.NotNil(keyStore)
|
||||
|
||||
// create an account
|
||||
address, pubKey, mnemonic, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, mnemonic, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
s.T().Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
|
||||
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s, mnemonic:%s}",
|
||||
accountInfo.WalletAddress, accountInfo.WalletPubKey, accountInfo.ChatAddress, accountInfo.ChatPubKey, mnemonic)
|
||||
|
||||
acct, err := account.ParseAccountString(address)
|
||||
acct, err := account.ParseAccountString(accountInfo.WalletAddress)
|
||||
s.NoError(err, "can not get account from address")
|
||||
|
||||
// obtain decrypted key, and make sure that extended key (which will be used as root for sub-accounts) is present
|
||||
|
@ -105,7 +106,7 @@ func (s *AccountsTestSuite) TestCreateChildAccount() {
|
|||
_, _, err = s.Backend.AccountManager().CreateChildAccount("", TestConfig.Account1.Password)
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "expected error is not returned (tried to create sub-account w/o login)")
|
||||
|
||||
err = s.Backend.SelectAccount(address, TestConfig.Account1.Password)
|
||||
err = s.Backend.SelectAccount(accountInfo.WalletAddress, accountInfo.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err, "cannot select account")
|
||||
|
||||
// try to create sub-account with wrong password
|
||||
|
@ -136,17 +137,19 @@ func (s *AccountsTestSuite) TestRecoverAccount() {
|
|||
s.NoError(err)
|
||||
|
||||
// create an acc
|
||||
address, pubKey, mnemonic, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, mnemonic, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
s.T().Logf("Account created: {address: %s, key: %s, mnemonic:%s}", address, pubKey, mnemonic)
|
||||
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s, mnemonic:%s}",
|
||||
accountInfo.WalletAddress, accountInfo.WalletPubKey, accountInfo.ChatAddress, accountInfo.ChatPubKey, mnemonic)
|
||||
|
||||
// try recovering using password + mnemonic
|
||||
addressCheck, pubKeyCheck, err := s.Backend.AccountManager().RecoverAccount(TestConfig.Account1.Password, mnemonic)
|
||||
accountInfoCheck, err := s.Backend.AccountManager().RecoverAccount(TestConfig.Account1.Password, mnemonic)
|
||||
s.NoError(err, "recover acc failed")
|
||||
s.False(address != addressCheck || pubKey != pubKeyCheck, "incorrect accound details recovered")
|
||||
|
||||
s.EqualValues(accountInfo, accountInfoCheck, "incorrect accound details recovered")
|
||||
|
||||
// now test recovering, but make sure that acc/key file is removed i.e. simulate recovering on a new device
|
||||
acc, err := account.ParseAccountString(address)
|
||||
acc, err := account.ParseAccountString(accountInfo.WalletAddress)
|
||||
s.NoError(err, "can not get acc from address")
|
||||
|
||||
acc, key, err := keyStore.AccountDecryptedKey(acc, TestConfig.Account1.Password)
|
||||
|
@ -155,10 +158,9 @@ func (s *AccountsTestSuite) TestRecoverAccount() {
|
|||
|
||||
s.NoError(keyStore.Delete(acc, TestConfig.Account1.Password), "cannot remove acc")
|
||||
|
||||
addressCheck, pubKeyCheck, err = s.Backend.AccountManager().RecoverAccount(TestConfig.Account1.Password, mnemonic)
|
||||
accountInfoCheck, err = s.Backend.AccountManager().RecoverAccount(TestConfig.Account1.Password, mnemonic)
|
||||
s.NoError(err, "recover acc failed (for non-cached acc)")
|
||||
s.False(address != addressCheck || pubKey != pubKeyCheck,
|
||||
"incorrect acc details recovered (for non-cached acc)")
|
||||
s.EqualValues(accountInfo, accountInfoCheck, "incorrect acc details recovered (for non-cached acc)")
|
||||
|
||||
// make sure that extended key exists and is imported ok too
|
||||
_, key, err = keyStore.AccountDecryptedKey(acc, TestConfig.Account1.Password)
|
||||
|
@ -166,10 +168,9 @@ func (s *AccountsTestSuite) TestRecoverAccount() {
|
|||
s.Equal(extChild2String, key.ExtendedKey.String(), "CKD#2 key mismatch")
|
||||
|
||||
// make sure that calling import several times, just returns from cache (no error is expected)
|
||||
addressCheck, pubKeyCheck, err = s.Backend.AccountManager().RecoverAccount(TestConfig.Account1.Password, mnemonic)
|
||||
accountInfoCheck, err = s.Backend.AccountManager().RecoverAccount(TestConfig.Account1.Password, mnemonic)
|
||||
s.NoError(err, "recover acc failed (for non-cached acc)")
|
||||
s.False(address != addressCheck || pubKey != pubKeyCheck,
|
||||
"incorrect acc details recovered (for non-cached acc)")
|
||||
s.EqualValues(accountInfo, accountInfoCheck, "incorrect acc details recovered (for non-cached acc)")
|
||||
}
|
||||
|
||||
func (s *AccountsTestSuite) TestSelectAccount() {
|
||||
|
@ -177,46 +178,51 @@ func (s *AccountsTestSuite) TestSelectAccount() {
|
|||
defer s.StopTestBackend()
|
||||
|
||||
// create an account
|
||||
address1, pubKey1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
s.T().Logf("Account created: {address: %s, key: %s}", address1, pubKey1)
|
||||
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s}",
|
||||
accountInfo1.WalletAddress, accountInfo1.WalletPubKey, accountInfo1.ChatAddress, accountInfo1.ChatPubKey)
|
||||
|
||||
address2, pubKey2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
s.T().Logf("Account created: {address: %s, key: %s}", address2, pubKey2)
|
||||
s.T().Logf("Account created: {walletAddress: %s, walletKey: %s, chatAddress: %s, chatKey: %s}",
|
||||
accountInfo2.WalletAddress, accountInfo2.WalletPubKey, accountInfo2.ChatAddress, accountInfo2.ChatPubKey)
|
||||
|
||||
// try selecting with wrong password
|
||||
err = s.Backend.SelectAccount(address1, "wrongPassword")
|
||||
err = s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, "wrongPassword")
|
||||
expectedErr := errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase")
|
||||
s.EqualError(expectedErr, err.Error(), "select account is expected to throw error: wrong password used")
|
||||
|
||||
err = s.Backend.SelectAccount(address1, TestConfig.Account1.Password)
|
||||
err = s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
s.NoError(s.Backend.SelectAccount(address2, TestConfig.Account1.Password))
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo2.WalletAddress, accountInfo2.ChatAddress, TestConfig.Account1.Password))
|
||||
}
|
||||
|
||||
func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
||||
s.StartTestBackend()
|
||||
|
||||
// create test accounts
|
||||
address1, _, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
address2, _, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// make sure that no account is selected by default
|
||||
selectedAccount, err := s.Backend.AccountManager().SelectedWalletAccount()
|
||||
selectedWalletAccount, err := s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "account selected, but should not be")
|
||||
s.Nil(selectedAccount)
|
||||
s.Nil(selectedWalletAccount)
|
||||
selectedChatAccount, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "account selected, but should not be")
|
||||
s.Nil(selectedChatAccount)
|
||||
|
||||
// select account
|
||||
err = s.Backend.SelectAccount(address1, "wrongPassword")
|
||||
err = s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, "wrongPassword")
|
||||
expectedErr := errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase")
|
||||
s.EqualError(expectedErr, err.Error())
|
||||
|
||||
s.NoError(s.Backend.SelectAccount(address2, TestConfig.Account1.Password))
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo2.WalletAddress, accountInfo2.ChatAddress, TestConfig.Account1.Password))
|
||||
|
||||
// stop node (and all of its sub-protocols)
|
||||
nodeConfig := s.Backend.StatusNode().Config()
|
||||
|
@ -225,19 +231,27 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.NoError(s.Backend.StopNode())
|
||||
|
||||
// make sure that account is still selected
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
selectedWalletAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.Require().NoError(err)
|
||||
s.NotNil(selectedWalletAccount)
|
||||
s.Equal(selectedWalletAccount.Address.Hex(), accountInfo2.WalletAddress, "incorrect wallet address selected")
|
||||
selectedChatAccount, err = s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedAccount)
|
||||
s.Equal(selectedAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
s.NotNil(selectedChatAccount)
|
||||
s.Equal(selectedChatAccount.Address.Hex(), accountInfo2.ChatAddress, "incorrect chat address selected")
|
||||
|
||||
// resume node
|
||||
s.Require().NoError(s.Backend.StartNode(&preservedNodeConfig))
|
||||
|
||||
// re-check selected account (account2 MUST be selected)
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
selectedWalletAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedAccount)
|
||||
s.Equal(selectedAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
s.NotNil(selectedWalletAccount)
|
||||
s.Equal(selectedWalletAccount.Address.Hex(), accountInfo2.WalletAddress, "incorrect wallet address selected")
|
||||
selectedChatAccount, err = s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedChatAccount)
|
||||
s.Equal(selectedChatAccount.Address.Hex(), accountInfo2.WalletAddress, "incorrect chat address selected")
|
||||
|
||||
// now restart node using RestartNode() method, and make sure that account is still available
|
||||
s.RestartTestNode()
|
||||
|
@ -247,7 +261,10 @@ func (s *AccountsTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.NoError(s.Backend.Logout())
|
||||
s.RestartTestNode()
|
||||
|
||||
selectedAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
selectedWalletAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error())
|
||||
s.Nil(selectedAccount)
|
||||
s.Nil(selectedWalletAccount)
|
||||
selectedChatAccount, err = s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error())
|
||||
s.Nil(selectedChatAccount)
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@ package rpc
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/node"
|
||||
"github.com/status-im/status-go/params"
|
||||
|
@ -174,7 +173,7 @@ func (s *RPCTestSuite) TestCallContextResult() {
|
|||
defer cancel()
|
||||
|
||||
var balance hexutil.Big
|
||||
err := client.CallContext(ctx, &balance, "eth_getBalance", TestConfig.Account1.Address, "latest")
|
||||
err := client.CallContext(ctx, &balance, "eth_getBalance", TestConfig.Account1.WalletAddress, "latest")
|
||||
s.NoError(err)
|
||||
s.True(balance.ToInt().Cmp(big.NewInt(0)) > 0, "balance should be higher than 0")
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
. "github.com/status-im/status-go/t/utils"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -65,7 +64,7 @@ func (s *PersonalSignSuite) TestPersonalSignUnsupportedMethod() {
|
|||
basicCall := fmt.Sprintf(
|
||||
`{"jsonrpc":"2.0","method":"personal_sign","params":["%s", "%s"],"id":67}`,
|
||||
signDataString,
|
||||
TestConfig.Account1.Address)
|
||||
TestConfig.Account1.WalletAddress)
|
||||
|
||||
rawResult, err := s.Backend.CallRPC(basicCall)
|
||||
s.NoError(err)
|
||||
|
|
|
@ -9,9 +9,8 @@ import (
|
|||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/services/status"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
. "github.com/status-im/status-go/t/utils"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type statusTestParams struct {
|
||||
|
@ -62,7 +61,7 @@ func (s *StatusAPISuite) TestAccessibleStatusAPIs() {
|
|||
|
||||
func (s *StatusAPISuite) TestStatusLoginSuccess() {
|
||||
addressKeyID := s.testStatusLogin(statusTestParams{
|
||||
Address: TestConfig.Account1.Address,
|
||||
Address: TestConfig.Account1.WalletAddress,
|
||||
Password: TestConfig.Account1.Password,
|
||||
})
|
||||
s.NotEmpty(addressKeyID)
|
||||
|
@ -90,13 +89,13 @@ func (s *StatusAPISuite) TestStatusSignupSuccess() {
|
|||
res := s.testStatusSignup(statusTestParams{
|
||||
Password: pwd,
|
||||
})
|
||||
s.NotEmpty(res.Address)
|
||||
s.NotEmpty(res.Pubkey)
|
||||
s.NotEmpty(res.WalletAddress)
|
||||
s.NotEmpty(res.WalletPubkey)
|
||||
s.Equal(12, len(strings.Split(res.Mnemonic, " ")))
|
||||
|
||||
// I should be able to login with the newly created account
|
||||
_ = s.testStatusLogin(statusTestParams{
|
||||
Address: res.Address,
|
||||
Address: res.WalletAddress,
|
||||
Password: pwd,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ func (s *TransactionsTestSuite) TestCallUpstreamPrivateRPCSendTransaction() {
|
|||
func (s *TransactionsTestSuite) sendTransactionUsingRPCClient(
|
||||
callRPCFn func(string) (string, error),
|
||||
) {
|
||||
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err := s.Backend.SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
result, err := callRPCFn(`{
|
||||
|
@ -78,7 +78,7 @@ func (s *TransactionsTestSuite) sendTransactionUsingRPCClient(
|
|||
"id": 1,
|
||||
"method": "eth_sendTransaction",
|
||||
"params": [{
|
||||
"from": "` + TestConfig.Account1.Address + `",
|
||||
"from": "` + TestConfig.Account1.WalletAddress + `",
|
||||
"to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
|
||||
"value": "0x9184e72a"
|
||||
}]
|
||||
|
@ -94,11 +94,11 @@ func (s *TransactionsTestSuite) TestEmptyToFieldPreserved() {
|
|||
defer s.StopTestBackend()
|
||||
|
||||
EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
||||
err := s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err := s.Backend.SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
args := transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
}
|
||||
|
||||
hash, err := s.Backend.SendTransaction(args, TestConfig.Account1.Password)
|
||||
|
@ -162,7 +162,7 @@ func (s *TransactionsTestSuite) testSendContractTx(setInputAndDataValue initFunc
|
|||
|
||||
EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
||||
|
||||
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// this call blocks, up until Complete Transaction is called
|
||||
|
@ -171,7 +171,7 @@ func (s *TransactionsTestSuite) testSendContractTx(setInputAndDataValue initFunc
|
|||
|
||||
gas := uint64(params.DefaultGas)
|
||||
args := transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: nil, // marker, contract creation is expected
|
||||
//Value: (*hexutil.Big)(new(big.Int).Mul(big.NewInt(1), gethcommon.Ether)),
|
||||
Gas: (*hexutil.Uint64)(&gas),
|
||||
|
@ -196,12 +196,12 @@ func (s *TransactionsTestSuite) TestSendEther() {
|
|||
|
||||
EnsureNodeSync(s.Backend.StatusNode().EnsureSync)
|
||||
|
||||
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err := s.Backend.AccountManager().SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
hash, err := s.Backend.SendTransaction(transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
}, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
@ -216,12 +216,12 @@ func (s *TransactionsTestSuite) TestSendEtherTxUpstream() {
|
|||
s.StartTestBackend(e2e.WithUpstream(addr))
|
||||
defer s.StopTestBackend()
|
||||
|
||||
err = s.Backend.SelectAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
err = s.Backend.SelectAccount(TestConfig.Account1.WalletAddress, TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
hash, err := s.Backend.SendTransaction(transactions.SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
GasPrice: (*hexutil.Big)(big.NewInt(28000000000)),
|
||||
Value: (*hexutil.Big)(big.NewInt(1000000000000)),
|
||||
}, TestConfig.Account1.Password)
|
||||
|
|
|
@ -37,7 +37,7 @@ func (s *WhisperTestSuite) TestWhisperFilterRace() {
|
|||
whisperAPI := whisper.NewPublicWhisperAPI(whisperService)
|
||||
|
||||
// account1
|
||||
_, accountKey1, err := accountManager.AddressToDecryptedAccount(TestConfig.Account1.Address, TestConfig.Account1.Password)
|
||||
_, accountKey1, err := accountManager.AddressToDecryptedAccount(TestConfig.Account1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
accountKey1Byte := crypto.FromECDSAPub(&accountKey1.PrivateKey.PublicKey)
|
||||
|
||||
|
@ -47,7 +47,7 @@ func (s *WhisperTestSuite) TestWhisperFilterRace() {
|
|||
s.True(ok, "identity not injected")
|
||||
|
||||
// account2
|
||||
_, accountKey2, err := accountManager.AddressToDecryptedAccount(TestConfig.Account2.Address, TestConfig.Account2.Password)
|
||||
_, accountKey2, err := accountManager.AddressToDecryptedAccount(TestConfig.Account2.ChatAddress, TestConfig.Account2.Password)
|
||||
s.NoError(err)
|
||||
key2ID, err := whisperService.AddKeyPair(accountKey2.PrivateKey)
|
||||
s.NoError(err)
|
||||
|
@ -96,21 +96,31 @@ func (s *WhisperTestSuite) TestSelectAccount() {
|
|||
whisperService, err := s.Backend.StatusNode().WhisperService()
|
||||
s.NoError(err)
|
||||
|
||||
// create an acc
|
||||
address, pubKey, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
// create account 1
|
||||
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
s.False(whisperService.HasKeyPair(pubKey), "identity already present in whisper")
|
||||
// create account 2
|
||||
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// make sure that identities are not injected yet
|
||||
s.False(whisperService.HasKeyPair(accountInfo1.ChatPubKey), "identity already present in whisper")
|
||||
s.False(whisperService.HasKeyPair(accountInfo2.ChatPubKey), "identity already present in whisper")
|
||||
|
||||
// try selecting with wrong password
|
||||
err = s.Backend.SelectAccount(address, "wrongPassword")
|
||||
err = s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, "wrongpassword")
|
||||
s.NotNil(err)
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
s.False(whisperService.HasKeyPair(pubKey), "identity already present in whisper")
|
||||
s.NoError(s.Backend.SelectAccount(address, TestConfig.Account1.Password))
|
||||
s.True(whisperService.HasKeyPair(pubKey), "identity not injected into whisper")
|
||||
// select account 1
|
||||
err = s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
s.True(whisperService.HasKeyPair(accountInfo1.ChatPubKey), "identity not injected in whisper")
|
||||
|
||||
// select account 2, make sure that previous account is wiped out from Whisper cache
|
||||
s.False(whisperService.HasKeyPair(accountInfo2.ChatPubKey), "identity already present in whisper")
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo2.WalletAddress, accountInfo2.ChatAddress, TestConfig.Account2.Password))
|
||||
s.True(whisperService.HasKeyPair(accountInfo2.ChatPubKey), "identity not injected into whisper")
|
||||
}
|
||||
|
||||
func (s *WhisperTestSuite) TestLogout() {
|
||||
|
@ -121,16 +131,16 @@ func (s *WhisperTestSuite) TestLogout() {
|
|||
s.NoError(err)
|
||||
|
||||
// create an account
|
||||
address, pubKey, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// make sure that identity doesn't exist (yet) in Whisper
|
||||
s.False(whisperService.HasKeyPair(pubKey), "identity already present in whisper")
|
||||
s.NoError(s.Backend.SelectAccount(address, TestConfig.Account1.Password))
|
||||
s.True(whisperService.HasKeyPair(pubKey), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(accountInfo.ChatPubKey), "identity already present in whisper")
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo.WalletAddress, accountInfo.ChatAddress, TestConfig.Account1.Password))
|
||||
s.True(whisperService.HasKeyPair(accountInfo.ChatPubKey), "identity not injected into whisper")
|
||||
|
||||
s.NoError(s.Backend.Logout())
|
||||
s.False(whisperService.HasKeyPair(pubKey), "identity not cleared from whisper")
|
||||
s.False(whisperService.HasKeyPair(accountInfo.ChatPubKey), "identity not cleared from whisper")
|
||||
}
|
||||
|
||||
func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
|
||||
|
@ -140,15 +150,15 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
|
|||
whisperService := s.WhisperService()
|
||||
|
||||
// create test accounts
|
||||
address1, pubKey1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo1, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
address2, pubKey2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
|
||||
accountInfo2, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account2.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// make sure that identity is not (yet injected)
|
||||
s.False(whisperService.HasKeyPair(pubKey1), "identity already present in whisper")
|
||||
s.False(whisperService.HasKeyPair(accountInfo1.ChatPubKey), "identity already present in whisper")
|
||||
|
||||
// make sure that no account is selected by default
|
||||
// make sure that no wallet account is selected by default
|
||||
selectedWalletAccount, err := s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.EqualError(account.ErrNoAccountSelected, err.Error(), "account selected, but should not be")
|
||||
s.Nil(selectedWalletAccount)
|
||||
|
@ -159,25 +169,25 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
|
|||
s.Nil(selectedChatAccount)
|
||||
|
||||
// select account with wrong password
|
||||
err = s.Backend.SelectAccount(address1, "wrongPassword")
|
||||
err = s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, "wrongPassword")
|
||||
expectedErr := errors.New("cannot retrieve a valid key for a given account: could not decrypt key with given passphrase")
|
||||
s.EqualError(expectedErr, err.Error())
|
||||
|
||||
// select account with right password
|
||||
s.NoError(s.Backend.SelectAccount(address1, TestConfig.Account1.Password))
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo1.WalletAddress, accountInfo1.ChatAddress, TestConfig.Account1.Password))
|
||||
selectedChatAccount1, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
selectedChatPubKey1 := hexutil.Encode(crypto.FromECDSAPub(&selectedChatAccount1.AccountKey.PrivateKey.PublicKey))
|
||||
s.Equal(selectedChatPubKey1, pubKey1)
|
||||
s.Equal(selectedChatPubKey1, accountInfo1.ChatPubKey)
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey1), "identity not injected into whisper")
|
||||
|
||||
// select another account, make sure that previous account is wiped out from Whisper cache
|
||||
s.False(whisperService.HasKeyPair(pubKey2), "identity already present in whisper")
|
||||
s.NoError(s.Backend.SelectAccount(address2, TestConfig.Account2.Password))
|
||||
s.False(whisperService.HasKeyPair(accountInfo2.ChatPubKey), "identity already present in whisper")
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo2.WalletAddress, accountInfo2.ChatAddress, TestConfig.Account2.Password))
|
||||
selectedChatAccount2, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
selectedChatPubKey2 := hexutil.Encode(crypto.FromECDSAPub(&selectedChatAccount2.AccountKey.PrivateKey.PublicKey))
|
||||
s.Equal(selectedChatPubKey2, pubKey2)
|
||||
s.Equal(selectedChatPubKey2, accountInfo2.ChatPubKey)
|
||||
s.True(whisperService.HasKeyPair(selectedChatPubKey2), "identity not injected into whisper")
|
||||
s.False(whisperService.HasKeyPair(selectedChatPubKey1), "identity should be removed, but it is still present in whisper")
|
||||
|
||||
|
@ -194,7 +204,11 @@ func (s *WhisperTestSuite) TestSelectedAccountOnRestart() {
|
|||
selectedWalletAccount, err = s.Backend.AccountManager().SelectedWalletAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedWalletAccount)
|
||||
s.Equal(selectedWalletAccount.Address.Hex(), address2, "incorrect address selected")
|
||||
s.Equal(selectedWalletAccount.Address.Hex(), accountInfo2.WalletAddress, "incorrect wallet address selected")
|
||||
selectedChatAccount, err = s.Backend.AccountManager().SelectedChatAccount()
|
||||
s.NoError(err)
|
||||
s.NotNil(selectedChatAccount)
|
||||
s.Equal(selectedChatAccount.Address.Hex(), accountInfo2.ChatAddress, "incorrect chat address selected")
|
||||
|
||||
// make sure that Whisper gets identity re-injected
|
||||
whisperService = s.WhisperService()
|
||||
|
@ -233,11 +247,11 @@ func (s *WhisperTestSuite) TestSelectedChatKeyIsUsedInWhisper() {
|
|||
s.NoError(err)
|
||||
|
||||
// create an account
|
||||
address, _, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
accountInfo, _, err := s.Backend.AccountManager().CreateAccount(TestConfig.Account1.Password)
|
||||
s.NoError(err)
|
||||
|
||||
// select account
|
||||
s.NoError(s.Backend.SelectAccount(address, TestConfig.Account1.Password))
|
||||
s.NoError(s.Backend.SelectAccount(accountInfo.WalletAddress, accountInfo.ChatAddress, TestConfig.Account1.Password))
|
||||
|
||||
// Get the chat account
|
||||
selectedChatAccount, err := s.Backend.AccountManager().SelectedChatAccount()
|
||||
|
|
|
@ -19,11 +19,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/status-im/status-go/logutils"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/status-im/status-go/logutils"
|
||||
"github.com/status-im/status-go/params"
|
||||
|
||||
_ "github.com/stretchr/testify/suite" // required to register testify flags
|
||||
)
|
||||
|
||||
|
@ -307,8 +305,9 @@ func MakeTestNodeConfigWithDataDir(name, dataDir string, networkID uint64) (*par
|
|||
}
|
||||
|
||||
type account struct {
|
||||
Address string
|
||||
Password string
|
||||
WalletAddress string
|
||||
ChatAddress string
|
||||
Password string
|
||||
}
|
||||
|
||||
// testConfig contains shared (among different test packages) parameters
|
||||
|
|
|
@ -21,14 +21,12 @@ import (
|
|||
"github.com/ethereum/go-ethereum/rlp"
|
||||
gethrpc "github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/transactions/fake"
|
||||
|
||||
. "github.com/status-im/status-go/t/utils"
|
||||
"github.com/status-im/status-go/transactions/fake"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
func TestTransactorSuite(t *testing.T) {
|
||||
|
@ -120,7 +118,7 @@ func (s *TransactorSuite) rlpEncodeTx(args SendTxArgs, config *params.NodeConfig
|
|||
func (s *TransactorSuite) TestGasValues() {
|
||||
key, _ := crypto.GenerateKey()
|
||||
selectedAccount := &account.SelectedExtKey{
|
||||
Address: account.FromAddress(TestConfig.Account1.Address),
|
||||
Address: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
AccountKey: &keystore.Key{PrivateKey: key},
|
||||
}
|
||||
testCases := []struct {
|
||||
|
@ -154,8 +152,8 @@ func (s *TransactorSuite) TestGasValues() {
|
|||
s.T().Run(testCase.name, func(t *testing.T) {
|
||||
s.SetupTest()
|
||||
args := SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
Gas: testCase.gas,
|
||||
GasPrice: testCase.gasPrice,
|
||||
}
|
||||
|
@ -170,14 +168,14 @@ func (s *TransactorSuite) TestGasValues() {
|
|||
|
||||
func (s *TransactorSuite) TestArgsValidation() {
|
||||
args := SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
Data: hexutil.Bytes([]byte{0x01, 0x02}),
|
||||
Input: hexutil.Bytes([]byte{0x02, 0x01}),
|
||||
}
|
||||
s.False(args.Valid())
|
||||
selectedAccount := &account.SelectedExtKey{
|
||||
Address: account.FromAddress(TestConfig.Account1.Address),
|
||||
Address: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
}
|
||||
_, err := s.manager.SendTransaction(args, selectedAccount)
|
||||
s.EqualError(err, ErrInvalidSendTxArgs.Error())
|
||||
|
@ -185,8 +183,8 @@ func (s *TransactorSuite) TestArgsValidation() {
|
|||
|
||||
func (s *TransactorSuite) TestAccountMismatch() {
|
||||
args := SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
}
|
||||
|
||||
var err error
|
||||
|
@ -197,7 +195,7 @@ func (s *TransactorSuite) TestAccountMismatch() {
|
|||
|
||||
// mismatched accounts
|
||||
selectedAccount := &account.SelectedExtKey{
|
||||
Address: account.FromAddress(TestConfig.Account2.Address),
|
||||
Address: account.FromAddress(TestConfig.Account2.WalletAddress),
|
||||
}
|
||||
_, err = s.manager.SendTransaction(args, selectedAccount)
|
||||
s.EqualError(err, ErrInvalidTxSender.Error())
|
||||
|
@ -214,15 +212,15 @@ func (s *TransactorSuite) TestLocalNonce() {
|
|||
txCount := 3
|
||||
key, _ := crypto.GenerateKey()
|
||||
selectedAccount := &account.SelectedExtKey{
|
||||
Address: account.FromAddress(TestConfig.Account1.Address),
|
||||
Address: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
AccountKey: &keystore.Key{PrivateKey: key},
|
||||
}
|
||||
nonce := hexutil.Uint64(0)
|
||||
|
||||
for i := 0; i < txCount; i++ {
|
||||
args := SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
}
|
||||
s.setupTransactionPoolAPI(args, nonce, hexutil.Uint64(i), selectedAccount, nil)
|
||||
|
||||
|
@ -234,8 +232,8 @@ func (s *TransactorSuite) TestLocalNonce() {
|
|||
|
||||
nonce = hexutil.Uint64(5)
|
||||
args := SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
}
|
||||
|
||||
s.setupTransactionPoolAPI(args, nonce, nonce, selectedAccount, nil)
|
||||
|
@ -249,8 +247,8 @@ func (s *TransactorSuite) TestLocalNonce() {
|
|||
testErr := errors.New("test")
|
||||
s.txServiceMock.EXPECT().GetTransactionCount(gomock.Any(), selectedAccount.Address, gethrpc.PendingBlockNumber).Return(nil, testErr)
|
||||
args = SendTxArgs{
|
||||
From: account.FromAddress(TestConfig.Account1.Address),
|
||||
To: account.ToAddress(TestConfig.Account2.Address),
|
||||
From: account.FromAddress(TestConfig.Account1.WalletAddress),
|
||||
To: account.ToAddress(TestConfig.Account2.WalletAddress),
|
||||
}
|
||||
|
||||
_, err = s.manager.SendTransaction(args, selectedAccount)
|
||||
|
|
Loading…
Reference in New Issue