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