A card-carrying agent pays any x402/USDC endpoint — with no crypto wallet. Built for the Agentic Commerce Hackathon (Visa Intelligent Commerce / Prava track).
An AI agent with only a Prava card (no private key, no USDC) asks the bridge for data behind an HTTP-402 paywall. The bridge reads the 402, decides a spend-policy, charges the card via Prava, settles the USDC leg on Base, and returns the paid response. Small calls go through autonomously against a standing mandate; anything above a threshold escalates to a passkey — that permission/control surface is the point, not a payment button bolted on.
- Pre-existing (NOT this submission): Predge — the live x402 merchant we buy
from (
x402-api-production-266e.up.railway.app, Polymarket whale data, USDC on Base mainnet). It existed and was in production before the event; it is the seller, not the entry. - Built during the hackathon (this repo): the entire bridge —
x402.mjs(402 probe +payment-requiredheader decode + leg selection),policy.mjs(spend-policy gate + audit log),server.mjs(/payorchestration), the Prava-leg wiring, and the demo agent. Nothing here existed before 2026-07-31. - No fake transactions. Where a leg runs in sandbox (Prava test cards) that is stated plainly on screen; the USDC leg is a real on-chain settlement. We never present a mock as a real charge.
card-only agent ──POST /pay {targetUrl}──▶ x402-prava-bridge
a) probe target → HTTP 402
decode `payment-required` → accepts[]
pick Base(eip155:8453) USDC leg
b) spend-policy gate
price ≤ threshold → charge MANDATE (auto)
price > threshold → payment SESSION (passkey)
c) Prava leg → card charge (sandbox test card)
d) x402 leg → USDC settle on Base (float wallet)
e) reconcile + audit log → return paid JSON
- Visa Intelligent Commerce ($5k) — the transaction flows through Prava; the judged
axes permissions / trust / controls ARE the spend-policy gate: autonomous under a
capped mandate, human passkey above it, every call audit-logged (
GET /audit). - Prava Overall ($10k credits) — Prava is the core enabler: without it a card-only agent simply cannot buy from a wallet-only x402 seller. It unlocks a new action, not a checkout button.
- OpenAI ($9k) — the agent's brain is an OpenAI model (
src/brain.mjs): it plans which paid endpoint answers a natural-language question (structured-output tool call) and explains the data it bought, honouring theoutcome_verifiedtrust flag. The LLM drives the buying decision — it is not a hardcoded router. - Localhost — Most Startup-Ready Product ($5k) — Predge is a live, revenue-ready x402 API; the bridge widens its buyer market from "agents holding USDC" to "any agent with a card", which is the whole go-to-market unlock.
- Senso — Agent Commerce Discovery & Trust ($7.5k) — the bridge discovers pricing from
the
.well-known/x402+payment-requiredheader, and every answer carries a machine-readableoutcome_verifiedtrust flag (win rate verified, PnL modelled).
x402 prices are sub-cent ($0.005); card rails settle in whole cents. So the bridge charges a $0.01 minimum to the card and carries the change as float credit — which is exactly why small calls batch against a mandate instead of hitting the card per call.
npm install
npm run server # :8899 GET /health · POST /pay {targetUrl} · GET /audit
# probe-only (no money), against live Predge:
curl -sS -X POST localhost:8899/pay -H 'content-type: application/json' \
-d '{"targetUrl":"https://x402-api-production-266e.up.railway.app/v1/whales/latest"}'/pay returns a payment plan (x402 leg + Prava leg params + policy decision) and
moves no money on its own. Executing the two legs are separate authorized steps.
The demo agent thinks with an OpenAI model (src/brain.mjs, default gpt-4o-mini) at
three points — all standard OpenAI patterns:
- Plan (tool calling) — the model is given two buy tools,
buy_whales_latestandbuy_wallet_history({wallet}), withtool_choice: "required". Its tool call is the agent's purchase decision — which paid Predge endpoint to spend on, and which wallet. The LLM drives the action; we just execute the tool it picked. - Trust audit —
assessTrust()reads the purchased data'soutcome_verifiedflag and states in one line what the agent may act on (verified win rate) vs. discount (modelled PnL). - Answer — the model writes the final reply over the data the agent just bought.
Set OPENAI_API_KEY to enable it; without a key the agent falls back to a regex router so
the demo still runs offline.
npm run eval:brain # runs sample questions through the tool-calling planner
# ✓ ❓ is wallet 0x8dab… smart money?
# → wallet-history (0x8dab…) — evaluate this wallet's track record
node --env-file=.env src/demo-agent.mjs --prava --settle "is wallet 0x8dab… smart money?"
# 🧠 OpenAI (gpt-4o-mini) called tool → wallet-history: …
# 🔐 trust (OpenAI): act on the verified win rate; treat PnL as a modelled estimatePrava test cards work only in sandbox, which is separate infrastructure from the
pay.prava.space production dashboard (adding the test card there fails with "card
network could not process"). Sandbox:
- Console / signup: dashboard.prava.space (self-serve, no KYC) → issues
pk_test_*/sk_test_* - API base:
https://sandbox.api.prava.space· card collection:sandbox.collect.prava.space - The test card is entered via the secure collect iframe during a payment session
(created with
sk_test_*), not by a standalone "Add a card": create session → openiframe_url→ enter test card4622 9431 2313 7789CVV757exp12/27→ passkey → poll result → reportAPPROVED/DECLINED.
- Sign up at dashboard.prava.space (sandbox, self-serve) and generate test keys.
Put the SECRET in the bridge env — do NOT paste it in chat:
PRAVA_SK_TEST=sk_test_…(andPRAVA_PK_TEST=pk_test_…)..envis gitignored. (Alt route for a genuinely-real card-leg: add a REAL card with a $5 cap in pay.prava.space and use the connected Prava MCP — real money, strongest for judging.) - Fund a float wallet on Base mainnet with ~$1–5 USDC and set
FLOAT_PRIVATE_KEY(used only by the x402 settle step; keep it out of git). - Devfolio: add the project to the accepted entry; note the Prava MCP connection.
Env: PRAVA_SK_TEST, PRAVA_PK_TEST, FLOAT_PRIVATE_KEY, OPENAI_API_KEY,
OPENAI_MODEL (default gpt-4o-mini), BRIDGE_AUTO_THRESHOLD_USDC (default 0.01),
BRIDGE_FEE_USDC (default 0), PORT. See .env.example.