Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 31 additions & 7 deletions packages/wallet-stack/src/account/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -140,16 +140,42 @@ 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'] } })
)

await expectSaga(initializeAccountSaga)
.provide([
[call(getOrCreateAccount), undefined],
[call(generateSignedMessage), undefined],
[select(choseToRestoreAccountSelector), true],
[call(generateSignedMessage), undefined],
[call(retrieveSignedMessage), 'some signed message'],
[select(walletAddressSelector), '0xabc'],
])
Expand All @@ -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'],
])
Expand All @@ -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'],
])
Expand Down
10 changes: 7 additions & 3 deletions packages/wallet-stack/src/account/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
}
Expand Down
20 changes: 6 additions & 14 deletions packages/wallet-stack/src/web3/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -12,7 +13,7 @@ import {
UnlockResult,
getConnectedAccount,
getConnectedUnlockedAccount,
getOrCreateAccount,
createAccount,
getWalletAddress,
unlockAccount,
assignAccountFromPrivateKey,
Expand Down Expand Up @@ -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'}
Expand All @@ -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),
Expand All @@ -71,6 +63,7 @@ describe(getOrCreateAccount, () => {
],
[call(getPasswordSaga, expectedAddress, false, true), 'somePassword'],
])
.call(clearStoredAccounts)
.put(setAccount(expectedAddress))
.returns(expectedAddress)
.run()
Expand All @@ -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),
Expand Down
23 changes: 9 additions & 14 deletions packages/wallet-stack/src/web3/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand All @@ -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)
}
}
Expand Down
Loading