@opensea/cli 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +51 -6
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/client.ts","../src/commands/accounts.ts","../src/toon.ts","../src/output.ts","../src/parse.ts","../src/commands/chains.ts","../src/commands/collections.ts","../src/commands/drops.ts","../src/commands/events.ts","../src/commands/health.ts","../src/health.ts","../src/commands/listings.ts","../src/commands/nfts.ts","../src/commands/offers.ts","../src/commands/search.ts","../src/commands/swaps.ts","../src/wallet/fireblocks.generated.ts","../src/wallet/fireblocks.ts","../src/wallet/private-key.ts","../src/wallet/privy.ts","../src/wallet/turnkey.ts","../src/wallet/chains.generated.ts","../src/wallet/index.ts","../src/sdk.ts","../src/commands/tokens.ts"],"sourcesContent":["import { Command } from \"commander\"\nimport { OpenSeaAPIError, OpenSeaClient } from \"./client.js\"\nimport {\n accountsCommand,\n chainsCommand,\n collectionsCommand,\n dropsCommand,\n eventsCommand,\n healthCommand,\n listingsCommand,\n nftsCommand,\n offersCommand,\n searchCommand,\n swapsCommand,\n tokensCommand,\n} from \"./commands/index.js\"\nimport { type OutputFormat, setOutputOptions } from \"./output.js\"\nimport { parseIntOption } from \"./parse.js\"\n\nconst EXIT_API_ERROR = 1\nconst EXIT_AUTH_ERROR = 2\nconst EXIT_RATE_LIMITED = 3\n\nconst BANNER = `\n ____ _____\n / __ \\\\ / ____|\n | | | |_ __ ___ _ _| (___ ___ __ _\n | | | | '_ \\\\ / _ \\\\ '_ \\\\___ \\\\ / _ \\\\/ _\\` |\n | |__| | |_) | __/ | | |___) | __/ (_| |\n \\\\____/| .__/ \\\\___|_| |_|____/ \\\\___|\\\\__,_|\n | |\n |_|\n`\n\nconst program = new Command()\n\nprogram\n .name(\"opensea\")\n .description(\"OpenSea CLI - Query the OpenSea API from the command line\")\n .version(process.env.npm_package_version ?? \"0.0.0\")\n .addHelpText(\"before\", BANNER)\n .option(\"--api-key <key>\", \"OpenSea API key (or set OPENSEA_API_KEY env var)\")\n .option(\"--chain <chain>\", \"Default chain\", \"ethereum\")\n .option(\"--format <format>\", \"Output format (json, table, or toon)\", \"json\")\n .option(\"--base-url <url>\", \"API base URL\")\n .option(\"--timeout <ms>\", \"Request timeout in milliseconds\", \"30000\")\n .option(\"--verbose\", \"Log request and response info to stderr\")\n .option(\n \"--fields <fields>\",\n \"Comma-separated list of fields to include in output\",\n )\n .option(\"--max-lines <lines>\", \"Truncate output after N lines\")\n .option(\"--max-retries <n>\", \"Max retries on 429/5xx (0 to disable)\", \"3\")\n .option(\"--no-retry\", \"Disable request retries\")\n\nfunction getClient(): OpenSeaClient {\n const opts = program.opts<{\n apiKey?: string\n chain: string\n baseUrl?: string\n timeout: string\n verbose?: boolean\n maxRetries: string\n retry: boolean\n }>()\n\n const apiKey = opts.apiKey ?? process.env.OPENSEA_API_KEY\n if (!apiKey) {\n console.error(\n \"Error: API key required. Use --api-key or set OPENSEA_API_KEY environment variable.\",\n )\n process.exit(EXIT_AUTH_ERROR)\n }\n\n const maxRetries = opts.retry\n ? parseIntOption(opts.maxRetries, \"--max-retries\")\n : 0\n\n return new OpenSeaClient({\n apiKey,\n chain: opts.chain,\n baseUrl: opts.baseUrl,\n timeout: parseIntOption(opts.timeout, \"--timeout\"),\n verbose: opts.verbose,\n maxRetries,\n })\n}\n\nfunction getFormat(): OutputFormat {\n const opts = program.opts<{ format: string }>()\n if (opts.format === \"table\") return \"table\"\n if (opts.format === \"toon\") return \"toon\"\n return \"json\"\n}\n\nprogram.hook(\"preAction\", () => {\n const opts = program.opts<{\n fields?: string\n maxLines?: string\n }>()\n let maxLines: number | undefined\n if (opts.maxLines) {\n maxLines = parseIntOption(opts.maxLines, \"--max-lines\")\n if (maxLines < 1) {\n console.error(\"Error: --max-lines must be >= 1\")\n process.exit(2)\n }\n }\n setOutputOptions({\n fields: opts.fields?.split(\",\").map(f => f.trim()),\n maxLines,\n })\n})\n\nprogram.addCommand(chainsCommand(getClient, getFormat))\nprogram.addCommand(collectionsCommand(getClient, getFormat))\nprogram.addCommand(dropsCommand(getClient, getFormat))\nprogram.addCommand(nftsCommand(getClient, getFormat))\nprogram.addCommand(listingsCommand(getClient, getFormat))\nprogram.addCommand(offersCommand(getClient, getFormat))\nprogram.addCommand(eventsCommand(getClient, getFormat))\nprogram.addCommand(accountsCommand(getClient, getFormat))\nprogram.addCommand(tokensCommand(getClient, getFormat))\nprogram.addCommand(searchCommand(getClient, getFormat))\nprogram.addCommand(swapsCommand(getClient, getFormat))\nprogram.addCommand(healthCommand(getClient, getFormat))\n\nasync function main() {\n try {\n await program.parseAsync(process.argv)\n } catch (error) {\n if (error instanceof OpenSeaAPIError) {\n const isRateLimited = error.statusCode === 429\n console.error(\n JSON.stringify(\n {\n error: isRateLimited ? \"Rate Limited\" : \"API Error\",\n status: error.statusCode,\n path: error.path,\n message: error.responseBody,\n },\n null,\n 2,\n ),\n )\n process.exit(isRateLimited ? EXIT_RATE_LIMITED : EXIT_API_ERROR)\n }\n const label =\n error instanceof TypeError ? \"Network Error\" : (error as Error).name\n console.error(\n JSON.stringify(\n {\n error: label,\n message: (error as Error).message,\n },\n null,\n 2,\n ),\n )\n process.exit(EXIT_API_ERROR)\n }\n}\n\nmain()\n","import type { OpenSeaClientConfig } from \"./types/index.js\"\n\ndeclare const __VERSION__: string\n\nconst DEFAULT_BASE_URL = \"https://api.opensea.io\"\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst USER_AGENT = `opensea-cli/${__VERSION__}`\nconst DEFAULT_MAX_RETRIES = 0\nconst DEFAULT_RETRY_BASE_DELAY_MS = 1_000\n\nfunction isRetryableStatus(status: number, method: string): boolean {\n if (status === 429) return true\n return status >= 500 && method === \"GET\"\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (!header) return undefined\n const seconds = Number(header)\n if (!Number.isNaN(seconds)) return seconds * 1000\n const date = Date.parse(header)\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now())\n return undefined\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nexport class OpenSeaClient {\n private apiKey: string\n private baseUrl: string\n private defaultChain: string\n private timeoutMs: number\n private verbose: boolean\n private maxRetries: number\n private retryBaseDelay: number\n\n constructor(config: OpenSeaClientConfig) {\n this.apiKey = config.apiKey\n this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL\n this.defaultChain = config.chain ?? \"ethereum\"\n this.timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS\n this.verbose = config.verbose ?? false\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES\n this.retryBaseDelay = config.retryBaseDelay ?? DEFAULT_RETRY_BASE_DELAY_MS\n }\n\n private get defaultHeaders(): Record<string, string> {\n return {\n Accept: \"application/json\",\n \"User-Agent\": USER_AGENT,\n \"x-api-key\": this.apiKey,\n }\n }\n\n async get<T>(path: string, params?: Record<string, unknown>): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n if (this.verbose) {\n console.error(`[verbose] GET ${url.toString()}`)\n }\n\n const response = await this.fetchWithRetry(\n url.toString(),\n {\n method: \"GET\",\n headers: this.defaultHeaders,\n },\n path,\n )\n\n return response.json() as Promise<T>\n }\n\n async post<T>(\n path: string,\n body?: Record<string, unknown>,\n params?: Record<string, unknown>,\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n const headers: Record<string, string> = { ...this.defaultHeaders }\n\n if (body) {\n headers[\"Content-Type\"] = \"application/json\"\n }\n\n if (this.verbose) {\n console.error(`[verbose] POST ${url.toString()}`)\n }\n\n const response = await this.fetchWithRetry(\n url.toString(),\n {\n method: \"POST\",\n headers,\n body: body ? JSON.stringify(body) : undefined,\n },\n path,\n )\n\n return response.json() as Promise<T>\n }\n\n getDefaultChain(): string {\n return this.defaultChain\n }\n\n getApiKeyPrefix(): string {\n if (this.apiKey.length < 8) return \"***\"\n return `${this.apiKey.slice(0, 4)}...`\n }\n\n private async fetchWithRetry(\n url: string,\n init: RequestInit,\n path: string,\n ): Promise<Response> {\n for (let attempt = 0; ; attempt++) {\n const response = await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.timeoutMs),\n })\n\n if (this.verbose) {\n console.error(`[verbose] ${response.status} ${response.statusText}`)\n }\n\n if (response.ok) {\n return response\n }\n\n const method = init.method ?? \"GET\"\n if (\n attempt < this.maxRetries &&\n isRetryableStatus(response.status, method)\n ) {\n const retryAfterMs = parseRetryAfter(\n response.headers.get(\"Retry-After\"),\n )\n const backoffMs = this.retryBaseDelay * 2 ** attempt\n const jitterMs = Math.random() * this.retryBaseDelay\n const delayMs = Math.max(retryAfterMs ?? 0, backoffMs) + jitterMs\n\n if (this.verbose) {\n console.error(\n `[verbose] Retry ${attempt + 1}/${this.maxRetries} after ${Math.round(delayMs)}ms (status ${response.status})`,\n )\n }\n\n try {\n await response.body?.cancel()\n } catch {\n // Stream may already be disturbed\n }\n await sleep(delayMs)\n continue\n }\n\n const text = await response.text()\n throw new OpenSeaAPIError(response.status, text, path)\n }\n }\n}\n\nexport class OpenSeaAPIError extends Error {\n constructor(\n public statusCode: number,\n public responseBody: string,\n public path: string,\n ) {\n super(`OpenSea API error ${statusCode} on ${path}: ${responseBody}`)\n this.name = \"OpenSeaAPIError\"\n }\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type {\n Account,\n AccountResolveResponse,\n TokenBalancePaginatedResponse,\n TokenBalanceSortBy,\n} from \"../types/index.js\"\n\nexport function accountsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"accounts\").description(\"Query accounts\")\n\n cmd\n .command(\"get\")\n .description(\"Get an account by address\")\n .argument(\"<address>\", \"Wallet address\")\n .action(async (address: string) => {\n const client = getClient()\n const result = await client.get<Account>(`/api/v2/accounts/${address}`)\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"tokens\")\n .description(\"Get token balances for an account\")\n .argument(\"<address>\", \"Wallet address\")\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\n \"--sort-by <field>\",\n \"Sort by field (USD_VALUE, MARKET_CAP, ONE_DAY_VOLUME, PRICE, ONE_DAY_PRICE_CHANGE, SEVEN_DAY_PRICE_CHANGE)\",\n )\n .option(\"--sort-direction <dir>\", \"Sort direction (asc, desc)\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .option(\"--no-spam-filter\", \"Disable spam token filtering\")\n .action(\n async (\n address: string,\n options: {\n chains?: string\n limit: string\n sortBy?: string\n sortDirection?: string\n next?: string\n spamFilter: boolean\n },\n ) => {\n const client = getClient()\n const result = await client.get<TokenBalancePaginatedResponse>(\n `/api/v2/account/${address}/tokens`,\n {\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n sort_by: options.sortBy as TokenBalanceSortBy | undefined,\n sort_direction: options.sortDirection,\n cursor: options.next,\n disable_spam_filtering: options.spamFilter ? undefined : true,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"resolve\")\n .description(\n \"Resolve an ENS name, OpenSea username, or wallet address to canonical account info\",\n )\n .argument(\n \"<identifier>\",\n \"ENS name (e.g. vitalik.eth), OpenSea username, or wallet address\",\n )\n .action(async (identifier: string) => {\n const client = getClient()\n const result = await client.get<AccountResolveResponse>(\n `/api/v2/accounts/resolve/${identifier}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n","const INDENT = \" \"\n\nconst NUMERIC_RE = /^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i\nconst LEADING_ZERO_RE = /^0\\d+$/\nconst UNQUOTED_KEY_RE = /^[A-Za-z_][A-Za-z0-9_.]*$/\n\nfunction escapeString(s: string): string {\n return s\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n}\n\nfunction needsQuoting(value: string, delimiter: string): boolean {\n if (value === \"\") return true\n if (value !== value.trim()) return true\n if (value === \"true\" || value === \"false\" || value === \"null\") return true\n if (NUMERIC_RE.test(value) || LEADING_ZERO_RE.test(value)) return true\n if (/[:\"\\\\[\\]{}]/.test(value)) return true\n if (/[\\n\\r\\t]/.test(value)) return true\n if (value.includes(delimiter)) return true\n if (value.startsWith(\"-\")) return true\n return false\n}\n\nfunction encodeKey(key: string): string {\n if (UNQUOTED_KEY_RE.test(key)) return key\n return `\"${escapeString(key)}\"`\n}\n\nfunction encodePrimitive(value: unknown, delimiter: string): string {\n if (value === null) return \"null\"\n if (value === undefined) return \"null\"\n if (typeof value === \"boolean\") return String(value)\n if (typeof value === \"number\") return String(value)\n if (typeof value === \"string\") {\n if (needsQuoting(value, delimiter)) {\n return `\"${escapeString(value)}\"`\n }\n return value\n }\n return `\"${escapeString(String(value))}\"`\n}\n\nfunction isPrimitive(value: unknown): boolean {\n return (\n value === null ||\n value === undefined ||\n typeof value === \"boolean\" ||\n typeof value === \"number\" ||\n typeof value === \"string\"\n )\n}\n\nfunction isTabular(arr: unknown[]): boolean {\n if (arr.length === 0) return false\n const first = arr[0]\n if (first === null || typeof first !== \"object\" || Array.isArray(first))\n return false\n const keys = Object.keys(first as Record<string, unknown>).sort()\n for (const item of arr) {\n if (item === null || typeof item !== \"object\" || Array.isArray(item))\n return false\n const itemKeys = Object.keys(item as Record<string, unknown>).sort()\n if (itemKeys.length !== keys.length) return false\n for (let i = 0; i < keys.length; i++) {\n if (itemKeys[i] !== keys[i]) return false\n }\n for (const k of keys) {\n if (!isPrimitive((item as Record<string, unknown>)[k])) return false\n }\n }\n return true\n}\n\nfunction isPrimitiveArray(arr: unknown[]): boolean {\n return arr.every(isPrimitive)\n}\n\nfunction encodeValue(value: unknown, depth: number, delimiter: string): string {\n if (isPrimitive(value)) {\n return encodePrimitive(value, delimiter)\n }\n\n if (Array.isArray(value)) {\n return encodeArray(value, depth, delimiter)\n }\n\n if (typeof value === \"object\" && value !== null) {\n return encodeObject(value as Record<string, unknown>, depth, delimiter)\n }\n\n return encodePrimitive(value, delimiter)\n}\n\nfunction encodeObject(\n obj: Record<string, unknown>,\n depth: number,\n delimiter: string,\n): string {\n const entries = Object.entries(obj)\n if (entries.length === 0) return \"\"\n\n const lines: string[] = []\n const prefix = INDENT.repeat(depth)\n\n for (const [key, value] of entries) {\n const encodedKey = encodeKey(key)\n\n if (isPrimitive(value)) {\n lines.push(`${prefix}${encodedKey}: ${encodePrimitive(value, delimiter)}`)\n } else if (Array.isArray(value)) {\n lines.push(encodeArrayField(encodedKey, value, depth, delimiter))\n } else if (typeof value === \"object\" && value !== null) {\n const nested = value as Record<string, unknown>\n if (Object.keys(nested).length === 0) {\n lines.push(`${prefix}${encodedKey}:`)\n } else {\n lines.push(`${prefix}${encodedKey}:`)\n lines.push(encodeObject(nested, depth + 1, delimiter))\n }\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction encodeArrayField(\n encodedKey: string,\n arr: unknown[],\n depth: number,\n delimiter: string,\n): string {\n const prefix = INDENT.repeat(depth)\n\n if (arr.length === 0) {\n return `${prefix}${encodedKey}[0]:`\n }\n\n if (isPrimitiveArray(arr)) {\n const values = arr.map(v => encodePrimitive(v, delimiter)).join(delimiter)\n return `${prefix}${encodedKey}[${arr.length}]: ${values}`\n }\n\n if (isTabular(arr)) {\n const firstObj = arr[0] as Record<string, unknown>\n const fields = Object.keys(firstObj)\n const fieldHeader = fields.map(encodeKey).join(delimiter)\n const lines: string[] = []\n lines.push(`${prefix}${encodedKey}[${arr.length}]{${fieldHeader}}:`)\n const rowPrefix = INDENT.repeat(depth + 1)\n for (const item of arr) {\n const obj = item as Record<string, unknown>\n const row = fields\n .map(f => encodePrimitive(obj[f], delimiter))\n .join(delimiter)\n lines.push(`${rowPrefix}${row}`)\n }\n return lines.join(\"\\n\")\n }\n\n return encodeExpandedList(encodedKey, arr, depth, delimiter)\n}\n\nfunction encodeExpandedList(\n encodedKey: string,\n arr: unknown[],\n depth: number,\n delimiter: string,\n): string {\n const prefix = INDENT.repeat(depth)\n const itemPrefix = INDENT.repeat(depth + 1)\n const lines: string[] = []\n lines.push(`${prefix}${encodedKey}[${arr.length}]:`)\n\n for (const item of arr) {\n if (isPrimitive(item)) {\n lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`)\n } else if (Array.isArray(item)) {\n if (isPrimitiveArray(item)) {\n const values = item\n .map(v => encodePrimitive(v, delimiter))\n .join(delimiter)\n lines.push(`${itemPrefix}- [${item.length}]: ${values}`)\n } else {\n lines.push(`${itemPrefix}- [${item.length}]:`)\n for (const inner of item) {\n lines.push(encodeValue(inner, depth + 2, delimiter))\n }\n }\n } else if (typeof item === \"object\" && item !== null) {\n const obj = item as Record<string, unknown>\n const entries = Object.entries(obj)\n if (entries.length === 0) {\n lines.push(`${itemPrefix}-`)\n } else {\n const [firstKey, firstValue] = entries[0]\n const ek = encodeKey(firstKey)\n\n if (Array.isArray(firstValue)) {\n const arrayLine = encodeArrayField(ek, firstValue, 0, delimiter)\n lines.push(`${itemPrefix}- ${arrayLine.trimStart()}`)\n } else if (isPrimitive(firstValue)) {\n lines.push(\n `${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`,\n )\n } else {\n lines.push(`${itemPrefix}- ${ek}:`)\n lines.push(\n encodeObject(\n firstValue as Record<string, unknown>,\n depth + 2,\n delimiter,\n ),\n )\n }\n\n for (let i = 1; i < entries.length; i++) {\n const [k, v] = entries[i]\n const encodedK = encodeKey(k)\n if (isPrimitive(v)) {\n lines.push(\n `${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`,\n )\n } else if (Array.isArray(v)) {\n lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter))\n } else if (typeof v === \"object\" && v !== null) {\n lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`)\n lines.push(\n encodeObject(v as Record<string, unknown>, depth + 3, delimiter),\n )\n }\n }\n }\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction encodeArray(arr: unknown[], depth: number, delimiter: string): string {\n const prefix = INDENT.repeat(depth)\n\n if (arr.length === 0) {\n return `${prefix}[0]:`\n }\n\n if (isPrimitiveArray(arr)) {\n const values = arr.map(v => encodePrimitive(v, delimiter)).join(delimiter)\n return `${prefix}[${arr.length}]: ${values}`\n }\n\n if (isTabular(arr)) {\n const firstObj = arr[0] as Record<string, unknown>\n const fields = Object.keys(firstObj)\n const fieldHeader = fields.map(encodeKey).join(delimiter)\n const lines: string[] = []\n lines.push(`${prefix}[${arr.length}]{${fieldHeader}}:`)\n const rowPrefix = INDENT.repeat(depth + 1)\n for (const item of arr) {\n const obj = item as Record<string, unknown>\n const row = fields\n .map(f => encodePrimitive(obj[f], delimiter))\n .join(delimiter)\n lines.push(`${rowPrefix}${row}`)\n }\n return lines.join(\"\\n\")\n }\n\n const lines: string[] = []\n lines.push(`${prefix}[${arr.length}]:`)\n const itemPrefix = INDENT.repeat(depth + 1)\n for (const item of arr) {\n if (isPrimitive(item)) {\n lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`)\n } else if (Array.isArray(item)) {\n if (isPrimitiveArray(item)) {\n const values = item\n .map(v => encodePrimitive(v, delimiter))\n .join(delimiter)\n lines.push(`${itemPrefix}- [${item.length}]: ${values}`)\n } else {\n lines.push(`${itemPrefix}- [${item.length}]:`)\n }\n } else if (typeof item === \"object\" && item !== null) {\n const obj = item as Record<string, unknown>\n const entries = Object.entries(obj)\n if (entries.length > 0) {\n const [firstKey, firstValue] = entries[0]\n const ek = encodeKey(firstKey)\n if (isPrimitive(firstValue)) {\n lines.push(\n `${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`,\n )\n } else {\n lines.push(`${itemPrefix}- ${ek}:`)\n lines.push(encodeValue(firstValue, depth + 2, delimiter))\n }\n for (let i = 1; i < entries.length; i++) {\n const [k, v] = entries[i]\n const encodedK = encodeKey(k)\n if (isPrimitive(v)) {\n lines.push(\n `${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`,\n )\n } else if (Array.isArray(v)) {\n lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter))\n } else if (typeof v === \"object\" && v !== null) {\n lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`)\n lines.push(\n encodeObject(v as Record<string, unknown>, depth + 3, delimiter),\n )\n }\n }\n }\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nexport function formatToon(data: unknown): string {\n if (isPrimitive(data)) {\n return encodePrimitive(data, \",\")\n }\n\n if (Array.isArray(data)) {\n return encodeArray(data, 0, \",\")\n }\n\n if (typeof data === \"object\" && data !== null) {\n return encodeObject(data as Record<string, unknown>, 0, \",\")\n }\n\n return String(data)\n}\n","import { formatToon } from \"./toon.js\"\n\nexport type OutputFormat = \"json\" | \"table\" | \"toon\"\n\nexport interface OutputOptions {\n fields?: string[]\n maxLines?: number\n}\n\nlet _outputOptions: OutputOptions = {}\n\nexport function setOutputOptions(options: OutputOptions): void {\n _outputOptions = options\n}\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n const processed = _outputOptions.fields\n ? filterFields(data, _outputOptions.fields)\n : data\n\n let result: string\n if (format === \"table\") {\n result = formatTable(processed)\n } else if (format === \"toon\") {\n result = formatToon(processed)\n } else {\n result = JSON.stringify(processed, null, 2)\n }\n\n if (_outputOptions.maxLines != null) {\n result = truncateOutput(result, _outputOptions.maxLines)\n }\n\n return result\n}\n\nfunction formatTable(data: unknown): string {\n if (Array.isArray(data)) {\n if (data.length === 0) return \"(empty)\"\n const keys = Object.keys(data[0] as Record<string, unknown>)\n const widths = keys.map(key =>\n Math.max(\n key.length,\n ...data.map(row => {\n const val = (row as Record<string, unknown>)[key]\n return String(val ?? \"\").length\n }),\n ),\n )\n\n const header = keys.map((key, i) => key.padEnd(widths[i])).join(\" \")\n const separator = widths.map(w => \"-\".repeat(w)).join(\" \")\n const rows = data.map(row =>\n keys\n .map((key, i) => {\n const val = (row as Record<string, unknown>)[key]\n return String(val ?? \"\").padEnd(widths[i])\n })\n .join(\" \"),\n )\n\n return [header, separator, ...rows].join(\"\\n\")\n }\n\n if (data && typeof data === \"object\") {\n const entries = Object.entries(data as Record<string, unknown>)\n if (entries.length === 0) return \"(empty)\"\n const maxKeyLength = Math.max(...entries.map(([k]) => k.length))\n return entries\n .map(([key, value]) => {\n const displayValue =\n typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value ?? \"\")\n return `${key.padEnd(maxKeyLength)} ${displayValue}`\n })\n .join(\"\\n\")\n }\n\n return String(data)\n}\n\nfunction pickFields(\n obj: Record<string, unknown>,\n fields: string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n for (const field of fields) {\n if (field in obj) {\n result[field] = obj[field]\n }\n }\n return result\n}\n\nfunction filterFields(data: unknown, fields: string[]): unknown {\n if (Array.isArray(data)) {\n return data.map(item => filterFields(item, fields))\n }\n if (data && typeof data === \"object\") {\n return pickFields(data as Record<string, unknown>, fields)\n }\n return data\n}\n\nfunction truncateOutput(text: string, maxLines: number): string {\n const lines = text.split(\"\\n\")\n if (lines.length <= maxLines) return text\n const omitted = lines.length - maxLines\n return (\n lines.slice(0, maxLines).join(\"\\n\") +\n `\\n... (${omitted} more line${omitted === 1 ? \"\" : \"s\"})`\n )\n}\n","export function parseIntOption(value: string, name: string): number {\n const parsed = Number.parseInt(value, 10)\n if (Number.isNaN(parsed)) {\n throw new Error(`Invalid value for ${name}: \"${value}\" is not an integer`)\n }\n return parsed\n}\n\nexport function parseFloatOption(value: string, name: string): number {\n const parsed = Number.parseFloat(value)\n if (Number.isNaN(parsed)) {\n throw new Error(`Invalid value for ${name}: \"${value}\" is not a number`)\n }\n return parsed\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport type { ChainListResponse } from \"../types/index.js\"\n\nexport function chainsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"chains\").description(\"Query supported blockchains\")\n\n cmd\n .command(\"list\")\n .description(\"List all supported blockchains and their capabilities\")\n .action(async () => {\n const client = getClient()\n const result = await client.get<ChainListResponse>(\"/api/v2/chains\")\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type {\n Chain,\n Collection,\n CollectionOrderBy,\n CollectionPaginatedResponse,\n CollectionStats,\n GetTraitsResponse,\n} from \"../types/index.js\"\n\nexport function collectionsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"collections\").description(\n \"Manage and query NFT collections\",\n )\n\n cmd\n .command(\"get\")\n .description(\"Get a single collection by slug\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<Collection>(`/api/v2/collections/${slug}`)\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"list\")\n .description(\"List collections\")\n .option(\"--chain <chain>\", \"Filter by chain\")\n .option(\n \"--order-by <orderBy>\",\n \"Order by field (created_date, one_day_change, seven_day_volume, seven_day_change, num_owners, market_cap)\",\n )\n .option(\"--creator <username>\", \"Filter by creator username\")\n .option(\"--include-hidden\", \"Include hidden collections\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n chain?: string\n orderBy?: string\n creator?: string\n includeHidden?: boolean\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<{\n collections: Collection[]\n next?: string\n }>(\"/api/v2/collections\", {\n chain: options.chain as Chain | undefined,\n order_by: options.orderBy as CollectionOrderBy | undefined,\n creator_username: options.creator,\n include_hidden: options.includeHidden,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"stats\")\n .description(\"Get collection stats\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<CollectionStats>(\n `/api/v2/collections/${slug}/stats`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"traits\")\n .description(\"Get collection traits\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<GetTraitsResponse>(\n `/api/v2/traits/${slug}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"trending\")\n .description(\"Get trending collections by sales activity\")\n .option(\n \"--timeframe <timeframe>\",\n \"Time window (one_minute, five_minutes, fifteen_minutes, one_hour, one_day, seven_days, thirty_days, one_year, all_time)\",\n \"one_day\",\n )\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\n \"--category <category>\",\n \"Category (art, gaming, memberships, music, pfps, photography, domain-names, virtual-worlds, sports-collectibles)\",\n )\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n timeframe: string\n chains?: string\n category?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<CollectionPaginatedResponse>(\n \"/api/v2/collections/trending\",\n {\n timeframe: options.timeframe,\n chains: options.chains,\n category: options.category,\n limit: parseIntOption(options.limit, \"--limit\"),\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"top\")\n .description(\"Get top collections ranked by volume, sales, or floor price\")\n .option(\n \"--sort-by <field>\",\n \"Sort by (one_day_volume, seven_days_volume, thirty_days_volume, floor_price, one_day_sales, seven_days_sales, thirty_days_sales, total_volume, total_sales)\",\n \"one_day_volume\",\n )\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\n \"--category <category>\",\n \"Category (art, gaming, memberships, music, pfps, photography, domain-names, virtual-worlds, sports-collectibles)\",\n )\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"50\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n sortBy: string\n chains?: string\n category?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<CollectionPaginatedResponse>(\n \"/api/v2/collections/top\",\n {\n sort_by: options.sortBy,\n chains: options.chains,\n category: options.category,\n limit: parseIntOption(options.limit, \"--limit\"),\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type {\n DropDetailedResponse,\n DropMintResponse,\n DropPaginatedResponse,\n} from \"../types/index.js\"\n\nexport function dropsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"drops\").description(\"Query and mint NFT drops\")\n\n cmd\n .command(\"list\")\n .description(\"List drops (featured, upcoming, or recently minted)\")\n .option(\n \"--type <type>\",\n \"Drop type: featured, upcoming, or recently_minted\",\n \"featured\",\n )\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n type: string\n chains?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<DropPaginatedResponse>(\n \"/api/v2/drops\",\n {\n type: options.type,\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"get\")\n .description(\"Get detailed drop info by collection slug\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<DropDetailedResponse>(\n `/api/v2/drops/${slug}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"mint\")\n .description(\"Build a mint transaction for a drop\")\n .argument(\"<slug>\", \"Collection slug\")\n .requiredOption(\"--minter <address>\", \"Wallet address to receive tokens\")\n .option(\"--quantity <n>\", \"Number of tokens to mint\", \"1\")\n .action(\n async (\n slug: string,\n options: {\n minter: string\n quantity: string\n },\n ) => {\n const client = getClient()\n const result = await client.post<DropMintResponse>(\n `/api/v2/drops/${slug}/mint`,\n {\n minter: options.minter,\n quantity: parseIntOption(options.quantity, \"--quantity\"),\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { AssetEvent } from \"../types/index.js\"\n\nexport function eventsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"events\").description(\"Query marketplace events\")\n\n cmd\n .command(\"list\")\n .description(\"List events\")\n .option(\n \"--event-type <type>\",\n \"Event type (sale, transfer, mint, listing, offer, trait_offer, collection_offer)\",\n )\n .option(\"--after <timestamp>\", \"Filter events after this Unix timestamp\")\n .option(\"--before <timestamp>\", \"Filter events before this Unix timestamp\")\n .option(\"--chain <chain>\", \"Filter by chain\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n eventType?: string\n after?: string\n before?: string\n chain?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(\"/api/v2/events\", {\n event_type: options.eventType,\n after: options.after\n ? parseIntOption(options.after, \"--after\")\n : undefined,\n before: options.before\n ? parseIntOption(options.before, \"--before\")\n : undefined,\n chain: options.chain,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"by-account\")\n .description(\"Get events for an account\")\n .argument(\"<address>\", \"Account address\")\n .option(\"--event-type <type>\", \"Event type\")\n .option(\"--chain <chain>\", \"Filter by chain\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n address: string,\n options: {\n eventType?: string\n chain?: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(`/api/v2/events/accounts/${address}`, {\n event_type: options.eventType,\n chain: options.chain,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"by-collection\")\n .description(\"Get events for a collection\")\n .argument(\"<slug>\", \"Collection slug\")\n .option(\"--event-type <type>\", \"Event type\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n slug: string,\n options: {\n eventType?: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(`/api/v2/events/collection/${slug}`, {\n event_type: options.eventType,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"by-nft\")\n .description(\"Get events for a specific NFT\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .option(\"--event-type <type>\", \"Event type\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n chain: string,\n contract: string,\n tokenId: string,\n options: {\n eventType?: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(\n `/api/v2/events/chain/${chain}/contract/${contract}/nfts/${tokenId}`,\n {\n event_type: options.eventType,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport { checkHealth } from \"../health.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\n\nexport function healthCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"health\")\n .description(\"Check API connectivity and authentication\")\n .action(async () => {\n const client = getClient()\n const result = await checkHealth(client)\n console.log(formatOutput(result, getFormat()))\n if (result.status === \"error\") {\n process.exit(result.rate_limited ? 3 : 1)\n }\n })\n\n return cmd\n}\n","import { OpenSeaAPIError, type OpenSeaClient } from \"./client.js\"\nimport type { HealthResult } from \"./types/index.js\"\n\nexport async function checkHealth(\n client: OpenSeaClient,\n): Promise<HealthResult> {\n const keyPrefix = client.getApiKeyPrefix()\n\n // Step 1: Check basic connectivity with a public endpoint\n try {\n await client.get(\"/api/v2/collections\", { limit: 1 })\n } catch (error) {\n let message: string\n if (error instanceof OpenSeaAPIError) {\n message =\n error.statusCode === 429\n ? \"Rate limited: too many requests\"\n : `API error (${error.statusCode}): ${error.responseBody}`\n } else {\n message = `Network error: ${(error as Error).message}`\n }\n return {\n status: \"error\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited:\n error instanceof OpenSeaAPIError && error.statusCode === 429,\n message,\n }\n }\n\n // Step 2: Validate authentication with an endpoint that requires a valid API key\n try {\n await client.get(\"/api/v2/listings/collection/boredapeyachtclub/all\", {\n limit: 1,\n })\n return {\n status: \"ok\",\n key_prefix: keyPrefix,\n authenticated: true,\n rate_limited: false,\n message: \"Connectivity and authentication are working\",\n }\n } catch (error) {\n if (error instanceof OpenSeaAPIError) {\n if (error.statusCode === 429) {\n return {\n status: \"error\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited: true,\n message: \"Rate limited: too many requests\",\n }\n }\n if (error.statusCode === 401 || error.statusCode === 403) {\n return {\n status: \"error\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited: false,\n message: `Authentication failed (${error.statusCode}): invalid API key`,\n }\n }\n }\n // Non-auth error on listings endpoint — connectivity works but auth is unverified\n return {\n status: \"ok\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited: false,\n message:\n \"Connectivity is working but authentication could not be verified\",\n }\n }\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Listing } from \"../types/index.js\"\n\nexport function listingsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"listings\").description(\"Query NFT listings\")\n\n cmd\n .command(\"all\")\n .description(\"Get all listings for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n listings: Listing[]\n next?: string\n }>(`/api/v2/listings/collection/${collection}/all`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"best\")\n .description(\"Get best listings for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n listings: Listing[]\n next?: string\n }>(`/api/v2/listings/collection/${collection}/best`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"best-for-nft\")\n .description(\"Get best listing for a specific NFT\")\n .argument(\"<collection>\", \"Collection slug\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (collection: string, tokenId: string) => {\n const client = getClient()\n const result = await client.get<Listing>(\n `/api/v2/listings/collection/${collection}/nfts/${tokenId}/best`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Contract, NFT, ValidateMetadataResponse } from \"../types/index.js\"\n\nexport function nftsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"nfts\").description(\"Query NFTs\")\n\n cmd\n .command(\"get\")\n .description(\"Get a single NFT\")\n .argument(\"<chain>\", \"Chain (e.g. ethereum, base)\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (chain: string, contract: string, tokenId: string) => {\n const client = getClient()\n const result = await client.get<{ nft: NFT }>(\n `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"list-by-collection\")\n .description(\"List NFTs in a collection\")\n .argument(\"<slug>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(async (slug: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{ nfts: NFT[]; next?: string }>(\n `/api/v2/collection/${slug}/nfts`,\n {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"list-by-contract\")\n .description(\"List NFTs by contract address\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n chain: string,\n contract: string,\n options: { limit: string; next?: string },\n ) => {\n const client = getClient()\n const result = await client.get<{ nfts: NFT[]; next?: string }>(\n `/api/v2/chain/${chain}/contract/${contract}/nfts`,\n {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"list-by-account\")\n .description(\"List NFTs owned by an account\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<address>\", \"Account address\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n chain: string,\n address: string,\n options: { limit: string; next?: string },\n ) => {\n const client = getClient()\n const result = await client.get<{ nfts: NFT[]; next?: string }>(\n `/api/v2/chain/${chain}/account/${address}/nfts`,\n {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"refresh\")\n .description(\"Refresh NFT metadata\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (chain: string, contract: string, tokenId: string) => {\n const client = getClient()\n await client.post(\n `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}/refresh`,\n )\n console.log(\n formatOutput(\n { status: \"ok\", message: \"Metadata refresh requested\" },\n getFormat(),\n ),\n )\n })\n\n cmd\n .command(\"contract\")\n .description(\"Get contract details\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<address>\", \"Contract address\")\n .action(async (chain: string, address: string) => {\n const client = getClient()\n const result = await client.get<Contract>(\n `/api/v2/chain/${chain}/contract/${address}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"validate-metadata\")\n .description(\"Validate NFT metadata by fetching and parsing it\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .option(\n \"--ignore-cache\",\n \"Ignore cached item URLs and re-fetch from source\",\n )\n .action(\n async (\n chain: string,\n contract: string,\n tokenId: string,\n options: { ignoreCache?: boolean },\n ) => {\n const client = getClient()\n const params: Record<string, unknown> = {}\n if (options.ignoreCache) {\n params.ignoreCachedItemUrls = true\n }\n const result = await client.post<ValidateMetadataResponse>(\n `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}/validate-metadata`,\n undefined,\n params,\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Offer } from \"../types/index.js\"\n\nexport function offersCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"offers\").description(\"Query NFT offers\")\n\n cmd\n .command(\"all\")\n .description(\"Get all offers for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n offers: Offer[]\n next?: string\n }>(`/api/v2/offers/collection/${collection}/all`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"collection\")\n .description(\"Get collection offers\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n offers: Offer[]\n next?: string\n }>(`/api/v2/offers/collection/${collection}`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"best-for-nft\")\n .description(\"Get best offer for a specific NFT\")\n .argument(\"<collection>\", \"Collection slug\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (collection: string, tokenId: string) => {\n const client = getClient()\n const result = await client.get<Offer>(\n `/api/v2/offers/collection/${collection}/nfts/${tokenId}/best`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"traits\")\n .description(\"Get trait offers for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .requiredOption(\"--type <type>\", \"Trait type (required)\")\n .requiredOption(\"--value <value>\", \"Trait value (required)\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n collection: string,\n options: {\n type: string\n value: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n offers: Offer[]\n next?: string\n }>(`/api/v2/offers/collection/${collection}/traits`, {\n type: options.type,\n value: options.value,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { SearchResponse } from \"../types/index.js\"\n\nexport function searchCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"search\")\n .description(\"Search across collections, tokens, NFTs, and accounts\")\n .argument(\"<query>\", \"Search query\")\n .option(\n \"--types <types>\",\n \"Filter by type (comma-separated: collection,nft,token,account)\",\n )\n .option(\"--chains <chains>\", \"Filter by chains (comma-separated)\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .action(\n async (\n query: string,\n options: {\n types?: string\n chains?: string\n limit: string\n },\n ) => {\n const client = getClient()\n const params: Record<string, unknown> = {\n query,\n limit: parseIntOption(options.limit, \"--limit\"),\n }\n if (options.types) {\n params.asset_types = options.types\n }\n if (options.chains) {\n params.chains = options.chains\n }\n const result = await client.get<SearchResponse>(\n \"/api/v2/search\",\n params,\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseFloatOption } from \"../parse.js\"\nimport { SwapsAPI } from \"../sdk.js\"\nimport type { SwapQuoteResponse } from \"../types/index.js\"\nimport type { WalletProvider } from \"../wallet/index.js\"\nimport { createWalletFromEnv, WALLET_PROVIDERS } from \"../wallet/index.js\"\n\nexport function swapsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"swaps\").description(\n \"Get swap quotes and execute token swaps\",\n )\n\n cmd\n .command(\"quote\")\n .description(\n \"Get a quote for swapping tokens, including price details and executable transaction data\",\n )\n .requiredOption(\"--from-chain <chain>\", \"Chain of the token to swap from\")\n .requiredOption(\n \"--from-address <address>\",\n \"Contract address of the token to swap from\",\n )\n .requiredOption(\"--to-chain <chain>\", \"Chain of the token to swap to\")\n .requiredOption(\n \"--to-address <address>\",\n \"Contract address of the token to swap to\",\n )\n .requiredOption(\"--quantity <quantity>\", \"Amount to swap (in token units)\")\n .requiredOption(\"--address <address>\", \"Wallet address executing the swap\")\n .option(\n \"--slippage <slippage>\",\n \"Slippage tolerance (0.0 to 0.5, default: 0.01)\",\n )\n .option(\n \"--recipient <recipient>\",\n \"Recipient address (defaults to sender address)\",\n )\n .action(\n async (options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n address: string\n slippage?: string\n recipient?: string\n }) => {\n const client = getClient()\n const result = await client.get<SwapQuoteResponse>(\n \"/api/v2/swap/quote\",\n {\n from_chain: options.fromChain,\n from_address: options.fromAddress,\n to_chain: options.toChain,\n to_address: options.toAddress,\n quantity: options.quantity,\n address: options.address,\n slippage: options.slippage\n ? parseFloatOption(options.slippage, \"--slippage\")\n : undefined,\n recipient: options.recipient,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"execute\")\n .description(\n \"Get a swap quote and execute it onchain using a managed wallet. \" +\n \"Supports Privy (default), Turnkey, and Fireblocks providers.\",\n )\n .requiredOption(\"--from-chain <chain>\", \"Chain of the token to swap from\")\n .requiredOption(\n \"--from-address <address>\",\n \"Contract address of the token to swap from\",\n )\n .requiredOption(\"--to-chain <chain>\", \"Chain of the token to swap to\")\n .requiredOption(\n \"--to-address <address>\",\n \"Contract address of the token to swap to\",\n )\n .requiredOption(\"--quantity <quantity>\", \"Amount to swap (in token units)\")\n .option(\n \"--slippage <slippage>\",\n \"Slippage tolerance (0.0 to 0.5, default: 0.01)\",\n )\n .option(\n \"--recipient <recipient>\",\n \"Recipient address (defaults to wallet address)\",\n )\n .option(\n \"--wallet-provider <provider>\",\n `Wallet provider to use (${WALLET_PROVIDERS.join(\", \")})`,\n )\n .option(\"--dry-run\", \"Print quote and transaction details without signing\")\n .action(\n async (options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n slippage?: string\n recipient?: string\n walletProvider?: string\n dryRun?: boolean\n }) => {\n const wallet = createWalletFromEnv(\n options.walletProvider as WalletProvider | undefined,\n )\n const address = await wallet.getAddress()\n console.error(`Using ${wallet.name} wallet: ${address}`)\n\n const swaps = new SwapsAPI(getClient())\n const format = getFormat()\n const slippage = options.slippage\n ? parseFloatOption(options.slippage, \"--slippage\")\n : undefined\n\n if (options.dryRun) {\n const quote = await swaps.quote({\n ...options,\n address,\n slippage,\n })\n console.log(formatOutput(quote, format))\n return\n }\n\n const results = await swaps.execute(\n {\n ...options,\n address,\n slippage,\n },\n wallet,\n {\n onQuote: () =>\n console.error(\n `Quote: ${options.quantity} on ${options.fromChain} → ${options.toChain}`,\n ),\n onSending: tx =>\n console.error(\n `Sending transaction to ${tx.to} on chain ${tx.chain} (${tx.chainId})...`,\n ),\n onSkipped: tx =>\n console.error(\n `Skipping transaction on ${tx.chain}: ${tx.reason}`,\n ),\n },\n )\n\n for (const result of results) {\n console.log(formatOutput({ hash: result.hash }, format))\n }\n },\n )\n\n return cmd\n}\n","/**\n * AUTO-GENERATED by scripts/sync-chains.ts — DO NOT EDIT.\n * Source of truth: OpenSea REST API + scripts/chain-data.json\n * Run `pnpm sync-chains` to regenerate.\n */\n\n/** Map EVM chain IDs to Fireblocks asset IDs. */\nexport const CHAIN_TO_FIREBLOCKS_ASSET: Record<number, string> = {\n 1: \"ETH\",\n 10: \"ETH-OPT\",\n 130: \"UNICHAIN_ETH\",\n 137: \"MATIC_POLYGON\",\n 360: \"SHAPE_ETH\",\n 1329: \"SEI_EVM\",\n 1868: \"SONEIUM_ETH\",\n 2741: \"ABSTRACT_ETH\",\n 8453: \"BASECHAIN_ETH\",\n 33139: \"APE_CHAIN\",\n 42161: \"ETH-AETH\",\n 43114: \"AVAX\",\n 80094: \"BERA_CHAIN\",\n 81457: \"BLAST_ETH\",\n 7777777: \"ZORA_ETH\",\n}\n","/**\n * Fireblocks wallet adapter.\n *\n * Uses Fireblocks' REST API to sign and send transactions through their\n * enterprise-grade custody infrastructure. Fireblocks provides MPC-based\n * key management, transaction policy engine, and multi-level approval\n * workflows suitable for institutional use.\n *\n * Required environment variables:\n * FIREBLOCKS_API_KEY — Fireblocks API key\n * FIREBLOCKS_API_SECRET — Fireblocks API secret (RSA private key, PEM-encoded)\n * FIREBLOCKS_VAULT_ID — Fireblocks vault account ID\n *\n * Optional:\n * FIREBLOCKS_API_BASE_URL — Override the Fireblocks API base URL\n * (default: https://api.fireblocks.io)\n * FIREBLOCKS_ASSET_ID — Override the Fireblocks asset ID\n * (default: ETH — for EVM chains Fireblocks uses\n * asset IDs like ETH, ETH_TEST5, MATIC, etc.)\n *\n * @see https://developers.fireblocks.com/docs/introduction\n * @see https://developers.fireblocks.com/reference/api-overview\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\nimport { CHAIN_TO_FIREBLOCKS_ASSET } from \"./fireblocks.generated.js\"\n\ninterface FireblocksConfig {\n apiKey: string\n apiSecret: string\n vaultId: string\n assetId?: string\n baseUrl?: string\n}\n\nconst FIREBLOCKS_API_BASE = \"https://api.fireblocks.io\"\n\nexport class FireblocksAdapter implements WalletAdapter {\n readonly name = \"fireblocks\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: FireblocksConfig\n private cachedAddress?: string\n\n constructor(config: FireblocksConfig) {\n this.config = config\n }\n\n /**\n * Create a FireblocksAdapter from environment variables.\n * Throws if any required variable is missing.\n */\n static fromEnv(): FireblocksAdapter {\n const apiKey = process.env.FIREBLOCKS_API_KEY\n const apiSecret = process.env.FIREBLOCKS_API_SECRET\n const vaultId = process.env.FIREBLOCKS_VAULT_ID\n\n if (!apiKey) {\n throw new Error(\"FIREBLOCKS_API_KEY environment variable is required\")\n }\n if (!apiSecret) {\n throw new Error(\"FIREBLOCKS_API_SECRET environment variable is required\")\n }\n if (!vaultId) {\n throw new Error(\"FIREBLOCKS_VAULT_ID environment variable is required\")\n }\n\n return new FireblocksAdapter({\n apiKey,\n apiSecret,\n vaultId,\n assetId: process.env.FIREBLOCKS_ASSET_ID,\n baseUrl: process.env.FIREBLOCKS_API_BASE_URL,\n })\n }\n\n private get baseUrl(): string {\n return this.config.baseUrl ?? FIREBLOCKS_API_BASE\n }\n\n /**\n * Create a JWT for Fireblocks API authentication.\n *\n * Fireblocks uses JWT tokens signed with the API secret (RSA private key).\n * The JWT contains the API key as `sub`, a URI claim for the endpoint path,\n * and a body hash for POST requests.\n *\n * @see https://developers.fireblocks.com/reference/signing-a-request-jwt-structure\n */\n private async createJwt(path: string, bodyHash: string): Promise<string> {\n const now = Math.floor(Date.now() / 1000)\n\n const header = { alg: \"RS256\", typ: \"JWT\" }\n const payload = {\n uri: path,\n nonce: crypto.randomUUID(),\n iat: now,\n exp: now + 30,\n sub: this.config.apiKey,\n bodyHash,\n }\n\n const b64url = (obj: unknown) =>\n Buffer.from(JSON.stringify(obj)).toString(\"base64url\")\n\n const unsigned = `${b64url(header)}.${b64url(payload)}`\n\n const key = await crypto.subtle.importKey(\n \"pkcs8\",\n this.pemToBuffer(this.config.apiSecret),\n { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n )\n\n const sig = await crypto.subtle.sign(\n \"RSASSA-PKCS1-v1_5\",\n key,\n new TextEncoder().encode(unsigned),\n )\n\n return `${unsigned}.${Buffer.from(sig).toString(\"base64url\")}`\n }\n\n private pemToBuffer(pem: string): ArrayBuffer {\n const lines = pem\n .replace(/-----BEGIN .*-----/, \"\")\n .replace(/-----END .*-----/, \"\")\n .replace(/\\s/g, \"\")\n const buf = Buffer.from(lines, \"base64\")\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)\n }\n\n private async hashBody(body: string): Promise<string> {\n const hash = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(body),\n )\n return Buffer.from(hash).toString(\"hex\")\n }\n\n private resolveAssetId(chainId: number): string {\n if (this.config.assetId) return this.config.assetId\n const asset = CHAIN_TO_FIREBLOCKS_ASSET[chainId]\n if (!asset) {\n throw new Error(\n `No Fireblocks asset ID mapping for chain ${chainId}. ` +\n `Set FIREBLOCKS_ASSET_ID explicitly or use a supported chain: ${Object.keys(CHAIN_TO_FIREBLOCKS_ASSET).join(\", \")}`,\n )\n }\n return asset\n }\n\n async getAddress(): Promise<string> {\n if (this.cachedAddress) return this.cachedAddress\n\n const assetId = this.config.assetId ?? \"ETH\"\n const path = `/v1/vault/accounts/${this.config.vaultId}/${assetId}/addresses`\n const bodyHash = await this.hashBody(\"\")\n const jwt = await this.createJwt(path, bodyHash)\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n headers: {\n \"X-API-Key\": this.config.apiKey,\n Authorization: `Bearer ${jwt}`,\n },\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Fireblocks getAddress failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as { address: string }[]\n if (!data[0]?.address) {\n throw new Error(\"Fireblocks returned no addresses for vault\")\n }\n this.cachedAddress = data[0].address\n return data[0].address\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n const assetId = this.resolveAssetId(tx.chainId)\n const path = \"/v1/transactions\"\n\n const requestBody = {\n assetId,\n operation: \"CONTRACT_CALL\",\n source: {\n type: \"VAULT_ACCOUNT\",\n id: this.config.vaultId,\n },\n destination: {\n type: \"ONE_TIME_ADDRESS\",\n oneTimeAddress: { address: tx.to },\n },\n amount: tx.value === \"0\" ? \"0\" : tx.value,\n extraParameters: {\n contractCallData: tx.data,\n },\n }\n\n const bodyStr = JSON.stringify(requestBody)\n const bodyHash = await this.hashBody(bodyStr)\n const jwt = await this.createJwt(path, bodyHash)\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.config.apiKey,\n Authorization: `Bearer ${jwt}`,\n },\n body: bodyStr,\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Fireblocks sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as { id: string; txHash?: string }\n\n if (data.txHash) {\n const result = { hash: data.txHash }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n\n // Fireblocks transactions are async — poll until completed\n const result = await this.waitForTransaction(data.id)\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n\n /**\n * Poll a Fireblocks transaction until it reaches a terminal status.\n * Fireblocks MPC signing + broadcast is asynchronous, so the initial\n * POST returns a transaction ID that must be polled for the final hash.\n */\n private async waitForTransaction(txId: string): Promise<TransactionResult> {\n // Default: 60 attempts × 2s = 120s. Override with FIREBLOCKS_MAX_POLL_ATTEMPTS.\n // Note: transactions requiring multi-party approval may exceed this timeout.\n const maxAttempts = process.env.FIREBLOCKS_MAX_POLL_ATTEMPTS\n ? Number.parseInt(process.env.FIREBLOCKS_MAX_POLL_ATTEMPTS, 10)\n : 60\n const pollIntervalMs = 2000\n\n for (let i = 0; i < maxAttempts; i++) {\n const path = `/v1/transactions/${txId}`\n const bodyHash = await this.hashBody(\"\")\n const jwt = await this.createJwt(path, bodyHash)\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n headers: {\n \"X-API-Key\": this.config.apiKey,\n Authorization: `Bearer ${jwt}`,\n },\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Fireblocks poll failed (${response.status}): ${body}`)\n }\n\n const data = (await response.json()) as {\n status: string\n txHash?: string\n }\n\n if (data.status === \"COMPLETED\" && data.txHash) {\n return { hash: data.txHash }\n }\n\n if (\n data.status === \"FAILED\" ||\n data.status === \"REJECTED\" ||\n data.status === \"CANCELLED\" ||\n data.status === \"BLOCKED\"\n ) {\n throw new Error(\n `Fireblocks transaction ${txId} ended with status: ${data.status}`,\n )\n }\n\n await new Promise(resolve => setTimeout(resolve, pollIntervalMs))\n }\n\n throw new Error(\n `Fireblocks transaction ${txId} did not complete within ${(maxAttempts * pollIntervalMs) / 1000}s`,\n )\n }\n}\n","/**\n * Raw private key wallet adapter.\n *\n * WARNING: Using a raw private key is NOT recommended for production use.\n * It provides no spending limits, no destination allowlists, and no\n * human-in-the-loop approval. Prefer Privy, Turnkey, or Fireblocks\n * for managed wallet security.\n *\n * This adapter sends transactions via eth_sendTransaction on the RPC node,\n * which requires the node to manage the key (e.g. Hardhat, Anvil, Ganache).\n * The PRIVATE_KEY env var is validated (format + address derivation) to\n * confirm intent, but is NOT used for signing — the RPC node holds the key\n * and signs server-side. This means this adapter only works with local dev\n * nodes, not production RPC providers like Infura or Alchemy.\n *\n * Required environment variables:\n * PRIVATE_KEY — Hex-encoded private key (validated for format;\n * the RPC node must already have this key imported)\n * RPC_URL — JSON-RPC endpoint URL (must be a local dev node)\n * WALLET_ADDRESS — The wallet address corresponding to the private key\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\n\n/** Known hosted RPC provider hostnames that don't support eth_sendTransaction */\nconst HOSTED_RPC_PROVIDERS = [\n \"infura.io\",\n \"alchemy.com\",\n \"quicknode.com\",\n \"ankr.com\",\n \"cloudflare-eth.com\",\n \"pokt.network\",\n \"blastapi.io\",\n \"chainnodes.org\",\n \"drpc.org\",\n]\n\ninterface PrivateKeyConfig {\n /**\n * The private key hex string. Validated at construction time to confirm\n * the user intends to use raw key mode, but NOT used for signing.\n * The RPC node (Hardhat/Anvil/Ganache) handles signing via eth_sendTransaction.\n */\n privateKey: string\n rpcUrl: string\n walletAddress: string\n}\n\nexport class PrivateKeyAdapter implements WalletAdapter {\n readonly name = \"private-key\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: PrivateKeyConfig\n private hasWarned = false\n\n constructor(config: PrivateKeyConfig) {\n this.config = config\n }\n\n /**\n * Create a PrivateKeyAdapter from environment variables.\n * Validates the private key format and warns if the RPC URL looks\n * like a hosted provider (which won't support eth_sendTransaction).\n */\n static fromEnv(): PrivateKeyAdapter {\n const privateKey = process.env.PRIVATE_KEY\n const rpcUrl = process.env.RPC_URL\n const walletAddress = process.env.WALLET_ADDRESS\n\n if (!privateKey) {\n throw new Error(\"PRIVATE_KEY environment variable is required\")\n }\n if (!rpcUrl) {\n throw new Error(\n \"RPC_URL environment variable is required when using PRIVATE_KEY\",\n )\n }\n if (!walletAddress) {\n throw new Error(\n \"WALLET_ADDRESS environment variable is required when using PRIVATE_KEY\",\n )\n }\n\n // Validate private key format (should be 32 bytes hex, with or without 0x prefix)\n const cleanKey = privateKey.startsWith(\"0x\")\n ? privateKey.slice(2)\n : privateKey\n if (!/^[0-9a-fA-F]{64}$/.test(cleanKey)) {\n throw new Error(\n \"PRIVATE_KEY must be a 32-byte hex string (64 hex characters, with optional 0x prefix)\",\n )\n }\n\n // Warn if RPC URL looks like a hosted provider\n try {\n const host = new URL(rpcUrl).hostname\n const isHosted = HOSTED_RPC_PROVIDERS.some(provider =>\n host.includes(provider),\n )\n if (isHosted) {\n console.warn(\n `WARNING: RPC_URL (${host}) looks like a hosted provider. ` +\n \"The private-key adapter uses eth_sendTransaction which only works \" +\n \"with local dev nodes (Hardhat, Anvil, Ganache). \" +\n \"Hosted providers will reject this call.\",\n )\n }\n } catch {\n // Invalid URL — will fail at sendTransaction time\n }\n\n return new PrivateKeyAdapter({ privateKey, rpcUrl, walletAddress })\n }\n\n async getAddress(): Promise<string> {\n return this.config.walletAddress\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n if (!this.hasWarned) {\n this.hasWarned = true\n console.warn(\n \"WARNING: Using raw PRIVATE_KEY adapter. \" +\n \"This is not recommended for production. \" +\n \"Use --wallet-provider privy|turnkey|fireblocks for managed wallet security.\",\n )\n }\n\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n const response = await fetch(this.config.rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_sendTransaction\",\n params: [\n {\n from: this.config.walletAddress,\n to: tx.to,\n data: tx.data,\n value:\n tx.value === \"0\" ? \"0x0\" : `0x${BigInt(tx.value).toString(16)}`,\n chainId: `0x${tx.chainId.toString(16)}`,\n },\n ],\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Private key sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as {\n result?: string\n error?: { message: string }\n }\n\n if (data.error) {\n throw new Error(\n `Private key sendTransaction RPC error: ${data.error.message}`,\n )\n }\n\n if (!data.result) {\n throw new Error(\"Private key sendTransaction returned no tx hash\")\n }\n\n const result = { hash: data.result }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n}\n","/**\n * Privy wallet adapter.\n *\n * Uses Privy's server-side wallet API to sign and send transactions.\n * Transactions are governed by Privy's programmable policy engine —\n * policies (transaction limits, destination allowlists, chain restrictions)\n * are evaluated in a trusted execution environment before any signing occurs.\n *\n * Required environment variables:\n * PRIVY_APP_ID — Privy application ID\n * PRIVY_APP_SECRET — Privy application secret\n * PRIVY_WALLET_ID — Wallet ID to use for signing\n *\n * @see https://docs.privy.io/wallets/wallets/server-side-access\n * @see https://docs.privy.io/controls/policies/overview\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\n\ninterface PrivyConfig {\n appId: string\n appSecret: string\n walletId: string\n baseUrl?: string\n}\n\nconst PRIVY_API_BASE = \"https://api.privy.io\"\n\nexport class PrivyAdapter implements WalletAdapter {\n readonly name = \"privy\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: PrivyConfig\n private cachedAddress?: string\n\n constructor(config: PrivyConfig) {\n this.config = config\n }\n\n /**\n * Create a PrivyAdapter from environment variables.\n * Throws if any required variable is missing.\n */\n static fromEnv(): PrivyAdapter {\n const appId = process.env.PRIVY_APP_ID\n const appSecret = process.env.PRIVY_APP_SECRET\n const walletId = process.env.PRIVY_WALLET_ID\n\n if (!appId) {\n throw new Error(\"PRIVY_APP_ID environment variable is required\")\n }\n if (!appSecret) {\n throw new Error(\"PRIVY_APP_SECRET environment variable is required\")\n }\n if (!walletId) {\n throw new Error(\"PRIVY_WALLET_ID environment variable is required\")\n }\n\n return new PrivyAdapter({\n appId,\n appSecret,\n walletId,\n baseUrl: process.env.PRIVY_API_BASE_URL,\n })\n }\n\n private get baseUrl(): string {\n return this.config.baseUrl ?? PRIVY_API_BASE\n }\n\n private get authHeaders(): Record<string, string> {\n const credentials = Buffer.from(\n `${this.config.appId}:${this.config.appSecret}`,\n ).toString(\"base64\")\n return {\n Authorization: `Basic ${credentials}`,\n \"privy-app-id\": this.config.appId,\n \"Content-Type\": \"application/json\",\n }\n }\n\n async getAddress(): Promise<string> {\n if (this.cachedAddress) return this.cachedAddress\n\n const response = await fetch(\n `${this.baseUrl}/v1/wallets/${this.config.walletId}`,\n { headers: this.authHeaders },\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Privy getAddress failed (${response.status}): ${body}`)\n }\n\n const data = (await response.json()) as { address: string }\n this.cachedAddress = data.address\n return data.address\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n const caip2 = `eip155:${tx.chainId}`\n\n const response = await fetch(\n `${this.baseUrl}/v1/wallets/${this.config.walletId}/rpc`,\n {\n method: \"POST\",\n headers: this.authHeaders,\n body: JSON.stringify({\n method: \"eth_sendTransaction\",\n caip2,\n params: {\n transaction: {\n to: tx.to,\n data: tx.data,\n value: tx.value,\n },\n },\n }),\n },\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Privy sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as { data: { hash: string } }\n const result = { hash: data.data.hash }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n}\n","/**\n * Turnkey wallet adapter.\n *\n * Uses Turnkey's API to sign and send transactions via their HSM-backed\n * signing infrastructure. Turnkey provides non-custodial key management\n * with policy controls, audit logging, and multi-party approval workflows.\n *\n * Authentication uses Turnkey's stamp scheme: each request body is hashed\n * and signed with a P-256 ECDSA key, then the signature + public key are\n * sent in the X-Stamp header.\n *\n * Required environment variables:\n * TURNKEY_API_PUBLIC_KEY — Turnkey API public key (hex-encoded, compressed or uncompressed)\n * TURNKEY_API_PRIVATE_KEY — Turnkey API private key (hex-encoded P-256 private key)\n * TURNKEY_ORGANIZATION_ID — Turnkey organization ID\n * TURNKEY_WALLET_ADDRESS — Ethereum address managed by Turnkey\n *\n * Required:\n * TURNKEY_RPC_URL — RPC endpoint for gas estimation and broadcast (must match target chain)\n *\n * Optional:\n * TURNKEY_API_BASE_URL — Override the Turnkey API base URL (default: https://api.turnkey.com)\n * TURNKEY_PRIVATE_KEY_ID — Turnkey private key ID (for signing with a specific key)\n *\n * @see https://docs.turnkey.com/\n * @see https://docs.turnkey.com/developer-tools/api-overview/stamps\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\n\ninterface TurnkeyConfig {\n apiPublicKey: string\n apiPrivateKey: string\n organizationId: string\n walletAddress: string\n rpcUrl: string\n privateKeyId?: string\n baseUrl?: string\n}\n\nconst TURNKEY_API_BASE = \"https://api.turnkey.com\"\n\nexport class TurnkeyAdapter implements WalletAdapter {\n readonly name = \"turnkey\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: TurnkeyConfig\n\n constructor(config: TurnkeyConfig) {\n this.config = config\n }\n\n /**\n * Create a TurnkeyAdapter from environment variables.\n * Throws if any required variable is missing.\n */\n static fromEnv(): TurnkeyAdapter {\n const apiPublicKey = process.env.TURNKEY_API_PUBLIC_KEY\n const apiPrivateKey = process.env.TURNKEY_API_PRIVATE_KEY\n const organizationId = process.env.TURNKEY_ORGANIZATION_ID\n const walletAddress = process.env.TURNKEY_WALLET_ADDRESS\n\n if (!apiPublicKey) {\n throw new Error(\"TURNKEY_API_PUBLIC_KEY environment variable is required\")\n }\n if (!apiPrivateKey) {\n throw new Error(\n \"TURNKEY_API_PRIVATE_KEY environment variable is required\",\n )\n }\n if (!organizationId) {\n throw new Error(\n \"TURNKEY_ORGANIZATION_ID environment variable is required\",\n )\n }\n if (!walletAddress) {\n throw new Error(\"TURNKEY_WALLET_ADDRESS environment variable is required\")\n }\n\n const rpcUrl = process.env.TURNKEY_RPC_URL\n if (!rpcUrl) {\n throw new Error(\n \"TURNKEY_RPC_URL environment variable is required. \" +\n \"It is used for gas estimation and transaction broadcasting.\",\n )\n }\n\n return new TurnkeyAdapter({\n apiPublicKey,\n apiPrivateKey,\n organizationId,\n walletAddress,\n rpcUrl,\n privateKeyId: process.env.TURNKEY_PRIVATE_KEY_ID,\n baseUrl: process.env.TURNKEY_API_BASE_URL,\n })\n }\n\n private get baseUrl(): string {\n return this.config.baseUrl ?? TURNKEY_API_BASE\n }\n\n /**\n * Sign a Turnkey API request using the API key pair (P-256 ECDSA).\n *\n * Turnkey uses a stamp-based authentication scheme: the request body\n * is hashed with SHA-256 and signed with the P-256 private key. The\n * stamp JSON (publicKey + scheme + signature) is then base64url-encoded\n * and sent in the X-Stamp header.\n *\n * @see https://docs.turnkey.com/developer-tools/api-overview/stamps\n */\n private async stamp(body: string): Promise<string> {\n const encoder = new TextEncoder()\n\n // Hash the body with SHA-256\n const bodyHash = await crypto.subtle.digest(\"SHA-256\", encoder.encode(body))\n\n // Import the P-256 private key\n const keyData = hexToBytes(this.config.apiPrivateKey)\n const cryptoKey = await crypto.subtle.importKey(\n \"pkcs8\",\n derEncodeP256PrivateKey(keyData),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"sign\"],\n )\n\n // Sign the body hash with ECDSA P-256\n // Web Crypto returns IEEE P1363 format (raw r||s, 64 bytes for P-256).\n // Turnkey expects DER-encoded signatures, so we must convert.\n // @see https://github.com/tkhq/sdk/blob/main/packages/api-key-stamper\n const p1363Sig = await crypto.subtle.sign(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n cryptoKey,\n bodyHash,\n )\n\n const derSig = p1363ToDer(new Uint8Array(p1363Sig))\n const signatureHex = bytesToHex(derSig)\n\n // The stamp must be base64url-encoded per Turnkey's spec\n const stampJson = JSON.stringify({\n publicKey: this.config.apiPublicKey,\n scheme: \"SIGNATURE_SCHEME_TK_API_P256\",\n signature: signatureHex,\n })\n\n return Buffer.from(stampJson).toString(\"base64url\")\n }\n\n private async signedRequest(\n path: string,\n body: Record<string, unknown>,\n ): Promise<Response> {\n const bodyStr = JSON.stringify(body)\n const stampValue = await this.stamp(bodyStr)\n\n return fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Stamp\": stampValue,\n },\n body: bodyStr,\n })\n }\n\n async getAddress(): Promise<string> {\n return this.config.walletAddress\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n // Turnkey is a pure signing service — it does NOT estimate gas or fill nonce.\n // We must populate gas fields via RPC before serializing, just like the\n // Turnkey SDK does via ethers provider.populateTransaction().\n // @see https://docs.turnkey.com/company-wallets/code-examples/signing-transactions\n const { rpcUrl } = this.config\n\n const gasParams = await this.estimateGasParams(rpcUrl, tx)\n\n // RLP-serialize the fully-populated unsigned EIP-1559 transaction for Turnkey.\n // Turnkey expects `unsignedTransaction` as hex-encoded RLP (no 0x prefix).\n // @see https://docs.turnkey.com/api-reference/activities/sign-transaction\n const rlpHex = rlpEncodeEip1559Tx({\n chainId: tx.chainId,\n nonce: gasParams.nonce,\n maxPriorityFeePerGas: gasParams.maxPriorityFeePerGas,\n maxFeePerGas: gasParams.maxFeePerGas,\n gasLimit: gasParams.gasLimit,\n to: tx.to,\n data: tx.data,\n value: tx.value,\n })\n\n const signWith = this.config.privateKeyId ?? this.config.walletAddress\n\n const response = await this.signedRequest(\n \"/public/v1/submit/sign_transaction\",\n {\n type: \"ACTIVITY_TYPE_SIGN_TRANSACTION_V2\",\n organizationId: this.config.organizationId,\n timestampMs: Date.now().toString(),\n parameters: {\n signWith,\n type: \"TRANSACTION_TYPE_ETHEREUM\",\n unsignedTransaction: rlpHex,\n },\n },\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Turnkey sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as {\n activity: {\n status: string\n result?: {\n signTransactionResult?: { signedTransaction: string }\n }\n }\n }\n\n const signedTx =\n data.activity.result?.signTransactionResult?.signedTransaction\n if (!signedTx) {\n throw new Error(\n `Turnkey sign transaction did not return a signed payload (activity status: ${data.activity.status})`,\n )\n }\n\n // Broadcast the signed transaction via RPC\n // Turnkey signs but does not broadcast — we must submit via eth_sendRawTransaction\n const rpcResponse = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_sendRawTransaction\",\n params: [signedTx],\n }),\n })\n\n if (!rpcResponse.ok) {\n const rpcBody = await rpcResponse.text()\n throw new Error(\n `Turnkey broadcast failed (${rpcResponse.status}): ${rpcBody}`,\n )\n }\n\n const rpcData = (await rpcResponse.json()) as {\n result?: string\n error?: { message: string }\n }\n\n if (rpcData.error) {\n throw new Error(`Turnkey broadcast RPC error: ${rpcData.error.message}`)\n }\n\n if (!rpcData.result) {\n throw new Error(\"Turnkey broadcast returned no tx hash\")\n }\n\n const result = { hash: rpcData.result }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n\n /**\n * Populate gas parameters via JSON-RPC calls to the target chain.\n * Mirrors what ethers.js provider.populateTransaction() does internally.\n *\n * Makes three parallel RPC calls:\n * - eth_getTransactionCount (nonce)\n * - eth_estimateGas (gasLimit)\n * - eth_maxPriorityFeePerGas + eth_getBlockByNumber (fee data)\n */\n private async estimateGasParams(\n rpcUrl: string,\n tx: TransactionRequest,\n ): Promise<{\n nonce: bigint\n gasLimit: bigint\n maxFeePerGas: bigint\n maxPriorityFeePerGas: bigint\n }> {\n const from = this.config.walletAddress\n const txValue =\n tx.value === \"0\" ? \"0x0\" : `0x${BigInt(tx.value).toString(16)}`\n\n // Batch all RPC calls in parallel for speed\n const [nonceResult, gasEstimateResult, feeDataResult] = await Promise.all([\n this.rpcCall(rpcUrl, \"eth_getTransactionCount\", [from, \"pending\"]),\n this.rpcCall(rpcUrl, \"eth_estimateGas\", [\n {\n from,\n to: tx.to,\n data: tx.data || \"0x\",\n value: txValue,\n },\n ]),\n this.rpcCall(rpcUrl, \"eth_feeHistory\", [1, \"latest\", [50]]),\n ])\n\n const nonce = BigInt(nonceResult as string)\n\n // Add 20% buffer to gas estimate to avoid out-of-gas\n const rawGasLimit = BigInt(gasEstimateResult as string)\n const gasLimit = (rawGasLimit * 120n) / 100n\n\n // Extract fee data from eth_feeHistory\n const feeHistory = feeDataResult as {\n baseFeePerGas: string[]\n reward?: string[][]\n }\n const latestBaseFee = BigInt(\n feeHistory.baseFeePerGas[1] ?? feeHistory.baseFeePerGas[0],\n )\n const maxPriorityFeePerGas = feeHistory.reward?.[0]?.[0]\n ? BigInt(feeHistory.reward[0][0])\n : 1_500_000_000n // 1.5 gwei default\n\n // maxFeePerGas = 2 * baseFee + maxPriorityFeePerGas (same formula as ethers.js)\n const maxFeePerGas = latestBaseFee * 2n + maxPriorityFeePerGas\n\n return { nonce, gasLimit, maxFeePerGas, maxPriorityFeePerGas }\n }\n\n /** Make a single JSON-RPC call */\n private async rpcCall(\n rpcUrl: string,\n method: string,\n params: unknown[],\n ): Promise<unknown> {\n const response = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method,\n params,\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Turnkey RPC ${method} failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as {\n result?: unknown\n error?: { message: string }\n }\n\n if (data.error) {\n throw new Error(`Turnkey RPC ${method} error: ${data.error.message}`)\n }\n\n return data.result\n }\n}\n\n/**\n * RLP-encode an unsigned EIP-1559 (type 2) transaction and return the\n * hex string without 0x prefix, as expected by Turnkey's sign_transaction API.\n *\n * EIP-1559 unsigned tx encoding:\n * 0x02 || RLP([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas,\n * gasLimit, to, value, data, accessList])\n *\n * Gas fields must be populated via RPC before calling this function —\n * Turnkey is a pure signing service and does not estimate gas.\n *\n * @see https://eips.ethereum.org/EIPS/eip-1559\n * @see https://github.com/tkhq/sdk/blob/main/packages/ethers/src/index.ts\n */\nexport function rlpEncodeEip1559Tx(tx: {\n chainId: number\n nonce: bigint\n maxPriorityFeePerGas: bigint\n maxFeePerGas: bigint\n gasLimit: bigint\n to: string\n data: string\n value: string\n}): string {\n const chainIdBytes = bigIntToBytes(BigInt(tx.chainId))\n const nonce = bigIntToBytes(tx.nonce)\n const maxPriorityFeePerGas = bigIntToBytes(tx.maxPriorityFeePerGas)\n const maxFeePerGas = bigIntToBytes(tx.maxFeePerGas)\n const gasLimit = bigIntToBytes(tx.gasLimit)\n const toBytes = hexToBytes(tx.to)\n const valueBytes =\n tx.value === \"0\" ? new Uint8Array(0) : bigIntToBytes(BigInt(tx.value))\n const dataBytes = tx.data ? hexToBytes(tx.data) : new Uint8Array(0)\n\n // RLP-encode the 9-element list\n const fields = [\n rlpEncodeBytes(chainIdBytes),\n rlpEncodeBytes(nonce),\n rlpEncodeBytes(maxPriorityFeePerGas),\n rlpEncodeBytes(maxFeePerGas),\n rlpEncodeBytes(gasLimit),\n rlpEncodeBytes(toBytes),\n rlpEncodeBytes(valueBytes),\n rlpEncodeBytes(dataBytes),\n rlpEncodeList([]), // empty access list\n ]\n\n const rlpList = rlpEncodeList(fields)\n\n // EIP-1559 envelope: 0x02 prefix + RLP list\n const result = new Uint8Array(1 + rlpList.length)\n result[0] = 0x02\n result.set(rlpList, 1)\n\n return bytesToHex(result)\n}\n\n/** RLP-encode a byte array */\nfunction rlpEncodeBytes(bytes: Uint8Array): Uint8Array {\n if (bytes.length === 1 && bytes[0] < 0x80) {\n return bytes\n }\n if (bytes.length === 0) {\n return new Uint8Array([0x80])\n }\n if (bytes.length <= 55) {\n const result = new Uint8Array(1 + bytes.length)\n result[0] = 0x80 + bytes.length\n result.set(bytes, 1)\n return result\n }\n const lenBytes = bigIntToBytes(BigInt(bytes.length))\n const result = new Uint8Array(1 + lenBytes.length + bytes.length)\n result[0] = 0xb7 + lenBytes.length\n result.set(lenBytes, 1)\n result.set(bytes, 1 + lenBytes.length)\n return result\n}\n\n/** RLP-encode a list of already-RLP-encoded items */\nfunction rlpEncodeList(items: Uint8Array[]): Uint8Array {\n let totalLen = 0\n for (const item of items) totalLen += item.length\n\n if (totalLen <= 55) {\n const result = new Uint8Array(1 + totalLen)\n result[0] = 0xc0 + totalLen\n let offset = 1\n for (const item of items) {\n result.set(item, offset)\n offset += item.length\n }\n return result\n }\n\n const lenBytes = bigIntToBytes(BigInt(totalLen))\n const result = new Uint8Array(1 + lenBytes.length + totalLen)\n result[0] = 0xf7 + lenBytes.length\n result.set(lenBytes, 1)\n let offset = 1 + lenBytes.length\n for (const item of items) {\n result.set(item, offset)\n offset += item.length\n }\n return result\n}\n\n/** Convert a BigInt to minimal big-endian byte representation */\nfunction bigIntToBytes(value: bigint): Uint8Array {\n if (value === 0n) return new Uint8Array(0)\n const hex = value.toString(16)\n const padded = hex.length % 2 === 0 ? hex : `0${hex}`\n return hexToBytes(padded)\n}\n\n/** Convert a hex string to Uint8Array */\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex\n const bytes = new Uint8Array(clean.length / 2)\n for (let i = 0; i < clean.length; i += 2) {\n bytes[i / 2] = Number.parseInt(clean.slice(i, i + 2), 16)\n }\n return bytes\n}\n\n/** Convert Uint8Array to hex string */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\")\n}\n\n/**\n * Convert an ECDSA signature from IEEE P1363 format (raw r||s) to DER encoding.\n * Web Crypto's crypto.subtle.sign returns P1363 (64 bytes for P-256: r[32] || s[32]).\n * Turnkey's stamp auth expects DER-encoded signatures (ASN.1 SEQUENCE of two INTEGERs).\n * @see https://github.com/tkhq/sdk/blob/main/packages/api-key-stamper\n */\nexport function p1363ToDer(p1363: Uint8Array): Uint8Array {\n const r = p1363.subarray(0, 32)\n const s = p1363.subarray(32, 64)\n\n const rDer = integerToDer(r)\n const sDer = integerToDer(s)\n\n const seqLen = rDer.length + sDer.length\n const result = new Uint8Array(2 + seqLen)\n result[0] = 0x30 // SEQUENCE tag\n result[1] = seqLen\n result.set(rDer, 2)\n result.set(sDer, 2 + rDer.length)\n return result\n}\n\n/** Encode a big-endian unsigned integer as an ASN.1 DER INTEGER */\nfunction integerToDer(bytes: Uint8Array): Uint8Array {\n // Strip leading zeros\n let start = 0\n while (start < bytes.length - 1 && bytes[start] === 0) start++\n const stripped = bytes.subarray(start)\n\n // If high bit is set, prepend a 0x00 pad byte (ASN.1 INTEGER sign encoding)\n const needsPad = stripped[0] >= 0x80\n const len = stripped.length + (needsPad ? 1 : 0)\n\n const result = new Uint8Array(2 + len)\n result[0] = 0x02 // INTEGER tag\n result[1] = len\n if (needsPad) {\n result[2] = 0x00\n result.set(stripped, 3)\n } else {\n result.set(stripped, 2)\n }\n return result\n}\n\n/**\n * Wrap a raw 32-byte P-256 private key in a PKCS#8 DER envelope.\n * Web Crypto's importKey(\"pkcs8\") requires the DER-encoded structure,\n * not just the raw key bytes.\n */\nfunction derEncodeP256PrivateKey(rawKey: Uint8Array): ArrayBuffer {\n // PKCS#8 header for P-256 (secp256r1) private key\n const header = new Uint8Array([\n 0x30,\n 0x41, // SEQUENCE (65 bytes)\n 0x02,\n 0x01,\n 0x00, // INTEGER 0 (version)\n 0x30,\n 0x13, // SEQUENCE (19 bytes) - AlgorithmIdentifier\n 0x06,\n 0x07, // OID (7 bytes) - id-ecPublicKey\n 0x2a,\n 0x86,\n 0x48,\n 0xce,\n 0x3d,\n 0x02,\n 0x01,\n 0x06,\n 0x08, // OID (8 bytes) - secp256r1\n 0x2a,\n 0x86,\n 0x48,\n 0xce,\n 0x3d,\n 0x03,\n 0x01,\n 0x07,\n 0x04,\n 0x27, // OCTET STRING (39 bytes)\n 0x30,\n 0x25, // SEQUENCE (37 bytes)\n 0x02,\n 0x01,\n 0x01, // INTEGER 1 (version)\n 0x04,\n 0x20, // OCTET STRING (32 bytes) - private key\n ])\n\n const result = new Uint8Array(header.length + rawKey.length)\n result.set(header)\n result.set(rawKey, header.length)\n return result.buffer\n}\n","/**\n * AUTO-GENERATED by scripts/sync-chains.ts — DO NOT EDIT.\n * Source of truth: OpenSea REST API + scripts/chain-data.json\n * Run `pnpm sync-chains` to regenerate.\n */\n\nexport const CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n mainnet: 1,\n optimism: 10,\n unichain: 130,\n polygon: 137,\n matic: 137,\n monad: 143,\n shape: 360,\n flow: 747,\n hyperevm: 999,\n sei: 1329,\n soneium: 1868,\n ronin: 2020,\n abstract: 2741,\n megaeth: 4326,\n somnia: 5031,\n b3: 8333,\n base: 8453,\n ape_chain: 33139,\n apechain: 33139,\n arbitrum: 42161,\n avalanche: 43114,\n gunzilla: 43419,\n ink: 57073,\n animechain: 69000,\n bera_chain: 80094,\n berachain: 80094,\n blast: 81457,\n zora: 7777777,\n}\n\n/**\n * Resolve a chain identifier to a numeric EVM chain ID.\n * Accepts a known chain name (e.g. \"base\") or a numeric string / number.\n */\nexport function resolveChainId(chain: string | number): number {\n if (typeof chain === \"number\") return chain\n const asNum = Number(chain)\n if (!Number.isNaN(asNum) && Number.isInteger(asNum)) return asNum\n const id = CHAIN_IDS[chain]\n if (id === undefined) {\n throw new Error(\n `Unknown chain \"${chain}\". Pass a numeric chain ID or use a known name: ${Object.keys(CHAIN_IDS).join(\", \")}`,\n )\n }\n return id\n}\n","import type { WalletAdapter } from \"./adapter.js\"\nimport { FireblocksAdapter } from \"./fireblocks.js\"\nimport { PrivateKeyAdapter } from \"./private-key.js\"\nimport { PrivyAdapter } from \"./privy.js\"\nimport { TurnkeyAdapter } from \"./turnkey.js\"\n\nexport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\nexport { CHAIN_IDS, resolveChainId } from \"./chains.js\"\nexport { FireblocksAdapter } from \"./fireblocks.js\"\nexport { PrivateKeyAdapter } from \"./private-key.js\"\nexport { PrivyAdapter } from \"./privy.js\"\nexport { TurnkeyAdapter } from \"./turnkey.js\"\n\nexport type WalletProvider = \"privy\" | \"turnkey\" | \"fireblocks\" | \"private-key\"\n\nexport const WALLET_PROVIDERS: WalletProvider[] = [\n \"privy\",\n \"turnkey\",\n \"fireblocks\",\n \"private-key\",\n]\n\n/**\n * Create a WalletAdapter from the current environment.\n *\n * When no provider is specified, auto-detects based on which\n * environment variables are set. Priority: Turnkey > Fireblocks > PrivateKey > Privy.\n * If no provider-specific vars are found, defaults to Privy.\n */\nexport function createWalletFromEnv(provider?: WalletProvider): WalletAdapter {\n if (provider) {\n return createAdapter(provider)\n }\n\n // Auto-detect based on available env vars\n const hasTurnkey =\n !!process.env.TURNKEY_API_PUBLIC_KEY &&\n !!process.env.TURNKEY_ORGANIZATION_ID\n const hasFireblocks =\n !!process.env.FIREBLOCKS_API_KEY && !!process.env.FIREBLOCKS_VAULT_ID\n const hasPrivateKey = !!process.env.PRIVATE_KEY && !!process.env.RPC_URL\n const hasPrivy = !!process.env.PRIVY_APP_ID && !!process.env.PRIVY_APP_SECRET\n\n const detected = [\n hasTurnkey && \"turnkey\",\n hasFireblocks && \"fireblocks\",\n hasPrivateKey && \"private-key\",\n hasPrivy && \"privy\",\n ].filter(Boolean) as WalletProvider[]\n\n if (detected.length > 1) {\n console.warn(\n `WARNING: Multiple wallet providers detected: ${detected.join(\", \")}. ` +\n `Using ${detected[0]}. Set --wallet-provider explicitly to avoid ambiguity.`,\n )\n }\n\n if (hasTurnkey) return TurnkeyAdapter.fromEnv()\n if (hasFireblocks) return FireblocksAdapter.fromEnv()\n if (hasPrivateKey) return PrivateKeyAdapter.fromEnv()\n\n // Default to Privy\n return PrivyAdapter.fromEnv()\n}\n\nfunction createAdapter(provider: WalletProvider): WalletAdapter {\n switch (provider) {\n case \"privy\":\n return PrivyAdapter.fromEnv()\n case \"turnkey\":\n return TurnkeyAdapter.fromEnv()\n case \"fireblocks\":\n return FireblocksAdapter.fromEnv()\n case \"private-key\":\n return PrivateKeyAdapter.fromEnv()\n default:\n throw new Error(\n `Unknown wallet provider \"${provider}\". Valid providers: ${WALLET_PROVIDERS.join(\", \")}`,\n )\n }\n}\n","import { OpenSeaClient } from \"./client.js\"\nimport { checkHealth } from \"./health.js\"\nimport type {\n Account,\n AccountResolveResponse,\n AssetEvent,\n Chain,\n ChainListResponse,\n Collection,\n CollectionOrderBy,\n CollectionPaginatedResponse,\n CollectionStats,\n Contract,\n DropDetailedResponse,\n DropMintResponse,\n DropPaginatedResponse,\n EventType,\n GetTraitsResponse,\n HealthResult,\n Listing,\n NFT,\n Offer,\n OpenSeaClientConfig,\n SearchAssetType,\n SearchResponse,\n SwapQuoteResponse,\n Token,\n TokenBalancePaginatedResponse,\n TokenBalanceSortBy,\n TokenDetails,\n ValidateMetadataResponse,\n} from \"./types/index.js\"\nimport type { TransactionResult, WalletAdapter } from \"./wallet/index.js\"\nimport { resolveChainId } from \"./wallet/index.js\"\n\nexport class OpenSeaCLI {\n private client: OpenSeaClient\n\n readonly chains: ChainsAPI\n readonly collections: CollectionsAPI\n readonly drops: DropsAPI\n readonly nfts: NFTsAPI\n readonly listings: ListingsAPI\n readonly offers: OffersAPI\n readonly events: EventsAPI\n readonly accounts: AccountsAPI\n readonly tokens: TokensAPI\n readonly search: SearchAPI\n readonly swaps: SwapsAPI\n readonly health: HealthAPI\n\n constructor(config: OpenSeaClientConfig) {\n this.client = new OpenSeaClient(config)\n this.chains = new ChainsAPI(this.client)\n this.collections = new CollectionsAPI(this.client)\n this.drops = new DropsAPI(this.client)\n this.nfts = new NFTsAPI(this.client)\n this.listings = new ListingsAPI(this.client)\n this.offers = new OffersAPI(this.client)\n this.events = new EventsAPI(this.client)\n this.accounts = new AccountsAPI(this.client)\n this.tokens = new TokensAPI(this.client)\n this.search = new SearchAPI(this.client)\n this.swaps = new SwapsAPI(this.client)\n this.health = new HealthAPI(this.client)\n }\n}\n\nclass ChainsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async list(): Promise<ChainListResponse> {\n return this.client.get(\"/api/v2/chains\")\n }\n}\n\nclass CollectionsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async get(slug: string): Promise<Collection> {\n return this.client.get<Collection>(`/api/v2/collections/${slug}`)\n }\n\n async list(options?: {\n chain?: Chain\n limit?: number\n next?: string\n orderBy?: CollectionOrderBy\n creatorUsername?: string\n includeHidden?: boolean\n }): Promise<{ collections: Collection[]; next?: string }> {\n return this.client.get(\"/api/v2/collections\", {\n chain: options?.chain,\n limit: options?.limit,\n next: options?.next,\n order_by: options?.orderBy,\n creator_username: options?.creatorUsername,\n include_hidden: options?.includeHidden,\n })\n }\n\n async stats(slug: string): Promise<CollectionStats> {\n return this.client.get<CollectionStats>(`/api/v2/collections/${slug}/stats`)\n }\n\n async traits(slug: string): Promise<GetTraitsResponse> {\n return this.client.get<GetTraitsResponse>(`/api/v2/traits/${slug}`)\n }\n\n async trending(options?: {\n timeframe?: string\n chains?: string[]\n category?: string\n limit?: number\n next?: string\n }): Promise<CollectionPaginatedResponse> {\n return this.client.get(\"/api/v2/collections/trending\", {\n timeframe: options?.timeframe,\n chains: options?.chains?.join(\",\"),\n category: options?.category,\n limit: options?.limit,\n cursor: options?.next,\n })\n }\n\n async top(options?: {\n sortBy?: string\n chains?: string[]\n category?: string\n limit?: number\n next?: string\n }): Promise<CollectionPaginatedResponse> {\n return this.client.get(\"/api/v2/collections/top\", {\n sort_by: options?.sortBy,\n chains: options?.chains?.join(\",\"),\n category: options?.category,\n limit: options?.limit,\n cursor: options?.next,\n })\n }\n}\n\nclass DropsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async list(options?: {\n type?: string\n chains?: string[]\n limit?: number\n next?: string\n }): Promise<DropPaginatedResponse> {\n return this.client.get(\"/api/v2/drops\", {\n type: options?.type,\n chains: options?.chains?.join(\",\"),\n limit: options?.limit,\n cursor: options?.next,\n })\n }\n\n async get(slug: string): Promise<DropDetailedResponse> {\n return this.client.get(`/api/v2/drops/${slug}`)\n }\n\n async mint(\n slug: string,\n options: { minter: string; quantity?: number },\n ): Promise<DropMintResponse> {\n return this.client.post(`/api/v2/drops/${slug}/mint`, {\n minter: options.minter,\n quantity: options.quantity ?? 1,\n })\n }\n}\n\nclass NFTsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async get(\n chain: Chain,\n address: string,\n identifier: string,\n ): Promise<{ nft: NFT }> {\n return this.client.get(\n `/api/v2/chain/${chain}/contract/${address}/nfts/${identifier}`,\n )\n }\n\n async listByCollection(\n slug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ nfts: NFT[]; next?: string }> {\n return this.client.get(`/api/v2/collection/${slug}/nfts`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async listByContract(\n chain: Chain,\n address: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ nfts: NFT[]; next?: string }> {\n return this.client.get(`/api/v2/chain/${chain}/contract/${address}/nfts`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async listByAccount(\n chain: Chain,\n address: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ nfts: NFT[]; next?: string }> {\n return this.client.get(`/api/v2/chain/${chain}/account/${address}/nfts`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async refresh(\n chain: Chain,\n address: string,\n identifier: string,\n ): Promise<void> {\n await this.client.post(\n `/api/v2/chain/${chain}/contract/${address}/nfts/${identifier}/refresh`,\n )\n }\n\n async getContract(chain: Chain, address: string): Promise<Contract> {\n return this.client.get(`/api/v2/chain/${chain}/contract/${address}`)\n }\n\n async validateMetadata(\n chain: Chain,\n address: string,\n identifier: string,\n options?: { ignoreCachedItemUrls?: boolean },\n ): Promise<ValidateMetadataResponse> {\n const params: Record<string, unknown> = {}\n if (options?.ignoreCachedItemUrls) {\n params.ignoreCachedItemUrls = true\n }\n return this.client.post(\n `/api/v2/chain/${chain}/contract/${address}/nfts/${identifier}/validate-metadata`,\n undefined,\n params,\n )\n }\n}\n\nclass ListingsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async all(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ listings: Listing[]; next?: string }> {\n return this.client.get(\n `/api/v2/listings/collection/${collectionSlug}/all`,\n { limit: options?.limit, next: options?.next },\n )\n }\n\n async best(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ listings: Listing[]; next?: string }> {\n return this.client.get(\n `/api/v2/listings/collection/${collectionSlug}/best`,\n { limit: options?.limit, next: options?.next },\n )\n }\n\n async bestForNFT(collectionSlug: string, tokenId: string): Promise<Listing> {\n return this.client.get(\n `/api/v2/listings/collection/${collectionSlug}/nfts/${tokenId}/best`,\n )\n }\n}\n\nclass OffersAPI {\n constructor(private client: OpenSeaClient) {}\n\n async all(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ offers: Offer[]; next?: string }> {\n return this.client.get(`/api/v2/offers/collection/${collectionSlug}/all`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async collection(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ offers: Offer[]; next?: string }> {\n return this.client.get(`/api/v2/offers/collection/${collectionSlug}`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async bestForNFT(collectionSlug: string, tokenId: string): Promise<Offer> {\n return this.client.get(\n `/api/v2/offers/collection/${collectionSlug}/nfts/${tokenId}/best`,\n )\n }\n\n async traits(\n collectionSlug: string,\n options: {\n type: string\n value: string\n limit?: number\n next?: string\n },\n ): Promise<{ offers: Offer[]; next?: string }> {\n return this.client.get(\n `/api/v2/offers/collection/${collectionSlug}/traits`,\n {\n type: options.type,\n value: options.value,\n limit: options.limit,\n next: options.next,\n },\n )\n }\n}\n\nclass EventsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async list(options?: {\n eventType?: EventType\n after?: number\n before?: number\n limit?: number\n next?: string\n chain?: Chain\n }): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(\"/api/v2/events\", {\n event_type: options?.eventType,\n after: options?.after,\n before: options?.before,\n limit: options?.limit,\n next: options?.next,\n chain: options?.chain,\n })\n }\n\n async byAccount(\n address: string,\n options?: {\n eventType?: EventType\n limit?: number\n next?: string\n chain?: Chain\n },\n ): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(`/api/v2/events/accounts/${address}`, {\n event_type: options?.eventType,\n limit: options?.limit,\n next: options?.next,\n chain: options?.chain,\n })\n }\n\n async byCollection(\n collectionSlug: string,\n options?: {\n eventType?: EventType\n limit?: number\n next?: string\n },\n ): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(`/api/v2/events/collection/${collectionSlug}`, {\n event_type: options?.eventType,\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async byNFT(\n chain: Chain,\n address: string,\n identifier: string,\n options?: {\n eventType?: EventType\n limit?: number\n next?: string\n },\n ): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(\n `/api/v2/events/chain/${chain}/contract/${address}/nfts/${identifier}`,\n {\n event_type: options?.eventType,\n limit: options?.limit,\n next: options?.next,\n },\n )\n }\n}\n\nclass AccountsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async get(address: string): Promise<Account> {\n return this.client.get(`/api/v2/accounts/${address}`)\n }\n\n async tokens(\n address: string,\n options?: {\n chains?: string[]\n limit?: number\n sortBy?: TokenBalanceSortBy\n sortDirection?: \"asc\" | \"desc\"\n disableSpamFiltering?: boolean\n next?: string\n },\n ): Promise<TokenBalancePaginatedResponse> {\n return this.client.get(`/api/v2/account/${address}/tokens`, {\n chains: options?.chains?.join(\",\"),\n limit: options?.limit,\n sort_by: options?.sortBy,\n sort_direction: options?.sortDirection,\n disable_spam_filtering: options?.disableSpamFiltering,\n cursor: options?.next,\n })\n }\n\n async resolve(identifier: string): Promise<AccountResolveResponse> {\n return this.client.get(`/api/v2/accounts/resolve/${identifier}`)\n }\n}\n\nclass TokensAPI {\n constructor(private client: OpenSeaClient) {}\n\n async trending(options?: {\n limit?: number\n chains?: string[]\n next?: string\n }): Promise<{ tokens: Token[]; next?: string }> {\n // The tokens API uses \"cursor\" as its query param instead of \"next\".\n // The SDK accepts \"next\" for consistency with all other endpoints.\n return this.client.get(\"/api/v2/tokens/trending\", {\n limit: options?.limit,\n chains: options?.chains?.join(\",\"),\n cursor: options?.next,\n })\n }\n\n async top(options?: {\n limit?: number\n chains?: string[]\n next?: string\n }): Promise<{ tokens: Token[]; next?: string }> {\n // The tokens API uses \"cursor\" as its query param instead of \"next\".\n // The SDK accepts \"next\" for consistency with all other endpoints.\n return this.client.get(\"/api/v2/tokens/top\", {\n limit: options?.limit,\n chains: options?.chains?.join(\",\"),\n cursor: options?.next,\n })\n }\n\n async get(chain: Chain, address: string): Promise<TokenDetails> {\n return this.client.get(`/api/v2/chain/${chain}/token/${address}`)\n }\n}\n\nclass SearchAPI {\n constructor(private client: OpenSeaClient) {}\n\n async query(\n query: string,\n options?: {\n assetTypes?: SearchAssetType[]\n chains?: string[]\n limit?: number\n },\n ): Promise<SearchResponse> {\n return this.client.get<SearchResponse>(\"/api/v2/search\", {\n query,\n asset_types: options?.assetTypes?.join(\",\"),\n chains: options?.chains?.join(\",\"),\n limit: options?.limit,\n })\n }\n}\n\nexport class SwapsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async quote(options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n address: string\n slippage?: number\n recipient?: string\n }): Promise<SwapQuoteResponse> {\n return this.client.get(\"/api/v2/swap/quote\", {\n from_chain: options.fromChain,\n from_address: options.fromAddress,\n to_chain: options.toChain,\n to_address: options.toAddress,\n quantity: options.quantity,\n address: options.address,\n slippage: options.slippage,\n recipient: options.recipient,\n })\n }\n\n /**\n * Get a swap quote and execute all transactions using the provided wallet adapter.\n * Returns an array of transaction results (one per transaction in the quote).\n *\n * @param options - Swap parameters (chains, addresses, quantity, etc.)\n * @param wallet - Wallet adapter to sign and send transactions\n * @param callbacks - Optional callbacks for progress reporting and skipped txs\n */\n async execute(\n options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n slippage?: number\n recipient?: string\n address?: string\n },\n wallet: WalletAdapter,\n callbacks?: {\n onQuote?: (quote: SwapQuoteResponse) => void\n onSending?: (tx: { to: string; chain: string; chainId: number }) => void\n onSkipped?: (tx: { chain: string; reason: string }) => void\n },\n ): Promise<TransactionResult[]> {\n const address = options.address ?? (await wallet.getAddress())\n const quote = await this.quote({ ...options, address })\n\n callbacks?.onQuote?.(quote)\n\n if (!quote.transactions || quote.transactions.length === 0) {\n throw new Error(\n \"Swap quote returned zero transactions — the swap may not be available for these tokens/chains.\",\n )\n }\n\n const results: TransactionResult[] = []\n\n for (const tx of quote.transactions) {\n if (!tx.to) {\n callbacks?.onSkipped?.({\n chain: tx.chain,\n reason: \"missing 'to' address\",\n })\n continue\n }\n const chainId = resolveChainId(tx.chain)\n callbacks?.onSending?.({ to: tx.to, chain: tx.chain, chainId })\n const result = await wallet.sendTransaction({\n to: tx.to,\n data: tx.data,\n value: tx.value ?? \"0\",\n chainId,\n })\n results.push(result)\n }\n\n if (results.length === 0) {\n throw new Error(\n \"All swap transactions were skipped (no valid 'to' addresses). The quote may be malformed.\",\n )\n }\n\n return results\n }\n}\n\nclass HealthAPI {\n constructor(private client: OpenSeaClient) {}\n\n async check(): Promise<HealthResult> {\n return checkHealth(this.client)\n }\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Chain, Token, TokenDetails } from \"../types/index.js\"\n\nexport function tokensCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"tokens\").description(\n \"Query trending tokens, top tokens, and token details\",\n )\n\n cmd\n .command(\"trending\")\n .description(\"Get trending tokens based on OpenSea's trending score\")\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: { chains?: string; limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{ tokens: Token[]; next?: string }>(\n \"/api/v2/tokens/trending\",\n {\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n // Tokens API uses \"cursor\" instead of \"next\" as the query param\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"top\")\n .description(\"Get top tokens ranked by 24-hour trading volume\")\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: { chains?: string; limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{ tokens: Token[]; next?: string }>(\n \"/api/v2/tokens/top\",\n {\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n // Tokens API uses \"cursor\" instead of \"next\" as the query param\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"get\")\n .description(\"Get detailed information about a specific token\")\n .argument(\"<chain>\", \"Blockchain chain\")\n .argument(\"<address>\", \"Token contract address\")\n .action(async (chain: string, address: string) => {\n const client = getClient()\n const result = await client.get<TokenDetails>(\n `/api/v2/chain/${chain as Chain}/token/${address}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n"],"mappings":"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","names":["Command","lines","getClient","getFormat","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","result","result","offset","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/client.ts","../src/commands/accounts.ts","../src/toon.ts","../src/output.ts","../src/parse.ts","../src/commands/chains.ts","../src/commands/collections.ts","../src/commands/drops.ts","../src/commands/events.ts","../src/commands/health.ts","../src/health.ts","../src/commands/listings.ts","../src/commands/nfts.ts","../src/commands/offers.ts","../src/commands/search.ts","../src/commands/swaps.ts","../src/wallet/fireblocks.generated.ts","../src/wallet/fireblocks.ts","../src/wallet/private-key.ts","../src/wallet/privy.ts","../src/wallet/turnkey.ts","../src/wallet/chains.generated.ts","../src/wallet/index.ts","../src/sdk.ts","../src/commands/tokens.ts"],"sourcesContent":["import { Command } from \"commander\"\nimport { OpenSeaAPIError, OpenSeaClient } from \"./client.js\"\nimport {\n accountsCommand,\n chainsCommand,\n collectionsCommand,\n dropsCommand,\n eventsCommand,\n healthCommand,\n listingsCommand,\n nftsCommand,\n offersCommand,\n searchCommand,\n swapsCommand,\n tokensCommand,\n} from \"./commands/index.js\"\nimport { type OutputFormat, setOutputOptions } from \"./output.js\"\nimport { parseIntOption } from \"./parse.js\"\n\ndeclare const __VERSION__: string\n\nconst EXIT_API_ERROR = 1\nconst EXIT_AUTH_ERROR = 2\nconst EXIT_RATE_LIMITED = 3\n\nconst BANNER = `\n ____ _____\n / __ \\\\ / ____|\n | | | |_ __ ___ _ _| (___ ___ __ _\n | | | | '_ \\\\ / _ \\\\ '_ \\\\___ \\\\ / _ \\\\/ _\\` |\n | |__| | |_) | __/ | | |___) | __/ (_| |\n \\\\____/| .__/ \\\\___|_| |_|____/ \\\\___|\\\\__,_|\n | |\n |_|\n`\n\nconst program = new Command()\n\nprogram\n .name(\"opensea\")\n .description(\"OpenSea CLI - Query the OpenSea API from the command line\")\n .version(__VERSION__)\n .addHelpText(\"before\", BANNER)\n .option(\"--api-key <key>\", \"OpenSea API key (or set OPENSEA_API_KEY env var)\")\n .option(\"--chain <chain>\", \"Default chain\", \"ethereum\")\n .option(\"--format <format>\", \"Output format (json, table, or toon)\", \"json\")\n .option(\"--base-url <url>\", \"API base URL\")\n .option(\"--timeout <ms>\", \"Request timeout in milliseconds\", \"30000\")\n .option(\"--verbose\", \"Log request and response info to stderr\")\n .option(\n \"--fields <fields>\",\n \"Comma-separated list of fields to include in output\",\n )\n .option(\"--max-lines <lines>\", \"Truncate output after N lines\")\n .option(\"--max-retries <n>\", \"Max retries on 429/5xx (0 to disable)\", \"3\")\n .option(\"--no-retry\", \"Disable request retries\")\n\nfunction getClient(): OpenSeaClient {\n const opts = program.opts<{\n apiKey?: string\n chain: string\n baseUrl?: string\n timeout: string\n verbose?: boolean\n maxRetries: string\n retry: boolean\n }>()\n\n const apiKey = opts.apiKey ?? process.env.OPENSEA_API_KEY\n if (!apiKey) {\n console.error(\n \"Error: API key required. Use --api-key or set OPENSEA_API_KEY environment variable.\",\n )\n process.exit(EXIT_AUTH_ERROR)\n }\n\n const maxRetries = opts.retry\n ? parseIntOption(opts.maxRetries, \"--max-retries\")\n : 0\n\n return new OpenSeaClient({\n apiKey,\n chain: opts.chain,\n baseUrl: opts.baseUrl,\n timeout: parseIntOption(opts.timeout, \"--timeout\"),\n verbose: opts.verbose,\n maxRetries,\n })\n}\n\nfunction getFormat(): OutputFormat {\n const opts = program.opts<{ format: string }>()\n if (opts.format === \"table\") return \"table\"\n if (opts.format === \"toon\") return \"toon\"\n return \"json\"\n}\n\nprogram.hook(\"preAction\", () => {\n const opts = program.opts<{\n fields?: string\n maxLines?: string\n }>()\n let maxLines: number | undefined\n if (opts.maxLines) {\n maxLines = parseIntOption(opts.maxLines, \"--max-lines\")\n if (maxLines < 1) {\n console.error(\"Error: --max-lines must be >= 1\")\n process.exit(2)\n }\n }\n setOutputOptions({\n fields: opts.fields?.split(\",\").map(f => f.trim()),\n maxLines,\n })\n})\n\nprogram.addCommand(chainsCommand(getClient, getFormat))\nprogram.addCommand(collectionsCommand(getClient, getFormat))\nprogram.addCommand(dropsCommand(getClient, getFormat))\nprogram.addCommand(nftsCommand(getClient, getFormat))\nprogram.addCommand(listingsCommand(getClient, getFormat))\nprogram.addCommand(offersCommand(getClient, getFormat))\nprogram.addCommand(eventsCommand(getClient, getFormat))\nprogram.addCommand(accountsCommand(getClient, getFormat))\nprogram.addCommand(tokensCommand(getClient, getFormat))\nprogram.addCommand(searchCommand(getClient, getFormat))\nprogram.addCommand(swapsCommand(getClient, getFormat))\nprogram.addCommand(healthCommand(getClient, getFormat))\n\nasync function main() {\n try {\n await program.parseAsync(process.argv)\n } catch (error) {\n if (error instanceof OpenSeaAPIError) {\n const isRateLimited = error.statusCode === 429\n console.error(\n JSON.stringify(\n {\n error: isRateLimited ? \"Rate Limited\" : \"API Error\",\n status: error.statusCode,\n path: error.path,\n message: error.responseBody,\n },\n null,\n 2,\n ),\n )\n process.exit(isRateLimited ? EXIT_RATE_LIMITED : EXIT_API_ERROR)\n }\n const label =\n error instanceof TypeError ? \"Network Error\" : (error as Error).name\n console.error(\n JSON.stringify(\n {\n error: label,\n message: (error as Error).message,\n },\n null,\n 2,\n ),\n )\n process.exit(EXIT_API_ERROR)\n }\n}\n\nmain()\n","import type { OpenSeaClientConfig } from \"./types/index.js\"\n\ndeclare const __VERSION__: string\n\nconst DEFAULT_BASE_URL = \"https://api.opensea.io\"\nconst DEFAULT_TIMEOUT_MS = 30_000\nconst USER_AGENT = `opensea-cli/${__VERSION__}`\nconst DEFAULT_MAX_RETRIES = 0\nconst DEFAULT_RETRY_BASE_DELAY_MS = 1_000\n\nfunction isRetryableStatus(status: number, method: string): boolean {\n if (status === 429) return true\n return status >= 500 && method === \"GET\"\n}\n\nfunction parseRetryAfter(header: string | null): number | undefined {\n if (!header) return undefined\n const seconds = Number(header)\n if (!Number.isNaN(seconds)) return seconds * 1000\n const date = Date.parse(header)\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now())\n return undefined\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms))\n}\n\nexport class OpenSeaClient {\n private apiKey: string\n private baseUrl: string\n private defaultChain: string\n private timeoutMs: number\n private verbose: boolean\n private maxRetries: number\n private retryBaseDelay: number\n\n constructor(config: OpenSeaClientConfig) {\n this.apiKey = config.apiKey\n this.baseUrl = config.baseUrl ?? DEFAULT_BASE_URL\n this.defaultChain = config.chain ?? \"ethereum\"\n this.timeoutMs = config.timeout ?? DEFAULT_TIMEOUT_MS\n this.verbose = config.verbose ?? false\n this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES\n this.retryBaseDelay = config.retryBaseDelay ?? DEFAULT_RETRY_BASE_DELAY_MS\n }\n\n private get defaultHeaders(): Record<string, string> {\n return {\n Accept: \"application/json\",\n \"User-Agent\": USER_AGENT,\n \"x-api-key\": this.apiKey,\n }\n }\n\n async get<T>(path: string, params?: Record<string, unknown>): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n if (this.verbose) {\n console.error(`[verbose] GET ${url.toString()}`)\n }\n\n const response = await this.fetchWithRetry(\n url.toString(),\n {\n method: \"GET\",\n headers: this.defaultHeaders,\n },\n path,\n )\n\n return response.json() as Promise<T>\n }\n\n async post<T>(\n path: string,\n body?: Record<string, unknown>,\n params?: Record<string, unknown>,\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n const headers: Record<string, string> = { ...this.defaultHeaders }\n\n if (body) {\n headers[\"Content-Type\"] = \"application/json\"\n }\n\n if (this.verbose) {\n console.error(`[verbose] POST ${url.toString()}`)\n }\n\n const response = await this.fetchWithRetry(\n url.toString(),\n {\n method: \"POST\",\n headers,\n body: body ? JSON.stringify(body) : undefined,\n },\n path,\n )\n\n return response.json() as Promise<T>\n }\n\n getDefaultChain(): string {\n return this.defaultChain\n }\n\n getApiKeyPrefix(): string {\n if (this.apiKey.length < 8) return \"***\"\n return `${this.apiKey.slice(0, 4)}...`\n }\n\n private async fetchWithRetry(\n url: string,\n init: RequestInit,\n path: string,\n ): Promise<Response> {\n for (let attempt = 0; ; attempt++) {\n const response = await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(this.timeoutMs),\n })\n\n if (this.verbose) {\n console.error(`[verbose] ${response.status} ${response.statusText}`)\n }\n\n if (response.ok) {\n return response\n }\n\n const method = init.method ?? \"GET\"\n if (\n attempt < this.maxRetries &&\n isRetryableStatus(response.status, method)\n ) {\n const retryAfterMs = parseRetryAfter(\n response.headers.get(\"Retry-After\"),\n )\n const backoffMs = this.retryBaseDelay * 2 ** attempt\n const jitterMs = Math.random() * this.retryBaseDelay\n const delayMs = Math.max(retryAfterMs ?? 0, backoffMs) + jitterMs\n\n if (this.verbose) {\n console.error(\n `[verbose] Retry ${attempt + 1}/${this.maxRetries} after ${Math.round(delayMs)}ms (status ${response.status})`,\n )\n }\n\n try {\n await response.body?.cancel()\n } catch {\n // Stream may already be disturbed\n }\n await sleep(delayMs)\n continue\n }\n\n const text = await response.text()\n throw new OpenSeaAPIError(response.status, text, path)\n }\n }\n}\n\nexport class OpenSeaAPIError extends Error {\n constructor(\n public statusCode: number,\n public responseBody: string,\n public path: string,\n ) {\n super(`OpenSea API error ${statusCode} on ${path}: ${responseBody}`)\n this.name = \"OpenSeaAPIError\"\n }\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type {\n Account,\n AccountResolveResponse,\n TokenBalancePaginatedResponse,\n TokenBalanceSortBy,\n} from \"../types/index.js\"\n\nexport function accountsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"accounts\").description(\"Query accounts\")\n\n cmd\n .command(\"get\")\n .description(\"Get an account by address\")\n .argument(\"<address>\", \"Wallet address\")\n .action(async (address: string) => {\n const client = getClient()\n const result = await client.get<Account>(`/api/v2/accounts/${address}`)\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"tokens\")\n .description(\"Get token balances for an account\")\n .argument(\"<address>\", \"Wallet address\")\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\n \"--sort-by <field>\",\n \"Sort by field (USD_VALUE, MARKET_CAP, ONE_DAY_VOLUME, PRICE, ONE_DAY_PRICE_CHANGE, SEVEN_DAY_PRICE_CHANGE)\",\n )\n .option(\"--sort-direction <dir>\", \"Sort direction (asc, desc)\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .option(\"--no-spam-filter\", \"Disable spam token filtering\")\n .action(\n async (\n address: string,\n options: {\n chains?: string\n limit: string\n sortBy?: string\n sortDirection?: string\n next?: string\n spamFilter: boolean\n },\n ) => {\n const client = getClient()\n const result = await client.get<TokenBalancePaginatedResponse>(\n `/api/v2/account/${address}/tokens`,\n {\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n sort_by: options.sortBy as TokenBalanceSortBy | undefined,\n sort_direction: options.sortDirection,\n cursor: options.next,\n disable_spam_filtering: options.spamFilter ? undefined : true,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"resolve\")\n .description(\n \"Resolve an ENS name, OpenSea username, or wallet address to canonical account info\",\n )\n .argument(\n \"<identifier>\",\n \"ENS name (e.g. vitalik.eth), OpenSea username, or wallet address\",\n )\n .action(async (identifier: string) => {\n const client = getClient()\n const result = await client.get<AccountResolveResponse>(\n `/api/v2/accounts/resolve/${identifier}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n","const INDENT = \" \"\n\nconst NUMERIC_RE = /^-?\\d+(?:\\.\\d+)?(?:e[+-]?\\d+)?$/i\nconst LEADING_ZERO_RE = /^0\\d+$/\nconst UNQUOTED_KEY_RE = /^[A-Za-z_][A-Za-z0-9_.]*$/\n\nfunction escapeString(s: string): string {\n return s\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n}\n\nfunction needsQuoting(value: string, delimiter: string): boolean {\n if (value === \"\") return true\n if (value !== value.trim()) return true\n if (value === \"true\" || value === \"false\" || value === \"null\") return true\n if (NUMERIC_RE.test(value) || LEADING_ZERO_RE.test(value)) return true\n if (/[:\"\\\\[\\]{}]/.test(value)) return true\n if (/[\\n\\r\\t]/.test(value)) return true\n if (value.includes(delimiter)) return true\n if (value.startsWith(\"-\")) return true\n return false\n}\n\nfunction encodeKey(key: string): string {\n if (UNQUOTED_KEY_RE.test(key)) return key\n return `\"${escapeString(key)}\"`\n}\n\nfunction encodePrimitive(value: unknown, delimiter: string): string {\n if (value === null) return \"null\"\n if (value === undefined) return \"null\"\n if (typeof value === \"boolean\") return String(value)\n if (typeof value === \"number\") return String(value)\n if (typeof value === \"string\") {\n if (needsQuoting(value, delimiter)) {\n return `\"${escapeString(value)}\"`\n }\n return value\n }\n return `\"${escapeString(String(value))}\"`\n}\n\nfunction isPrimitive(value: unknown): boolean {\n return (\n value === null ||\n value === undefined ||\n typeof value === \"boolean\" ||\n typeof value === \"number\" ||\n typeof value === \"string\"\n )\n}\n\nfunction isTabular(arr: unknown[]): boolean {\n if (arr.length === 0) return false\n const first = arr[0]\n if (first === null || typeof first !== \"object\" || Array.isArray(first))\n return false\n const keys = Object.keys(first as Record<string, unknown>).sort()\n for (const item of arr) {\n if (item === null || typeof item !== \"object\" || Array.isArray(item))\n return false\n const itemKeys = Object.keys(item as Record<string, unknown>).sort()\n if (itemKeys.length !== keys.length) return false\n for (let i = 0; i < keys.length; i++) {\n if (itemKeys[i] !== keys[i]) return false\n }\n for (const k of keys) {\n if (!isPrimitive((item as Record<string, unknown>)[k])) return false\n }\n }\n return true\n}\n\nfunction isPrimitiveArray(arr: unknown[]): boolean {\n return arr.every(isPrimitive)\n}\n\nfunction encodeValue(value: unknown, depth: number, delimiter: string): string {\n if (isPrimitive(value)) {\n return encodePrimitive(value, delimiter)\n }\n\n if (Array.isArray(value)) {\n return encodeArray(value, depth, delimiter)\n }\n\n if (typeof value === \"object\" && value !== null) {\n return encodeObject(value as Record<string, unknown>, depth, delimiter)\n }\n\n return encodePrimitive(value, delimiter)\n}\n\nfunction encodeObject(\n obj: Record<string, unknown>,\n depth: number,\n delimiter: string,\n): string {\n const entries = Object.entries(obj)\n if (entries.length === 0) return \"\"\n\n const lines: string[] = []\n const prefix = INDENT.repeat(depth)\n\n for (const [key, value] of entries) {\n const encodedKey = encodeKey(key)\n\n if (isPrimitive(value)) {\n lines.push(`${prefix}${encodedKey}: ${encodePrimitive(value, delimiter)}`)\n } else if (Array.isArray(value)) {\n lines.push(encodeArrayField(encodedKey, value, depth, delimiter))\n } else if (typeof value === \"object\" && value !== null) {\n const nested = value as Record<string, unknown>\n if (Object.keys(nested).length === 0) {\n lines.push(`${prefix}${encodedKey}:`)\n } else {\n lines.push(`${prefix}${encodedKey}:`)\n lines.push(encodeObject(nested, depth + 1, delimiter))\n }\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction encodeArrayField(\n encodedKey: string,\n arr: unknown[],\n depth: number,\n delimiter: string,\n): string {\n const prefix = INDENT.repeat(depth)\n\n if (arr.length === 0) {\n return `${prefix}${encodedKey}[0]:`\n }\n\n if (isPrimitiveArray(arr)) {\n const values = arr.map(v => encodePrimitive(v, delimiter)).join(delimiter)\n return `${prefix}${encodedKey}[${arr.length}]: ${values}`\n }\n\n if (isTabular(arr)) {\n const firstObj = arr[0] as Record<string, unknown>\n const fields = Object.keys(firstObj)\n const fieldHeader = fields.map(encodeKey).join(delimiter)\n const lines: string[] = []\n lines.push(`${prefix}${encodedKey}[${arr.length}]{${fieldHeader}}:`)\n const rowPrefix = INDENT.repeat(depth + 1)\n for (const item of arr) {\n const obj = item as Record<string, unknown>\n const row = fields\n .map(f => encodePrimitive(obj[f], delimiter))\n .join(delimiter)\n lines.push(`${rowPrefix}${row}`)\n }\n return lines.join(\"\\n\")\n }\n\n return encodeExpandedList(encodedKey, arr, depth, delimiter)\n}\n\nfunction encodeExpandedList(\n encodedKey: string,\n arr: unknown[],\n depth: number,\n delimiter: string,\n): string {\n const prefix = INDENT.repeat(depth)\n const itemPrefix = INDENT.repeat(depth + 1)\n const lines: string[] = []\n lines.push(`${prefix}${encodedKey}[${arr.length}]:`)\n\n for (const item of arr) {\n if (isPrimitive(item)) {\n lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`)\n } else if (Array.isArray(item)) {\n if (isPrimitiveArray(item)) {\n const values = item\n .map(v => encodePrimitive(v, delimiter))\n .join(delimiter)\n lines.push(`${itemPrefix}- [${item.length}]: ${values}`)\n } else {\n lines.push(`${itemPrefix}- [${item.length}]:`)\n for (const inner of item) {\n lines.push(encodeValue(inner, depth + 2, delimiter))\n }\n }\n } else if (typeof item === \"object\" && item !== null) {\n const obj = item as Record<string, unknown>\n const entries = Object.entries(obj)\n if (entries.length === 0) {\n lines.push(`${itemPrefix}-`)\n } else {\n const [firstKey, firstValue] = entries[0]\n const ek = encodeKey(firstKey)\n\n if (Array.isArray(firstValue)) {\n const arrayLine = encodeArrayField(ek, firstValue, 0, delimiter)\n lines.push(`${itemPrefix}- ${arrayLine.trimStart()}`)\n } else if (isPrimitive(firstValue)) {\n lines.push(\n `${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`,\n )\n } else {\n lines.push(`${itemPrefix}- ${ek}:`)\n lines.push(\n encodeObject(\n firstValue as Record<string, unknown>,\n depth + 2,\n delimiter,\n ),\n )\n }\n\n for (let i = 1; i < entries.length; i++) {\n const [k, v] = entries[i]\n const encodedK = encodeKey(k)\n if (isPrimitive(v)) {\n lines.push(\n `${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`,\n )\n } else if (Array.isArray(v)) {\n lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter))\n } else if (typeof v === \"object\" && v !== null) {\n lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`)\n lines.push(\n encodeObject(v as Record<string, unknown>, depth + 3, delimiter),\n )\n }\n }\n }\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nfunction encodeArray(arr: unknown[], depth: number, delimiter: string): string {\n const prefix = INDENT.repeat(depth)\n\n if (arr.length === 0) {\n return `${prefix}[0]:`\n }\n\n if (isPrimitiveArray(arr)) {\n const values = arr.map(v => encodePrimitive(v, delimiter)).join(delimiter)\n return `${prefix}[${arr.length}]: ${values}`\n }\n\n if (isTabular(arr)) {\n const firstObj = arr[0] as Record<string, unknown>\n const fields = Object.keys(firstObj)\n const fieldHeader = fields.map(encodeKey).join(delimiter)\n const lines: string[] = []\n lines.push(`${prefix}[${arr.length}]{${fieldHeader}}:`)\n const rowPrefix = INDENT.repeat(depth + 1)\n for (const item of arr) {\n const obj = item as Record<string, unknown>\n const row = fields\n .map(f => encodePrimitive(obj[f], delimiter))\n .join(delimiter)\n lines.push(`${rowPrefix}${row}`)\n }\n return lines.join(\"\\n\")\n }\n\n const lines: string[] = []\n lines.push(`${prefix}[${arr.length}]:`)\n const itemPrefix = INDENT.repeat(depth + 1)\n for (const item of arr) {\n if (isPrimitive(item)) {\n lines.push(`${itemPrefix}- ${encodePrimitive(item, delimiter)}`)\n } else if (Array.isArray(item)) {\n if (isPrimitiveArray(item)) {\n const values = item\n .map(v => encodePrimitive(v, delimiter))\n .join(delimiter)\n lines.push(`${itemPrefix}- [${item.length}]: ${values}`)\n } else {\n lines.push(`${itemPrefix}- [${item.length}]:`)\n }\n } else if (typeof item === \"object\" && item !== null) {\n const obj = item as Record<string, unknown>\n const entries = Object.entries(obj)\n if (entries.length > 0) {\n const [firstKey, firstValue] = entries[0]\n const ek = encodeKey(firstKey)\n if (isPrimitive(firstValue)) {\n lines.push(\n `${itemPrefix}- ${ek}: ${encodePrimitive(firstValue, delimiter)}`,\n )\n } else {\n lines.push(`${itemPrefix}- ${ek}:`)\n lines.push(encodeValue(firstValue, depth + 2, delimiter))\n }\n for (let i = 1; i < entries.length; i++) {\n const [k, v] = entries[i]\n const encodedK = encodeKey(k)\n if (isPrimitive(v)) {\n lines.push(\n `${INDENT.repeat(depth + 2)}${encodedK}: ${encodePrimitive(v, delimiter)}`,\n )\n } else if (Array.isArray(v)) {\n lines.push(encodeArrayField(encodedK, v, depth + 2, delimiter))\n } else if (typeof v === \"object\" && v !== null) {\n lines.push(`${INDENT.repeat(depth + 2)}${encodedK}:`)\n lines.push(\n encodeObject(v as Record<string, unknown>, depth + 3, delimiter),\n )\n }\n }\n }\n }\n }\n\n return lines.join(\"\\n\")\n}\n\nexport function formatToon(data: unknown): string {\n if (isPrimitive(data)) {\n return encodePrimitive(data, \",\")\n }\n\n if (Array.isArray(data)) {\n return encodeArray(data, 0, \",\")\n }\n\n if (typeof data === \"object\" && data !== null) {\n return encodeObject(data as Record<string, unknown>, 0, \",\")\n }\n\n return String(data)\n}\n","import { formatToon } from \"./toon.js\"\n\nexport type OutputFormat = \"json\" | \"table\" | \"toon\"\n\nexport interface OutputOptions {\n fields?: string[]\n maxLines?: number\n}\n\nlet _outputOptions: OutputOptions = {}\n\nexport function setOutputOptions(options: OutputOptions): void {\n _outputOptions = options\n}\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n const processed = _outputOptions.fields\n ? filterFields(data, _outputOptions.fields)\n : data\n\n let result: string\n if (format === \"table\") {\n result = formatTable(processed)\n } else if (format === \"toon\") {\n result = formatToon(processed)\n } else {\n result = JSON.stringify(processed, null, 2)\n }\n\n if (_outputOptions.maxLines != null) {\n result = truncateOutput(result, _outputOptions.maxLines)\n }\n\n return result\n}\n\nfunction formatTable(data: unknown): string {\n if (Array.isArray(data)) {\n if (data.length === 0) return \"(empty)\"\n const keys = Object.keys(data[0] as Record<string, unknown>)\n const widths = keys.map(key =>\n Math.max(\n key.length,\n ...data.map(row => {\n const val = (row as Record<string, unknown>)[key]\n return String(val ?? \"\").length\n }),\n ),\n )\n\n const header = keys.map((key, i) => key.padEnd(widths[i])).join(\" \")\n const separator = widths.map(w => \"-\".repeat(w)).join(\" \")\n const rows = data.map(row =>\n keys\n .map((key, i) => {\n const val = (row as Record<string, unknown>)[key]\n return String(val ?? \"\").padEnd(widths[i])\n })\n .join(\" \"),\n )\n\n return [header, separator, ...rows].join(\"\\n\")\n }\n\n if (data && typeof data === \"object\") {\n const entries = Object.entries(data as Record<string, unknown>)\n if (entries.length === 0) return \"(empty)\"\n const maxKeyLength = Math.max(...entries.map(([k]) => k.length))\n return entries\n .map(([key, value]) => {\n const displayValue =\n typeof value === \"object\" && value !== null\n ? JSON.stringify(value)\n : String(value ?? \"\")\n return `${key.padEnd(maxKeyLength)} ${displayValue}`\n })\n .join(\"\\n\")\n }\n\n return String(data)\n}\n\nfunction pickFields(\n obj: Record<string, unknown>,\n fields: string[],\n): Record<string, unknown> {\n const result: Record<string, unknown> = {}\n for (const field of fields) {\n if (field in obj) {\n result[field] = obj[field]\n }\n }\n return result\n}\n\nfunction filterFields(data: unknown, fields: string[]): unknown {\n if (Array.isArray(data)) {\n return data.map(item => filterFields(item, fields))\n }\n if (data && typeof data === \"object\") {\n return pickFields(data as Record<string, unknown>, fields)\n }\n return data\n}\n\nfunction truncateOutput(text: string, maxLines: number): string {\n const lines = text.split(\"\\n\")\n if (lines.length <= maxLines) return text\n const omitted = lines.length - maxLines\n return (\n lines.slice(0, maxLines).join(\"\\n\") +\n `\\n... (${omitted} more line${omitted === 1 ? \"\" : \"s\"})`\n )\n}\n","export function parseIntOption(value: string, name: string): number {\n const parsed = Number.parseInt(value, 10)\n if (Number.isNaN(parsed)) {\n throw new Error(`Invalid value for ${name}: \"${value}\" is not an integer`)\n }\n return parsed\n}\n\nexport function parseFloatOption(value: string, name: string): number {\n const parsed = Number.parseFloat(value)\n if (Number.isNaN(parsed)) {\n throw new Error(`Invalid value for ${name}: \"${value}\" is not a number`)\n }\n return parsed\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport type { ChainListResponse } from \"../types/index.js\"\n\nexport function chainsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"chains\").description(\"Query supported blockchains\")\n\n cmd\n .command(\"list\")\n .description(\"List all supported blockchains and their capabilities\")\n .action(async () => {\n const client = getClient()\n const result = await client.get<ChainListResponse>(\"/api/v2/chains\")\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type {\n Chain,\n Collection,\n CollectionOrderBy,\n CollectionPaginatedResponse,\n CollectionStats,\n GetTraitsResponse,\n} from \"../types/index.js\"\n\nexport function collectionsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"collections\").description(\n \"Manage and query NFT collections\",\n )\n\n cmd\n .command(\"get\")\n .description(\"Get a single collection by slug\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<Collection>(`/api/v2/collections/${slug}`)\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"list\")\n .description(\"List collections\")\n .option(\"--chain <chain>\", \"Filter by chain\")\n .option(\n \"--order-by <orderBy>\",\n \"Order by field (created_date, one_day_change, seven_day_volume, seven_day_change, num_owners, market_cap)\",\n )\n .option(\"--creator <username>\", \"Filter by creator username\")\n .option(\"--include-hidden\", \"Include hidden collections\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n chain?: string\n orderBy?: string\n creator?: string\n includeHidden?: boolean\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<{\n collections: Collection[]\n next?: string\n }>(\"/api/v2/collections\", {\n chain: options.chain as Chain | undefined,\n order_by: options.orderBy as CollectionOrderBy | undefined,\n creator_username: options.creator,\n include_hidden: options.includeHidden,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"stats\")\n .description(\"Get collection stats\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<CollectionStats>(\n `/api/v2/collections/${slug}/stats`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"traits\")\n .description(\"Get collection traits\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<GetTraitsResponse>(\n `/api/v2/traits/${slug}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"trending\")\n .description(\"Get trending collections by sales activity\")\n .option(\n \"--timeframe <timeframe>\",\n \"Time window (one_minute, five_minutes, fifteen_minutes, one_hour, one_day, seven_days, thirty_days, one_year, all_time)\",\n \"one_day\",\n )\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\n \"--category <category>\",\n \"Category (art, gaming, memberships, music, pfps, photography, domain-names, virtual-worlds, sports-collectibles)\",\n )\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n timeframe: string\n chains?: string\n category?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<CollectionPaginatedResponse>(\n \"/api/v2/collections/trending\",\n {\n timeframe: options.timeframe,\n chains: options.chains,\n category: options.category,\n limit: parseIntOption(options.limit, \"--limit\"),\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"top\")\n .description(\"Get top collections ranked by volume, sales, or floor price\")\n .option(\n \"--sort-by <field>\",\n \"Sort by (one_day_volume, seven_days_volume, thirty_days_volume, floor_price, one_day_sales, seven_days_sales, thirty_days_sales, total_volume, total_sales)\",\n \"one_day_volume\",\n )\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\n \"--category <category>\",\n \"Category (art, gaming, memberships, music, pfps, photography, domain-names, virtual-worlds, sports-collectibles)\",\n )\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"50\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n sortBy: string\n chains?: string\n category?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<CollectionPaginatedResponse>(\n \"/api/v2/collections/top\",\n {\n sort_by: options.sortBy,\n chains: options.chains,\n category: options.category,\n limit: parseIntOption(options.limit, \"--limit\"),\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type {\n DropDetailedResponse,\n DropMintResponse,\n DropPaginatedResponse,\n} from \"../types/index.js\"\n\nexport function dropsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"drops\").description(\"Query and mint NFT drops\")\n\n cmd\n .command(\"list\")\n .description(\"List drops (featured, upcoming, or recently minted)\")\n .option(\n \"--type <type>\",\n \"Drop type: featured, upcoming, or recently_minted\",\n \"featured\",\n )\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n type: string\n chains?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<DropPaginatedResponse>(\n \"/api/v2/drops\",\n {\n type: options.type,\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"get\")\n .description(\"Get detailed drop info by collection slug\")\n .argument(\"<slug>\", \"Collection slug\")\n .action(async (slug: string) => {\n const client = getClient()\n const result = await client.get<DropDetailedResponse>(\n `/api/v2/drops/${slug}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"mint\")\n .description(\"Build a mint transaction for a drop\")\n .argument(\"<slug>\", \"Collection slug\")\n .requiredOption(\"--minter <address>\", \"Wallet address to receive tokens\")\n .option(\"--quantity <n>\", \"Number of tokens to mint\", \"1\")\n .action(\n async (\n slug: string,\n options: {\n minter: string\n quantity: string\n },\n ) => {\n const client = getClient()\n const result = await client.post<DropMintResponse>(\n `/api/v2/drops/${slug}/mint`,\n {\n minter: options.minter,\n quantity: parseIntOption(options.quantity, \"--quantity\"),\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { AssetEvent } from \"../types/index.js\"\n\nexport function eventsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"events\").description(\"Query marketplace events\")\n\n cmd\n .command(\"list\")\n .description(\"List events\")\n .option(\n \"--event-type <type>\",\n \"Event type (sale, transfer, mint, listing, offer, trait_offer, collection_offer)\",\n )\n .option(\"--after <timestamp>\", \"Filter events after this Unix timestamp\")\n .option(\"--before <timestamp>\", \"Filter events before this Unix timestamp\")\n .option(\"--chain <chain>\", \"Filter by chain\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: {\n eventType?: string\n after?: string\n before?: string\n chain?: string\n limit: string\n next?: string\n }) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(\"/api/v2/events\", {\n event_type: options.eventType,\n after: options.after\n ? parseIntOption(options.after, \"--after\")\n : undefined,\n before: options.before\n ? parseIntOption(options.before, \"--before\")\n : undefined,\n chain: options.chain,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"by-account\")\n .description(\"Get events for an account\")\n .argument(\"<address>\", \"Account address\")\n .option(\"--event-type <type>\", \"Event type\")\n .option(\"--chain <chain>\", \"Filter by chain\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n address: string,\n options: {\n eventType?: string\n chain?: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(`/api/v2/events/accounts/${address}`, {\n event_type: options.eventType,\n chain: options.chain,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"by-collection\")\n .description(\"Get events for a collection\")\n .argument(\"<slug>\", \"Collection slug\")\n .option(\"--event-type <type>\", \"Event type\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n slug: string,\n options: {\n eventType?: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(`/api/v2/events/collection/${slug}`, {\n event_type: options.eventType,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"by-nft\")\n .description(\"Get events for a specific NFT\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .option(\"--event-type <type>\", \"Event type\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n chain: string,\n contract: string,\n tokenId: string,\n options: {\n eventType?: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n asset_events: AssetEvent[]\n next?: string\n }>(\n `/api/v2/events/chain/${chain}/contract/${contract}/nfts/${tokenId}`,\n {\n event_type: options.eventType,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport { checkHealth } from \"../health.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\n\nexport function healthCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"health\")\n .description(\"Check API connectivity and authentication\")\n .action(async () => {\n const client = getClient()\n const result = await checkHealth(client)\n console.log(formatOutput(result, getFormat()))\n if (result.status === \"error\") {\n process.exit(result.rate_limited ? 3 : 1)\n }\n })\n\n return cmd\n}\n","import { OpenSeaAPIError, type OpenSeaClient } from \"./client.js\"\nimport type { HealthResult } from \"./types/index.js\"\n\nexport async function checkHealth(\n client: OpenSeaClient,\n): Promise<HealthResult> {\n const keyPrefix = client.getApiKeyPrefix()\n\n // Step 1: Check basic connectivity with a public endpoint\n try {\n await client.get(\"/api/v2/collections\", { limit: 1 })\n } catch (error) {\n let message: string\n if (error instanceof OpenSeaAPIError) {\n message =\n error.statusCode === 429\n ? \"Rate limited: too many requests\"\n : `API error (${error.statusCode}): ${error.responseBody}`\n } else {\n message = `Network error: ${(error as Error).message}`\n }\n return {\n status: \"error\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited:\n error instanceof OpenSeaAPIError && error.statusCode === 429,\n message,\n }\n }\n\n // Step 2: Validate authentication with an endpoint that requires a valid API key\n try {\n await client.get(\"/api/v2/listings/collection/boredapeyachtclub/all\", {\n limit: 1,\n })\n return {\n status: \"ok\",\n key_prefix: keyPrefix,\n authenticated: true,\n rate_limited: false,\n message: \"Connectivity and authentication are working\",\n }\n } catch (error) {\n if (error instanceof OpenSeaAPIError) {\n if (error.statusCode === 429) {\n return {\n status: \"error\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited: true,\n message: \"Rate limited: too many requests\",\n }\n }\n if (error.statusCode === 401 || error.statusCode === 403) {\n return {\n status: \"error\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited: false,\n message: `Authentication failed (${error.statusCode}): invalid API key`,\n }\n }\n }\n // Non-auth error on listings endpoint — connectivity works but auth is unverified\n return {\n status: \"ok\",\n key_prefix: keyPrefix,\n authenticated: false,\n rate_limited: false,\n message:\n \"Connectivity is working but authentication could not be verified\",\n }\n }\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Listing } from \"../types/index.js\"\n\nexport function listingsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"listings\").description(\"Query NFT listings\")\n\n cmd\n .command(\"all\")\n .description(\"Get all listings for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n listings: Listing[]\n next?: string\n }>(`/api/v2/listings/collection/${collection}/all`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"best\")\n .description(\"Get best listings for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n listings: Listing[]\n next?: string\n }>(`/api/v2/listings/collection/${collection}/best`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"best-for-nft\")\n .description(\"Get best listing for a specific NFT\")\n .argument(\"<collection>\", \"Collection slug\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (collection: string, tokenId: string) => {\n const client = getClient()\n const result = await client.get<Listing>(\n `/api/v2/listings/collection/${collection}/nfts/${tokenId}/best`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Contract, NFT, ValidateMetadataResponse } from \"../types/index.js\"\n\nexport function nftsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"nfts\").description(\"Query NFTs\")\n\n cmd\n .command(\"get\")\n .description(\"Get a single NFT\")\n .argument(\"<chain>\", \"Chain (e.g. ethereum, base)\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (chain: string, contract: string, tokenId: string) => {\n const client = getClient()\n const result = await client.get<{ nft: NFT }>(\n `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"list-by-collection\")\n .description(\"List NFTs in a collection\")\n .argument(\"<slug>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(async (slug: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{ nfts: NFT[]; next?: string }>(\n `/api/v2/collection/${slug}/nfts`,\n {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"list-by-contract\")\n .description(\"List NFTs by contract address\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n chain: string,\n contract: string,\n options: { limit: string; next?: string },\n ) => {\n const client = getClient()\n const result = await client.get<{ nfts: NFT[]; next?: string }>(\n `/api/v2/chain/${chain}/contract/${contract}/nfts`,\n {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"list-by-account\")\n .description(\"List NFTs owned by an account\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<address>\", \"Account address\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n chain: string,\n address: string,\n options: { limit: string; next?: string },\n ) => {\n const client = getClient()\n const result = await client.get<{ nfts: NFT[]; next?: string }>(\n `/api/v2/chain/${chain}/account/${address}/nfts`,\n {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"refresh\")\n .description(\"Refresh NFT metadata\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (chain: string, contract: string, tokenId: string) => {\n const client = getClient()\n await client.post(\n `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}/refresh`,\n )\n console.log(\n formatOutput(\n { status: \"ok\", message: \"Metadata refresh requested\" },\n getFormat(),\n ),\n )\n })\n\n cmd\n .command(\"contract\")\n .description(\"Get contract details\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<address>\", \"Contract address\")\n .action(async (chain: string, address: string) => {\n const client = getClient()\n const result = await client.get<Contract>(\n `/api/v2/chain/${chain}/contract/${address}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"validate-metadata\")\n .description(\"Validate NFT metadata by fetching and parsing it\")\n .argument(\"<chain>\", \"Chain\")\n .argument(\"<contract>\", \"Contract address\")\n .argument(\"<token-id>\", \"Token ID\")\n .option(\n \"--ignore-cache\",\n \"Ignore cached item URLs and re-fetch from source\",\n )\n .action(\n async (\n chain: string,\n contract: string,\n tokenId: string,\n options: { ignoreCache?: boolean },\n ) => {\n const client = getClient()\n const params: Record<string, unknown> = {}\n if (options.ignoreCache) {\n params.ignoreCachedItemUrls = true\n }\n const result = await client.post<ValidateMetadataResponse>(\n `/api/v2/chain/${chain}/contract/${contract}/nfts/${tokenId}/validate-metadata`,\n undefined,\n params,\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Offer } from \"../types/index.js\"\n\nexport function offersCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"offers\").description(\"Query NFT offers\")\n\n cmd\n .command(\"all\")\n .description(\"Get all offers for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n offers: Offer[]\n next?: string\n }>(`/api/v2/offers/collection/${collection}/all`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"collection\")\n .description(\"Get collection offers\")\n .argument(\"<collection>\", \"Collection slug\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (collection: string, options: { limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{\n offers: Offer[]\n next?: string\n }>(`/api/v2/offers/collection/${collection}`, {\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"best-for-nft\")\n .description(\"Get best offer for a specific NFT\")\n .argument(\"<collection>\", \"Collection slug\")\n .argument(\"<token-id>\", \"Token ID\")\n .action(async (collection: string, tokenId: string) => {\n const client = getClient()\n const result = await client.get<Offer>(\n `/api/v2/offers/collection/${collection}/nfts/${tokenId}/best`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n cmd\n .command(\"traits\")\n .description(\"Get trait offers for a collection\")\n .argument(\"<collection>\", \"Collection slug\")\n .requiredOption(\"--type <type>\", \"Trait type (required)\")\n .requiredOption(\"--value <value>\", \"Trait value (required)\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (\n collection: string,\n options: {\n type: string\n value: string\n limit: string\n next?: string\n },\n ) => {\n const client = getClient()\n const result = await client.get<{\n offers: Offer[]\n next?: string\n }>(`/api/v2/offers/collection/${collection}/traits`, {\n type: options.type,\n value: options.value,\n limit: parseIntOption(options.limit, \"--limit\"),\n next: options.next,\n })\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { SearchResponse } from \"../types/index.js\"\n\nexport function searchCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"search\")\n .description(\"Search across collections, tokens, NFTs, and accounts\")\n .argument(\"<query>\", \"Search query\")\n .option(\n \"--types <types>\",\n \"Filter by type (comma-separated: collection,nft,token,account)\",\n )\n .option(\"--chains <chains>\", \"Filter by chains (comma-separated)\")\n .option(\"--limit <limit>\", \"Number of results\", \"20\")\n .action(\n async (\n query: string,\n options: {\n types?: string\n chains?: string\n limit: string\n },\n ) => {\n const client = getClient()\n const params: Record<string, unknown> = {\n query,\n limit: parseIntOption(options.limit, \"--limit\"),\n }\n if (options.types) {\n params.asset_types = options.types\n }\n if (options.chains) {\n params.chains = options.chains\n }\n const result = await client.get<SearchResponse>(\n \"/api/v2/search\",\n params,\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n return cmd\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseFloatOption } from \"../parse.js\"\nimport { resolveQuantity, SwapsAPI } from \"../sdk.js\"\nimport type { SwapQuoteResponse } from \"../types/index.js\"\nimport type { WalletProvider } from \"../wallet/index.js\"\nimport { createWalletFromEnv, WALLET_PROVIDERS } from \"../wallet/index.js\"\n\nexport function swapsCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"swaps\").description(\n \"Get swap quotes and execute token swaps\",\n )\n\n cmd\n .command(\"quote\")\n .description(\n \"Get a quote for swapping tokens, including price details and executable transaction data\",\n )\n .requiredOption(\"--from-chain <chain>\", \"Chain of the token to swap from\")\n .requiredOption(\n \"--from-address <address>\",\n \"Contract address of the token to swap from\",\n )\n .requiredOption(\"--to-chain <chain>\", \"Chain of the token to swap to\")\n .requiredOption(\n \"--to-address <address>\",\n \"Contract address of the token to swap to\",\n )\n .requiredOption(\n \"--quantity <quantity>\",\n \"Amount to swap (decimals like 0.1 are auto-converted to smallest units)\",\n )\n .requiredOption(\"--address <address>\", \"Wallet address executing the swap\")\n .option(\n \"--slippage <slippage>\",\n \"Slippage tolerance (0.0 to 0.5, default: 0.01)\",\n )\n .option(\n \"--recipient <recipient>\",\n \"Recipient address (defaults to sender address)\",\n )\n .action(\n async (options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n address: string\n slippage?: string\n recipient?: string\n }) => {\n const client = getClient()\n const quantity = await resolveQuantity(\n client,\n options.fromChain,\n options.fromAddress,\n options.quantity,\n )\n const result = await client.get<SwapQuoteResponse>(\n \"/api/v2/swap/quote\",\n {\n from_chain: options.fromChain,\n from_address: options.fromAddress,\n to_chain: options.toChain,\n to_address: options.toAddress,\n quantity,\n address: options.address,\n slippage: options.slippage\n ? parseFloatOption(options.slippage, \"--slippage\")\n : undefined,\n recipient: options.recipient,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"execute\")\n .description(\n \"Get a swap quote and execute it onchain using a managed wallet. \" +\n \"Supports Privy (default), Turnkey, and Fireblocks providers.\",\n )\n .requiredOption(\"--from-chain <chain>\", \"Chain of the token to swap from\")\n .requiredOption(\n \"--from-address <address>\",\n \"Contract address of the token to swap from\",\n )\n .requiredOption(\"--to-chain <chain>\", \"Chain of the token to swap to\")\n .requiredOption(\n \"--to-address <address>\",\n \"Contract address of the token to swap to\",\n )\n .requiredOption(\n \"--quantity <quantity>\",\n \"Amount to swap (decimals like 0.1 are auto-converted to smallest units)\",\n )\n .option(\n \"--slippage <slippage>\",\n \"Slippage tolerance (0.0 to 0.5, default: 0.01)\",\n )\n .option(\n \"--recipient <recipient>\",\n \"Recipient address (defaults to wallet address)\",\n )\n .option(\n \"--wallet-provider <provider>\",\n `Wallet provider to use (${WALLET_PROVIDERS.join(\", \")})`,\n )\n .option(\"--dry-run\", \"Print quote and transaction details without signing\")\n .action(\n async (options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n slippage?: string\n recipient?: string\n walletProvider?: string\n dryRun?: boolean\n }) => {\n const wallet = createWalletFromEnv(\n options.walletProvider as WalletProvider | undefined,\n )\n const address = await wallet.getAddress()\n console.error(`Using ${wallet.name} wallet: ${address}`)\n\n const client = getClient()\n const quantity = await resolveQuantity(\n client,\n options.fromChain,\n options.fromAddress,\n options.quantity,\n )\n const swaps = new SwapsAPI(client)\n const format = getFormat()\n const slippage = options.slippage\n ? parseFloatOption(options.slippage, \"--slippage\")\n : undefined\n\n if (options.dryRun) {\n const quote = await swaps.quote({\n ...options,\n quantity,\n address,\n slippage,\n })\n console.log(formatOutput(quote, format))\n return\n }\n\n const results = await swaps.execute(\n {\n ...options,\n quantity,\n address,\n slippage,\n },\n wallet,\n {\n onQuote: () =>\n console.error(\n `Quote: ${options.quantity} on ${options.fromChain} → ${options.toChain}`,\n ),\n onSending: tx =>\n console.error(\n `Sending transaction to ${tx.to} on chain ${tx.chain} (${tx.chainId})...`,\n ),\n onSkipped: tx =>\n console.error(\n `Skipping transaction on ${tx.chain}: ${tx.reason}`,\n ),\n },\n )\n\n for (const result of results) {\n console.log(formatOutput({ hash: result.hash }, format))\n }\n },\n )\n\n return cmd\n}\n","/**\n * AUTO-GENERATED by scripts/sync-chains.ts — DO NOT EDIT.\n * Source of truth: OpenSea REST API + scripts/chain-data.json\n * Run `pnpm sync-chains` to regenerate.\n */\n\n/** Map EVM chain IDs to Fireblocks asset IDs. */\nexport const CHAIN_TO_FIREBLOCKS_ASSET: Record<number, string> = {\n 1: \"ETH\",\n 10: \"ETH-OPT\",\n 130: \"UNICHAIN_ETH\",\n 137: \"MATIC_POLYGON\",\n 360: \"SHAPE_ETH\",\n 1329: \"SEI_EVM\",\n 1868: \"SONEIUM_ETH\",\n 2741: \"ABSTRACT_ETH\",\n 8453: \"BASECHAIN_ETH\",\n 33139: \"APE_CHAIN\",\n 42161: \"ETH-AETH\",\n 43114: \"AVAX\",\n 80094: \"BERA_CHAIN\",\n 81457: \"BLAST_ETH\",\n 7777777: \"ZORA_ETH\",\n}\n","/**\n * Fireblocks wallet adapter.\n *\n * Uses Fireblocks' REST API to sign and send transactions through their\n * enterprise-grade custody infrastructure. Fireblocks provides MPC-based\n * key management, transaction policy engine, and multi-level approval\n * workflows suitable for institutional use.\n *\n * Required environment variables:\n * FIREBLOCKS_API_KEY — Fireblocks API key\n * FIREBLOCKS_API_SECRET — Fireblocks API secret (RSA private key, PEM-encoded)\n * FIREBLOCKS_VAULT_ID — Fireblocks vault account ID\n *\n * Optional:\n * FIREBLOCKS_API_BASE_URL — Override the Fireblocks API base URL\n * (default: https://api.fireblocks.io)\n * FIREBLOCKS_ASSET_ID — Override the Fireblocks asset ID\n * (default: ETH — for EVM chains Fireblocks uses\n * asset IDs like ETH, ETH_TEST5, MATIC, etc.)\n *\n * @see https://developers.fireblocks.com/docs/introduction\n * @see https://developers.fireblocks.com/reference/api-overview\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\nimport { CHAIN_TO_FIREBLOCKS_ASSET } from \"./fireblocks.generated.js\"\n\ninterface FireblocksConfig {\n apiKey: string\n apiSecret: string\n vaultId: string\n assetId?: string\n baseUrl?: string\n}\n\nconst FIREBLOCKS_API_BASE = \"https://api.fireblocks.io\"\n\nexport class FireblocksAdapter implements WalletAdapter {\n readonly name = \"fireblocks\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: FireblocksConfig\n private cachedAddress?: string\n\n constructor(config: FireblocksConfig) {\n this.config = config\n }\n\n /**\n * Create a FireblocksAdapter from environment variables.\n * Throws if any required variable is missing.\n */\n static fromEnv(): FireblocksAdapter {\n const apiKey = process.env.FIREBLOCKS_API_KEY\n const apiSecret = process.env.FIREBLOCKS_API_SECRET\n const vaultId = process.env.FIREBLOCKS_VAULT_ID\n\n if (!apiKey) {\n throw new Error(\"FIREBLOCKS_API_KEY environment variable is required\")\n }\n if (!apiSecret) {\n throw new Error(\"FIREBLOCKS_API_SECRET environment variable is required\")\n }\n if (!vaultId) {\n throw new Error(\"FIREBLOCKS_VAULT_ID environment variable is required\")\n }\n\n return new FireblocksAdapter({\n apiKey,\n apiSecret,\n vaultId,\n assetId: process.env.FIREBLOCKS_ASSET_ID,\n baseUrl: process.env.FIREBLOCKS_API_BASE_URL,\n })\n }\n\n private get baseUrl(): string {\n return this.config.baseUrl ?? FIREBLOCKS_API_BASE\n }\n\n /**\n * Create a JWT for Fireblocks API authentication.\n *\n * Fireblocks uses JWT tokens signed with the API secret (RSA private key).\n * The JWT contains the API key as `sub`, a URI claim for the endpoint path,\n * and a body hash for POST requests.\n *\n * @see https://developers.fireblocks.com/reference/signing-a-request-jwt-structure\n */\n private async createJwt(path: string, bodyHash: string): Promise<string> {\n const now = Math.floor(Date.now() / 1000)\n\n const header = { alg: \"RS256\", typ: \"JWT\" }\n const payload = {\n uri: path,\n nonce: crypto.randomUUID(),\n iat: now,\n exp: now + 30,\n sub: this.config.apiKey,\n bodyHash,\n }\n\n const b64url = (obj: unknown) =>\n Buffer.from(JSON.stringify(obj)).toString(\"base64url\")\n\n const unsigned = `${b64url(header)}.${b64url(payload)}`\n\n const key = await crypto.subtle.importKey(\n \"pkcs8\",\n this.pemToBuffer(this.config.apiSecret),\n { name: \"RSASSA-PKCS1-v1_5\", hash: \"SHA-256\" },\n false,\n [\"sign\"],\n )\n\n const sig = await crypto.subtle.sign(\n \"RSASSA-PKCS1-v1_5\",\n key,\n new TextEncoder().encode(unsigned),\n )\n\n return `${unsigned}.${Buffer.from(sig).toString(\"base64url\")}`\n }\n\n private pemToBuffer(pem: string): ArrayBuffer {\n const lines = pem\n .replace(/-----BEGIN .*-----/, \"\")\n .replace(/-----END .*-----/, \"\")\n .replace(/\\s/g, \"\")\n const buf = Buffer.from(lines, \"base64\")\n return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength)\n }\n\n private async hashBody(body: string): Promise<string> {\n const hash = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(body),\n )\n return Buffer.from(hash).toString(\"hex\")\n }\n\n private resolveAssetId(chainId: number): string {\n if (this.config.assetId) return this.config.assetId\n const asset = CHAIN_TO_FIREBLOCKS_ASSET[chainId]\n if (!asset) {\n throw new Error(\n `No Fireblocks asset ID mapping for chain ${chainId}. ` +\n `Set FIREBLOCKS_ASSET_ID explicitly or use a supported chain: ${Object.keys(CHAIN_TO_FIREBLOCKS_ASSET).join(\", \")}`,\n )\n }\n return asset\n }\n\n async getAddress(): Promise<string> {\n if (this.cachedAddress) return this.cachedAddress\n\n const assetId = this.config.assetId ?? \"ETH\"\n const path = `/v1/vault/accounts/${this.config.vaultId}/${assetId}/addresses`\n const bodyHash = await this.hashBody(\"\")\n const jwt = await this.createJwt(path, bodyHash)\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n headers: {\n \"X-API-Key\": this.config.apiKey,\n Authorization: `Bearer ${jwt}`,\n },\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Fireblocks getAddress failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as { address: string }[]\n if (!data[0]?.address) {\n throw new Error(\"Fireblocks returned no addresses for vault\")\n }\n this.cachedAddress = data[0].address\n return data[0].address\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n const assetId = this.resolveAssetId(tx.chainId)\n const path = \"/v1/transactions\"\n\n const requestBody = {\n assetId,\n operation: \"CONTRACT_CALL\",\n source: {\n type: \"VAULT_ACCOUNT\",\n id: this.config.vaultId,\n },\n destination: {\n type: \"ONE_TIME_ADDRESS\",\n oneTimeAddress: { address: tx.to },\n },\n amount: tx.value === \"0\" ? \"0\" : tx.value,\n extraParameters: {\n contractCallData: tx.data,\n },\n }\n\n const bodyStr = JSON.stringify(requestBody)\n const bodyHash = await this.hashBody(bodyStr)\n const jwt = await this.createJwt(path, bodyHash)\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.config.apiKey,\n Authorization: `Bearer ${jwt}`,\n },\n body: bodyStr,\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Fireblocks sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as { id: string; txHash?: string }\n\n if (data.txHash) {\n const result = { hash: data.txHash }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n\n // Fireblocks transactions are async — poll until completed\n const result = await this.waitForTransaction(data.id)\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n\n /**\n * Poll a Fireblocks transaction until it reaches a terminal status.\n * Fireblocks MPC signing + broadcast is asynchronous, so the initial\n * POST returns a transaction ID that must be polled for the final hash.\n */\n private async waitForTransaction(txId: string): Promise<TransactionResult> {\n // Default: 60 attempts × 2s = 120s. Override with FIREBLOCKS_MAX_POLL_ATTEMPTS.\n // Note: transactions requiring multi-party approval may exceed this timeout.\n const maxAttempts = process.env.FIREBLOCKS_MAX_POLL_ATTEMPTS\n ? Number.parseInt(process.env.FIREBLOCKS_MAX_POLL_ATTEMPTS, 10)\n : 60\n const pollIntervalMs = 2000\n\n for (let i = 0; i < maxAttempts; i++) {\n const path = `/v1/transactions/${txId}`\n const bodyHash = await this.hashBody(\"\")\n const jwt = await this.createJwt(path, bodyHash)\n\n const response = await fetch(`${this.baseUrl}${path}`, {\n headers: {\n \"X-API-Key\": this.config.apiKey,\n Authorization: `Bearer ${jwt}`,\n },\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Fireblocks poll failed (${response.status}): ${body}`)\n }\n\n const data = (await response.json()) as {\n status: string\n txHash?: string\n }\n\n if (data.status === \"COMPLETED\" && data.txHash) {\n return { hash: data.txHash }\n }\n\n if (\n data.status === \"FAILED\" ||\n data.status === \"REJECTED\" ||\n data.status === \"CANCELLED\" ||\n data.status === \"BLOCKED\"\n ) {\n throw new Error(\n `Fireblocks transaction ${txId} ended with status: ${data.status}`,\n )\n }\n\n await new Promise(resolve => setTimeout(resolve, pollIntervalMs))\n }\n\n throw new Error(\n `Fireblocks transaction ${txId} did not complete within ${(maxAttempts * pollIntervalMs) / 1000}s`,\n )\n }\n}\n","/**\n * Raw private key wallet adapter.\n *\n * WARNING: Using a raw private key is NOT recommended for production use.\n * It provides no spending limits, no destination allowlists, and no\n * human-in-the-loop approval. Prefer Privy, Turnkey, or Fireblocks\n * for managed wallet security.\n *\n * This adapter sends transactions via eth_sendTransaction on the RPC node,\n * which requires the node to manage the key (e.g. Hardhat, Anvil, Ganache).\n * The PRIVATE_KEY env var is validated (format + address derivation) to\n * confirm intent, but is NOT used for signing — the RPC node holds the key\n * and signs server-side. This means this adapter only works with local dev\n * nodes, not production RPC providers like Infura or Alchemy.\n *\n * Required environment variables:\n * PRIVATE_KEY — Hex-encoded private key (validated for format;\n * the RPC node must already have this key imported)\n * RPC_URL — JSON-RPC endpoint URL (must be a local dev node)\n * WALLET_ADDRESS — The wallet address corresponding to the private key\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\n\n/** Known hosted RPC provider hostnames that don't support eth_sendTransaction */\nconst HOSTED_RPC_PROVIDERS = [\n \"infura.io\",\n \"alchemy.com\",\n \"quicknode.com\",\n \"ankr.com\",\n \"cloudflare-eth.com\",\n \"pokt.network\",\n \"blastapi.io\",\n \"chainnodes.org\",\n \"drpc.org\",\n]\n\ninterface PrivateKeyConfig {\n /**\n * The private key hex string. Validated at construction time to confirm\n * the user intends to use raw key mode, but NOT used for signing.\n * The RPC node (Hardhat/Anvil/Ganache) handles signing via eth_sendTransaction.\n */\n privateKey: string\n rpcUrl: string\n walletAddress: string\n}\n\nexport class PrivateKeyAdapter implements WalletAdapter {\n readonly name = \"private-key\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: PrivateKeyConfig\n private hasWarned = false\n\n constructor(config: PrivateKeyConfig) {\n this.config = config\n }\n\n /**\n * Create a PrivateKeyAdapter from environment variables.\n * Validates the private key format and warns if the RPC URL looks\n * like a hosted provider (which won't support eth_sendTransaction).\n */\n static fromEnv(): PrivateKeyAdapter {\n const privateKey = process.env.PRIVATE_KEY\n const rpcUrl = process.env.RPC_URL\n const walletAddress = process.env.WALLET_ADDRESS\n\n if (!privateKey) {\n throw new Error(\"PRIVATE_KEY environment variable is required\")\n }\n if (!rpcUrl) {\n throw new Error(\n \"RPC_URL environment variable is required when using PRIVATE_KEY\",\n )\n }\n if (!walletAddress) {\n throw new Error(\n \"WALLET_ADDRESS environment variable is required when using PRIVATE_KEY\",\n )\n }\n\n // Validate private key format (should be 32 bytes hex, with or without 0x prefix)\n const cleanKey = privateKey.startsWith(\"0x\")\n ? privateKey.slice(2)\n : privateKey\n if (!/^[0-9a-fA-F]{64}$/.test(cleanKey)) {\n throw new Error(\n \"PRIVATE_KEY must be a 32-byte hex string (64 hex characters, with optional 0x prefix)\",\n )\n }\n\n // Warn if RPC URL looks like a hosted provider\n try {\n const host = new URL(rpcUrl).hostname\n const isHosted = HOSTED_RPC_PROVIDERS.some(provider =>\n host.includes(provider),\n )\n if (isHosted) {\n console.warn(\n `WARNING: RPC_URL (${host}) looks like a hosted provider. ` +\n \"The private-key adapter uses eth_sendTransaction which only works \" +\n \"with local dev nodes (Hardhat, Anvil, Ganache). \" +\n \"Hosted providers will reject this call.\",\n )\n }\n } catch {\n // Invalid URL — will fail at sendTransaction time\n }\n\n return new PrivateKeyAdapter({ privateKey, rpcUrl, walletAddress })\n }\n\n async getAddress(): Promise<string> {\n return this.config.walletAddress\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n if (!this.hasWarned) {\n this.hasWarned = true\n console.warn(\n \"WARNING: Using raw PRIVATE_KEY adapter. \" +\n \"This is not recommended for production. \" +\n \"Use --wallet-provider privy|turnkey|fireblocks for managed wallet security.\",\n )\n }\n\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n const response = await fetch(this.config.rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_sendTransaction\",\n params: [\n {\n from: this.config.walletAddress,\n to: tx.to,\n data: tx.data,\n value:\n tx.value === \"0\" ? \"0x0\" : `0x${BigInt(tx.value).toString(16)}`,\n chainId: `0x${tx.chainId.toString(16)}`,\n },\n ],\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Private key sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as {\n result?: string\n error?: { message: string }\n }\n\n if (data.error) {\n throw new Error(\n `Private key sendTransaction RPC error: ${data.error.message}`,\n )\n }\n\n if (!data.result) {\n throw new Error(\"Private key sendTransaction returned no tx hash\")\n }\n\n const result = { hash: data.result }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n}\n","/**\n * Privy wallet adapter.\n *\n * Uses Privy's server-side wallet API to sign and send transactions.\n * Transactions are governed by Privy's programmable policy engine —\n * policies (transaction limits, destination allowlists, chain restrictions)\n * are evaluated in a trusted execution environment before any signing occurs.\n *\n * Required environment variables:\n * PRIVY_APP_ID — Privy application ID\n * PRIVY_APP_SECRET — Privy application secret\n * PRIVY_WALLET_ID — Wallet ID to use for signing\n *\n * @see https://docs.privy.io/wallets/wallets/server-side-access\n * @see https://docs.privy.io/controls/policies/overview\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\n\ninterface PrivyConfig {\n appId: string\n appSecret: string\n walletId: string\n baseUrl?: string\n}\n\nconst PRIVY_API_BASE = \"https://api.privy.io\"\n\nexport class PrivyAdapter implements WalletAdapter {\n readonly name = \"privy\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: PrivyConfig\n private cachedAddress?: string\n\n constructor(config: PrivyConfig) {\n this.config = config\n }\n\n /**\n * Create a PrivyAdapter from environment variables.\n * Throws if any required variable is missing.\n */\n static fromEnv(): PrivyAdapter {\n const appId = process.env.PRIVY_APP_ID\n const appSecret = process.env.PRIVY_APP_SECRET\n const walletId = process.env.PRIVY_WALLET_ID\n\n if (!appId) {\n throw new Error(\"PRIVY_APP_ID environment variable is required\")\n }\n if (!appSecret) {\n throw new Error(\"PRIVY_APP_SECRET environment variable is required\")\n }\n if (!walletId) {\n throw new Error(\"PRIVY_WALLET_ID environment variable is required\")\n }\n\n return new PrivyAdapter({\n appId,\n appSecret,\n walletId,\n baseUrl: process.env.PRIVY_API_BASE_URL,\n })\n }\n\n private get baseUrl(): string {\n return this.config.baseUrl ?? PRIVY_API_BASE\n }\n\n private get authHeaders(): Record<string, string> {\n const credentials = Buffer.from(\n `${this.config.appId}:${this.config.appSecret}`,\n ).toString(\"base64\")\n return {\n Authorization: `Basic ${credentials}`,\n \"privy-app-id\": this.config.appId,\n \"Content-Type\": \"application/json\",\n }\n }\n\n async getAddress(): Promise<string> {\n if (this.cachedAddress) return this.cachedAddress\n\n const response = await fetch(\n `${this.baseUrl}/v1/wallets/${this.config.walletId}`,\n { headers: this.authHeaders },\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(`Privy getAddress failed (${response.status}): ${body}`)\n }\n\n const data = (await response.json()) as { address: string }\n this.cachedAddress = data.address\n return data.address\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n const caip2 = `eip155:${tx.chainId}`\n\n const response = await fetch(\n `${this.baseUrl}/v1/wallets/${this.config.walletId}/rpc`,\n {\n method: \"POST\",\n headers: this.authHeaders,\n body: JSON.stringify({\n method: \"eth_sendTransaction\",\n caip2,\n params: {\n transaction: {\n to: tx.to,\n data: tx.data,\n value: tx.value,\n },\n },\n }),\n },\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Privy sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as { data: { hash: string } }\n const result = { hash: data.data.hash }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n}\n","/**\n * Turnkey wallet adapter.\n *\n * Uses Turnkey's API to sign and send transactions via their HSM-backed\n * signing infrastructure. Turnkey provides non-custodial key management\n * with policy controls, audit logging, and multi-party approval workflows.\n *\n * Authentication uses Turnkey's stamp scheme: each request body is hashed\n * and signed with a P-256 ECDSA key, then the signature + public key are\n * sent in the X-Stamp header.\n *\n * Required environment variables:\n * TURNKEY_API_PUBLIC_KEY — Turnkey API public key (hex-encoded, compressed or uncompressed)\n * TURNKEY_API_PRIVATE_KEY — Turnkey API private key (hex-encoded P-256 private key)\n * TURNKEY_ORGANIZATION_ID — Turnkey organization ID\n * TURNKEY_WALLET_ADDRESS — Ethereum address managed by Turnkey\n *\n * Required:\n * TURNKEY_RPC_URL — RPC endpoint for gas estimation and broadcast (must match target chain)\n *\n * Optional:\n * TURNKEY_API_BASE_URL — Override the Turnkey API base URL (default: https://api.turnkey.com)\n * TURNKEY_PRIVATE_KEY_ID — Turnkey private key ID (for signing with a specific key)\n *\n * @see https://docs.turnkey.com/\n * @see https://docs.turnkey.com/developer-tools/api-overview/stamps\n */\n\nimport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\n\ninterface TurnkeyConfig {\n apiPublicKey: string\n apiPrivateKey: string\n organizationId: string\n walletAddress: string\n rpcUrl: string\n privateKeyId?: string\n baseUrl?: string\n}\n\nconst TURNKEY_API_BASE = \"https://api.turnkey.com\"\n\nexport class TurnkeyAdapter implements WalletAdapter {\n readonly name = \"turnkey\"\n onRequest?: (method: string, params: unknown) => void\n onResponse?: (method: string, result: unknown, durationMs: number) => void\n private config: TurnkeyConfig\n\n constructor(config: TurnkeyConfig) {\n this.config = config\n }\n\n /**\n * Create a TurnkeyAdapter from environment variables.\n * Throws if any required variable is missing.\n */\n static fromEnv(): TurnkeyAdapter {\n const apiPublicKey = process.env.TURNKEY_API_PUBLIC_KEY\n const apiPrivateKey = process.env.TURNKEY_API_PRIVATE_KEY\n const organizationId = process.env.TURNKEY_ORGANIZATION_ID\n const walletAddress = process.env.TURNKEY_WALLET_ADDRESS\n\n if (!apiPublicKey) {\n throw new Error(\"TURNKEY_API_PUBLIC_KEY environment variable is required\")\n }\n if (!apiPrivateKey) {\n throw new Error(\n \"TURNKEY_API_PRIVATE_KEY environment variable is required\",\n )\n }\n if (!organizationId) {\n throw new Error(\n \"TURNKEY_ORGANIZATION_ID environment variable is required\",\n )\n }\n if (!walletAddress) {\n throw new Error(\"TURNKEY_WALLET_ADDRESS environment variable is required\")\n }\n\n const rpcUrl = process.env.TURNKEY_RPC_URL\n if (!rpcUrl) {\n throw new Error(\n \"TURNKEY_RPC_URL environment variable is required. \" +\n \"It is used for gas estimation and transaction broadcasting.\",\n )\n }\n\n return new TurnkeyAdapter({\n apiPublicKey,\n apiPrivateKey,\n organizationId,\n walletAddress,\n rpcUrl,\n privateKeyId: process.env.TURNKEY_PRIVATE_KEY_ID,\n baseUrl: process.env.TURNKEY_API_BASE_URL,\n })\n }\n\n private get baseUrl(): string {\n return this.config.baseUrl ?? TURNKEY_API_BASE\n }\n\n /**\n * Sign a Turnkey API request using the API key pair (P-256 ECDSA).\n *\n * Turnkey uses a stamp-based authentication scheme: the request body\n * is hashed with SHA-256 and signed with the P-256 private key. The\n * stamp JSON (publicKey + scheme + signature) is then base64url-encoded\n * and sent in the X-Stamp header.\n *\n * @see https://docs.turnkey.com/developer-tools/api-overview/stamps\n */\n private async stamp(body: string): Promise<string> {\n const encoder = new TextEncoder()\n\n // Hash the body with SHA-256\n const bodyHash = await crypto.subtle.digest(\"SHA-256\", encoder.encode(body))\n\n // Import the P-256 private key\n const keyData = hexToBytes(this.config.apiPrivateKey)\n const cryptoKey = await crypto.subtle.importKey(\n \"pkcs8\",\n derEncodeP256PrivateKey(keyData),\n { name: \"ECDSA\", namedCurve: \"P-256\" },\n false,\n [\"sign\"],\n )\n\n // Sign the body hash with ECDSA P-256\n // Web Crypto returns IEEE P1363 format (raw r||s, 64 bytes for P-256).\n // Turnkey expects DER-encoded signatures, so we must convert.\n // @see https://github.com/tkhq/sdk/blob/main/packages/api-key-stamper\n const p1363Sig = await crypto.subtle.sign(\n { name: \"ECDSA\", hash: \"SHA-256\" },\n cryptoKey,\n bodyHash,\n )\n\n const derSig = p1363ToDer(new Uint8Array(p1363Sig))\n const signatureHex = bytesToHex(derSig)\n\n // The stamp must be base64url-encoded per Turnkey's spec\n const stampJson = JSON.stringify({\n publicKey: this.config.apiPublicKey,\n scheme: \"SIGNATURE_SCHEME_TK_API_P256\",\n signature: signatureHex,\n })\n\n return Buffer.from(stampJson).toString(\"base64url\")\n }\n\n private async signedRequest(\n path: string,\n body: Record<string, unknown>,\n ): Promise<Response> {\n const bodyStr = JSON.stringify(body)\n const stampValue = await this.stamp(bodyStr)\n\n return fetch(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Stamp\": stampValue,\n },\n body: bodyStr,\n })\n }\n\n async getAddress(): Promise<string> {\n return this.config.walletAddress\n }\n\n async sendTransaction(tx: TransactionRequest): Promise<TransactionResult> {\n this.onRequest?.(\"sendTransaction\", tx)\n const startTime = Date.now()\n\n // Turnkey is a pure signing service — it does NOT estimate gas or fill nonce.\n // We must populate gas fields via RPC before serializing, just like the\n // Turnkey SDK does via ethers provider.populateTransaction().\n // @see https://docs.turnkey.com/company-wallets/code-examples/signing-transactions\n const { rpcUrl } = this.config\n\n const gasParams = await this.estimateGasParams(rpcUrl, tx)\n\n // RLP-serialize the fully-populated unsigned EIP-1559 transaction for Turnkey.\n // Turnkey expects `unsignedTransaction` as hex-encoded RLP (no 0x prefix).\n // @see https://docs.turnkey.com/api-reference/activities/sign-transaction\n const rlpHex = rlpEncodeEip1559Tx({\n chainId: tx.chainId,\n nonce: gasParams.nonce,\n maxPriorityFeePerGas: gasParams.maxPriorityFeePerGas,\n maxFeePerGas: gasParams.maxFeePerGas,\n gasLimit: gasParams.gasLimit,\n to: tx.to,\n data: tx.data,\n value: tx.value,\n })\n\n const signWith = this.config.privateKeyId ?? this.config.walletAddress\n\n const response = await this.signedRequest(\n \"/public/v1/submit/sign_transaction\",\n {\n type: \"ACTIVITY_TYPE_SIGN_TRANSACTION_V2\",\n organizationId: this.config.organizationId,\n timestampMs: Date.now().toString(),\n parameters: {\n signWith,\n type: \"TRANSACTION_TYPE_ETHEREUM\",\n unsignedTransaction: rlpHex,\n },\n },\n )\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Turnkey sendTransaction failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as {\n activity: {\n status: string\n result?: {\n signTransactionResult?: { signedTransaction: string }\n }\n }\n }\n\n const signedTx =\n data.activity.result?.signTransactionResult?.signedTransaction\n if (!signedTx) {\n throw new Error(\n `Turnkey sign transaction did not return a signed payload (activity status: ${data.activity.status})`,\n )\n }\n\n // Broadcast the signed transaction via RPC\n // Turnkey signs but does not broadcast — we must submit via eth_sendRawTransaction\n const rpcResponse = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_sendRawTransaction\",\n params: [signedTx],\n }),\n })\n\n if (!rpcResponse.ok) {\n const rpcBody = await rpcResponse.text()\n throw new Error(\n `Turnkey broadcast failed (${rpcResponse.status}): ${rpcBody}`,\n )\n }\n\n const rpcData = (await rpcResponse.json()) as {\n result?: string\n error?: { message: string }\n }\n\n if (rpcData.error) {\n throw new Error(`Turnkey broadcast RPC error: ${rpcData.error.message}`)\n }\n\n if (!rpcData.result) {\n throw new Error(\"Turnkey broadcast returned no tx hash\")\n }\n\n const result = { hash: rpcData.result }\n this.onResponse?.(\"sendTransaction\", result, Date.now() - startTime)\n return result\n }\n\n /**\n * Populate gas parameters via JSON-RPC calls to the target chain.\n * Mirrors what ethers.js provider.populateTransaction() does internally.\n *\n * Makes three parallel RPC calls:\n * - eth_getTransactionCount (nonce)\n * - eth_estimateGas (gasLimit)\n * - eth_maxPriorityFeePerGas + eth_getBlockByNumber (fee data)\n */\n private async estimateGasParams(\n rpcUrl: string,\n tx: TransactionRequest,\n ): Promise<{\n nonce: bigint\n gasLimit: bigint\n maxFeePerGas: bigint\n maxPriorityFeePerGas: bigint\n }> {\n const from = this.config.walletAddress\n const txValue =\n tx.value === \"0\" ? \"0x0\" : `0x${BigInt(tx.value).toString(16)}`\n\n // Batch all RPC calls in parallel for speed\n const [nonceResult, gasEstimateResult, feeDataResult] = await Promise.all([\n this.rpcCall(rpcUrl, \"eth_getTransactionCount\", [from, \"pending\"]),\n this.rpcCall(rpcUrl, \"eth_estimateGas\", [\n {\n from,\n to: tx.to,\n data: tx.data || \"0x\",\n value: txValue,\n },\n ]),\n this.rpcCall(rpcUrl, \"eth_feeHistory\", [1, \"latest\", [50]]),\n ])\n\n const nonce = BigInt(nonceResult as string)\n\n // Add 20% buffer to gas estimate to avoid out-of-gas\n const rawGasLimit = BigInt(gasEstimateResult as string)\n const gasLimit = (rawGasLimit * 120n) / 100n\n\n // Extract fee data from eth_feeHistory\n const feeHistory = feeDataResult as {\n baseFeePerGas: string[]\n reward?: string[][]\n }\n const latestBaseFee = BigInt(\n feeHistory.baseFeePerGas[1] ?? feeHistory.baseFeePerGas[0],\n )\n const maxPriorityFeePerGas = feeHistory.reward?.[0]?.[0]\n ? BigInt(feeHistory.reward[0][0])\n : 1_500_000_000n // 1.5 gwei default\n\n // maxFeePerGas = 2 * baseFee + maxPriorityFeePerGas (same formula as ethers.js)\n const maxFeePerGas = latestBaseFee * 2n + maxPriorityFeePerGas\n\n return { nonce, gasLimit, maxFeePerGas, maxPriorityFeePerGas }\n }\n\n /** Make a single JSON-RPC call */\n private async rpcCall(\n rpcUrl: string,\n method: string,\n params: unknown[],\n ): Promise<unknown> {\n const response = await fetch(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method,\n params,\n }),\n })\n\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `Turnkey RPC ${method} failed (${response.status}): ${body}`,\n )\n }\n\n const data = (await response.json()) as {\n result?: unknown\n error?: { message: string }\n }\n\n if (data.error) {\n throw new Error(`Turnkey RPC ${method} error: ${data.error.message}`)\n }\n\n return data.result\n }\n}\n\n/**\n * RLP-encode an unsigned EIP-1559 (type 2) transaction and return the\n * hex string without 0x prefix, as expected by Turnkey's sign_transaction API.\n *\n * EIP-1559 unsigned tx encoding:\n * 0x02 || RLP([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas,\n * gasLimit, to, value, data, accessList])\n *\n * Gas fields must be populated via RPC before calling this function —\n * Turnkey is a pure signing service and does not estimate gas.\n *\n * @see https://eips.ethereum.org/EIPS/eip-1559\n * @see https://github.com/tkhq/sdk/blob/main/packages/ethers/src/index.ts\n */\nexport function rlpEncodeEip1559Tx(tx: {\n chainId: number\n nonce: bigint\n maxPriorityFeePerGas: bigint\n maxFeePerGas: bigint\n gasLimit: bigint\n to: string\n data: string\n value: string\n}): string {\n const chainIdBytes = bigIntToBytes(BigInt(tx.chainId))\n const nonce = bigIntToBytes(tx.nonce)\n const maxPriorityFeePerGas = bigIntToBytes(tx.maxPriorityFeePerGas)\n const maxFeePerGas = bigIntToBytes(tx.maxFeePerGas)\n const gasLimit = bigIntToBytes(tx.gasLimit)\n const toBytes = hexToBytes(tx.to)\n const valueBytes =\n tx.value === \"0\" ? new Uint8Array(0) : bigIntToBytes(BigInt(tx.value))\n const dataBytes = tx.data ? hexToBytes(tx.data) : new Uint8Array(0)\n\n // RLP-encode the 9-element list\n const fields = [\n rlpEncodeBytes(chainIdBytes),\n rlpEncodeBytes(nonce),\n rlpEncodeBytes(maxPriorityFeePerGas),\n rlpEncodeBytes(maxFeePerGas),\n rlpEncodeBytes(gasLimit),\n rlpEncodeBytes(toBytes),\n rlpEncodeBytes(valueBytes),\n rlpEncodeBytes(dataBytes),\n rlpEncodeList([]), // empty access list\n ]\n\n const rlpList = rlpEncodeList(fields)\n\n // EIP-1559 envelope: 0x02 prefix + RLP list\n const result = new Uint8Array(1 + rlpList.length)\n result[0] = 0x02\n result.set(rlpList, 1)\n\n return bytesToHex(result)\n}\n\n/** RLP-encode a byte array */\nfunction rlpEncodeBytes(bytes: Uint8Array): Uint8Array {\n if (bytes.length === 1 && bytes[0] < 0x80) {\n return bytes\n }\n if (bytes.length === 0) {\n return new Uint8Array([0x80])\n }\n if (bytes.length <= 55) {\n const result = new Uint8Array(1 + bytes.length)\n result[0] = 0x80 + bytes.length\n result.set(bytes, 1)\n return result\n }\n const lenBytes = bigIntToBytes(BigInt(bytes.length))\n const result = new Uint8Array(1 + lenBytes.length + bytes.length)\n result[0] = 0xb7 + lenBytes.length\n result.set(lenBytes, 1)\n result.set(bytes, 1 + lenBytes.length)\n return result\n}\n\n/** RLP-encode a list of already-RLP-encoded items */\nfunction rlpEncodeList(items: Uint8Array[]): Uint8Array {\n let totalLen = 0\n for (const item of items) totalLen += item.length\n\n if (totalLen <= 55) {\n const result = new Uint8Array(1 + totalLen)\n result[0] = 0xc0 + totalLen\n let offset = 1\n for (const item of items) {\n result.set(item, offset)\n offset += item.length\n }\n return result\n }\n\n const lenBytes = bigIntToBytes(BigInt(totalLen))\n const result = new Uint8Array(1 + lenBytes.length + totalLen)\n result[0] = 0xf7 + lenBytes.length\n result.set(lenBytes, 1)\n let offset = 1 + lenBytes.length\n for (const item of items) {\n result.set(item, offset)\n offset += item.length\n }\n return result\n}\n\n/** Convert a BigInt to minimal big-endian byte representation */\nfunction bigIntToBytes(value: bigint): Uint8Array {\n if (value === 0n) return new Uint8Array(0)\n const hex = value.toString(16)\n const padded = hex.length % 2 === 0 ? hex : `0${hex}`\n return hexToBytes(padded)\n}\n\n/** Convert a hex string to Uint8Array */\nfunction hexToBytes(hex: string): Uint8Array {\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex\n const bytes = new Uint8Array(clean.length / 2)\n for (let i = 0; i < clean.length; i += 2) {\n bytes[i / 2] = Number.parseInt(clean.slice(i, i + 2), 16)\n }\n return bytes\n}\n\n/** Convert Uint8Array to hex string */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, \"0\"))\n .join(\"\")\n}\n\n/**\n * Convert an ECDSA signature from IEEE P1363 format (raw r||s) to DER encoding.\n * Web Crypto's crypto.subtle.sign returns P1363 (64 bytes for P-256: r[32] || s[32]).\n * Turnkey's stamp auth expects DER-encoded signatures (ASN.1 SEQUENCE of two INTEGERs).\n * @see https://github.com/tkhq/sdk/blob/main/packages/api-key-stamper\n */\nexport function p1363ToDer(p1363: Uint8Array): Uint8Array {\n const r = p1363.subarray(0, 32)\n const s = p1363.subarray(32, 64)\n\n const rDer = integerToDer(r)\n const sDer = integerToDer(s)\n\n const seqLen = rDer.length + sDer.length\n const result = new Uint8Array(2 + seqLen)\n result[0] = 0x30 // SEQUENCE tag\n result[1] = seqLen\n result.set(rDer, 2)\n result.set(sDer, 2 + rDer.length)\n return result\n}\n\n/** Encode a big-endian unsigned integer as an ASN.1 DER INTEGER */\nfunction integerToDer(bytes: Uint8Array): Uint8Array {\n // Strip leading zeros\n let start = 0\n while (start < bytes.length - 1 && bytes[start] === 0) start++\n const stripped = bytes.subarray(start)\n\n // If high bit is set, prepend a 0x00 pad byte (ASN.1 INTEGER sign encoding)\n const needsPad = stripped[0] >= 0x80\n const len = stripped.length + (needsPad ? 1 : 0)\n\n const result = new Uint8Array(2 + len)\n result[0] = 0x02 // INTEGER tag\n result[1] = len\n if (needsPad) {\n result[2] = 0x00\n result.set(stripped, 3)\n } else {\n result.set(stripped, 2)\n }\n return result\n}\n\n/**\n * Wrap a raw 32-byte P-256 private key in a PKCS#8 DER envelope.\n * Web Crypto's importKey(\"pkcs8\") requires the DER-encoded structure,\n * not just the raw key bytes.\n */\nfunction derEncodeP256PrivateKey(rawKey: Uint8Array): ArrayBuffer {\n // PKCS#8 header for P-256 (secp256r1) private key\n const header = new Uint8Array([\n 0x30,\n 0x41, // SEQUENCE (65 bytes)\n 0x02,\n 0x01,\n 0x00, // INTEGER 0 (version)\n 0x30,\n 0x13, // SEQUENCE (19 bytes) - AlgorithmIdentifier\n 0x06,\n 0x07, // OID (7 bytes) - id-ecPublicKey\n 0x2a,\n 0x86,\n 0x48,\n 0xce,\n 0x3d,\n 0x02,\n 0x01,\n 0x06,\n 0x08, // OID (8 bytes) - secp256r1\n 0x2a,\n 0x86,\n 0x48,\n 0xce,\n 0x3d,\n 0x03,\n 0x01,\n 0x07,\n 0x04,\n 0x27, // OCTET STRING (39 bytes)\n 0x30,\n 0x25, // SEQUENCE (37 bytes)\n 0x02,\n 0x01,\n 0x01, // INTEGER 1 (version)\n 0x04,\n 0x20, // OCTET STRING (32 bytes) - private key\n ])\n\n const result = new Uint8Array(header.length + rawKey.length)\n result.set(header)\n result.set(rawKey, header.length)\n return result.buffer\n}\n","/**\n * AUTO-GENERATED by scripts/sync-chains.ts — DO NOT EDIT.\n * Source of truth: OpenSea REST API + scripts/chain-data.json\n * Run `pnpm sync-chains` to regenerate.\n */\n\nexport const CHAIN_IDS: Record<string, number> = {\n ethereum: 1,\n mainnet: 1,\n optimism: 10,\n unichain: 130,\n polygon: 137,\n matic: 137,\n monad: 143,\n shape: 360,\n flow: 747,\n hyperevm: 999,\n sei: 1329,\n soneium: 1868,\n ronin: 2020,\n abstract: 2741,\n megaeth: 4326,\n somnia: 5031,\n b3: 8333,\n base: 8453,\n ape_chain: 33139,\n apechain: 33139,\n arbitrum: 42161,\n avalanche: 43114,\n gunzilla: 43419,\n ink: 57073,\n animechain: 69000,\n bera_chain: 80094,\n berachain: 80094,\n blast: 81457,\n zora: 7777777,\n}\n\n/**\n * Resolve a chain identifier to a numeric EVM chain ID.\n * Accepts a known chain name (e.g. \"base\") or a numeric string / number.\n */\nexport function resolveChainId(chain: string | number): number {\n if (typeof chain === \"number\") return chain\n const asNum = Number(chain)\n if (!Number.isNaN(asNum) && Number.isInteger(asNum)) return asNum\n const id = CHAIN_IDS[chain]\n if (id === undefined) {\n throw new Error(\n `Unknown chain \"${chain}\". Pass a numeric chain ID or use a known name: ${Object.keys(CHAIN_IDS).join(\", \")}`,\n )\n }\n return id\n}\n","import type { WalletAdapter } from \"./adapter.js\"\nimport { FireblocksAdapter } from \"./fireblocks.js\"\nimport { PrivateKeyAdapter } from \"./private-key.js\"\nimport { PrivyAdapter } from \"./privy.js\"\nimport { TurnkeyAdapter } from \"./turnkey.js\"\n\nexport type {\n TransactionRequest,\n TransactionResult,\n WalletAdapter,\n} from \"./adapter.js\"\nexport { CHAIN_IDS, resolveChainId } from \"./chains.js\"\nexport { FireblocksAdapter } from \"./fireblocks.js\"\nexport { PrivateKeyAdapter } from \"./private-key.js\"\nexport { PrivyAdapter } from \"./privy.js\"\nexport { TurnkeyAdapter } from \"./turnkey.js\"\n\nexport type WalletProvider = \"privy\" | \"turnkey\" | \"fireblocks\" | \"private-key\"\n\nexport const WALLET_PROVIDERS: WalletProvider[] = [\n \"privy\",\n \"turnkey\",\n \"fireblocks\",\n \"private-key\",\n]\n\n/**\n * Create a WalletAdapter from the current environment.\n *\n * When no provider is specified, auto-detects based on which\n * environment variables are set. Priority: Turnkey > Fireblocks > PrivateKey > Privy.\n * If no provider-specific vars are found, defaults to Privy.\n */\nexport function createWalletFromEnv(provider?: WalletProvider): WalletAdapter {\n if (provider) {\n return createAdapter(provider)\n }\n\n // Auto-detect based on available env vars\n const hasTurnkey =\n !!process.env.TURNKEY_API_PUBLIC_KEY &&\n !!process.env.TURNKEY_ORGANIZATION_ID\n const hasFireblocks =\n !!process.env.FIREBLOCKS_API_KEY && !!process.env.FIREBLOCKS_VAULT_ID\n const hasPrivateKey = !!process.env.PRIVATE_KEY && !!process.env.RPC_URL\n const hasPrivy = !!process.env.PRIVY_APP_ID && !!process.env.PRIVY_APP_SECRET\n\n const detected = [\n hasTurnkey && \"turnkey\",\n hasFireblocks && \"fireblocks\",\n hasPrivateKey && \"private-key\",\n hasPrivy && \"privy\",\n ].filter(Boolean) as WalletProvider[]\n\n if (detected.length > 1) {\n console.warn(\n `WARNING: Multiple wallet providers detected: ${detected.join(\", \")}. ` +\n `Using ${detected[0]}. Set --wallet-provider explicitly to avoid ambiguity.`,\n )\n }\n\n if (hasTurnkey) return TurnkeyAdapter.fromEnv()\n if (hasFireblocks) return FireblocksAdapter.fromEnv()\n if (hasPrivateKey) return PrivateKeyAdapter.fromEnv()\n\n // Default to Privy\n return PrivyAdapter.fromEnv()\n}\n\nfunction createAdapter(provider: WalletProvider): WalletAdapter {\n switch (provider) {\n case \"privy\":\n return PrivyAdapter.fromEnv()\n case \"turnkey\":\n return TurnkeyAdapter.fromEnv()\n case \"fireblocks\":\n return FireblocksAdapter.fromEnv()\n case \"private-key\":\n return PrivateKeyAdapter.fromEnv()\n default:\n throw new Error(\n `Unknown wallet provider \"${provider}\". Valid providers: ${WALLET_PROVIDERS.join(\", \")}`,\n )\n }\n}\n","import { OpenSeaClient } from \"./client.js\"\nimport { checkHealth } from \"./health.js\"\nimport type {\n Account,\n AccountResolveResponse,\n AssetEvent,\n Chain,\n ChainListResponse,\n Collection,\n CollectionOrderBy,\n CollectionPaginatedResponse,\n CollectionStats,\n Contract,\n DropDetailedResponse,\n DropMintResponse,\n DropPaginatedResponse,\n EventType,\n GetTraitsResponse,\n HealthResult,\n Listing,\n NFT,\n Offer,\n OpenSeaClientConfig,\n SearchAssetType,\n SearchResponse,\n SwapQuoteResponse,\n Token,\n TokenBalancePaginatedResponse,\n TokenBalanceSortBy,\n TokenDetails,\n ValidateMetadataResponse,\n} from \"./types/index.js\"\nimport type { TransactionResult, WalletAdapter } from \"./wallet/index.js\"\nimport { resolveChainId } from \"./wallet/index.js\"\n\nfunction convertToSmallestUnit(amount: string, decimals: number): string {\n const [whole = \"0\", frac = \"\"] = amount.split(\".\")\n if (frac.length > decimals) {\n throw new Error(\n `Too many decimal places (${frac.length}) for token with ${decimals} decimals`,\n )\n }\n const paddedFrac = frac.padEnd(decimals, \"0\")\n return (\n BigInt(whole) * BigInt(10) ** BigInt(decimals) +\n BigInt(paddedFrac)\n ).toString()\n}\n\nexport async function resolveQuantity(\n client: OpenSeaClient,\n chain: string,\n tokenAddress: string,\n quantity: string,\n): Promise<string> {\n if (/^\\d+$/.test(quantity)) {\n return quantity\n }\n if (!/^\\d+\\.\\d+$/.test(quantity)) {\n throw new Error(\n `Invalid quantity \"${quantity}\": must be an integer or decimal number`,\n )\n }\n const token = await client.get<TokenDetails>(\n `/api/v2/chain/${chain}/token/${tokenAddress}`,\n )\n return convertToSmallestUnit(quantity, token.decimals)\n}\n\n/** @internal Exported for testing only */\nexport { convertToSmallestUnit as _convertToSmallestUnit }\n\nexport class OpenSeaCLI {\n private client: OpenSeaClient\n\n readonly chains: ChainsAPI\n readonly collections: CollectionsAPI\n readonly drops: DropsAPI\n readonly nfts: NFTsAPI\n readonly listings: ListingsAPI\n readonly offers: OffersAPI\n readonly events: EventsAPI\n readonly accounts: AccountsAPI\n readonly tokens: TokensAPI\n readonly search: SearchAPI\n readonly swaps: SwapsAPI\n readonly health: HealthAPI\n\n constructor(config: OpenSeaClientConfig) {\n this.client = new OpenSeaClient(config)\n this.chains = new ChainsAPI(this.client)\n this.collections = new CollectionsAPI(this.client)\n this.drops = new DropsAPI(this.client)\n this.nfts = new NFTsAPI(this.client)\n this.listings = new ListingsAPI(this.client)\n this.offers = new OffersAPI(this.client)\n this.events = new EventsAPI(this.client)\n this.accounts = new AccountsAPI(this.client)\n this.tokens = new TokensAPI(this.client)\n this.search = new SearchAPI(this.client)\n this.swaps = new SwapsAPI(this.client)\n this.health = new HealthAPI(this.client)\n }\n}\n\nclass ChainsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async list(): Promise<ChainListResponse> {\n return this.client.get(\"/api/v2/chains\")\n }\n}\n\nclass CollectionsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async get(slug: string): Promise<Collection> {\n return this.client.get<Collection>(`/api/v2/collections/${slug}`)\n }\n\n async list(options?: {\n chain?: Chain\n limit?: number\n next?: string\n orderBy?: CollectionOrderBy\n creatorUsername?: string\n includeHidden?: boolean\n }): Promise<{ collections: Collection[]; next?: string }> {\n return this.client.get(\"/api/v2/collections\", {\n chain: options?.chain,\n limit: options?.limit,\n next: options?.next,\n order_by: options?.orderBy,\n creator_username: options?.creatorUsername,\n include_hidden: options?.includeHidden,\n })\n }\n\n async stats(slug: string): Promise<CollectionStats> {\n return this.client.get<CollectionStats>(`/api/v2/collections/${slug}/stats`)\n }\n\n async traits(slug: string): Promise<GetTraitsResponse> {\n return this.client.get<GetTraitsResponse>(`/api/v2/traits/${slug}`)\n }\n\n async trending(options?: {\n timeframe?: string\n chains?: string[]\n category?: string\n limit?: number\n next?: string\n }): Promise<CollectionPaginatedResponse> {\n return this.client.get(\"/api/v2/collections/trending\", {\n timeframe: options?.timeframe,\n chains: options?.chains?.join(\",\"),\n category: options?.category,\n limit: options?.limit,\n cursor: options?.next,\n })\n }\n\n async top(options?: {\n sortBy?: string\n chains?: string[]\n category?: string\n limit?: number\n next?: string\n }): Promise<CollectionPaginatedResponse> {\n return this.client.get(\"/api/v2/collections/top\", {\n sort_by: options?.sortBy,\n chains: options?.chains?.join(\",\"),\n category: options?.category,\n limit: options?.limit,\n cursor: options?.next,\n })\n }\n}\n\nclass DropsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async list(options?: {\n type?: string\n chains?: string[]\n limit?: number\n next?: string\n }): Promise<DropPaginatedResponse> {\n return this.client.get(\"/api/v2/drops\", {\n type: options?.type,\n chains: options?.chains?.join(\",\"),\n limit: options?.limit,\n cursor: options?.next,\n })\n }\n\n async get(slug: string): Promise<DropDetailedResponse> {\n return this.client.get(`/api/v2/drops/${slug}`)\n }\n\n async mint(\n slug: string,\n options: { minter: string; quantity?: number },\n ): Promise<DropMintResponse> {\n return this.client.post(`/api/v2/drops/${slug}/mint`, {\n minter: options.minter,\n quantity: options.quantity ?? 1,\n })\n }\n}\n\nclass NFTsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async get(\n chain: Chain,\n address: string,\n identifier: string,\n ): Promise<{ nft: NFT }> {\n return this.client.get(\n `/api/v2/chain/${chain}/contract/${address}/nfts/${identifier}`,\n )\n }\n\n async listByCollection(\n slug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ nfts: NFT[]; next?: string }> {\n return this.client.get(`/api/v2/collection/${slug}/nfts`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async listByContract(\n chain: Chain,\n address: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ nfts: NFT[]; next?: string }> {\n return this.client.get(`/api/v2/chain/${chain}/contract/${address}/nfts`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async listByAccount(\n chain: Chain,\n address: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ nfts: NFT[]; next?: string }> {\n return this.client.get(`/api/v2/chain/${chain}/account/${address}/nfts`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async refresh(\n chain: Chain,\n address: string,\n identifier: string,\n ): Promise<void> {\n await this.client.post(\n `/api/v2/chain/${chain}/contract/${address}/nfts/${identifier}/refresh`,\n )\n }\n\n async getContract(chain: Chain, address: string): Promise<Contract> {\n return this.client.get(`/api/v2/chain/${chain}/contract/${address}`)\n }\n\n async validateMetadata(\n chain: Chain,\n address: string,\n identifier: string,\n options?: { ignoreCachedItemUrls?: boolean },\n ): Promise<ValidateMetadataResponse> {\n const params: Record<string, unknown> = {}\n if (options?.ignoreCachedItemUrls) {\n params.ignoreCachedItemUrls = true\n }\n return this.client.post(\n `/api/v2/chain/${chain}/contract/${address}/nfts/${identifier}/validate-metadata`,\n undefined,\n params,\n )\n }\n}\n\nclass ListingsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async all(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ listings: Listing[]; next?: string }> {\n return this.client.get(\n `/api/v2/listings/collection/${collectionSlug}/all`,\n { limit: options?.limit, next: options?.next },\n )\n }\n\n async best(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ listings: Listing[]; next?: string }> {\n return this.client.get(\n `/api/v2/listings/collection/${collectionSlug}/best`,\n { limit: options?.limit, next: options?.next },\n )\n }\n\n async bestForNFT(collectionSlug: string, tokenId: string): Promise<Listing> {\n return this.client.get(\n `/api/v2/listings/collection/${collectionSlug}/nfts/${tokenId}/best`,\n )\n }\n}\n\nclass OffersAPI {\n constructor(private client: OpenSeaClient) {}\n\n async all(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ offers: Offer[]; next?: string }> {\n return this.client.get(`/api/v2/offers/collection/${collectionSlug}/all`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async collection(\n collectionSlug: string,\n options?: { limit?: number; next?: string },\n ): Promise<{ offers: Offer[]; next?: string }> {\n return this.client.get(`/api/v2/offers/collection/${collectionSlug}`, {\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async bestForNFT(collectionSlug: string, tokenId: string): Promise<Offer> {\n return this.client.get(\n `/api/v2/offers/collection/${collectionSlug}/nfts/${tokenId}/best`,\n )\n }\n\n async traits(\n collectionSlug: string,\n options: {\n type: string\n value: string\n limit?: number\n next?: string\n },\n ): Promise<{ offers: Offer[]; next?: string }> {\n return this.client.get(\n `/api/v2/offers/collection/${collectionSlug}/traits`,\n {\n type: options.type,\n value: options.value,\n limit: options.limit,\n next: options.next,\n },\n )\n }\n}\n\nclass EventsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async list(options?: {\n eventType?: EventType\n after?: number\n before?: number\n limit?: number\n next?: string\n chain?: Chain\n }): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(\"/api/v2/events\", {\n event_type: options?.eventType,\n after: options?.after,\n before: options?.before,\n limit: options?.limit,\n next: options?.next,\n chain: options?.chain,\n })\n }\n\n async byAccount(\n address: string,\n options?: {\n eventType?: EventType\n limit?: number\n next?: string\n chain?: Chain\n },\n ): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(`/api/v2/events/accounts/${address}`, {\n event_type: options?.eventType,\n limit: options?.limit,\n next: options?.next,\n chain: options?.chain,\n })\n }\n\n async byCollection(\n collectionSlug: string,\n options?: {\n eventType?: EventType\n limit?: number\n next?: string\n },\n ): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(`/api/v2/events/collection/${collectionSlug}`, {\n event_type: options?.eventType,\n limit: options?.limit,\n next: options?.next,\n })\n }\n\n async byNFT(\n chain: Chain,\n address: string,\n identifier: string,\n options?: {\n eventType?: EventType\n limit?: number\n next?: string\n },\n ): Promise<{ asset_events: AssetEvent[]; next?: string }> {\n return this.client.get(\n `/api/v2/events/chain/${chain}/contract/${address}/nfts/${identifier}`,\n {\n event_type: options?.eventType,\n limit: options?.limit,\n next: options?.next,\n },\n )\n }\n}\n\nclass AccountsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async get(address: string): Promise<Account> {\n return this.client.get(`/api/v2/accounts/${address}`)\n }\n\n async tokens(\n address: string,\n options?: {\n chains?: string[]\n limit?: number\n sortBy?: TokenBalanceSortBy\n sortDirection?: \"asc\" | \"desc\"\n disableSpamFiltering?: boolean\n next?: string\n },\n ): Promise<TokenBalancePaginatedResponse> {\n return this.client.get(`/api/v2/account/${address}/tokens`, {\n chains: options?.chains?.join(\",\"),\n limit: options?.limit,\n sort_by: options?.sortBy,\n sort_direction: options?.sortDirection,\n disable_spam_filtering: options?.disableSpamFiltering,\n cursor: options?.next,\n })\n }\n\n async resolve(identifier: string): Promise<AccountResolveResponse> {\n return this.client.get(`/api/v2/accounts/resolve/${identifier}`)\n }\n}\n\nclass TokensAPI {\n constructor(private client: OpenSeaClient) {}\n\n async trending(options?: {\n limit?: number\n chains?: string[]\n next?: string\n }): Promise<{ tokens: Token[]; next?: string }> {\n // The tokens API uses \"cursor\" as its query param instead of \"next\".\n // The SDK accepts \"next\" for consistency with all other endpoints.\n return this.client.get(\"/api/v2/tokens/trending\", {\n limit: options?.limit,\n chains: options?.chains?.join(\",\"),\n cursor: options?.next,\n })\n }\n\n async top(options?: {\n limit?: number\n chains?: string[]\n next?: string\n }): Promise<{ tokens: Token[]; next?: string }> {\n // The tokens API uses \"cursor\" as its query param instead of \"next\".\n // The SDK accepts \"next\" for consistency with all other endpoints.\n return this.client.get(\"/api/v2/tokens/top\", {\n limit: options?.limit,\n chains: options?.chains?.join(\",\"),\n cursor: options?.next,\n })\n }\n\n async get(chain: Chain, address: string): Promise<TokenDetails> {\n return this.client.get(`/api/v2/chain/${chain}/token/${address}`)\n }\n}\n\nclass SearchAPI {\n constructor(private client: OpenSeaClient) {}\n\n async query(\n query: string,\n options?: {\n assetTypes?: SearchAssetType[]\n chains?: string[]\n limit?: number\n },\n ): Promise<SearchResponse> {\n return this.client.get<SearchResponse>(\"/api/v2/search\", {\n query,\n asset_types: options?.assetTypes?.join(\",\"),\n chains: options?.chains?.join(\",\"),\n limit: options?.limit,\n })\n }\n}\n\nexport class SwapsAPI {\n constructor(private client: OpenSeaClient) {}\n\n async quote(options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n address: string\n slippage?: number\n recipient?: string\n }): Promise<SwapQuoteResponse> {\n return this.client.get(\"/api/v2/swap/quote\", {\n from_chain: options.fromChain,\n from_address: options.fromAddress,\n to_chain: options.toChain,\n to_address: options.toAddress,\n quantity: options.quantity,\n address: options.address,\n slippage: options.slippage,\n recipient: options.recipient,\n })\n }\n\n /**\n * Get a swap quote and execute all transactions using the provided wallet adapter.\n * Returns an array of transaction results (one per transaction in the quote).\n *\n * @param options - Swap parameters (chains, addresses, quantity, etc.)\n * @param wallet - Wallet adapter to sign and send transactions\n * @param callbacks - Optional callbacks for progress reporting and skipped txs\n */\n async execute(\n options: {\n fromChain: string\n fromAddress: string\n toChain: string\n toAddress: string\n quantity: string\n slippage?: number\n recipient?: string\n address?: string\n },\n wallet: WalletAdapter,\n callbacks?: {\n onQuote?: (quote: SwapQuoteResponse) => void\n onSending?: (tx: { to: string; chain: string; chainId: number }) => void\n onSkipped?: (tx: { chain: string; reason: string }) => void\n },\n ): Promise<TransactionResult[]> {\n const address = options.address ?? (await wallet.getAddress())\n const quote = await this.quote({ ...options, address })\n\n callbacks?.onQuote?.(quote)\n\n if (!quote.transactions || quote.transactions.length === 0) {\n throw new Error(\n \"Swap quote returned zero transactions — the swap may not be available for these tokens/chains.\",\n )\n }\n\n const results: TransactionResult[] = []\n\n for (const tx of quote.transactions) {\n if (!tx.to) {\n callbacks?.onSkipped?.({\n chain: tx.chain,\n reason: \"missing 'to' address\",\n })\n continue\n }\n const chainId = resolveChainId(tx.chain)\n callbacks?.onSending?.({ to: tx.to, chain: tx.chain, chainId })\n const result = await wallet.sendTransaction({\n to: tx.to,\n data: tx.data,\n value: tx.value ?? \"0\",\n chainId,\n })\n results.push(result)\n }\n\n if (results.length === 0) {\n throw new Error(\n \"All swap transactions were skipped (no valid 'to' addresses). The quote may be malformed.\",\n )\n }\n\n return results\n }\n}\n\nclass HealthAPI {\n constructor(private client: OpenSeaClient) {}\n\n async check(): Promise<HealthResult> {\n return checkHealth(this.client)\n }\n}\n","import { Command } from \"commander\"\nimport type { OpenSeaClient } from \"../client.js\"\nimport type { OutputFormat } from \"../output.js\"\nimport { formatOutput } from \"../output.js\"\nimport { parseIntOption } from \"../parse.js\"\nimport type { Chain, Token, TokenDetails } from \"../types/index.js\"\n\nexport function tokensCommand(\n getClient: () => OpenSeaClient,\n getFormat: () => OutputFormat,\n): Command {\n const cmd = new Command(\"tokens\").description(\n \"Query trending tokens, top tokens, and token details\",\n )\n\n cmd\n .command(\"trending\")\n .description(\"Get trending tokens based on OpenSea's trending score\")\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: { chains?: string; limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{ tokens: Token[]; next?: string }>(\n \"/api/v2/tokens/trending\",\n {\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n // Tokens API uses \"cursor\" instead of \"next\" as the query param\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"top\")\n .description(\"Get top tokens ranked by 24-hour trading volume\")\n .option(\"--chains <chains>\", \"Comma-separated list of chains to filter by\")\n .option(\"--limit <limit>\", \"Number of results (max 100)\", \"20\")\n .option(\"--next <cursor>\", \"Pagination cursor\")\n .action(\n async (options: { chains?: string; limit: string; next?: string }) => {\n const client = getClient()\n const result = await client.get<{ tokens: Token[]; next?: string }>(\n \"/api/v2/tokens/top\",\n {\n chains: options.chains,\n limit: parseIntOption(options.limit, \"--limit\"),\n // Tokens API uses \"cursor\" instead of \"next\" as the query param\n cursor: options.next,\n },\n )\n console.log(formatOutput(result, getFormat()))\n },\n )\n\n cmd\n .command(\"get\")\n .description(\"Get detailed information about a specific token\")\n .argument(\"<chain>\", \"Blockchain chain\")\n .argument(\"<address>\", \"Token contract address\")\n .action(async (chain: string, address: string) => {\n const client = getClient()\n const result = await client.get<TokenDetails>(\n `/api/v2/chain/${chain as Chain}/token/${address}`,\n )\n console.log(formatOutput(result, getFormat()))\n })\n\n return cmd\n}\n"],"mappings":"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","names":["Command","lines","getClient","getFormat","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command","result","result","offset","getClient","getFormat","Command","Command","getClient","getFormat","Command","Command"]}
|