Skip to content

Surface failed and pending outbound payments in list_transactions - #89

Open
hash-money wants to merge 1 commit into
lightningdevkit:masterfrom
emergent-money:fix/surface-failed-outbound-payments
Open

Surface failed and pending outbound payments in list_transactions#89
hash-money wants to merge 1 commit into
lightningdevkit:masterfrom
emergent-money:fix/surface-failed-outbound-payments

Conversation

@hash-money

Copy link
Copy Markdown
Contributor

list_transactions currently hides every payment whose status isn't Completed, on both mapping paths. The comment justifies hiding issued-but-unpaid inbound invoices — but the condition also swallows failed and in-flight outbound payments, so a failed send leaves no record at all. A wallet UI built on list_transactions can't show users what happened to a payment they made (downstream report: emergent-money/graduated-wallet#328 — our UI already renders a failed status for records it receives, they just never arrive).

This keeps the unpaid-inbound filtering and surfaces outbound attempts regardless of status:

  • should_surface_lightning_payment_without_metadata gains the payment direction; outbound always surfaces.
  • The trusted-payment fallback branch gets the same !outbound && guard.

Unit tests: failed/pending outbound listed, inbound failure (expired unpaid invoice) still hidden; existing pending-onchain cases updated for the new parameter. cargo test -p orange-sdk --lib 17/17.

Both mapping paths hid every non-Completed payment. The comment
justified hiding issued-but-unpaid inbound invoices, but the condition
also swallowed failed and in-flight *outbound* payments — a failed send
leaves no record in the wallet's transaction list at all, and a UI
built on list_transactions cannot show the user what happened.

Hide only non-completed inbound records (unpaid invoices/quotes stay
noise); outbound attempts always surface. Applies to both the
self-custodial path (should_surface_lightning_payment_without_metadata
gains the direction) and the trusted-payment fallback branch.

Observed downstream (emergent-money/graduated-wallet#328): a failed
BOLT11 send was absent from history while the UI already renders a
'failed' status for records it receives.

@benthecarman benthecarman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather not put all these in the list_transactions function, would adding a get_transaction function fix your usecase here so you can track an individual payment state?

@hash-money

Copy link
Copy Markdown
Contributor Author

Sorry for the slow turnaround, and thanks for taking a look.

Honest answer: get_transaction(payment_id) wouldn't close it, because the failures that matter most never produce an id. When every method is exhausted, Wallet::pay() returns Err (the tail of pay, lib.rs:1477) — the caller gets a WalletError and no PaymentId. Insufficient funds, no route, all paths failed: there's nothing to look up.

For the asynchronous case — pay returned Ok(id) and the payment fails afterwards — an id lookup does work, but only if we persist every dispatched id in our own store and replay it on the history screen. That's a parallel ledger duplicating tx_metadata, and it's empty after a reinstall or a restore-from-seed, so history would silently drop exactly the failed sends the user is trying to understand.

The shape of the need is a list, not a watch: the screen has to render "you tried to send X, it failed" with no prior handle on the payment.

That said, your objection to loading this into list_transactions is fair — it changes the default output for every integrator, and I'd rather match your preference than push my diff. Three shapes, happy to implement any:

  1. As filed — direction-gated; outbound always surfaces. Smallest diff, but changes the default.
  2. Opt-in — list_transactions keeps today's behavior; a ListTransactionsParams { include_failed: bool } or a filtered variant. No change for anyone who doesn't ask.
  3. A separate accessor returning just the non-completed outbound records, leaving list_transactions untouched.

(2) is my guess at what you'd prefer. Say which and I'll rework the PR. Happy to add get_transaction alongside if it's independently useful — it just doesn't close this one on its own.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants