From a2549b42b04fbce33b77dbf3fcdd4d6e711ac192 Mon Sep 17 00:00:00 2001 From: David Adegoke <64401859+Blazebrain@users.noreply.github.com> Date: Wed, 31 Jul 2024 02:26:56 +0100 Subject: [PATCH 1/7] CW-680: Fix Wakelock Issue (#1557) * chore: Bump up wakelock_plus dependency version * Fix: try fixing ci failure by bumping jdk version --- .github/workflows/pr_test_build.yml | 2 +- pubspec_base.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index f37919e9d..4c46137ac 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -41,7 +41,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-java@v1 with: - java-version: "11.x" + java-version: "17.x" - name: Configure placeholder git details run: | git config --global user.email "CI@cakewallet.com" diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 2cfeae716..67a162674 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -66,7 +66,7 @@ dependencies: url: https://github.com/cake-tech/device_display_brightness.git ref: master workmanager: ^0.5.1 - wakelock_plus: ^1.1.3 + wakelock_plus: ^1.2.5 flutter_mailer: ^2.0.2 device_info_plus: ^9.1.0 base32: 2.1.3 From 9da9bee384588675dda11cf28b58e74d0ac7a030 Mon Sep 17 00:00:00 2001 From: cyan Date: Tue, 6 Aug 2024 13:01:38 +0200 Subject: [PATCH 2/7] make the error more readable when node fails to respond (#1570) --- cw_monero/lib/api/transaction_history.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 5e33c6c56..c28f162be 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -110,7 +110,10 @@ Future createTransactionSync( })(); if (error != null) { - final message = error; + String message = error; + if (message.contains("RPC error")) { + message = "Invalid node response, please try again or switch node\n\ntrace: $message"; + } throw CreationTransactionException(message: message); } From 5e944a8bf7069f0b083f177c44d1b4e5eb1f265e Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Tue, 6 Aug 2024 17:59:44 +0300 Subject: [PATCH 3/7] Try to show seeds if wallet files gets corrupted (#1567) * add litecoin nodes minor ui fix * Try to open the wallet or fetch the seeds and show them to the user * make sure the seeds are only displayed after authentication --- assets/litecoin_electrum_server_list.yml | 17 ++++++- cw_core/lib/wallet_service.dart | 19 +++++++ cw_monero/lib/monero_wallet.dart | 1 - cw_monero/lib/monero_wallet_service.dart | 37 +++++++++++--- lib/core/wallet_loading_service.dart | 31 ++++++++++- lib/di.dart | 14 +++++ .../on_authentication_state_change.dart | 14 +++++ .../monero_account_edit_or_create_page.dart | 4 +- lib/utils/exception_handler.dart | 51 +++++++++++++++++++ 9 files changed, 175 insertions(+), 13 deletions(-) diff --git a/assets/litecoin_electrum_server_list.yml b/assets/litecoin_electrum_server_list.yml index 991762885..550b900e1 100644 --- a/assets/litecoin_electrum_server_list.yml +++ b/assets/litecoin_electrum_server_list.yml @@ -1,4 +1,19 @@ - uri: ltc-electrum.cakewallet.com:50002 useSSL: true - isDefault: true \ No newline at end of file + isDefault: true +- + uri: litecoin.stackwallet.com:20063 + useSSL: true +- + uri: electrum-ltc.bysh.me:50002 + useSSL: true +- + uri: lightweight.fiatfaucet.com:50002 + useSSL: true +- + uri: electrum.ltc.xurious.com:50002 + useSSL: true +- + uri: backup.electrum-ltc.org:443 + useSSL: true diff --git a/cw_core/lib/wallet_service.dart b/cw_core/lib/wallet_service.dart index fcbd59ff3..d90ae30bc 100644 --- a/cw_core/lib/wallet_service.dart +++ b/cw_core/lib/wallet_service.dart @@ -1,6 +1,8 @@ +import 'dart:convert'; import 'dart:io'; import 'package:cw_core/pathForWallet.dart'; +import 'package:cw_core/utils/file.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_credentials.dart'; import 'package:cw_core/wallet_type.dart'; @@ -42,4 +44,21 @@ abstract class WalletService getSeeds(String name, String password, WalletType type) async { + try { + final path = await pathForWallet(name: name, type: type); + final jsonSource = await read(path: path, password: password); + try { + final data = json.decode(jsonSource) as Map; + return data['mnemonic'] as String? ?? ''; + } catch (_) { + // if not a valid json + return jsonSource.substring(0, 200); + } + } catch (_) { + // if the file couldn't be opened or read + return ''; + } + } } diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index 4b596648e..b8e3c2765 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -19,7 +19,6 @@ import 'package:cw_core/transaction_priority.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_info.dart'; -import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/api/coins_info.dart'; import 'package:cw_monero/api/monero_output.dart'; import 'package:cw_monero/api/structs/pending_transaction.dart'; diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index ea2f3b766..3588ebb78 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -57,8 +57,11 @@ class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials { final String spendKey; } -class MoneroWalletService extends WalletService { +class MoneroWalletService extends WalletService< + MoneroNewWalletCredentials, + MoneroRestoreWalletFromSeedCredentials, + MoneroRestoreWalletFromKeysCredentials, + MoneroNewWalletCredentials> { MoneroWalletService(this.walletInfoSource, this.unspentCoinsInfoSource); final Box walletInfoSource; @@ -183,11 +186,8 @@ class MoneroWalletService extends WalletService restoreFromHardwareWallet(MoneroNewWalletCredentials credentials) { - throw UnimplementedError("Restoring a Monero wallet from a hardware wallet is not yet supported!"); + throw UnimplementedError( + "Restoring a Monero wallet from a hardware wallet is not yet supported!"); } @override @@ -350,4 +351,24 @@ class MoneroWalletService extends WalletService getSeeds(String name, String password, WalletType type) async { + try { + final path = await pathForWallet(name: name, type: getType()); + + if (walletFilesExist(path)) { + await repairOldAndroidWallet(name); + } + + await monero_wallet_manager.openWalletAsync({'path': path, 'password': password}); + final walletInfo = walletInfoSource.values + .firstWhere((info) => info.id == WalletBase.idFor(name, getType())); + final wallet = MoneroWallet(walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource); + return wallet.seed; + } catch (_) { + // if the file couldn't be opened or read + return ''; + } + } } diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart index 1f17a7a1c..ca29576e4 100644 --- a/lib/core/wallet_loading_service.dart +++ b/lib/core/wallet_loading_service.dart @@ -1,6 +1,9 @@ +import 'dart:async'; + import 'package:cake_wallet/core/generate_wallet_password.dart'; import 'package:cake_wallet/core/key_service.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; +import 'package:cake_wallet/reactions/on_authentication_state_change.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cw_core/cake_hive.dart'; import 'package:cw_core/wallet_base.dart'; @@ -52,6 +55,12 @@ class WalletLoadingService { } catch (error, stack) { ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); + // try fetching the seeds of the corrupted wallet to show it to the user + String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):"; + try { + corruptedWalletsSeeds += await _getCorruptedWalletSeeds(name, type); + } catch (_) {} + // try opening another wallet that is not corrupted to give user access to the app final walletInfoSource = await CakeHive.openBox(WalletInfo.boxName); @@ -69,12 +78,23 @@ class WalletLoadingService { await sharedPreferences.setInt( PreferencesKey.currentWalletType, serializeToInt(wallet.type)); + // if found a wallet that is not corrupted, then still display the seeds of the corrupted ones + authenticatedErrorStreamController.add(corruptedWalletsSeeds); + return wallet; - } catch (_) {} + } catch (_) { + // save seeds and show corrupted wallets' seeds to the user + try { + final seeds = await _getCorruptedWalletSeeds(walletInfo.name, walletInfo.type); + if (!corruptedWalletsSeeds.contains(seeds)) { + corruptedWalletsSeeds += seeds; + } + } catch (_) {} + } } // if all user's wallets are corrupted throw exception - throw error; + throw error.toString() + "\n\n" + corruptedWalletsSeeds; } } @@ -96,4 +116,11 @@ class WalletLoadingService { isPasswordUpdated = true; await sharedPreferences.setBool(key, isPasswordUpdated); } + + Future _getCorruptedWalletSeeds(String name, WalletType type) async { + final walletService = walletServiceFactory.call(type); + final password = await keyService.getWalletPassword(walletName: name); + + return "\n\n$type ($name): ${await walletService.getSeeds(name, password, type)}"; + } } diff --git a/lib/di.dart b/lib/di.dart index 1462370fc..a37574f21 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -1,3 +1,5 @@ +import 'dart:async' show Timer; + import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/anonpay/anonpay_api.dart'; import 'package:cake_wallet/anonpay/anonpay_info_base.dart'; @@ -487,6 +489,7 @@ Future setup({ if (loginError != null) { authPageState.changeProcessText('ERROR: ${loginError.toString()}'); + loginError = null; } ReactionDisposer? _reaction; @@ -498,6 +501,17 @@ Future setup({ linkViewModel.handleLink(); } }); + + Timer.periodic(Duration(seconds: 1), (timer) { + if (timer.tick > 30) { + timer.cancel(); + } + + if (loginError != null) { + authPageState.changeProcessText('ERROR: ${loginError.toString()}'); + timer.cancel(); + } + }); } }); }); diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart index 5f1214b76..e4fd9b32f 100644 --- a/lib/reactions/on_authentication_state_change.dart +++ b/lib/reactions/on_authentication_state_change.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:flutter/widgets.dart'; @@ -8,9 +10,16 @@ import 'package:cake_wallet/store/authentication_store.dart'; ReactionDisposer? _onAuthenticationStateChange; dynamic loginError; +StreamController authenticatedErrorStreamController = StreamController(); void startAuthenticationStateChange( AuthenticationStore authenticationStore, GlobalKey navigatorKey) { + authenticatedErrorStreamController.stream.listen((event) { + if (authenticationStore.state == AuthenticationState.allowed) { + ExceptionHandler.showError(event.toString(), delayInSeconds: 3); + } + }); + _onAuthenticationStateChange ??= autorun((_) async { final state = authenticationStore.state; @@ -26,6 +35,11 @@ void startAuthenticationStateChange( if (state == AuthenticationState.allowed) { await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false); + if (!(await authenticatedErrorStreamController.stream.isEmpty)) { + ExceptionHandler.showError( + (await authenticatedErrorStreamController.stream.first).toString()); + authenticatedErrorStreamController.stream.drain(); + } return; } }); diff --git a/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart b/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart index 779628be8..2c9918d74 100644 --- a/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart +++ b/lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart @@ -51,7 +51,9 @@ class MoneroAccountEditOrCreatePage extends BasePage { await moneroAccountCreationViewModel.save(); - Navigator.of(context).pop(_textController.text); + if (context.mounted) { + Navigator.of(context).pop(_textController.text); + } }, text: moneroAccountCreationViewModel.isEdit ? S.of(context).rename diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart index b19b1bb7e..6045c0004 100644 --- a/lib/utils/exception_handler.dart +++ b/lib/utils/exception_handler.dart @@ -4,11 +4,13 @@ import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; +import 'package:cake_wallet/utils/show_bar.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cw_core/root_dir.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_mailer/flutter_mailer.dart'; import 'package:cake_wallet/utils/package_info.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -254,4 +256,53 @@ class ExceptionHandler { 'productName': data.productName, }; } + + static void showError(String error, {int? delayInSeconds}) async { + if (_hasError) { + return; + } + _hasError = true; + + if (delayInSeconds != null) { + Future.delayed(Duration(seconds: delayInSeconds), () => _showCopyPopup(error)); + return; + } + + WidgetsBinding.instance.addPostFrameCallback( + (_) async => _showCopyPopup(error), + ); + } + + static Future _showCopyPopup(String content) async { + if (navigatorKey.currentContext != null) { + final shouldCopy = await showPopUp( + context: navigatorKey.currentContext!, + builder: (context) { + return AlertWithTwoActions( + isDividerExist: true, + alertTitle: S.of(context).error, + alertContent: content, + rightButtonText: S.of(context).copy, + leftButtonText: S.of(context).close, + actionRightButton: () { + Navigator.of(context).pop(true); + }, + actionLeftButton: () { + Navigator.of(context).pop(); + }, + ); + }, + ); + + if (shouldCopy == true) { + await Clipboard.setData(ClipboardData(text: content)); + await showBar( + navigatorKey.currentContext!, + S.of(navigatorKey.currentContext!).copied_to_clipboard, + ); + } + } + + _hasError = false; + } } From e58d87e94cc82e268fc5e5901e4bea47c7c4ce50 Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 7 Aug 2024 13:40:31 +0200 Subject: [PATCH 4/7] add card for when monero wallet is in broken state (#1578) --- .../screens/dashboard/pages/balance_page.dart | 14 ++++++++++++++ .../dashboard/dashboard_view_model.dart | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/src/screens/dashboard/pages/balance_page.dart b/lib/src/screens/dashboard/pages/balance_page.dart index d95c19dad..11abdeb58 100644 --- a/lib/src/screens/dashboard/pages/balance_page.dart +++ b/lib/src/screens/dashboard/pages/balance_page.dart @@ -250,6 +250,20 @@ class CryptoBalanceWidget extends StatelessWidget { Observer(builder: (context) { return Column( children: [ + if (dashboardViewModel.isMoneroWalletBrokenReasons.isNotEmpty) ...[ + SizedBox(height: 10), + Padding( + padding: const EdgeInsets.fromLTRB(16, 0, 16, 8), + child: DashBoardRoundedCardWidget( + customBorder: 30, + title: "Monero wallet is broken", + subTitle: "Here are the things that are broken:\n - " + +dashboardViewModel.isMoneroWalletBrokenReasons.join("\n - ") + +"\n\nPlease restart your wallet and if it doesn't help contact our support.", + onTap: () {}, + ) + ) + ], if (dashboardViewModel.showSilentPaymentsCard) ...[ SizedBox(height: 10), Padding( diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 5b5353e06..06c565035 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -335,6 +335,23 @@ abstract class DashboardViewModelBase with Store { wallet.type == WalletType.wownero || wallet.type == WalletType.haven; + @computed + List get isMoneroWalletBrokenReasons { + if (wallet.type != WalletType.monero) return []; + final keys = monero!.getKeys(wallet); + List errors = [ + if (keys['privateSpendKey'] == List.generate(64, (index) => "0").join("")) "Private spend key is 0", + if (keys['privateViewKey'] == List.generate(64, (index) => "0").join("")) "private view key is 0", + if (keys['publicSpendKey'] == List.generate(64, (index) => "0").join("")) "public spend key is 0", + if (keys['publicViewKey'] == List.generate(64, (index) => "0").join("")) "private view key is 0", + if (wallet.seed == null) "wallet seed is null", + if (wallet.seed == "") "wallet seed is empty", + if (monero!.getSubaddressList(wallet).getAll(wallet)[0].address == "41d7FXjswpK1111111111111111111111111111111111111111111111111111111111111111111111111111112KhNi4") + "primary address is invalid, you won't be able to receive / spend funds", + ]; + return errors; + } + @computed bool get hasSilentPayments => wallet.type == WalletType.bitcoin && !wallet.isHardwareWallet; From 96e4a4eb6c41a0a3c541a617073096ef96c1492f Mon Sep 17 00:00:00 2001 From: cyan Date: Wed, 7 Aug 2024 18:12:49 +0200 Subject: [PATCH 5/7] monero fixes (#1581) * correct comparision while syncing * fix issue from report 25916.txt * return proper address even if numSubaddresses returned 0 --- cw_monero/lib/api/subaddress_list.dart | 6 +++++- cw_monero/lib/api/wallet.dart | 2 +- cw_monero/lib/monero_wallet_addresses.dart | 2 +- cw_wownero/lib/api/subaddress_list.dart | 6 +++++- cw_wownero/lib/wownero_wallet_addresses.dart | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cw_monero/lib/api/subaddress_list.dart b/cw_monero/lib/api/subaddress_list.dart index 57edea76e..e5145692d 100644 --- a/cw_monero/lib/api/subaddress_list.dart +++ b/cw_monero/lib/api/subaddress_list.dart @@ -42,12 +42,16 @@ class Subaddress { List getAllSubaddresses() { final size = monero.Wallet_numSubaddresses(wptr!, accountIndex: subaddress!.accountIndex); - return List.generate(size, (index) { + final list = List.generate(size, (index) { return Subaddress( accountIndex: subaddress!.accountIndex, addressIndex: index, ); }).reversed.toList(); + if (list.length == 0) { + list.add(Subaddress(addressIndex: subaddress!.accountIndex, accountIndex: 0)); + } + return list; } void addSubaddressSync({required int accountIndex, required String label}) { diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 6ca9cd1bb..0f6e59c4e 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -131,7 +131,7 @@ void storeSync() async { return monero.Wallet_synchronized(Pointer.fromAddress(addr)); }); if (lastStorePointer == wptr!.address && - lastStoreHeight + 5000 < monero.Wallet_blockChainHeight(wptr!) && + lastStoreHeight + 5000 > monero.Wallet_blockChainHeight(wptr!) && !synchronized) { return; } diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart index f74e7dd5b..d4f22e46f 100644 --- a/cw_monero/lib/monero_wallet_addresses.dart +++ b/cw_monero/lib/monero_wallet_addresses.dart @@ -109,7 +109,7 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store { accountIndex: accountIndex, defaultLabel: defaultLabel, usedAddresses: usedAddresses.toList()); - subaddress = subaddressList.subaddresses.last; + subaddress = (subaddressList.subaddresses.isEmpty) ? Subaddress(id: 0, address: address, label: defaultLabel) : subaddressList.subaddresses.last; address = subaddress!.address; } diff --git a/cw_wownero/lib/api/subaddress_list.dart b/cw_wownero/lib/api/subaddress_list.dart index cec7d94cb..d8c91a584 100644 --- a/cw_wownero/lib/api/subaddress_list.dart +++ b/cw_wownero/lib/api/subaddress_list.dart @@ -41,12 +41,16 @@ class Subaddress { List getAllSubaddresses() { final size = wownero.Wallet_numSubaddresses(wptr!, accountIndex: subaddress!.accountIndex); - return List.generate(size, (index) { + final list = List.generate(size, (index) { return Subaddress( accountIndex: subaddress!.accountIndex, addressIndex: index, ); }).reversed.toList(); + if (list.isEmpty) { + list.add(Subaddress(addressIndex: 0, accountIndex: subaddress!.accountIndex)); + } + return list; } void addSubaddressSync({required int accountIndex, required String label}) { diff --git a/cw_wownero/lib/wownero_wallet_addresses.dart b/cw_wownero/lib/wownero_wallet_addresses.dart index dc4b42840..9eeb182eb 100644 --- a/cw_wownero/lib/wownero_wallet_addresses.dart +++ b/cw_wownero/lib/wownero_wallet_addresses.dart @@ -109,7 +109,7 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store { accountIndex: accountIndex, defaultLabel: defaultLabel, usedAddresses: usedAddresses.toList()); - subaddress = subaddressList.subaddresses.last; + subaddress = (subaddressList.subaddresses.isEmpty) ? Subaddress(id: 0, address: address, label: defaultLabel) : subaddressList.subaddresses.last; address = subaddress!.address; } From 15d88e0f8dc8b9b3b055d913bb64e42ed5e322e0 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Thu, 8 Aug 2024 12:17:17 +0200 Subject: [PATCH 6/7] Add Ledger Flex Support (#1576) --- cw_bitcoin/pubspec.yaml | 4 ++++ cw_evm/pubspec.yaml | 2 +- pubspec_base.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index 66c5729e8..69ff3d29b 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -56,6 +56,10 @@ dev_dependencies: hive_generator: ^1.1.3 dependency_overrides: + ledger_flutter: + git: + url: https://github.com/cake-tech/ledger-flutter.git + ref: cake-v3 watcher: ^1.1.0 # For information on the generic Dart part of this file, see the diff --git a/cw_evm/pubspec.yaml b/cw_evm/pubspec.yaml index e4b29b676..c3f4347c2 100644 --- a/cw_evm/pubspec.yaml +++ b/cw_evm/pubspec.yaml @@ -35,7 +35,7 @@ dependency_overrides: ledger_flutter: git: url: https://github.com/cake-tech/ledger-flutter.git - ref: cake + ref: cake-v3 watcher: ^1.1.0 dev_dependencies: diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 67a162674..84b4631fc 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -133,7 +133,7 @@ dependency_overrides: ledger_flutter: git: url: https://github.com/cake-tech/ledger-flutter.git - ref: cake-stax + ref: cake-v3 web3dart: git: url: https://github.com/cake-tech/web3dart.git From ba433ef6f30442e2ac69724fdcb4415699f3db8d Mon Sep 17 00:00:00 2001 From: Matthew Fosse Date: Thu, 8 Aug 2024 03:27:04 -0700 Subject: [PATCH 7/7] Request timeout fix (#1584) * always handle RequestFailedTimeoutException * undo change that was for testing --- cw_bitcoin/lib/electrum.dart | 69 +++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index b52015794..e3925ca74 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -236,25 +236,37 @@ class ElectrumClient { return []; }); - Future> getTransactionRaw({required String hash}) async => - callWithTimeout(method: 'blockchain.transaction.get', params: [hash, true], timeout: 10000) - .then((dynamic result) { - if (result is Map) { - return result; - } + Future> getTransactionRaw({required String hash}) async { + try { + final result = await callWithTimeout( + method: 'blockchain.transaction.get', params: [hash, true], timeout: 10000); + if (result is Map) { + return result; + } + } on RequestFailedTimeoutException catch (_) { + return {}; + } catch (e) { + print("getTransactionRaw: ${e.toString()}"); + return {}; + } + return {}; + } - return {}; - }); - - Future getTransactionHex({required String hash}) async => - callWithTimeout(method: 'blockchain.transaction.get', params: [hash, false], timeout: 10000) - .then((dynamic result) { - if (result is String) { - return result; - } - - return ''; - }); + Future getTransactionHex({required String hash}) async { + try { + final result = await callWithTimeout( + method: 'blockchain.transaction.get', params: [hash, false], timeout: 10000); + if (result is String) { + return result; + } + } on RequestFailedTimeoutException catch (_) { + return ''; + } catch (e) { + print("getTransactionHex: ${e.toString()}"); + return ''; + } + return ''; + } Future broadcastTransaction( {required String transactionRaw, @@ -353,14 +365,21 @@ class ElectrumClient { // "height": 520481, // "hex": "00000020890208a0ae3a3892aa047c5468725846577cfcd9b512b50000000000000000005dc2b02f2d297a9064ee103036c14d678f9afc7e3d9409cf53fd58b82e938e8ecbeca05a2d2103188ce804c4" // } - Future getCurrentBlockChainTip() => - callWithTimeout(method: 'blockchain.headers.subscribe').then((result) { - if (result is Map) { - return result["height"] as int; - } - return null; - }); + Future getCurrentBlockChainTip() async { + try { + final result = await callWithTimeout(method: 'blockchain.headers.subscribe'); + if (result is Map) { + return result["height"] as int; + } + return null; + } on RequestFailedTimeoutException catch (_) { + return null; + } catch (e) { + print("getCurrentBlockChainTip: ${e.toString()}"); + return null; + } + } BehaviorSubject? chainTipSubscribe() { _id += 1;