dev
dart 113 lines 3.56 KB
Raw
1 import 'dart:io';
2 import 'package:cake_wallet/core/backup_service_v3.dart';
3 import 'package:cake_wallet/core/execution_state.dart';
4 import 'package:cake_wallet/utils/exception_handler.dart';
5 import 'package:flutter/material.dart';
6 import 'package:hive/hive.dart';
7 import 'package:mobx/mobx.dart';
8 import 'package:cake_wallet/main.dart';
9 import 'package:cake_wallet/di.dart';
10 import 'package:cw_core/node.dart';
11 import 'package:cake_wallet/store/app_store.dart';
12 import 'package:cake_wallet/store/authentication_store.dart';
13
14 part 'restore_from_backup_view_model.g.dart';
15
16 class RestoreFromBackupViewModel = RestoreFromBackupViewModelBase with _$RestoreFromBackupViewModel;
17
18 abstract class RestoreFromBackupViewModelBase with Store {
19 RestoreFromBackupViewModelBase(this.backupService)
20 : state = InitialExecutionState(),
21 filePath = '';
22
23 final BackupServiceV3 backupService;
24
25 @observable
26 String filePath;
27
28 @observable
29 ExecutionState state;
30
31 @action
32 void reset() => filePath = '';
33
34 @action
35 Future<void> import(String password, {bool checkBackupApp = true}) async {
36 try {
37 state = IsExecutingState();
38
39 if (filePath.isEmpty) {
40 state = FailureState('Backup file is not selected.');
41 return;
42 }
43
44 final file = File(filePath);
45
46 try {
47 await backupService.importBackupFile(file, password, checkBackupApp: checkBackupApp);
48 } on IncompatibleBackupAppException {
49 rethrow;
50 } catch (e, s) {
51 if (e.toString().contains("unknown_backup_version")) {
52 state = FailureState(
53 'This is not a valid backup file, please make sure you have selected the correct one');
54 } else {
55 state = FailureState(e.toString() + "\n" + s.toString());
56 }
57 }
58
59 try {
60 await initializeAppAtRoot(reInitializing: true);
61 } catch (e, s) {
62 state = FailureState('Failed app initialization, please try again');
63 ExceptionHandler.onError(FlutterErrorDetails(exception: e, stack: s, silent: true));
64 }
65
66 final store = getIt.get<AppStore>();
67 ReactionDisposer? reaction;
68 await store.settingsStore.reload();
69 await store.themeStore.loadSavedTheme(isFromBackup: true);
70 reaction = autorun((_) {
71 final wallet = store.wallet;
72
73 if (wallet != null) {
74 store.authenticationStore.state = AuthenticationState.allowed;
75 reaction?.reaction.dispose();
76 }
77 });
78
79 state = ExecutedSuccessfullyState();
80 } on IncompatibleBackupAppException {
81 state = InitialExecutionState();
82 rethrow;
83 } catch (e, s) {
84 var msg = e.toString().toLowerCase();
85
86 // can't use a switch here because of .contains() / not an exact match
87 bool shouldBeMadeAware = false;
88 if (msg.contains("message authentication code (mac)")) {
89 msg = 'Incorrect backup password';
90 } else if (msg.contains("faileddecryption")) {
91 msg = 'Failed to decrypt backup file, please check you entered the right password';
92 } else if (msg.contains("failed_to_decode")) {
93 msg = 'Failed to decode backup file, please try again';
94 shouldBeMadeAware = true;
95 } else if (msg.contains("failed_app_initialization")) {
96 msg = 'Failed to initialize app, please try again';
97 shouldBeMadeAware = true;
98 } else {
99 shouldBeMadeAware = true;
100 }
101
102 if (shouldBeMadeAware) {
103 await ExceptionHandler.onError(FlutterErrorDetails(
104 exception: e,
105 stack: s,
106 library: this.toString(),
107 ));
108 }
109
110 state = FailureState(msg);
111 }
112 }
113 }