Skip to content

mdlog/AgentGate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

104 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentGate

ci npm version license

Live now: CLI on npm → npx @mdlog/agentgate · dashboard agentgate.mdloglabs.org · gateway gateway.mdloglabs.org · registry deployed on Casper Testnet.

AgentGate dashboard — live catalog of on-chain registered services

Stripe for AI agents on Casper. Read the live on-chain service catalog with zero setup — no config, no keys:

npx @mdlog/agentgate list

Wrap any HTTP API into a paid, on-chain-registered service in one command — the only thing on the line besides the args is your funded wallet key:

npx @mdlog/agentgate wrap https://api.example.com/data --price 2.5 --name "My Data API" --pem ./key.pem

Buy one call to any listed service the same way — the CLI pays the 402 invoice and prints the data (body → stdout, payment receipt → stderr):

npx @mdlog/agentgate buy 5 --pem ./buyer.pem --max 5

wrap registers on-chain (signed by --pem) and maps your upstream on the gateway by signing an ownership challenge — no shared admin token. --gateway defaults to the hosted gateway; pass it to target a local/self-hosted one.

Sellers put a 402 paywall in front of their API and register it in an on-chain registry. Buyer agents discover services from the registry, pay with a native CSPR transfer carrying the invoice nonce as transfer_id, retry with the payment proof, and get the data — while the gateway records an on-chain attestation that feeds each service's trust score. No accounts, no API keys, no subscriptions: HTTP 402 + Casper.

How it works

sequenceDiagram
    autonumber
    participant Seller as Seller (CLI)
    participant Chain as Casper (registry)
    participant Gate as AgentGate gateway
    participant Agent as Buyer agent
    participant API as Upstream API

    Seller->>Chain: register service (price, payment target, attestor)
    Seller->>Gate: map upstream (owner-signed challenge → /services/:id/map)
    Agent->>Chain: discover catalog + trust scores
    Agent->>Gate: GET /svc/:id
    Gate-->>Agent: 402 PaymentRequiredResponse (x402Version, error, accepts[])
    Agent->>Chain: CSPR transfer (transfer_id = nonce)
    Agent->>Gate: GET /svc/:id + X-PAYMENT: <base64 proof>
    Gate->>Chain: verify transfer (target, amount, transfer_id, age)
    Gate->>API: proxy (nonce burned first — single use)
    API-->>Gate: data
    Gate-->>Agent: 200 data
    Gate--)Chain: attestation (success) → score → trust tier
Loading

Full component breakdown: docs/ARCHITECTURE.md · engineering contract: docs/SPEC.md.

Quickstart (offline, 60 seconds)

Requires Node ≥ 22. No keys, no network, no chain access needed:

npm install
npm run demo     # full loop: register → 402 → pay → serve → attest → score, exits 0

The demo boots a mock chain + oracle + gateway in-process, wraps the oracle at 0.5 CSPR, runs the LLM buyer agent (deterministic MockLlm — no API key needed), and prints the payment deploy hash, the attestation tx hash, and the final score.

Ports: the demo binds :4030 (devnet), :4010 (oracle) and :4021 (gateway). If one is taken (EADDRINUSE), override: DEVNET_PORT=14030 ORACLE_PORT=14010 MIDDLEWARE_PORT=14021 npm run demo

See it in the dashboard (one command)

npm run dev:seed          # boots devnet+oracle+middleware AND seeds one wrapped
                          # service + a real paid call, then STAYS UP
npm run dev:dashboard     # in a second terminal → open the URL it prints

npm run demo won't show in the dashboard — it's a self-contained one-shot that boots its own in-memory chain, runs the loop, and exits, so its data is gone by the time you open a browser. Use npm run dev:seed (persistent + populated) to view it live. The dashboard polls the running stack every 5 s.

Port note: the dashboard defaults to http://localhost:3000, but if 3000 is already taken Next.js silently moves to 3001 (or the next free port). Always open the URL printed in the dev:dashboard terminal, not a hard-coded 3000.

Manual dev loop

npm run dev               # empty stack: devnet :4030 + oracle :4010 + middleware :4021
# paste the printed MOCK_BUYER_ACCOUNT / MOCK_SELLER_ACCOUNT export lines, then:
npm run agentgate -- wrap http://localhost:4010/feed --price 0.5 --name "RWA FX & Gold Oracle"
npm run agent -- --task "Get today's USD/IDR rate and gold price, summarize for a treasury report"
npm run agentgate -- buy 1 --mode mock    # or skip the agent: pay once, print the data

Set ANTHROPIC_API_KEY to let the buyer agent use Claude instead of the MockLlm.

Mode matrix

AGENTGATE_MODE=mock|live (default mock for the repo stack; the published CLI defaults to live) selects the chain backend behind the ChainClient seam — everything above it is identical:

