链上 AI Agent 安全
Agent 信任它读到的链。
链会撒谎。我们守住签名。

读路径完整性 · 确定性不变量 · 决策—授权分离——说不动、零云端。

$ npm install @intentwall/gate
✓ 零依赖 · 在签名路径 drop-in · viem / GOAT / ElizaOS / AgentKit█
════════════════════════════════════════════════════════════════
# 攻击 —— 读路径

链上 Agent 读状态 → LLM 决策 → 签名。区块链只担保账本,从不担保合约返回值的语义。 `symbol()`、`decimals()`、价格、注册表返回的收款人——都是合约"想返回什么就返回什么"。投毒读取,决策即翻转。 这不是聊天框里的提示词注入:毒藏在 Agent 本就要读的链上数据里,输入过滤根本看不见。

同一条毒,8 个框架,48/48
一行毒把 GOAT、web3.py、ElizaOS、ZerePy、Rig(Rust)、Daydreams、Coinbase AgentKit、IQ ADK-TS 全翻——BUY→SELL,零攻击代码。还迁移到了一个 Solana、一个知识图谱 Agent。
D1 文本注入 · C1 现货操纵 · D4 decimals 欺骗 · B 收款人重定向 · D5 revert 当指令 · W2 端点劫持
[ 阅读完整研究 → ]
────────────────────────────────────────────────────────────────
# 防御 —— 一道带外闸门

你没法用提示词把自己从提示词注入里救出来——你要守的组件,恰恰是会被说服的那个。IntentWall 把守卫放到模型 之外:把决策与授权拆开,在签名前只查规则。

🧱 读路径完整性
pin 你交易的 token。读到的 symbol/decimals 与 pin 不符即拒,在它进入 prompt 或金额计算之前(D1/D4)。
✅ 确定性不变量
收款人 ∈ 白名单?授权 ≤ 上限?现货价在 TWAP 带内?累计亏损在预算内?只查规则、不推理,所以说不动(B / C1)。
🔗 决策 ≠ 授权
Agent 自由决策;闸门卡在决策与不可逆动作之间。三态裁决:ALLOW / BLOCK / QUARANTINE。
⚡ 运行时几乎免费
单次检查中位 ~2.7µs——约一笔交易签名预算的万分之一。零依赖。与红队判定成功用的是同一套谓词,防守与攻击永不漂移。
────────────────────────────────────────────────────────────────
# 工作原理
  ┌──────────────┐   intent   ┌──────────────────────────────┐  ALLOW  ┌──────────────┐
  │  AI agent    │──────────▶ │  I N T E N T W A L L  gate     │────────▶│  签名并广播  │
  │  (已被投毒)  │            │  只查规则,从不推理           │  BLOCK  └──────────────┘
  │  读链        │◀────────── │  白名单 · pin · TWAP · 上限    │──┐
  └──────────────┘            └──────────────────────────────┘  └─▶ QUARANTINE(挂起)
────────────────────────────────────────────────────────────────
# 快速上手
// 配置一次 —— pin 你交易的 token
const gate = createGate({ ownAddress, allowlist, tokenPins: { [USDC]:{symbol:"USDC",decimals:6} } });
// 签名前,校验动作 + agent 读到的值
const v = gate.authorize({ action:"transfer", to, amount, token, context:{ symbolRead, decimalsRead } });
if (!v.allowed) throw new Error(v.decision); // BLOCK / QUARANTINE → 不签
[ github ]    [ 研究 ]