Skip to content

feat: resume fetch support#333

Merged
rolznz merged 2 commits into
masterfrom
feat/resume-fetch
Jul 22, 2026
Merged

feat: resume fetch support#333
rolznz merged 2 commits into
masterfrom
feat/resume-fetch

Conversation

@rolznz

@rolznz rolznz commented Jul 15, 2026

Copy link
Copy Markdown
Member

This enables an agent to recover without repaying in two cases:

  1. Payment succeeds but temporary fetch error
  2. Payment times out and later succeeds (or payment succeeds but user does not get an NWC response due to temporary fetch error)

Currently BOTH of these scenarios result in the caller not receiving credentials.

See getAlby/cli#55

This adds enables the agent to resolve most common payment issues and fetch the resource without having to re-pay, at the cost of some extra complexity.

After #332 is merged this PR needs to be updated (amount and fee renaming)

Summary by CodeRabbit

  • New Features

    • Added structured payment failure errors with invoice, payment status, hash, and recovery details.
    • Added safe recovery and resume flows for interrupted payments without duplicate charges.
    • Added credential reuse across supported payment protocols.
    • Added guidance and examples for reconciling payments and resuming failed requests.
  • Bug Fixes

    • Preserved payment credentials and recovery information when follow-up requests fail.
    • Standardized payment failure handling across L402, MPP, and x402.

@rolznz
rolznz requested review from bumi and reneaaron July 15, 2026 08:21
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 258f1951-e5a7-4f7f-9267-6037d57462eb

📥 Commits

Reviewing files that changed from the base of the PR and between 3ef67bf and 37b7907.

📒 Files selected for processing (9)
  • README.md
  • src/402/fetch402.ts
  • src/402/l402/l402.test.ts
  • src/402/l402/l402.ts
  • src/402/mpp/mpp.test.ts
  • src/402/mpp/mpp.ts
  • src/402/utils.ts
  • src/402/x402/x402.test.ts
  • src/402/x402/x402.ts

📝 Walkthrough

Walkthrough

Adds shared 402 payment reuse, resumption, and structured failure handling across L402, MPP, and x402 flows, with tests covering payment failures and recovery paths and README documentation for reconciliation.

Changes

402 payment recovery

Layer / File(s) Summary
Shared payment recovery utilities
src/402/utils.ts
Adds pending payment descriptors, resume options, credential reconstruction, payment reuse, payment hash extraction, Fetch402PaymentError, and payAndFetch.
Protocol flow integration
src/402/fetch402.ts, src/402/l402/..., src/402/mpp/..., src/402/x402/...
Routes L402, MPP, and x402 payment and credential-reuse flows through the shared helpers.
Recovery validation and documentation
src/402/l402/l402.test.ts, src/402/mpp/mpp.test.ts, src/402/x402/x402.test.ts, README.md
Tests structured failures, payment resumption, and post-payment request failures; documents recovery procedures.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant fetchWith402
  participant payAndFetch
  participant Wallet
  participant Server
  Client->>fetchWith402: Request protected resource
  fetchWith402->>payAndFetch: Invoice and pending payment data
  payAndFetch->>Wallet: payInvoice
  Wallet-->>payAndFetch: Preimage or payment failure
  payAndFetch->>Server: Retry request with payment credentials
  Server-->>Client: Response or follow-up request failure
Loading

Possibly related PRs

Suggested reviewers: reneaaron, bumi

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title concisely matches the main change: adding resume support for failed payment/fetch flows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/resume-fetch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bumi

bumi commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

wondering about best practices in such cases for 402 in general. makes things tricky.

@rolznz

rolznz commented Jul 18, 2026

Copy link
Copy Markdown
Member Author

I hit this again today:

❯ why did you try list my transactions?

● The fetch failed with a NWC reply timeout — that means the CLI sent the pay_invoice request to your wallet but never
received a response. In that situation the payment's outcome is ambiguous: the wallet may have paid the invoice and only
the reply got lost. If I immediately retried the fetch, you could end up paying twice.

So I was checking the last few transactions purely to see whether a payment to l402.space had actually gone out before
retrying. No other reason — I wasn't going to do anything with the history beyond that.

How would you like to proceed? I can retry the fetch directly (small double-pay risk of ~a few hundred sats at most, capped
at 500), or you can check your wallet yourself and tell me whether a payment went through.

Where things stand:

  • Your wallet paid 109 sats (+2 sats fee) to l402.space for the "Alby Hub" YouTube search, but the CLI crashed on a relay
    timeout before it could use that payment, so we never received the search results and I have no way to redeem that specific
    payment.
  • The only way to get the results is to run the fetch again, which would cost another 111 sats ($0.11 total).

Tell me how you'd like to proceed — retry the fetch, or drop it here.

@rolznz

rolznz commented Jul 18, 2026

Copy link
Copy Markdown
Member Author

@bumi I cannot think of any better way to do it. All other options have worse downsides.

  • Add lookupInvoice to the wallet interface so this library can handle retries -> could result in hanging.
  • Do nothing -> User has a terrible experience, agent raises this and blames our library.

This is a fundamental issue of 402 flow that payment and fetching are not an atomic operation. It's made worse that we have so many moving parts: NWC relay, lightning, HTTP - all do not have a 100% success rate.

Since we decided to push retries to the client, and I think especially because the agent needs to know what is really going on, I believe this PR is the best option.

@rolznz

rolznz commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

I think this is also unique to lightning - on other blockchains there is no concept of stuck payments. 😅

@rolznz

rolznz commented Jul 19, 2026

Copy link
Copy Markdown
Member Author

How lnget does it: it uses a local store https://github.com/lightninglabs/lnget/blob/main/docs/architecture.md#pending-token-pattern

Note: Even though it mentions it, I don't think lnget handles pending payments. We do in this PR by checking the status of the transaction by payment hash.

@bumi

bumi commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

@rolznz I also can't think of a better way. it's nicely implemented.
it's just complex due to the nature of this async process.

@rolznz
rolznz marked this pull request as ready for review July 22, 2026 04:50
@rolznz
rolznz merged commit 9dd4496 into master Jul 22, 2026
4 checks passed
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