mock live (Casper Testnet)
Chain in-memory devnet (@agentgate/devnet) casper-js-sdk v5 + CSPR.cloud REST
Signers mock account strings PEM keys
Payment verify devnet transfer lookup CSPR.cloud GET /transfers?deploy_hash=
Registry devnet mirrors the Odra contract rules deployed AgentGateRegistry contract
Guardrails default admin token OK, SSRF guard off default token refused, SSRF guard on

All env vars are documented in .env.example. The gateway and background services in live mode require CSPR_CLOUD_API_KEY and a non-default AGENTGATE_ADMIN_TOKEN (enforced by config). The CLI is looser: list/status read the public node with no keys at all; only status attestation history needs CSPR_CLOUD_API_KEY. Live wrap needs no admin token — it maps the upstream by signing an ownership challenge with your --pem key (verified against the on-chain owner); the admin token is only the legacy/self-hosted path. Live buy needs only a funded buyer key (--pem or BUYER_SIGNER_PEM_PATH). Every value can also be passed as a flag (--mode, --node-url, --registry, --pem, --api-key, --admin-token; flag > env > default).

Repo layout

packages/
  shared/        types · config · bigint money · trust tiers (zero runtime deps)
  devnet/        in-memory mock chain HTTP server          :4030
  chain/         ChainClient: MockChainHttpClient + LiveCasperClient
  middleware/    the product core — 402 paywall proxy + owner-signed self-map   :4021
  client/        agent-side fetchPaid (parse 402 → pay → retry)
  oracle/        demo RWA feed: USD/IDR + gold spot + confidence            :4010
  buyer-agent/   LLM decision loop (AnthropicLlm / MockLlm)
  cli/           agentgate wrap | buy | list | status | pause | resume | demo-accounts
dashboard/       Next.js 16 landing + catalog + live activity + docs        :3000
contracts/       AgentGateRegistry (Rust/Odra) — registry, scores, attestations
e2e/             full-loop test, in-process servers on port 0
scripts/         dev.ts (stack) · demo.ts (one-shot scripted demo)

Scripts

Command What it does
npm run demo one-shot full loop, offline, exits 0 with both tx hashes
npm run dev boots devnet + oracle + middleware, seeds demo accounts
npm run dev:dashboard Next.js dashboard at :3000
npm run agentgate -- … the agentgate CLI
npm run agent -- --task "…" run the buyer agent once
npm run typecheck tsc --noEmit in every package + dashboard + root scripts/e2e
npm test vitest: all package units + the e2e loop (341 tests)
npm run build dashboard next build

Contract tests: cd contracts/agentgate-registry && cargo odra test (20 OdraVM tests), plus contracts/spend-guard (25 tests via cargo test).

Deployed addresses (Casper Testnet)

Live on Casper Testnet (Casper 2.0, network casper-test). The full loop — register → pay (native CSPR transfer, transfer_id = invoice nonce) → attest → score — runs on-chain; the trust score reads (1,1) after the attestation below. Set REGISTRY_CONTRACT_PACKAGE_HASH to the package hash for live mode.

Artifact Value
AgentGateRegistry package hash hash-10f92725551941ffe5be84cd340ce0f31f9f25d1f8ed959cc1a6c3383c3e27e9
Install (contract deploy) tx 4eace325…
register_service tx 35d10755…
Payment transfer tx (transfer_id = nonce) 7cbba41d…
record_attestation tx f9759829…
Flagship service #5 register_service (2026-07-02) dbfdecbb…
#5 buyer-paid transfer via agentgate buy (2.5 CSPR) d6cbfcab…
#5 record_attestation 23ddacf9…

Going live

The registry is deployed to Casper Testnet (addresses above). The deploy runbook is in docs/DEPLOY.md, including the wasm toolchain requirement (binaryen ≥ 123 + wasm-strip; older binaryen leaves a bulk-memory DataCount section that makes stored entry-point calls revert with "Sections out of order") and the verify-against-deployed-contract notes.

Hosting the services is documented in docs/HOSTING.md: dashboard → Vercel (root vercel.json), middleware + oracle → Railway (per-package Dockerfiles + railway.json), plus a self-contained docker-compose.hosting.yml demo stack.

Currently hosted: the live-mode gateway runs at https://gateway.mdloglabs.org and the dashboard at https://agentgate.mdloglabs.org (cloudflared tunnels → local PM2 services; runbook + deploy/agentgate.ecosystem.config.cjs in docs/DEPLOY-GATEWAY.md). The CLI is published to npm as @mdlog/agentgate.

Roadmap

Testnet Plan B (native transfer + transfer_id) → mainnet → x402 Facilitator (Plan A) → CSPR.cloud streaming → MCP server for agent frameworks.

Hackathon

Built solo by mdlog for the Casper Agentic Buildathon 2026 (Casper Innovation Track — Agentic AI × DeFi/RWA on Casper).

License

MIT

About

Stripe for AI agents on Casper — x402 (HTTP 402) payment gateway with an on-chain service registry, native CSPR payments, and attestation-based trust scores. Live on Casper Testnet.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors