Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

US-1972 RIF Wallet - Android crashes when opening the wallet #801

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
8 changes: 6 additions & 2 deletions src/components/loading/LoadingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { sharedColors, sharedStyles } from 'shared/constants'
import { castStyle } from 'shared/utils'
import { AppSpinner } from 'components/index'

export const LoadingScreen = () => {
interface Props {
isVisible: boolean
}

export const LoadingScreen = ({ isVisible }: Props) => {
return (
<Modal animationType="none" transparent visible>
<Modal animationType="none" transparent visible={isVisible}>
<View
style={[
sharedStyles.flex,
Expand Down
27 changes: 10 additions & 17 deletions src/core/Core.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ import {
RootTabsParamsList,
} from 'navigation/rootNavigator'
import { RequestHandler } from 'src/ux/requestsModal/RequestHandler'
import { LoadingScreen } from 'components/loading/LoadingScreen'
import { useAppDispatch, useAppSelector } from 'store/storeUtils'
import {
closeRequest,
selectRequests,
selectTopColor,
selectWholeSettingsState,
unlockApp,
} from 'store/slices/settingsSlice'
import { sharedStyles } from 'shared/constants'
Expand All @@ -33,11 +31,10 @@ export const navigationContainerRef =

export const Core = () => {
const dispatch = useAppDispatch()
const settings = useAppSelector(selectWholeSettingsState)
const requests = useAppSelector(selectRequests)
const topColor = useAppSelector(selectTopColor)
const isOffline = useIsOffline()
const { unlocked, active } = useStateSubscription()
const { active } = useStateSubscription()
const { wallet, initializeWallet } = useContext(WalletContext)

const unlockAppFn = useCallback(async () => {
Expand All @@ -59,19 +56,15 @@ export const Core = () => {
{!active && <Cover />}
<NavigationContainer ref={navigationContainerRef}>
<WalletConnect2Provider wallet={wallet}>
{settings.loading && !unlocked ? (
<LoadingScreen />
) : (
<>
<RootNavigationComponent />
{requests.length !== 0 && (
<RequestHandler
request={requests[0]}
closeRequest={() => dispatch(closeRequest())}
/>
)}
</>
)}
<>
<RootNavigationComponent />
{requests.length !== 0 && (
<RequestHandler
request={requests[0]}
closeRequest={() => dispatch(closeRequest())}
/>
)}
</>
</WalletConnect2Provider>
</NavigationContainer>
</View>
Expand Down
109 changes: 54 additions & 55 deletions src/navigation/rootNavigator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import BootSplash from 'react-native-bootsplash'
import { CreateKeysNavigation } from 'navigation/createKeysNavigator'
import { ConfirmationModal } from 'components/modal'
import { useAppSelector } from 'store/storeUtils'
import { selectFullscreen, selectIsUnlocked } from 'store/slices/settingsSlice'
import {
selectFullscreen,
selectIsUnlocked,
selectSettingsIsLoading,
} from 'store/slices/settingsSlice'
import { TransactionSummaryScreen } from 'screens/transactionSummary'
import { AppFooterMenu } from 'src/ux/appFooter'
import { sharedStyles } from 'shared/constants'
Expand All @@ -20,6 +24,7 @@ import {
WalletConnectScreenWithProvider,
} from 'screens/index'
import { OfflineScreen } from 'core/components/OfflineScreen'
import { LoadingScreen } from 'components/loading/LoadingScreen'

import { RootTabsParamsList, rootTabsRouteNames } from './types'
import { HomeNavigator } from '../homeNavigator'
Expand All @@ -40,6 +45,7 @@ export const RootNavigationComponent = () => {
const isDeviceRooted = JailMonkey.isJailBroken()
const [isWarningVisible, setIsWarningVisible] = useState(isDeviceRooted)
const unlocked = useAppSelector(selectIsUnlocked)
const settingsLoading = useAppSelector(selectSettingsIsLoading)
const fullscreen = useAppSelector(selectFullscreen)

const isShown = unlocked && !fullscreen
Expand All @@ -52,13 +58,13 @@ export const RootNavigationComponent = () => {
<View style={sharedStyles.flex}>
<RootTabs.Navigator
tabBar={props => (!isShown ? null : <AppFooterMenu {...props} />)}>
{!unlocked ? (
<RootTabs.Screen
name={rootTabsRouteNames.CreateKeysUX}
component={CreateKeysNavigation}
options={screenOptionsNoHeader}
/>
{!unlocked && (
<>
<RootTabs.Screen
name={rootTabsRouteNames.CreateKeysUX}
component={CreateKeysNavigation}
options={screenOptionsNoHeader}
/>
<RootTabs.Screen
name={rootTabsRouteNames.InitialPinScreen}
component={PinScreen}
Expand All @@ -76,55 +82,47 @@ export const RootNavigationComponent = () => {
options={screenOptionsNoHeader}
/>
</>
) : (
<RootTabs.Group>
<RootTabs.Group screenOptions={screenOptionsWithAppHeader}>
<RootTabs.Screen
name={rootTabsRouteNames.Home}
component={HomeNavigator}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Activity}
component={ActivityScreen}
/>
<RootTabs.Screen
name={rootTabsRouteNames.ScanQR}
component={ScanQRScreen}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Contacts}
component={ContactsNavigation}
/>
<RootTabs.Screen
name={rootTabsRouteNames.WalletConnect}
component={WalletConnectScreenWithProvider}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Settings}
component={SettingsNavigator}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Profile}
component={ProfileNavigator}
/>
</RootTabs.Group>
<RootTabs.Group
screenOptions={screenOptionsWithHeader(
top,
t('transaction_summary_screen_title'),
)}>
<RootTabs.Screen
name={rootTabsRouteNames.TransactionSummary}
component={TransactionSummaryScreen}
/>
</RootTabs.Group>
<RootTabs.Screen
name={rootTabsRouteNames.CreateKeysUX}
component={CreateKeysNavigation}
options={screenOptionsNoHeader}
/>
</RootTabs.Group>
)}
<RootTabs.Group screenOptions={screenOptionsWithAppHeader}>
<RootTabs.Screen
name={rootTabsRouteNames.Home}
component={HomeNavigator}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Activity}
component={ActivityScreen}
/>
<RootTabs.Screen
name={rootTabsRouteNames.ScanQR}
component={ScanQRScreen}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Contacts}
component={ContactsNavigation}
/>
<RootTabs.Screen
name={rootTabsRouteNames.WalletConnect}
component={WalletConnectScreenWithProvider}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Settings}
component={SettingsNavigator}
/>
<RootTabs.Screen
name={rootTabsRouteNames.Profile}
component={ProfileNavigator}
/>
</RootTabs.Group>
<RootTabs.Group
screenOptions={screenOptionsWithHeader(
top,
t('transaction_summary_screen_title'),
)}>
<RootTabs.Screen
name={rootTabsRouteNames.TransactionSummary}
component={TransactionSummaryScreen}
/>
</RootTabs.Group>
</RootTabs.Navigator>
<ConfirmationModal
isVisible={isWarningVisible}
Expand All @@ -133,6 +131,7 @@ export const RootNavigationComponent = () => {
okText={t('ok')}
onOk={() => setIsWarningVisible(false)}
/>
<LoadingScreen isVisible={settingsLoading} />
</View>
)
}
Expand Down
122 changes: 54 additions & 68 deletions src/redux/slices/settingsSlice/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,54 @@ import {
UnlockAppAction,
} from './types'

const initializeApp = createAsyncThunk<
void,
{ rifWallet: RIFWallet; mnemonic: string },
AsyncThunkWithTypes
>('settings/initializeApp', async ({ rifWallet, mnemonic }, thunkAPI) => {
try {
const {
usdPrices,
balances,
settings: { chainId },
} = thunkAPI.getState()
// create fetcher
const fetcherInstance = new RifWalletServicesFetcher(
createPublicAxios(chainId),
{
defaultChainId: chainId.toString(),
resultsLimit: 10,
},
)

// connect to sockets
rifSockets({
wallet: rifWallet,
fetcher: fetcherInstance,
dispatch: thunkAPI.dispatch,
setGlobalError: thunkAPI.rejectWithValue,
usdPrices,
chainId,
balances: balances.tokenBalances,
})

socketsEvents.emit(SocketsEvents.CONNECT)

// initialize bitcoin
const bitcoin = initializeBitcoin(
mnemonic,
thunkAPI.dispatch,
fetcherInstance,
chainId,
)

// set bitcoin in redux
thunkAPI.dispatch(setBitcoinState(bitcoin))
} catch (err) {
thunkAPI.rejectWithValue(err)
}
})

export const createWallet = createAsyncThunk<
RIFWallet,
CreateFirstWalletAction,
Expand Down Expand Up @@ -81,43 +129,10 @@ export const createWallet = createAsyncThunk<

thunkAPI.dispatch(setKeysExist(true))

// create fetcher
//@TODO: refactor socket initialization, it repeats several times
thunkAPI.dispatch(setChainId(chainId))

const fetcherInstance = new RifWalletServicesFetcher(
createPublicAxios(chainId),
{
defaultChainId: chainId.toString(),
resultsLimit: 10,
},
)

const { usdPrices, balances } = thunkAPI.getState()

// connect to sockets
rifSockets({
wallet: kms.rifWallet,
fetcher: fetcherInstance,
dispatch: thunkAPI.dispatch,
setGlobalError: thunkAPI.rejectWithValue,
usdPrices,
chainId,
balances: balances.tokenBalances,
})

socketsEvents.emit(SocketsEvents.CONNECT)

// initialize bitcoin
const bitcoin = initializeBitcoin(
mnemonic,
thunkAPI.dispatch,
fetcherInstance,
chainId,
)

// set bitcoin in redux
thunkAPI.dispatch(setBitcoinState(bitcoin))
thunkAPI.dispatch(initializeApp({ rifWallet: kms.rifWallet, mnemonic }))

return kms.rifWallet
} catch (err) {
Expand All @@ -133,6 +148,7 @@ export const unlockApp = createAsyncThunk<
try {
const {
persistentData: { isFirstLaunch },
settings: { chainId },
} = thunkAPI.getState()
// if previously installed the app, remove stored encryted keys
if (isFirstLaunch && !__DEV__) {
Expand All @@ -142,7 +158,6 @@ export const unlockApp = createAsyncThunk<
}

const serializedKeys = await getKeys()
const { chainId } = thunkAPI.getState().settings

if (!serializedKeys) {
// if keys do not exist, set to false
Expand Down Expand Up @@ -203,40 +218,11 @@ export const unlockApp = createAsyncThunk<

thunkAPI.dispatch(setUnlocked(true))

// create fetcher
const fetcherInstance = new RifWalletServicesFetcher(
createPublicAxios(chainId),
{
defaultChainId: chainId.toString(),
resultsLimit: 10,
},
)

const { usdPrices, balances } = thunkAPI.getState()

// connect to sockets
rifSockets({
wallet: rifWallet,
fetcher: fetcherInstance,
dispatch: thunkAPI.dispatch,
setGlobalError: thunkAPI.rejectWithValue,
usdPrices,
chainId,
balances: balances.tokenBalances,
})

socketsEvents.emit(SocketsEvents.CONNECT)
navigationContainerRef.navigate(rootTabsRouteNames.Home)

// initialize bitcoin
const bitcoin = initializeBitcoin(
kms.mnemonic,
thunkAPI.dispatch,
fetcherInstance,
chainId,
)

// set bitcoin in redux
thunkAPI.dispatch(setBitcoinState(bitcoin))
setTimeout(() => {
thunkAPI.dispatch(initializeApp({ rifWallet, mnemonic: kms.mnemonic }))
}, 1000)
return kms
} catch (err) {
return thunkAPI.rejectWithValue(err)
Expand Down
Loading