Generic fixes (#1154)

* Fix White screen issue Bypass node certificate issue * check on Fiat currency only with fiat templates * Add possible missing cache file android error * Dispose exchange state reaction when page is closed * Fix minor chinese translation * Temp remove BCH from robinhood * Minor fixes

Omar Hatem committed Nov 3, 2023 at 21:24 UTC 37c2ee9e9ec9c8db5d913846c9610b7588b42b3e
10 files changed +93 -72
cw_core/lib/node.dart
+3
@@ -162,6 +162,9 @@ class Node extends HiveObject with Keyable {
162 try {
163 final authenticatingClient = HttpClient();
164
165 + authenticatingClient.badCertificateCallback =
166 + ((X509Certificate cert, String host, int port) => true);
167 +
168 authenticatingClient.addCredentials(
169 rpcUri,
170 realm,
cw_monero/lib/monero_wallet_service.dart
+12 -3
@@ -57,7 +57,7 @@ class MoneroWalletService extends WalletService<
57
58 final Box<WalletInfo> walletInfoSource;
59 final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
60 -
60 +
61 static bool walletFilesExist(String path) =>
62 !File(path).existsSync() && !File('$path.keys').existsSync();
63
@@ -135,9 +135,18 @@ class MoneroWalletService extends WalletService<
135 (e is WalletOpeningException && e.message.contains('basic_string'));
136
137 final bool isMissingCacheFilesAndroid = e.toString().contains('input_stream') ||
138 - (e is WalletOpeningException && e.message.contains('input_stream'));
138 + e.toString().contains('input stream error') ||
139 + (e is WalletOpeningException &&
140 + (e.message.contains('input_stream') || e.message.contains('input stream error')));
141 +
142 + final bool invalidSignature = e.toString().contains('invalid signature') ||
143 + (e is WalletOpeningException && e.message.contains('invalid signature'));
144
140 - if (isBadAlloc || doesNotCorrespond || isMissingCacheFilesIOS || isMissingCacheFilesAndroid) {
145 + if (isBadAlloc ||
146 + doesNotCorrespond ||
147 + isMissingCacheFilesIOS ||
148 + isMissingCacheFilesAndroid ||
149 + invalidSignature) {
150 await restoreOrResetWalletFiles(name);
151 return openWallet(name, password);
152 }
ios/Podfile.lock
+2 -2
@@ -283,7 +283,7 @@ SPEC CHECKSUMS:
283 flutter_inappwebview: 3d32228f1304635e7c028b0d4252937730bbc6cf
284 flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83
285 flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
286 - fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
286 + fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
287 in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
288 local_auth_ios: c6cf091ded637a88f24f86a8875d8b0f526e2605
289 MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
@@ -302,7 +302,7 @@ SPEC CHECKSUMS:
302 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
303 uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
304 UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
305 - url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4
305 + url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86
306 wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
307 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
308
lib/buy/robinhood/robinhood_buy_provider.dart
+1 -1
@@ -34,7 +34,7 @@ class RobinhoodBuyProvider {
34 case WalletType.bitcoin:
35 return _wallet.signMessage(message, address: _wallet.walletAddresses.address);
36 default:
37 - throw Exception("WalletType is not available for Robinhood");
37 + throw Exception("WalletType is not available for Robinhood ${_wallet.type}");
38 }
39 }
40
lib/entities/default_settings_migration.dart
+50 -43
@@ -191,63 +191,70 @@ Future<void> defaultSettingsMigration(
191 }
192
193 Future<void> _validateWalletInfoBoxData(Box<WalletInfo> walletInfoSource) async {
194 - final root = await getApplicationDocumentsDirectory();
194 + try {
195 + final root = await getApplicationDocumentsDirectory();
196
196 - for (var type in WalletType.values) {
197 - if (type == WalletType.none) {
198 - continue;
199 - }
197 + for (var type in WalletType.values) {
198 + if (type == WalletType.none) {
199 + continue;
200 + }
201
201 - String prefix = walletTypeToString(type).toLowerCase();
202 - Directory walletsDir = Directory('${root.path}/wallets/$prefix/');
202 + String prefix = walletTypeToString(type).toLowerCase();
203 + Directory walletsDir = Directory('${root.path}/wallets/$prefix/');
204
204 - if (!walletsDir.existsSync()) {
205 - continue;
206 - }
205 + if (!walletsDir.existsSync()) {
206 + continue;
207 + }
208
208 - List<String> walletNames = walletsDir.listSync().map((e) => e.path.split("/").last).toList();
209 + List<String> walletNames = walletsDir.listSync().map((e) => e.path.split("/").last).toList();
210
210 - for (var name in walletNames) {
211 - final dir = Directory(await pathForWalletDir(name: name, type: type));
211 + for (var name in walletNames) {
212 + final Directory dir;
213 + try {
214 + dir = Directory(await pathForWalletDir(name: name, type: type));
215 + } catch (_) {
216 + continue;
217 + }
218
213 - final walletFiles = dir.listSync();
214 - final hasCacheFile = walletFiles.any((element) => element.path.contains("$name/$name"));
219 + final walletFiles = dir.listSync();
220 + final hasCacheFile = walletFiles.any((element) => element.path.contains("$name/$name"));
221
216 - if (!hasCacheFile) {
217 - continue;
218 - }
222 + if (!hasCacheFile) {
223 + continue;
224 + }
225
220 - if (type == WalletType.monero || type == WalletType.haven) {
221 - final hasKeysFile = walletFiles.any((element) => element.path.contains(".keys"));
226 + if (type == WalletType.monero || type == WalletType.haven) {
227 + final hasKeysFile = walletFiles.any((element) => element.path.contains(".keys"));
228
223 - if (!hasKeysFile) {
224 - continue;
229 + if (!hasKeysFile) {
230 + continue;
231 + }
232 }
226 - }
233
228 - final id = prefix + '_' + name;
229 - final exist = walletInfoSource.values.any((el) => el.id == id);
234 + final id = prefix + '_' + name;
235 + final exist = walletInfoSource.values.any((el) => el.id == id);
236
231 - if (exist) {
232 - continue;
233 - }
237 + if (exist) {
238 + continue;
239 + }
240
235 - final walletInfo = WalletInfo.external(
236 - id: id,
237 - type: type,
238 - name: name,
239 - isRecovery: true,
240 - restoreHeight: 0,
241 - date: DateTime.now(),
242 - dirPath: dir.path,
243 - path: '${dir.path}/$name',
244 - address: '',
245 - showIntroCakePayCard: false,
246 - );
247 -
248 - walletInfoSource.add(walletInfo);
241 + final walletInfo = WalletInfo.external(
242 + id: id,
243 + type: type,
244 + name: name,
245 + isRecovery: true,
246 + restoreHeight: 0,
247 + date: DateTime.now(),
248 + dirPath: dir.path,
249 + path: '${dir.path}/$name',
250 + address: '',
251 + showIntroCakePayCard: false,
252 + );
253 +
254 + walletInfoSource.add(walletInfo);
255 + }
256 }
250 - }
257 + } catch (_) {}
258 }
259
260 Future<void> validateBitcoinSavedTransactionPriority(SharedPreferences sharedPreferences) async {
lib/entities/main_actions.dart
+1 -1
@@ -52,7 +52,7 @@ class MainActions {
52 case WalletType.bitcoin:
53 case WalletType.litecoin:
54 case WalletType.ethereum:
55 - case WalletType.bitcoinCash:
55 + // case WalletType.bitcoinCash: // TODO: add sign message function to BCH first
56 switch (defaultBuyProvider) {
57 case BuyProviderType.AskEachTime:
58 Navigator.pushNamed(context, Routes.buy);
lib/src/screens/exchange_trade/exchange_trade_page.dart
+5 -2
@@ -91,6 +91,8 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
91
92 bool _effectsInstalled = false;
93
94 + ReactionDisposer? _exchangeStateReaction;
95 +
96 @override
97 void initState() {
98 super.initState();
@@ -103,8 +105,9 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
105
106 @override
107 void dispose() {
106 - super.dispose();
108 widget.exchangeTradeViewModel.timer?.cancel();
109 + _exchangeStateReaction?.reaction.dispose();
110 + super.dispose();
111 }
112
113 @override
@@ -229,7 +232,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
232 return;
233 }
234
232 - reaction((_) => this.widget.exchangeTradeViewModel.sendViewModel.state,
235 + _exchangeStateReaction = reaction((_) => this.widget.exchangeTradeViewModel.sendViewModel.state,
236 (ExecutionState state) {
237 if (state is FailureState) {
238 WidgetsBinding.instance.addPostFrameCallback((_) {
lib/src/screens/root/root.dart
+1 -2
@@ -13,8 +13,7 @@ import 'package:cake_wallet/store/authentication_store.dart';
13 import 'package:cake_wallet/entities/qr_scanner.dart';
14 import 'package:fluttertoast/fluttertoast.dart';
15 import 'package:uni_links/uni_links.dart';
16 -
17 -import '../setup_2fa/setup_2fa_enter_code_page.dart';
16 +import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
17
18 class Root extends StatefulWidget {
19 Root({
lib/src/screens/send/send_page.dart
+16 -16
@@ -413,39 +413,39 @@ class SendPage extends BasePage {
413 if (context.mounted) {
414 showPopUp<void>(
415 context: context,
416 - builder: (BuildContext context) {
416 + builder: (BuildContext _dialogContext) {
417 return ConfirmSendingAlert(
418 - alertTitle: S.of(context).confirm_sending,
419 - amount: S.of(context).send_amount,
418 + alertTitle: S.of(_dialogContext).confirm_sending,
419 + amount: S.of(_dialogContext).send_amount,
420 amountValue: sendViewModel.pendingTransaction!.amountFormatted,
421 fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
422 - fee: S.of(context).send_fee,
422 + fee: S.of(_dialogContext).send_fee,
423 feeValue: sendViewModel.pendingTransaction!.feeFormatted,
424 feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
425 outputs: sendViewModel.outputs,
426 - rightButtonText: S.of(context).ok,
427 - leftButtonText: S.of(context).cancel,
426 + rightButtonText: S.of(_dialogContext).ok,
427 + leftButtonText: S.of(_dialogContext).cancel,
428 actionRightButton: () {
429 - Navigator.of(context).pop();
429 + Navigator.of(_dialogContext).pop();
430 sendViewModel.commitTransaction();
431 showPopUp<void>(
432 context: context,
433 - builder: (BuildContext context) {
433 + builder: (BuildContext _dialogContext) {
434 return Observer(builder: (_) {
435 final state = sendViewModel.state;
436
437 if (state is FailureState) {
438 - Navigator.of(context).pop();
438 + Navigator.of(_dialogContext).pop();
439 }
440
441 if (state is TransactionCommitted) {
442 return AlertWithOneAction(
443 alertTitle: '',
444 - alertContent: S.of(context).send_success(
444 + alertContent: S.of(_dialogContext).send_success(
445 sendViewModel.selectedCryptoCurrency.toString()),
446 - buttonText: S.of(context).ok,
446 + buttonText: S.of(_dialogContext).ok,
447 buttonAction: () {
448 - Navigator.of(context).pop();
448 + Navigator.of(_dialogContext).pop();
449 RequestReviewHandler.requestReview();
450 });
451 }
@@ -454,7 +454,7 @@ class SendPage extends BasePage {
454 });
455 });
456 },
457 - actionLeftButton: () => Navigator.of(context).pop());
457 + actionLeftButton: () => Navigator.of(_dialogContext).pop());
458 });
459 }
460 });
@@ -472,15 +472,15 @@ class SendPage extends BasePage {
472
473 Future<void> _setInputsFromTemplate(BuildContext context,
474 {required Output output, required Template template}) async {
475 - final fiatFromTemplate =
476 - FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency);
477 -
475 output.address = template.address;
476
477 if (template.isCurrencySelected) {
478 sendViewModel.setSelectedCryptoCurrency(template.cryptoCurrency);
479 output.setCryptoAmount(template.amount);
480 } else {
481 + final fiatFromTemplate =
482 + FiatCurrency.all.singleWhere((element) => element.title == template.fiatCurrency);
483 +
484 sendViewModel.setFiatCurrency(fiatFromTemplate);
485 output.setFiatAmount(template.amountFiat);
486 }
res/values/strings_zh.arb
+2 -2
@@ -64,8 +64,8 @@
64 "powered_by": "Powered by ${title}",
65 "error": "错误",
66 "estimated": "估计值",
67 - "min_value": "最低: ${value} ${currency}",
68 - "max_value": "最高: ${value} ${currency}",
67 + "min_value": "最小: ${value} ${currency}",
68 + "max_value": "最大: ${value} ${currency}",
69 "change_currency": "更改币种",
70 "overwrite_amount": "Overwrite amount",
71 "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",