Skip to content

feat(sdk): x402Serve() routes can declare the Bazaar discovery extension - #262

Merged
Eras256 merged 1 commit into
mainfrom
feat/x402serve-bazaar-discovery
Nov 7, 2026
Merged

Eras256 merged 1 commit into
mainfrom
feat/x402serve-bazaar-discovery

Conversation

@M0nsxx

@M0nsxx M0nsxx commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

x402Serve() had no way to declare the extensions.bazaar field on a route — every route it built was just { description?, accepts }. A seller using x402Serve() as documented couldn't get their endpoint listed in any x402 Bazaar.

  • X402ServeConfig.routes entries now accept optional input, inputSchema, and output.
  • When any of those is present, x402Serve() dynamically loads @x402/extensions/bazaar (same lazy-load pattern as the other @x402/* packages, via the existing load() helper) and sets declareDiscoveryExtension({ input, inputSchema, output }) as that route's extensions — the same shape PREMIUM_ROUTES in packages/agent/src/middleware/x402.ts (the private monorepo) already uses directly.
  • Without those fields, nothing changes: no extensions key, no new required dependency, no behavior change for existing callers.

Live proof (not just unit tests)

Ran the actual fixed build (npm pack of this branch's packages/sdk) as a real x402Serve()-protected route on a public host (a throwaway Vercel deployment, deleted after this test), using Rail402's hosted testnet facilitator (https://testnet.rail402.dev) — no mocks, no hand-rolled @x402/express middleware bypassing the fix.

  • Settled payment tx: 7fb9bca13c9451fdfa11b8e909a4b6c3d49fe6411b7865f4a9bf11da8a465139 (Stellar testnet, ledger 5608942, confirmed via Horizon)
  • After settlement, the resource was cataloged: GET https://testnet.rail402.dev/discovery/resources?payTo=GB73CQ5UTUEUGR6ZSPW5T4XWMZZJAP545G2F6RH2SFL2CTR24RY2VCRK returns the route with extensions.bazaar and rail402.trust: "origin_verified".

Test plan

  • New test packages/sdk/src/x402serve-discovery.test.ts: a route with input/inputSchema/output gets extensions.bazaar; a route without them gets no extensions key; mixed config only extends the opted-in route.
  • Full suite green: npm test (jest + node:test) in packages/sdk — 165/165.
  • tsc --noEmit and npm run build clean.
  • Live testnet run against Rail402 as described above (tx hash and listing confirmed independently via curl, not just the test harness's own output).

Closes #217

Routes in X402ServeConfig.routes now accept optional input/inputSchema/
output. When any is present, x402Serve() loads @x402/extensions/bazaar
(dynamic import, same pattern as the other @x402/* packages) and sets
declareDiscoveryExtension({ input, inputSchema, output }) as that
route's extensions - same shape PREMIUM_ROUTES in
packages/agent/src/middleware/x402.ts already uses directly. Without
those fields, a route is unchanged: no extensions key, no new required
dependency.

Verified against Rail402's hosted testnet facilitator with a real
x402Serve()-protected route on a public host: after a settled payment
(tx 7fb9bca13c9451fdfa11b8e909a4b6c3d49fe6411b7865f4a9bf11da8a465139,
Stellar testnet, ledger 5608942), the resource was cataloged at
GET https://testnet.rail402.dev/discovery/resources, trust
origin_verified.

Closes #217

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@Eras256 Eras256 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.

Approving — 17/17 checks green, and this includes the real live-testnet proof against Rail402's facilitator (settled tx + Bazaar listing at origin_verified trust) that the issue's "Done when" required. Clean fix, matches the reference pattern already used in packages/agent's own middleware.

@Eras256
Eras256 merged commit ce9dec4 into main Nov 7, 2026
17 checks passed
@M0nsxx M0nsxx mentioned this pull request Nov 7, 2026
Eras256 pushed a commit that referenced this pull request Nov 7, 2026
…) (#267)

Bumps packages/sdk 0.17.0 -> 0.18.0 (new public API, not a patch) and
dates the Unreleased CHANGELOG section. #262, already merged, is the
only change in this release.

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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.

x402Serve(): let routes declare the Bazaar discovery extension

2 participants