diff --git a/src/context/WalletProvider/NativeWallet/components/NativeCreate.tsx b/src/context/WalletProvider/NativeWallet/components/NativeCreate.tsx index 8bc00179877..f6b859286b9 100644 --- a/src/context/WalletProvider/NativeWallet/components/NativeCreate.tsx +++ b/src/context/WalletProvider/NativeWallet/components/NativeCreate.tsx @@ -4,7 +4,6 @@ import { AlertIcon, Button, Code, - Link, ModalBody, ModalFooter, ModalHeader, @@ -13,11 +12,10 @@ import { } from '@chakra-ui/react' import { Default } from '@shapeshiftoss/hdwallet-native/dist/crypto/isolation/engines' import type { Vault } from '@shapeshiftoss/hdwallet-native-vault' +import { useQuery } from '@tanstack/react-query' import { range } from 'lodash' -import type { ReactNode } from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { FaEye } from 'react-icons/fa' -import { useTranslate } from 'react-polyglot' import { useHistory, useLocation } from 'react-router-dom' import { Text } from 'components/Text' import { NativeWalletRoutes } from 'context/WalletProvider/types' @@ -43,18 +41,24 @@ export const NativeCreate = () => { const history = useHistory() const location = useLocation() const [revealed, setRevealed] = useState(false) - const translate = useTranslate() const mixpanel = getMixPanel() const revealedOnce = useRef(false) const handleShow = useCallback(() => { revealedOnce.current = true setRevealed(!revealed) }, [revealed]) - const [vault, setVault] = useState(null) - const [words, setWords] = useState(null) - const [revoker] = useState(new (Revocable(class {}))()) - const isLegacyWallet = !!location.state?.vault + const revokerRef = useRef(new (Revocable(class {}))()) + const initiatedWordsRef = useRef(false) + + const { data: vault } = useQuery({ + queryKey: ['native-create-vault', location.state?.vault], + queryFn: async () => { + return location.state?.vault ?? (await getVault()) + }, + staleTime: Infinity, + gcTime: Infinity, + }) const placeholders = useMemo(() => { return range(1, 13).map(i => ( @@ -76,75 +80,57 @@ export const NativeCreate = () => { if (vault) { history.push(NativeWalletRoutes.CreateTest, { vault, - isLegacyWallet, }) mixpanel?.track(MixPanelEvent.NativeCreate) } - }, [history, isLegacyWallet, mixpanel, vault]) + }, [history, mixpanel, vault]) - useEffect(() => { - ;(async () => { - try { - // If the vault is already passed from the legacy wallet flow, use it. - const vault = isLegacyWallet ? location.state.vault : await getVault() - setVault(vault) - } catch (e) { - console.error(e) - } - })() - }, [setVault, location.state?.vault, isLegacyWallet]) + const { data: words } = useQuery({ + queryKey: ['native-create-words', vault], + queryFn: async () => { + if (!vault) return [] - useEffect(() => { - if (!vault) return - ;(async () => { - try { - setWords( - (await vault.unwrap().get('#mnemonic')).split(' ').map((word: string, index: number) => - revocable( - - {index + 1} - {word} - , - revoker.addRevoker.bind(revocable), - ), - ), - ) - } catch (e) { - console.error(e) - setWords(null) - } - })() + revokerRef.current?.revoke() + revokerRef.current = new (Revocable(class {}))() + + const mnemonic = await vault.unwrap().get('#mnemonic') + + initiatedWordsRef.current = true + return mnemonic.split(' ').map((word: string, index: number) => + revocable( + + {index + 1} + {word} + , + revokerRef.current.addRevoker.bind(revokerRef.current), + ), + ) + }, + enabled: !!vault, + staleTime: 0, + gcTime: 0, + }) + + useEffect(() => { return () => { - revoker.revoke() + if (initiatedWordsRef.current) { + revokerRef.current?.revoke() + initiatedWordsRef.current = false + } } - }, [setWords, vault, revoker]) + }, []) return ( <> - {isLegacyWallet && ( - - - - - - {translate('walletProvider.shapeShift.legacy.learnMore')} - - - - )} diff --git a/src/context/WalletProvider/NativeWallet/components/NativeLegacySuccess.tsx b/src/context/WalletProvider/NativeWallet/components/NativeLegacySuccess.tsx index 58dfbdb5af3..4cbb1ea4ca1 100644 --- a/src/context/WalletProvider/NativeWallet/components/NativeLegacySuccess.tsx +++ b/src/context/WalletProvider/NativeWallet/components/NativeLegacySuccess.tsx @@ -1,16 +1,18 @@ -import type { Vault } from '@shapeshiftoss/hdwallet-native-vault' import { useCallback } from 'react' import { useHistory, useLocation } from 'react-router-dom' import { NativeWalletRoutes } from 'context/WalletProvider/types' +import type { LocationState } from '../types' import { LegacyLoginSuccess } from './LegacyMigration/LegacyLoginSuccess' export const NativeLegacySuccess = () => { - const history = useHistory<{ vault: Vault }>() - const location = useLocation<{ vault: Vault }>() + const history = useHistory() + const location = useLocation() const handleContinue = useCallback(() => { - history.push(NativeWalletRoutes.Create, location.state) + history.push(NativeWalletRoutes.Create, { + vault: location.state.vault, + }) }, [history, location.state]) return diff --git a/src/context/WalletProvider/NativeWallet/components/NativeTestPhrase.tsx b/src/context/WalletProvider/NativeWallet/components/NativeTestPhrase.tsx index 57a7316731b..e59f6129336 100644 --- a/src/context/WalletProvider/NativeWallet/components/NativeTestPhrase.tsx +++ b/src/context/WalletProvider/NativeWallet/components/NativeTestPhrase.tsx @@ -1,8 +1,6 @@ import { Box, Button, - Checkbox, - Divider, Flex, Icon, ModalBody, @@ -44,7 +42,6 @@ export const NativeTestPhrase = ({ history, location }: NativeSetupProps) => { const borderColor = useColorModeValue('gray.300', 'whiteAlpha.200') const dottedTitleBackground = useColorModeValue('#f7fafc', '#2e3236') const [testState, setTestState] = useState(null) - const [hasAlreadySaved, setHasAlreadySaved] = useState(false) const testCount = useRef(0) const [revoker] = useState(new (Revocable(class {}))()) const [shuffledNumbers] = useState(slice(shuffle(range(12)), 0, TEST_COUNT_REQUIRED)) @@ -69,13 +66,7 @@ export const NativeTestPhrase = ({ history, location }: NativeSetupProps) => { [borderColor], ) - const onCheck = useCallback((e: React.ChangeEvent) => { - // Check the captcha in case the captcha has been validated - setHasAlreadySaved(e.target.checked) - return - }, []) - - const { vault, isLegacyWallet } = location.state + const { vault } = location.state const shuffleMnemonic = useCallback(async () => { if (testCount.current >= TEST_COUNT_REQUIRED) return @@ -135,11 +126,6 @@ export const NativeTestPhrase = ({ history, location }: NativeSetupProps) => { } } - const handleSkipClick = useCallback( - () => history.push('/native/password', { vault }), - [history, vault], - ) - return !testState ? null : ( <> @@ -233,37 +219,6 @@ export const NativeTestPhrase = ({ history, location }: NativeSetupProps) => { ))} - - {isLegacyWallet && ( - - - - - - - - - - - )} ) diff --git a/src/context/WalletProvider/NativeWallet/types.ts b/src/context/WalletProvider/NativeWallet/types.ts index 491d952c0c0..122248c980a 100644 --- a/src/context/WalletProvider/NativeWallet/types.ts +++ b/src/context/WalletProvider/NativeWallet/types.ts @@ -14,7 +14,6 @@ export type NativeWalletValues = { export interface LocationState { vault: Vault - isLegacyWallet?: boolean error?: { message: string } diff --git a/src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx b/src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx index 165cded1710..88ccae9052d 100644 --- a/src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx +++ b/src/context/WalletProvider/NewWalletViews/NewWalletViewsSwitch.tsx @@ -18,13 +18,14 @@ import { useTranslate } from 'react-polyglot' import { reactQueries } from 'react-queries' import type { StaticContext } from 'react-router' import type { RouteComponentProps } from 'react-router-dom' -import { Route, Switch, useHistory } from 'react-router-dom' +import { Route, Switch, useHistory, useLocation } from 'react-router-dom' import { Text } from 'components/Text' import { WalletActions } from 'context/WalletProvider/actions' import { KeepKeyRoutes as KeepKeyRoutesEnum } from 'context/WalletProvider/routes' import { useWallet } from 'hooks/useWallet/useWallet' import type { KeyManager } from '../KeyManager' +import type { LocationState } from '../NativeWallet/types' import { NativeWalletRoutes } from '../types' import { RDNS_TO_FIRST_CLASS_KEYMANAGER } from './constants' import { KeepKeyRoutes } from './routes/KeepKeyRoutes' @@ -96,6 +97,7 @@ export const NewWalletViewsSwitch = () => { const [selectedWalletId, setSelectedWalletId] = useState(null) const history = useHistory() + const location = useLocation() const toast = useToast() const translate = useTranslate() const { @@ -129,15 +131,29 @@ export const NewWalletViewsSwitch = () => { }, [toast, translate, wallet]) const handleBack = useCallback(async () => { - history.goBack() + const { pathname } = history.location + + if (location.state?.vault && pathname === NativeWalletRoutes.CreateTest) { + history.replace({ + pathname: NativeWalletRoutes.Create, + state: { vault: location.state.vault }, + }) + + // Queue navigation in the next tick to ensure state is updated + setTimeout(() => { + history.goBack() + }, 0) + } else { + history.goBack() + } + // If we're back at the select wallet modal, remove the initial route // otherwise clicking the button for the same wallet doesn't do anything - const { pathname } = history.location if ([INITIAL_WALLET_MODAL_ROUTE, NativeWalletRoutes.Load].includes(pathname)) { dispatch({ type: WalletActions.SET_INITIAL_ROUTE, payload: '' }) } await cancelWalletRequests() - }, [cancelWalletRequests, dispatch, history]) + }, [cancelWalletRequests, dispatch, history, location.state]) const handleRouteReset = useCallback(() => { history.replace(INITIAL_WALLET_MODAL_ROUTE)