Switch to SSL for Cake's Electrum and Monero nodes (#1899)

* Force SSL for Electrum and Monero nodes
Some Cleanup

* minor [skip ci]

* potential fix for transactions not cleared correctly [skip ci]

* minor fix [skip ci]
This commit is contained in:
Omar Hatem 2024-12-25 21:27:46 +02:00 committed by GitHub
parent b79ef988c8
commit c6b9f054cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 49 additions and 55 deletions

View file

@ -2,12 +2,10 @@ import 'dart:async';
import 'package:cake_wallet/core/generate_wallet_password.dart'; import 'package:cake_wallet/core/generate_wallet_password.dart';
import 'package:cake_wallet/core/key_service.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/entities/preferences_key.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/main.dart'; import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/reactions/on_authentication_state_change.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/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:cake_wallet/utils/exception_handler.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';

View file

@ -167,7 +167,11 @@ Future<void> defaultSettingsMigration(
break; break;
case 18: case 18:
await addOnionNode(nodes); await updateWalletTypeNodesWithNewNode(
nodes: nodes,
newNodeUri: "cakexmrl7bonq7ovjka5kuwuyd3f7qnkz6z6s6dmsy3uckwra7bvggyd.onion:18081",
type: WalletType.monero,
);
break; break;
case 19: case 19:
@ -261,15 +265,15 @@ Future<void> defaultSettingsMigration(
await updateTronNodesWithNowNodes(sharedPreferences: sharedPreferences, nodes: nodes); await updateTronNodesWithNowNodes(sharedPreferences: sharedPreferences, nodes: nodes);
break; break;
case 42: case 42:
updateBtcElectrumNodeToUseSSL(nodes, sharedPreferences); _fixNodesUseSSLFlag(nodes);
break; break;
case 43: case 43:
await _updateCakeXmrNode(nodes); _fixNodesUseSSLFlag(nodes);
_deselectExchangeProvider(sharedPreferences, "THORChain"); _deselectExchangeProvider(sharedPreferences, "THORChain");
_deselectExchangeProvider(sharedPreferences, "SimpleSwap"); _deselectExchangeProvider(sharedPreferences, "SimpleSwap");
break; break;
case 44: case 44:
await _updateCakeXmrNode(nodes); _fixNodesUseSSLFlag(nodes);
await _changeDefaultNode( await _changeDefaultNode(
nodes: nodes, nodes: nodes,
sharedPreferences: sharedPreferences, sharedPreferences: sharedPreferences,
@ -297,14 +301,12 @@ Future<void> defaultSettingsMigration(
updateWalletTypeNodesWithNewNode( updateWalletTypeNodesWithNewNode(
newNodeUri: 'matic.nownodes.io', newNodeUri: 'matic.nownodes.io',
sharedPreferences: sharedPreferences,
nodes: nodes, nodes: nodes,
type: WalletType.polygon, type: WalletType.polygon,
useSSL: true, useSSL: true,
); );
updateWalletTypeNodesWithNewNode( updateWalletTypeNodesWithNewNode(
newNodeUri: 'eth.nownodes.io', newNodeUri: 'eth.nownodes.io',
sharedPreferences: sharedPreferences,
nodes: nodes, nodes: nodes,
type: WalletType.ethereum, type: WalletType.ethereum,
useSSL: true, useSSL: true,
@ -330,6 +332,22 @@ Future<void> defaultSettingsMigration(
useSSL: true, useSSL: true,
oldUri: ['rpc.ankr.com'], 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: default:
break; break;
} }
@ -361,7 +379,8 @@ Future<void> _changeDefaultNode({
required String newDefaultUri, required String newDefaultUri,
required String currentNodePreferenceKey, required String currentNodePreferenceKey,
required bool useSSL, required bool useSSL,
required List<String> oldUri, // leave empty if you want to force replace the node regardless of the user's current node required List<String>
oldUri, // leave empty if you want to force replace the node regardless of the user's current node
}) async { }) async {
final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey); final currentNodeId = sharedPreferences.getInt(currentNodePreferenceKey);
final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId); final currentNode = nodes.values.firstWhere((node) => node.key == currentNodeId);
@ -389,11 +408,10 @@ Future<void> _changeDefaultNode({
/// Generic function for adding a new Node for a Wallet Type. /// Generic function for adding a new Node for a Wallet Type.
Future<void> updateWalletTypeNodesWithNewNode({ Future<void> updateWalletTypeNodesWithNewNode({
required SharedPreferences sharedPreferences,
required Box<Node> nodes, required Box<Node> nodes,
required WalletType type, required WalletType type,
required String newNodeUri, required String newNodeUri,
required bool useSSL, bool? useSSL,
}) async { }) async {
// If it already exists in the box of nodes, no need to add it annymore. // If it already exists in the box of nodes, no need to add it annymore.
if (nodes.values.any((node) => node.uriRaw == newNodeUri)) return; if (nodes.values.any((node) => node.uriRaw == newNodeUri)) return;
@ -407,26 +425,6 @@ Future<void> updateWalletTypeNodesWithNewNode({
); );
} }
Future<void> _updateCakeXmrNode(Box<Node> 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<Node> 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) { void _deselectExchangeProvider(SharedPreferences sharedPreferences, String providerName) {
final Map<String, dynamic> exchangeProvidersSelection = final Map<String, dynamic> exchangeProvidersSelection =
json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}")
@ -445,8 +443,10 @@ void _fixNodesUseSSLFlag(Box<Node> nodes) {
switch (node.uriRaw) { switch (node.uriRaw) {
case cakeWalletLitecoinElectrumUri: case cakeWalletLitecoinElectrumUri:
case cakeWalletBitcoinElectrumUri: case cakeWalletBitcoinElectrumUri:
case newCakeWalletBitcoinUri:
case newCakeWalletMoneroUri:
node.useSSL = true; node.useSSL = true;
break; node.trusted = true;
} }
} }
} }
@ -580,15 +580,6 @@ Future<void> validateBitcoinSavedTransactionPriority(SharedPreferences sharedPre
} }
} }
Future<void> addOnionNode(Box<Node> 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<void> replaceNodesMigration({required Box<Node> nodes}) async { Future<void> replaceNodesMigration({required Box<Node> nodes}) async {
final replaceNodes = <String, Node>{ final replaceNodes = <String, Node>{
'eu-node.cakewallet.io:18081': 'eu-node.cakewallet.io:18081':

View file

@ -1,3 +1,5 @@
import 'package:cake_wallet/src/screens/wallet_connect/utils/string_parsing.dart';
class EVMTransactionErrorFeesHandler { class EVMTransactionErrorFeesHandler {
EVMTransactionErrorFeesHandler({ EVMTransactionErrorFeesHandler({
this.balanceWei, this.balanceWei,
@ -64,14 +66,14 @@ class EVMTransactionErrorFeesHandler {
return EVMTransactionErrorFeesHandler( return EVMTransactionErrorFeesHandler(
balanceWei: balanceWei.toString(), balanceWei: balanceWei.toString(),
balanceEth: balanceEth.toString().substring(0, 12), balanceEth: balanceEth.toString().safeSubString(0, 12),
balanceUsd: balanceUsd.toString().substring(0, 4), balanceUsd: balanceUsd.toString().safeSubString(0, 4),
txCostWei: txCostWei.toString(), txCostWei: txCostWei.toString(),
txCostEth: txCostEth.toString().substring(0, 12), txCostEth: txCostEth.toString().safeSubString(0, 12),
txCostUsd: txCostUsd.toString().substring(0, 4), txCostUsd: txCostUsd.toString().safeSubString(0, 4),
overshotWei: overshotWei.toString(), overshotWei: overshotWei.toString(),
overshotEth: overshotEth.toString().substring(0, 12), overshotEth: overshotEth.toString().safeSubString(0, 12),
overshotUsd: overshotUsd.toString().substring(0, 4), overshotUsd: overshotUsd.toString().safeSubString(0, 4),
); );
} else { } else {
// If any value is missing, return an error message // If any value is missing, return an error message

View file

@ -215,7 +215,7 @@ Future<void> initializeAppConfigs() async {
secureStorage: secureStorage, secureStorage: secureStorage,
anonpayInvoiceInfo: anonpayInvoiceInfo, anonpayInvoiceInfo: anonpayInvoiceInfo,
havenSeedStore: havenSeedStore, havenSeedStore: havenSeedStore,
initialMigrationVersion: 45, initialMigrationVersion: 46,
); );
} }

View file

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:math';
import 'package:convert/convert.dart'; import 'package:convert/convert.dart';
@ -13,4 +14,8 @@ extension StringParsing on String {
return this; return this;
} }
String safeSubString(int start, int end) {
return this.substring(0, min(this.toString().length, 12));
}
} }

View file

@ -219,9 +219,9 @@ class ExceptionHandler {
// probably when the device was locked and then opened on Cake // probably when the device was locked and then opened on Cake
// this is solved by a restart of the app // 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 // 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/key_service.dart:14",
"core/wallet_loading_service.dart:133", "core/wallet_loading_service.dart:131",
]; ];
static Future<void> _addDeviceInfo(File file) async { static Future<void> _addDeviceInfo(File file) async {

View file

@ -4,13 +4,11 @@ import 'dart:io' show Platform;
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/bitcoin/bitcoin.dart'; 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/core/key_service.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.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/balance_display_mode.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/preferences_key.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/entities/service_status.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
@ -643,7 +641,7 @@ abstract class DashboardViewModelBase with Store {
transactions.clear(); transactions.clear();
transactions.addAll( transactions = ObservableList.of(
wallet.transactionHistory.transactions.values.map( wallet.transactionHistory.transactions.values.map(
(transaction) => TransactionListItem( (transaction) => TransactionListItem(
transaction: transaction, transaction: transaction,
@ -705,7 +703,7 @@ abstract class DashboardViewModelBase with Store {
monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id) monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
.toList(); .toList();
transactions.addAll( transactions = ObservableList.of(
_accountTransactions.map( _accountTransactions.map(
(transaction) => TransactionListItem( (transaction) => TransactionListItem(
transaction: transaction, transaction: transaction,
@ -725,7 +723,7 @@ abstract class DashboardViewModelBase with Store {
wow.wownero!.getCurrentAccount(wallet).id) wow.wownero!.getCurrentAccount(wallet).id)
.toList(); .toList();
transactions.addAll( transactions = ObservableList.of(
_accountTransactions.map( _accountTransactions.map(
(transaction) => TransactionListItem( (transaction) => TransactionListItem(
transaction: transaction, transaction: transaction,