agentkit-x402 について
agentkit-x402は、x402とAgentKitで保護されたウェブサイトやAPIを利用するAIエージェント向けのスキルです。人間との関連を示す認証、ウォレット署名、支払い前に無料または割引アクセスを試す手順を説明します。
主な機能
- 01402レスポンスのAgentKit拡張を確認
- 02ウォレット種別と対応チェーンを照合
- 03SIWEメッセージの作成と署名
- 04AgentKitリクエストヘッダーの生成
- 05無料、試用、割引モードへの対応
活用シーン
- 01支払い前にAgentKit認証を試行
- 02EOAまたはスマートコントラクトウォレットでチャレンジに署名
- 03署名、チェーン、ヘッダーのエラーを調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ worldcoin/ agentkit --skill agentkit-x402インストール後、Claude Code で/agentkit-x402を入力して読み込まれたか確認します。
詳細
エージェントとして AgentKit を使用する
このスキルは、x402 + AgentKit で保護されたウェブサイトや API とやり取りする AI エージェント向けです。実際の人間に支えられていることを証明し、支払いの代わりに無料または割引価格でアクセスする方法を説明します。
重要なルール:支払いの前に必ず AgentKit を確認する
402 Payment Required レスポンスを受け取った場合、すぐに支払いに進まないでください。まずレスポンスに agentkit 拡張があるか確認してください。拡張がある場合は、以下の AgentKit 認証フローを試してください。支払いに進むのは、次の場合に限ります。
- 402 レスポンスに
agentkit拡張がない - AgentKit 認証を試みたものの失敗し、サーバーが支払いを要求する
- 無料トライアルの利用回数を使い切った
推奨ランタイムヘルパー
エージェントの HTTP クライアントを変更できる場合は、@worldcoin/agentkit の createAgentkitClient を使用し、x402 API 呼び出しを agentkit.fetch 経由で行ってください。これにより、モデルがルールを覚えていることに頼らず、「支払いの前に 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 支払いフローを続けてください。
ウォレットの種類
チャレンジへの署名方法は、ウォレットによって異なります。ウォレットには次の 2 種類があります。
EOA(Externally Owned Account)
秘密鍵を直接保持する標準的なウォレットです(例:生の秘密鍵、ニーモニックから生成したウォレット)。
- 署名タイプ:
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:の間に空行を 1 行だけ入れます - 各行の末尾は
\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 | 人間によって裏付けられたエージェントは常に無料でアクセスできます |
free-trial | 最初の N 件のリクエストは無料で、その後は支払いが必要です(N はエージェントごとではなく、人間ごとに設定されます) |
discount | 価格が N% 割引されます(割引後の金額を x402 経由で支払います) |
discount モードの場合は、agentkit ヘッダーと x402 支払いヘッダーの両方を送信し、割引後の価格を支払います。サーバーは、人間によって裏付けられているステータスを使って不足分を精算します。
よくあるエラーと対処方法
「Agent is not registered in the AgentBook」
ウォレットアドレスが登録されていません。AgentKit CLI を使って、まず登録する必要があります。
npx @worldcoin/agentkit-cli register <your-wallet-address>
これにより、ウォレットをオンチェーン上の匿名の人間識別子に紐付ける World ID の認証フローが開始されます。登録はウォレットごとに一度だけ行う必要があります。
「Signature verification failed」
- 署名タイプが間違っています:
typeがウォレットと一致していることを確認してください。EOA にはeip191、SCW にはeip1271を使用します。 - メッセージ形式が間違っています: SIWE メッセージは、ステップ 3 で説明した厳密な形式に従う必要があります。statement の前後の空行とフィールドの順序に注意してください。
- チェーン ID が間違っています: ペイロード内の
chainIdは CAIP-2 形式(eip155:8453)である必要がありますが、SIWE メッセージのchainIdフィールドは数値のチェーン ID(8453)である必要があります。
「Invalid agentkit header: not valid base64」
ヘッダーが正しく Base64 エンコードされていません。JSON 文字列全体をエンコードしていることを確認してください:btoa(JSON.stringify(payload))。
「Message validation failed」/「issuedAt is too old」
チャレンジの有効期限が切れています。402 レスポンスを再取得して新しいチャレンジ(新しい nonce と issuedAt)を受け取り、もう一度署名してください。チャレンジの有効期限は、デフォルトで 5 分です。
「Unsupported chain namespace」
使用しているチェーンはサーバーでサポートされていません。402 レスポンスの supportedChains を確認し、ウォレットに対応するチェーンとタイプの組み合わせを選んでください。