diff --git a/blue_modules/notifications.js b/blue_modules/notifications.js index 39707eb72..c8cc2a5f7 100644 --- a/blue_modules/notifications.js +++ b/blue_modules/notifications.js @@ -574,6 +574,9 @@ export const isNotificationsEnabled = async () => { return !isDisabledByUser && !!token && !!levels.level_all; } catch (error) { console.log('Error checking notification levels:', error); + if (error instanceof SyntaxError) { + throw error; + } return false; } }; diff --git a/components/Context/StorageProvider.tsx b/components/Context/StorageProvider.tsx index 4fcaaee0e..f92680040 100644 --- a/components/Context/StorageProvider.tsx +++ b/components/Context/StorageProvider.tsx @@ -49,7 +49,7 @@ interface StorageContextType { cachedPassword: typeof BlueApp.cachedPassword; getItem: typeof BlueApp.getItem; setItem: typeof BlueApp.setItem; - handleWalletDeletion: (walletID: string, forceDelete?: boolean) => Promise; + handleWalletDeletion: (walletID: string, forceDelete?: boolean) => Promise; } export enum WalletTransactionsStatus { @@ -101,28 +101,84 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) => }, []); const handleWalletDeletion = useCallback( - async (walletID: string, forceDelete = false) => { + async (walletID: string, forceDelete = false): Promise => { + console.debug(`handleWalletDeletion: invoked for walletID ${walletID}`); const wallet = wallets.find(w => w.getID() === walletID); - if (!wallet) return; + if (!wallet) { + console.warn(`handleWalletDeletion: wallet not found for ${walletID}`); + return false; + } - try { - const isNotificationsSettingsEnabled = await isNotificationsEnabled(); - if (isNotificationsSettingsEnabled) { - const externalAddresses = wallet.getAllExternalAddresses(); - if (externalAddresses.length > 0) { - await unsubscribe(externalAddresses, [], []); - } - } + // Force deletion: if forceDelete is true then delete and return true immediately. + if (forceDelete) { deleteWallet(wallet); saveToDisk(true); triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess); + return true; + } + + let isNotificationsSettingsEnabled = false; + try { + isNotificationsSettingsEnabled = await isNotificationsEnabled(); + } catch (error) { + console.error(`handleWalletDeletion: error checking notifications for wallet ${walletID}`, error); + presentAlert({ + title: loc.errors.error, + message: loc.wallets.details_delete_wallet_error_message, + buttons: [ + { + text: loc.wallets.details_delete_anyway, + onPress: async () => await handleWalletDeletion(walletID, true), + style: 'destructive', + }, + { + text: loc.wallets.list_tryagain, + onPress: async () => await handleWalletDeletion(walletID), + }, + { + text: loc._.cancel, + onPress: () => {}, + style: 'cancel', + }, + ], + options: { cancelable: false }, + }); + return false; + } + + try { + if (isNotificationsSettingsEnabled) { + const externalAddresses = wallet.getAllExternalAddresses(); + if (externalAddresses.length > 0) { + console.debug(`handleWalletDeletion: unsubscribing addresses for wallet ${walletID}`); + try { + await unsubscribe(externalAddresses, [], []); + console.debug(`handleWalletDeletion: unsubscribe succeeded for wallet ${walletID}`); + } catch (unsubscribeError) { + console.error(`handleWalletDeletion: unsubscribe failed for wallet ${walletID}`, unsubscribeError); + presentAlert({ + title: loc.errors.error, + message: loc.wallets.details_delete_wallet_error_message, + buttons: [{ text: loc._.ok, onPress: () => {} }], + options: { cancelable: false }, + }); + return false; + } + } + } + deleteWallet(wallet); + console.debug(`handleWalletDeletion: wallet ${walletID} deleted successfully`); + saveToDisk(true); + triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess); + return true; } catch (e: unknown) { - console.error(e); + console.error(`handleWalletDeletion: encountered error for wallet ${walletID}`, e); triggerHapticFeedback(HapticFeedbackTypes.NotificationError); if (forceDelete) { deleteWallet(wallet); saveToDisk(true); triggerHapticFeedback(HapticFeedbackTypes.NotificationSuccess); + return true; } else { presentAlert({ title: loc.errors.error, @@ -130,12 +186,12 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) => buttons: [ { text: loc.wallets.details_delete_anyway, - onPress: () => handleWalletDeletion(walletID, true), + onPress: async () => await handleWalletDeletion(walletID, true), style: 'destructive', }, { text: loc.wallets.list_tryagain, - onPress: () => handleWalletDeletion(walletID), + onPress: async () => await handleWalletDeletion(walletID), }, { text: loc._.cancel, @@ -145,6 +201,7 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) => ], options: { cancelable: false }, }); + return false; } } }, diff --git a/screen/wallets/ManageWallets.tsx b/screen/wallets/ManageWallets.tsx index 88c07f1bb..6337401a0 100644 --- a/screen/wallets/ManageWallets.tsx +++ b/screen/wallets/ManageWallets.tsx @@ -401,11 +401,8 @@ const ManageWallets: React.FC = () => { text: loc.wallets.details_yes_delete, onPress: async () => { const isBiometricsEnabled = await isBiometricUseCapableAndEnabled(); - - if (isBiometricsEnabled) { - if (!(await unlockWithBiometrics())) { - return; - } + if (isBiometricsEnabled && !(await unlockWithBiometrics())) { + return; } if (wallet.getBalance && wallet.getBalance() > 0 && wallet.allowSend && wallet.allowSend()) { presentWalletHasBalanceAlert(wallet); @@ -413,6 +410,10 @@ const ManageWallets: React.FC = () => { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); dispatch({ type: REMOVE_WALLET, payload: wallet.getID() }); } + const deleted = await handleWalletDeletion(wallet.getID(), true); + if (deleted) { + goBack(); + } }, style: 'destructive', }, @@ -421,7 +422,7 @@ const ManageWallets: React.FC = () => { options: { cancelable: false }, }); }, - [isBiometricUseCapableAndEnabled, presentWalletHasBalanceAlert], + [isBiometricUseCapableAndEnabled, handleWalletDeletion, presentWalletHasBalanceAlert, goBack], ); const handleToggleHideBalance = useCallback( diff --git a/screen/wallets/WalletDetails.tsx b/screen/wallets/WalletDetails.tsx index e4f5f7f6a..cd2a68f45 100644 --- a/screen/wallets/WalletDetails.tsx +++ b/screen/wallets/WalletDetails.tsx @@ -87,9 +87,9 @@ const WalletDetails: React.FC = () => { }, [wallet]); const [isMasterFingerPrintVisible, setIsMasterFingerPrintVisible] = useState(false); - const navigateToOverviewAndDeleteWallet = useCallback(() => { + const navigateToOverviewAndDeleteWallet = useCallback(async () => { setIsLoading(true); - handleWalletDeletion(wallet.getID()); + await handleWalletDeletion(wallet.getID()); popToTop(); }, [handleWalletDeletion, wallet]);