Both rails are live in sandbox today. Base Sepolia (
eip155:84532) and
Stellar testnet (stellar:testnet) settle real USDC through the same Sly
governance loop. Mainnet for both rails (Base + Stellar pubnet) ships with
production access — contact us once you’ve worked
through the production access checklist.What “rail-neutral” actually means
The four Sly primitives — Identity, Governance, Policy, Receipts — work the same on every rail. A receipt minted on Base and a receipt minted on Stellar carry the same identity fields, the same canonical encoding, the same HMAC algorithm, and the same offline verifier. The rail is a setting, not an integration./v1/agents/:id/... endpoints, the same dashboard surfaces, the same receipt shape. Only chain and the address format differ.
The two production rails
Base (EVM L2)
Coinbase’s L2 on Optimism Stack. Mid-large settlements. EVM ecosystem. ~2s finality. EIP-191 key-control proofs.
Stellar (Soroban)
Stellar Development Foundation’s smart-contract chain. Agent micro-payments. Fee-sponsored settlement. ~5s finality. SEP-10 key-control proofs.
Side by side
Picking a rail by hand? The short rule: Base for mid/large settles in EVM-heavy stacks; Stellar for sub-cent agent micropayments and emerging-markets edges. Better: let
selectRail() pick for you.
selectRail() — the decision function
Rail-neutrality at the platform level becomes a single pure function at the code level. selectRail() takes an intent, the tenant’s allow-list, the agent’s allow-list, and current network conditions, intersects them, scores the survivors, and returns the chosen rail plus the human-readable reasons it won.
rail_selection field. The receipt explains itself.
The decision tree
apps/api/src/services/x402/select-rail.ts. Pure function, fully unit-tested, 0 side effects — replayable forever.
Allow-lists — two levers
Every agent’s effective rail allow-list istenant.allowed_rails ∩ agent.allowed_rails. Two operators can independently dial down (never up) the rails their agents can settle on.
[]) means “no restriction” — defaults to platform-wide allow. Both fields render as Allowed Rails chip panels in the dashboard for the relevant scope.
Receipt shape, across rails
Every Sly governed payment — Base or Stellar — produces the same receipt envelope. Onlychain, address format, and a couple of optional rail-specific fields vary.
Offline verification works the same
Theverify-offline.mjs script in examples/stellar-demo/ is rail-agnostic — it re-derives the canonical encoding and HMAC, then byte-compares. Works for both Base and Stellar receipts because the canonical encoding is json-sort-keys-v1 regardless of chain.
What’s NOT yet at parity
Three places where Base is ahead of Stellar today, by design:
All three are coded against an abstraction; flipping one over is a config change, not a rebuild.
Where to go from here
Settling on Base
Full guide — endpoints, EIP-191 binding, witness receipts, dashboard surface, EAS anchoring.
Settling on Stellar
Full guide — endpoints, SEP-10 binding, custody providers, AttestProtocol anchoring, the three identity layers.
x402 protocol
The HTTP 402 micropayment protocol that both rails serve under the same Sly governance loop.
Production access
How to graduate from sandbox (both rails) to live mainnet settlement.