O que OpenSea Tool SDK faz?
Construa, registre e proteja endpoints de ferramentas acionáveis por IA usando o OpenSea Tool Registry (ERC-8257) na Base.
Quando usar este skill (scope_in)
Use opensea-tool-sdk quando precisar:
- Criar um endpoint de ferramenta acionável por IA (HTTPS, JSON Schema, manifesto
.well-known) para Vercel, Cloudflare ou Express - Registrar uma ferramenta on-chain no ToolRegistry da Base para que outros agentes possam descobri-la
- Proteger o acesso via x402 pay-per-call (USDC) ou predicados (posse de ERC-721/ERC-1155, assinaturas, controle por atributos, saldo de ERC-20, composições)
- Chamar uma ferramenta protegida ou paga: pagamentos 402 (
paidFetch), autenticação baseada em predicado (eip3009AuthenticatedFetch), ou ambos (paidAuthenticatedFetch) - Pesquisar e descobrir ferramentas registradas via API REST da OpenSea
Quando NÃO usar este skill (scope_out, encaminhamento)
| Necessidade | Use em vez disso |
|---|---|
| Consultar dados de NFT/token, pesquisar, estatísticas de coleções | opensea-api |
| Comprar/vender NFTs | opensea-marketplace |
| Trocar tokens ERC20 | opensea-swaps |
| Configurar provedores de assinatura de carteira | opensea-wallet |
Este SDK é para provedores e consumidores de ferramentas. Para consultar dados do marketplace OpenSea (preços mínimos, listagens, negociações), use o skill opensea-api.
Conceitos
| Termo | Significado |
|---|---|
| Ferramenta (Tool) | Um único endpoint de API REST com interface JSON Schema, descoberto via /.well-known/ai-tool/<slug>.json. Cada ferramenta deve realizar uma operação focada. |
| Manifesto (Manifest) | JSON canonizado pelo JCS descrevendo o nome, endpoint, entradas, saídas, preço e política de acesso da ferramenta |
| ToolRegistry | Contrato on-chain (Base) onde as ferramentas são registradas com um hash do manifesto e predicado de acesso opcional |
| Predicado de Acesso (Access Predicate) | Um contrato IAccessPredicate que controla quem pode invocar uma ferramenta (posse de NFT, assinaturas, controle por atributos, saldo ERC-20, composições) |
| x402 | Protocolo de pagamento por chamada baseado em HTTP 402 (o chamador assina uma TransferWithAuthorization de USDC; o servidor liquida após a execução) |
| Autenticação EIP-3009 | Assinatura TransferWithAuthorization de USDC de valor zero usada para autenticar chamadores de ferramentas protegidas por predicado |
| Facilitador (Facilitator) | Serviço terceirizado que verifica e liquida pagamentos x402 (PayAI ou Coinbase CDP) |
Restrições Importantes
Uma ferramenta = um endpoint. Cada registro de ferramenta representa um único endpoint de API REST com um foco e intenção singular. A URL do endpoint no seu manifesto deve apontar para uma rota de API específica que realiza uma operação bem definida (por exemplo, POST /api/consulta-preco ou POST /api/traduzir), não uma página HTML genérica, site de documentação ou URL de múltiplos propósitos. Pense em cada ferramenta registrada da mesma forma que você pensa em um endpoint de API REST individual. Ela deve aceitar uma entrada específica, realizar uma ação específica e retornar uma saída específica.
Vínculo de origem: manifesto e endpoint devem compartilhar a mesma origem. Seu manifesto .well-known/ai-tool/<slug>.json e o endpoint de invocação da sua ferramenta devem ser servidos da mesma origem exata (mesmo esquema, host e porta conforme RFC 6454). Subdomínios não contam como a mesma origem. example.com e api.example.com são origens diferentes. Isso é verificado no momento do registro. Se a origem do manifesto e a origem do endpoint não coincidirem exatamente, a ferramenta será rejeitada e marcada como não registrada.
- Válido: manifesto em
https://minha-ferramenta.example.com/.well-known/ai-tool/minha-ferramenta.json, endpoint emhttps://minha-ferramenta.example.com/api/minha-ferramenta - Inválido: manifesto em
https://example.com/.well-known/ai-tool/minha-ferramenta.json, endpoint emhttps://api.example.com/api/minha-ferramenta
Se você precisar que sua API esteja em um subdomínio, sirva o manifesto do mesmo subdomínio (por exemplo, ambos em api.example.com).
Contratos Implantados (Ethereum mainnet, Base, Shape, Abstract, Monad, Robinhood Chain)
Implantações canônicas v0.2 — mesmo endereço CREATE2 em todas as chains suportadas.
| Contrato | Endereço |
|---|---|
| ToolRegistry (v0.2) | 0x265BB2DBFC0A8165C9A1941Eb1372F349baD2cf1 |
| ERC721OwnerPredicate (v0.2) | 0xc8721c9A776958FfFfEb602DA1b708bf1D318379 |
| ERC1155OwnerPredicate (v0.2) | 0x77373Dc3c1AE9A1e937eF3e5E08F4807D47c7c11 |
| SubscriptionPredicate (v0.2) | 0xCBe0cd9B1d99d95Baa9c58f2767246C52e461f25 |
| TraitGatedPredicate (v0.2) | 0x10abF07CfA34Bf22372C57f27e8bd9C2DCF93fA1 |
| ERC20BalancePredicate (v0.2) | 0x1a834FC48B5f6e119c62C12a98b32137bCFA77cD |
Descoberta de Ferramentas [Beta]
Pesquise ou consulte ferramentas registradas via API REST da OpenSea. Requer OPENSEA_API_KEY.
# Reutilize OPENSEA_API_KEY se já estiver definida; caso contrário, obtenha uma chave instantânea gratuita
# (sem cadastro — 600/h leitura, 30/h escrita, expira em 7 dias) e SALVE-a para reutilização.
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") # reutiliza chave em cache
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") # salva antes de usar
export OPENSEA_API_KEY="${api_key}"
fi
fi
Sempre salve uma chave instantânea obtida e reutilize-a em vez de obtê-la novamente. O skill opensea-api fornece um helper auth/opensea-resolve-key.sh que faz isso (env → arquivo em cache → busca + salvamento); consulte sua seção "Resolução de chave de API". Para limites de taxa mais altos, crie uma chave completa em Configurações → Desenvolvedor.
Listar ferramentas: GET /api/v2/tools (docs)
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
sort_by | Não | Ordenar por: newest (padrão), oldest |
type | Não | Filtrar por tipo de acesso: open, nft_gated, token_gated, subscription, gated |
limit | Não | Resultados por página (1–100) |
cursor | Não | Cursor de paginação |
Pesquisar ferramentas: GET /api/v2/tools/search (docs)
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
query | Não | Texto da consulta de pesquisa |
registry_chain | Não | Filtrar pelo ID da chain do registro |
tags | Não | Filtrar por tags |
access_type | Não | Filtrar por tipo de acesso: open, nft_gated, subscription |
creator | Não | Filtrar pelo endereço do criador |
sort_by | Não | Ordenar por: relevance (padrão), newest, most_used |
limit | Não | Resultados por página (1–200) |
cursor.value | Não | Cursor de paginação |
Obter uma ferramenta: GET /api/v2/tools/{registry_chain}/{registry_addr}/{tool_id} (docs)
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
registry_chain | Sim | ID da chain do registro (ex.: 1, 8453) |
registry_addr | Sim | Endereço do contrato do registro |
tool_id | Sim | ID numérico da ferramenta |
# Listar ferramentas ordenadas pelas mais novas
curl -s "https://api.opensea.io/api/v2/tools?sort_by=newest&limit=10" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Listar ferramentas filtradas por tipo
curl -s "https://api.opensea.io/api/v2/tools?type=open&sort_by=oldest" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Pesquisar ferramentas por palavra-chave
curl -s "https://api.opensea.io/api/v2/tools/search?query=nft" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Obter uma ferramenta específica na Base
curl -s "https://api.opensea.io/api/v2/tools/8453/0x265BB2DBFC0A8165C9A1941Eb1372F349baD2cf1/1" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Filtrar por tipo de acesso
curl -s "https://api.opensea.io/api/v2/tools/search?access_type=open&limit=10" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
1. Criar uma Ferramenta
1a. Criar um projeto
npx @opensea/tool-sdk init --runtime vercel # ou: cloudflare, express
Isso gera:
src/manifest.ts— definição do manifesto da ferramentasrc/handler.ts— manipulador de requisições com esquemas de entrada/saídaapi/index.ts— ponto de entrada do adaptador do frameworkpublic/llms.txt— página de descoberta legível por agenteapi/well-known/[slug].ts— serve o manifesto em/.well-known/ai-tool/<slug>.json
1b. Definir o manifesto
import { defineManifest } from "@opensea/tool-sdk"
export const manifest = defineManifest({
name: "Minha Ferramenta",
description: "O que esta ferramenta faz",
endpoint: "https://minha-ferramenta.example.com/api",
creatorAddress: "0xSEU_ENDERECO_DE_CARTEIRA",
inputs: {
type: "object",
properties: {
query: { type: "string", description: "Consulta de pesquisa" },
},
required: ["query"],
},
outputs: {
type: "object",
properties: {
result: { type: "string" },
},
},
// Opcional: adicionar preço para paywall x402 (consulte references/x402.md)
// pricing: paywall.pricing,
// Opcional: adicionar requisitos de acesso (consulte references/predicate-gating.md)
// access: { logic: "OR", requirements: [...] },
})
1c. Escrever o manipulador
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: [], // Adicione gates aqui (consulte references/x402.md e references/predicate-gating.md)
handler: async (input) => {
return { result: `Processado: ${input.query}` }
},
})
1d. Conectar o adaptador
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. Registrar uma Ferramenta On-chain
2a. Via CLI
# Configurar carteira
export PRIVATE_KEY=0x...
export RPC_URL=https://mainnet.base.org
# Registrar (acesso aberto — sem predicado)
npx @opensea/tool-sdk register \
--metadata https://minha-ferramenta.example.com/.well-known/ai-tool/minha-ferramenta.json \
--network base
# Registrar com um predicado de acesso
npx @opensea/tool-sdk register \
--metadata https://minha-ferramenta.example.com/.well-known/ai-tool/minha-ferramenta.json \
--network base \
--access-predicate 0xENDERECO_DO_PREDICADO
# Simulação (sem transação)
npx @opensea/tool-sdk register --metadata ... --network base --dry-run
A CLI:
- Busca o manifesto da URL
--metadata - Valida o esquema do manifesto
- Verifica se
manifest.creatorAddresscorresponde à sua carteira - Calcula o hash do manifesto JCS keccak256
- Chama
ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate) - Retorna o
toolIddo eventoToolRegistered
2b. Via SDK (programaticamente)
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://minha-ferramenta.example.com/.well-known/ai-tool/minha-ferramenta.json",
manifest, // seu objeto ToolManifest
accessPredicate: "0x0000...0000", // address(0) = acesso aberto
})
console.log(`Ferramenta ${toolId} registrada na tx ${txHash}`)
3. Protegendo o acesso à ferramenta
Ferramentas podem ser protegidas de três maneiras:
| Gate | Mecanismo | Referência |
|---|---|---|
| Paywall x402 | Pagamento por chamada (USDC, EIP-3009) | references/x402.md |
| Gate de predicado | Verificação on-chain (NFT, assinatura, controle por atributos, saldo ERC-20, composição) | references/predicate-gating.md |
| Combinado | Autenticação EIP-3009 e pagamento (predicado primeiro, depois x402) | references/predicate-gating.md |
Para endereços de predicados implantados, codificações de requisitos e helpers do SDK como describeToolAccess / decodeRequirement, consulte references/known-predicates.md.
4. Configuração de Carteira
O SDK suporta múltiplos provedores de carteira via @opensea/wallet-adapters. Defina variáveis de ambiente e o SDK detecta automaticamente o provedor. Consulte o skill opensea-wallet para a tabela completa de provedores, variáveis de ambiente, guias de configuração e configuração de política de assinatura.
| Provedor | Variáveis de ambiente | Melhor para |
|---|---|---|
| Chave Privada | PRIVATE_KEY | Desenvolvimento local, scripts |
| Privy | PRIVY_APP_ID, PRIVY_APP_SECRET, PRIVY_WALLET_ID | Carteiras de servidor |
| Turnkey | TURNKEY_API_PUBLIC_KEY, TURNKEY_API_PRIVATE_KEY, TURNKEY_ORGANIZATION_ID | Assinatura empresarial |
| Fireblocks | FIREBLOCKS_API_KEY, FIREBLOCKS_API_SECRET, FIREBLOCKS_VAULT_ACCOUNT_ID | Custódia institucional |
| Bankr | BANKR_API_KEY | Carteiras de agente (via API HTTP) |
Para qualquer provedor, RPC_URL (ou a flag --rpc-url) define o endpoint RPC para leituras e gravações on-chain. Quando nenhum é definido, os comandos da CLI usam o RPC público padrão da rede, que pode ser lento ou com limite de taxa.
import { createWalletFromEnv } from "@opensea/tool-sdk"
// Auto-detecção: Privy > Fireblocks > Turnkey > Bankr > PrivateKey
const adapter = createWalletFromEnv()
const address = await adapter.getAddress()
Para Bankr (signatário externo):
import { createBankrAccount } from "@opensea/tool-sdk"
const account = await createBankrAccount("sua-chave-de-api-bankr")
// Use com eip3009AuthenticatedFetch ou paidAuthenticatedFetch
5. Resposta
…
[truncado para tradução]