SDK des outils OpenSea
Construisez, enregistrez et contrôlez l'accès aux endpoints d'outils appelables par l'IA en utilisant le registre des outils OpenSea (ERC proposé) sur Base.
Quand utiliser cette compétence (scope_in)
Utilisez opensea-tool-sdk quand vous devez :
- Scaffolder un endpoint d'outil appelable par l'IA (HTTPS, JSON Schema, manifeste
.well-known) pour Vercel, Cloudflare ou Express - Enregistrer un outil onchain sur le ToolRegistry de Base pour que d'autres agents puissent le découvrir
- 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 | Utiliser à la place |
|---|---|
| Interroger des données NFT/token, recherche, statistiques de collection | opensea-api |
| Acheter/vendre des NFT | opensea-marketplace |
| Échanger des tokens ERC20 | opensea-swaps |
| Configurer les fournisseurs de signature de portefeuille | opensea-wallet |
Ce SDK s'adresse aux fournisseurs et consommateurs d'outils. Pour interroger les données de la marketplace OpenSea (prix plancher, annonces, échanges), utilisez plutôt la compétence opensea-api.
Concepts
| Terme | Signification |
|---|---|
| Tool | Un endpoint HTTPS avec interface JSON Schema, découvrable via /.well-known/ai-tool/<slug>.json |
| Manifest | JSON canonicalisé en 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 | 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 d'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 (mainnet Base)
| 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
Ceci 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 adaptateur de 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" },
},
},
// Optional: ajouter la tarification pour le mur de paiement x402 (voir references/x402.md)
// pricing: paywall.pricing,
// Optional: 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 contrôles ici (voir references/x402.md et references/predicate-gating.md)
handler: async (input) => {
return { result: `Processed: ${input.query}` }
},
})
1d. Brancher 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 portefeuille
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 contrôle 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
# Simulation (pas de transaction)
npx @opensea/tool-sdk register --metadata ... --network base --dry-run
La CLI :
- Récupère le manifeste depuis l'URL
--metadata - Valide le schéma du manifeste
- Vérifie que
manifest.creatorAddresscorrespond à votre portefeuille - Calcule le hash keccak256 JCS du manifeste
- Appelle
ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate) - Retourne le
toolIddepuis l'événementToolRegistered
2b. Via SDK (programmation)
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 :
| Contrôle | Mécanisme | Référence |
|---|---|---|
| Mur de paiement x402 | Pay-per-call (USDC, EIP-3009) | references/x402.md |
| Contrôle par prédicat | 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 de conditions requises et les helpers SDK comme describeToolAccess / decodeRequirement, voir references/known-predicates.md.
4. Configuration du portefeuille
Le SDK supporte plusieurs fournisseurs de portefeuille 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'environnement, les procédures 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 | Analyser 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 en amont ou le facilitateur de paiement s'est mal comporté ; 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 keccak256 JCS 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 |
Consulter la configuration onchain d'un outil par ID |
verify |
Vérifier un manifeste par rapport à son hash onchain |
deploy |
Déployer un outil vers 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 contrôle et appeler |
dry-run-gate |
Simuler localement une vérification de contrôle x402 |
dry-run-predicate-gate |
Simuler localement une vérification de contrôle par prédicat |
Toutes les commandes CLI acceptent --wallet-provider privy|turnkey|fireblocks|bankr|private-key ou détection automatique depuis les variables d'environnement.
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 un contrôle de mur de paiement (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 contrôle 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 contrôles)
# Serveur : ajouter 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, mur de paiement côté serveur,paidFetchreferences/predicate-gating.md: contrôle d'accès basé sur SIWE, contrôles combinésreferences/known-predicates.md: contrats de prédicat déployés et helpers SDK- SDK des outils GitHub