OpenSea Tool SDK
Erstelle, registriere und beschränke den Zugriff auf KI-gesteuerte Tool-Endpunkte mit dem OpenSea Tool Registry (ERC-8257) auf Base.
Wann dieses Skill verwenden (scope_in)
Verwende opensea-tool-sdk, wenn du Folgendes benötigst:
- Erstellen eines KI-gesteuerten Tool-Endpunkts (HTTPS, JSON Schema,
.well-known-Manifest) für Vercel, Cloudflare oder Express - Onchain-Registrierung eines Tools im Base ToolRegistry, damit andere Agenten es finden können
- Zugriffsbeschränkung über x402 Pay-per-Call (USDC) oder Prädikate (ERC-721/ERC-1155-Besitz, Abonnements, Trait-Gating, ERC-20-Kontostand, Kombinationen)
- Aufrufen eines geschützten oder bezahlten Tools: 402-Zahlungen (
paidFetch), prädikatsgesteuerte Authentifizierung (eip3009AuthenticatedFetch) oder beides (paidAuthenticatedFetch) - Suchen und Finden registrierter Tools über die OpenSea REST API
Wann dieses Skill NICHT verwenden (scope_out, Übergabe)
| Bedarf | Stattdessen verwenden |
|---|---|
| NFT/Token-Daten abfragen, suchen, Sammlungsstatistiken | opensea-api |
| NFTs kaufen/verkaufen | opensea-marketplace |
| ERC20-Token tauschen | opensea-swaps |
| Wallet-Signing-Provider einrichten | opensea-wallet |
Dieses SDK ist für Tool-Anbieter und -Nutzer. Verwende für Abfragen von OpenSea-Marktplatzdaten (Bodenpreise, Listings, Trades) stattdessen das Skill opensea-api.
Konzepte
| Begriff | Bedeutung |
|---|---|
| Tool | Ein einzelner REST-API-Endpunkt mit einer JSON-Schema-Schnittstelle, auffindbar über /.well-known/ai-tool/<slug>.json. Jedes Tool sollte eine fokussierte Operation durchführen. |
| Manifest | JCS-kanonisches JSON, das den Namen, Endpunkt, Eingaben, Ausgaben, Preisgestaltung und Zugriffsrichtlinie des Tools beschreibt |
| ToolRegistry | Onchain-Vertrag (Base) in dem Tools mit einem Manifest-Hash und optionalem Zugriffsprädikat registriert werden |
| Zugriffsprädikat | Ein IAccessPredicate-Vertrag, der den Zugriff auf ein Tool beschränkt (NFT-Besitz, Abonnements, Trait-Gating, ERC-20-Kontostand, Kombinationen) |
| x402 | HTTP 402-basiertes Pay-per-Call-Protokoll (Aufrufer signiert eine USDC TransferWithAuthorization; Server führt nach Ausführung aus) |
| EIP-3009-Auth | USDC TransferWithAuthorization-Signatur mit Nullwert, die zur Authentifizierung von Aufrufern für prädikatsgesteuerte Tools verwendet wird |
| Vermittler | Drittanbieter-Dienst, der x402-Zahlungen verifiziert und ausführt (PayAI oder Coinbase CDP) |
Wichtige Einschränkungen
Ein Tool = ein Endpunkt. Jede Tool-Registrierung repräsentiert einen einzelnen REST-API-Endpunkt mit einem singulären Fokus und Zweck. Die Endpunkt-URL in deinem Manifest sollte auf eine bestimmte API-Route verweisen, die eine klar definierte Operation ausführt (z. B. POST /api/price-check oder POST /api/translate), nicht auf eine generische HTML-Seite, Dokumentationsseite oder Multi-Purpose-URL. Betrachte jedes registrierte Tool wie einen einzelnen REST-API-Endpunkt. Es sollte eine bestimmte Eingabe akzeptieren, eine bestimmte Aktion ausführen und eine bestimmte Ausgabe zurückgeben.
Ursprungsbindung: Manifest und Endpunkt müssen denselben Ursprung haben. Dein .well-known/ai-tool/<slug>.json-Manifest und dein Tool-Invokationsendpunkt müssen vom exakt gleichen Ursprung bereitgestellt werden (identisches Schema, Host und Port gemäß RFC 6454). Subdomänen zählen nicht als derselbe Ursprung. example.com und api.example.com sind unterschiedliche Ursprünge. Dies wird zur Registrierungszeit erzwungen. Wenn der Manifest-Ursprung und der Endpunkt-Ursprung nicht exakt übereinstimmen, wird das Tool abgelehnt und als deregistriert markiert.
- Gültig: Manifest unter
https://my-tool.example.com/.well-known/ai-tool/my-tool.json, Endpunkt unterhttps://my-tool.example.com/api/my-tool - Ungültig: Manifest unter
https://example.com/.well-known/ai-tool/my-tool.json, Endpunkt unterhttps://api.example.com/api/my-tool
Wenn du deine API auf einer Subdomain benötigst, stelle das Manifest von derselben Subdomain bereit (z. B. beide auf api.example.com).
Bereitgestellte Verträge (Ethereum Mainnet, Base, Shape, Abstract, Monad, Robinhood Chain)
Kanonische v0.2-Bereitstellungen – identische CREATE2-Adresse auf jeder unterstützten Chain.
| Vertrag | Adresse |
|---|---|
| ToolRegistry (v0.2) | 0x265BB2DBFC0A8165C9A1941Eb1372F349baD2cf1 |
| ERC721OwnerPredicate (v0.2) | 0xc8721c9A776958FfFfEb602DA1b708bf1D318379 |
| ERC1155OwnerPredicate (v0.2) | 0x77373Dc3c1AE9A1e937eF3e5E08F4807D47c7c11 |
| SubscriptionPredicate (v0.2) | 0xCBe0cd9B1d99d95Baa9c58f2767246C52e461f25 |
| TraitGatedPredicate (v0.2) | 0x10abF07CfA34Bf22372C57f27e8bd9C2DCF93fA1 |
| ERC20BalancePredicate (v0.2) | 0x1a834FC48B5f6e119c62C12a98b32137bCFA77cD |
Tool-Erkennung [Beta]
Suche oder rufe registrierte Tools über die OpenSea REST API auf. Erfordert OPENSEA_API_KEY.
# Verwende OPENSEA_API_KEY, falls bereits gesetzt; ansonsten hole einen kostenlosen Instant-Key
# (keine Anmeldung – 600/h lesen, 30/h schreiben, 7 Tage Gültigkeit) und SPARE ihn für die Wiederverwendung.
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") # verwende zwischengespeicherten Key
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") # speichere vor der Verwendung
export OPENSEA_API_KEY="${api_key}"
fi
fi
Speichere einen abgerufenen Instant-Key immer und verwende ihn erneut, anstatt ihn erneut abzurufen. Das opensea-api-Skill enthält einen auth/opensea-resolve-key.sh-Helfer, der dies tut (env → zwischengespeicherte Datei → abrufen + speichern); siehe seinen Abschnitt "API-Key-Auflösung". Für höhere Ratenbegrenzungen erstelle einen vollständigen Key unter Einstellungen → Entwickler.
Tools auflisten: GET /api/v2/tools (Dokumentation)
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
sort_by | Nein | Sortieren nach: newest (Standard), oldest |
type | Nein | Filtern nach Zugriffstyp: open, nft_gated, token_gated, subscription, gated |
limit | Nein | Ergebnisse pro Seite (1–100) |
cursor | Nein | Paginierungs-Cursor |
Tools suchen: GET /api/v2/tools/search (Dokumentation)
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
query | Nein | Suchtext |
registry_chain | Nein | Filtere nach Registrierungs-Chain-ID |
tags | Nein | Filtere nach Tags |
access_type | Nein | Filtere nach Zugriffstyp: open, nft_gated, subscription |
creator | Nein | Filtere nach Ersteller-Adresse |
sort_by | Nein | Sortieren nach: relevance (Standard), newest, most_used |
limit | Nein | Ergebnisse pro Seite (1–200) |
cursor.value | Nein | Paginierungs-Cursor |
Ein Tool abrufen: GET /api/v2/tools/{registry_chain}/{registry_addr}/{tool_id} (Dokumentation)
| Parameter | Erforderlich | Beschreibung |
|---|---|---|
registry_chain | Ja | Registrierungs-Chain-ID (z. B. 1, 8453) |
registry_addr | Ja | Vertragsadresse des Registrierungsvertrags |
tool_id | Ja | Numerische Tool-ID |
# Tools, sortiert nach neuesten
curl -s "https://api.opensea.io/api/v2/tools?sort_by=newest&limit=10" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Tools, gefiltert nach Typ
curl -s "https://api.opensea.io/api/v2/tools?type=open&sort_by=oldest" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Tools nach Stichwort suchen
curl -s "https://api.opensea.io/api/v2/tools/search?query=nft" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Ein bestimmtes Tool auf Base abrufen
curl -s "https://api.opensea.io/api/v2/tools/8453/0x265BB2DBFC0A8165C9A1941Eb1372F349baD2cf1/1" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
# Nach Zugriffstyp filtern
curl -s "https://api.opensea.io/api/v2/tools/search?access_type=open&limit=10" \
-H "x-api-key: $OPENSEA_API_KEY" | jq
1. Ein Tool erstellen
1a. Ein Projekt erstellen
npx @opensea/tool-sdk init --runtime vercel # oder: cloudflare, express
Dies erzeugt:
src/manifest.ts— Tool-Manifest-Definitionsrc/handler.ts— Request-Handler mit Eingabe-/Ausgabeschemataapi/index.ts— Framework-Adapter-Einstiegspunktpublic/llms.txt— agentenlesbare Erkennungsseiteapi/well-known/[slug].ts— stellt das Manifest unter/.well-known/ai-tool/<slug>.jsonbereit
1b. Das Manifest definieren
import { defineManifest } from "@opensea/tool-sdk"
export const manifest = defineManifest({
name: "Mein Tool",
description: "Was dieses Tool tut",
endpoint: "https://my-tool.example.com/api",
creatorAddress: "0xYOUR_WALLET_ADDRESS",
inputs: {
type: "object",
properties: {
query: { type: "string", description: "Suchanfrage" },
},
required: ["query"],
},
outputs: {
type: "object",
properties: {
result: { type: "string" },
},
},
// Optional: Preisgestaltung für x402-Paywall hinzufügen (siehe references/x402.md)
// pricing: paywall.pricing,
// Optional: Zugriffsanforderungen hinzufügen (siehe references/predicate-gating.md)
// access: { logic: "OR", requirements: [...] },
})
1c. Den Handler schreiben
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: [], // Füge hier Gates hinzu (siehe references/x402.md und references/predicate-gating.md)
handler: async (input) => {
return { result: `Verarbeitet: ${input.query}` }
},
})
1d. Den Adapter einbinden
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. Ein Tool onchain registrieren
2a. Über die CLI
# Wallet einrichten
export PRIVATE_KEY=0x...
export RPC_URL=https://mainnet.base.org
# Registrieren (offener Zugriff — kein Prädikat)
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base
# Registrieren mit einem Zugriffsprädikat
npx @opensea/tool-sdk register \
--metadata https://my-tool.example.com/.well-known/ai-tool/my-tool.json \
--network base \
--access-predicate 0xPREDICATE_ADDRESS
# Trockentest (keine Transaktion)
npx @opensea/tool-sdk register --metadata ... --network base --dry-run
Die CLI:
- Ruft das Manifest von der
--metadata-URL ab - Validiert das Manifest-Schema
- Überprüft, ob
manifest.creatorAddressmit deiner Wallet übereinstimmt - Berechnet den JCS keccak256-Manifest-Hash
- Ruft
ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate)auf - Gibt die
toolIdaus demToolRegistered-Ereignis zurück
2b. Über das SDK (programmatisch)
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, // dein ToolManifest-Objekt
accessPredicate: "0x0000...0000", // address(0) = offener Zugriff
})
console.log(`Tool ${toolId} in Transaktion ${txHash} registriert`)
3. Tool-Zugriff beschränken
Tools können auf drei Arten beschränkt werden:
| Gate | Mechanismus | Referenz |
|---|---|---|
| x402-Paywall | Pay-per-Call (USDC, EIP-3009) | references/x402.md |
| Prädikatsgate | Onchain-Prüfung (NFT, Abonnement, Trait-Gating, ERC-20-Kontostand, Kombination) | references/predicate-gating.md |
| Kombiniert | EIP-3009-Authentifizierung und Zahlung (zuerst Prädikat, dann x402) | references/predicate-gating.md |
Informationen zu bereitgestellten Prädikatsadressen, Anforderungscodierungen und SDK-Helfern wie describeToolAccess / decodeRequirement findest du in references/known-predicates.md.
4. Wallet-Einrichtung
Das SDK unterstützt mehrere Wallet-Provider über @opensea/wallet-adapters. Setze Umgebungsvariablen und das SDK erkennt den Provider automatisch. Siehe das Skill opensea-wallet für die vollständige Provider-Tabelle, Umgebungsvariablen, Einrichtungsschritte und Konfiguration der Signier-Richtlinie.
| Provider | Umgebungsvariablen | Am besten geeignet für |
|---|---|---|
| Privater Schlüssel | PRIVATE_KEY | Lokale Entwicklung, Skripte |
| Privy | PRIVY_APP_ID, PRIVY_APP_SECRET, PRIVY_WALLET_ID | Server-Wallets |
| Turnkey | TURNKEY_API_PUBLIC_KEY, TURNKEY_API_PRIVATE_KEY, TURNKEY_ORGANIZATION_ID | Unternehmenssignierung |
| Fireblocks | FIREBLOCKS_API_KEY, FIREBLOCKS_API_SECRET, FIREBLOCKS_VAULT_ACCOUNT_ID | Institutionelle Verwahrung |
| Bankr | BANKR_API_KEY | Agenten-Wallets (über HTTP-API) |
Für jeden Provider legt RPC_URL (oder das --rpc-url-Flag) den RPC-Endpunkt für Onchain-Lese- und Schreibvorgänge fest. Wenn keines gesetzt ist, fallen CLI-Befehle auf den standardmäßigen öffentlichen RPC des Netzwerks zurück, der langsam oder ratenbegrenzt sein kann.
import { createWalletFromEnv } from "@opensea/tool-sdk"
// Automatische Erkennung: Privy > Fireblocks > Turnkey > Bankr > PrivateKey
const adapter = createWalletFromEnv()
const address = await adapter.getAddress()
Für Bankr (externer Signierer):
import { createBankrAccount } from "@opensea/tool-sdk"
const account = await createBankrAccount("your-bankr-api-key")
// Verwende mit eip3009AuthenticatedFetch oder paidAuthenticatedFetch
5. Antwort
…
[gekürzt zur Übersetzung]