feat(lightning): instant pay feedback, balances never vanish mid-payment
Demo images / Build & push demo images (push) Failing after 4m20s
Demo images / Build & push demo images (push) Failing after 4m20s
Framework-pt report: a paid invoice stalled the UI with no success shown, and lightning/total balances disappeared until it settled. Three compounding causes, three fixes: - Backend payinvoice's synchronous wait drops 120s → 8s. Fast payments (the majority) still settle in one round trip; slow multi-hop routes return pending + payment_hash quickly and the caller's 3s poll takes over — instead of the modal freezing for up to two minutes. - payLightningInvoice gains an onPending hook: SendBitcoinModal and the scan modal now flip to a visible "Settling…" success pane the moment the payment goes pending (safe to close), and the ongoing poll upgrades it to Paid — or replaces it with LND's real failure. - One slow lnd.getinfo poll (5s budget) flipped the Home wallet card to "disconnected", hiding balances the user already knew. Three consecutive failures are now required (~30s) before the card gives up; last-known balances keep rendering throughout. rpc-client tests 75/75. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
b7310ecfaf
commit
8bea3707ca
@@ -621,9 +621,28 @@ async function send() {
|
||||
} else if (method === 'lightning') {
|
||||
if (!dest.value.trim()) { error.value = t('web5.pasteInvoice'); return }
|
||||
// Waits out slow multi-hop routing and only reports failure when LND
|
||||
// itself declares the payment failed — never on a timeout.
|
||||
const res = await rpcClient.payLightningInvoice({ payment_request: dest.value.trim() })
|
||||
// itself declares the payment failed — never on a timeout. The moment
|
||||
// the payment goes pending (~8s), the success pane appears in
|
||||
// "settling…" mode instead of freezing the modal through the poll —
|
||||
// the poll keeps running and upgrades the pane when LND settles.
|
||||
const res = await rpcClient.payLightningInvoice(
|
||||
{ payment_request: dest.value.trim() },
|
||||
(hash) => {
|
||||
successInfo.value = {
|
||||
amount: paidAmount,
|
||||
methodLabel: 'Settling…',
|
||||
hash,
|
||||
note: 'Payment is on its way through the network. This pane updates the moment it settles — safe to close.',
|
||||
}
|
||||
confirming.value = false
|
||||
processing.value = false
|
||||
emit('sent')
|
||||
},
|
||||
)
|
||||
if (res.status === 'failed') {
|
||||
// If the settling pane is up, replace it with the failure — LND
|
||||
// declared this payment failed for real.
|
||||
successInfo.value = null
|
||||
error.value = res.failure_reason || t('web5.sendFailed')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -704,8 +704,18 @@ async function confirmSend() {
|
||||
const params: { payment_request: string; amount_sats?: number } = { payment_request: dest.value }
|
||||
if (!amountLocked.value && effectiveAmount.value > 0) params.amount_sats = effectiveAmount.value
|
||||
// Waits out slow multi-hop routing and only reports failure when LND
|
||||
// itself declares the payment failed — never on a timeout.
|
||||
const res = await rpcClient.payLightningInvoice(params)
|
||||
// itself declares the payment failed — never on a timeout. Pending
|
||||
// (~8s) jumps straight to the success pane in SETTLING mode instead of
|
||||
// spinning through the whole poll; the poll upgrades it to PAID.
|
||||
const res = await rpcClient.payLightningInvoice(params, (hash) => {
|
||||
successAmount.value = effectiveAmount.value
|
||||
successVerb.value = 'SETTLING'
|
||||
successDetail.value = 'Payment is on its way — this updates the moment it settles. Safe to close.'
|
||||
successRef.value = hash
|
||||
processing.value = false
|
||||
goTo('success')
|
||||
emit('sent')
|
||||
})
|
||||
if (res.status === 'failed') throw new Error(res.failure_reason || 'Payment failed')
|
||||
successAmount.value = res.amount_sats || effectiveAmount.value
|
||||
successVerb.value = res.status === 'pending' ? 'SENDING' : 'PAID'
|
||||
|
||||
Reference in New Issue
Block a user