OpenSea Tool SDK
Construisez, enregistrez et contrôlez l'accès à des endpoints d'outils appelables par IA en utilisant le registre OpenSea Tool (ERC-8257) sur Base.
Quand utiliser cette compétence (scope_in)
Utilisez opensea-tool-sdk quand vous avez besoin de :
- Scaffolder un endpoint d'outil appelable par IA (HTTPS, JSON Schema, manifeste
.well-known) pour Vercel, Cloudflare ou Express - Enregistrer un outil onchain sur le ToolRegistry Base pour que d'autres agents le découvrent
- Contrôler l'accès via x402 pay-per-call (USDC) ou prédicats (propriété ERC-721/ERC-1155, abonnements, composites)
- Appeler un outil contrôlé : authentification SIWE (
authenticatedFetch), paiements 402 (paidFetch), ou les deux (paidAuthenticatedFetch)
Quand NE PAS utiliser cette compétence (scope_out, handoff)
| Besoin | Utilisez plutôt |
|---|---|
| Requêter des données NFT/token, rechercher, statistiques de collection | opensea-api |
| Acheter/vendre des NFT | opensea-marketplace |
| Échanger des tokens ERC20 | opensea-swaps |
| Configurer des fournisseurs de signature wallet | opensea-wallet |
Ce SDK est pour les fournisseurs et consommateurs d'outils. Pour requêter les données du marketplace OpenSea (prix plancher, listes, échanges), utilisez plutôt la compétence opensea-api.
Concepts
| Terme | Signification |
|---|---|
| Tool | Un endpoint HTTPS avec une interface JSON Schema, découvrable via /.well-known/ai-tool/<slug>.json |
| Manifest | JSON canonicalisé JCS décrivant le nom, l'endpoint, les entrées, sorties, tarification et politique d'accès de l'outil |
| ToolRegistry | Contrat onchain (Base) où les outils sont enregistrés avec un hash de manifeste et un prédicat d'accès optionnel |
| Access Predicate | Un contrat IAccessPredicate qui contrôle qui peut invoquer un outil (propriété NFT, abonnements, composites) |
| x402 | Protocole pay-per-call basé sur HTTP 402 (l'appelant signe une TransferWithAuthorization USDC ; le serveur règle après exécution) |
| SIWE | Sign-In with Ethereum (EIP-4361), utilisé pour authentifier les appelants pour les outils contrôlés par prédicat |
| Facilitator | Service tiers qui vérifie et règle les paiements x402 (PayAI ou Coinbase CDP) |
Contrats déployés (Base mainnet)
| Contrat | Adresse |
|---|---|
| ToolRegistry (v0.1) | 0x7291BbFbC368C2D478eCe1eA30de31F612a34856 |
| ERC721OwnerPredicate (v0.2) | 0xd1F703D0B90BB7106fAebBfbcAdD2B07BDc4c769 |
| ERC1155OwnerPredicate (v0.2) | 0xc179b9d4D9B7ffe0CdA608134729f72003380A7e |
1. Créer un outil
1a. Scaffolder un projet
npx @opensea/tool-sdk init --runtime vercel # ou : cloudflare, express
Cela génère :
src/manifest.ts: définition du manifeste de l'outilsrc/handler.ts: gestionnaire de requête avec schémas d'entrée/sortieapi/index.ts: point d'entrée de l'adaptateur frameworkpublic/llms.txt: page de découverte lisible par agentapi/well-known/[slug].ts: sert le manifeste à/.well-known/ai-tool/<slug>.json
1b. Définir le manifeste
import { defineManifest } from "@opensea/tool-sdk"
export const manifest = defineManifest({
name: "My Tool",
description: "What this tool does",
endpoint: "https://my-tool.example.com/api",
creatorAddress: "0xYOUR_WALLET_ADDRESS",
inputs: {
type: "object",
properties: {
query: { type: "string", description: "Search query" },
},
required: ["query"],
},
outputs: {
type: "object",
properties: {
result: { type: "string" },
},
},
// Optionnel : ajouter la tarification pour paywall x402 (voir references/x402.md)
// pricing: paywall.pricing,
// Optionnel : ajouter les exigences d'accès (voir references/predicate-gating.md)
// access: { logic: "OR", requirements: [...] },
})
1c. Écrire le gestionnaire
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: [], // Ajouter les gates ici (voir references/x402.md et references/predicate-gating.md)
handler: async (input) => {
return { result: `Processed: ${input.query}` }
},
})
1d. Connecter l'adaptateur
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. Enregistrer un outil onchain
2a. Via CLI
# Configurer le wallet
export PRIVATE_KEY=0x...
export RPC_URL=https://mainnet.base.org
# Enregistrer (accès ouvert, pas de prédicat)
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base
# Enregistrer avec gate NFT (collection ERC-721)
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base \
--nft-gate 0xCOLLECTION_ADDRESS
# Enregistrer avec un prédicat d'accès personnalisé
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base \
--access-predicate 0xPREDICATE_ADDRESS
# Dry run (pas de transaction)
npx @opensea/tool-sdk register --metadata ... --network base --dry-run
Le CLI :
- Récupère le manifeste de l'URL
--metadata - Valide le schéma du manifeste
- Vérifie que
manifest.creatorAddresscorrespond à votre wallet - Calcule le hash JCS keccak256 du manifeste
- Appelle
ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate) - Retourne le
toolIdde l'événementToolRegistered
2b. Via SDK (programmatique)
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, // votre objet ToolManifest
accessPredicate: "0x0000...0000", // address(0) pour accès ouvert
})
console.log(`Registered tool ${toolId} in tx ${txHash}`)
3. Contrôler l'accès aux outils
Les outils peuvent être contrôlés de trois façons :
| Gate | Mécanisme | Référence |
|---|---|---|
| Paywall x402 | Pay-per-call (USDC, EIP-3009) | references/x402.md |
| Predicate gate | Vérification onchain (NFT, abonnement, composite) | references/predicate-gating.md |
| Combiné | Authentification SIWE et paiement (prédicat d'abord, puis x402) | references/predicate-gating.md |
Pour les adresses de prédicat déployées, les encodages d'exigences et les aides SDK comme describeToolAccess / decodeRequirement, voir references/known-predicates.md.
4. Configuration du wallet
Le SDK supporte plusieurs fournisseurs de wallet via @opensea/wallet-adapters. Définissez les variables d'environnement et le SDK détecte automatiquement le fournisseur. Consultez la compétence opensea-wallet pour la table complète des fournisseurs, les variables d'env, les guides de configuration et la configuration de la politique de signature.
import { createWalletFromEnv } from "@opensea/tool-sdk"
const adapter = createWalletFromEnv()
const address = await adapter.getAddress()
Pour Bankr (signataire externe) :
import { createBankrAccount } from "@opensea/tool-sdk"
const account = await createBankrAccount("your-bankr-api-key")
// Utiliser avec authenticatedFetch ou paidAuthenticatedFetch
5. Codes de réponse
| Code | Signification | Action |
|---|---|---|
| 200 | Succès | Parser le corps JSON selon le schéma outputs du manifeste |
| 400 | Entrée invalide | Corriger le corps de la requête pour correspondre au schéma inputs du manifeste |
| 401 | Authentification SIWE manquante/invalide | Signer un message SIWE et inclure Authorization: SIWE <token> |
| 402 | Paiement requis | Lire body.accepts[0] pour les exigences de paiement, signer et réessayer avec X-Payment |
| 403 | Accès refusé | Inspecter body.predicate pour découvrir ce qui est nécessaire ; acquérir le token/abonnement requis |
| 405 | Méthode non autorisée | Utiliser POST |
| 500 | Erreur interne de l'outil | Réessayer ou contacter le créateur de l'outil |
| 502 | Erreur prédicat/facilitateur | Le prédicat ou facilitateur de paiement en amont a mal agi ; réessayer plus tard |
6. Référence rapide : commandes CLI
| Commande | Objectif |
|---|---|
init |
Scaffolder un nouveau projet d'outil |
validate |
Valider un fichier manifeste |
hash |
Calculer le hash JCS keccak256 d'un manifeste |
export |
Exporter le manifeste en JSON |
register |
Enregistrer un outil onchain |
update-metadata |
Mettre à jour l'URI de métadonnées et le hash du manifeste d'un outil onchain |
inspect |
Regarder la configuration onchain d'un outil par ID |
verify |
Vérifier un manifeste contre son hash onchain |
deploy |
Déployer un outil sur Vercel |
auth |
Appeler un outil contrôlé par prédicat (SIWE) |
pay |
Appeler un outil payant x402 (USDC) |
smoke |
Détecter automatiquement le type de gate et appeler |
dry-run-gate |
Simuler une vérification gate x402 localement |
dry-run-predicate-gate |
Simuler une vérification gate prédicat localement |
Toutes les commandes CLI acceptent --wallet-provider privy|turnkey|fireblocks|bankr|private-key ou détectent automatiquement depuis les variables d'env.
7. Exemples de bout en bout
Exemple A : Outil libre à accès ouvert
# 1. Scaffolder
npx @opensea/tool-sdk init --runtime vercel
# 2. Éditer src/manifest.ts et src/handler.ts avec votre logique
# 3. Déployer
npx @opensea/tool-sdk deploy
# 4. Enregistrer (accès ouvert)
PRIVATE_KEY=0x... npx @opensea/tool-sdk register \
--metadata https://my-tool.vercel.app/.well-known/ai-tool/my-tool.json \
--network base
# 5. Appeler
curl -X POST https://my-tool.vercel.app/api \
-H "Content-Type: application/json" \
-d '{"query": "hello"}'
Exemple B : Outil payant x402 (pay-per-call uniquement, pas de vérification d'identité)
# Serveur : ajouter la gate paywall (voir references/x402.md)
# Appeler via CLI :
PRIVATE_KEY=0x... npx @opensea/tool-sdk pay \
https://my-tool.vercel.app/api \
--body '{"query": "hello"}'
Exemple C : Outil contrôlé par NFT (vérification d'identité, pas de paiement)
# Enregistrer avec gate NFT
PRIVATE_KEY=0x... npx @opensea/tool-sdk register \
--metadata https://my-tool.vercel.app/.well-known/ai-tool/my-tool.json \
--network base \
--nft-gate 0xCOLLECTION
# Serveur : ajouter predicateGate (voir references/predicate-gating.md)
# Appeler via CLI :
PRIVATE_KEY=0x... RPC_URL=https://mainnet.base.org \
npx @opensea/tool-sdk auth \
https://my-tool.vercel.app/api \
--body '{"query": "hello"}'
Exemple D : Outil contrôlé par NFT et payant (les deux gates)
# Serveur : ajouter à la fois predicateGate et paywall.gate (voir references/predicate-gating.md)
# Appeler via CLI :
PRIVATE_KEY=0x... RPC_URL=https://mainnet.base.org \
npx @opensea/tool-sdk smoke \
--endpoint https://my-tool.vercel.app/api \
--expect 200
Références
references/x402.md: protocole pay-per-call, paywall côté serveur,paidFetchreferences/predicate-gating.md: contrôle d'accès basé sur SIWE, gates combinéesreferences/known-predicates.md: contrats de prédicat déployés et aides SDK- Tool SDK GitHub