OpenSea Tool SDK 是做什麼的?
使用 Base 鏈上的 OpenSea 工具註冊表 (ERC-8257) 來建構、註冊並管理可由 AI 呼叫的工具端點。
何時使用此技能 (scope_in)
當您需要以下功能時,請使用 opensea-tool-sdk:
- 搭建一個可由 AI 呼叫的工具端點 (HTTPS, JSON Schema,
.well-known清單),適用於 Vercel、Cloudflare 或 Express - 在 Base 鏈上的 ToolRegistry 合約註冊工具,以便其他代理程式可以發現它
- 透過 x402 每次呼叫付費 (USDC) 或謂詞 (ERC-721/ERC-1155 所有權、訂閱、特質門控、ERC-20 餘額、複合條件) 來管理存取
- 呼叫受門控或付費工具:402 付款 (
paidFetch)、謂詞門控驗證 (eip3009AuthenticatedFetch),或兩者並用 (paidAuthenticatedFetch) - 透過 OpenSea REST API 搜尋和發現已註冊的工具
何時不應使用此技能 (scope_out, 交接)
| 需求 | 請改用 |
|---|---|
| 查詢 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 發現。每個工具應執行一個集中的操作。 |
| 清單 | 經 JCS 標準化處理的 JSON,描述工具的名稱、端點、輸入、輸出、定價和存取政策 |
| ToolRegistry | 上鏈合約 (Base),工具在此註冊,包含清單哈希和可選的存取謂詞 |
| 存取謂詞 | 一個 IAccessPredicate 合約,用於決定誰可以呼叫工具 (NFT 所有權、訂閱、特質門控、ERC-20 餘額、複合條件) |
| x402 | 基於 HTTP 402 的每次呼叫付費協議(呼叫者簽署 USDC TransferWithAuthorization;伺服器在執行後結算) |
| EIP-3009 驗證 | 使用零值 USDC TransferWithAuthorization 簽名來驗證謂詞門控工具的呼叫者 |
| 協調者 | 驗證和結算 x402 付款的第三方服務 (PayAI 或 Coinbase CDP) |
重要限制
一個工具 = 一個端點。 每個工具註冊代表一個具有單一焦點和意圖的 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 上)。
已部署合約 (以太坊主網, 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 |
工具探索 [Beta]
透過 OpenSea REST API 搜尋或查詢已註冊的工具。需要 OPENSEA_API_KEY。
# 如果已設定,則重用 OPENSEA_API_KEY;否則獲取即時免費層級金鑰
# (無需註冊 — 每小時 600 次讀取,30 次寫入,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 輔助腳本來執行此操作 (環境變數 → 快取檔案 → 獲取並儲存);請參閱其「API 金鑰解析」章節。如需更高的速率限制,請在 設定 → 開發者 建立完整金鑰。
列出工具: GET /api/v2/tools (文件)
| 參數 | 必要 | 說明 |
|---|---|---|
sort_by | 否 | 排序方式:newest (預設),oldest |
type | 否 | 依存取類型篩選:open, nft_gated, token_gated, subscription, gated |
limit | 否 | 每頁結果數 (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–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: "我的工具",
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(`已在交易 ${txHash} 中註冊工具 ${toolId}`)
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 > PrivateKey
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. 回應
…
[為翻譯而截斷]