CW-1152-Enable-selecting-used-addresses (#2483)

* allow selecting used Electrum addresses * fix ci issue

Serhii committed Aug 28, 2025 at 06:23 UTC ef85f512f9e031fd4b927ea5e1069d6a26207dca
2 files changed +26
cw_bitcoin/lib/electrum_wallet.dart
+2
@@ -2147,6 +2147,7 @@ abstract class ElectrumWalletBase
2147
2148 if (history.isNotEmpty) {
2149 addressRecord.setAsUsed();
2150 + walletAddresses.clearLockIfMatches(addressRecord.type, addressRecord.address);
2151
2152 await Future.wait(history.map((transaction) async {
2153 txid = transaction['tx_hash'] as String;
@@ -2353,6 +2354,7 @@ abstract class ElectrumWalletBase
2354 addressRecord.balance = confirmed + unconfirmed;
2355 if (confirmed > 0 || unconfirmed > 0) {
2356 addressRecord.setAsUsed();
2357 + walletAddresses.clearLockIfMatches(addressRecord.type, addressRecord.address);
2358 }
2359 }
2360
cw_bitcoin/lib/electrum_wallet_addresses.dart
+24
@@ -71,6 +71,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
71 currentSilentAddressIndex = initialSilentAddressIndex,
72 mwebAddresses =
73 ObservableList<BitcoinAddressRecord>.of((initialMwebAddresses ?? []).toSet()),
74 + lockedReceiveAddressByType = ObservableMap<BitcoinAddressType, String>(),
75 super(walletInfo) {
76 if (masterHd != null) {
77 silentAddress = SilentPaymentOwner.fromPrivateKeys(
@@ -121,6 +122,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
122 final Bip32Slip10Secp256k1 sideHd;
123 final bool isHardwareWallet;
124
125 + @observable
126 + ObservableMap<BitcoinAddressType, String> lockedReceiveAddressByType;
127 +
128 @observable
129 SilentPaymentOwner? silentAddress;
130
@@ -167,6 +171,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
171 return generateNewAddress().address;
172 }
173
174 + final locked = lockedReceiveAddressByType[addressPageType];
175 + if (locked != null) return locked;
176 +
177 final prev = previousAddressRecord;
178 if (prev != null && prev.type == addressPageType && !prev.isUsed) {
179 return prev.address;
@@ -199,14 +206,31 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
206 (addressRecord) => addressRecord.address == addr,
207 );
208
209 + lockedReceiveAddressByType.remove(addressPageType);
210 +
211 previousAddressRecord = addressRecord;
212 receiveAddresses.remove(addressRecord);
213 receiveAddresses.insert(0, addressRecord);
214 +
215 + if (isEnabledAutoGenerateSubaddress &&
216 + addressRecord.isUsed &&
217 + addressRecord.type == addressPageType) {
218 + lockedReceiveAddressByType[addressPageType] = addr;
219 + }
220 +
221 } catch (e) {
222 printV("ElectrumWalletAddressBase: set address ($addr): $e");
223 }
224 }
225
226 + @action
227 + void clearLockIfMatches(BitcoinAddressType type, String address) {
228 + final locked = lockedReceiveAddressByType[type];
229 + if (locked != null && locked == address) {
230 + lockedReceiveAddressByType.remove(type);
231 + }
232 + }
233 +
234 @override
235 String get primaryAddress => getAddress(index: 0, hd: mainHd, addressType: addressPageType);
236