Skip to content

feat: discover all protocols + l402.space bridge note#49

Draft
reneaaron wants to merge 3 commits into
masterfrom
feat/discover-all-protocols
Draft

feat: discover all protocols + l402.space bridge note#49
reneaaron wants to merge 3 commits into
masterfrom
feat/discover-all-protocols

Conversation

@reneaaron

@reneaaron reneaaron commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Two changes so an agent (or human) with only a lightning wallet can discover and pay for services on any 402 protocol:

  1. discover returns all protocols. Drop the server-side payment_asset=BTC filter so discover returns L402, x402, and MPP services, not just lightning ones.
  2. fetch transparently bridges non-lightning services. lightning-tools already pays L402, MPP, and lightning-payable x402 directly; for endpoints it can't settle over lightning (e.g. USDC-only x402) it hands back an unpaid 402. When that happens, fetch retries once through the l402.space bridge, which re-wraps the upstream as an L402 lightning challenge it can pay. Native L402 is still paid directly and never touches the bridge.

No new flags, no manual URL-encoding, no protocol knowledge required — fetch <service-url> just works regardless of protocol.

Why

Per #26, x402 / MPP services were silently filtered out of discovery, and there was no way to pay them from a lightning wallet. The bridge fallback is an internal implementation detail, so callers never construct a special URL or reason about rails.

Test

  • yarn test — 109 pass, 2 skipped (3 new tests in fetch-bridge.test.ts cover: bridge retry on a 402, direct pay on success with no bridge call, and no double-bridging an l402.space URL).
  • Live discover returns x402 services (previously empty).
  • Verified the bridge live: https://l402.space/<encoded-x402-url> returns 402 + WWW-Authenticate: L402 + a lightning invoice.

Companion skill update: getAlby/payments-skill#28.

Refs #26

Drop the server-side payment_asset=BTC filter so discover returns L402,
x402 and MPP services. Non-lightning services (e.g. x402/USDC) can be
paid in sats by fetching them through the l402.space bridge.

Also surface payment_network in results so callers can tell which rail a
service settles on and decide whether the bridge is needed.

Refs #26
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a151e251-ab33-4f4c-92f8-e5ca79055892

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/discover-all-protocols

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.

When lightning-tools hands back an unpaid 402 (e.g. a USDC-only x402
endpoint it can't settle over lightning), retry once through the
l402.space bridge, which re-wraps the upstream as an L402 lightning
challenge we can pay. Native L402 and lightning-payable x402/MPP are
still paid directly and never touch the bridge - no flag, no manual URL
encoding for the caller.

Refs #26
It was added so callers could decide whether to use the bridge, but
fetch now bridges non-lightning services transparently, so the rail is
an implementation detail. protocol already covers what a service is.
// lightning and handed the response back. Retry once through the l402.space
// bridge, which converts it to an L402 lightning challenge we can pay.
if (result.status === 402 && !params.url.startsWith(L402_SPACE_BRIDGE)) {
result = await fetch402Lib(bridgeUrl(params.url), buildRequestOptions(), {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder if there are any side effects of this e.g. regarding getAlby/js-lightning-tools#328

if the client doesn't know at all they are going through this bridge, if they do the request again passing a macaroon (or x402/MPP equivalent) I wonder if this will break.

Would it be possible to wrap the discover response urls with the bridge url instead?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This will be more in-line also if we decide to switch to l402.space for the discovery recommendations

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