-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Summary
When a user scans or pastes an amountless BOLT11 invoice (one with no num_msat field), the app decodes it correctly but navigates straight to the confirmation screen showing "0 sats" with no way to enter an amount. Pressing "Pay" sends a payment request to LNBits without an amount, which the server rejects.
Root Cause
_processBolt11Payment() always navigates to InvoiceConfirmScreen regardless of whether the decoded invoice has an amount:
// lib/screens/10send_screen.dart
final decodedInvoice = await _invoiceService.decodeBolt11(...);
// No check for amountSats == 0
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => InvoiceConfirmScreen(decodedInvoice: decodedInvoice),
),
);DecodedInvoice._parseAmount() correctly returns BigInt.zero for amountless invoices, so decodedInvoice.amountSats == 0. But InvoiceConfirmScreen has no input field for the user to specify an amount, and sendPayment() passes only the raw bolt11 to LNBits with no amount field — causing the server to return an error.
Steps to Reproduce
- Generate an amountless BOLT11 invoice (e.g. from BTCPay Server, a tip jar, or any BOLT11 generator with amount left blank).
- In LaChispa, go to Send and paste or scan the invoice.
- The confirmation screen shows "0 sats".
- Press "Pay".
- Payment fails with a server error. No sats are sent.
Expected Behavior
When an amountless invoice is detected (amountSats == 0), the app should prompt the user to enter the amount before proceeding to confirmation.
Fix
Detect the zero-amount case in _processBolt11Payment() and show an amount input dialog before navigating to confirmation:
final decodedInvoice = await _invoiceService.decodeBolt11(...);
if (decodedInvoice.amountSats == 0) {
// Amountless invoice — ask user for amount
final int? chosenAmount = await _showAmountInputDialog(context);
if (chosenAmount == null || !mounted) return; // user cancelled
// Pass the chosen amount to the confirmation screen and to sendPayment()
}InvoiceConfirmScreen and sendPayment() would also need to accept an optional overrideAmountSats parameter to forward the user-entered amount to the LNBits API.
Note: AmountScreen (11amount_screen.dart) is designed for LNURL-pay and Lightning Address flows and cannot be reused directly here without refactoring.
Impact
- Amountless invoices are commonly used for tip jars, donations, and BTCPay Server payment buttons
- Payment is completely broken for this invoice type — no workaround exists in the current UI
Affected Files
lib/screens/10send_screen.dart—_processBolt11Payment()lib/screens/12invoice_confirm_screen.dart— needsoverrideAmountSatslib/services/invoice_service.dart—sendPayment()needs amount param