Make SP scanning, wallet-specific (#2383)
Omar Hatem committed
Jul 12, 2025 at 19:58 UTC
ab5849c57df2af3e8f23ba4b4502aa45c3720eee
13 files changed
+34
-50
cw_bitcoin/lib/bitcoin_wallet.dart
+1
-2
@@ -168,7 +168,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
168
required Box<PayjoinSession> payjoinBox,
169
required String password,
170
required EncryptionFileUtils encryptionFileUtils,
171
- required bool alwaysScan,
171
}) async {
172
final network = walletInfo.network != null
173
? BasedUtxoNetwork.fromName(walletInfo.network!)
@@ -252,7 +251,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
251
initialChangeAddressIndex: snp?.changeAddressIndex,
252
addressPageType: snp?.addressPageType,
253
networkParam: network,
255
- alwaysScan: alwaysScan,
254
+ alwaysScan: snp?.alwaysScan,
255
payjoinBox: payjoinBox);
256
}
257
cw_bitcoin/lib/bitcoin_wallet_service.dart
+1
-5
@@ -23,12 +23,11 @@ class BitcoinWalletService extends WalletService<
23
BitcoinRestoreWalletFromWIFCredentials,
24
BitcoinRestoreWalletFromHardware> {
25
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource,
26
- this.payjoinSessionSource, this.alwaysScan, this.isDirect);
26
+ this.payjoinSessionSource, this.isDirect);
27
28
final Box<WalletInfo> walletInfoSource;
29
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
30
final Box<PayjoinSession> payjoinSessionSource;
31
- final bool alwaysScan;
31
final bool isDirect;
32
33
@override
@@ -84,7 +83,6 @@ class BitcoinWalletService extends WalletService<
83
walletInfo: walletInfo,
84
unspentCoinsInfo: unspentCoinsInfoSource,
85
payjoinBox: payjoinSessionSource,
87
- alwaysScan: alwaysScan,
86
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
87
);
88
await wallet.init();
@@ -98,7 +96,6 @@ class BitcoinWalletService extends WalletService<
96
walletInfo: walletInfo,
97
unspentCoinsInfo: unspentCoinsInfoSource,
98
payjoinBox: payjoinSessionSource,
101
- alwaysScan: alwaysScan,
99
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
100
);
101
await wallet.init();
@@ -133,7 +130,6 @@ class BitcoinWalletService extends WalletService<
130
walletInfo: currentWalletInfo,
131
unspentCoinsInfo: unspentCoinsInfoSource,
132
payjoinBox: payjoinSessionSource,
136
- alwaysScan: alwaysScan,
133
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
134
);
135
cw_bitcoin/lib/electrum_wallet.dart
+1
@@ -150,6 +150,7 @@ abstract class ElectrumWalletBase
150
}
151
}
152
153
+ @observable
154
bool? alwaysScan;
155
156
final Bip32Slip10Secp256k1 accountHD;
cw_bitcoin/lib/litecoin_wallet.dart
-1
@@ -210,7 +210,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
210
required WalletInfo walletInfo,
211
required Box<UnspentCoinsInfo> unspentCoinsInfo,
212
required String password,
213
- required bool alwaysScan,
213
required EncryptionFileUtils encryptionFileUtils,
214
}) async {
215
final hasKeysFile = await WalletKeysFile.hasKeysFile(name, walletInfo.type);
cw_bitcoin/lib/litecoin_wallet_service.dart
+1
-5
@@ -23,11 +23,10 @@ class LitecoinWalletService extends WalletService<
23
BitcoinRestoreWalletFromWIFCredentials,
24
BitcoinRestoreWalletFromHardware> {
25
LitecoinWalletService(
26
- this.walletInfoSource, this.unspentCoinsInfoSource, this.alwaysScan, this.isDirect);
26
+ this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
27
28
final Box<WalletInfo> walletInfoSource;
29
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
30
- final bool alwaysScan;
30
final bool isDirect;
31
32
@override
@@ -78,7 +77,6 @@ class LitecoinWalletService extends WalletService<
77
name: name,
78
walletInfo: walletInfo,
79
unspentCoinsInfo: unspentCoinsInfoSource,
81
- alwaysScan: alwaysScan,
80
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
81
);
82
await wallet.init();
@@ -91,7 +89,6 @@ class LitecoinWalletService extends WalletService<
89
name: name,
90
walletInfo: walletInfo,
91
unspentCoinsInfo: unspentCoinsInfoSource,
94
- alwaysScan: alwaysScan,
92
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
93
);
94
await wallet.init();
@@ -146,7 +143,6 @@ class LitecoinWalletService extends WalletService<
143
name: currentName,
144
walletInfo: currentWalletInfo,
145
unspentCoinsInfo: unspentCoinsInfoSource,
149
- alwaysScan: alwaysScan,
146
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
147
);
148
lib/bitcoin/cw_bitcoin.dart
+12
-4
@@ -231,15 +231,14 @@ class CWBitcoin extends Bitcoin {
231
Box<WalletInfo> walletInfoSource,
232
Box<UnspentCoinsInfo> unspentCoinSource,
233
Box<PayjoinSession> payjoinSessionSource,
234
- bool alwaysScan,
234
bool isDirect) {
235
return BitcoinWalletService(walletInfoSource, unspentCoinSource,
237
- payjoinSessionSource, alwaysScan, isDirect);
236
+ payjoinSessionSource, isDirect);
237
}
238
239
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource,
241
- Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
242
- return LitecoinWalletService(walletInfoSource, unspentCoinSource, alwaysScan, isDirect);
240
+ Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
241
+ return LitecoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
242
}
243
244
@override
@@ -580,6 +579,15 @@ class CWBitcoin extends Bitcoin {
579
bitcoinWallet.setSilentPaymentsScanning(active);
580
}
581
582
+ Future<void> setIsAlwaysScanningSP(Object wallet, bool active) async {
583
+ final bitcoinWallet = wallet as ElectrumWallet;
584
+ bitcoinWallet.alwaysScan = active;
585
+ bitcoinWallet.save();
586
+ }
587
+
588
+ @computed
589
+ bool getIsAlwaysScanningSP(Object wallet) => (wallet as ElectrumWallet).alwaysScan ?? false;
590
+
591
@override
592
bool isTestnet(Object wallet) {
593
final bitcoinWallet = wallet as ElectrumWallet;
lib/core/address_validator.dart
+1
-1
@@ -28,7 +28,7 @@ class AddressValidator extends TextValidator {
28
pattern: getPattern(type, isTestnet: isTestnet),
29
length: getLength(type));
30
31
- static String getPattern(CryptoCurrency type, {required bool isTestnet}) {
31
+ static String getPattern(CryptoCurrency type, {bool isTestnet = false}) {
32
var pattern = "";
33
if (type is Erc20Token) {
34
pattern = '0x[0-9a-zA-Z]+';
lib/di.dart
-3
@@ -76,7 +76,6 @@ import 'package:cake_wallet/entities/qr_view_data.dart';
76
import 'package:cake_wallet/entities/template.dart';
77
import 'package:cake_wallet/entities/transaction_description.dart';
78
import 'package:cake_wallet/ethereum/ethereum.dart';
79
-import 'package:cake_wallet/cake_pay/src/models/cake_pay_card.dart';
79
import 'package:cake_wallet/exchange/exchange_template.dart';
80
import 'package:cake_wallet/exchange/trade.dart';
81
import 'package:cake_wallet/monero/monero.dart';
@@ -1119,14 +1118,12 @@ Future<void> setup({
1118
_walletInfoSource,
1119
_unspentCoinsInfoSource,
1120
_payjoinSessionSource,
1122
- getIt.get<SettingsStore>().silentPaymentsAlwaysScan,
1121
SettingsStoreBase.walletPasswordDirectInput,
1122
);
1123
case WalletType.litecoin:
1124
return bitcoin!.createLitecoinWalletService(
1125
_walletInfoSource,
1126
_unspentCoinsInfoSource,
1129
- getIt.get<SettingsStore>().mwebAlwaysScan,
1127
SettingsStoreBase.walletPasswordDirectInput,
1128
);
1129
case WalletType.ethereum:
lib/entities/preferences_key.dart
-1
@@ -54,7 +54,6 @@ class PreferencesKey {
54
static const decredTransactionPriority = 'current_fee_priority_decred';
55
static const customBitcoinFeeRate = 'custom_electrum_fee_rate';
56
static const silentPaymentsCardDisplay = 'silentPaymentsCardDisplay';
57
- static const silentPaymentsAlwaysScan = 'silentPaymentsAlwaysScan';
57
static const mwebCardDisplay = 'mwebCardDisplay';
58
static const mwebEnabled = 'mwebEnabled';
59
static const hasEnabledMwebBefore = 'hasEnabledMwebBefore';
lib/store/settings_store.dart
-14
@@ -123,7 +123,6 @@ abstract class SettingsStoreBase with Store {
123
required this.showPayjoinCard,
124
required this.customBitcoinFeeRate,
125
required this.silentPaymentsCardDisplay,
126
- required this.silentPaymentsAlwaysScan,
126
required this.mwebAlwaysScan,
127
required this.mwebCardDisplay,
128
required this.mwebEnabled,
@@ -592,11 +591,6 @@ abstract class SettingsStoreBase with Store {
591
PreferencesKey.silentPaymentsCardDisplay, silentPaymentsCardDisplay);
592
});
593
595
- reaction(
596
- (_) => silentPaymentsAlwaysScan,
597
- (bool silentPaymentsAlwaysScan) => _sharedPreferences.setBool(
598
- PreferencesKey.silentPaymentsAlwaysScan, silentPaymentsAlwaysScan));
599
-
594
reaction(
595
(_) => mwebAlwaysScan,
596
(bool mwebAlwaysScan) =>
@@ -850,9 +844,6 @@ abstract class SettingsStoreBase with Store {
844
@observable
845
bool silentPaymentsCardDisplay;
846
853
- @observable
854
- bool silentPaymentsAlwaysScan;
855
-
847
@observable
848
bool mwebAlwaysScan;
849
@@ -1036,8 +1027,6 @@ abstract class SettingsStoreBase with Store {
1027
final customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
1028
final silentPaymentsCardDisplay =
1029
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
1039
- final silentPaymentsAlwaysScan =
1040
- sharedPreferences.getBool(PreferencesKey.silentPaymentsAlwaysScan) ?? false;
1030
final mwebAlwaysScan = sharedPreferences.getBool(PreferencesKey.mwebAlwaysScan) ?? false;
1031
final mwebCardDisplay = sharedPreferences.getBool(PreferencesKey.mwebCardDisplay) ?? true;
1032
final mwebEnabled = sharedPreferences.getBool(PreferencesKey.mwebEnabled) ?? false;
@@ -1341,7 +1330,6 @@ abstract class SettingsStoreBase with Store {
1330
showPayjoinCard: showPayjoinCard,
1331
customBitcoinFeeRate: customBitcoinFeeRate,
1332
silentPaymentsCardDisplay: silentPaymentsCardDisplay,
1344
- silentPaymentsAlwaysScan: silentPaymentsAlwaysScan,
1333
mwebAlwaysScan: mwebAlwaysScan,
1334
mwebCardDisplay: mwebCardDisplay,
1335
mwebEnabled: mwebEnabled,
@@ -1525,8 +1513,6 @@ abstract class SettingsStoreBase with Store {
1513
customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
1514
silentPaymentsCardDisplay =
1515
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
1528
- silentPaymentsAlwaysScan =
1529
- sharedPreferences.getBool(PreferencesKey.silentPaymentsAlwaysScan) ?? false;
1516
mwebAlwaysScan = sharedPreferences.getBool(PreferencesKey.mwebAlwaysScan) ?? false;
1517
mwebCardDisplay = sharedPreferences.getBool(PreferencesKey.mwebCardDisplay) ?? true;
1518
mwebEnabled = sharedPreferences.getBool(PreferencesKey.mwebEnabled) ?? false;
lib/view_model/buy/buy_sell_view_model.dart
+11
-10
@@ -12,7 +12,6 @@ import 'package:cake_wallet/entities/provider_types.dart';
12
import 'package:cake_wallet/generated/i18n.dart';
13
import 'package:cake_wallet/routes.dart';
14
import 'package:cake_wallet/store/app_store.dart';
15
-import 'package:cake_wallet/themes/core/material_base_theme.dart';
15
import 'package:cw_core/crypto_currency.dart';
16
import 'package:flutter/cupertino.dart';
17
import 'package:intl/intl.dart';
@@ -89,7 +88,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
88
return isBuyAction ? formattedFiatAmount : formattedCryptoAmount;
89
}
90
92
- AppStore _appStore;
91
+ final AppStore _appStore;
92
93
Quote? bestRateQuote;
94
@@ -315,14 +314,16 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
314
...outOfLimitQuotes,
315
]);
316
318
- await Navigator.of(context).pushNamed(
319
- Routes.buyOptionsPage,
320
- arguments: [
321
- updatedQuoteOptions,
322
- changeOption,
323
- launchTrade,
324
- ],
325
- ).then((value) => calculateBestRate());
317
+ if (context.mounted) {
318
+ await Navigator.of(context).pushNamed(
319
+ Routes.buyOptionsPage,
320
+ arguments: [
321
+ updatedQuoteOptions,
322
+ changeOption,
323
+ launchTrade,
324
+ ],
325
+ ).then((value) => calculateBestRate());
326
+ }
327
}
328
329
void _onPairChange() {
lib/view_model/settings/silent_payments_settings_view_model.dart
+2
-2
@@ -18,7 +18,7 @@ abstract class SilentPaymentsSettingsViewModelBase with Store {
18
bool get silentPaymentsCardDisplay => _settingsStore.silentPaymentsCardDisplay;
19
20
@computed
21
- bool get silentPaymentsAlwaysScan => _settingsStore.silentPaymentsAlwaysScan;
21
+ bool get silentPaymentsAlwaysScan => bitcoin!.getIsAlwaysScanningSP(_wallet);
22
23
@action
24
void setSilentPaymentsCardDisplay(bool value) {
@@ -27,7 +27,7 @@ abstract class SilentPaymentsSettingsViewModelBase with Store {
27
28
@action
29
void setSilentPaymentsAlwaysScan(bool value) {
30
- _settingsStore.silentPaymentsAlwaysScan = value;
30
+ bitcoin!.setIsAlwaysScanningSP(_wallet, value);
31
if (value) bitcoin!.setScanningActive(_wallet, true);
32
}
33
}
tool/configure.dart
+4
-2
@@ -192,8 +192,8 @@ abstract class Bitcoin {
192
List<Unspent> getUnspents(Object wallet, {UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any});
193
Future<void> updateUnspents(Object wallet);
194
WalletService createBitcoinWalletService(
195
- Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, Box<PayjoinSession> payjoinSessionSource, bool alwaysScan, bool isDirect);
196
- WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect);
195
+ Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, Box<PayjoinSession> payjoinSessionSource, bool isDirect);
196
+ WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
197
TransactionPriority getBitcoinTransactionPriorityMedium();
198
TransactionPriority getBitcoinTransactionPriorityCustom();
199
TransactionPriority getLitecoinTransactionPriorityMedium();
@@ -216,6 +216,8 @@ abstract class Bitcoin {
216
bool hasTaprootInput(PendingTransaction pendingTransaction);
217
bool getScanningActive(Object wallet);
218
Future<void> setScanningActive(Object wallet, bool active);
219
+ Future<void> setIsAlwaysScanningSP(Object wallet, bool active);
220
+ bool getIsAlwaysScanningSP(Object wallet);
221
bool isTestnet(Object wallet);
222
223
Future<PendingTransaction> replaceByFee(Object wallet, String transactionHash, String fee);