尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Arbitrum Open House Singapore entry. Before an agent pays on Robinhood Chain or
Arbitrum One: is that USDG real, and who gets paid? Try
a-identity.xyz/check/robinhood. What was built
during the Buildathon, what existed before, and how to verify both:
docs/arbitrum-open-house.md.
Captured from a-identity.xyz in production, so every number in it is a live read rather than a mockup.
The passport and wallet for the agentic economy. Give every AI agent a
verified on-chain identity and a wallet it can pay from. Verify first, then pay,
with a human in the tower for anything that moves real value.檢視完整 README ↗Live demo | Docs | Architecture | Roadmap
Arbitrum Open House Singapore entry. Before an agent pays on Robinhood Chain or Arbitrum One: is that USDG real, and who gets paid? Try a-identity.xyz/check/robinhood. What was built during the Buildathon, what existed before, and how to verify both: docs/arbitrum-open-house.md.
Captured from a-identity.xyz in production, so every number in it is a live read rather than a mockup.
| You are | Start here |
|---|---|
| An agent operator | a-identity.xyz/intro - claim an Agent ID, verify with KYA, set spend limits. MCP: claude mcp add a-identity --transport http https://a-identity.xyz/mcp |
| A service builder | Docs quickstart + npm i @a-identity/marketplace-sdk - register, get hired, settle in USDC |
| A judge (60 seconds) | Sign in as guest (read-only, no keys) then jump to judge mode - live contracts, real transactions |
The passport and wallet for the agentic economy. Give every AI agent a verified on-chain identity and a wallet it can pay from. Verify first, then pay, with a human in the tower for anything that moves real value.
Built on Circle Arc (gas paid in USDC, sub-second finality), using ERC-8004 for identity, ERC-8183 for job escrow, and x402 for per-request payments.
Arc Mainnet is live. Arc opened to the public on 2026-09-16 and A-Identity went live on it the same day: agent #0, the first identity the canonical ERC-8004 registry on Arc Mainnet ever minted, an AgentSpendPolicy vault holding real USDC under a 1 USDC daily cap, and trust checks paid through both Circle Gateway nanopayments and our own EIP-3009 facilitator. Every receipt is at /arc and /proof/arc; the first payments were our own and are labeled internal.
Status: early-stage and pre-revenue: nearly every mainnet payment so far is our own, and the few checks paid by wallets off our internal lists are labeled external on /proof/arc. Arc was phase 1 and is now live on mainnet, with escrow and KYA anchoring still on Arc testnet. Stellar is phase 2 and shipped: the Soroban spend vault holds real Circle USDC on pubnet under a 1 USDC daily cap, and the hosted deployment sells over the Soroban x402 rail on BOTH Stellar networks, with the first mainnet sale settled 2026-08-27 by our own broadcaster. Pubnet is
live; the testnet mirror staysbeta, because test money is not live money. The chain page is Build on Stellar. Algorand is phase 3 and wentlivethe day it shipped, 2026-08-30: an x402 v2 rail through the GoPlausible facilitator with a real mainnet sale recorded (0.001 USDC, funded end to end from a Stellar XLM treasury; the whole trail is at /proof/algorand). Its testnet mirror staysbeta. Avalanche is after that.
One product, one live engine. The hackathons below are past entries, not awards: none of them won a prize.
0x6a5f...8ce6 on OKLink,
all of them from our own buyer wallet during the demo and seeding runs, so not revenue.
Details in the OKX.AI section below.Track alignment (Agentic Economy) - every claim is verifiable on-chain:
| We demonstrate | The proof |
|---|---|
| Agents with verified on-chain identity | ERC-8004 anchor tx + KYA attestation in Proof it's real |
| Agents paying agents, bounded by policy | 120 self-funded x402 settlements with tx hashes at /proof (the same list is in mcp/src/asp/settlements.ts); over-limit pay() reverts on Arc |
| A working agent marketplace with escrow | ERC-8183 job #155504 full lifecycle txs below; only KYA-verified agents hireable |
| Autonomy with a human in the tower | /api/guardrail-status answers 503 the moment the engine stops enforcing |
One rule: verify first, then pay. A buyer agent asks A-Identity about a
counterparty before any money moves. A clean counterparty gets paid at machine
speed; one we hold evidence against (revoked KYA, a Sybil flag, or a low reputation with
rejected settlements or guardrail override attempts on its record) gets a hard
DENY, as does one where we could not read our record, because we stay strict and the reasons
say which; and one we know nothing about gets WARN,
with reasons that say what we do not know, because unknown is not the same as bad. It is
not the same as clean either: a payee with a bad record can appear under a new address.
sequenceDiagram
autonumber
participant B as Buyer agent
participant O as A-Identity Trust Oracle
participant Chain as On-chain (ERC-8004)
participant S as Seller agent
B->>O: verify the counterparty (risk_check)
O->>Chain: read identity + KYA + reputation
Chain-->>O: live on-chain signals
O-->>B: ALLOW / WARN / DENY + reasons
Note over B,S: DENY, do not pay
B->>S: ALLOW, pay in USDC over x402
S-->>B: deliver the work
The system is three layers under that one rule: identity (who is this agent), bounded authority (what is it allowed to spend), and payment rails (how it settles), all anchored on-chain.
flowchart TB
A["AI agent / human"] --> ID
subgraph ID["1. Identity, verify first"]
direction LR
E["ERC-8004<br/>IdentityRegistry"]
K["KYA<br/>ValidationRegistry"]
R["Reputation 0-1000<br/>+ Sybil + risk verdict"]
end
ID --> ENF
subgraph ENF["2. Bounded authority, 3 enforcement layers"]
direction LR
SV["Server policy<br/>pre-check"]
VA["On-chain vault<br/>spend caps + freeze"]
CW["Circle Agent<br/>Wallet screening"]
end
ENF --> PAY
subgraph PAY["3. Payment rails"]
direction LR
X["x402<br/>pay-per-call"]
NP["Nanopayments<br/>gasless"]
ES["ERC-8183<br/>job escrow"]
end
PAY --> SET["Settle in USDC on Circle Arc<br/>Gateway + CCTP for cross-chain"]
ID -. sells its trust tools .-> OKX["OKX.AI Trust Oracle<br/>x402 on X Layer mainnet"]
A-Identity is now a trusted agent marketplace on Arc: anyone registers an autonomous agent as a verified worker, it takes tasks, and it gets paid in USDC through on-chain escrow. The identity/reputation product above is the trust layer that makes it trusted: only KYA-verified agents are hireable, every payment is bounded, every settlement is on-chain.
The loop: verify (ERC-8004 + KYA) → hire (fund an ERC-8183 escrow) → work (the agent buys helper APIs over x402 mid-task) → verify (a verifier agent checks the deliverable) → release (the escrow settles USDC on Arc) → earn (reputation + a cross-chain redeem via Gateway).
| The Agent House: verified agents, live KYA badges, real reputation | An agent's public certificate: score breakdown, services, on-chain id |
|---|---|
GET /api/marketplace/catalog · POST /api/marketplace/hire | deliver | release | dispute · GET /api/marketplace/task | tasks. Only KYA-verified agents are hireable.POST /api/v1/agents/register (any framework registers its agent with
a verified session: a Bearer token from OAuth, or a wallet or email sign-in, see
auth.md) + GET /api/v1/agents/manifest (a per-agent AMP
"Discover" manifest). Registering writes a platform record on Arc testnet; it stays
onchain: queued until the owner anchors it from the console.@a-identity/marketplace-sdk: register / hire / deliver / release in ~10 lines.find_agent · hire_agent · deliver_task · check_task_status ·
release_escrow, and register_agent (every write, registering included, requires a verified
session and answers Forbidden without one; an external agent transacts entirely over MCP).worker.mjs (translation / data-analysis / code-review, real
Claude work + mid-task x402 purchase), verifier.mjs (auto release/dispute on real signals),
starter-kit-demo.mjs (external agent over MCP), seed-demo.mjs (real on-chain activity).AMP - Agent Machine Payments (MPP / Mastercard Agent Pay framing): Discover (ERC-8004 passport + catalog + manifest) → Authorize (spend caps + human-on-the-loop) → Execute (x402 + Nanopayments + ERC-8183 escrow) → Settle (USDC on Arc, sub-second; Gateway/CCTP cross-chain).
Honesty note: with a funded signer, a task locks its escrow on-chain at hire (real ERC-8183 createJob → setBudget → approve → fund) and completes on-chain at release (submit → complete), both verifiable on the Arc explorer. The platform signer is the escrow party in this build; each party signing from its own wallet is the roadmap. Without a signer key the task is funded off-chain and release is clearly labeled
simulated(no fake tx). On-chain funding at hire is best-effort: any failure falls back to off-chain funded, so a hire never breaks.
A-Identity was listed on OKX.AI until OKX.AI delisted #6271 and #8913 on 2026-09-26, as an A2MCP ASP,
the identity and reputation oracle for the agent economy. Before any agent-to-agent
transaction, an agent calls us to verify the counterparty. Same live engine as the
Arc product below; seven services, six of them paid, sold pay-per-call via x402 on X Layer mainnet
(eip155:196).
How a paid call settles (real USD₮0 on X Layer mainnet, gas sponsored by the OKX facilitator):
sequenceDiagram
autonumber
participant A as Buyer agent (OKX Agentic Wallet)
participant T as Trust Oracle (A2MCP endpoint)
A->>T: POST /tools/risk_check { agentId }
T-->>A: HTTP 402 + x402 challenge (X Layer, USD₮0)
A->>A: sign and pay on X Layer mainnet
A->>T: retry with the PAYMENT-SIGNATURE header
T-->>A: HTTP 200 + ALLOW / WARN / DENY + on-chain proof
| Tool | Price | What it returns |
|---|---|---|
trust_preview | free | coarse trust band + revoked/Sybil flags (rate-limited adoption on-ramp) |
verify_agent | $0.001 | ERC-8004 on-chain identity + KYA status |
reputation_score | $0.002 | deterministic 0-1000 reputation from real on-chain settlements |
risk_check | $0.005 | pre-transaction ALLOW / WARN / DENY with reasons |
guardrail_check | $0.005 | whether the agent runs under an enforced policy, reported in bands, never raw limits |
counterparty_check | $0.008 | deal-specific two-agent verdict + same-operator self-deal detection |
agent_passport | $0.01 | full passport: identity + KYA + reputation + risk |
Live endpoint: https://a-identity-asp.onrender.com - POST /tools/<name> (paid),
or free GET /proof, GET /methodology, GET /health.
Real on-chain settlements (not a mock, and not revenue: sub-cent amounts by design): 120 real x402 settlements on X Layer mainnet, all
paid by our own buyer wallet during the demo and seeding runs, and all listed at GET /proof and in
mcp/src/asp/settlements.ts. Four representative ones, each independently verifiable on OKLink:
| Tool | Settlement tx |
|---|---|
verify_agent | 0x8174a4b2…c5e7a27a |
reputation_score | 0x2ede816a…977fc9af |
risk_check | 0x36977927…fa8557c1 |
agent_passport | 0xc7f9342b…c302a0cb |
Backed by real data, not an LLM guess: a live ERC-8004 showcase agent, Meridian
#849980, KYA-verified, with a reputation earned from 3 real settlements. The score
itself is recency-weighted and decays as those settlements age, so it is read live rather
than quoted here. Scoring is deterministic and
unit-tested (2613 unit tests as of Nov 2026), reads on-chain live via viem, and is fully documented at
GET /methodology. This is our answer to "surface your rigor": every number is
reproducible and every settlement is on-chain.
timeline
title A-Identity for the OKX.AI Genesis Hackathon
Jul 6 : Idea, the trust oracle for the agent economy
Jul 10-11 : Live engine, ERC-8004 identity + deterministic 0-1000 reputation
Jul 17 : Live on OKX.AI as Agent #6271, x402 on X Layer mainnet
Jul 21-22 : Deeper tools, Sybil detection + on-chain attestation + counterparty_check
Jul 24 : Multichain identity + step-by-step verify pipeline
Jul 24-25 : 120 real settlements on X Layer, OKX buyer-CLI verified end to end
Jul 25 : Submission, 6 tools + backup Risk Copilot ASP + demo
An agent gets two things it does not have today:
The product is a full loop: register an agent (KYA) -> create a wallet -> fund it -> set permissions -> give it instructions (pay / purchase / rent / batch) -> watch it in Agent House. Anything above the limits you set pauses for your approval.
The backend reads real deployed contracts, no mocks. Every address below is the
one in the chain registry (mcp/src/chains/registry.ts), in registry order, and
nothing is listed that a live eth_getCode plus a real read did not confirm. A missing
address is not always missing on-chain: Arc Mainnet and several other mainnets carry
the ERC-8004 ValidationRegistry proxy, which we have not wired, so it is not listed.
eip155:5042 - liveLive since the day Arc Mainnet opened, 2026-09-16. Agent #0, the registry's first mint,
is ours (tx 0x1d9f5711...).
x402 settled here through our own EIP-3009 facilitator (tx
0xd44287c8...)
and through Circle Gateway nanopayments. The first payments were self-funded; wallets off our
internal lists have paid for a few checks since, and each side is labeled. Our own verify-then-pay
flows run here too, and one 0.5 USDC payment was mined and refused by the vault on chain (tx
0x134de0b2...).
The explorer's pages open
in a browser without signing in (only its JSON API turns non-browser clients away with a
bot challenge); every transaction is also at /proof/arc.
| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004a169fb4a3325136eb29fa0ceb6d2e539a432 | ERC-8004 |
| Reputation Registry | 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 | ERC-8004 |
| AgentSpendPolicy vault (ours) | 0xe07819e6d28a5dfd5a9f4cd94dc6dc9aeeda4146 | Spend policy |
| USDC | 0x3600000000000000000000000000000000000000 | ERC-20 + EIP-3009 |
eip155:5042002 - live| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004A818BFB912233c491871b3d84c89A494BD9e | ERC-8004 |
| Reputation Registry | 0x8004B663056A597Dffe9eCcC1965A193B7388713 | ERC-8004 |
| Validation Registry | 0x8004Cb1BF31DAf7788923b405b754f57acEB4272 | ERC-8004 |
| Agentic Commerce (jobs) | 0x0747EEf0706327138c69792bF28Cd525089e4583 | ERC-8183 |
| USDC | 0x3600000000000000000000000000000000000000 | ERC-20 |
Our showcase agent #849980 lives here, and so do the escrow, the spend-policy vault and the Gateway nanopayment rail.
eip155:196 - live| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004a169fb4a3325136eb29fa0ceb6d2e539a432 | ERC-8004 |
OKX.AI's own registry, not ours. Our paid Trust Oracle is agent #6271 in it (with #8913 as the backup listing), and its x402 calls settle in real USD₮0.
eip155:46630 - beta| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004A818BFB912233c491871b3d84c89A494BD9e | ERC-8004 |
| Reputation Registry | 0x8004B663056A597Dffe9eCcC1965A193B7388713 | ERC-8004 |
| Validation Registry | 0x8004Cb1BF31DAf7788923b405b754f57acEB4272 | ERC-8004 |
The full canonical ERC-8004 set, at the same addresses as Arc. Agent #0 is ours: mint tx. Its settlement token is the canonical bridge's USDC.e, which our facilitator can verify against; we do not sell on this testnet.
eip155:4663 - live| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004a169fb4a3325136eb29fa0ceb6d2e539a432 | ERC-8004 |
| Reputation Registry | 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 | ERC-8004 |
We did not deploy these registries. The ERC-8004 authors did. What is ours is
agent #0, the registry's first mint:
tx 0x602ce85a…
in block 34617892, owner 0xd305607510E0Db2c95807173c7A05BEA53c1ed36, tokenURI
agent-card.json. The family's
ValidationRegistry proxy has code here too (read live 2026-10-11), but we do not wire it,
so KYA is not anchored on-chain here.
eip155:42220 - live| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432 | ERC-8004 |
| Reputation Registry | 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 | ERC-8004 |
| USDC | 0xcebA9300f2b948710d2653dD7B07f33A8B32118C | ERC-20 |
Our agent is #9759, and the four trust tools sell here over the first-party x402 facilitator Celo runs, not one of ours. Every payment so far came from our own buyer wallet and is labeled internal at /celo-proof. Celo has a ValidationRegistry proxy that we do not wire, so KYA is not anchored on-chain there either.
eip155:11142220 - beta| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004A818BFB912233c491871b3d84c89A494BD9e | ERC-8004 |
| Reputation Registry | 0x8004B663056A597Dffe9eCcC1965A193B7388713 | ERC-8004 |
| USDC | 0x01C5C0122039549AD1493B8220cABEdD739BC44E | ERC-20 |
eip155:42161 - live| Contract | Address | Standard |
|---|---|---|
| Identity Registry | 0x8004a169fb4a3325136eb29fa0ceb6d2e539a432 | ERC-8004 |
| Reputation Registry | 0x8004BAa17C55a88189AE136b182e5fdA19dE9b63 | ERC-8004 |
| USDC | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 | ERC-20 |
The canonical registries again, deployed by their authors rather than by us. Ours is agent #1259 (mint tx), and paid calls settle in native Circle USDC through our own EIP-3009 facilitator (first settlement, 0.015 USDC, block 494160024). The family's ValidationRegistry proxy has code here but we do not wire it, so KYA is not anchored here.
stellar:testnet - beta| Contract | Address | Standard |
|---|---|---|
| AgentSpendPolicy | CAIL6ECR...G2ZOEB4UI | Soroban, ours |
| USDC | CBIELTK6...IHMXQDAMA | SEP-41 |
The only chain here where the spending limit is enforced by a contract before the
payment exists. AgentSpendPolicy is ours, written in Rust for this chain rather than
translated: Soroban has no msg.sender, so the whole authorization surface collapses
onto one require_auth line, and the suite proves it would notice if that line went
missing (soroban/README.md). Both halves are on the ledger: an
under-limit payment
settled,
and an over-limit one was
refused on chain
with the contract's typed DailyCapExceeded. x402 settles here in SEP-41 USDC through a
Soroban facilitator we wrote for this chain, with the buyer signing an authorization
entry and paying no network fee.
The full artifact ledger is at
/api/proof/stellar.
Test money, and it stays labeled that way. Pubnet is a separate record: the same vault
wasm, byte for byte, at
CB5LYXFK...WSYP,
holding real Circle USDC under a 1 USDC daily cap, with four settlements, a freeze and an
owner override on the ledger. Pubnet is live; the testnet mirror stays beta, because
test money is not live money. Since 2026-08-27 the Soroban x402 rail sells on pubnet
too: the first mainnet sale (tx f213371c, 0.001 USDC) settled through our own
broadcaster, the buyer signing an authorization entry and paying no fee, the sale
counted only once the SEP-41 transfer event bound to its nonce was read back. Since
2026-09-15 the console reads live vault state and prepares the owner calls (set_policy,
set_frozen, set_allowed, set_session_key_expiry, withdraw, owner_pay) for the
owner to sign with their own Stellar wallet, so the server never holds that key, and a
per-agent Soroban vault can be provisioned on testnet against the existing code entry.
There is no ERC-8004 on Stellar, so an agent's passport is bridged from an EVM chain
rather than anchored here; TrionLabs' third-party Stellar 8004 registry is read, read-only
and labeled as theirs, which is a pointer and not our anchor. Since 2026-09-19 testnet also
carries a second vault, CBGTXWFB...NS6J6U,
whose owner is not a key at all but an OpenZeppelin smart account signed by a WebAuthn
passkey: it set its own policy, allowlisted a payee, paid one, and refused a revoked payee
on the ledger with PayeeNotAllowed, all recorded in
soroban/releases/testnet-passkey-owner-2026-09-19.json.
The chain page is Build on Stellar.
The Stellar work here was written with kaankacar/stellar-build
installed. That bundle does not redistribute the Stellar knowledge modules; it fetches them
from their canonical upstreams at install time and drops them at the paths below. The paths
are where each file sits once installed, and each link points at the upstream revision it
came from, so every link resolves.
Skill files used:
skills/soroban/SKILL.md (the AgentSpendPolicy contract in soroban/contracts/agent-spend-policy: storage choices, the single require_auth line, typed errors, instance TTL)skills/smart-contracts/SKILL.md (the audit and negative-control discipline in soroban/audit, where each guard is deleted in turn and the suite is required to go red)skills/dapp/SKILL.md (Stellar Wallets Kit sign-in in src/lib/stellar/kit.ts, and the passkey smart account flow behind the vault above)skills/agentic-payments/SKILL.md (the Soroban x402 rail in mcp/src/x402-stellar, where the buyer signs an authorization entry and pays no network fee)skills/data/SKILL.md (the RPC and Horizon reads in mcp/src/chains/stellar, including read failover and turning a ledger TTL into a date)skills/assets/SKILL.md (SAC derivation on both networks and the trustline handling every classic payee needs)skills/cross-chain/SKILL.md (CCTP between Stellar and EVM in mcp/src/cctp-stellar.ts: domain 27 and the CctpForwarder a Stellar recipient requires)Not used, and why:
skills/stellar-anchor-skill/SKILL.md (no anchor built)skills/zk-proofs/SKILL.md (no ZK circuit built)Those last two were read past rather than applied, and the reason is structural rather than
a matter of time: this project operates no fiat on-ramp or off-ramp, so there is no anchor
and no SEP-6, SEP-24 or SEP-31 flow to build, and it proves nothing in zero knowledge, so
there is no circuit and no verifier contract. Two notes on the links: soroban is pinned to
the revision installed here because upstream has since split that skill into
smart-contracts, and the anchor skill comes from Cheesecake Labs rather than from the same
upstream as the rest.
Base carries the canonical ERC-8004 identity and reputation registries (verified
2026-08-28 by reading each proxy's EIP-1967 implementation slot and matching the
implementation code byte for byte against Arbitrum One), our agent #73232 (minted
2026-08-27 UTC, tx 0xb428bf8e), native Circle USDC, the Gateway hop, and the same
first-party x402 facilitator that serves Arc Mainnet, Robinhood Chain and Arbitrum One, settling in
native USDC: the first settlement landed 2026-08-27 UTC (tx 0xb59ae67c, 102828 gas, the
receipt carrying the matching Transfer log). A second rail sells the same tools here
through Circle Gateway nanopayments to Circle Agent Marketplace buyers, gasless on both
sides, and stays labeled unproven until a Gateway-credited call is read back. The whole
trail, including the Stellar funding hop behind the wallets, is on
/proof/base.
Avalanche carries public metadata only and stays planned until something of ours is
deployed on it.
Machine-readable: the chain registry is served live at
GET /api/chains and the same table ships
in .well-known/ai-agent-manifest.json.
GET /api/arc/contracts reads them live (registry name AgentIdentity, symbol
AGENT, USDC 6 decimals). GET /api/arc reads the latest block over JSON-RPC.
Writes (agent registration, job escrow) are wired against the same contracts and
broadcast for real once a funded signer key is present.
No install, no keys - it is already live:
Open the app: a-identity.xyz - use Continue as guest on the sign-in screen (read-only, honest banner, nothing to configure). Creating an agent with an in-browser wallet takes one more minute if you want the full write path.
Prove the backend is real (a live on-chain read, not a mock):
curl https://a-identity-backend.onrender.com/api/arc/contracts
Open the real transactions on Arc - the "Proof it's real" links below.
Look up any agent publicly: /explorer?q=849980 runs the whole verify pipeline (resolve identity → KYA → reputation → verdict) with no login.
First hit can take ~30s if the free-tier backend is waking up; retry once and it is warm.
Every claim here is a transaction you can open on the Arc testnet explorer:
0x506b125f… ·
KYA attestation:
0x758ddbfa…0xcce5a56c… →
complete
0x245f0ee7…An agent's spend policy can be deployed as its own smart contract on Arc:
AgentSpendPolicy (mcp/contracts/AgentSpendPolicy.sol). Once an agent is given a
vault, its USDC payments settle through the contract, which enforces the policy
on-chain - a per-UTC-day cap, an auto-approve ceiling, a payee allowlist, and a freeze
switch. A payment that breaks a rule reverts on Arc with a typed error (verifiable
on the Arc explorer), not just a server "no"; the human owner can override, adjust limits, freeze,
or withdraw. The server policy engine stays as the fast pre-check and fallback, so agents
without a vault behave exactly as before.
Try it: cd mcp && node --env-file=.env scripts/test-vault.mjs (needs a funded
ARC_SIGNER_KEY) deploys a vault and plays pay / over-limit-revert / freeze / cap out on
real Arc testnet - or use the Permissions → On-chain policy vault panel in the app.
Memo precompileEvery direct USDC settlement is routed through Arc's predeployed Memo precompile
(0x5294…), so each agent payment carries an on-chain, indexable audit trail of why it
happened - {agentId, instructionId, service, policyDecision} - emitted as a Memo event on
the Arc explorer, not a server log. Memo.memo(usdc, transferCalldata, memoId, memoBytes) routes the
transfer via the CallFrom precompile, so the paying wallet stays msg.sender (the USDC still
moves exactly as a bare transfer, plus the reason). The memoId is a deterministic keccak of the
instruction, so anyone can look the payment up by memoId without the tx hash. Additive and
credential-gated: on a chain without a Memo precompile it degrades to a plain transfer; the
smart-account vault path stays un-memoed (an SCA can't call the precompile). The Settlements
screen shows the reason and links to the memo on the Arc explorer.
Try it: cd mcp && node --env-file=.env scripts/test-memo.mjs settles $0.01 through the Memo
precompile on real Arc testnet, then reads the emitted event back by its memoId to prove the
reason is provably on-chain. Read it live: GET /api/arc/memos?memoId=<0x…> (or ?sender=<0x…>).
An agent can pay a whole burst of USDC transfers in a single, all-or-nothing Arc transaction
through the predeployed Multicall3From precompile (0x522f…): aggregate3(...) routes each
transfer via CallFrom, so the wallet stays msg.sender for every subcall (one on-chain
Transfer per payment, from = the wallet). This is Arc-native batching for high-frequency
agent payments. allowFailure=false, so the batch is atomic.
→ mcp/src/chains/evm/adapter.ts (payUsdcBatch) · POST /api/arc/batch-demo · the
Settlements "Batched settlement (Multicall3From)" panel. On a chain without the precompile it
degrades to a sequential loop; prepared without a signer.
Try it: cd mcp && node --env-file=.env scripts/test-batch.mjs settles three USDC transfers in
one tx and verifies the three Transfer events, each with from set to your wallet.
When an agent hires another through the ERC-8183 escrow, the money isn't a blind prepay: the
budget is held in escrow and only released to the provider on delivery. If the deliverable is
disputed, the evaluator rejects it and the escrowed USDC is refunded to the client in the same
transaction (reject → Refunded) - buyer protection, on-chain. A second safety net,
claimRefund, lets the client reclaim the escrow after the job's deadline passes (an expiry
refund). This is the ERC-8183 AgenticCommerce reference implementation's own refund path - no
blind prepay, trust-minimized agent-to-agent commerce.
mcp/src/chains/evm/adapter.ts (runEscrowDemo({ outcome }), rejectJob,
claimJobRefund, readJob) · POST /api/arc/job-demo {outcome}, POST /api/arc/job/dispute,
POST /api/arc/job/claim-refund, GET /api/arc/job?jobId=.Try it: cd mcp && node --env-file=.env scripts/test-refund.mjs runs the full dispute lifecycle
(create → fund → submit → reject) on real Arc testnet and proves the client is refunded on-chain.
The same Trust Oracle we sell on OKX.AI (and list on Circle's Agent Marketplace - manifest
in mcp/marketplace/, served live at
/.well-known/agent.json) is
dogfooded by our own agents: before it pays a counterparty, a buyer agent buys a risk_check
over x402 - a gasless Arc-testnet nanopayment via Circle Gateway - and acts on the returned
ALLOW / WARN / DENY verdict. A live "agent pays an agent for trust" loop, on real Arc.
mcp/src/trust-oracle.ts (runTrustOracleDogfood) · POST /api/arc/trust-oracle-demo.Try it: cd mcp && node --env-file=.env scripts/test-dogfood.mjs - a buyer agent pays $0.005 over
x402 on real Arc testnet and gets the verdict on the counterparty before it can transact.
An agent is no longer marked verified for free. It must prove control of its wallet by
signing a challenge (the same verifyMessage primitive as wallet sign-in); only then does its
KYA flip to verified. New agents start unverified; a wrong signature is rejected. The result
is attested on Arc's real ERC-8004 ValidationRegistry (validationRequest +
validationResponse=100, tag "kya", readable via getSummary). Honest by design: an
operator/wallet-proof attestation, not a third-party audit.
An agent's on-chain policy vault can be granted a session key: the operator (the agent's
signer) is authorized by the human owner, scoped by the spend cap and payee allowlist and - now
pay reverts (SessionKeyExpired) until the owner
extends, re-grants, or revokes it (ownerPay overrides are never time-bound). This is the purest
expression of bounded authority - no human in the loop, but it can't run amok - enforced by the
contract (mcp/contracts/AgentSpendPolicy.sol sessionKeyExpiry / setSessionKeyExpiry), not a
server. Grant it from Permissions → On-chain Policy Vault → Session key.The bounds have sharp edges an owner should know. The cap is a calendar UTC day, so up to twice it can
go within seconds around 00:00 UTC. An ownerPay counts toward the agent's day and can stop it until
00:00 UTC; a withdraw does not. setPolicy writes both limits and the allowlist flag in one call. 0
means no limit, not no spending. The end date belongs to the vault, so a new one after a revoke turns
the same key back on, and a new key keeps it: replace a key that may have leaked first. See
the integration guide.
Try it: cd mcp && node --env-file=.env scripts/test-session.mjs runs the full lifecycle on real
Arc testnet - grant → pay within the window → the key expires → the agent's pay reverts → the owner
extends → pays again → revoke → reverts.
Real ERC-4337 session key (the standard AA primitive). The same idea, expressed as an actual
account-abstraction session key: the owner deploys a Kernel (ERC-4337 v0.7) smart account and
grants the agent a session key scoped by standard permission policies - toTimestampPolicy
(expiry), toCallPolicy (a payee allowlist + a per-tx cap). The agent then settles entirely on its
own by signing a UserOperation; a payment outside the bounds is rejected by the account's policy
validator on-chain, not a server. Runs on Arc testnet via a Pimlico bundler (Zerodev Kernel).
→ mcp/src/aa-wallet.ts · credential PIMLICO_API_KEY (free at pimlico.io; clean prepared no-op
without it) · POST /api/arc/session-key-demo · the Settlements → "Session-key smart account
(ERC-4337)" panel.
Try it: cd mcp && node --env-file=.env scripts/test-aa-session.mjs deploys a Kernel smart account,
grants a session key (cap + allowlist + expiry), and proves it settles a real UserOp within
bounds while an out-of-bounds payment is rejected on-chain by the policy validator.
An agent can also be given a Circle Agent Wallet (Developer-Controlled, on ARC-TESTNET):
Circle's hosted policy engine screens every USDC transfer at the wallet layer (sanctions, address
allow/block, freeze). Credential-gated behind CIRCLE_API_KEY + CIRCLE_ENTITY_SECRET; a clean
no-op without them. Precise by design: Circle screens transfers - the USD spend cap stays enforced
by our server and the on-chain vault. Together: server pre-check + Circle screening + on-chain
vault = three separate enforcement layers.
The same system in three views (also drop-in slides for a deck):
a-identity/
├─ src/ React 19 + Vite + Tailwind v4 frontend (landing, app, blog, use cases)
├─ mcp/ Backend: MCP server + REST companion (Node + viem)
│ ├─ contracts/ AgentSpendPolicy.sol - on-chain spend-policy vault (npm run compile)
│ └─ src/
│ ├─ arc.ts Live Arc testnet status (block reads)
│ ├─ arc-contracts.ts Real ERC-8004 + ERC-8183 reads/writes + AgentSpendPolicy vault
│ ├─ circle.ts Circle developer platform link (env-gated ping)
│ ├─ platform.ts Agents, wallets, instructions, marketplace (write side)
│ ├─ erc8004.ts Multi-chain identity provider (mock + rpc)
│ ├─ reputation.ts Deterministic reputation score (0-1000)
│ └─ http.ts REST + Streamable HTTP MCP endpoints
├─ docs/ Mintlify documentation site
└─ .env.example Every configurable key, documented
Two entry points share the same tools: an MCP server (read-only tools for agents) and a REST API (the write side that the app uses).
GET /health liveness + supported chains
GET /api/arc live Arc testnet block/chainId
GET /api/arc/contracts LIVE reads of ERC-8004 + ERC-8183 + USDC
POST /api/arc/register-onchain ERC-8004 register (prepared, or real w/ key)
POST /api/arc/create-job ERC-8183 createJob (prepared, or real w/ key)
GET /api/circle Circle platform link (real ping w/ CIRCLE_API_KEY)
POST /api/wallets create a real Arc keypair (key returned once)
GET /api/wallet-balance live native-USDC balance
POST /api/agents register an agent (KYA + permissions)
POST /api/instructions pay / purchase / rental / batch (policy engine)
POST /api/instructions/approve human approval
POST /api/instructions/execute execute (through the vault if provisioned, else direct; simulated without a signer)
POST /api/agents/vault provision an on-chain AgentSpendPolicy vault (real w/ key)
GET /api/agents/vault live on-chain vault policy + balance
POST /api/agents/circle-wallet provision a Circle Agent Wallet (hosted screening, w/ Circle keys)
GET /api/agents/circle-wallet live Circle wallet state + balance
POST /api/agents/kya/challenge start a KYA wallet-control challenge
POST /api/agents/kya/verify verify the signature, key or ERC-1271 contract account (+ on-chain ValidationRegistry attestation)
POST /api/agents/circle-policy/challenge hash a pasted `circle wallet limit --output json`; returns the message the wallet signs
POST /api/agents/circle-policy/attest store the owner-attested Circle policy as bands + signed hash (never the policy)
GET /api/agents/circle-policy/attestation the attestation, bands only
GET /api/agents/circle-policy the same caps as Circle wallet policy commands the owner runs (owner only)
GET /api/agents/kya KYA status + live on-chain validation
GET /api/x402/nano/data x402 Nanopayments seller (gasless, Gateway-batched; 402→settle)
GET /api/x402/gateway/tools/:name the trust tools for Circle Agent Marketplace buyers: Gateway nanopayments on Arc Mainnet and Base mainnet (402; GET or POST to pay)
GET /api/x402/gateway/status that rail's config and the Gateway kind proven per chain
GET /api/x402/gateway/proof Gateway-credited settlements, batch hashes once landed
POST /api/x402/gateway/verify-then-pay free vault + payee checks on Arc Mainnet, then risk_check through Gateway; returns the vault call to sign (never signs)
GET /api/x402/gateway/flows/:flowId one verify-then-pay flow, public by its check nonce (a DENY's evidence)
POST /api/x402/gateway/flows/:flowId/receipt {txHash}: the server reads the receipt from every RPC and records only what it proves
POST /api/arc/nanopay-demo one-click gasless nanopayment (EIP-3009 + Circle Gateway batch)
POST /api/arc/cctp-demo one-click CCTP burn-and-mint (Arc→Base Sepolia, native USDC)
GET /api/cctp/stellar/status CCTP between Stellar and EVM: sides, Circle-verified contracts, signers (addresses only)
POST /api/cctp/stellar/bridge CCTP transfer either way: prepared for any verified session, executed only for CCTP_BRIDGE_OPERATORS (dedicated keys; capped; testnet unless opted in)
POST /api/arc/agent-run autonomous run: agent pays a service on its own until its budget is used up, then stops (+ protocol fee)
GET /api/marketplace Agent House feed
POST /api/follow follow an agent
POST /api/feedback site feedback from the corner widget, emailed to the team via Resend (anonymous; rate-limited; 503 when no RESEND_API_KEY)
# 1. Install
npm install
npm install --prefix mcp
# 2. Run everything (UI + MCP backend + docs)
npm run dev:all
# UI -> http://localhost:5173
# MCP -> http://localhost:3399
# Docs -> http://localhost:3000
# 3. Prove the live Arc integration
curl http://localhost:3399/api/arc/contracts
Copy .env.example to .env.local for the frontend (Vite). The backend reads
its config from the process env directly - see below. Everything is optional for
a demo: without a signer key the app still does live contract reads and labels
on-chain writes as prepared/simulated; add a funded ARC_SIGNER_KEY to
broadcast real transactions.
Fund a wallet: create one in the app (Agent ID -> New agent -> Create wallet; the keypair is generated in your browser), then get testnet USDC at faucet.circle.com.
Enable real writes: the backend reads ARC_SIGNER_KEY from process.env
and does not auto-load a .env file. Start it with the key inline:
ARC_SIGNER_KEY=0x<funded-key> node mcp/dist/http.js
# or, keeping it in mcp/.env (Node 20.6+):
node --env-file=mcp/.env mcp/dist/http.js
Now, on-chain registration, USDC settlement, and job escrow broadcast for real.
Circle platform: add CIRCLE_API_KEY (from
console.circle.com) to enable the real Circle ping.
Frontend is a static Vite build; the backend is a long-running Node server (not serverless).
VITE_MCP_URL empty so the app calls same-origin
paths (vercel.json proxies them to the backend). Set VITE_DOCS_URL to the
deployed docs site (if unset, docs links fall back to the live app origin, not a
dead domain).mcp, build npm install --include=dev && npm run build, start
npm run start:http. The server binds to the host-provided $PORT and self-pings
to stay warm on free tiers. Set in the host's env panel:
AUTH_SECRET - required: a strong, stable random string. Without it the
server signs session tokens with a random per-process secret (safe, but sessions
drop on restart) and logs a warning; a public default is never used.ALLOWED_ORIGINS - comma-separated site origins allowed to call the API
cross-origin (e.g. https://a-identity.xyz). Unset → * (dev only).ARC_SIGNER_KEY - funded key to broadcast real Arc writes (optional; without it
writes are prepared/simulated and labeled as such).DATABASE_URL - Postgres connection string for durable state.State persists to Postgres when DATABASE_URL is set, else to
mcp/data/platform.json (gitignored). x402 replay protection (spent-payment
hashes) persists the same way, so a restart can't reset it.
A free Render web service spins down after ~15 min idle and takes ~50s to wake. Because the frontend reaches it through a same-origin Vercel proxy whose gateway times out at ~30s, a cold wake shows up in the app as a hard 502 - and the poller can't warm it through the proxy, so "waiting" doesn't help. This is handled in three layers:
a-identity-backend service
→ Settings → Instance Type → Starter. This is the only way to fully eliminate the
cold-start 502 for a live demo. Recommended before any presentation..github/workflows/keep-warm.yml pings /health every
~10 min so the service never idles out. Set the repo Actions variable BACKEND_URL if
the host changes. Note: GitHub cron can be delayed under load, so it reduces - but
doesn't guarantee zero - cold starts on the free plan.src/lib/api.ts). wakeBackend() fires a direct no-cors
ping to the backend origin (bypassing the proxy's 30s cap so a cold boot can finish);
apiFetch() retries idempotent reads through a cold start and, for mutations, waits
for /health before sending exactly once (never double-submitting). The console
pre-warms the backend on mount, and screens show a "waking up" state instead of failing.A-Identity never custodies a key autonomously, never deploys a contract on its own, and never moves real value without an explicit human approval. Wallet keys are generated in the browser and never leave it - the server only ever sees the public address, and sign-in is by wallet signature (no passwords). This is a design rule, not an afterthought.
Testnet MVP, engineered like it is not. The short version:
mcp/src/x402.ts).prepared with the exact call when no signer
is configured; nothing is marked settled without a confirmed receipt.Report vulnerabilities per SECURITY.md.
The living version is ROADMAP.md (now / next / later). The phase view:
live and selling
since 2026-08-27. What is still owed there is operational rather than structural: the
2-of-3 owner signers split across more than one keystore, the vault's instance TTL
re-extended before it archives, and an external audit the contract has never had. The
pubnet fee payer was split off the vault operator key on 2026-09-15.New networks are a registry entry plus (for non-EVM) one adapter: the chain registry
(mcp/src/chains/registry.ts) is the single source of truth
and a test fails the build if anything else hardcodes a chain, so adding one is additive,
not a rewrite (see CONTRIBUTING.md).
@circle-fin/developer-controlled-wallets), Gateway,
CCTP / Bridge Kit (@circle-fin/bridge-kit), Nanopayments (@circle-fin/x402-batching),
USYC (tokenized money-market yield)AgentSpendPolicy vault,
Circle Agent Wallet screening) and honest settlement: an instruction is never marked
executed_onchain without a confirmed transaction hasha-identity.mintlify.site)How each Circle product is wired, the code path, the credential to set, and the live
endpoint - so any of it can be verified against the repo. Nothing is mocked: with the
credentials set, every path runs a real transaction on Arc; without them it returns a
prepared / not configured state and says so. The on-chain rails (Gateway, CCTP,
Nanopayments) are permissionless on Arc testnet - they need only a funded
ARC_SIGNER_KEY, no Circle API key.
0x3600…0000, 6-decimal ERC-20 view); real transfer / balanceOf.
→ mcp/src/arc-contracts.ts · credential ARC_SIGNER_KEY (to broadcast) · read live at
GET /api/wallet-balance.initiateDeveloperControlledWalletsClient → createWalletSet →
createWallets → createTransaction.
→ mcp/src/circle-agent.ts · credentials CIRCLE_API_KEY + CIRCLE_ENTITY_SECRET ·
POST/GET /api/agents/circle-wallet, status GET /api/circle.mcp/src/gateway.ts · permissionless (ARC_SIGNER_KEY only) ·
GET /api/arc/gateway-balance, POST /api/arc/gateway-demo.@circle-fin/bridge-kit + @circle-fin/adapter-viem-v2: approve → burn → attestation →
mint, Arc → Base Sepolia (never wrapped).
→ mcp/src/cctp.ts · permissionless (ARC_SIGNER_KEY only) · POST /api/arc/cctp-demo.@circle-fin/x402-batching): the buyer signs an EIP-3009 authorization off-chain, Gateway
credits instantly and batches the on-chain tx, so thousands of authorizations net into one.
→ · permissionless ( only) · seller
, one-click , autonomous
(the agent pays a burst on its own, then stops at its budget).StableFX is not used. USDY is deliberately avoided too - it is an Ondo product, not Circle, and not deployed on Arc; USYC is the Circle-native yield token used here.
Which Circle products we used, why, what worked, and what we'd improve.
Circle Arc (testnet), our base chain. Gas paid in USDC and sub-second finality
made the whole "agent pays per action" loop feel native; a single asset for both gas
and value removed a class of UX problems. Improve: the IdentityRegistry isn't
enumerable (totalSupply reverts), so a "registered agents" count needs off-chain
indexing; a documented events/indexing path would help.
Circle Gateway, chain-abstracted USDC. We deposit on Arc → a unified balance →
move it to Base Sepolia via the Forwarding Service (signed EIP-712 burn intent),
minted gaslessly in seconds, permissionlessly (no API key). This is the cleanest
cross-chain UX we integrated. Improve: the estimate→sign→submit shape and the
bytes32-padded TransferSpec fields were the fiddly part; a typed helper in the SDK
would cut integration time.
Circle Developer-Controlled Wallets (Agent Wallets), a hosted wallet layer policy engine that screens each transfer (sanctions / allow-block / freeze). We use it as one of three independent enforcement layers. Improve: the testnet faucet doesn't cover ARC-TESTNET (403), so we fund new Circle wallets from our own signer; first-class Arc faucet support would remove that step. Also, screening is transaction screening, not a per-wallet USD spend cap; we enforce the cap in our server + the on-chain vault and are explicit about that split.
USDC / faucet - the unit of account throughout; faucet.circle.com for testnet
funding.
Circle Nanopayments, gasless, sub-cent, Gateway-batched. We ship two x402 rails:
mcp/src/x402.ts) - server returns 402 + requirements →
client pays USDC on Arc → server verifies the payment on-chain with replay protection + a
single-use request nonce → serves. Open standard, provable settlement, no hosted meter.mcp/src/nanopay.ts), the same x402 negotiation over Circle
Gateway's GatewayWalletBatched scheme: the buyer signs an EIP-3009 authorization
off-chain (zero gas), Circle Gateway verifies + credits instantly and batches the
on-chain settlement, so true sub-cent payments become economical for high-frequency agent
traffic. Permissionless on Arc testnet (no API key); the buyer's balance is the same Gateway
Wallet deposit we already fund. Improve: a testnet faucet that pre-funds a Gateway balance
would remove the one-time deposit step from a first-run demo.Circle CCTP (Bridge Kit), native USDC cross-chain by burn-and-mint (mcp/src/cctp.ts):
USDC is burned on Arc and minted natively on Base Sepolia - never wrapped - via CCTPv2
(@circle-fin/bridge-kit). Distinct from Gateway's unified-balance forwarding; together they
show both canonical USDC-liquidity primitives. Improve: the "leaving Arc, amount must exceed
the CCTPv2 max fee" floor is easy to trip on tiny testnet transfers - a clearer SDK error would help.
MIT. See LICENSE.
mcp/src/nanopay.tsARC_SIGNER_KEYGET /api/x402/nano/dataPOST /api/arc/nanopay-demoPOST /api/arc/agent-runmcp/src/treasury.ts · GET/POST /api/agents/treasury.