| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
| |
The zap dispatch parsed the invoice description and, when it wasn't JSON,
suppressed the error only if the message contained "Unexpected" — V8's parse-
error wording. On Bun the message is "Unable to parse JSON string", so every
paid invoice with a non-JSON memo logged a warning. Parse-then-check instead:
a non-JSON description is simply not a zap and is skipped silently; warn only
when an actual kind-9734 zap request fails to process.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- invoices: reject caller-supplied bolt11/bolt12; the server always mints its
own. Closes the invoice-registration path behind the shared-node credit and
payment-hijack vectors.
- lightning: skip mint-owned invoices (lbl* label) in the paid-invoice listener.
- payments: lightning free-tier fee credit, withheld for flagged high-throughput
(ln:nofree) accounts which pay an elevated rate; the failed-send reversal
restores credit at the same rate. freezeCheck made crash-resilient. Lightning
and bolt12 sends stay pending until the preimage settles.
- payments (route): validate payment-request / invoice input types.
- logging: collapse repeated xpay failure lines into one.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- sendLightning fetches an invoice from lno1 offers (payer_note passthrough
for NIP-177 zap intents) and pays it through the existing bolt12 path
- NWC: new nwc#2 pay/receive methods (BIP-321 URIs, payer proofs stubbed
until CLN 26.06 createproof), nip44_v2 alongside nip04 with per-request
scheme detection, dual 23196/23197 notifications, 13194 refreshed when
its content or encryption tag goes stale
- standing per-user bolt12 offer via GET /offer; incoming bolt12 payments
record invreq_payer_note as memo
- parse/fetchinvoice routes handle offers; zap display parses kind 9736
receipts (amount tag + embedded intent) and drops a call to a sync()
helper that never existed
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The zombie-listener watchdog (bd1ece38) treated "waitanyinvoice blocked > 5min
while cl is alive" as a stall — but that's NORMAL during quiet periods, so it
false-fired and needlessly recycled the cl listen socket every few minutes
(~26x in 6h on 2026-06-07). Receives still worked, but it was churn + noise and
would mask a genuine zombie.
Fix: a blocked long-poll is only a zombie if cl actually has a paid invoice the
listener isn't picking up. When blocked past the threshold, probe cl on the MAIN
socket with waitanyinvoice(pay_index, 2s server-side timeout): if it returns an
invoice there's a real backlog the wedged listener missed -> recycle; if it
times out (CLN code 904 = nothing waiting) the listener is just idle and healthy
-> leave it alone. Only recycle on a confirmed backlog.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
On 2026-06-04 cl restarted (autoheal, after its 15s healthcheck timed out),
and the app's waitanyinvoice long-poll hung on the now-dead listen socket.
listenerActive stayed true forever, so ensureListenerAlive never restarted
it, and incoming lightning payments stopped crediting for ~2h until a manual
app restart. The per-call RPC timeout in ln.ts can't catch this: waitanyinvoice
is intentionally in NO_TIMEOUT (it's meant to block).
Fix: ensureListenerAlive (runs every 120s) now also detects a stalled listener
— active but blocked in waitanyinvoice for >5min. It probes cl via the main
ln socket (getinfo); only if cl is actually alive does it treat the listen
socket as a zombie, call lnListen.reset() (new: drops the proxy's socket so the
next call reconnects), and re-arm. A listenerEpoch guard makes the wedged
invocation bow out when its waitanyinvoice finally rejects, so we never run two
listeners concurrently and never double-credit. Verified with a state-machine
test covering normal receive, quiet-but-healthy (left alone), stall+cl-alive
(recycled), stall+cl-down (left alone), and the no-double-listener race.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|