OpenSea Tool SDK은(는) 무엇을 하나요?
Base 체인에서 OpenSea Tool Registry (ERC-8257)를 사용하여 AI가 호출 가능한 도구 엔드포인트를 구축, 등록 및 게이트합니다.
이 스킬을 사용해야 하는 경우 (scope_in)
다음과 같은 경우 opensea-tool-sdk를 사용하세요:
- Vercel, Cloudflare 또는 Express용 AI 호출 가능 도구 엔드포인트(HTTPS, JSON Schema,
.well-known매니페스트)를 스캐폴딩할 때 - 다른 에이전트가 발견할 수 있도록 Base ToolRegistry에 온체인 도구를 등록할 때
- x402 호출당 지불(USDC) 또는 조건자(ERC-721/ERC-1155 소유권, 구독, 특성 게이팅, ERC-20 잔액, 복합 조건)를 통해 접근을 게이트할 때
- 게이트되거나 유료 도구를 호출할 때: 402 결제(
paidFetch), 조건자 게이트 인증(eip3009AuthenticatedFetch), 또는 둘 다(paidAuthenticatedFetch) - OpenSea REST API를 통해 등록된 도구를 검색하고 발견할 때
이 스킬을 사용하지 말아야 하는 경우 (scope_out, 인계)
| 필요 사항 | 대신 사용할 도구 |
|---|---|
| NFT/토큰 데이터 조회, 검색, 컬렉션 통계 | opensea-api |
| NFT 매수/매도 | opensea-marketplace |
| ERC20 토큰 스왑 | opensea-swaps |
| 지갑 서명 공급자 설정 | opensea-wallet |
이 SDK는 도구 제공자와 소비자를 위한 것입니다. OpenSea 마켓플레이스 데이터(바닥 가격, 리스팅, 거래)를 조회하려면 대신 opensea-api 스킬을 사용하세요.
개념
| 용어 | 의미 |
|---|---|
| 도구 (Tool) | /.well-known/ai-tool/<slug>.json을 통해 발견 가능한, JSON Schema 인터페이스를 가진 단일 REST API 엔드포인트. 각 도구는 하나의 집중된 작업을 수행해야 합니다. |
| 매니페스트 (Manifest) | 도구의 이름, 엔드포인트, 입력, 출력, 가격 및 접근 정책을 설명하는 JCS 표준화된 JSON |
| ToolRegistry | (Base) 온체인 계약. 매니페스트 해시와 선택적 접근 조건자를 사용하여 도구가 등록됩니다. |
| 접근 조건자 (Access Predicate) | 도구 호출을 게이트하는 IAccessPredicate 계약 (NFT 소유권, 구독, 특성 게이팅, ERC-20 잔액, 복합 조건) |
| x402 | HTTP 402 기반 호출당 지불 프로토콜 (호출자가 USDC TransferWithAuthorization에 서명; 서버는 실행 후 정산) |
| EIP-3009 인증 | 조건자 게이트 도구 호출자를 인증하는 데 사용되는 0값 USDC TransferWithAuthorization 서명 |
| Facilitator | x402 결제를 확인하고 정산하는 타사 서비스 (PayAI 또는 Coinbase CDP) |
중요한 제약 사항
하나의 도구 = 하나의 엔드포인트. 각 도구 등록은 단일 REST API 엔드포인트를 나타내며, 하나의 초점과 의도를 가져야 합니다. 매니페스트의 엔드포인트 URL은 하나의 잘 정의된 작업을 수행하는 특정 API 경로(예: POST /api/price-check 또는 POST /api/translate)를 가리켜야 하며, 일반 HTML 페이지, 문서 사이트 또는 다목적 URL이 아니어야 합니다. 각 등록된 도구는 개별 REST API 엔드포인트와 동일한 방식으로 생각하세요. 특정 입력을 받고, 특정 작업을 수행하며, 특정 출력을 반환해야 합니다.
오리진 바인딩: 매니페스트와 엔드포인트는 정확히 동일한 오리진을 공유해야 합니다. <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에서).
배포된 계약 (Ethereum 메인넷, 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 |
도구 발견 [베타]
OpenSea REST API를 통해 등록된 도구를 검색하거나 조회합니다. OPENSEA_API_KEY가 필요합니다.
# OPENSEA_API_KEY가 이미 설정되어 있으면 재사용; 그렇지 않으면 무료 즉시 티어 키를 가져옵니다
# (가입 불필요 — 읽기 600/h, 쓰기 30/h, 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: "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" },
},
},
// 선택 사항: 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: `Processed: ${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는 다음을 수행합니다:
--metadataURL에서 매니페스트를 가져옵니다- 매니페스트 스키마를 검증합니다
manifest.creatorAddress가 지갑과 일치하는지 확인합니다- JCS keccak256 매니페스트 해시를 계산합니다
ToolRegistry.registerTool(metadataURI, manifestHash, accessPredicate)를 호출합니다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(`Registered tool ${toolId} in tx ${txHash}`)
3. 도구 접근 게이팅
도구는 세 가지 방법으로 게이트할 수 있습니다:
| 게이트 | 메커니즘 | 참조 |
|---|---|---|
| x402 페이월 | 호출당 지불 (USDC, EIP-3009) | references/x402.md |
| 조건자 게이트 | 온체인 확인 (NFT, 구독, 특성 게이팅, ERC-20 잔액, 복합) | references/predicate-gating.md |
| 결합 | EIP-3009 인증 및 결제 (조건자 먼저, 그 다음 x402) | references/predicate-gating.md |
배포된 조건자 주소, 요구 사항 인코딩 및 describeToolAccess / decodeRequirement와 같은 SDK 헬퍼에 대해서는 references/known-predicates.md를 참조하세요.
4. 지갑 설정
SDK는 @opensea/wallet-adapters를 통해 여러 지갑 공급자를 지원합니다. 환경 변수를 설정하면 SDK가 공급자를 자동 감지합니다. 전체 공급자 테이블, 환경 변수, 설정 워크스루 및 서명 정책 구성에 대해서는 opensea-wallet 스킬을 참조하세요.
| 공급자 | 환경 변수 | 가장 적합한 경우 |
|---|---|---|
| Private Key | PRIVATE_KEY | 로컬 개발, 스크립트 |
| Privy | PRIVY_APP_ID, PRIVY_APP_SECRET, PRIVY_WALLET_ID | 서버 지갑 |
| Turnkey | TURNKEY_API_PUBLIC_KEY, TURNKEY_API_PRIVATE_KEY, TURNKEY_ORGANIZATION_ID | 엔터프라이즈 서명 |
| Fireblocks | FIREBLOCKS_API_KEY, FIREBLOCKS_API_SECRET, FIREBLOCKS_VAULT_ACCOUNT_ID | 기관 수탁 |
| Bankr | BANKR_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. 응답
…
[번역을 위해 잘림]