Security for On-Chain AI Agents
Agents trust the chain they read.
The chain can lie. We gate the signature.
Read-path integrity · deterministic invariants · decision–authorization split — unpersuadable, zero cloud.
$ npm install @intentwall/gate
✓ zero-dep · drop-in at your sign path · viem / GOAT / ElizaOS / AgentKit█
════════════════════════════════════════════════════════════════
# THE ATTACK — the read path
An on-chain agent reads state → an LLM decides → it signs. A blockchain guarantees the ledger,
never the semantics of what a contract returns. `symbol()`, `decimals()`, a price, the recipient a
registry hands back — are all whatever the contract decides. Poison the read, and the decision flips.
This is not chat prompt injection: the payload lives in the chain data the agent was always going to read,
so input filters never see it.
Same poison, 8 frameworks, 48/48
One line of poison flipped GOAT, web3.py, ElizaOS, ZerePy, Rig (Rust), Daydreams, Coinbase AgentKit, and IQ ADK-TS — BUY→SELL, with zero attack code. It carried to a Solana agent and a knowledge-graph agent too.
D1 symbol injection · C1 spot manipulation · D4 decimals spoof · B recipient redirect · D5 revert-as-instruction · W2 endpoint capture
────────────────────────────────────────────────────────────────
# THE DEFENSE — an out-of-band gate
You can't prompt your way out of prompt injection — the component you'd defend is the one that gets
persuaded. IntentWall puts the guard outside the model: split the decision from the authorization,
and check rules before the signature.
🧱 Read-path integrity
Pin the tokens you trade. A read whose symbol/decimals doesn't match the pinned truth is rejected before it reaches the prompt or amount math (D1/D4).
✅ Deterministic invariants
Recipient ∈ allowlist? approval ≤ cap? spot within TWAP band? cumulative loss under budget? Rules — not reasoning — so the gate can't be talked around (B / C1).
🔗 Decision ≠ authorization
The agent decides freely; the gate stands between the decision and the irreversible action. Three-state verdict: ALLOW / BLOCK / QUARANTINE.
⚡ Free at runtime
~2.7µs median per check — about 1/10,000 of a transaction's signing budget. Zero dependencies. Same predicates the red team uses to judge success, so defense and attack never drift.
────────────────────────────────────────────────────────────────
# HOW IT WORKS
┌──────────────┐ intent ┌──────────────────────────────┐ ALLOW ┌──────────────┐
│ AI agent │──────────▶ │ I N T E N T W A L L gate │────────▶│ sign & send │
│ (poisoned) │ │ rules, never reasoning │ BLOCK └──────────────┘
│ reads chain │◀────────── │ allowlist · pins · TWAP · cap │──┐
└──────────────┘ └──────────────────────────────┘ └─▶ QUARANTINE (hold)
────────────────────────────────────────────────────────────────
# GET STARTED
// configure once — pin the tokens you trade
const gate = createGate({ ownAddress, allowlist, tokenPins: { [USDC]:{symbol:"USDC",decimals:6} } });
// before you sign, authorize the action + what the agent read
const v = gate.authorize({ action:"transfer", to, amount, token, context:{ symbolRead, decimalsRead } });
if (!v.allowed) throw new Error(v.decision); // BLOCK / QUARANTINE → don't sign