What changed, and why it matters
This commit only adds explanatory comments and a developer TODO note. It does not change any actual encryption logic, access controls, or behavior of the Electrum wallet. There is no security fix or vulnerability introduced by this change.
No action required for this commit. The TODO in wallet.py may warrant future refactoring to remove the fallback lightning private key derivation branch, but that is outside the scope of this documentation-only change.
Security signals we found
No functional code changes
Comments document existing encryption design choices
Developer TODO marks a fallback code branch as risky
Evidence from the diff
The diff adds docstring comments in lnworker.py and labels.py explaining that master public keys (xpub/fingerprint) are used to encrypt channel backups and labels because they are available in watching-only/hardware wallets. It also adds an inline comment in wallet.py noting that a fallback branch for deriving a lightning private key is a ‘footgun’ and should eventually be removed. No code behavior is altered.
Changed components
electrum/lnworker.pyelectrum/plugins/labels/labels.pyelectrum/wallet.pyInspect captured patch +21 / −0
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
index b532e5a..e73fb51 100644
--- a/electrum/lnworker.py
+++ b/electrum/lnworker.py
@@ -3610,6 +3610,20 @@ class LNWallet(Logger):
)
def export_channel_backup(self, channel_id):
+ """Historically, we allowed watching-only wallets and hardware wallets
+ to have lightning channels. Since these wallets do not have
+ private keys, we use their master public key to encrypt
+ channel backups. This allows users to import channel backups
+ in these wallets. Note that these are static backups: they
+ only allow to request a force close (and, in some scenarios,
+ to sweep funds after a channel has been force closed).
+
+ The creation of lightning channels in watching-only wallets
+ has been disabled for anchor channels. Note that it is still
+ possible to create non-anchor channels, see
+ config.ENABLE_ANCHOR_CHANNELS.
+
+ """
xpub = self.wallet.get_fingerprint()
backup_bytes = self.create_channel_backup(channel_id).to_bytes()
assert backup_bytes == ImportedChannelBackupStorage.from_bytes(backup_bytes).to_bytes(), "roundtrip failed"
diff --git a/electrum/plugins/labels/labels.py b/electrum/plugins/labels/labels.py
index 0b7dd75..ed44d4d 100644
--- a/electrum/plugins/labels/labels.py
+++ b/electrum/plugins/labels/labels.py
@@ -212,6 +212,10 @@ class LabelsPlugin(BasePlugin):
return asyncio.run_coroutine_threadsafe(self.push_thread(wallet), wallet.network.asyncio_loop).result()
def start_wallet(self, wallet: 'Abstract_Wallet'):
+ """Labels have the same level of privacy as the wallet transaction
+ history. Since the wallet master public key(s) give access to
+ the transaction history, we also use it to encrypt labels.
+ """
if not wallet.network:
return # 'offline' mode
mpk = wallet.get_fingerprint()
diff --git a/electrum/wallet.py b/electrum/wallet.py
index 00f5c93..29e2e52 100644
--- a/electrum/wallet.py
+++ b/electrum/wallet.py
@@ -548,6 +548,9 @@ class Abstract_Wallet(ABC, Logger, EventListener):
ln_xprv = self.keystore.get_lightning_xprv(password)
self.db.put('lightning_xprv', ln_xprv)
else:
+ # bip39 seeds and imported zprv.
+ # also, watching-only and hw wallets, if the user disables anchors.
+ # todo: we should kill that branch, it is a footgun.
seed = os.urandom(32)
node = BIP32Node.from_rootseed(seed, xtype='standard')
ln_xprv = node.to_xprv()
Why this scored 15/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.