fix: handle missing bolt11 in CLN list_payments for keysend/BOLT12

Follow-up to #290 — same class of bug, different code path.

list_payments() in cln_jrpc.py unconditionally indexed p["bolt11"] for any
incomplete payment, causing a KeyError -> the function returned None and
then list_all_tx() crashed with `TypeError: 'NoneType' object is not
iterable`, returning HTTP 500 to the Transactions view.

CLN's `listpays` does not include `bolt11` for keysend payments or for
BOLT12 offer payments, so any node that has ever made one of those will
hit this on every Transactions load.

Fix: guard the bolt11 decode the same way #290 guards invoice fields —
only decode when bolt11 is present, and fall back to amount_sent_msat
when neither bolt11 nor amount_msat are available, so the payment still
shows up in the list.

Reproduced on RaspiBlitz v1.12.1 with Core Lightning v25.12.1 and a
keysend payment in history.
This commit is contained in:
Justin Sharp 2026-05-06 10:58:05 -06:00 committed by fusion44
parent e33c11cb8a
commit d415fb30fd

View file

@ -415,8 +415,14 @@ class LnNodeCLNjRPC(LightningNodeBase):
continue
if include_incomplete:
b11_decoded = await self._decode_bolt11_cached(p["bolt11"])
p["amount_msat"] = b11_decoded.num_msat
# bolt11 is absent for keysend and BOLT12 payments — only
# decode it when present and amount_msat isn't already set.
bolt11 = p.get("bolt11")
if bolt11 and "amount_msat" not in p:
b11_decoded = await self._decode_bolt11_cached(bolt11)
p["amount_msat"] = b11_decoded.num_msat
elif "amount_msat" not in p:
p["amount_msat"] = p.get("amount_sent_msat", 0)
pays.append(Payment.from_cln_jrpc(p))
if reversed: