Generic fixes (#1716)

* reset brightness after using * set default qr to auto detect * minor safety enhancement * close socket after checking connectivity * fix incorrect parent exception class * pump medium and fast priorities even if they are equal to slow * Add Ton to exchange * fix silent payments add Seth bitcoin node * deselect quantex add seth node for existing users * fix node uri

Omar Hatem committed Oct 4, 2024 at 23:00 UTC 6dba73a1d5b627a8bb4566f273aec63111a90cb3
11 files changed +119 -43
assets/bitcoin_electrum_server_list.yml
+3
@@ -6,3 +6,6 @@
6 isDefault: true
7 -
8 uri: electrs.cakewallet.com:50001
9 +-
10 + uri: fulcrum.sethforprivacy.com:50002
11 + useSSL: true
assets/images/ton_icon.png
Binary files /dev/null and b/assets/images/ton_icon.png differ
cw_bitcoin/lib/electrum_wallet.dart
+29 -19
@@ -479,8 +479,14 @@ abstract class ElectrumWalletBase
479
480 final result = json.decode(response.body) as Map<String, num>;
481 final slowFee = result['economyFee']?.toInt() ?? 0;
482 - final mediumFee = result['hourFee']?.toInt() ?? 0;
483 - final fastFee = result['fastestFee']?.toInt() ?? 0;
482 + int mediumFee = result['hourFee']?.toInt() ?? 0;
483 + int fastFee = result['fastestFee']?.toInt() ?? 0;
484 + if (slowFee == mediumFee) {
485 + mediumFee++;
486 + }
487 + while (fastFee <= mediumFee) {
488 + fastFee++;
489 + }
490 _feeRates = [slowFee, mediumFee, fastFee];
491 return;
492 } catch (_) {}
@@ -813,6 +819,8 @@ abstract class ElectrumWalletBase
819 network: network,
820 memo: memo,
821 feeRate: feeRate,
822 + inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos,
823 + vinOutpoints: utxoDetails.vinOutpoints,
824 );
825
826 if (fee == 0) {
@@ -1639,27 +1647,29 @@ abstract class ElectrumWalletBase
1647 if (verboseTransaction.isEmpty) {
1648 transactionHex = await electrumClient.getTransactionHex(hash: hash);
1649
1642 - if (height != null && await checkIfMempoolAPIIsEnabled()) {
1643 - final blockHash = await http.get(
1644 - Uri.parse(
1645 - "http://mempool.cakewallet.com:8999/api/v1/block-height/$height",
1646 - ),
1647 - );
1648 -
1649 - if (blockHash.statusCode == 200 &&
1650 - blockHash.body.isNotEmpty &&
1651 - jsonDecode(blockHash.body) != null) {
1652 - final blockResponse = await http.get(
1650 + if (height != null && height > 0 && await checkIfMempoolAPIIsEnabled()) {
1651 + try {
1652 + final blockHash = await http.get(
1653 Uri.parse(
1654 - "http://mempool.cakewallet.com:8999/api/v1/block/${blockHash.body}",
1654 + "http://mempool.cakewallet.com:8999/api/v1/block-height/$height",
1655 ),
1656 );
1657 - if (blockResponse.statusCode == 200 &&
1658 - blockResponse.body.isNotEmpty &&
1659 - jsonDecode(blockResponse.body)['timestamp'] != null) {
1660 - time = int.parse(jsonDecode(blockResponse.body)['timestamp'].toString());
1657 +
1658 + if (blockHash.statusCode == 200 &&
1659 + blockHash.body.isNotEmpty &&
1660 + jsonDecode(blockHash.body) != null) {
1661 + final blockResponse = await http.get(
1662 + Uri.parse(
1663 + "http://mempool.cakewallet.com:8999/api/v1/block/${blockHash.body}",
1664 + ),
1665 + );
1666 + if (blockResponse.statusCode == 200 &&
1667 + blockResponse.body.isNotEmpty &&
1668 + jsonDecode(blockResponse.body)['timestamp'] != null) {
1669 + time = int.parse(jsonDecode(blockResponse.body)['timestamp'].toString());
1670 + }
1671 }
1662 - }
1672 + } catch (_) {}
1673 }
1674 } else {
1675 transactionHex = verboseTransaction['hex'] as String;
cw_bitcoin/pubspec.lock
+28 -11
@@ -49,6 +49,15 @@ packages:
49 url: "https://pub.dev"
50 source: hosted
51 version: "2.11.0"
52 + bech32:
53 + dependency: "direct main"
54 + description:
55 + path: "."
56 + ref: HEAD
57 + resolved-ref: "05755063b593aa6cca0a4820a318e0ce17de6192"
58 + url: "https://github.com/cake-tech/bech32.git"
59 + source: git
60 + version: "0.2.2"
61 bip32:
62 dependency: transitive
63 description:
@@ -78,8 +87,8 @@ packages:
87 dependency: "direct overridden"
88 description:
89 path: "."
81 - ref: cake-update-v7
82 - resolved-ref: f577e83fe78766b2655ea0602baa9299b953a31b
90 + ref: cake-update-v8
91 + resolved-ref: fc045a11db3d85d806ca67f75e8b916c706745a2
92 url: "https://github.com/cake-tech/bitcoin_base"
93 source: git
94 version: "4.7.0"
@@ -308,13 +317,13 @@ packages:
317 source: hosted
318 version: "1.3.1"
319 ffi:
311 - dependency: transitive
320 + dependency: "direct overridden"
321 description:
322 name: ffi
314 - sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
323 + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
324 url: "https://pub.dev"
325 source: hosted
317 - version: "2.1.3"
326 + version: "2.1.0"
327 ffigen:
328 dependency: transitive
329 description:
@@ -450,6 +459,14 @@ packages:
459 url: "https://pub.dev"
460 source: hosted
461 version: "1.2.2"
462 + http2:
463 + dependency: transitive
464 + description:
465 + name: http2
466 + sha256: "9ced024a160b77aba8fb8674e38f70875e321d319e6f303ec18e87bd5a4b0c1d"
467 + url: "https://pub.dev"
468 + source: hosted
469 + version: "2.3.0"
470 http_multi_server:
471 dependency: transitive
472 description:
@@ -693,13 +710,13 @@ packages:
710 source: hosted
711 version: "2.1.8"
712 pointycastle:
696 - dependency: transitive
713 + dependency: "direct overridden"
714 description:
715 name: pointycastle
699 - sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe"
716 + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
717 url: "https://pub.dev"
718 source: hosted
702 - version: "3.9.1"
719 + version: "3.7.4"
720 pool:
721 dependency: transitive
722 description:
@@ -709,13 +726,13 @@ packages:
726 source: hosted
727 version: "1.5.1"
728 protobuf:
712 - dependency: transitive
729 + dependency: "direct overridden"
730 description:
731 name: protobuf
715 - sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08"
732 + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d"
733 url: "https://pub.dev"
734 source: hosted
718 - version: "2.1.0"
735 + version: "3.1.0"
736 provider:
737 dependency: transitive
738 description:
cw_core/lib/crypto_currency.dart
+2
@@ -106,6 +106,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
106 CryptoCurrency.usdcTrc20,
107 CryptoCurrency.tbtc,
108 CryptoCurrency.wow,
109 + CryptoCurrency.ton,
110 ];
111
112 static const havenCurrencies = [
@@ -223,6 +224,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
224 static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/images/usdc_icon.png', decimals: 6);
225 static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8);
226 static const wow = CryptoCurrency(title: 'WOW', fullName: 'Wownero', raw: 94, name: 'wow', iconPath: 'assets/images/wownero_icon.png', decimals: 11);
227 + static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/images/ton_icon.png', decimals: 8);
228
229
230 static final Map<int, CryptoCurrency> _rawCurrencyMap =
cw_core/lib/node.dart
+5 -2
@@ -239,12 +239,15 @@ class Node extends HiveObject with Keyable {
239 // you try to communicate with it
240 Future<bool> requestElectrumServer() async {
241 try {
242 + final Socket socket;
243 if (useSSL == true) {
243 - await SecureSocket.connect(uri.host, uri.port,
244 + socket = await SecureSocket.connect(uri.host, uri.port,
245 timeout: Duration(seconds: 5), onBadCertificate: (_) => true);
246 } else {
246 - await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5));
247 + socket = await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5));
248 }
249 +
250 + socket.destroy();
251 return true;
252 } catch (_) {
253 return false;
lib/entities/default_settings_migration.dart
+47 -5
@@ -1,3 +1,4 @@
1 +import 'dart:convert';
2 import 'dart:io' show Directory, File, Platform;
3 import 'package:cake_wallet/bitcoin/bitcoin.dart';
4 import 'package:cake_wallet/core/secure_storage.dart';
@@ -234,7 +235,8 @@ Future<void> defaultSettingsMigration(
235 break;
236 case 36:
237 await addWowneroNodeList(nodes: nodes);
237 - await changeWowneroCurrentNodeToDefault(sharedPreferences: sharedPreferences, nodes: nodes);
238 + await changeWowneroCurrentNodeToDefault(
239 + sharedPreferences: sharedPreferences, nodes: nodes);
240 break;
241 case 37:
242 await replaceTronDefaultNode(sharedPreferences: sharedPreferences, nodes: nodes);
@@ -249,6 +251,10 @@ Future<void> defaultSettingsMigration(
251 case 40:
252 await removeMoneroWorld(sharedPreferences: sharedPreferences, nodes: nodes);
253 break;
254 + case 41:
255 + _deselectQuantex(sharedPreferences);
256 + await _addSethNode(nodes, sharedPreferences);
257 + break;
258 default:
259 break;
260 }
@@ -263,6 +269,19 @@ Future<void> defaultSettingsMigration(
269 await sharedPreferences.setInt(PreferencesKey.currentDefaultSettingsMigrationVersion, version);
270 }
271
272 +void _deselectQuantex(SharedPreferences sharedPreferences) {
273 + final Map<String, dynamic> exchangeProvidersSelection =
274 + json.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}")
275 + as Map<String, dynamic>;
276 +
277 + exchangeProvidersSelection['Quantex'] = false;
278 +
279 + sharedPreferences.setString(
280 + PreferencesKey.exchangeProvidersSelection,
281 + json.encode(exchangeProvidersSelection),
282 + );
283 +}
284 +
285 void _fixNodesUseSSLFlag(Box<Node> nodes) {
286 for (Node node in nodes.values) {
287 switch (node.uriRaw) {
@@ -887,7 +906,30 @@ Future<void> changeDefaultBitcoinNode(
906 }
907 }
908
909 +Future<void> _addSethNode(Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
910 + _addBitcoinNode(
911 + nodeSource: nodeSource,
912 + sharedPreferences: sharedPreferences,
913 + nodeUri: "fulcrum.sethforprivacy.com:50002",
914 + useSSL: false,
915 + );
916 +}
917 +
918 Future<void> _addElectRsNode(Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
919 + _addBitcoinNode(
920 + nodeSource: nodeSource,
921 + sharedPreferences: sharedPreferences,
922 + nodeUri: cakeWalletSilentPaymentsElectrsUri,
923 + );
924 +}
925 +
926 +Future<void> _addBitcoinNode({
927 + required Box<Node> nodeSource,
928 + required SharedPreferences sharedPreferences,
929 + required String nodeUri,
930 + bool replaceExisting = false,
931 + bool useSSL = false,
932 +}) async {
933 const cakeWalletBitcoinNodeUriPattern = '.cakewallet.com';
934 final currentBitcoinNodeId =
935 sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
@@ -896,12 +938,11 @@ Future<void> _addElectRsNode(Box<Node> nodeSource, SharedPreferences sharedPrefe
938 final needToReplaceCurrentBitcoinNode =
939 currentBitcoinNode.uri.toString().contains(cakeWalletBitcoinNodeUriPattern);
940
899 - final newElectRsBitcoinNode =
900 - Node(uri: cakeWalletSilentPaymentsElectrsUri, type: WalletType.bitcoin, useSSL: false);
941 + final newElectRsBitcoinNode = Node(uri: nodeUri, type: WalletType.bitcoin, useSSL: useSSL);
942
943 await nodeSource.add(newElectRsBitcoinNode);
944
904 - if (needToReplaceCurrentBitcoinNode) {
945 + if (needToReplaceCurrentBitcoinNode && replaceExisting) {
946 await sharedPreferences.setInt(
947 PreferencesKey.currentBitcoinElectrumSererIdKey, newElectRsBitcoinNode.key as int);
948 }
@@ -1262,7 +1303,8 @@ Future<void> removeMoneroWorld(
1303 const cakeWalletMoneroNodeUriPattern = '.moneroworld.com';
1304 final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
1305 final currentMoneroNode = nodes.values.firstWhere((node) => node.key == currentMoneroNodeId);
1265 - final needToReplaceCurrentMoneroNode = currentMoneroNode.uri.toString().contains(cakeWalletMoneroNodeUriPattern);
1306 + final needToReplaceCurrentMoneroNode =
1307 + currentMoneroNode.uri.toString().contains(cakeWalletMoneroNodeUriPattern);
1308
1309 nodes.values.forEach((node) async {
1310 if (node.type == WalletType.monero &&
lib/main.dart
+1 -1
@@ -192,7 +192,7 @@ Future<void> initializeAppConfigs() async {
192 transactionDescriptions: transactionDescriptions,
193 secureStorage: secureStorage,
194 anonpayInvoiceInfo: anonpayInvoiceInfo,
195 - initialMigrationVersion: 40,
195 + initialMigrationVersion: 41,
196 );
197 }
198
lib/reactions/check_connection.dart
+2
@@ -11,6 +11,8 @@ Timer? _checkConnectionTimer;
11 void startCheckConnectionReaction(WalletBase wallet, SettingsStore settingsStore,
12 {int timeInterval = 5}) {
13 _checkConnectionTimer?.cancel();
14 + // TODO: check the validity of this code, and if it's working fine, then no need for
15 + // having the connect function in electrum.dart when the syncstatus is lost or failed and add the not connected state
16 _checkConnectionTimer = Timer.periodic(Duration(seconds: timeInterval), (_) async {
17 if (wallet.type == WalletType.bitcoin && wallet.syncStatus is SyncingSyncStatus) {
18 return;
lib/src/screens/receive/widgets/qr_image.dart
+1 -1
@@ -23,7 +23,7 @@ class QrImage extends StatelessWidget {
23 return qr.QrImageView(
24 data: data,
25 errorCorrectionLevel: errorCorrectionLevel,
26 - version: version ?? 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ???
26 + version: version ?? qr.QrVersions.auto,
27 size: size,
28 foregroundColor: foregroundColor,
29 backgroundColor: backgroundColor,
lib/utils/brightness_util.dart
+1 -4
@@ -9,15 +9,12 @@ class BrightnessUtil {
9 return;
10 }
11
12 - // Get the current brightness:
13 - final brightness = await DeviceDisplayBrightness.getBrightness();
14 -
12 // ignore: unawaited_futures
13 DeviceDisplayBrightness.setBrightness(1.0);
14
15 await func();
16
17 // ignore: unawaited_futures
21 - DeviceDisplayBrightness.setBrightness(brightness);
18 + DeviceDisplayBrightness.resetBrightness();
19 }
20 }
\ No newline at end of file