mcpField
A
agentkit-x402

agentkit-x402

github.com/worldcoinAgent 工作流2558 次安装1 周前更新
代码仓库

关于 agentkit-x402

agentkit-x402 是指导 AI Agent 使用 AgentKit 访问受 x402 保护的网站和 API 的技能。它说明如何验证人类关联身份、选择钱包签名方式,并在符合条件时优先尝试免费或折扣访问。

主要功能

  1. 01检查 402 响应中的 AgentKit 扩展
  2. 02匹配钱包类型与支持的链
  3. 03构造并签署 SIWE 消息
  4. 04生成 AgentKit 请求头
  5. 05处理免费、试用和折扣访问模式

适用场景

  1. 01在支付前尝试 AgentKit 身份验证
  2. 02为 EOA 或智能合约钱包签署挑战
  3. 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 EOAeip155:*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,并选择与你的钱包匹配的链和类型组合。

评论

支持 Markdown