V4.26.0 rc (#2198)
* v4.26.0 Release Candidate * Fix Wownero Creation issue * Add KES fiat currency * Adjust backup to default node selection if null Gracefully handle Decred failure Minor fixes
Omar Hatem committed
Apr 15, 2025 at 02:50 UTC
ca564bc2e66172cffc84eced4d9bea88dabed1ac
8 files changed
+78
-51
cw_decred/lib/wallet.dart
+1
-1
@@ -222,7 +222,7 @@ abstract class DecredWalletBase
222
223
Future<bool> checkSync() async {
224
final syncStatusJSON = await _libwallet.syncStatus(walletInfo.name);
225
- final decoded = json.decode(syncStatusJSON);
225
+ final decoded = json.decode(syncStatusJSON.isEmpty ? "{}" : syncStatusJSON);
226
227
final syncStatusCode = decoded["syncstatuscode"] ?? 0;
228
// final syncStatusStr = decoded["syncstatus"] ?? "";
lib/core/utilities.dart
new
+9
@@ -0,0 +1,9 @@
1
+extension EnhancedList<T> on Iterable<T> {
2
+ T? firstWhereOrNull(bool Function(T element) test) {
3
+ try {
4
+ return firstWhere(test);
5
+ } catch (e) {
6
+ return null;
7
+ }
8
+ }
9
+}
\ No newline at end of file
lib/src/screens/backup/backup_page.dart
+4
-3
@@ -3,10 +3,9 @@ import 'package:cake_wallet/core/execution_state.dart';
3
import 'package:cake_wallet/src/screens/base_page.dart';
4
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
5
import 'package:cake_wallet/src/widgets/primary_button.dart';
6
-import 'package:cake_wallet/src/widgets/trail_button.dart';
6
import 'package:cake_wallet/generated/i18n.dart';
8
-import 'package:cake_wallet/palette.dart';
7
import 'package:cake_wallet/routes.dart';
8
+import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
9
import 'package:cake_wallet/utils/clipboard_util.dart';
10
import 'package:cake_wallet/utils/exception_handler.dart';
11
import 'package:cake_wallet/utils/share_util.dart';
@@ -76,7 +75,9 @@ class BackupPage extends BasePage {
75
Navigator.of(context).pushNamed(Routes.editBackupPassword),
76
text: S.of(context).change_password,
77
color: Theme.of(context).cardColor,
79
- textColor: Colors.white,
78
+ textColor: Theme.of(context)
79
+ .extension<CakeTextTheme>()!
80
+ .buttonTextColor,
81
),
82
SizedBox(height: 10),
83
Observer(
lib/src/widgets/primary_button.dart
+1
-1
@@ -104,7 +104,7 @@ class LoadingPrimaryButton extends StatelessWidget {
104
),
105
)),
106
child: isLoading
107
- ? CupertinoActivityIndicator(animating: true)
107
+ ? CupertinoActivityIndicator(animating: true, color: textColor)
108
: Text(text,
109
style: TextStyle(
110
fontSize: 15.0,
lib/store/settings_store.dart
+32
-24
@@ -3,6 +3,7 @@ import 'dart:convert';
3
import 'dart:io';
4
5
import 'package:cake_wallet/bitcoin/bitcoin.dart';
6
+import 'package:cake_wallet/core/utilities.dart';
7
import 'package:cake_wallet/decred/decred.dart';
8
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
9
import 'package:cake_wallet/core/secure_storage.dart';
@@ -12,13 +13,13 @@ import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
13
import 'package:cake_wallet/entities/balance_display_mode.dart';
14
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
15
import 'package:cake_wallet/entities/country.dart';
16
+import 'package:cake_wallet/entities/default_settings_migration.dart';
17
import 'package:cake_wallet/entities/exchange_api_mode.dart';
18
import 'package:cake_wallet/entities/fiat_api_mode.dart';
19
import 'package:cake_wallet/entities/fiat_currency.dart';
20
import 'package:cake_wallet/entities/language_service.dart';
21
import 'package:cake_wallet/entities/pin_code_required_duration.dart';
22
import 'package:cake_wallet/entities/preferences_key.dart';
21
-import 'package:cake_wallet/entities/provider_types.dart';
23
import 'package:cake_wallet/entities/secret_store_key.dart';
24
import 'package:cake_wallet/entities/seed_phrase_length.dart';
25
import 'package:cake_wallet/entities/seed_type.dart';
@@ -37,11 +38,8 @@ import 'package:cake_wallet/themes/theme_list.dart';
38
import 'package:cake_wallet/utils/device_info.dart';
39
import 'package:cake_wallet/utils/package_info.dart';
40
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
40
-import 'package:cake_wallet/wallet_type_utils.dart';
41
-import 'package:cake_wallet/wownero/wownero.dart';
41
import 'package:cw_core/node.dart';
42
import 'package:cw_core/set_app_secure_native.dart';
44
-import 'package:cw_core/transaction_priority.dart';
43
import 'package:cw_core/utils/print_verbose.dart';
44
import 'package:cw_core/wallet_type.dart';
45
import 'package:device_info_plus/device_info_plus.dart';
@@ -312,7 +310,7 @@ abstract class SettingsStoreBase with Store {
310
311
reaction((_) => disableTradeOption,
312
(bool disableTradeOption) => sharedPreferences.setBool(PreferencesKey.disableTradeOption, disableTradeOption));
315
-
313
+
314
reaction(
315
(_) => disableBulletin,
316
(bool disableBulletin) =>
@@ -1038,7 +1036,6 @@ abstract class SettingsStoreBase with Store {
1036
sharedPreferences.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
1037
final bitcoinCashElectrumServerId =
1038
sharedPreferences.getInt(PreferencesKey.currentBitcoinCashNodeIdKey);
1041
- final havenNodeId = sharedPreferences.getInt(PreferencesKey.currentHavenNodeIdKey);
1039
final ethereumNodeId = sharedPreferences.getInt(PreferencesKey.currentEthereumNodeIdKey);
1040
final polygonNodeId = sharedPreferences.getInt(PreferencesKey.currentPolygonNodeIdKey);
1041
final nanoNodeId = sharedPreferences.getInt(PreferencesKey.currentNanoNodeIdKey);
@@ -1048,20 +1045,35 @@ abstract class SettingsStoreBase with Store {
1045
final wowneroNodeId = sharedPreferences.getInt(PreferencesKey.currentWowneroNodeIdKey);
1046
final zanoNodeId = sharedPreferences.getInt(PreferencesKey.currentZanoNodeIdKey);
1047
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
1051
- final moneroNode = nodeSource.get(nodeId);
1052
- final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
1053
- final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
1054
- final havenNode = nodeSource.get(havenNodeId);
1055
- final ethereumNode = nodeSource.get(ethereumNodeId);
1056
- final polygonNode = nodeSource.get(polygonNodeId);
1057
- final bitcoinCashElectrumServer = nodeSource.get(bitcoinCashElectrumServerId);
1058
- final nanoNode = nodeSource.get(nanoNodeId);
1059
- final decredNode = nodeSource.get(decredNodeId);
1060
- final nanoPowNode = powNodeSource.get(nanoPowNodeId);
1061
- final solanaNode = nodeSource.get(solanaNodeId);
1062
- final tronNode = nodeSource.get(tronNodeId);
1063
- final wowneroNode = nodeSource.get(wowneroNodeId);
1064
- final zanoNode = nodeSource.get(zanoNodeId);
1048
+
1049
+ /// get the selected node, if null, then use the default
1050
+ final moneroNode = nodeSource.get(nodeId) ??
1051
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == newCakeWalletMoneroUri);
1052
+ final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId) ??
1053
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == newCakeWalletBitcoinUri);
1054
+ final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId) ??
1055
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == cakeWalletLitecoinElectrumUri);
1056
+ final ethereumNode = nodeSource.get(ethereumNodeId) ??
1057
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == ethereumDefaultNodeUri);
1058
+ final polygonNode = nodeSource.get(polygonNodeId) ??
1059
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == polygonDefaultNodeUri);
1060
+ final bitcoinCashElectrumServer = nodeSource.get(bitcoinCashElectrumServerId) ??
1061
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
1062
+ final nanoNode = nodeSource.get(nanoNodeId) ??
1063
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == nanoDefaultNodeUri);
1064
+ final decredNode = nodeSource.get(decredNodeId) ??
1065
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == decredDefaultUri);
1066
+ final nanoPowNode = powNodeSource.get(nanoPowNodeId) ??
1067
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == nanoDefaultPowNodeUri);
1068
+ final solanaNode = nodeSource.get(solanaNodeId) ??
1069
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == solanaDefaultNodeUri);
1070
+ final tronNode = nodeSource.get(tronNodeId) ??
1071
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == tronDefaultNodeUri);
1072
+ final wowneroNode = nodeSource.get(wowneroNodeId) ??
1073
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
1074
+ final zanoNode = nodeSource.get(zanoNodeId) ??
1075
+ nodeSource.values.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
1076
+
1077
final packageInfo = await PackageInfo.fromPlatform();
1078
final deviceName = await _getDeviceName() ?? '';
1079
final shouldShowYatPopup = sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
@@ -1107,10 +1119,6 @@ abstract class SettingsStoreBase with Store {
1119
nodes[WalletType.litecoin] = litecoinElectrumServer;
1120
}
1121
1110
- if (havenNode != null) {
1111
- nodes[WalletType.haven] = havenNode;
1112
- }
1113
-
1122
if (ethereumNode != null) {
1123
nodes[WalletType.ethereum] = ethereumNode;
1124
}
lib/view_model/anon_invoice_page_view_model.dart
+28
-20
@@ -107,20 +107,24 @@ abstract class AnonInvoicePageViewModelBase with Store {
107
return;
108
}
109
}
110
- final result = await anonPayApi.createInvoice(AnonPayRequest(
111
- cryptoCurrency: cryptoCurrency,
112
- address: address,
113
- amount: amount.isEmpty ? null : amount,
114
- description: description,
115
- email: receipientEmail,
116
- name: receipientName,
117
- fiatEquivalent:
118
- selectedCurrency is FiatCurrency ? (selectedCurrency as FiatCurrency).raw : null,
119
- ));
120
-
121
- _anonpayInvoiceInfoSource.add(result);
122
-
123
- state = ExecutedSuccessfullyState(payload: result);
110
+ try {
111
+ final result = await anonPayApi.createInvoice(AnonPayRequest(
112
+ cryptoCurrency: cryptoCurrency,
113
+ address: address,
114
+ amount: amount.isEmpty ? null : amount,
115
+ description: description,
116
+ email: receipientEmail,
117
+ name: receipientName,
118
+ fiatEquivalent:
119
+ selectedCurrency is FiatCurrency ? (selectedCurrency as FiatCurrency).raw : null,
120
+ ));
121
+
122
+ _anonpayInvoiceInfoSource.add(result);
123
+
124
+ state = ExecutedSuccessfullyState(payload: result);
125
+ } catch (e) {
126
+ state = FailureState(e.toString());
127
+ }
128
}
129
130
@action
@@ -156,12 +160,16 @@ abstract class AnonInvoicePageViewModelBase with Store {
160
}
161
162
Future<void> _fetchLimits() async {
159
- final limit = await anonPayApi.fetchLimits(
160
- cryptoCurrency: cryptoCurrency,
161
- fiatCurrency: selectedCurrency is FiatCurrency ? selectedCurrency as FiatCurrency : null,
162
- );
163
- minimum = limit.min;
164
- maximum = limit.max != null ? limit.max! / 4 : null;
163
+ try {
164
+ final limit = await anonPayApi.fetchLimits(
165
+ cryptoCurrency: cryptoCurrency,
166
+ fiatCurrency: selectedCurrency is FiatCurrency ? selectedCurrency as FiatCurrency : null,
167
+ );
168
+ minimum = limit.min;
169
+ maximum = limit.max != null ? limit.max! / 4 : null;
170
+ } catch (e) {
171
+ state = FailureState(e.toString());
172
+ }
173
}
174
175
@computed
lib/view_model/hardware_wallet/ledger_view_model.dart
+3
-1
@@ -137,7 +137,9 @@ abstract class LedgerViewModelBase with Store {
137
allowChangeWallet: true,
138
isReconnect: true,
139
onConnectDevice: (context, ledgerVM) async {
140
- Navigator.of(context).pop();
140
+ if (context.mounted) {
141
+ Navigator.of(context).pop();
142
+ }
143
},
144
),
145
);
lib/view_model/wallet_list/wallet_list_view_model.dart
-1
@@ -216,7 +216,6 @@ abstract class WalletListViewModelBase with Store {
216
await sortGroupByType();
217
break;
218
case FilterListOrderType.Custom:
219
- default:
219
await reorderAccordingToWalletList();
220
break;
221
}