2
3
import 'package:cake_wallet/core/generate_wallet_password.dart';
4
import 'package:cake_wallet/core/key_service.dart';
5
+import 'package:cake_wallet/core/secure_storage.dart';
6
import 'package:cake_wallet/entities/preferences_key.dart';
7
+import 'package:cake_wallet/generated/i18n.dart';
8
+import 'package:cake_wallet/main.dart';
9
import 'package:cake_wallet/reactions/on_authentication_state_change.dart';
10
+import 'package:cake_wallet/src/screens/auth/auth_page.dart';
11
+import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
12
import 'package:cake_wallet/utils/exception_handler.dart';
13
+import 'package:cake_wallet/utils/show_pop_up.dart';
14
import 'package:cw_core/cake_hive.dart';
15
import 'package:cw_core/wallet_base.dart';
16
import 'package:cw_core/wallet_info.dart';
17
import 'package:cw_core/wallet_service.dart';
18
import 'package:cw_core/wallet_type.dart';
19
import 'package:flutter/material.dart';
20
+import 'package:flutter/services.dart';
21
import 'package:shared_preferences/shared_preferences.dart';
22
23
class WalletLoadingService {
65
66
return wallet;
67
} catch (error, stack) {
61
- ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
68
+ await ExceptionHandler.resetLastPopupDate();
69
+ await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack));
70
71
// try fetching the seeds of the corrupted wallet to show it to the user
72
String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):";
73
try {
74
corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type);
75
} catch (e) {
68
- corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
76
+ corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
77
}
78
79
// try opening another wallet that is not corrupted to give user access to the app
80
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
73
-
81
+ WalletBase? wallet;
82
for (var walletInfo in walletInfoSource.values) {
83
try {
84
final walletService = walletServiceFactory.call(walletInfo.type);
77
- final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
78
- final wallet = await walletService.openWallet(walletInfo.name, walletPassword);
85
+ final walletPassword = await keyService.getWalletPassword(walletName: walletInfo.name);
86
+ wallet = await walletService.openWallet(walletInfo.name, walletPassword);
87
88
if (walletInfo.type == WalletType.monero) {
89
await updateMoneroWalletPassword(wallet);
96
97
// if found a wallet that is not corrupted, then still display the seeds of the corrupted ones
98
authenticatedErrorStreamController.add(corruptedWalletsSeeds);
91
-
92
- return wallet;
99
} catch (e) {
100
print(e);
101
// save seeds and show corrupted wallets' seeds to the user
105
corruptedWalletsSeeds += seeds;
106
}
107
} catch (e) {
102
- corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
108
+ corruptedWalletsSeeds += "\nFailed to fetch $name seeds: $e";
109
}
110
}
111
}
112
113
// if all user's wallets are corrupted throw exception
108
- throw error.toString() + "\n\n" + corruptedWalletsSeeds;
114
+ final msg = error.toString() + "\n" + corruptedWalletsSeeds;
115
+ if (navigatorKey.currentContext != null) {
116
+ await showPopUp<void>(
117
+ context: navigatorKey.currentContext!,
118
+ builder: (BuildContext context) {
119
+ return AlertWithTwoActions(
120
+ alertTitle: "Corrupted seeds",
121
+ alertContent: S.of(context).corrupted_seed_notice,
122
+ leftButtonText: S.of(context).cancel,
123
+ rightButtonText: S.of(context).show_seed,
124
+ actionLeftButton: () => Navigator.of(context).pop(),
125
+ actionRightButton: () => showSeedsPopup(context, msg),
126
+ );
127
+ });
128
+ } else {
129
+ throw msg;
130
+ }
131
+ if (wallet == null) {
132
+ throw Exception("Wallet is null");
133
+ }
134
+ return wallet;
135
}
136
}
137
138
+ Future<void> showSeedsPopup(BuildContext context, String message) async {
139
+ Navigator.of(context).pop();
140
+ await showPopUp<void>(
141
+ context: context,
142
+ builder: (BuildContext context) {
143
+ return AlertWithTwoActions(
144
+ alertTitle: "Corrupted seeds",
145
+ alertContent: message,
146
+ leftButtonText: S.of(context).copy,
147
+ rightButtonText: S.of(context).ok,
148
+ actionLeftButton: () async {
149
+ await Clipboard.setData(ClipboardData(text: message));
150
+ },
151
+ actionRightButton: () async {
152
+ Navigator.of(context).pop();
153
+ },
154
+ );
155
+ });
156
+ }
157
+
158
Future<void> updateMoneroWalletPassword(WalletBase wallet) async {
159
final key = PreferencesKey.moneroWalletUpdateV1Key(wallet.name);
160
var isPasswordUpdated = sharedPreferences.getBool(key) ?? false;