fix(wallet): send amount_msat when paying an amountless invoice #162

Merged
padreug merged 1 commit from fix/wallet-amountless-invoice into dev 2026-09-22 21:06:01 +00:00
Owner

Paying a zero-amount BOLT11 always failed. The send dialog correctly showed an amount field for such an invoice, but the amount the user typed was then dropped: the request body carried only bolt11.

LNbits rejects that outright. _validate_payment_request raises "Amount required for amountless invoices." when the invoice has no amount and no amount_msat accompanies it. So the user filled in an amount and got an error back.

Approach

The invoice is decoded in the service rather than trusted from the caller, so every caller benefits and no call site has to remember the rule. light-bolt11-decoder was already a dependency.

  • Decoded amount is zero: forward the caller's amount as amount_msat.
  • Invoice carries its own amount: send nothing. The invoice amount is authoritative and must not be overridable by the caller.
  • Decode fails: send nothing and let the server decide whether the invoice is payable. A local decode hiccup should not block a valid payment.

Verification

Ran the helper against real inputs:

BOLT11 spec donation vector (amountless) -> 0        amount_msat sent
live 777-sat LNbits invoice              -> 777000   amount_msat omitted
malformed input                          -> null     defer to server

If the funding source has no amountless support, LNbits returns "Amountless invoices not supported by the funding source." and that message surfaces to the user, which is the right outcome.

vue-tsc --noEmit is clean.

Paying a zero-amount BOLT11 always failed. The send dialog correctly showed an amount field for such an invoice, but the amount the user typed was then dropped: the request body carried only `bolt11`. LNbits rejects that outright. `_validate_payment_request` raises "Amount required for amountless invoices." when the invoice has no amount and no `amount_msat` accompanies it. So the user filled in an amount and got an error back. ## Approach The invoice is decoded in the service rather than trusted from the caller, so every caller benefits and no call site has to remember the rule. `light-bolt11-decoder` was already a dependency. - Decoded amount is zero: forward the caller's amount as `amount_msat`. - Invoice carries its own amount: send nothing. The invoice amount is authoritative and must not be overridable by the caller. - Decode fails: send nothing and let the server decide whether the invoice is payable. A local decode hiccup should not block a valid payment. ## Verification Ran the helper against real inputs: ``` BOLT11 spec donation vector (amountless) -> 0 amount_msat sent live 777-sat LNbits invoice -> 777000 amount_msat omitted malformed input -> null defer to server ``` If the funding source has no amountless support, LNbits returns "Amountless invoices not supported by the funding source." and that message surfaces to the user, which is the right outcome. `vue-tsc --noEmit` is clean.
Paying a zero-amount BOLT11 always failed. The send dialog correctly
showed an amount field for such an invoice, but the amount the user
typed was then dropped: the request body carried only `bolt11`.

LNbits rejects that outright — `_validate_payment_request` raises
"Amount required for amountless invoices." when the invoice has no
amount and no `amount_msat` accompanies it. So the user filled in an
amount and got an error.

The invoice is now decoded in the service rather than trusted from the
caller, so every caller benefits and no call site has to remember. When
the decoded amount is zero we forward the caller's amount as
`amount_msat`; when the invoice carries its own amount we deliberately
send nothing, since the invoice amount is authoritative and must not be
overridable by the caller.

A decode failure returns null and sends nothing, leaving the server as
the authority on whether the invoice is payable.

Verified with light-bolt11-decoder:
  BOLT11 spec donation vector (amountless) -> 0      (amount_msat sent)
  live 777-sat LNbits invoice              -> 777000 (amount_msat omitted)
  malformed input                          -> null   (defer to server)
padreug deleted branch fix/wallet-amountless-invoice 2026-09-22 21:06:01 +00:00
Sign in to join this conversation.
No description provided.