fix(lightning): never report a slow in-flight payment as failed
Slow multi-hop payments (>15s routing) surfaced as "Payment failed" while LND settled them in the background: the shared LND REST client's 15s total timeout aborted the synchronous /v1/channels/transactions wait, and every UI path treated that abort as a definitive failure. The payment then succeeded anyway and only appeared in history on the next background poll. Backend: lnd.payinvoice now decodes the invoice up front for its payment hash, pays on a dedicated 120s client, and answers status:"pending" with the hash (never an error) when the wait elapses after the payment was handed to LND — only a pre-connect failure is still a hard error. New lnd.paymentstatus RPC reports succeeded/failed/in_flight (with humanized failure reasons) from /v1/payments. Frontend: new rpcClient.payLightningInvoice() pays then polls lnd.paymentstatus to a real terminal state (3s interval, up to 2 min); all five call sites (send modal, scan modal, web5 unified send, peer-file purchase, app-launcher payments) migrated. Failure is only shown when LND itself declares FAILED; a still-settling payment shows an in-flight state and success fires the transaction refresh. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
aa272bfcf4
commit
9cd507269c
@@ -291,10 +291,10 @@ async function unifiedSend() {
|
||||
unifiedSendError.value = t('web5.pasteInvoice')
|
||||
return
|
||||
}
|
||||
const res = await rpcClient.call<{ payment_hash: string; amount_sats: number }>({
|
||||
method: 'lnd.payinvoice',
|
||||
params: { payment_request: unifiedSendDest.value.trim() },
|
||||
})
|
||||
// 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: unifiedSendDest.value.trim() })
|
||||
if (res.status === 'failed') throw new Error(res.failure_reason || 'Payment failed')
|
||||
sendResultHash.value = res.payment_hash
|
||||
} else {
|
||||
if (!unifiedSendDest.value.trim()) {
|
||||
|
||||
Reference in New Issue
Block a user