guard regeneration of lightning address
What changed, and why it matters
This commit prevents users from rotating (regenerating) a Bitcoin Lightning address in the Cake Wallet app. Previously, the app may have allowed address regeneration for Lightning addresses, which could cause confusion, lost incoming payments, or funds sent to an old/unexpected address. The fix adds a guard that throws an error if code tries to rotate a Lightning address, and updates the UI logic to recognize when a Lightning address type is selected.
Treat as a low-severity hardening fix. Verify that all user-facing paths that trigger address regeneration are covered by the new guard, and ensure the thrown exception is handled gracefully in the UI rather than crashing the app.
Security signals we found
Prevents unsupported address rotation that could lead to loss of incoming Lightning payments
Adds explicit runtime exception to guard against invalid state transitions
UI state now correctly reflects Lightning address selection
No cryptographic, authentication, or network-layer changes
Evidence from the diff
The patch adds a runtime guard in ElectrumWalletAddressesBase.generateNewAddress() that throws if addressPageType is LightningAddressType. It also introduces a new Bitcoin interface method hasSelectedLightning() and updates WalletAddressListViewModelBase.isLightning to use it. A missing import for LightningAddressType is added in tool/configure.dart. The change is defensive: it blocks an unsupported operation rather than fixing a remote-exploitable vulnerability.
Changed components
cw_bitcoin/lib/electrum_wallet_addresses.dartlib/bitcoin/cw_bitcoin.dartlib/view_model/wallet_address_list/wallet_address_list_view_model.darttool/configure.dartInspect captured patch +14 / −1
diff --git a/cw_bitcoin/lib/electrum_wallet_addresses.dart b/cw_bitcoin/lib/electrum_wallet_addresses.dart
index 239977ec..0beb02d2 100644
--- a/cw_bitcoin/lib/electrum_wallet_addresses.dart
+++ b/cw_bitcoin/lib/electrum_wallet_addresses.dart
@@ -442,6 +442,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
@action
BaseBitcoinAddressRecord generateNewAddress({String label = ''}) {
+ if (addressPageType is LightningAddressType) {
+ throw Exception("Lightning addresses cannot be rotated");
+ }
+
if (addressPageType == SilentPaymentsAddresType.p2sp && silentAddress != null) {
final currentSilentAddressIndex = silentAddresses
.where((addressRecord) => addressRecord.type != SegwitAddresType.p2tr)
diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart
index ae101831..c2343dfe 100644
--- a/lib/bitcoin/cw_bitcoin.dart
+++ b/lib/bitcoin/cw_bitcoin.dart
@@ -317,6 +317,12 @@ class CWBitcoin extends Bitcoin {
return bitcoinWallet.walletAddresses.addressPageType == SilentPaymentsAddresType.p2sp;
}
+ @override
+ bool hasSelectedLightning(Object wallet) {
+ final bitcoinWallet = wallet as ElectrumWallet;
+ return bitcoinWallet.walletAddresses.addressPageType is LightningAddressType;
+ }
+
@override
BitcoinAddressType getBitcoinAddressType(ReceivePageOption option) {
switch (option) {
diff --git a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
index 0610381c..9841661d 100644
--- a/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
+++ b/lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
@@ -614,7 +614,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
@computed
bool get isLightning =>
- wallet.type == WalletType.bitcoin && selectedCurrency == CryptoCurrency.btcln;
+ wallet.type == WalletType.bitcoin &&
+ (selectedCurrency == CryptoCurrency.btcln || bitcoin!.hasSelectedLightning(wallet));
@computed
bool get isZCashTransparent {
diff --git a/tool/configure.dart b/tool/configure.dart
index 19e1521f..93cb2d59 100644
--- a/tool/configure.dart
+++ b/tool/configure.dart
@@ -149,6 +149,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
+import 'package:cw_bitcoin/lightning/lightning_addres_type.dart';
import 'package:cw_bitcoin/lightning/pending_lightning_transaction.dart';
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
import 'package:cw_bitcoin/litecoin_wallet.dart';
@@ -245,6 +246,7 @@ abstract class Bitcoin {
ReceivePageOption getLitecoinMwebReceivePageOption();
bool isPayjoinAvailable(Object wallet);
bool hasSelectedSilentPayments(Object wallet);
+ bool hasSelectedLightning(Object wallet);
bool isBitcoinReceivePageOption(ReceivePageOption option);
BitcoinAddressType getOptionToType(ReceivePageOption option);
bool hasTaprootInput(PendingTransaction pendingTransaction);
Why this scored 37/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.