关于 agentkit-x402
agentkit-x402 是指导 AI Agent 使用 AgentKit 访问受 x402 保护的网站和 API 的技能。它说明如何验证人类关联身份、选择钱包签名方式,并在符合条件时优先尝试免费或折扣访问。
主要功能
- 01检查 402 响应中的 AgentKit 扩展
- 02匹配钱包类型与支持的链
- 03构造并签署 SIWE 消息
- 04生成 AgentKit 请求头
- 05处理免费、试用和折扣访问模式
适用场景
- 01在支付前尝试 AgentKit 身份验证
- 02为 EOA 或智能合约钱包签署挑战
- 03排查签名、链或请求头错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ worldcoin/ agentkit --skill agentkit-x402安装后在 Claude Code 中输入/agentkit-x402确认已加载。
详细介绍
将 AgentKit 用作 Agent
此技能适用于与受 x402 + AgentKit 保护的网站和 API 交互的 AI Agent。它会告诉你如何证明自己由真人支持,从而免费或以折扣价访问,而不是付费。
关键规则:付费前务必检查 AgentKit
收到 402 Payment Required 响应时,不要立即继续付款。首先检查响应中是否包含 agentkit 扩展。如果包含,请尝试以下 AgentKit 身份验证流程。仅在以下情况下才改为付款:
- 402 响应中没有
agentkit扩展 - AgentKit 身份验证尝试失败,且服务要求付款
- 你已用完免费试用次数
首选运行时助手
如果你可以更改 Agent 的 HTTP 客户端,请使用 @worldcoin/agentkit 中的 createAgentkitClient,并通过 agentkit.fetch 路由 x402 API 调用。这样一来,“先尝试 AgentKit,再付款”的规则就能确定地执行,而不必依赖模型记住这条规则。
import { createAgentkitClient } from '@worldcoin/agentkit'
const agentkit = createAgentkitClient({
signer: {
address: wallet.address,
chainId: 'eip155:8453',
type: 'eip191',
signMessage: message => wallet.signMessage(message),
},
})
const response = await agentkit.fetch('https://api.example.com/data')
如果 agentkit.fetch 返回另一个 402,请继续使用常规 x402 付款流程。
钱包类型
你的钱包决定了你如何对挑战进行签名。钱包有两种类型:
EOA(外部拥有账户)
一种标准钱包,你直接持有私钥(例如,原始私钥或通过助记词派生的钱包)。
- 签名类型:
eip191 - 签名方式: 使用
personal_sign(EIP-191)对 SIWE 消息进行签名 - 示例:
wallet.signMessage(siweMessage)
智能合约钱包(SCW)
一种“账户”为智能合约的钱包,签名由底层所有者密钥完成。服务会通过合约的 isValidSignature 方法(ERC-1271)在链上验证你的签名。
示例:Coinbase Smart Wallet、Safe、任何 ERC-4337 账户。
- 签名类型:
eip1271 - 签名方式: 使用钱包的 SDK 或内部签名器对 SIWE 消息进行签名。签名格式取决于钱包实现方式,使用钱包 SDK 提供的签名方式即可。
- 示例(Coinbase CDP):
account.signMessage({ message: siweMessage })
如果不确定钱包属于哪种类型:如果钱包是通过私钥或助记词创建的,它就是 EOA。如果钱包是通过钱包 SDK(Coinbase CDP、Safe SDK 等)创建的,它很可能是 SCW。
AgentKit 流程
步骤 1:解析 402 响应
收到 402 Payment Required 时,请在响应正文中查找 agentkit 扩展。402 响应包含带扩展的 x402 数据。agentkit 扩展如下所示:
{
"agentkit": {
"info": {
"domain": "api.example.com",
"uri": "https://api.example.com/data",
"version": "1",
"nonce": "abc123",
"issuedAt": "2025-01-01T00:00:00.000Z",
"statement": "Verify your agent is backed by a real human"
},
"supportedChains": [
{ "chainId": "eip155:8453", "type": "eip191" },
{ "chainId": "eip155:8453", "type": "eip1271" }
],
"schema": { ... }
}
}
需要提取的关键字段:
info— 你必须签名的挑战数据supportedChains— 服务接受的链和签名类型mode(如果存在)— 告知访问策略:free、free-trial或discount
步骤 2:选择链和签名类型
将你的钱包与 supportedChains 条目之一匹配:
| 你的钱包 | 匹配 chainId | 使用 type |
|---|---|---|
| EVM EOA | eip155:* | eip191 |
| EVM 智能合约钱包 | eip155:* | eip1271 |
选择同时匹配你的链和钱包类型的条目。
第 3 步:构造并签署 SIWE 消息
根据挑战中的 info 字段构造 SIWE(EIP-4361)消息字符串。格式为纯文本字符串,且必须严格遵循以下结构:
{domain} wants you to sign in with your Ethereum account:
{address}
{statement}
URI: {uri}
Version: {version}
Chain ID: {numericChainId}
Nonce: {nonce}
Issued At: {issuedAt}
其中,{numericChainId} 从 CAIP-2 链 ID 中提取(例如,eip155:8453 转换为 8453),{address} 必须采用 EIP-55 校验和格式。
如果挑战包含可选字段,请按以下顺序追加(仅包含存在的字段对应的行):
Expiration Time: {expirationTime}
Not Before: {notBefore}
Request ID: {requestId}
Resources:
- {resources[0]}
- {resources[1]}
完整示例:
api.example.com wants you to sign in with your Ethereum account:
0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Verify your agent is backed by a real human
URI: https://api.example.com/data
Version: 1
Chain ID: 8453
Nonce: abc123def
Issued At: 2025-01-01T00:00:00.000Z
Expiration Time: 2025-01-01T00:05:00.000Z
Request ID: req-456
Resources:
- https://api.example.com/tos
重要格式规则:
{statement}行前后都必须有一个空行- 如果没有 statement,地址与
URI:之间必须有一个空行 - 每行以
\n结尾(LF,而非 CRLF) - 最后一行后不能有换行符
然后对消息字符串签名:
// EOA — use personal_sign (EIP-191)
const signature = await wallet.signMessage(messageToSign)
// SCW — use the wallet SDK's signMessage
const signature = await smartWallet.signMessage({ message: messageToSign })
第 4 步:发送请求
将包含挑战 info 字段以及 address、type 和 signature 的 JSON 对象进行 Base64 编码,并将其作为 agentkit HTTP 标头发送:
const header = btoa(JSON.stringify({
...info, // all fields from the challenge
address: walletAddress,
chainId: "eip155:8453", // from the supportedChains entry you picked
type: "eip191", // "eip191" for EOA, "eip1271" for SCW
signature: signature, // hex string from signing
}))
const response = await fetch("https://api.example.com/data", {
headers: {
"agentkit": header,
},
})
如果服务器授予访问权限(取决于模式),你将直接收到资源,无需付款。
如果服务器返回另一个 402 响应或错误,请回退到常规 x402 付款流程。
访问模式
AgentKit 扩展中的 mode 字段会告知你预期的访问方式:
| 模式 | 含义 |
|---|---|
free | 由真人背书的 Agent 始终可免费访问 |
free-trial | 前 N 次请求免费,之后必须付款(N 按真人计算,而非按 Agent 计算) |
discount | 价格可享受 N% 折扣(通过 x402 支付折后金额) |
对于 discount 模式:同时发送 agentkit 标头和 x402 付款标头,但支付折后价格。服务器会根据你的真人背书状态结算未付足的金额。
常见错误及处理方法
“Agent 未在 AgentBook 中注册”
你的钱包地址尚未注册。你需要先使用 AgentKit CLI 注册:
npx @worldcoin/agentkit-cli register <your-wallet-address>
这会打开 World ID 验证流程,将你的钱包与链上的匿名真人标识符关联起来。每个钱包只需注册一次。
“签名验证失败”
- 签名类型错误: 确保
type与你的钱包匹配。EOA 使用eip191,SCW 使用eip1271。 - 消息格式错误: SIWE 消息必须严格遵循第 3 步所述的格式。请特别注意 statement 前后的空行以及字段顺序。
- 链 ID 错误: 载荷中的
chainId必须采用 CAIP-2 格式(eip155:8453),但 SIWE 消息中的chainId字段必须使用数字链 ID(8453)。
“AgentKit 标头无效:不是有效的 Base64”
你的标头未正确进行 Base64 编码。请确保对完整的 JSON 字符串进行编码:btoa(JSON.stringify(payload))。
“消息验证失败”/“issuedAt 已过期”
挑战已过期。重新获取 402 响应,以获取新的挑战(新的 nonce 和 issuedAt),然后再次签名。挑战默认在 5 分钟后过期。
“不支持的链命名空间”
你使用的链不受服务器支持。请检查 402 响应中的 supportedChains,并选择与你的钱包匹配的链和类型组合。