System Architecture Overview
Payee bridges web3 stablecoin networks, biometric hardware security modules, and autonomous software workflows. Circle developer-controlled USDC wallets are mapped to biometric passkey credentials, giving users high security with a frictionless interface. AI agents interact via scoped Bearer API keys with enforced spending policies.
Integration Flow
Client Layer
Security Gate
Ledger Layer
Claiming a Paytag
Every claimed identifier is minted as a prefix-free on-chain ERC-721 NFT on the Arc Network. Choose whether a handle serves a human user or an autonomous AI agent — each gets a different auth model and metadata standard.
For Humans
Passkey SecuredPersonal handles are tied to browser WebAuthn biometrics (Touch ID, Face ID, or hardware keys). No seed phrases or private keys to manage.
myname). Displayed as the branded USDC paytag @myname.For AI Agents
ERC-8004 StandardAgent handles represent autonomous on-chain identities. They are configured with spending caps, TEE attestation, and publish discoverable ERC-8004 AgentCard metadata. Agents can also be externally-provisioned Circle CLI wallets linked to Payee for monitoring.
Comparative Feature Matrix
| Feature | Human Handle | AI Agent Handle |
|---|---|---|
| Auth Method | Device Biometrics (Passkey WebAuthn) | Bearer API Key (payee_agent_live_…) |
| Wallet Type | Circle Developer-Controlled (Payee-provisioned) | Circle Agent Wallet (CLI or Payee-provisioned) |
| Spending Caps | Unlimited (owner full custody) | Daily limit & per-tx cap enforced server-side |
| Interface | Conversational Dashboard + WhatsApp | JSON REST API / monitored via Agent Control Plane |
| Metadata Spec | Standard ERC-721 | ERC-8004 AgentCard (discoverable) |
| Paytag Handle | profiles.username | profiles.username OR agent_wallets.agent_paytag |
Paytag Registry & Tiers
Paytags establish an industry-standard, unauthenticated public namespace mapping human-readable handles directly on-chain. Registered as dynamic ERC-721 NFT contracts on the Arc Network Layer-2, every Paytag is prefix-free and bridges biometric passkeys for humans with secure hardware enclaves for AI agents.
1 — Identity Classification & Registry Tiers
Payee registry tiers classify every claimed handle into a distinct digital role, mapping them to standard smart-contract rules and metadata standards.
Human Profile
HUMANA consumer profile linked to WebAuthn browser biometrics (Touch ID / Face ID). Claiming a personal paytag automatically provisions a seedless, gasless smart wallet to settle USDC directly.
AI Agent Enclave
AGENTAn attestation-backed sovereign identity bound to Trusted Execution Environments (TEEs) and AI model hashes. Runs spending actions programmatically up to strict daily USDC budget caps.
Autonomous Service
SERVICEA decentralized machine API endpoint. Enables direct web3 billing paths for LLM token computation pipelines, vector oracle data queries, and secure backend webhook routing.
Team Organization
ORGA corporate multi-sig treasury or joint enclave handle. Direct corporate invoice settlement, team workspace spend tracking, and automated global client billing.
2 — AI Agent Identity Benefits (ERC-8004)
Upgrading a handle into a verified Agent profile binds dynamic hardware attestation and discovery standards directly to the on-chain identity.
Sovereign Trust & TEE Attestations
Every Agent Paytag binds its identifier to hardware-level Intel SGX, AMD SEV, or AWS Nitro Enclave attestation documents and LLM hashes on-chain. Third-party nodes verify the agent runs unmodified source logic before transacting.
Standardized ERC-8004 Discovery
Registered agents publish dynamic discovery URIs on-chain pointing to standard AgentCard JSONs. A2A clients, discoverability indexers, and MCP servers look up communication endpoints and capabilities automatically.
Bounded Budget Authority
Eliminate vulnerable Master private keys from script variables. Agents use restricted, budget-bounded delegated keys that manage up to set daily thresholds, fully revocable by the human owner with one click.
Inter-Agent Reputation (A2A)
As agents collaborate in complex loops, prefix-free USDC paytags enable clean audit-friendly payment logs. Agents score counterparties based on success rates, establishing an on-chain reputation matrix.
3 — Registry Technical Specifications & FAQs
General protocol architecture questions regarding namespace guidelines, network relays, and gas sponsorship.
Q: Are Paytags locked to a specific prefix like @ or $?
No. The Paytags namespace is completely prefix-free inside the PayeeRegistry contract on-chain. You claim and resolve direct alphanumeric strings (letters, numbers, and underscores). The @ character is strictly a UI/UX branding convention.
Q: How does on-chain resolution occur?
Payee uses the Arc Network Layer-2 L1 registry contract for live EVM broadcasts. The contract binds the handle string to the Circle USDC EVM wallet address, fully searchable by any web3 RPC client globally.
Q: Is there any gas or cost associated with claiming?
No. Payee runs a fully gasless relayer infrastructure. All minting, updating, and registry transfers are sponsored behind the scenes by the protocol, giving users a completely gas-free onboarding experience.
Developer Use Cases
Payee provides simple programmatic tools so developers can integrate stablecoin transactions into multiple workflows — serving both people and autonomous backend processes.
Conversational Money
Enable biometric sign-in and conversational AI chat. Humans send money with plain English: "send 2 USDC to @sarah" — no cryptographic complexity required.
Autonomous AI Agents
Equip scripts or LLM agents with scoped Bearer API keys. Set daily budgets and per-tx caps. The server enforces limits server-side before any transfer is submitted to Circle.
Seedless Smart Accounts
Turnkey HSM passkeys eliminate seed phrases. Biometrics authorize every transaction — private keys are generated in hardware and never leave the enclave.
Agent Control Plane
Link Circle Agent Wallets (provisioned on your PC via CLI) to the Payee dashboard. Monitor per-agent spending, pause agents, set budgets, and review transaction logs in real time.
ERC-8004 Discovery
Every agent handle auto-publishes a verified AgentCard at /api/agent/{username}/agent-card.json. Discovery indexers, A2A clients, and MCP servers can find and verify agent capabilities.
WhatsApp Payments
Send and receive USDC via WhatsApp messages. The Payee conversational layer understands payment intents and routes them through the same budget-gated API.
Agent Control Plane
The Agent Control Plane turns Payee into a financial oversight dashboard for AI agents running on your PC. Agents are provisioned externally via the Circle CLI, then linked to your Payee account by providing their wallet ID and address. Payee syncs transactions from the Circle API (with an on-chain ethers.js fallback) and stores them locally for fast querying.
How it works
Provision on PC
Run the Circle CLI on your machine to create an Agent Wallet. Copy the wallet ID and on-chain address from the output.
Link to Payee
Paste the wallet ID and address into the Agents dashboard. Assign a unique agent paytag (@my-claude-agent), type, and budget policy.
Monitor & Control
Payee syncs transactions every time you open the dashboard. View per-agent spend, pause an agent with one click, or fund it directly.
Step 1 — Provision on your PC (Circle CLI)
# Install the Circle CLI npm install -g @circle-fin/cli # Authenticate (OTP sent to your email) circle wallet login you@example.com # List your agent wallets — copy "id" and "address" circle wallet list --chain BASE --output json
Transaction Sync Architecture
Primary: Circle REST API
Queries GET /v1/w3s/transactions?walletIds={id}. Works for wallets provisioned under the same Circle developer account as Payee.
Fallback: On-chain ethers.js indexing
If the Circle API fails (e.g. externally-provisioned wallet), Payee uses provider.getLogs() to index USDC ERC-20 Transfer events directly. Works for any EVM wallet on Base / Arbitrum — no API key needed.
Cache: agent_wallet_transactions
Results are upserted into Postgres using circle_tx_id as the idempotency key — safe to re-run on every sync without creating duplicates.
@my-claude-agent) is checked for uniqueness across both profiles.username (human handles) and agent_wallets.agent_paytag(linked agent wallets). The paytag resolves to the agent's on-chain address via the standard /api/wallet/resolve-username endpoint, which returns handle_type: "agent" so callers can distinguish agent identities.Workflows & Spending Rules
Every operation executed through Payee follows strict database locks and safety triggers. Autonomous scripts cannot drain wallets due to software loops, double-spend attempts, or credential theft.
Claiming an On-Chain Handle
Users register a unique identifier (e.g. @arbitrage_bot). This handle is anchored via smart contracts to a secure EVM address on the Arc L1 or Base ledger. The Arc registry contract supports agentCardURI() queries for decentralized indexers.
Provisioning Delegated API Keys
Instead of sharing biometrics or seed phrases with software bots, users provision scoped API keys starting with payee_agent_live_. The user defines exact limits: e.g. daily_limit = 20 USDC and single_tx_limit = 5 USDC. Keys are stored as SHA-256 hashes and never returned after creation.
Concurrency Safety Gate
When the API receives a transfer command, the database locks the api_key row using SELECT ... FOR UPDATE. It verifies the key is active, checks that the UTC midnight reset has fired if needed, confirms both single-tx and daily limits, then submits to Circle's developer wallet API.
UTC Midnight Budget Reset
The spent_today counter resets automatically at UTC midnight. The last_spent_reset timestamp is checked on every API call — if a calendar day has passed since the last reset, spent_today is zeroed before the budget check runs.
Quickstart & Integration Code
Create an API key in Dashboard → Settings → Agent Keys. The key is shown only once — copy it immediately. All requests require the key in the Authorization header. The toAddress field accepts both 0x… addresses and @paytag handles.
// Payee Agent SDK — Node.js / TypeScript
const BASE_URL = 'https://stablepayee.xyz'
const API_KEY = 'payee_agent_live_YOUR_KEY_HERE'
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
}
async function run() {
// 1 — Fetch wallet balance
const balRes = await fetch(`${BASE_URL}/api/wallet/balance`, { headers })
const { balance, username } = await balRes.json()
console.log(`💰 @${username} balance: ${balance} USDC`)
// 2 — Send to a paytag (human or agent)
const sendRes = await fetch(`${BASE_URL}/api/wallet/send`, {
method: 'POST',
headers,
body: JSON.stringify({ toAddress: '@sarah', amount: '2.00' }),
})
const send = await sendRes.json()
if (sendRes.ok) console.log('✅ Sent! transferId:', send.transferId)
else console.error('❌ Failed:', send.error)
// 3 — Resolve any paytag to its on-chain address
const resolve = await fetch(
`${BASE_URL}/api/wallet/resolve-username?username=sarah`
)
const { address, handle_type } = await resolve.json()
console.log(`📍 @sarah → ${address} (type: ${handle_type})`)
}
run()Wallet API Endpoints
All wallet API requests must include the API key: Authorization: Bearer payee_agent_live_…
Response (200):
{
"success": true,
"balance": "250.00",
"address": "0x5462D682dB237A3a992687Bc628F5b18B33eD0c1",
"username": "arbitrage_bot",
"onchainTxHash": "0xabc123..." // registration tx hash
}Response (200):
{
"success": true,
"transactions": [
{
"id": "tx_87f9da52",
"amounts": ["10.00"],
"sourceAddress": "0x5462D682dB237A3a992687Bc628F5b18B33eD0c1",
"destinationAddress": "0x9812A6bC72e92a83C25Dcb654c6A7F2D179c3d4a",
"type": "OUTBOUND",
"state": "COMPLETE",
"createDate": "2026-05-22T19:30:15Z",
"isAgentTx": true, // true if sent via an agent API key
"agentName": "Trading Bot" // name label of the key used
}
]
}Request Body:
{
"toAddress": "0x9812A6bC72e92a83C25Dcb654c6A7F2D179c3d4a",
// OR paytag (human or agent):
"toAddress": "@sarah",
"amount": "1.50"
}Success (200):
{ "success": true, "transferId": "4c94f58c-4f9e-4e3a-b2c3-92f7e8a9f0d1" }Error — daily limit exceeded (403):
{ "error": "Amount exceeds daily spending limit. Remaining budget: 0.50 USDC" }Query params: ?username=sarah — no @ prefix needed
Response (200):
{
"success": true,
"address": "0x5462D682dB237A3a992687Bc628F5b18B33eD0c1",
"handle_type": "human", // "human" | "agent"
"username": "sarah"
}
// For a linked Circle Agent Wallet paytag:
{
"success": true,
"address": "0xAbCd...1234",
"handle_type": "agent",
"username": "my-claude-agent"
}Resolves across both human paytags (profiles.username) and agent paytags (agent_wallets.agent_paytag). Human paytags take priority on collision.
Agent Wallets API
These endpoints manage the Agent Control Plane — linking, listing, updating, and syncing Circle Agent Wallets. All requests require a valid user session (cookie-based auth, not an agent API key).
Response (200):
{
"success": true,
"wallets": [
{
"id": "uuid",
"agent_paytag": "my-claude-agent",
"display_name": "My Claude Code Agent",
"agent_type": "coding",
"circle_address": "0xAbCd...1234",
"chain": "BASE",
"daily_limit": 20,
"per_tx_limit": 5,
"is_paused": false,
"last_synced_at": "2026-06-01T04:00:00Z",
"spent_today": 3.50, // computed from cached tx log
"tx_count_today": 2
}
]
}Request Body:
// Link a Circle Agent Wallet provisioned via CLI
const res = await fetch('https://stablepayee.xyz/api/agent-wallets', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_SESSION_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
circle_wallet_id: 'a7f3d2e1-9b4c-4f8a-b2e5-1c3d5e7f9a0b', // from: circle wallet list
circle_address: '0xAbCd...1234', // from: circle wallet list
chain: 'BASE',
agent_paytag: 'my-claude-agent',
display_name: 'My Claude Code Agent',
agent_type: 'coding',
daily_limit: 20,
per_tx_limit: 5,
}),
})
const { wallet } = await res.json()
console.log('Linked agent paytag:', `@${wallet.agent_paytag}`)Updatable fields:
{
"display_name": "Upgraded Agent",
"daily_limit": 50,
"per_tx_limit": 10,
"is_paused": true, // soft pause (display only)
"agent_type": "trading"
}Response (200):
{ "success": true, "synced": 5, "source": "circle" }
// source: "circle" | "onchain" (fallback)Query params: ?limit=50 (max 100)
Response (200):
{
"success": true,
"transactions": [
{
"id": "uuid",
"tx_direction": "OUTBOUND",
"amount_usdc": 2.50,
"destination_address": "0x...",
"destination_paytag": "sarah", // null if unknown
"state": "COMPLETE",
"source": "circle", // "circle" | "onchain"
"blockchain_tx_hash": "0x...",
"circle_created_at": "2026-06-01T03:00:00Z"
}
]
}{ "success": true, "message": "Agent wallet unlinked" }ERC-8004 AgentCards & Discovery
Every AI Agent handle on Payee auto-publishes a standards-compliant ERC-8004 AgentCarddocument. Discovery indexers, A2A clients, and MCP servers can fetch and verify an agent's identity, capabilities, and payment endpoint from a single URL.
Domain Discovery Manifest — /.well-known/agent-registration.json
Proves that stablepayee.xyz is the canonical host for the on-chain registry, enabling search engines and indexers to verify authority.
{
"protocol": "ERC-8004",
"domain": "stablepayee.xyz",
"registry": "0xdeDC4abF8788dc0DE36567D92b04da3Fb9d803F7",
"description": "Canonical on-chain payment identity registry for humans and AI agents."
}AgentCard JSON — /api/agent/{username}/agent-card.json
CAIP-10 wallet address (eip155:{chainId}:{address}), A2A and PaymentAPI endpoints, skills, and trust mechanisms. Returned with Cache-Control: max-age=3600 and open CORS for agent discovery clients.
{
"type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
"name": "Payment Assistant",
"description": "@olayemi is a programmable Paytag for AI agents on Payee.",
"image": "https://stablepayee.xyz/api/metadata/olayemi",
"agentWallet": "eip155:2911:0x5462D682dB237A3a992687Bc628F5b18B33eD0c1",
"endpoints": [
{
"name": "A2A",
"endpoint": "https://stablepayee.xyz/api/agent/olayemi/agent-card.json",
"version": "0.3.0",
"a2aSkills": ["payments", "agent-communication"]
},
{
"name": "PaymentAPI",
"endpoint": "https://stablepayee.xyz/api/wallet/send",
"version": "1.0",
"description": "USDC payment endpoint — POST { toAddress, amount }. Accepts paytag @handles.",
"authentication": {
"scheme": "Bearer",
"description": "Payee Agent API key: payee_agent_live_…"
}
},
{
"name": "IdentityMetadata",
"endpoint": "https://stablepayee.xyz/api/metadata/olayemi",
"version": "1.0",
"description": "ERC-721 NFT metadata for this Paytag identity token."
}
],
"capabilities": ["payments", "agent-communication"],
"supportedTrust": ["reputation", "crypto-economic"],
"owner": "0x7a63750B1B619472e38c7C74C978D7Dfe36e39A3",
"paytag": "@olayemi",
"version": "1.0.0",
"provider": {
"name": "Payee Identity Protocol",
"url": "https://stablepayee.xyz",
"registryContract": "0xdeDC4abF8788dc0DE36567D92b04da3Fb9d803F7",
"chain": "eip155:2911"
}
}0xdeDC4abF8788dc0DE36567D92b04da3Fb9d803F7) supports agentCardURI(string) queries directly, enabling decentralized indexers to resolve the AgentCard via the EVM ledger. It also implements supportsInterface() (ERC-165) and burn() to release handles.Database Schema & Security Policies
Payee uses Supabase Postgres with Row-Level Security on every user-owned table. Agent API keys are stored as SHA-256 hashes and never returned after creation. Concurrency is handled with SELECT … FOR UPDATE row locks.
agent_api_keys
CREATE TABLE IF NOT EXISTS agent_api_keys ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, key_hash TEXT UNIQUE NOT NULL, -- SHA-256 of the raw key name TEXT NOT NULL, -- user-defined label key_prefix TEXT NOT NULL, -- first 12 chars for display daily_limit NUMERIC(18, 6) NOT NULL DEFAULT 10.000000, single_tx_limit NUMERIC(18, 6) NOT NULL DEFAULT 5.000000, spent_today NUMERIC(18, 6) NOT NULL DEFAULT 0.000000, last_spent_reset TIMESTAMPTZ NOT NULL DEFAULT NOW(), is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), last_used_at TIMESTAMPTZ ); ALTER TABLE agent_api_keys ENABLE ROW LEVEL SECURITY; CREATE POLICY "own_agent_keys" ON agent_api_keys FOR ALL USING (auth.uid() = profile_id);
agent_wallets — Circle CLI linked wallets
CREATE TABLE IF NOT EXISTS agent_wallets ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, -- Circle Agent Wallet (from: circle wallet list --output json) circle_wallet_id TEXT NOT NULL, -- Circle internal UUID circle_address TEXT NOT NULL, -- 0x... on-chain address chain TEXT NOT NULL DEFAULT 'BASE', -- Identity (globally unique across profiles.username AND here) agent_paytag TEXT UNIQUE NOT NULL, -- e.g. "my-claude-agent" display_name TEXT, agent_type TEXT DEFAULT 'coding', -- coding | trading | service | custom -- Budget policy (display + alerting; enforcement is CLI-side) daily_limit NUMERIC(18, 6), per_tx_limit NUMERIC(18, 6), -- State is_active BOOLEAN NOT NULL DEFAULT TRUE, is_paused BOOLEAN NOT NULL DEFAULT FALSE, last_synced_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); ALTER TABLE agent_wallets ENABLE ROW LEVEL SECURITY; CREATE POLICY "own_agent_wallets" ON agent_wallets FOR ALL USING (auth.uid() = profile_id);
agent_wallet_transactions — cached tx log
CREATE TABLE IF NOT EXISTS agent_wallet_transactions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), agent_wallet_id UUID NOT NULL REFERENCES agent_wallets(id) ON DELETE CASCADE, profile_id UUID NOT NULL REFERENCES profiles(id) ON DELETE CASCADE, -- Idempotency key: txHash-logIndex (onchain) or Circle tx UUID circle_tx_id TEXT UNIQUE NOT NULL, source TEXT NOT NULL DEFAULT 'circle', -- 'circle' | 'onchain' tx_direction TEXT NOT NULL, -- 'INBOUND' | 'OUTBOUND' amount_usdc NUMERIC(18, 6) NOT NULL, destination_address TEXT, source_address TEXT, state TEXT NOT NULL DEFAULT 'COMPLETE', blockchain_tx_hash TEXT, -- Enrichment (resolved after sync) destination_paytag TEXT, -- resolved @paytag if destination is a Payee user service_label TEXT, -- human-readable label from Circle metadata circle_created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), synced_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_awt_agent ON agent_wallet_transactions(agent_wallet_id); CREATE INDEX idx_awt_date ON agent_wallet_transactions(circle_created_at DESC); ALTER TABLE agent_wallet_transactions ENABLE ROW LEVEL SECURITY; CREATE POLICY "own_agent_txs" ON agent_wallet_transactions FOR ALL USING (auth.uid() = profile_id);