A2A tells agents what you can do. VAIP tells agents should I trust you.
MIT Bitcoin Hackathon 2026 · April 10–12 · Tracks: Dev Tools & Infrastructure, Smart Contracts
Team: Adam Lubomirski, Jennifer Ye, Vincent Hill
AI agents are increasingly delegating work to other AI agents. Google's A2A protocol standardizes how agents discover and communicate with each other via Agent Cards — structured metadata declaring capabilities, endpoints, and skills.
But Agent Cards are self-reported. Any agent can claim to be reliable, accurate, or protocol-compliant. There is no mechanism to verify those claims, and no shared reputation layer across agent ecosystems.
In a world where a client agent autonomously picks a remote agent to handle a legal document, medical record, or financial transaction, this is a serious trust gap: you have no way of knowing if the agent you're delegating to has a history of good outcomes, or is a bad actor gaming the system.
VAIP adds a decentralized trust layer on top of A2A. The core thesis:
Trust should be earned through verifiable interactions, not declared in a config file.
Each agent gets an Ethereum identity (did:ethr). After every task, the client agent writes an on-chain attestation to EAS (Ethereum Attestation Service) recording what happened: task ID, quality score (1–10), success/failure, and protocol compliance. These attestations are public, tamper-proof, and composable.
Before delegating any task, a client agent queries the trust middleware, which reads all on-chain attestations for a candidate agent and computes a trust score. Agents below 0.50 are rejected outright. The highest-scoring eligible agent wins the delegation.
This creates a reputation flywheel: good agents accumulate attestations, bad agents get rejected, and new agents start with a cold-start score until they earn history.
- Trust middleware — Express/TypeScript API that reads EAS attestations and returns live trust scores, with weighted scoring when attester credibility is known
- EAS schema — registered on Base Sepolia; schema encodes
taskId,quality,success,protocolwith the agent's Ethereum address as the EAS recipient - A2A agent system — three Python remote agents (LegalTranslate, QuickTranslate, NewBot) with different reliability profiles; a client agent that discovers them, queries trust, and delegates to the winner
- Attestation simulation —
simulation.pyruns 20–30 tasks across agents to build a realistic attestation history on-chain - React dashboard — real-time trust scores, attestation feed, trust-over-time charts, agent comparison table, and a one-click "simulate attestation" button
- DID identity layer — each agent derives a
did:ethrDID from its Ethereum wallet, embedded in its Agent Card start.sh— one-command local demo launcher spinning up middleware, dashboard, and all three remote agents
React (Vite + Tailwind + Recharts) at http://127.0.0.1:5173 (or set VITE_TRUST_API_URL if the API is not on 127.0.0.1:3001).
- Header: live clock, Base Sepolia badge, shared 30s refresh hint, and + simulate attestation. That button is context-aware: with All agents selected in the sidebar it sends one demo
POST /attestper configured agent (demo env addresses merged withGET /agents, deduped — not only the first API row). With one agent selected it sends a single demo attestation for that agent. Status text is green on success and amber on errors (e.g. middleware not running). - Left column: pick All agents or an individual agent. Cards show trust, a bar (emerald ≥ 0.50, red below, slate near zero), and YES/NO delegate eligibility vs the threshold; link to how-it-works (README).
- Tabs — overview:
- All agents: network KPIs (agents delegating, total attestations, network avg trust, network success %), a multi-series “trust scores over time” chart for every agent plus a 0.50 reference line, and an agent comparison table (trust bar, attestation count, success %, avg quality) — click a row to open that agent’s detail.
- Single agent: the existing four-tile summary plus inline AgentDetail (history, trust-over-time, quality distribution, etc.).
- Tabs — attestation feed: merged last 10 events across agents when viewing All agents; scoped to the selected agent otherwise. Rows show quality and a success column (✓ / x / -, green vs red).
- Tabs: on-chain (EAS / flow copy), protocol (VAIP loop + stack).
- Polling: agent list, per-agent data, and feeds use
DASHBOARD_POLL_MS(default 30s indashboard/src/constants.ts).
- Remote agents expose an A2A Agent Card with a VAIP-style Ethereum address for identity.
- The client calls the trust middleware
GET /trust/:address, which reads EAS attestations where that address is the recipient. - The client selects the best agent whose score is ≥ 0.50 and sends the A2A task (or skips failing agents).
- After the task, the client evaluates the outcome (including LLM quality 1–10 where configured) and calls
POST /attestto record quality, success, and protocol on-chain. OptionalattesterAddresslets the middleware sign with a registered client wallet for attester-aware weighting. - Trust scores are recomputed on each query; when attester scores are available, successful attestations are weighted by attester trust (see below).
User asks: "Translate this legal clause to Mandarin for the board."
| Agent | Trust score | Result |
|---|---|---|
| LegalTranslate | ~0.86 | Selected — strong history |
| QuickTranslate | ~0.41 | Rejected — below 0.50 |
| NewBot | ~0.58 | Eligible but outscored |
Client delegates → translation → evaluation → POST /attest → score updates for the next delegation.
agent-trust/
├── agents/ # Python A2A agents + client + simulation
├── trust-middleware/ # Express API, EAS, scoring
├── dashboard/ # React demo UI
├── contracts/ # Solidity (optional Hardhat resolver, etc.)
├── docs/ # Extra architecture / schema notes
├── start.sh # One-shot dev launcher (middleware + UI + 3 remotes)
├── reset-agents.sh # Optional: new random Legal/Quick/NewBot addresses → .env files
├── README.md
└── README_BRIEF.md # Minimal run instructions
┌─────────────────────────────────────────────────┐
│ Agent ecosystem (A2A) │
│ Client + LegalTranslate + QuickTranslate + … │
│ Agent cards + Ethereum addresses │
└────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Trust middleware (Node / TypeScript) │
│ GET /trust/:addr GET /agents │
│ GET /attestations/:addr POST /attest │
└────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ EAS on Base Sepolia (chain ID 84532) │
│ Schema: taskId, quality, success, protocol │
│ recipient = agent under attestation │
└─────────────────────────────────────────────────┘
Implemented in trust-middleware/src/scoring.ts (computeTrustScore):
- No non-revoked attestations → trust 0
- Fewer than 3 non-revoked rows → cold start 0.15
- No successful rows among those → 0
- Otherwise: among successful, non-revoked rows:
- If attester scores are present (middleware enriches from on-chain attesters):
weightedsum(quality × weight) / sum(weight × 10)with default weight 0.5 when an attester is unknown. - Else: plain average of quality / 10 over successes.
- If attester scores are present (middleware enriches from on-chain attesters):
Delegation threshold: 0.50 (middleware + client; configurable via env).
- Agents: Python 3.11+,
a2a-sdk,httpx,uvicorn - LLM: OpenAI (e.g.
gpt-4o-mini) for translations and evaluation where enabled - Trust middleware: Node.js 20+, TypeScript, Express, ethers v6,
@ethereum-attestation-service/eas-sdk - Chain: EAS on Base Sepolia (
84532) - Frontend: React 18, Vite, Tailwind CSS, Recharts
- Node.js 20+
- Python 3.11+
- A funded wallet on Base Sepolia (gas for
POST /attest) - OpenAI API key (for real agent + evaluation flows in
agents/)
From the repo root, install dependencies once:
(cd trust-middleware && npm install)
(cd dashboard && npm install)
pip3 install -r agents/requirements.txtCopy and edit env files:
cp trust-middleware/.env.example trust-middleware/.env
cp agents/.env.example agents/.env
# trust-middleware/.env → PRIVATE_KEY, SCHEMA_UID (after register-schema)
# agents/.env → OPENAI_API_KEY, agent addresses, etc.Register the EAS schema once (prints SCHEMA_UID):
cd trust-middleware && npm run register-schemaStart everything for local demo:
chmod +x start.sh # first time only
./start.shThis runs trust middleware (3001), dashboard (5173), and three remote agents (8001–8003) using python3 for each remote process. Ctrl+C stops all child processes.
Then, in a separate terminal, optional live client:
cd agents && python3 client_agent.pySeed attestations for the dashboard narrative:
python3 agents/simulation.pyOptional demo agent address reset:
chmod +x reset-agents.sh # first time only
./reset-agents.shRestart ./start.sh after changing env files; run simulation.py again if you want attestations for the new addresses.
# Terminal 1
cd trust-middleware && npm run dev
# Terminal 2
cd dashboard && npm run dev
# Terminals 3–5 — agents/
python3 remote_legal.py
python3 remote_quick.py
python3 remote_newbot.py
# Terminal 6 — optional
python3 client_agent.py| Variable | Required | Description |
|---|---|---|
PRIVATE_KEY |
Yes | Wallet that pays gas for attestations |
SCHEMA_UID |
Yes | From npm run register-schema |
BASE_SEPOLIA_RPC |
No | Default public Base Sepolia RPC |
TRUST_API_PORT |
No | Default 3001 |
MIN_TRUST_THRESHOLD |
No | Default 0.50 |
AGENT_LEGAL_ADDRESS |
No | Known demo agents for GET /agents |
AGENT_QUICK_ADDRESS |
No | |
AGENT_NEW_ADDRESS |
No | |
CLIENT_AGENT_ADDRESS |
No | Client wallet for signed attestations |
CLIENT_AGENT_PRIVATE_KEY |
No | Used when attesterAddress matches client |
| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
Yes* | *Required for LLM-backed agents / evaluation |
TRUST_MIDDLEWARE_URL |
No | Default http://127.0.0.1:3001 |
REMOTE_AGENT_URLS |
No | Default ports 8001,8002,8003 |
CLIENT_AGENT_ADDRESS |
No | Sent as attesterAddress when attesting |
OPENAI_TRANSLATE_MODEL |
No | Default gpt-4o-mini |
OPENAI_EVAL_MODEL |
No | Default gpt-4o-mini |
MIN_TRUST_THRESHOLD |
No | Default 0.50 |
VAIP_FALLBACK_BEST_EFFORT |
No | true to soften threshold behavior |
| Variable | Description |
|---|---|
VITE_TRUST_API_URL |
Trust API base URL (no trailing slash); default http://127.0.0.1:3001 |
VITE_AGENT_LEGAL / QUICK / NEW |
Fallback addresses if GET /agents is empty |
{
"agentAddress": "0xa6302ad60ca55167aaa94903c1b378e84e3d7a0e",
"did": "did:ethr:0x84532:0xA6302aD60Ca55167AaA94903C1B378e84E3d7a0e",
"trustScore": 0.86,
"attestationCount": 18,
"successRate": 0.94,
"avgQuality": 8.6,
"revokedCount": 0,
"lastAttestedAt": "2026-04-11T14:30:00Z"
}{
"taskId": "c4655de3-132a-415f-af0e-e7bd67f5f6a0",
"agentAddress": "0xa6302ad60ca55167aaa94903c1b378e84e3d7a0e",
"attesterAddress": "0xBbc37A9CC124F765977dB11F5b4cE7F35168244d",
"quality": 9,
"success": true,
"protocol": "compliant"
}Response: { "attestationUid": "0x...", "txHash": "0x...", "blockNumber": 123 }
attesterAddress is optional; when set and a matching key is configured, that wallet signs the attestation.
Known agents with live scores and counts.
Decoded attestation history for the dashboard and charts.
- Chain ID:
84532 - RPC: https://sepolia.base.org
- EAS:
0x4200000000000000000000000000000000000021 - Schema registry:
0x4200000000000000000000000000000000000020 - Explorer: https://sepolia.basescan.org · https://base-sepolia.easscan.org
On-chain attestations give properties that no off-chain trust system can match:
- Tamper-proof — attestations are immutable once on-chain; no one can retroactively edit a bad agent's history
- Permissionless — any agent, from any ecosystem, can read and write attestations without going through a central authority
- Composable — other agents, contracts, or protocols can read trust scores directly from EAS without depending on VAIP infrastructure
- Transparent — every attestation is publicly auditable via EAS explorer; judges can verify our demo attestations directly on-chain
EAS is ideal here because attestations have a structured schema, support revocation (for disputing fraudulent history), and use the EAS recipient field to tie attestations to a specific agent address — no extra mapping needed.
- Bitcoin anchoring — periodically commit Merkle roots of attestation batches via
OP_RETURNfor Bitcoin-level finality - Off-chain EAS — privacy-preserving attestations with on-chain Merkle timestamps for sensitive interactions
- Resolver contract — on-chain enforcement so only agents above a trust threshold can create new attestations (prevents reputation spam)
- Multi-skill reputation — separate trust scores per capability using distinct EAS schemas
- Trust graph visualization — D3 force-directed graph of attester/attestee relationships
See LICENSE.