diff --git a/stores/ChannelBackupStore.ts b/stores/ChannelBackupStore.ts index 73ff10550..f0c7ae7af 100644 --- a/stores/ChannelBackupStore.ts +++ b/stores/ChannelBackupStore.ts @@ -16,6 +16,7 @@ import { import BackendUtils from '../utils/BackendUtils'; import { LndMobileEventEmitter } from '../utils/LndMobileUtils'; import Base64Utils from '../utils/Base64Utils'; +import { errorToUserFriendly } from '../utils/ErrorUtils'; const BACKUPS_HOST = 'https://backups.lnolymp.us'; @@ -24,6 +25,7 @@ export default class ChannelBackupStore { @observable public backups: Array = []; @observable public loading: boolean = false; @observable public error: boolean = false; + @observable public error_msg: string; nodeInfoStore: NodeInfoStore; settingsStore: SettingsStore; @@ -36,6 +38,9 @@ export default class ChannelBackupStore { @action public reset = () => { this.channelEventsSubscription = null; + this.error_msg = ''; + this.error = false; + this.loading = false; }; logBackupStatus = async (status: string) => { @@ -195,16 +200,33 @@ export default class ChannelBackupStore { }; @action - public triggerRecovery = async (backup: string) => { - const decryptedBytes = CryptoJS.AES.decrypt( - backup, - this.settingsStore.seedPhrase.toString() - ); - const decryptedString = decryptedBytes.toString(CryptoJS.enc.Utf8); + public triggerRecovery = async (backup: string): Promise => { + this.error_msg = ''; + this.loading = true; + + return await new Promise(async (resolve, reject) => { + try { + const decryptedBytes = CryptoJS.AES.decrypt( + backup, + this.settingsStore.seedPhrase.toString() + ); + const decryptedString = decryptedBytes.toString( + CryptoJS.enc.Utf8 + ); - await restoreChannelBackups(decryptedString); + await restoreChannelBackups(decryptedString); - return; + this.error_msg = ''; + this.loading = false; + + resolve(); + } catch (e: any) { + this.error_msg = errorToUserFriendly(e); + this.loading = false; + + reject(new Error(this.error_msg)); + } + }); }; @action diff --git a/views/Settings/EmbeddedNode/DisasterRecoveryAdvanced.tsx b/views/Settings/EmbeddedNode/DisasterRecoveryAdvanced.tsx index 4e7e84544..984981871 100644 --- a/views/Settings/EmbeddedNode/DisasterRecoveryAdvanced.tsx +++ b/views/Settings/EmbeddedNode/DisasterRecoveryAdvanced.tsx @@ -6,14 +6,15 @@ import moment from 'moment'; import { StackNavigationProp } from '@react-navigation/stack'; import Button from '../../../components/Button'; -import Screen from '../../../components/Screen'; import Header from '../../../components/Header'; +import LoadingIndicator from '../../../components/LoadingIndicator'; +import Screen from '../../../components/Screen'; +import { ErrorMessage } from '../../../components/SuccessErrorMessage'; import ChannelBackupStore from '../../../stores/ChannelBackupStore'; import { localeString } from '../../../utils/LocaleUtils'; import { themeColor } from '../../../utils/ThemeUtils'; -import LoadingIndicator from '../../../components/LoadingIndicator'; interface DisasterRecoveryAdvancedProps { navigation: StackNavigationProp; @@ -35,7 +36,9 @@ export default class DisasterRecoveryAdvanced extends React.Component< }; UNSAFE_componentWillMount(): void { - this.props.ChannelBackupStore.advancedRecoveryList(); + const { ChannelBackupStore } = this.props; + ChannelBackupStore.reset(); + ChannelBackupStore.advancedRecoveryList(); } render() { @@ -46,7 +49,8 @@ export default class DisasterRecoveryAdvanced extends React.Component< triggerRecovery, backups, loading, - error + error, + error_msg } = ChannelBackupStore; const noneSelected = Object.keys(selected).length === 0; @@ -110,15 +114,20 @@ export default class DisasterRecoveryAdvanced extends React.Component< disabled={noneSelected} onPress={async () => { if (selected.backup) { - await triggerRecovery( - selected.backup - ); - navigation.popTo('Wallet'); + try { + await triggerRecovery( + selected.backup + ); + navigation.popTo('Wallet'); + } catch (e) {} } }} /> )} + {!loading && error_msg && ( + + )} {!loading && backups.length > 0 && (