diff options
| author | Adam Soltys <[email protected]> | 2026-06-04 18:40:42 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-06-04 18:40:42 -0700 |
| commit | ce9616f62d0ac682c1e92956ef4cb48f053df27d (patch) | |
| tree | f8401db5038e7b7bca613dbe3cce4c15f0fa2aa9 | |
| parent | 0154bb060fad7650cd8b825a30a5d88e7018bf8d (diff) | |
| download | coinos-server-ce9616f62d0ac682c1e92956ef4cb48f053df27d.tar.gz coinos-server-ce9616f62d0ac682c1e92956ef4cb48f053df27d.zip | |
nwc: pay_invoice honors request amount for amountless bolt11
pay_invoice derived the amount solely from the decoded invoice, so an
amountless bolt11 yielded amount = round(undefined/1000) = NaN and
sendLightning rejected it with "Invalid amount". NIP-47 allows the client
to specify the amount (msat) in the request for exactly this case (AlbyHub
supports it; Alby Go and others hit the error). Fall back to the request's
`amount` field when the invoice carries none; invoice amount still takes
precedence when present, and a still-missing amount returns a clear error
instead of NaN. sendLightning/sendInternal already handle amountless
invoices given a valid amount — the bug was only the handler dropping it.
Fixes #83
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
| -rw-r--r-- | lib/nwc.ts | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -222,10 +222,22 @@ export default () => { const handle = (method, params, ev, app, user) => ({ async pay_invoice() { - const { invoice: pr, metadata } = params; + const { invoice: pr, metadata, amount: reqAmountMsat } = params; const { amount_msat, payee } = await ln.decode(pr); const { id } = await ln.getinfo(); - const amount = Math.round(amount_msat / 1000); + // For an amountless bolt11, the invoice carries no amount — NIP-47 lets the + // client specify it in the request's `amount` field (msat). Fall back to + // that so amountless invoices aren't rejected with "Invalid amount" + // (issue #83). Invoice amount takes precedence when present. + const amountMsat = amount_msat || reqAmountMsat; + if (!amountMsat) { + return error({ + code: "OTHER", + message: + "Amountless invoice requires an amount; specify amount (msat) in the request", + }); + } + const amount = Math.round(amountMsat / 1000); const { max_amount, max_fee, budget_renewal, pubkey, created } = app; const periods = { |
