Skip to main content
The Playground (apps/playground) is a page and a small server for trying x402 on Stellar in a browser. Every payment it makes is real: a testnet key in your tab signs a Soroban authorization, a seller asks Rail402 to verify and settle it, and the transaction lands on the Stellar testnet, where its link opens in the explorer. Nothing is simulated, and the page draws each step from what actually happened.
The Playground serves stellar:testnet only. It refuses to start with any other network, and the page refuses payment requests on another network before anything is signed.

The test wallet

The header’s wallet chip opens the test wallet. Create makes a fresh testnet key in the tab; Import takes an S… testnet seed from a password field and clears the field at once. Set up test funds then runs three transactions, each shown with its explorer link: Friendbot funds the account with testnet XLM, a USDC trustline is added, and 1 USDC is bought on the testnet exchange, keeping 10 XLM for reserves and fees. No XLM of your own is needed. If the purchase fails, the panel links to Circle’s testnet faucet. The key is stored encrypted in the browser and never leaves it: How it works explains the storage, and the wallet can be downloaded as a key file for the CLI and the SDK (import it with rail402 keys import < <file>, or chmod 600 it before using RAIL402_SECRET_KEY_FILE), or forgotten. The wallet is used by one tab at a time; a second tab is read-only until the first one closes. Every paying run needs a per-call cap. It defaults to 0.01 USDC, the page clamps it at the operator’s ceiling of 0.10 USDC, and a run does not start without one. The session budget is 1.00 USDC per 24 hours and can only be lowered. The meter in the header shows what is spent, held and left.

The lab

The home page runs four scenarios against the hosted demo seller, Rail402 and the Bazaar. Each run draws a swimlane: one row per message, in causal order, each tagged with where its data came from (your browser, the seller, the chain or the Bazaar). Clicking a row opens it in the inspector; the code panel highlights the SDK lines that do the same step; the outcome card shows what moved, who paid the network fee and the transaction. A run’s report can be downloaded as JSON; it is built from the run’s events only and holds no key, signature or payment header. The sandbox route stands in for your own API: it is one listing, paid to the Playground operator’s testnet account, shared by every visitor. The Sell page covers your own endpoint.

Pay, Sell, Agents and Bazaar

  • Pay pays the demo route, a Bazaar listing (an HTTP route or an MCP tool) or any URL with a method and a JSON body, and shows the result with the response the seller delivered and the same swimlane underneath. A payment counts as settled only when the chain proves it: the transaction consumed this payment’s own nonce and moved its amount, so a seller that reports some other transaction gets “not proven”. Its refusal checks each send a payment your policy must refuse and pass when it is refused with the expected code, nothing is signed and your balance does not move (the session check pays once first): The session check pays once inside its window before the second payment is refused; its result links that first payment’s transaction, and its run report names it in the summary (transactions).
  • Sell shows the seller code for a paid route, then Check your endpoint runs the checks the catalog runs against your URL (an x402 402 with a price, valid discovery metadata, a payTo that can receive the asset, and, optionally, a stellar.toml that lists the payTo with a matching home domain), and Your listing shows the listings of a payTo with their trust level and version history.
  • Agents shows the MCP server configuration with your caps, the tools it offers and an example run.
  • Bazaar searches the catalog with filters and links each result to its version history and to the Pay page.

Run it yourself

The Playground needs Node.js 24.11 or later and a source checkout. Build the workspace and the page, then start the server against the hosted testnet services:
Then open http://localhost:8080. PLAYGROUND_PAY_TO is a public testnet account with a USDC trustline that the lab sellers are paid to; without it, set LAB_ENABLED=false, and the page then offers only what works without the lab sellers. Set DOCS_URL if the page should link to docs other than https://docs.rail402.dev. From a localhost page, Sell and get listed pays the sample route but the hosted Bazaar refuses to list a loopback URL (bazaar_resource_unsafe); the run says so. Self-host lists every setting, the Docker image and local mode, which lists the route with your own Rail402.