From 8b0aa6712b62fce04c92e3ee688462666a9d7f66 Mon Sep 17 00:00:00 2001 From: minibits-cash Date: Fri, 31 Jan 2025 13:25:06 +0100 Subject: [PATCH] Improve UX of seed recovery process --- package.json | 2 +- src/i18n_messages/en.json | 1 + src/models/WalletStore.ts | 2 +- src/screens/ImportBackupScreen.tsx | 4 +- src/screens/MintsScreen.tsx | 7 +- src/screens/SeedRecoveryScreen.tsx | 147 +++++++++++------------------ 6 files changed, 65 insertions(+), 98 deletions(-) diff --git a/package.json b/package.json index 53aa662f..614d735e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "minibits_wallet", - "version": "0.1.11-beta.6", + "version": "0.1.11-beta.7", "private": true, "scripts": { "android:clean": "cd android && ./gradlew clean", diff --git a/src/i18n_messages/en.json b/src/i18n_messages/en.json index d2724b1d..e068c92e 100644 --- a/src/i18n_messages/en.json +++ b/src/i18n_messages/en.json @@ -42,6 +42,7 @@ "change": "Change", "close": "Close", "complete": "Complete", + "completed": "Completed", "confirm": "Confirm", "confirmAlertTitle": "Confirmation", "confirmCreateInvoice": "Create invoice", diff --git a/src/models/WalletStore.ts b/src/models/WalletStore.ts index cdaea019..1abcf717 100644 --- a/src/models/WalletStore.ts +++ b/src/models/WalletStore.ts @@ -176,7 +176,7 @@ export const WalletStoreModel = types if (!keys) { throw new AppError( - Err.VALIDATION_ERROR, + Err.NOTFOUND_ERROR, 'Device secure storage could not return wallet keys, please reinstall and use your seed phrase to recover wallet.' ) } diff --git a/src/screens/ImportBackupScreen.tsx b/src/screens/ImportBackupScreen.tsx index 8dbe016f..255efbc2 100644 --- a/src/screens/ImportBackupScreen.tsx +++ b/src/screens/ImportBackupScreen.tsx @@ -91,7 +91,7 @@ export const ImportBackupScreen: FC> = obser if(existing && existing.SEED.mnemonic) { setMnemonicExists(true) } - } catch (e: any) { + } catch (e: any) { handleError(e) } } @@ -502,7 +502,7 @@ export const ImportBackupScreen: FC> = obser )} {error && } {info && } - {isLoading && } + {isLoading && } ) } diff --git a/src/screens/MintsScreen.tsx b/src/screens/MintsScreen.tsx index d5f495b9..0e386c09 100644 --- a/src/screens/MintsScreen.tsx +++ b/src/screens/MintsScreen.tsx @@ -68,7 +68,12 @@ export const MintsScreen: FC> = observer( } const toggleMintMenuModal = () => setIsMintMenuVisible(previousState => !previousState) - const toggleShareModal = () => setIsShareModalVisible(previousState => !previousState) + const toggleShareModal = () => { + if(isShareModalVisible) { + setSelectedMint(undefined) + } + setIsShareModalVisible(previousState => !previousState) + } const pasteMintUrl = async () => { const url = await Clipboard.getString() diff --git a/src/screens/SeedRecoveryScreen.tsx b/src/screens/SeedRecoveryScreen.tsx index 58855cef..169e9bce 100644 --- a/src/screens/SeedRecoveryScreen.tsx +++ b/src/screens/SeedRecoveryScreen.tsx @@ -18,6 +18,7 @@ import { BottomModal, Button, $sizeStyles, + Header, } from '../components' import {useHeader} from '../utils/useHeader' import AppError, { Err } from '../utils/AppError' @@ -41,6 +42,7 @@ import { MintUnit, formatCurrency, getCurrency } from '../services/wallet/curren import { isObj } from '@cashu/cashu-ts/src/utils' import { translate } from '../i18n' import { WalletProfileRecord } from '../models/WalletProfileStore' +import { MnemonicInput } from './Recovery/MnemonicInput' if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true) @@ -50,13 +52,6 @@ const RESTORE_INDEX_INTERVAL = 50 export const SeedRecoveryScreen: FC> = observer(function SeedRecoveryScreen(_props) { const {navigation, route} = _props - useHeader({ - leftIcon: 'faArrowLeft', - onLeftPress: () => { - navigation.goBack() - }, - }) - const { mintsStore, proofsStore, @@ -88,6 +83,7 @@ export const SeedRecoveryScreen: FC> = obser const [isErrorsModalVisible, setIsErrorsModalVisible] = useState(false) const [isIndexModalVisible, setIsIndexModalVisible] = useState(false) const [isKeysetModalVisible, setIsKeysetModalVisible] = useState(false) + const [isRecoveryStarted, setIsRecoveryStarted] = useState(false) const [resultModalInfo, setResultModalInfo] = useState<{status: TransactionStatus, message: string} | undefined>() const [isResultModalVisible, setIsResultModalVisible] = useState(false) const [lastRecoveredAmount, setLastRecoveredAmount] = useState(0) @@ -97,15 +93,12 @@ export const SeedRecoveryScreen: FC> = obser useEffect(() => { const getMnemonic = async () => { - try { - setIsLoading(true) - const existing = await walletStore.getCachedMnenomic() - - if(existing) { + try { + const existing = await KeyChain.getWalletKeys() + if(existing && existing.SEED.mnemonic) { setMnemonicExists(true) - } - setIsLoading(false) - } catch (e: any) { + } + } catch (e: any) { handleError(e) } } @@ -233,6 +226,8 @@ export const SeedRecoveryScreen: FC> = obser setInfo(translate("recovery.selectMintFrom")) return } + + setIsRecoveryStarted(true) setStatusMessage(translate("recovery.starting")) setIsLoading(true) setTimeout(() => doRecovery(), 100) @@ -567,6 +562,10 @@ export const SeedRecoveryScreen: FC> = obser if(mnemonicExists) { return ( +
navigation.goBack()} + /> @@ -599,31 +598,36 @@ export const SeedRecoveryScreen: FC> = obser } else { return ( + {isRecoveryStarted ? ( +
+ ) : ( +
navigation.goBack()} + /> + )} - + + <> - {isValidMnemonic ? ( - <> - } - style={$item} - /> - } - /> + {isValidMnemonic && ( + 0 ? undefined : "recoveryFromMintsDesc"} LeftComponent={} RightComponent={mintsStore.mintCount > 0 ? ( @@ -654,6 +658,7 @@ export const SeedRecoveryScreen: FC> = obser key={mint.mintUrl} mint={mint} mintBalance={proofsStore.getMintBalance(mint.mintUrl)} + selectedUnit={selectedKeyset?.unit as MintUnit} onMintSelect={() => onMintSelect(mint)} isSelectable={true} isSelected={selectedMintUrl === mint.mintUrl} @@ -677,29 +682,29 @@ export const SeedRecoveryScreen: FC> = obser {(startIndex > 0 || totalRecoveredAmount > 0) && (