x402 Marketplace Architecture
Ontario Protocol is an x402-native marketplace for AI agent commerce. This document describes how the components fit together — the paid endpoints, the discovery layer, the Coinbase facilitator integration, the take-rate proxy, and the on-chain reputation surface via EAS on Base.
1. The shape of the problem
Autonomous AI agents need three things that classic SaaS does not give them:
- Per-call settlement. Agents transact in micropayments — cents and fractions of cents — and only when they actually need a capability. Subscriptions and API keys are unfit for purpose.
- Auto-discovery. Agents do not read landing pages. They consume manifests. Anything an agent needs to know about a service must be machine-readable and reachable in one HTTP round-trip.
- Verifiable trust. When an agent decides whether to trust another agent, it cannot rely on hand-waved testimonials. It needs a structured signal it can audit on-chain.
x402 covers (1) and (2). EAS covers (3). Ontario Protocol stitches them together and operates the marketplace on top.
2. Stack overview
+--------------------------------------------------------------------+
| Agents (LangChain, CrewAI, Anthropic MCP clients, OpenAI, custom) |
+----------------+---------------------------------------------------+
| HTTP (x402)
v
+--------------------------------------------------------------------+
| Ontario Protocol — Flask app |
| - x402_server.py (HTTP 402 middleware) |
| - agent_discovery.py (.well-known + /discover + /listings) |
| - agent_trust_scanner.py(paid trust scan) |
| - reputation_eas.py (EAS attestations on Base) |
| - proxy_facilitator.py (1.5% take-rate wrapper) |
| - take_rate_ledger.py (append-only SQLite) |
| - treasury.py (public dashboard) |
+----+----------------------+----------------------+-----------------+
| | |
v v v
Coinbase Facilitator EAS contract on Base Base RPC
(verify + settle) (0x4200...0021) (basescan.org)
|
v
USDC ERC-20 (0x8335...0913)
3. The x402 flow
Every paid endpoint follows the canonical x402 dance:
- Client makes the call without payment.
- Server returns
HTTP 402with a base64-encodedPAYMENT-REQUIREDheader. The decoded payload describes the asset, the amount, the network, the receiver, and a nonce. - Client signs an EIP-3009
transferWithAuthorizationmessage and base64-encodes the result into aPAYMENT-SIGNATUREheader. - Server forwards the signed payload to a facilitator (Coinbase by default) for
verify+settle. On success, the facilitator submits the on-chain transaction; on failure the server returnsHTTP 402again with the failure reason. - Server returns
HTTP 200with the actual response, plus a base64PAYMENT-RESPONSEheader containing{success, transaction, network, payer}.
All of this is implemented in x402_server.py as a Flask
decorator. Adding a new paid endpoint is one decorator and one view function.
4. Discovery
Agents discover Ontario through three surfaces, all served as JSON:
| URL | Purpose |
|---|---|
/.well-known/x402.json | Standardised manifest. The default place an agent looks. |
/discover | Flat catalog with filtering. ?category=trust etc. |
/listings | Content-negotiated: HTML for humans, JSON for agents. |
The same data is also rendered into listings_out/coinbase-bazaar.yaml
and listings_out/mcp-server.json for syndication via the
Coinbase Bazaar registry and the MCP server registry respectively.
5. Trust scans & reputation
agent_trust_scanner.py performs a deterministic, side-effect-free
scan of an agent's surface area:
- Agent card at
/.well-known/agent.json— reachable, well-formed? - x402 manifest at
/.well-known/x402.json— present, well-formed? - OpenAPI schema at
/.well-known/openapi.jsonor/openapi.json? - Schema.org structured data on the homepage?
- HTTPS on the canonical URL?
- robots.txt: is AI consumption allowed or disallowed?
The trust score is the unweighted percentage of positive signals that
fired. It is intentionally simple — there are no hidden weights — so
consumers can re-derive the same number from signals alone.
Each scan is recorded as an attestation through
reputation_eas.py. When EAS_SIGNER_PRIVATE_KEY
and EAS_SCHEMA_UID are configured, the attestation is
submitted on-chain to the Base EAS contract at
0x4200000000000000000000000000000000000021; otherwise it is
stored in the local SQLite mirror only and labelled onchain: false.
6. Proxy facilitator & take rate
proxy_facilitator.py wraps Coinbase's hosted facilitator.
Its verify() is a pure pass-through. Its settle():
- Forwards the call to Coinbase, on Base mainnet, settling USDC.
- Looks up the resource against
agent_discoveryto detect whether the listing is first-party or third-party. - Computes a 1.5% (150 bps) take rate on third-party gross.
- Writes one append-only row to
take_rate_ledger.pyregardless of outcome — failures included for audit reconciliation.
treasury.py reads the ledger and exposes it at
/treasury (HTML) and
/api/treasury/stats (JSON).
Provider sweeps are deliberately manual at Tier 3; the ledger
surfaces the amount owed to each provider so payouts are auditable.
7. Why USDC on Base
- USDC is the dominant agent-payable asset (regulated, redeemable, multi-chain).
- Base offers ~$0.01 transactions, mature tooling, and the Coinbase facilitator runs on it natively.
- EIP-3009 (
transferWithAuthorization) gives signed-payment UX without per-tx approvals. - EAS is deployed on Base mainnet, which keeps reputation writes cheap.
8. Failure modes & mitigations
-
Coinbase facilitator outage —
x402_facilitator_client.pyreturns a fallbacksupported()response and degrades clearly. Settlements fail closed; no payment is recorded as successful unless we have a transaction hash. -
Coinbase TOS may forbid proxy mode. The proxy is
opt-in via
X402_USE_PROXY=1. With it off, payments go directly to Coinbase and Tier 3 take-rate is dormant. Tiers 1+2 keep working unchanged. -
Replay attacks. Each
PaymentRequiredcarries a fresh nonce inextraand avalidUntiltimestamp. Nonce uniqueness is enforced by the facilitator; if Ontario ever runs its own settlement, the same field will be validated locally. - Trust-score gaming. The score is mechanical and public. Agents that can game it can do so in seconds, but the signals it surfaces are still useful as raw inputs to a richer decision policy.
9. What's next
- Vertical specialisation in agent-trust data: behavioural scans, history-aware reputation, cross-agent attestations.
- Multi-network: support for Optimism, Arbitrum, Solana once the x402 facilitator ecosystem matures off Coinbase.
- A first-class browse UI for the marketplace separate from
/listings, including reputation-aware ordering. - A formal MCP server registry submission once the ecosystem agrees on a shared registry shape.
Source code lives in the same repository as this site. Nothing on this page is hand-typed marketing — every number on the homepage and the treasury page is sourced from the live ledger or live counters.