Communitygithub.com

OpenSea 工具 SDK

使用 OpenSea 工具注册表 (ERC-8257) 在 Base 网络上构建、注册和门控 AI 可调用的工具端点。

OpenSea 工具 SDK 是什么?

OpenSea 工具 SDK 是一个用于构建、注册和管理 AI 可调用工具端点的开发套件。它允许开发者快速搭建基于 HTTPS 的 REST API 工具端点(支持 Vercel、Cloudflare 或 Express),这些端点符合 JSON Schema 接口标准,并可通过 `/.well-known/ai-tool/<slug>.json` 清单文件进行发现。该 SDK 的核心是与支持 ERC-8257 标准的智能合约 `ToolRegistry` 进行交互,该合约部署在 Base、以太坊主网、Shape、Abstract、Monad 和 Robinhood Chain 等链上。注册工具后,开发者可以实施多种访问控制机制,包括基于 NFT 所有权、ERC-1155 代币、订阅、特质(trait)门控、ERC-20 余额的门控访问(统称为基于 EIP-3009 签名的谓词门控),以及通过 x402 协议(HTTP 402 付费调用)实现的按次付费(USDC)模式。工具发现功能通过 OpenSea REST API 实现,支持按关键词、访问类型、创建者等多种维度进行搜索。每个工具都必须与一个单一的 REST API 端点强绑定,并且其清单和端点必须严格同源(协议、主机、端口完全一致),这确保了工具注册的清晰性和安全性。

兼容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/ProjectOpenSea/opensea-skill/tree/main/opensea-tool-sdk

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

OpenSea 工具 SDK 是做什么的?

使用 OpenSea 工具注册表 (ERC-8257) 在 Base 网络上构建、注册和门控 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
买卖 NFTopensea-marketplace
交换 ERC20 代币opensea-swaps
设置钱包签名提供者opensea-wallet

此 SDK 适用于工具提供者和消费者。若要查询 OpenSea 市场数据(地板价、列表、交易),请改用 opensea-api 技能。

概念

术语含义
工具 (Tool)一个具有 JSON Schema 接口的单一 REST API 端点,可通过 /.well-known/ai-tool/<slug>.json 发现。每个工具应执行一个聚焦的操作。
清单 (Manifest)JCS 规范化后的 JSON,描述工具的名称、端点、输入、输出、定价和访问策略
工具注册表 (ToolRegistry)链上合约(Base),工具在此注册,包含清单哈希和可选的访问谓词
访问谓词 (Access Predicate)一个 IAccessPredicate 合约,用于门控谁可以调用工具(NFT 所有权、订阅、特质门控、ERC-20 余额、复合条件)
x402基于 HTTP 402 的按次付费协议(调用者签署 USDC TransferWithAuthorization;服务器在执行后结算)
EIP-3009 鉴权使用零值 USDC TransferWithAuthorization 签名来鉴权谓词门控工具的调用者
促进者 (Facilitator)验证和结算 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:

  1. 从 --metadata URL 获取清单
  2. 验证清单模式
  3. 确认 manifest.creatorAddress 与你的钱包匹配
  4. 计算 JCS keccak256 清单哈希
  5. 调用 ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate)
  6. 从 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

关于已部署的谓词地址、要求编码以及 SDK 辅助函数(如 describeToolAccess / decodeRequirement),请参见 references/known-predicates.md。

4. 钱包设置

该 SDK 通过 @opensea/wallet-adapters 支持多种钱包提供者。设置环境变量后,SDK 会自动检测提供者。有关完整的提供者表、环境变量、设置指南和签名策略配置,请参见 opensea-wallet 技能。

提供者环境变量最佳适用场景
私钥PRIVATE_KEY本地开发、脚本
PrivyPRIVY_APP_ID、PRIVY_APP_SECRET、PRIVY_WALLET_ID服务器钱包
TurnkeyTURNKEY_API_PUBLIC_KEY、TURNKEY_API_PRIVATE_KEY、TURNKEY_ORGANIZATION_ID企业级签名
FireblocksFIREBLOCKS_API_KEY、FIREBLOCKS_API_SECRET、FIREBLOCKS_VAULT_ACCOUNT_ID机构托管
BankrBANKR_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. 响应

…

[为翻译而截断]

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

相关技能