OpenSea Tool SDK
Base上で、OpenSea Tool Registry(ERC-8257)を使用して、AIエージェントが呼び出し可能なツールエンドポイントを構築、登録、およびアクセス制御します。
このスキルを使用するタイミング(scope_in)
以下の場合に opensea-tool-sdk を使用します。
- Vercel、Cloudflare、またはExpress用のAI呼び出し可能なツールエンドポイント(HTTPS、JSON Schema、
.well-knownマニフェスト)をスキャフォールディングする場合 - 他のエージェントが発見できるように、BaseのToolRegistryにツールをオンチェーン登録する場合
- x402従量課金(USDC)または述語(ERC-721/ERC-1155所有権、サブスクリプション、特性ゲート、ERC-20残高、複合条件)によるアクセスを制御する場合
- ゲートまたは有料のツールを呼び出す場合:402支払い(
paidFetch)、述語ゲート認証(eip3009AuthenticatedFetch)、またはその両方(paidAuthenticatedFetch) - OpenSea REST APIを介して登録済みツールを検索および発見する場合
このスキルを使用しないタイミング(scope_out、handoff)
| 必要な機能 | 代わりに使用するスキル |
|---|---|
| NFT/トークンデータのクエリ、検索、コレクション統計 | opensea-api |
| NFTの売買 | opensea-marketplace |
| ERC20トークンのスワップ | opensea-swaps |
| ウォレット署名プロバイダーの設定 | opensea-wallet |
このSDKはツールのプロバイダーとコンシューマー向けです。OpenSeaのマーケットプレイスデータ(フロアプライス、リスト、トレード)をクエリするには、代わりにopensea-apiスキルを使用してください。
概念
| 用語 | 意味 |
|---|---|
| ツール | JSON Schemaインターフェースを持つ単一のREST APIエンドポイント。/.well-known/ai-tool/<slug>.json で発見可能。各ツールは1つの焦点を絞った操作を実行する必要があります。 |
| マニフェスト | ツールの名前、エンドポイント、入力、出力、価格設定、アクセスポリシーを記述したJCS正規化JSON |
| ToolRegistry | Base上のオンチェーンコントラクト。ツールはマニフェストハッシュとオプションのアクセス述語とともに登録されます。 |
| アクセス述語 | 誰がツールを呼び出せるかを制御する IAccessPredicate コントラクト(NFT所有権、サブスクリプション、特性ゲート、ERC-20残高、複合条件) |
| x402 | HTTP 402ベースの従量課金プロトコル(呼び出し元がUSDCの TransferWithAuthorization に署名。サーバーは実行後に決済) |
| EIP-3009認証 | 述語ゲートツールの呼び出し元を認証するために使用される、ゼロ値のUSDC TransferWithAuthorization 署名 |
| ファシリテーター | x402支払いを検証および決済するサードパーティサービス(PayAIまたはCoinbase CDP) |
重要な制約
1ツール=1エンドポイント。 各ツール登録は、単一の焦点と意図を持つ単一のREST APIエンドポイントを表します。マニフェスト内のエンドポイントURLは、特定のAPIルート(例:POST /api/price-check や POST /api/translate)を指す必要があり、一般的なHTMLページ、ドキュメントサイト、または多目的URLを指してはいけません。登録された各ツールは、個別のREST APIエンドポイントと同じように考えてください。特定の入力を受け入れ、特定のアクションを実行し、特定の出力を返す必要があります。
オリジンバインディング:マニフェストとエンドポイントは完全に同一のオリジンである必要があります。 .well-known/ai-tool/<slug>.json マニフェストとツールの呼び出しエンドポイントは、完全に同一のオリジン(RFC 6454 に従い、スキーム、ホスト、ポートが同一)から提供される必要があります。サブドメインは同一オリジンと見なされません。 example.com と api.example.com は異なるオリジンです。これは登録時に強制されます。マニフェストのオリジンとエンドポイントのオリジンが完全に一致しない場合、ツールは拒否され、登録解除済みとしてマークされます。
- 有効:マニフェストが
https://my-tool.example.com/.well-known/ai-tool/my-tool.json、エンドポイントがhttps://my-tool.example.com/api/my-tool - 無効:マニフェストが
https://example.com/.well-known/ai-tool/my-tool.json、エンドポイントがhttps://api.example.com/api/my-tool
APIをサブドメインで提供する必要がある場合は、その同じサブドメインからマニフェストを提供してください(例:両方とも api.example.com 上)。
デプロイ済みコントラクト(Ethereumメインネット、Base、Shape、Abstract、Monad、Robinhood Chain)
正規のv0.2デプロイ — サポートされているすべてのチェーンで同一のCREATE2アドレス。
| コントラクト | アドレス |
|---|---|
| ToolRegistry(v0.2) | 0x265BB2DBFC0A8165C9A1941Eb1372F349baD2cf1 |
| ERC721OwnerPredicate(v0.2) | 0xc8721c9A776958FfFfEb602DA1b708bf1D318379 |
| ERC1155OwnerPredicate(v0.2) | 0x77373Dc3c1AE9A1e937eF3e5E08F4807D47c7c11 |
| SubscriptionPredicate(v0.2) | 0xCBe0cd9B1d99d95Baa9c58f2767246C52e461f25 |
| TraitGatedPredicate(v0.2) | 0x10abF07CfA34Bf22372C57f27e8bd9C2DCF93fA1 |
| ERC20BalancePredicate(v0.2) | 0x1a834FC48B5f6e119c62C12a98b32137bCFA77cD |
ツール発見 [ベータ]
OpenSea REST APIを介して登録済みツールを検索または参照します。OPENSEA_API_KEY が必要です。
# OPENSEA_API_KEYが既に設定されている場合は再利用。そうでなければインスタント無料キーを取得
# (サインアップ不要 — 読み取り600/h、書き込み30/h、7日間有効)し、再利用のために保存します。
if [ -z "${OPENSEA_API_KEY:-}" ]; then
KEY_FILE="${OPENSEA_CONFIG_DIR:-$HOME/.opensea}/api_key"
if [ -s "$KEY_FILE" ]; then
export OPENSEA_API_KEY=$(cat "$KEY_FILE") # キャッシュされたキーを再利用
else
api_key=$(curl -s -X POST https://api.opensea.io/api/v2/auth/keys | jq -r '.api_key')
mkdir -p "$(dirname "$KEY_FILE")"
(umask 077; printf '%s\n' "$api_key" > "$KEY_FILE") # 使用前に保存
export OPENSEA_API_KEY="${api_key}"
fi
fi
取得したインスタントキーは常に保存し、再取得せずに再利用してください。opensea-api スキルにはこれを実行する auth/opensea-resolve-key.sh ヘルパーが含まれています(env → キャッシュファイル → 取得+保存)。その「APIキー解決」セクションを参照してください。より高いレート制限が必要な場合は、Settings → Developer で完全なキーを作成してください。
ツール一覧: GET /api/v2/tools(ドキュメント)
| パラメーター | 必須 | 説明 |
|---|---|---|
sort_by | いいえ | 並び替え:newest(デフォルト)、oldest |
type | いいえ | アクセスタイプでフィルタリング:open、nft_gated、token_gated、subscription、gated |
limit | いいえ | 1ページあたりの結果数(1–100) |
cursor | いいえ | ページネーションカーソル |
ツール検索: GET /api/v2/tools/search(ドキュメント)
| パラメーター | 必須 | 説明 |
|---|---|---|
query | いいえ | 検索クエリテキスト |
registry_chain | いいえ | レジストリチェーンIDでフィルタリング |
tags | いいえ | タグでフィルタリング |
access_type | いいえ | アクセスタイプでフィルタリング:open、nft_gated、subscription |
creator | いいえ | 作成者アドレスでフィルタリング |
sort_by | いいえ | 並び替え:relevance(デフォルト)、newest、most_used |
limit | いいえ | 1ページあたりの結果数(1–200) |
cursor.value | いいえ | ページネーションカーソル |
ツール取得: GET /api/v2/tools/{registry_chain}/{registry_addr}/{tool_id}(ドキュメント)
| パラメーター | 必須 | 説明 |
|---|---|---|
registry_chain | はい | レジストリチェーンID(例:1、8453) |
registry_addr | はい | レジストリコントラクトアドレス |
tool_id | はい | 数値ツールID |
# 最新順にツールを一覧表示
curl -s "https://api.opensea.io/api/v2/tools?sort_by=newest&limit=10" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# タイプでフィルタリングしてツールを一覧表示
curl -s "https://api.opensea.io/api/v2/tools?type=open&sort_by=oldest" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# キーワードでツールを検索
curl -s "https://api.opensea.io/api/v2/tools/search?query=nft" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Base上の特定のツールを取得
curl -s "https://api.opensea.io/api/v2/tools/8453/0x265BB2DBFC0A8165C9A1941Eb1372F349baD2cf1/1" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# アクセスタイプでフィルタリング
curl -s "https://api.opensea.io/api/v2/tools/search?access_type=open&limit=10" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
1. ツールを作成する
1a. プロジェクトをスキャフォールディングする
npx @opensea/tool-sdk init --runtime vercel # または:cloudflare、express
これにより以下が生成されます。
src/manifest.ts— ツールマニフェスト定義src/handler.ts— 入出力スキーマを使用したリクエストハンドラーapi/index.ts— フレームワークアダプターエントリーポイントpublic/llms.txt— エージェントが読み取り可能な発見ページapi/well-known/[slug].ts—/.well-known/ai-tool/<slug>.jsonでマニフェストを提供
1b. マニフェストを定義する
import { defineManifest } from "@opensea/tool-sdk"
export const manifest = defineManifest({
name: "My Tool",
description: "このツールの機能",
endpoint: "https://my-tool.example.com/api",
creatorAddress: "0xYOUR_WALLET_ADDRESS",
inputs: {
type: "object",
properties: {
query: { type: "string", description: "検索クエリ" },
},
required: ["query"],
},
outputs: {
type: "object",
properties: {
result: { type: "string" },
},
},
// オプション:x402ペイウォールの価格設定を追加(references/x402.md を参照)
// pricing: paywall.pricing,
// オプション:アクセス要件を追加(references/predicate-gating.md を参照)
// access: { logic: "OR", requirements: [...] },
})
1c. ハンドラーを記述する
import { createToolHandler } from "@opensea/tool-sdk"
import { z } from "zod/v4"
import { manifest } from "./manifest.js"
const InputSchema = z.object({ query: z.string() })
const OutputSchema = z.object({ result: z.string() })
export const toolHandler = createToolHandler({
manifest,
inputSchema: InputSchema,
outputSchema: OutputSchema,
// gates: [], // ここにゲートを追加(references/x402.md および references/predicate-gating.md を参照)
handler: async (input) => {
return { result: `処理済み: ${input.query}` }
},
})
1d. アダプターを接続する
Vercel:
import { toVercelHandler } from "@opensea/tool-sdk"
import { toolHandler } from "../src/handler.js"
export default toVercelHandler(toolHandler)
Express:
import { toExpressHandler } from "@opensea/tool-sdk"
import { toolHandler } from "./handler.js"
app.post("/api", toExpressHandler(toolHandler))
Cloudflare Workers:
import { toolHandler } from "./handler.js"
export default { fetch: toolHandler }
2. ツールをオンチェーンに登録する
2a. CLI経由
# ウォレットの設定
export PRIVATE_KEY=0x...
export RPC_URL=https://mainnet.base.org
# 登録(オープンアクセス — 述語なし)
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base
# アクセス述語を指定して登録
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base \
--access-predicate 0xPREDICATE_ADDRESS
# ドライラン(トランザクションなし)
npx @opensea/tool-sdk register --metadata ... --network base --dry-run
CLIは以下を実行します。
--metadataURLからマニフェストを取得- マニフェストスキーマを検証
manifest.creatorAddressがあなたのウォレットと一致することを確認- JCS keccak256マニフェストハッシュを計算
ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate)を呼び出しToolRegisteredイベントからtoolIdを返す
2b. SDK経由(プログラム的)
import { ToolRegistryClient, computeManifestHash } from "@opensea/tool-sdk"
import { createWalletFromEnv, walletAdapterToClient } from "@opensea/tool-sdk"
import { base } from "viem/chains"
const adapter = createWalletFromEnv()
const walletClient = await walletAdapterToClient(adapter, base)
const registry = new ToolRegistryClient({
chain: base,
rpcUrl: "https://mainnet.base.org",
walletClient,
})
const { toolId, txHash } = await registry.registerTool({
metadataURI: "https://my-tool.example.com/.well-known/ai-tool/my-tool.json",
manifest, // あなたの ToolManifest オブジェクト
accessPredicate: "0x0000...0000", // address(0) = オープンアクセス
})
console.log(`ツール ${toolId} がトランザクション ${txHash} で登録されました`)
3. ツールアクセスのゲーティング
ツールは3つの方法でゲートできます。
| ゲート | メカニズム | リファレンス |
|---|---|---|
| x402ペイウォール | 従量課金(USDC、EIP-3009) | references/x402.md |
| 述語ゲート | オンチェーンチェック(NFT、サブスクリプション、特性ゲート、ERC-20残高、複合条件) | references/predicate-gating.md |
| 組み合わせ | EIP-3009認証と支払い(最初に述語、次にx402) | references/predicate-gating.md |
デプロイ済みの述語アドレス、要件エンコーディング、および describeToolAccess / decodeRequirement などのSDKヘルパーについては、references/known-predicates.md を参照してください。
4. ウォレット設定
SDKは @opensea/wallet-adapters を介して複数のウォレットプロバイダーをサポートしています。環境変数を設定すると、SDKは自動的にプロバイダーを検出します。完全なプロバイダーテーブル、環境変数、設定手順、署名ポリシーの設定については、opensea-wallet スキルを参照してください。
| プロバイダー | 環境変数 | 最適な用途 |
|---|---|---|
| 秘密鍵 | PRIVATE_KEY | ローカル開発、スクリプト |
| Privy | PRIVY_APP_ID、PRIVY_APP_SECRET、PRIVY_WALLET_ID | サーバーウォレット |
| Turnkey | TURNKEY_API_PUBLIC_KEY、TURNKEY_API_PRIVATE_KEY、TURNKEY_ORGANIZATION_ID | エンタープライズ署名 |
| Fireblocks | FIREBLOCKS_API_KEY、FIREBLOCKS_API_SECRET、FIREBLOCKS_VAULT_ACCOUNT_ID | 機関レベルのカストディ |
| Bankr | BANKR_API_KEY | エージェントウォレット(HTTP API経由) |
どのプロバイダーの場合も、RPC_URL(または --rpc-url フラグ)がオンチェーンの読み取りと書き込みのRPCエンドポイントを設定します。どちらも設定されていない場合、CLIコマンドはネットワークのデフォルトのパブリックRPCにフォールバックしますが、これは遅いかレート制限される可能性があります。
import { createWalletFromEnv } from "@opensea/tool-sdk"
// 自動検出:Privy > Fireblocks > Turnkey > Bankr > 秘密鍵
const adapter = createWalletFromEnv()
const address = await adapter.getAddress()
Bankr(外部サイナー)の場合:
import { createBankrAccount } from "@opensea/tool-sdk"
const account = await createBankrAccount("your-bankr-api-key")
// eip3009AuthenticatedFetch または paidAuthenticatedFetch で使用
5. 応答
…
[翻訳のため省略]