Skip to content

Commit

Permalink
US-1954 Fixed issue where the app was not triggering the keysExist fl… (
Browse files Browse the repository at this point in the history
#762)

* US-1954 Fixed issue where the app was not triggering the keysExist flow because it was being flushed. The storage has been moved away from the main chainId and defined as a chainId 0 so that it is not deleted (and hardcoded because that persistedData is shared among chainIds)

* Created update so that users don't lose their wallets.

* Moved PIN to persistentData

* Created first migration for persistentData

* Fixed pin
  • Loading branch information
Freshenext authored Oct 5, 2023
1 parent 132a451 commit bdf6376
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 38 deletions.
3 changes: 2 additions & 1 deletion src/navigation/createKeysNavigator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
SecurityInformation,
RetryLogin,
} from 'screens/createKeys'
import { selectIsUnlocked, selectKeysExist } from 'store/slices/settingsSlice'
import { selectIsUnlocked } from 'store/slices/settingsSlice'
import { selectKeysExist } from 'store/slices/persistentDataSlice'
import { useAppSelector } from 'store/storeUtils'
import { PinScreen } from 'screens/pinScreen'

Expand Down
55 changes: 51 additions & 4 deletions src/redux/rootReducer.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { combineReducers } from '@reduxjs/toolkit'
import { persistReducer, createMigrate, PersistConfig } from 'redux-persist'
import {
persistReducer,
createMigrate,
PersistConfig,
getStoredState,
} from 'redux-persist'

import { reduxStorage } from 'storage/ReduxStorage'
import { contactsReducer } from 'store/slices/contactsSlice'
import { ProfileStatus } from 'navigation/profileNavigator/types'
import { getCurrentChainId } from 'storage/ChainStorage'
import {
persistentDataReducer,
PersistentDataState,
} from 'store/slices/persistentDataSlice'

import { accountsReducer } from './slices/accountsSlice'
import { balancesReducer } from './slices/balancesSlice'
import { profileReducer } from './slices/profileSlice'
import { settingsSliceReducer } from './slices/settingsSlice'
import { transactionsReducer } from './slices/transactionsSlice'
import { usdPriceReducer } from './slices/usdPricesSlice'
import { usdPriceReducer, UsdPricesState } from './slices/usdPricesSlice'
import { SettingsSlice } from './slices/settingsSlice/types'

const migrations = {
Expand All @@ -29,13 +38,47 @@ const migrations = {
}),
}

const firstPersistentDataMigration = async state => {
// First migration, check if state already exists
if (!state) {
// First step is to get old settings storage - usually testnet storage has all the info
const oldStorage = await getStoredState({
key: 'settings',
storage: reduxStorage(31),
})
// If old storage exists, we will migrate it to the current state
if (oldStorage) {
return {
keysExist: oldStorage.keysExist,
isFirstLaunch: oldStorage.isFirstLaunch,
pin: oldStorage.pin,
}
}
}
return state
}

