diff --git a/packages/wallet-stack/src/account/saga.test.ts b/packages/wallet-stack/src/account/saga.test.ts index d7a944c05..abaaedcf0 100644 --- a/packages/wallet-stack/src/account/saga.test.ts +++ b/packages/wallet-stack/src/account/saga.test.ts @@ -21,7 +21,7 @@ import Logger from 'src/utils/Logger' import { ViemKeychainAccount } from 'src/viem/keychainAccountToAccount' import { getKeychainAccounts } from 'src/web3/contracts' import networkConfig from 'src/web3/networkConfig' -import { UnlockResult, getOrCreateAccount, unlockAccount } from 'src/web3/saga' +import { UnlockResult, createAccount, unlockAccount } from 'src/web3/saga' import { walletAddressSelector } from 'src/web3/selectors' import { initializeAccountSuccess, saveSignedMessage } from './actions' @@ -140,6 +140,33 @@ describe('initializeAccount', () => { mockFetch.resetMocks() }) + it('should call createAccount when not restoring', async () => { + await expectSaga(initializeAccountSaga) + .provide([ + [select(choseToRestoreAccountSelector), false], + [call(createAccount), undefined], + [call(generateSignedMessage), undefined], + ]) + .call(createAccount) + .put(initializeAccountSuccess()) + .run() + }) + + it('should skip createAccount when restoring', async () => { + mockFetch.mockResponse(JSON.stringify({ data: { phoneNumbers: [] } })) + + await expectSaga(initializeAccountSaga) + .provide([ + [select(choseToRestoreAccountSelector), true], + [call(generateSignedMessage), undefined], + [call(retrieveSignedMessage), 'some signed message'], + [select(walletAddressSelector), '0xabc'], + ]) + .not.call.fn(createAccount) + .put(initializeAccountSuccess()) + .run() + }) + it('should handle the last previously verified phone number', async () => { mockFetch.mockResponse( JSON.stringify({ data: { phoneNumbers: ['+1302123456', '+31619123456'] } }) @@ -147,9 +174,8 @@ describe('initializeAccount', () => { await expectSaga(initializeAccountSaga) .provide([ - [call(getOrCreateAccount), undefined], - [call(generateSignedMessage), undefined], [select(choseToRestoreAccountSelector), true], + [call(generateSignedMessage), undefined], [call(retrieveSignedMessage), 'some signed message'], [select(walletAddressSelector), '0xabc'], ]) @@ -176,9 +202,8 @@ describe('initializeAccount', () => { await expectSaga(initializeAccountSaga) .provide([ - [call(getOrCreateAccount), undefined], - [call(generateSignedMessage), undefined], [select(choseToRestoreAccountSelector), true], + [call(generateSignedMessage), undefined], [call(retrieveSignedMessage), 'some signed message'], [select(walletAddressSelector), '0xabc'], ]) @@ -194,9 +219,8 @@ describe('initializeAccount', () => { await expectSaga(initializeAccountSaga) .provide([ - [call(getOrCreateAccount), undefined], - [call(generateSignedMessage), undefined], [select(choseToRestoreAccountSelector), true], + [call(generateSignedMessage), undefined], [call(retrieveSignedMessage), 'some signed message'], [select(walletAddressSelector), '0xabc'], ]) diff --git a/packages/wallet-stack/src/account/saga.ts b/packages/wallet-stack/src/account/saga.ts index 84d2e0406..c341f3bf4 100644 --- a/packages/wallet-stack/src/account/saga.ts +++ b/packages/wallet-stack/src/account/saga.ts @@ -40,7 +40,7 @@ import { safely } from 'src/utils/safely' import { clearStoredAccounts } from 'src/web3/KeychainAccounts' import { getKeychainAccounts } from 'src/web3/contracts' import networkConfig from 'src/web3/networkConfig' -import { getOrCreateAccount, getWalletAddress, unlockAccount } from 'src/web3/saga' +import { createAccount, getWalletAddress, unlockAccount } from 'src/web3/saga' import { walletAddressSelector } from 'src/web3/selectors' import { call, put, select, spawn, take, takeLeading } from 'typed-redux-saga' const TAG = 'account/saga' @@ -75,10 +75,14 @@ export function* initializeAccountSaga() { Logger.debug(TAG + '@initializeAccountSaga', 'Creating account') try { AppAnalytics.track(OnboardingEvents.initialize_account_start) - yield* call(getOrCreateAccount) - yield* call(generateSignedMessage) const choseToRestoreAccount = yield* select(choseToRestoreAccountSelector) + if (!choseToRestoreAccount) { + yield* call(createAccount) + } + + yield* call(generateSignedMessage) + if (choseToRestoreAccount) { yield* call(handlePreviouslyVerifiedPhoneNumber) } diff --git a/packages/wallet-stack/src/web3/saga.test.ts b/packages/wallet-stack/src/web3/saga.test.ts index 75b829162..ff05e8a27 100644 --- a/packages/wallet-stack/src/web3/saga.test.ts +++ b/packages/wallet-stack/src/web3/saga.test.ts @@ -4,6 +4,7 @@ import { call, select } from 'redux-saga/effects' import { generateSignedMessage } from 'src/account/saga' import { ErrorMessages } from 'src/app/ErrorMessages' import { storeMnemonic } from 'src/backup/utils' +import { clearStoredAccounts } from 'src/web3/KeychainAccounts' import { currentLanguageSelector } from 'src/i18n/selectors' import { getPasswordSaga, retrieveSignedMessage } from 'src/pincode/authentication' import { MnemonicLanguages, MnemonicStrength, generateMnemonic } from 'src/utils/account' @@ -12,7 +13,7 @@ import { UnlockResult, getConnectedAccount, getConnectedUnlockedAccount, - getOrCreateAccount, + createAccount, getWalletAddress, unlockAccount, assignAccountFromPrivateKey, @@ -40,15 +41,7 @@ const state = createMockStore({ web3: { account: mockAccount }, }).getState() -describe(getOrCreateAccount, () => { - it('returns an existing account', async () => { - await expectSaga(getOrCreateAccount) - .withState(state) - .not.call.fn(generateMnemonic) - .returns('0x0000000000000000000000000000000000007e57') - .run() - }) - +describe(createAccount, () => { it.each` expectedAddress | expectedPrivateDek | mnemonic ${'0xE025583d25Eff2C254999b5904C97bAe9B3F8D83'} | ${'0xb6812219f7003c27cc1ef17c2033c033a38cfc52d83f176a0667086787d59d39'} | ${'avellana novio zona pinza ducha íntimo amante diluir toldo peón ocio encía gen balcón carro lingote millón amasar mármol bondad toser soledad croqueta agosto'} @@ -57,10 +50,9 @@ describe(getOrCreateAccount, () => { `( 'creates a new account $expectedAddress', async ({ expectedAddress, expectedPrivateDek, mnemonic }) => { - await expectSaga(getOrCreateAccount) + await expectSaga(createAccount) .withState(state) .provide([ - [select(currentAccountSelector), null], [matchers.call.fn(generateMnemonic), mnemonic], [ call(storeMnemonic, mnemonic, expectedAddress), @@ -71,6 +63,7 @@ describe(getOrCreateAccount, () => { ], [call(getPasswordSaga, expectedAddress, false, true), 'somePassword'], ]) + .call(clearStoredAccounts) .put(setAccount(expectedAddress)) .returns(expectedAddress) .run() @@ -86,10 +79,9 @@ describe(getOrCreateAccount, () => { `( 'creates an account with a mnemonic in $expectedMnemonicLang when app language is $appLang', async ({ appLang, expectedMnemonicLang }) => { - const { returnValue } = await expectSaga(getOrCreateAccount) + const { returnValue } = await expectSaga(createAccount) .withState(state) .provide([ - [select(currentAccountSelector), null], [select(currentLanguageSelector), appLang], [ matchers.call.fn(storeMnemonic), diff --git a/packages/wallet-stack/src/web3/saga.ts b/packages/wallet-stack/src/web3/saga.ts index fd0022222..3d6aa26fb 100644 --- a/packages/wallet-stack/src/web3/saga.ts +++ b/packages/wallet-stack/src/web3/saga.ts @@ -12,28 +12,23 @@ import Logger from 'src/utils/Logger' import { MnemonicLanguages, MnemonicStrength, generateMnemonic } from 'src/utils/account' import { privateKeyToAddress } from 'src/utils/address' import { ensureError } from 'src/utils/ensureError' +import { clearStoredAccounts } from 'src/web3/KeychainAccounts' import { Actions, SetAccountAction, setAccount } from 'src/web3/actions' import { UNLOCK_DURATION } from 'src/web3/consts' import { getKeychainAccounts } from 'src/web3/contracts' -import { currentAccountSelector, walletAddressSelector } from 'src/web3/selectors' +import { walletAddressSelector } from 'src/web3/selectors' import { call, put, select, take } from 'typed-redux-saga' import { RootState } from '../redux/reducers' const TAG = 'web3/saga' -export function* getOrCreateAccount() { - const account = yield* select(currentAccountSelector) - if (account) { - Logger.debug( - TAG + '@getOrCreateAccount', - 'Tried to create account twice, returning the existing one' - ) - return account - } - +export function* createAccount() { let privateKey: string | undefined try { - Logger.debug(TAG + '@getOrCreateAccount', 'Creating a new account') + Logger.debug(TAG + '@createAccount', 'Clearing stored accounts') + yield* call(clearStoredAccounts) + + Logger.debug(TAG + '@createAccount', 'Creating a new account') const mnemonicBitLength = MnemonicStrength.s128_12words const mnemonicLanguage = MnemonicLanguages.english @@ -45,7 +40,7 @@ export function* getOrCreateAccount() { } let duplicateInMnemonic = checkDuplicate(mnemonic) while (duplicateInMnemonic) { - Logger.debug(TAG + '@getOrCreateAccount', 'Regenerating mnemonic to avoid duplicates') + Logger.debug(TAG + '@createAccount', 'Regenerating mnemonic to avoid duplicates') mnemonic = yield* call(generateMnemonic, mnemonicBitLength, mnemonicLanguage) duplicateInMnemonic = checkDuplicate(mnemonic) } @@ -71,7 +66,7 @@ export function* getOrCreateAccount() { } catch (err) { const error = ensureError(err) const sanitizedError = Logger.sanitizeError(error, privateKey) - Logger.error(TAG + '@getOrCreateAccount', 'Error creating account', sanitizedError) + Logger.error(TAG + '@createAccount', 'Error creating account', sanitizedError) throw new Error(ErrorMessages.ACCOUNT_SETUP_FAILED) } }