diff --git a/assets/bitcoin_electrum_server_list.yml b/assets/bitcoin_electrum_server_list.yml index 8b734a7bb..305db38f5 100644 --- a/assets/bitcoin_electrum_server_list.yml +++ b/assets/bitcoin_electrum_server_list.yml @@ -6,3 +6,6 @@ isDefault: true - uri: electrs.cakewallet.com:50001 +- + uri: fulcrum.sethforprivacy.com:50002 + useSSL: true diff --git a/assets/images/ton_icon.png b/assets/images/ton_icon.png new file mode 100644 index 000000000..90f9968cc Binary files /dev/null and b/assets/images/ton_icon.png differ diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 4f8f3eab5..877b108b7 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -479,8 +479,14 @@ abstract class ElectrumWalletBase final result = json.decode(response.body) as Map; final slowFee = result['economyFee']?.toInt() ?? 0; - final mediumFee = result['hourFee']?.toInt() ?? 0; - final fastFee = result['fastestFee']?.toInt() ?? 0; + int mediumFee = result['hourFee']?.toInt() ?? 0; + int fastFee = result['fastestFee']?.toInt() ?? 0; + if (slowFee == mediumFee) { + mediumFee++; + } + while (fastFee <= mediumFee) { + fastFee++; + } _feeRates = [slowFee, mediumFee, fastFee]; return; } catch (_) {} @@ -813,6 +819,8 @@ abstract class ElectrumWalletBase network: network, memo: memo, feeRate: feeRate, + inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos, + vinOutpoints: utxoDetails.vinOutpoints, ); if (fee == 0) { @@ -1639,27 +1647,29 @@ abstract class ElectrumWalletBase if (verboseTransaction.isEmpty) { transactionHex = await electrumClient.getTransactionHex(hash: hash); - if (height != null && await checkIfMempoolAPIIsEnabled()) { - final blockHash = await http.get( - Uri.parse( - "http://mempool.cakewallet.com:8999/api/v1/block-height/$height", - ), - ); - - if (blockHash.statusCode == 200 && - blockHash.body.isNotEmpty && - jsonDecode(blockHash.body) != null) { - final blockResponse = await http.get( + if (height != null && height > 0 && await checkIfMempoolAPIIsEnabled()) { + try { + final blockHash = await http.get( Uri.parse( - "http://mempool.cakewallet.com:8999/api/v1/block/${blockHash.body}", + "http://mempool.cakewallet.com:8999/api/v1/block-height/$height", ), ); - if (blockResponse.statusCode == 200 && - blockResponse.body.isNotEmpty && - jsonDecode(blockResponse.body)['timestamp'] != null) { - time = int.parse(jsonDecode(blockResponse.body)['timestamp'].toString()); + + if (blockHash.statusCode == 200 && + blockHash.body.isNotEmpty && + jsonDecode(blockHash.body) != null) { + final blockResponse = await http.get( + Uri.parse( + "http://mempool.cakewallet.com:8999/api/v1/block/${blockHash.body}", + ), + ); + if (blockResponse.statusCode == 200 && + blockResponse.body.isNotEmpty && + jsonDecode(blockResponse.body)['timestamp'] != null) { + time = int.parse(jsonDecode(blockResponse.body)['timestamp'].toString()); + } } - } + } catch (_) {} } } else { transactionHex = verboseTransaction['hex'] as String; diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index f741230a5..4c7c49a9e 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -49,6 +49,15 @@ packages: url: "https://pub.dev" source: hosted version: "2.11.0" + bech32: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "05755063b593aa6cca0a4820a318e0ce17de6192" + url: "https://github.com/cake-tech/bech32.git" + source: git + version: "0.2.2" bip32: dependency: transitive description: @@ -78,8 +87,8 @@ packages: dependency: "direct overridden" description: path: "." - ref: cake-update-v7 - resolved-ref: f577e83fe78766b2655ea0602baa9299b953a31b + ref: cake-update-v8 + resolved-ref: fc045a11db3d85d806ca67f75e8b916c706745a2 url: "https://github.com/cake-tech/bitcoin_base" source: git version: "4.7.0" @@ -308,13 +317,13 @@ packages: source: hosted version: "1.3.1" ffi: - dependency: transitive + dependency: "direct overridden" description: name: ffi - sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.0" ffigen: dependency: transitive description: @@ -450,6 +459,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.2" + http2: + dependency: transitive + description: + name: http2 + sha256: "9ced024a160b77aba8fb8674e38f70875e321d319e6f303ec18e87bd5a4b0c1d" + url: "https://pub.dev" + source: hosted + version: "2.3.0" http_multi_server: dependency: transitive description: @@ -693,13 +710,13 @@ packages: source: hosted version: "2.1.8" pointycastle: - dependency: transitive + dependency: "direct overridden" description: name: pointycastle - sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.9.1" + version: "3.7.4" pool: dependency: transitive description: @@ -709,13 +726,13 @@ packages: source: hosted version: "1.5.1" protobuf: - dependency: transitive + dependency: "direct overridden" description: name: protobuf - sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "3.1.0" provider: dependency: transitive description: diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index 4f9b5d835..0280bb45a 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -106,6 +106,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen CryptoCurrency.usdcTrc20, CryptoCurrency.tbtc, CryptoCurrency.wow, + CryptoCurrency.ton, ]; static const havenCurrencies = [ @@ -223,6 +224,7 @@ class CryptoCurrency extends EnumerableItem with Serializable implemen static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/usdc_icon.png', decimals: 6); static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8); static const wow = CryptoCurrency(title: 'WOW', fullName: 'Wownero', raw: 94, name: 'wow', iconPath: 'assets/images/wownero_icon.png', decimals: 11); + static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/images/ton_icon.png', decimals: 8); static final Map _rawCurrencyMap = diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 85c61de15..e19d2a54b 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -239,12 +239,15 @@ class Node extends HiveObject with Keyable { // you try to communicate with it Future requestElectrumServer() async { try { + final Socket socket; if (useSSL == true) { - await SecureSocket.connect(uri.host, uri.port, + socket = await SecureSocket.connect(uri.host, uri.port, timeout: Duration(seconds: 5), onBadCertificate: (_) => true); } else { - await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5)); + socket = await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5)); } + + socket.destroy(); return true; } catch (_) { return false; diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 802ad0184..1c46cd605 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io' show Directory, File, Platform; import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/core/secure_storage.dart'; @@ -234,7 +235,8 @@ Future defaultSettingsMigration( break; case 36: await addWowneroNodeList(nodes: nodes); - await changeWowneroCurrentNodeToDefault(sharedPreferences: sharedPreferences, nodes: nodes); + await changeWowneroCurrentNodeToDefault( + sharedPreferences: sharedPreferences, nodes: nodes); break; case 37: await replaceTronDefaultNode(sharedPreferences: sharedPreferences, nodes: nodes); @@ -249,6 +251,10 @@ Future defaultSettingsMigration( case 40: await removeMoneroWorld(sharedPreferences: sharedPreferences, nodes: nodes); break; + case 41: + _deselectQuantex(sharedPreferences); + await _addSethNode(nodes, sharedPreferences); + break; default: break; } @@ -263,6 +269,19 @@ Future defaultSettingsMigration( await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version); } +void _deselectQuantex(SharedPreferences sharedPreferences) { + final Map exchangeProvidersSelection = + json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") + as Map; + + exchangeProvidersSelection['Quantex'] = false; + + sharedPreferences.setString( + PreferencesKey.exchangeProvidersSelection, + json.encode(exchangeProvidersSelection), + ); +} + void _fixNodesUseSSLFlag(Box nodes) { for (Node node in nodes.values) { switch (node.uriRaw) { @@ -887,7 +906,30 @@ Future changeDefaultBitcoinNode( } } +Future _addSethNode(Box nodeSource, SharedPreferences sharedPreferences) async { + _addBitcoinNode( + nodeSource: nodeSource, + sharedPreferences: sharedPreferences, + nodeUri: "fulcrum.sethforprivacy.com:50002", + useSSL: false, + ); +} + Future _addElectRsNode(Box nodeSource, SharedPreferences sharedPreferences) async { + _addBitcoinNode( + nodeSource: nodeSource, + sharedPreferences: sharedPreferences, + nodeUri: cakeWalletSilentPaymentsElectrsUri, + ); +} + +Future _addBitcoinNode({ + required Box nodeSource, + required SharedPreferences sharedPreferences, + required String nodeUri, + bool replaceExisting = false, + bool useSSL = false, +}) async { const cakeWalletBitcoinNodeUriPattern = '.cakewallet.com'; final currentBitcoinNodeId = sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey); @@ -896,12 +938,11 @@ Future _addElectRsNode(Box nodeSource, SharedPreferences sharedPrefe final needToReplaceCurrentBitcoinNode = currentBitcoinNode.uri.toString().contains(cakeWalletBitcoinNodeUriPattern); - final newElectRsBitcoinNode = - Node(uri: cakeWalletSilentPaymentsElectrsUri, type: WalletType.bitcoin, useSSL: false); + final newElectRsBitcoinNode = Node(uri: nodeUri, type: WalletType.bitcoin, useSSL: useSSL); await nodeSource.add(newElectRsBitcoinNode); - if (needToReplaceCurrentBitcoinNode) { + if (needToReplaceCurrentBitcoinNode && replaceExisting) { await sharedPreferences.setInt( PreferencesKey.currentBitcoinElectrumSererIdKey, newElectRsBitcoinNode.key as int); } @@ -1262,7 +1303,8 @@ Future removeMoneroWorld( const cakeWalletMoneroNodeUriPattern = '.moneroworld.com'; final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey); final currentMoneroNode = nodes.values.firstWhere((node) => node.key == currentMoneroNodeId); - final needToReplaceCurrentMoneroNode = currentMoneroNode.uri.toString().contains(cakeWalletMoneroNodeUriPattern); + final needToReplaceCurrentMoneroNode = + currentMoneroNode.uri.toString().contains(cakeWalletMoneroNodeUriPattern); nodes.values.forEach((node) async { if (node.type == WalletType.monero && diff --git a/lib/main.dart b/lib/main.dart index dcfd8d0da..7237de8b9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -192,7 +192,7 @@ Future initializeAppConfigs() async { transactionDescriptions: transactionDescriptions, secureStorage: secureStorage, anonpayInvoiceInfo: anonpayInvoiceInfo, - initialMigrationVersion: 40, + initialMigrationVersion: 41, ); } diff --git a/lib/reactions/check_connection.dart b/lib/reactions/check_connection.dart index 812fa9fcd..570b96864 100644 --- a/lib/reactions/check_connection.dart +++ b/lib/reactions/check_connection.dart @@ -11,6 +11,8 @@ Timer? _checkConnectionTimer; void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore, {int timeInterval = 5}) { _checkConnectionTimer?.cancel(); + // TODO: check the validity of this code, and if it's working fine, then no need for + // having the connect function in electrum.dart when the syncstatus is lost or failed and add the not connected state _checkConnectionTimer = Timer.periodic(Duration(seconds: timeInterval), (_) async { if (wallet.type == WalletType.bitcoin && wallet.syncStatus is SyncingSyncStatus) { return; diff --git a/lib/src/screens/receive/widgets/qr_image.dart b/lib/src/screens/receive/widgets/qr_image.dart index f388fdd0b..043958ef4 100644 --- a/lib/src/screens/receive/widgets/qr_image.dart +++ b/lib/src/screens/receive/widgets/qr_image.dart @@ -23,7 +23,7 @@ class QrImage extends StatelessWidget { return qr.QrImageView( data: data, errorCorrectionLevel: errorCorrectionLevel, - version: version ?? 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ??? + version: version ?? qr.QrVersions.auto, size: size, foregroundColor: foregroundColor, backgroundColor: backgroundColor, diff --git a/lib/utils/brightness_util.dart b/lib/utils/brightness_util.dart index 5afe065e5..1b34bceac 100644 --- a/lib/utils/brightness_util.dart +++ b/lib/utils/brightness_util.dart @@ -9,15 +9,12 @@ class BrightnessUtil { return; } - // Get the current brightness: - final brightness = await DeviceDisplayBrightness.getBrightness(); - // ignore: unawaited_futures DeviceDisplayBrightness.setBrightness(1.0); await func(); // ignore: unawaited_futures - DeviceDisplayBrightness.setBrightness(brightness); + DeviceDisplayBrightness.resetBrightness(); } } \ No newline at end of file