export const createRootReducer = () => {
const persistedReduxStorageAcrossChainSwitches = reduxStorage(0)

const settingsPersistConfig: PersistConfig<SettingsSlice> = {
key: 'settings',
whitelist: ['pin', 'keysExist', 'isFirstLaunch', 'usedBitcoinAddresses'],
whitelist: ['usedBitcoinAddresses'],
storage: reduxStorage(getCurrentChainId()),
}

const persistentDataPersistConfig: PersistConfig<PersistentDataState> = {
key: 'persistentData',
whitelist: ['keysExist', 'isFirstLaunch', 'pin'],
storage: persistedReduxStorageAcrossChainSwitches,
migrate: firstPersistentDataMigration,
}

const usdPricesPersistConfig: PersistConfig<UsdPricesState> = {
key: 'usdPrices',
storage: persistedReduxStorageAcrossChainSwitches,
}

const rootPersistConfig = {
key: 'root',
version: 0,
Expand All @@ -52,13 +95,17 @@ export const createRootReducer = () => {
}

const reducers = combineReducers({
usdPrices: usdPriceReducer,
usdPrices: persistReducer(usdPricesPersistConfig, usdPriceReducer),
balances: balancesReducer,
transactions: transactionsReducer,
settings: persistReducer(settingsPersistConfig, settingsSliceReducer),
profile: profileReducer,
accounts: accountsReducer,
contacts: contactsReducer,
persistentData: persistReducer(
persistentDataPersistConfig,
persistentDataReducer,
),
})

return persistReducer(rootPersistConfig, reducers)
Expand Down
36 changes: 36 additions & 0 deletions src/redux/slices/persistentDataSlice/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

import { PersistentDataState } from './types'

const initialState: PersistentDataState = {
keysExist: false,
isFirstLaunch: true,
pin: null,
}

/**
* Data that will be persisted across chain ID switches
*/
const persistentDataSlice = createSlice({
name: 'persistentData',
initialState,
reducers: {
setKeysExist: (state, { payload }: PayloadAction<boolean>) => {
state.keysExist = payload
},
setIsFirstLaunch: (state, { payload }: PayloadAction<boolean>) => {
state.isFirstLaunch = payload
},
setPinState: (state, { payload }: PayloadAction<string | null>) => {
state.pin = payload
},
},
})

export const { setKeysExist, setIsFirstLaunch, setPinState } =
persistentDataSlice.actions

export const persistentDataReducer = persistentDataSlice.reducer

export * from './types'
export * from './selectors'
6 changes: 6 additions & 0 deletions src/redux/slices/persistentDataSlice/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { RootState } from 'src/redux'

export const selectKeysExist = ({ persistentData }: RootState) =>
persistentData.keysExist

export const selectPin = ({ persistentData }: RootState) => persistentData.pin
5 changes: 5 additions & 0 deletions src/redux/slices/persistentDataSlice/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface PersistentDataState {
keysExist: boolean
isFirstLaunch: boolean
pin: string | null
}
24 changes: 7 additions & 17 deletions src/redux/slices/settingsSlice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import {
} from 'shared/constants/chainConstants'
import { getCurrentChainId } from 'storage/ChainStorage'
import { resetReduxStorage } from 'storage/ReduxStorage'
import {
setIsFirstLaunch,
setKeysExist,
setPinState,
} from 'store/slices/persistentDataSlice'

import {
Bitcoin,
Expand Down Expand Up @@ -145,7 +150,7 @@ export const unlockApp = createAsyncThunk<
try {
// check if it is a first launch, deleteKeys
const {
settings: { isFirstLaunch },
persistentData: { isFirstLaunch },
} = thunkAPI.getState()
// if previously installed the app, remove stored encryted keys
if (isFirstLaunch && !__DEV__) {
Expand All @@ -171,7 +176,7 @@ export const unlockApp = createAsyncThunk<

if (Platform.OS === 'android' && !supportedBiometry && !pinUnlocked) {
const {
settings: { pin },
persistentData: { pin },
} = thunkAPI.getState()

// if there's no pin yet and biometrics removed
Expand Down Expand Up @@ -314,8 +319,6 @@ export const resetApp = createAsyncThunk(
// )

const initialState: SettingsSlice = {
keysExist: false,
isFirstLaunch: true,
isSetup: false,
topColor: sharedColors.primary,
requests: [],
Expand All @@ -329,7 +332,6 @@ const initialState: SettingsSlice = {
previouslyUnlocked: false,
fullscreen: false,
hideBalance: false,
pin: null,
bitcoin: null,
chainId: 31,
usedBitcoinAddresses: {},
Expand All @@ -345,12 +347,6 @@ const settingsSlice = createSlice({
name: 'settings',
initialState: createInitialState,
reducers: {
setKeysExist: (state, { payload }: PayloadAction<boolean>) => {
state.keysExist = payload
},
setIsFirstLaunch: (state, { payload }: PayloadAction<boolean>) => {
state.isFirstLaunch = payload
},
setIsSetup: (state, { payload }: PayloadAction<boolean>) => {
state.isSetup = payload
return state
Expand Down Expand Up @@ -378,9 +374,6 @@ const settingsSlice = createSlice({
setPreviouslyUnlocked: (state, { payload }: PayloadAction<boolean>) => {
state.previouslyUnlocked = payload
},
setPinState: (state, { payload }: PayloadAction<string | null>) => {
state.pin = payload
},
setWallet: (
state,
{ payload: { wallet, walletIsDeployed } }: PayloadAction<SetKeysAction>,
Expand Down Expand Up @@ -492,14 +485,11 @@ const settingsSlice = createSlice({
})

export const {
setKeysExist,
setIsFirstLaunch,
setIsSetup,
changeTopColor,
onRequest,
closeRequest,
setWallet,
setPinState,
setChainId,
setAppIsActive,
setUnlocked,
Expand Down
6 changes: 0 additions & 6 deletions src/redux/slices/settingsSlice/selectors.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import { RootState } from 'store/store'

export const selectKeysExist = ({ settings }: RootState) => settings.keysExist

export const selectIsFirstLaunch = ({ settings }: RootState) =>
settings.isFirstLaunch

export const selectRequests = ({ settings }: RootState) => settings.requests

export const selectTopColor = ({ settings }: RootState) => settings.topColor
Expand Down Expand Up @@ -44,7 +39,6 @@ export const selectFullscreen = ({ settings }: RootState) => settings.fullscreen

export const selectHideBalance = ({ settings }: RootState) =>
settings.hideBalance
export const selectPin = ({ settings }: RootState) => settings.pin

export const selectBitcoin = ({ settings }: RootState) => settings.bitcoin

Expand Down
3 changes: 0 additions & 3 deletions src/redux/slices/settingsSlice/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ export interface Bitcoin {
}

export interface SettingsSlice {
keysExist: boolean
isFirstLaunch: boolean
isSetup: boolean
requests: RequestWithBitcoin[]
topColor: ColorValue
Expand All @@ -84,7 +82,6 @@ export interface SettingsSlice {
previouslyUnlocked: boolean
fullscreen: boolean
hideBalance: boolean
pin: string | null
bitcoin: Bitcoin | null
usedBitcoinAddresses: { [key: string]: string }
}
8 changes: 2 additions & 6 deletions src/screens/pinScreen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,8 @@ import {
Typography,
} from 'components/index'
import { useAppDispatch, useAppSelector } from 'store/storeUtils'
import {
selectPin,
setFullscreen,
setPinState,
unlockApp,
} from 'store/slices/settingsSlice'
import { setFullscreen, unlockApp } from 'store/slices/settingsSlice'
import { selectPin, setPinState } from 'store/slices/persistentDataSlice'
import { sharedColors, sharedStyles } from 'shared/constants'
import { castStyle } from 'shared/utils'
import {
Expand Down
2 changes: 1 addition & 1 deletion src/screens/settings/SettingsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ import { castStyle } from 'shared/utils'
import {
selectChainId,
selectChainType,
selectPin,
selectWalletIsDeployed,
} from 'store/slices/settingsSlice'
import { selectPin } from 'store/slices/persistentDataSlice'
import { useAppSelector } from 'store/storeUtils'
import { ChainTypeEnum, chainTypesById } from 'shared/constants/chainConstants'
import { GlobalErrorHandlerContext } from 'components/GlobalErrorHandler/GlobalErrorHandlerContext'
Expand Down

0 comments on commit bdf6376

Please sign in to comment.