TypeScript SDK for buying, selling, and managing NFTs and tokens on OpenSea. Supports ethers and viem providers.
cd packages/sdk
pnpm install
pnpm run build # Build with tsc
pnpm run test # Run unit tests with Vitest
pnpm run test:integration # Run integration tests (requires API key)
pnpm run lint # Lint with Biome
pnpm run format # Format with Biome
pnpm run check-types # TypeScript type checking (stricter tsconfig)| Directory | Role |
|---|---|
src/sdk.ts |
OpenSeaSDK — main ethers entry point |
src/viem.ts |
OpenSeaViemSDK — viem entry point |
src/types.ts |
Public types: Chain enum, Amount, order/event types |
src/constants.ts |
Math and Ethereum constants (basis points, addresses, etc.) |
src/auth/ |
OpenSeaAuth (SIWE-based wallet authentication) and OpenSeaOAuth (OAuth 2.1 authorization-code + PKCE for keyless login) |
src/scopes.ts |
OPENSEA_SCOPES — OAuth-style API scope string constants |
src/sdk/base.ts |
BaseOpenSeaSDK — shared logic for both providers |
src/sdk/fulfillment.ts |
Order fulfillment (buy, sell, match) via Seaport |
src/sdk/orders.ts |
Create and manage listings and offers |
src/sdk/cancellation.ts |
Order cancellation logic |
src/sdk/assets.ts |
Asset transfers and approvals |
src/sdk/tokens.ts |
ERC20 wrap/unwrap (WETH) |
src/sdk/context.ts |
Shared per-call context (provider, chain, API client) threaded through the SDK |
src/api/ |
OpenSeaAPI client — all REST API calls |
src/provider/ |
Provider abstraction: ethers adapter, viem adapter, Seaport bridge |
src/abi/ |
Contract ABIs (ERC20, ERC721, ERC1155, Multicall3, TransferHelper) |
src/utils/ |
Chain helpers, fee calculations, rate limiting, address utilities |
src/orders/ |
Order types and Seaport parameter construction |
test/ |
Unit and integration tests |
When reviewing changes to this package, verify:
-
Chain enum sync: The
Chainenum insrc/types.tshas a compile-time check (_AssertAPIChainsCovered) ensuring everyChainIdentifierfrom@opensea/api-typesmaps to aChainvalue.getOfferPaymentTokenandgetListingPaymentTokenuse exhaustiveswitchstatements whosedefaultbranch assignschainto aneverbinding, sopnpm check-typesfails if a newChainis added without a payment-token case — either map it to a real token or mark it unsupported explicitly (likeChain.Solana/Chain.Hyperliquid, which throw a clear "not supported" error).getNativeWrapTokenAddressdelegates togetOfferPaymentTokenexcept forChain.Polygon, so it is covered automatically unless the wrap token differs from the offer token.test/utils/chain.spec.tsalso iterates everyChainvalue at runtime as a second guard and runs inpnpm test. When adding a chain, also updatescripts/chain-data.jsonat the monorepo root and runpnpm sync-chainsfrom the monorepo root. -
Dual provider support: Both
OpenSeaSDK(ethers) andOpenSeaViemSDK(viem) must work. Changes toBaseOpenSeaSDKaffect both. If adding provider-specific logic, ensure both adapters insrc/provider/are updated. -
@opensea/api-typesdependency: The SDK imports types from the workspace@opensea/api-typespackage. If the OpenAPI spec changes, rebuild api-types first (pnpm --filter @opensea/api-types run build) before testing the SDK. Never hand-roll API request/response types insrc/api/types.ts— always import from@opensea/api-types(or re-export throughsrc/api/types.ts) using the canonical OpenAPI schema names. Thepnpm check-api-pathsCI guardrail will fail the build ifsrc/api/apiPaths.tsreferences a URL that isn't inpackages/api-types/opensea-api.json. See the top-level AGENTS.md → "Adding a new OpenSea API endpoint" for the full flow. -
Seaport integration: Order creation and fulfillment flows use
@opensea/seaport-js. Changes to order parameters, consideration items, or fulfillment logic must be tested against the Seaport contract behavior. -
No secret leakage: API keys are passed via
OpenSeaAPIConfig.apiKey. Never log or expose them. Integration tests read keys from environment variables. -
OAuth session contract:
OpenSeaOAuthrequestsoffline_access, so successful code and device flows must return a refresh token. Refresh responses may omit rotation; retain the previous refresh token in that case. The top-levelwalletJWT claim is the only wallet identity source. Never substitutesub, which is an account identifier.
- CommonJS (
"type": "commonjs"). The SDK is consumed by both CJS and ESM projects. - Biome for linting and formatting (config at monorepo root).
viemis an optional peer dependency — the main entry point uses ethers;@opensea/sdk/viemis the viem entry point.- Amounts use the
Amounttype (string | number | bigint). Preferstringfor decimal values to avoid floating-point precision issues. - The
Chainenum uses API slug strings (e.g."ethereum","base"), not numeric chain IDs.
- Unit tests (
test/): Mock API responses, test order construction and parameter validation. - Integration tests (
test/integration/): Hit the real API. RequireOPENSEA_API_KEYenv var. Run separately withpnpm run test:integration. - Always run
pnpm run check-types— it uses a stricter tsconfig than the build.