diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 18d2ffc44..aa7d27254 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -22,8 +22,8 @@ class Node extends HiveObject with Keyable { this.useSSL, this.trusted = false, this.socksProxyAddress, + this.path = '', String? uri, - String? path, WalletType? type, }) { if (uri != null) { @@ -32,9 +32,6 @@ class Node extends HiveObject with Keyable { if (type != null) { this.type = type; } - if (path != null) { - this.path = path; - } } Node.fromMap(Map map) @@ -95,19 +92,15 @@ class Node extends HiveObject with Keyable { case WalletType.bitcoin: case WalletType.litecoin: case WalletType.bitcoinCash: - return createUriFromElectrumAddress(uriRaw, path ?? ''); + return createUriFromElectrumAddress(uriRaw, path!); case WalletType.nano: case WalletType.banano: - if (isSSL) { - return Uri.https(uriRaw, path ?? ''); - } else { - return Uri.http(uriRaw, path ?? ''); - } case WalletType.ethereum: case WalletType.polygon: case WalletType.solana: case WalletType.tron: - return Uri.https(uriRaw, path ?? ''); + return Uri.parse( + "http${isSSL ? "s" : ""}://$uriRaw${path!.startsWith("/") ? path : "/$path"}"); case WalletType.none: throw Exception('Unexpected type ${type.toString()} for Node uri'); } @@ -247,7 +240,7 @@ class Node extends HiveObject with Keyable { if (proxy == null) { return false; } - final proxyAddress = proxy!.split(':')[0]; + final proxyAddress = proxy.split(':')[0]; final proxyPort = int.parse(proxy.split(':')[1]); try { final socket = await Socket.connect(proxyAddress, proxyPort, timeout: Duration(seconds: 5)); diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart index 6b1553443..f1996bae8 100644 --- a/lib/core/wallet_loading_service.dart +++ b/lib/core/wallet_loading_service.dart @@ -2,12 +2,10 @@ import 'dart:async'; import 'package:cake_wallet/core/generate_wallet_password.dart'; import 'package:cake_wallet/core/key_service.dart'; -import 'package:cake_wallet/core/secure_storage.dart'; 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/reactions/on_authentication_state_change.dart'; -import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 64370503f..9e06d25da 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -167,7 +167,11 @@ Future defaultSettingsMigration( break; case 18: - await addOnionNode(nodes); + await updateWalletTypeNodesWithNewNode( + nodes: nodes, + newNodeUri: "cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081", + type: WalletType.monero, + ); break; case 19: @@ -261,15 +265,15 @@ Future defaultSettingsMigration( await updateTronNodesWithNowNodes(sharedPreferences: sharedPreferences, nodes: nodes); break; case 42: - updateBtcElectrumNodeToUseSSL(nodes, sharedPreferences); + _fixNodesUseSSLFlag(nodes); break; case 43: - await _updateCakeXmrNode(nodes); + _fixNodesUseSSLFlag(nodes); _deselectExchangeProvider(sharedPreferences, "THORChain"); _deselectExchangeProvider(sharedPreferences, "SimpleSwap"); break; case 44: - await _updateCakeXmrNode(nodes); + _fixNodesUseSSLFlag(nodes); await _changeDefaultNode( nodes: nodes, sharedPreferences: sharedPreferences, @@ -297,14 +301,12 @@ Future defaultSettingsMigration( updateWalletTypeNodesWithNewNode( newNodeUri: 'matic.nownodes.io', - sharedPreferences: sharedPreferences, nodes: nodes, type: WalletType.polygon, useSSL: true, ); updateWalletTypeNodesWithNewNode( newNodeUri: 'eth.nownodes.io', - sharedPreferences: sharedPreferences, nodes: nodes, type: WalletType.ethereum, useSSL: true, @@ -330,6 +332,22 @@ Future defaultSettingsMigration( useSSL: true, oldUri: ['rpc.ankr.com'], ); + break; + case 46: + _fixNodesUseSSLFlag(nodes); + updateWalletTypeNodesWithNewNode( + newNodeUri: 'litecoin.stackwallet.com:20063', + nodes: nodes, + type: WalletType.litecoin, + useSSL: true, + ); + updateWalletTypeNodesWithNewNode( + newNodeUri: 'electrum-ltc.bysh.me:50002', + nodes: nodes, + type: WalletType.litecoin, + useSSL: true, + ); + break; default: break; } @@ -361,7 +379,8 @@ Future _changeDefaultNode({ required String newDefaultUri, required String currentNodePreferenceKey, required bool useSSL, - required List oldUri, // leave empty if you want to force replace the node regardless of the user's current node + required List + oldUri, // leave empty if you want to force replace the node regardless of the user's current node }) async { final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey); final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId); @@ -389,11 +408,10 @@ Future _changeDefaultNode({ /// Generic function for adding a new Node for a Wallet Type. Future updateWalletTypeNodesWithNewNode({ - required SharedPreferences sharedPreferences, required Box nodes, required WalletType type, required String newNodeUri, - required bool useSSL, + bool? useSSL, }) async { // If it already exists in the box of nodes, no need to add it annymore. if (nodes.values.any((node) => node.uriRaw == newNodeUri)) return; @@ -407,26 +425,6 @@ Future updateWalletTypeNodesWithNewNode({ ); } -Future _updateCakeXmrNode(Box nodes) async { - final node = nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletMoneroUri); - - if (node != null) { - node.trusted = true; - node.useSSL = true; - await node.save(); - } -} - -void updateBtcElectrumNodeToUseSSL(Box nodes, SharedPreferences sharedPreferences) { - final btcElectrumNode = - nodes.values.firstWhereOrNull((element) => element.uriRaw == newCakeWalletBitcoinUri); - - if (btcElectrumNode != null) { - btcElectrumNode.useSSL = true; - btcElectrumNode.save(); - } -} - void _deselectExchangeProvider(SharedPreferences sharedPreferences, String providerName) { final Map exchangeProvidersSelection = json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") @@ -445,8 +443,10 @@ void _fixNodesUseSSLFlag(Box nodes) { switch (node.uriRaw) { case cakeWalletLitecoinElectrumUri: case cakeWalletBitcoinElectrumUri: + case newCakeWalletBitcoinUri: + case newCakeWalletMoneroUri: node.useSSL = true; - break; + node.trusted = true; } } } @@ -580,15 +580,6 @@ Future validateBitcoinSavedTransactionPriority(SharedPreferences sharedPre } } -Future addOnionNode(Box nodes) async { - final onionNodeUri = "cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081"; - - // check if the user has this node before (added it manually) - if (nodes.values.firstWhereOrNull((element) => element.uriRaw == onionNodeUri) == null) { - await nodes.add(Node(uri: onionNodeUri, type: WalletType.monero)); - } -} - Future replaceNodesMigration({required Box nodes}) async { final replaceNodes = { 'eu-node.cakewallet.io:18081': diff --git a/lib/entities/evm_transaction_error_fees_handler.dart b/lib/entities/evm_transaction_error_fees_handler.dart index 63f6e164d..b802f9883 100644 --- a/lib/entities/evm_transaction_error_fees_handler.dart +++ b/lib/entities/evm_transaction_error_fees_handler.dart @@ -1,3 +1,5 @@ +import 'package:cake_wallet/src/screens/wallet_connect/utils/string_parsing.dart'; + class EVMTransactionErrorFeesHandler { EVMTransactionErrorFeesHandler({ this.balanceWei, @@ -64,14 +66,14 @@ class EVMTransactionErrorFeesHandler { return EVMTransactionErrorFeesHandler( balanceWei: balanceWei.toString(), - balanceEth: balanceEth.toString().substring(0, 12), - balanceUsd: balanceUsd.toString().substring(0, 4), + balanceEth: balanceEth.toString().safeSubString(0, 12), + balanceUsd: balanceUsd.toString().safeSubString(0, 4), txCostWei: txCostWei.toString(), - txCostEth: txCostEth.toString().substring(0, 12), - txCostUsd: txCostUsd.toString().substring(0, 4), + txCostEth: txCostEth.toString().safeSubString(0, 12), + txCostUsd: txCostUsd.toString().safeSubString(0, 4), overshotWei: overshotWei.toString(), - overshotEth: overshotEth.toString().substring(0, 12), - overshotUsd: overshotUsd.toString().substring(0, 4), + overshotEth: overshotEth.toString().safeSubString(0, 12), + overshotUsd: overshotUsd.toString().safeSubString(0, 4), ); } else { // If any value is missing, return an error message diff --git a/lib/main.dart b/lib/main.dart index 510705105..fd25a1e9c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -215,7 +215,7 @@ Future initializeAppConfigs() async { secureStorage: secureStorage, anonpayInvoiceInfo: anonpayInvoiceInfo, havenSeedStore: havenSeedStore, - initialMigrationVersion: 45, + initialMigrationVersion: 46, ); } diff --git a/lib/src/screens/seed/seed_verification/seed_verification_step_view.dart b/lib/src/screens/seed/seed_verification/seed_verification_step_view.dart index b8c1500dc..9fd70be05 100644 --- a/lib/src/screens/seed/seed_verification/seed_verification_step_view.dart +++ b/lib/src/screens/seed/seed_verification/seed_verification_step_view.dart @@ -70,6 +70,8 @@ class SeedVerificationStepView extends StatelessWidget { (option) { return GestureDetector( onTap: () async { + if (walletSeedViewModel.wrongEntries > 2) return; + final isCorrectWord = walletSeedViewModel.isChosenWordCorrect(option); final isSecondWrongEntry = walletSeedViewModel.wrongEntries >= 2; if (!isCorrectWord) { @@ -81,7 +83,9 @@ class SeedVerificationStepView extends StatelessWidget { ); if (isSecondWrongEntry) { - Navigator.pop(context); + if (context.mounted) { + Navigator.pop(context); + } } } }, diff --git a/lib/src/screens/wallet_connect/utils/string_parsing.dart b/lib/src/screens/wallet_connect/utils/string_parsing.dart index b9fdca7b2..0aed1b9e9 100644 --- a/lib/src/screens/wallet_connect/utils/string_parsing.dart +++ b/lib/src/screens/wallet_connect/utils/string_parsing.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:math'; import 'package:convert/convert.dart'; @@ -13,4 +14,8 @@ extension StringParsing on String { return this; } + + String safeSubString(int start, int end) { + return this.substring(0, min(this.toString().length, 12)); + } } diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart index 357a69fa6..66cbc61a0 100644 --- a/lib/utils/exception_handler.dart +++ b/lib/utils/exception_handler.dart @@ -219,9 +219,9 @@ class ExceptionHandler { // probably when the device was locked and then opened on Cake // this is solved by a restart of the app // just ignoring until we find a solution to this issue or migrate from flutter secure storage - "core/auth_service.dart:63", + "core/auth_service.dart:64", "core/key_service.dart:14", - "core/wallet_loading_service.dart:133", + "core/wallet_loading_service.dart:131", ]; static Future _addDeviceInfo(File file) async { diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 413bbbdaf..569d9f816 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -4,13 +4,11 @@ import 'dart:io' show Platform; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/bitcoin/bitcoin.dart'; -import 'package:cake_wallet/buy/buy_provider.dart'; import 'package:cake_wallet/core/key_service.dart'; import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart'; import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/entities/provider_types.dart'; import 'package:cake_wallet/entities/service_status.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/generated/i18n.dart'; @@ -651,7 +649,7 @@ abstract class DashboardViewModelBase with Store { transactions.clear(); - transactions.addAll( + transactions = ObservableList.of( wallet.transactionHistory.transactions.values.map( (transaction) => TransactionListItem( transaction: transaction, @@ -713,7 +711,7 @@ abstract class DashboardViewModelBase with Store { monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id) .toList(); - transactions.addAll( + transactions = ObservableList.of( _accountTransactions.map( (transaction) => TransactionListItem( transaction: transaction, @@ -733,7 +731,7 @@ abstract class DashboardViewModelBase with Store { wow.wownero!.getCurrentAccount(wallet).id) .toList(); - transactions.addAll( + transactions = ObservableList.of( _accountTransactions.map( (transaction) => TransactionListItem( transaction: transaction,