plugin: nwc: consider inflight htlcs in get_payment_info
What changed, and why it matters
This commit fixes a bug in Electrum's Nostr Wallet Connect (NWC) plugin where the reported amount and fee for a Lightning payment could be temporarily wrong right after the payment succeeds. Previously, the code only looked at fully settled payment parts. If one part had settled but others were still in flight, the plugin could report an incomplete or zero amount/fee. The fix now includes still-in-flight payment parts when calculating the total, assuming they will also settle. This is mainly a correctness/reliability fix, not a direct theft-of-funds vulnerability, but incorrect payment info could mislead connected apps or users.
Treat as a routine bug-fix patch with low-to-moderate security relevance. Users running NWC should update to include this fix to avoid incorrect payment reporting. No immediate incident response is indicated unless connected NWC applications made automated decisions based on the transiently wrong values.
Security signals we found
Incorrect financial amount/fee reporting in payment info API
Race condition between HTLC settlement state and API query
Multi-part Lightning payment state handling bug
NWC plugin data consistency fix
Evidence from the diff
In electrum/plugins/nwc/nwcserver.py, get_payment_info() previously called lnworker.get_payments(status=’settled’) and then computed the payment value from the returned HTLC list. Because get_payments(‘settled’) returns only HTLCs whose status is ‘settled’, a multi-part payment that had just partially settled could return an incomplete plist. The patch changes the query to status=None (all HTLCs for the payment hash), checks that at least one HTLC is settled, then filters to active_htlcs = settled + inflight and passes that subset to get_payment_value(). The code comment explicitly states the assumption that all inflight HTLCs will eventually settle. This prevents transient under-reporting of amount/fees immediately after payment success.
Changed components
electrum/plugins/nwc/nwcserver.pyNWC plugin get_payment_info methodLightning payment info reportingInspect captured patch +5 / −3
diff --git a/electrum/plugins/nwc/nwcserver.py b/electrum/plugins/nwc/nwcserver.py
index bd82509..2abffe7 100644
--- a/electrum/plugins/nwc/nwcserver.py
+++ b/electrum/plugins/nwc/nwcserver.py
@@ -979,13 +979,15 @@ class NWCServer(Logger, EventListener):
def get_payment_info(self, payment_hash: str) \
-> Optional[Tuple[PaymentDirection, int, Optional[int], int]]:
payment_hash: bytes = bytes.fromhex(payment_hash)
- payments = self.wallet.lnworker.get_payments(status='settled')
+ payments = self.wallet.lnworker.get_payments(status=None)
plist = payments.get(payment_hash)
- if plist:
+ if plist and any(htlc.status == 'settled' for htlc in plist):
direction = plist[0].direction
info = self.wallet.lnworker.get_payment_info(payment_hash, direction=direction)
if info:
- dir, amount, fee, ts = self.wallet.lnworker.get_payment_value(info, plist)
+ # assumes inflight htlcs will get settled and counts them into the payment values
+ active_htlcs = [htlc for htlc in plist if htlc.status in ('settled', 'inflight')]
+ dir, amount, fee, ts = self.wallet.lnworker.get_payment_value(info, active_htlcs)
fee = abs(fee) if fee else None
return dir, abs(amount), fee, ts
return None
Why this scored 35/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.