Skip to content

fix(payments): poll NWC wallet for pending invoices (closes #89) - #92

Merged
v0l merged 1 commit into
mainfrom
fix/nwc-poll-pending-payments
Jul 17, 2026
Merged

fix(payments): poll NWC wallet for pending invoices (closes #89)#92
v0l merged 1 commit into
mainfrom
fix/nwc-poll-pending-payments

Conversation

@v0l

@v0l v0l commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Problem

Normal top-up invoices (payment_type = 0) created against an NWC backend are paid in the user's wallet but never marked paid or credited — user balance stays flat and Core spams Balance has run out. See #89.

Root cause

NWCNode::subscribe_invoices detected settlements only through NIP-47 push notifications (subscribe_to_notifications / PaymentReceived). NIP-47 notifications is an optional wallet capability — many wallets/relays never deliver it (or drop the subscription silently). Unlike the LNURLNode backend, the NWC path had no polling fallback, so paid invoices were stranded with is_paid = 0.

The existing reconcile_expired_nwc_payments only helps invoices already past expiry, and only as a one-off --reconcile-payments CLI run — it doesn't fix live traffic.

Fix

Add a 10s polling fallback in NWCNode::subscribe_invoices alongside the notification path:

  • pulls db.get_pending_payments()
  • looks up each via conn.lookup_invoice { payment_hash }
  • emits InvoiceUpdate::Settled (with preimage) when settled_at.is_some()

Both paths funnel through the existing try_complete_paymentdb.complete_payment, which is idempotent (where is_paid = false), so overlap between the notification and polling paths is harmless. This mirrors the existing LNURLNode poller and the reconcile_expired_nwc_payments settlement check.

NWCNode now carries a ZapStreamDb handle (like LNURLNode); NWCNode::new and the create_lightning NWC arm are updated accordingly.

Testing

  • cargo check -p zap-stream — clean, no new warnings.

Closes #89

The NWC backend only detected settlements via NIP-47 push notifications,
which are an optional wallet capability. Wallets/relays that don't deliver
them left paid top-up invoices stranded: never marked paid and never
credited to the user balance (issue #89).

Add a 10s polling fallback in NWCNode::subscribe_invoices that looks up each
pending invoice via lookup_invoice and emits InvoiceUpdate::Settled when
settled_at is set, mirroring the LNURL poller and reconcile logic. The
notification path is kept as the fast path; complete_payment is idempotent
so overlap is harmless.

Closes #89
@v0l
v0l merged commit 06de2b5 into main Jul 17, 2026
2 checks passed
@v0l
v0l deleted the fix/nwc-poll-pending-payments branch July 17, 2026 18:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Paid top-up invoices remain pending and do not credit user balance on latest

1 participant