Skip to main content
Five recorded runs back the facilitator’s and the Bazaar’s claims. The canonical client, the live matrix, the live Bazaar run and the benchmark ran against the hosted service at https://testnet.rail402.dev without an API key; the upstream e2e suite starts Rail402 itself. They use fresh Friendbot-funded testnet accounts and Circle testnet USDC, so none needs secrets; the one exception is the live Bazaar run’s second seller, a fixed testnet account derived from a public label, so that repeated runs reuse its one listing. Their results are committed in tools/conformance/evidence/.

Canonical client

An unmodified buyer pays an unmodified seller whose facilitator is Rail402.
  • Buyer: @x402/fetch (wrapFetchWithPaymentFromConfig) with the stock ExactStellarScheme client from @x402/stellar and its default spend controls.
  • Seller: @x402/express paymentMiddleware with x402ResourceServer and HTTPFacilitatorClient({ url }), charging $0.01 for GET /weather.
The script funds a buyer and a seller with Friendbot, gives both a USDC trustline, buys 1 USDC for the buyer from the testnet XLM/USDC pool, makes the paid request, and then checks on-chain that the transaction succeeded and that the buyer’s loss equals the seller’s gain.
--facilitator defaults to http://localhost:8080; --write records the result in tools/conformance/evidence/canonical-exact-stellar-testnet.json. Run it from a source checkout after pnpm install.

Recorded run

From tools/conformance/evidence/canonical-exact-stellar-testnet.json: The buyer lost exactly the price and the seller gained exactly the price: the facilitator paid the fee and moved no funds of its own.

Live facilitator matrix

tools/conformance/src/live-matrix.ts exercises every facilitator behaviour over HTTP against a deployed Rail402, sending no API key. Every settlement is checked on chain: the transaction is a fee bump whose fee source and inner source are facilitator signers and never the payer or payTo; it emits exactly one transfer event, payer → payTo, for the exact amount of the required asset; the payer’s balance falls and payTo’s rises by exactly that amount; the sponsor’s XLM falls by exactly the fee and no other signer’s XLM changes; and no facilitator account holds the asset. Every rejection must be spec-shaped with a registered code and a non-empty reason.
The sponsor check is exact only while no other settlement runs on the service at the same time.

Recorded run

From tools/conformance/evidence/live-matrix-stellar-testnet.json (2026-09-28, facilitator https://testnet.rail402.dev): 17 of 17 cases passed, with 6 settlements and 27 coded rejections. The evidence file holds every transaction hash, fee, rejection code and reason.

Benchmark

tools/conformance/src/benchmark.ts runs the same workload against each facilitator named with --facilitator, from the same client in the same window: sequential verifications, sequential settlements from G… payers and from a C… smart-account payer, and batches of concurrent settlements (first facilitator only). Each payment is built before its timed call and never reused. Latency is the client’s wall time for the HTTP call, so it includes the network path; the round trip of GET /supported is recorded as that path’s baseline. Ledgers to confirm counts from the latest ledger when the request was sent to the ledger that included the transaction.

Recorded run

From tools/conformance/evidence/benchmark-stellar-testnet.json, 2026-09-28 15:54–16:08 UTC, Rail402 with 24 channel accounts, every payment 100 base units of testnet USDC:

Live Bazaar

tools/conformance/src/live-bazaar.ts exercises every cataloging and integrity rule against the hosted service through a public seller, apps/demo-seller: stock @x402/express with the bazaar server extension, three paid routes (GET /weather, GET /users/:id, POST /translate), a free /health, and a SEP-1 stellar.toml that lists its payTo. Each case settles a real payment built from the seller’s own 402 exactly as a stock client builds it, and records the EXTENSION-RESPONSES outcome and the resulting listing.
Listings persist between runs: a resource listed by an earlier run reports recorded instead of awaiting_origin_verification, and the checks accept either.

Recorded run

From tools/conformance/evidence/live-bazaar-stellar-testnet.json (2026-09-29): 14 of 14 cases passed, with 16 settlements. The evidence file holds every transaction hash and decoded outcome.

Upstream x402 e2e suite

The e2e suite of x402-foundation/x402 runs every stock TypeScript client and server against a facilitator, then validates the facilitator’s Bazaar. Rail402 joins it as an external facilitator through tools/conformance/upstream-e2e/ (test.config.json and run.sh), which the suite supports without modification. run.sh maps the suite’s variables onto Rail402’s and starts the service with STORE=memory, DISCOVERY_ALLOW_LOOPBACK=true (the suite’s sellers listen on localhost) and rate limits off.
--x402 is a checkout of x402-foundation/x402 at the tag matching @x402/stellar 2.27.0 (the script refuses any other version), prepared as its e2e/README.md describes: pnpm install in e2e/, the TypeScript packages built, and ./setup.sh run. The script funds a fresh sponsor, buyer and seller, installs the Rail402 proxy into the suite, and runs:
--write records tools/conformance/evidence/upstream-e2e-stellar-testnet.json. The run fails unless the suite exits 0, at least one test ran, and the Bazaar discovery validation passed.

Recorded run

From tools/conformance/evidence/upstream-e2e-stellar-testnet.json: Each result in the file carries its settlement transaction hash.

Integration tests

Beyond these runs, the integration tests (pnpm test:integration, against a private Stellar network) cover the required behaviours with real balances and events: G… and C… (smart account) payers, exact SEP-41 amounts, trustlines, expiry, tampering, replay, idempotent and crash-safe settlement, and the Bazaar end to end with a real @x402/express seller. The verification rules name the test for every check.