x402 icon indicating copy to clipboard operation
x402 copied to clipboard

Feature/exact btc lightning

Open jllauwers opened this issue 1 month ago • 2 comments

Description

This PR adds a BTC Lightning implementation of the exact scheme and exposes it through the demo site.

TypeScript SDK (typescript/packages/x402)

  • Implement exact/btc_lightning scheme with client + facilitator helpers
  • Export the BTC Lightning exact scheme from the main schemes/exact entry point
  • Add tests covering BTC Lightning client/facilitator behavior

Demo site (site/)

  • Add LND-backed Lightning integration via app/facilitator/lightning-lnd.ts
    • Uses LND_REST_URL, LND_MACAROON_HEX, and LIGHTNING_NETWORK env vars
    • Supports exact scheme on BTC Lightning networks (e.g. btc-lightning-signet)
  • Add /examples/lightning API route:
    • On missing/invalid X-PAYMENT header: returns HTTP 402 with x402 PaymentRequirements for BTC Lightning
    • On valid, settled payment: returns HTTP 200 with demo payload (message, network, transaction, sats, random number)
  • Add /examples/lightning-demo page:
    • Calls /examples/lightning to fetch payment requirements
    • Lets the user paste a BOLT11 invoice from their Lightning wallet
    • Sends the invoice in the X-PAYMENT header using the BTC Lightning exact scheme
    • Displays error states for unpaid/invalid invoices and a success UI once the invoice is settled

Docs

  • Update site/README.md to describe:
    • BTC Lightning exact scheme demo
    • LND facilitator configuration and env vars
    • End-to-end Lightning payment flow (verify + settle) behind /examples/lightning and /examples/lightning-demo

Tests

Automated

  • pnpm test from /typescript
  • pnpm format && pnpm lint from /typescript
  • cd site && pnpm lint

Manual sanity tests

Facilitator / Lightning

  • Started LND on the target network (e.g. signet) with REST + macaroon configured
  • Set LND_REST_URL, LND_MACAROON_HEX, and LIGHTNING_NETWORK in site/.env.local
  • Hit /facilitator endpoints and confirmed invalid inputs produce structured x402 errors (no 500 responses)

/examples/lightning API

  • GET /examples/lightning without X-PAYMENT:
    • Returns 402 with x402Version and at least one accepts[] entry
    • accepts[0].scheme === "exact"
    • accepts[0].network === LIGHTNING_NETWORK (e.g. btc-lightning-signet)
    • maxAmountRequired matches the expected sats amount
  • GET /examples/lightning with an invalid or unpaid BOLT11 invoice in X-PAYMENT:
    • Returns 402 with an error / invalidReason
    • No server crash or unhandled error

/examples/lightning-demo UI

  • Started dev server with cd site && pnpm dev
  • Visited /examples/lightning-demo:
    • Saw “Loading payment requirements…” followed by the “Payment requirements” card
    • Network and amount matched /examples/lightning response
  • Pasted an unpaid but otherwise valid BOLT11 invoice:
    • Clicked “Send payment & retry”
    • Got a “Payment not accepted yet” error and stayed in the needsPayment state
  • Paid the same invoice from a Lightning wallet:
    • Clicked “Send payment & retry” again
    • Got 200 from /examples/lightning and saw the “Access granted” card showing:
      • Message
      • Network
      • Transaction
      • Amount in sats
      • Random number from the demo payload
  • Tried invalid input (wrong network / garbage string):
    • UI showed an appropriate error
    • No 500s or crashes in the terminal

Checklist

  • [x] I have formatted and linted my code
  • [x] All new and existing tests pass
  • [x] My commits are signed (required for merge)

jllauwers avatar Nov 30 '25 22:11 jllauwers

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 0
Sum 1

cb-heimdall avatar Nov 30 '25 22:11 cb-heimdall

@jllauwers is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Nov 30 '25 22:11 vercel[bot]