@medialane/sdk 0.72.0 → 0.74.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/chains.ts","../src/fee/config.ts","../src/config.ts","../src/utils/address.ts","../src/utils/retry.ts","../src/api/client.ts","../src/types/api.ts","../src/constants.ts","../src/routes.ts","../src/services/registry.ts","../src/utils/token.ts","../src/utils/bigint.ts","../src/utils/rpc.ts"],"names":["z","keccak_256","base58","base32","SN"],"mappings":"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","file":"index.cjs","sourcesContent":["// Single source of per-chain coordinates for Medialane's own services\n// (spec 2026-06-13 §3.1, Decision A). Keyed by CHAIN ALONE — Medialane is\n// mainnet-only, so there is no network axis (refines decisions.md D-9).\n\n/** Mirrors the backend Prisma `Chain` enum. */\nexport const CHAINS = [\"STARKNET\", \"ETHEREUM\", \"SOLANA\", \"BASE\", \"STELLAR\", \"BITCOIN\"] as const;\nexport type Chain = (typeof CHAINS)[number];\n\n/** Starknet coordinates of Medialane services + venues. All fields optional\n * because not every service exists on every chain. */\nexport interface StarknetCoordinates {\n rpcUrl: string;\n marketplace721?: `0x${string}`;\n marketplace721ClassHash?: `0x${string}`;\n marketplace721StartBlock?: number;\n marketplace1155?: `0x${string}`;\n marketplace1155ClassHash?: `0x${string}`;\n marketplace1155StartBlock?: number;\n collection721?: `0x${string}`;\n collection721StartBlock?: number;\n ipNftClassHash?: `0x${string}`;\n ipCollectionClassHash?: `0x${string}`;\n collection1155?: `0x${string}`;\n collection1155FactoryClassHash?: `0x${string}`;\n collection1155ClassHash?: `0x${string}`;\n collection1155StartBlock?: number;\n popFactory?: `0x${string}`;\n popCollectionClassHash?: `0x${string}`;\n dropFactory?: `0x${string}`;\n dropCollectionClassHash?: `0x${string}`;\n nftComments?: `0x${string}`;\n creatorCoinFactory?: `0x${string}`;\n creatorCoinEkuboLauncher?: `0x${string}`;\n creatorCoinClassHash?: `0x${string}`;\n creatorCoinFactoryClassHash?: `0x${string}`;\n creatorCoinStartBlock?: number;\n ekuboCore?: `0x${string}`;\n ipTicketsFactory?: `0x${string}`;\n ipTicketCollectionClassHash?: `0x${string}`;\n ipTicketsFactoryClassHash?: `0x${string}`;\n ipTicketsStartBlock?: number;\n ipClubFactory?: `0x${string}`;\n ipClubFactoryClassHash?: `0x${string}`;\n ipClubCollectionClassHash?: `0x${string}`;\n ipClubFactoryStartBlock?: number;\n ipSponsorship?: `0x${string}`;\n ipSponsorshipClassHash?: `0x${string}`;\n ipSponsorshipStartBlock?: number;\n}\n\n/** Coordinates per chain. Only STARKNET is populated today; adding a chain\n * means adding an entry here (litmus test, spec §7). */\n/** EVM coordinates — one shape for Ethereum and Base (same bytecode, two\n * chains). Populated at deploy time (federation Phase 4). */\nexport interface EvmCoordinates {\n rpcUrl: string;\n marketplace721?: `0x${string}`;\n marketplace721StartBlock?: number;\n marketplace1155?: `0x${string}`;\n marketplace1155StartBlock?: number;\n mipRegistry?: `0x${string}`;\n mipRegistryStartBlock?: number;\n mipEditionsRegistry?: `0x${string}`;\n mipEditionsRegistryStartBlock?: number;\n}\n\n/** Solana coordinates — base58 program ids. Populated at deploy time. */\nexport interface SolanaCoordinates {\n rpcUrl: string;\n mipCollectionsProgram?: string;\n marketplaceProgram?: string;\n startSlot?: number;\n}\n\n/** Stellar (Soroban) coordinates — strkey contract ids. Populated at deploy\n * time; the registry takes the collection WASM hash as a constructor arg. */\nexport interface StellarCoordinates {\n rpcUrl: string;\n mipRegistry?: string;\n marketplace?: string;\n collectionWasmHash?: string;\n startLedger?: number;\n}\n\n/** Per-chain coordinate shapes. Every chain is an equal entry — no chain is\n * privileged in core (chain-sovereignty I2/I4). */\nexport interface CoordinatesByChain {\n STARKNET?: StarknetCoordinates;\n ETHEREUM?: EvmCoordinates;\n BASE?: EvmCoordinates;\n SOLANA?: SolanaCoordinates;\n STELLAR?: StellarCoordinates;\n BITCOIN?: never;\n}\n\n/** @deprecated Renamed — use `StarknetCoordinates` (coordinates are per-chain-shaped). */\nexport type ChainCoordinates = StarknetCoordinates;\n\nconst COORDINATES: CoordinatesByChain = {\n STARKNET: {\n rpcUrl: \"https://rpc.starknet.lava.build\",\n marketplace721: \"0x03eda9a2b6ad90845a43591bac8083ebaf677d51fdf20f503b2c01889e3131fc\",\n marketplace721ClassHash: \"0x0700d9230d07e5203e27778c0dc70f9134d2b25bf319f7cf8348dc66a6923e90\",\n marketplace721StartBlock: 11198146,\n marketplace1155: \"0x07c4ce1c19ea48cc11135ed22b19ff745f5aec508c3828593002e4f76fdb1b38\",\n marketplace1155ClassHash: \"0x0242f5c388da7cee2d99e2a69453c8159bf927fbec4e797a3cfdcbbcb5b68328\",\n marketplace1155StartBlock: 11198267,\n collection721: \"0x0225c3ae09506b8d97adc39649ca740dad5aac195b7f5f0441cc1852947acaea\",\n collection721StartBlock: 11198496,\n ipNftClassHash: \"0x012d3ae40ba35c7e2be0946532dac60e48932447912fdf96b674da67c029b9cc\",\n ipCollectionClassHash: \"0x022155a1a130a40e57aac4b89c07fab3f616bc351b1270fc40f756b963afe8b4\",\n collection1155: \"0x015368976d46fae5bfa1c58600f641d5aa5dbbf53ebc6b78aa3922194aad3551\",\n collection1155FactoryClassHash: \"0x04eb6b419770f13bd191f120b9fc9ee624c0613ad4490062d293ca2016b3b1d2\",\n collection1155ClassHash: \"0x06cf3f5a2322dac35e07a6064a5b8802f19fda8aa3f4726f0cb7bc05dea1bd78\",\n collection1155StartBlock: 11199527,\n popFactory: \"0x00b32c34b427d8f346b5843ada6a37bd3368d879fc752cd52b68a87287f60111\",\n popCollectionClassHash: \"0x077c421686f10851872561953ea16898d933364b7f8937a5d7e2b1ba0a36263f\",\n dropFactory: \"0x03587f42e29daee1b193f6cf83bf8627908ed6632d0d83fcb26225c50547d800\",\n dropCollectionClassHash: \"0x00092e72cdb63067521e803aaf7d4101c3e3ce026ae6bc045ec4228027e58282\",\n nftComments: \"0x02cdac70c94447189af0389dfea63f4d5e4154ea8a563de288a5ab1c39e37843\",\n creatorCoinFactory: \"0x50fa807b5274079fb19374673d7bab6d2dc3af7e1032ea43eb6e44bcbde4c3c\",\n creatorCoinEkuboLauncher: \"0x4f7fceb5ac10f12f9544a09580592e5bdf1b7f04f48765eecf12286d8ccb7b4\",\n creatorCoinClassHash: \"0x743e4c8a5b96bb83bbf4af04edbbb482d5ece89eed9b729a79fb7df0cd0b6b6\",\n creatorCoinFactoryClassHash: \"0x51765926b1344c9a20b8cd4b5abe7b7d47375ae97cf6804db3ea5d4b05a9b55\",\n creatorCoinStartBlock: 10474544,\n ekuboCore: \"0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b\",\n ipTicketsFactory: \"0x0767bf5b57e1f812463159b5ed683183e1b0c3f942b74871b5c6cd6a93c15e99\",\n ipTicketCollectionClassHash: \"0x0449e8eb7c117740d07cb8e0157d32c8ba3d19d1cfd2784ed5e139f5a1e04acc\",\n ipTicketsFactoryClassHash: \"0x04a739ac3a673ebd0db96bb24475600797c3ed34827e79517f9b2b1640276e6a\",\n ipTicketsStartBlock: 11933694,\n ipClubFactory: \"0x06a0b0be16d70c78f2e18119dbf90e5911cbfd5d8d484bc555dc61d96f56a2b9\",\n ipClubFactoryClassHash: \"0x05d9d431bd3532b1fa4d5bab572f49c5ad8034ee3cc83951aa41ae82c9cad266\",\n ipClubCollectionClassHash: \"0x05b8477c72e6bf0cf64967d71155021fd4d77d9a57e8805c6b40709121c002c5\",\n ipClubFactoryStartBlock: 11928775,\n // v3 redesign (deployed 2026-07-15): single contract is both the\n // offer/bid/proposal registry and the license collection (embeds\n // ERC721Component directly) — no separate receipt contract, no\n // set_minter bootstrap. Supersedes the 2026-07-02 v2 address, which had\n // zero offers/licenses ever issued (clean cutover, no reclassification).\n ipSponsorship: \"0x03729ebe0fedf29ec97fca34db09174772af7f870af26a26e024a61040143e5c\",\n ipSponsorshipClassHash: \"0x0626daac2ed7e2bf630ef5b10104b3202db1559216c0c1a504c0e99be2fbfec3\",\n ipSponsorshipStartBlock: 11896456,\n },\n};\n\nexport function getCoordinates(chain: \"STARKNET\"): StarknetCoordinates;\nexport function getCoordinates(chain: \"ETHEREUM\" | \"BASE\"): EvmCoordinates;\nexport function getCoordinates(chain: \"SOLANA\"): SolanaCoordinates;\nexport function getCoordinates(chain: \"STELLAR\"): StellarCoordinates;\nexport function getCoordinates(\n chain: Chain,\n): StarknetCoordinates | EvmCoordinates | SolanaCoordinates | StellarCoordinates;\nexport function getCoordinates(\n chain: Chain,\n): StarknetCoordinates | EvmCoordinates | SolanaCoordinates | StellarCoordinates {\n const c = COORDINATES[chain];\n if (!c) throw new Error(`No coordinates configured for chain \"${chain}\"`);\n return c;\n}\n\nexport const DEFAULT_CHAIN: Chain = \"STARKNET\";\n\n/** Typed Starknet coordinates for Starknet-only modules; throws when the\n * client is scoped to another chain. */\nexport function getStarknetCoordinates(chain: Chain): StarknetCoordinates {\n if (chain !== \"STARKNET\") {\n throw new Error(`This module is Starknet-only (client chain: \"${chain}\")`);\n }\n return getCoordinates(\"STARKNET\");\n}\n","import { z } from \"zod\";\n\nexport const FeeConfigSchema = z.object({\n enabled: z.boolean().default(true),\n fundAddress: z.string().min(1).optional(),\n marketplaceBps: z.number().int().min(0).max(10000).default(100),\n launchpadBps: z.number().int().min(0).max(10000).default(100),\n});\n\nexport type FeeConfig = z.input<typeof FeeConfigSchema>;\n\nexport interface ResolvedFeeConfig {\n enabled: boolean;\n fundAddress: string | undefined;\n marketplaceBps: number;\n launchpadBps: number;\n}\n\nexport function resolveFeeConfig(raw: FeeConfig | undefined): ResolvedFeeConfig {\n const p = FeeConfigSchema.parse(raw ?? {});\n return {\n enabled: p.enabled,\n fundAddress: p.fundAddress,\n marketplaceBps: p.marketplaceBps,\n launchpadBps: p.launchpadBps,\n };\n}\n","import { z } from \"zod\";\nimport { CHAINS, getCoordinates, DEFAULT_CHAIN, type Chain } from \"./chains.js\";\nimport type { RetryOptions } from \"./utils/retry.js\";\nimport { FeeConfigSchema, resolveFeeConfig, type ResolvedFeeConfig } from \"./fee/index.js\";\n\nexport const MedialaneConfigSchema = z.object({\n // Chain-scoped client (spec 2026-06-13 Decision B): one client per chain,\n // coordinates resolved from the registry. Replaces the removed `network` axis.\n chain: z.enum(CHAINS).default(DEFAULT_CHAIN),\n rpcUrl: z.string().url().optional(),\n backendUrl: z.string().url().optional(),\n apiKey: z.string().optional(),\n // Per-contract overrides remain for tests/forks; default from the registry.\n marketplace721Contract: z.string().optional(),\n marketplaceContract: z.string().optional(),\n marketplace1155Contract: z.string().optional(),\n collection721Contract: z.string().optional(),\n collectionContract: z.string().optional(),\n collection1155Contract: z.string().optional(),\n retryOptions: z.object({\n maxAttempts: z.number().int().min(1).max(10).optional(),\n baseDelayMs: z.number().int().min(0).optional(),\n maxDelayMs: z.number().int().min(0).optional(),\n }).optional(),\n feeConfig: FeeConfigSchema.optional(),\n});\n\nexport type MedialaneConfig = z.input<typeof MedialaneConfigSchema>;\n\nexport interface ResolvedConfig {\n chain: Chain;\n rpcUrl: string;\n backendUrl: string | undefined;\n apiKey: string | undefined;\n marketplace721Contract: string;\n marketplaceContract: string;\n marketplace1155Contract: string;\n collection721Contract: string;\n collectionContract: string;\n collection1155Contract: string;\n retryOptions?: RetryOptions;\n feeConfig: ResolvedFeeConfig;\n}\n\nexport function resolveConfig(raw: MedialaneConfig): ResolvedConfig {\n const parsed = MedialaneConfigSchema.parse(raw);\n const coords = getCoordinates(parsed.chain);\n // The resolved contract fields are the Starknet module surface; on other\n // chains they stay unset and the per-chain adapters resolve their own\n // coordinates.\n const sn = (parsed.chain === \"STARKNET\" ? coords : {}) as import(\"./chains.js\").StarknetCoordinates;\n\n const marketplace721Contract =\n parsed.marketplace721Contract ?? parsed.marketplaceContract ?? sn.marketplace721!;\n const collection721Contract =\n parsed.collection721Contract ?? parsed.collectionContract ?? sn.collection721!;\n\n return {\n chain: parsed.chain,\n rpcUrl: parsed.rpcUrl ?? coords.rpcUrl,\n backendUrl: parsed.backendUrl,\n apiKey: parsed.apiKey,\n marketplace721Contract,\n marketplaceContract: marketplace721Contract,\n marketplace1155Contract: parsed.marketplace1155Contract ?? sn.marketplace1155!,\n collection721Contract,\n collectionContract: collection721Contract,\n collection1155Contract: parsed.collection1155Contract ?? sn.collection1155!,\n retryOptions: parsed.retryOptions,\n feeConfig: resolveFeeConfig(parsed.feeConfig),\n };\n}\n","import { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport { base32, base58 } from \"@scure/base\";\nimport type { Chain } from \"../chains.js\";\n\n/**\n * Normalize an address to its chain's canonical form. The single source of\n * address normalization across Medialane (07-identity §I; spec 2026-06-13 §3.2).\n * `medialane-backend` re-exports this; do not maintain a parallel copy.\n *\n * - STARKNET: 0x-prefixed 64-char lowercase hex (felt, zero-padded).\n * - ETHEREUM / BASE: EIP-55 mixed-case checksum.\n * - SOLANA: base58, validated as a 32-byte public key, returned verbatim.\n * - STELLAR: strkey (G… account / C… contract), CRC16-XModem-verified,\n * canonical uppercase.\n * - BITCOIN: not implemented — a non-foreclosed seam, gated on a future\n * Bitcoin fork (chain-sovereignty §2); never a built path today.\n */\nexport function normalizeAddress(chain: Chain, address: string): string {\n switch (chain) {\n case \"STARKNET\":\n return normalizeStarknet(address);\n case \"ETHEREUM\":\n case \"BASE\":\n return normalizeEvm(address);\n case \"SOLANA\":\n return normalizeSolana(address);\n case \"STELLAR\":\n return normalizeStellar(address);\n case \"BITCOIN\":\n throw new Error(\"BITCOIN address normalization not implemented\");\n }\n}\n\nfunction normalizeStarknet(address: string): string {\n try {\n const hex = BigInt(address).toString(16);\n return \"0x\" + hex.padStart(64, \"0\").toLowerCase();\n } catch {\n throw new Error(`Invalid STARKNET address: \"${address}\"`);\n }\n}\n\nfunction normalizeEvm(address: string): string {\n const m = /^0x([0-9a-fA-F]{40})$/.exec(address);\n if (!m) throw new Error(`Invalid ETHEREUM/BASE address: \"${address}\"`);\n const lower = m[1].toLowerCase();\n // EIP-55: keccak256 of the lowercase hex (ASCII, no 0x); uppercase the i-th\n // hex char when the i-th nibble of the hash is >= 8.\n const hash = keccak_256(new TextEncoder().encode(lower));\n let out = \"0x\";\n for (let i = 0; i < 40; i++) {\n const nibble = (hash[i >> 1]! >> (i % 2 === 0 ? 4 : 0)) & 0xf;\n out += nibble >= 8 ? lower[i]!.toUpperCase() : lower[i];\n }\n return out;\n}\n\nfunction normalizeSolana(address: string): string {\n try {\n const bytes = base58.decode(address);\n if (bytes.length !== 32) throw new Error(\"not a 32-byte key\");\n return address; // base58 is canonical and case-sensitive — return as-is\n } catch {\n throw new Error(`Invalid SOLANA address: \"${address}\"`);\n }\n}\n\n/** Stellar strkey version bytes: 'G' account (6<<3), 'C' contract (2<<3). */\nconst STELLAR_VERSION_BYTES = new Set([6 << 3, 2 << 3]);\n\nfunction normalizeStellar(address: string): string {\n const upper = address.toUpperCase();\n if (!/^[GC][A-Z2-7]{55}$/.test(upper)) {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n let decoded: Uint8Array;\n try {\n decoded = base32.decode(upper);\n } catch {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n if (decoded.length !== 35 || !STELLAR_VERSION_BYTES.has(decoded[0]!)) {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n const payload = decoded.subarray(0, 33);\n const checksum = decoded[33]! | (decoded[34]! << 8);\n if (crc16xmodem(payload) !== checksum) {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n return upper;\n}\n\n/** CRC16-XModem (poly 0x1021, init 0x0000) — the strkey checksum. */\nfunction crc16xmodem(bytes: Uint8Array): number {\n let crc = 0;\n for (const byte of bytes) {\n crc ^= byte << 8;\n for (let i = 0; i < 8; i++) {\n crc = crc & 0x8000 ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff;\n }\n }\n return crc;\n}\n\n/**\n * Normalize a felt/hash (tx hash, order hash) to 0x-prefixed 64-char lowercase\n * hex. Starknet-shaped; chain-scoped at call sites that handle other chains'\n * hashes.\n */\nexport function normalizeHash(hash: string): string {\n try {\n const hex = BigInt(hash).toString(16);\n return \"0x\" + hex.padStart(64, \"0\").toLowerCase();\n } catch {\n throw new Error(`Invalid hash: \"${hash}\"`);\n }\n}\n\n/** Shorten an address to \"0x1234...abcd\" form, normalized for its chain. */\nexport function shortenAddress(chain: Chain, address: string, chars = 4): string {\n const norm = normalizeAddress(chain, address);\n return `${norm.slice(0, chars + 2)}...${norm.slice(-chars)}`;\n}\n","import { MedialaneApiError } from \"../api/client.js\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 300;\nconst DEFAULT_MAX_DELAY_MS = 5000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n opts?: RetryOptions\n): Promise<T> {\n const maxAttempts = opts?.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n const baseDelayMs = opts?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const maxDelayMs = opts?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n\n // Don't retry 4xx client errors — EXCEPT 429 (rate limited), which is\n // transient and clears with a short wait.\n if (err instanceof MedialaneApiError && err.status < 500 && err.status !== 429) {\n throw err;\n }\n\n // Retry on 5xx, 429, or network errors (TypeError from fetch).\n const isRetryable =\n (err instanceof MedialaneApiError && (err.status >= 500 || err.status === 429)) ||\n err instanceof TypeError;\n\n if (!isRetryable || attempt === maxAttempts - 1) {\n throw err;\n }\n\n // Prefer the server's Retry-After when it gave one (429 rate limits),\n // otherwise exponential backoff with jitter. Either way capped at\n // maxDelayMs so a client never hangs on a long server-asked wait.\n const retryAfterMs = err instanceof MedialaneApiError ? err.retryAfterMs : undefined;\n const backoff = baseDelayMs * Math.pow(2, attempt) + Math.random() * baseDelayMs;\n const delay = Math.min(retryAfterMs ?? backoff, maxDelayMs);\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n","import { normalizeAddress } from \"../utils/address.js\";\nimport type { Chain } from \"../chains.js\";\nimport type { ChainFilter } from \"../types/api.js\";\nimport type { MedialaneErrorCode } from \"../types/errors.js\";\nimport { withRetry, type RetryOptions } from \"../utils/retry.js\";\nimport type {\n ApiOrder,\n ApiOrdersQuery,\n ApiCounterOffersQuery,\n ApiToken,\n ApiCollection,\n ApiCoin,\n ApiUserRewards,\n ApiRewardsLeaderboardEntry,\n ApiRewardsConfig,\n ApiRewardsBatchEntry,\n ApiPointEvent,\n ApiCoinsQuery,\n ApiCollectionProfile,\n ApiCreatorProfile,\n ApiCreatorListResult,\n ApiCollectionClaim,\n ApiCollectionSlugClaim,\n ApiUserWallet,\n ApiAppSource,\n ApiChain,\n ApiActivity,\n ApiActivitiesQuery,\n ApiComment,\n ApiRemixOffer,\n ApiRemixOffersQuery,\n ApiPublicRemix,\n ApiSearchResult,\n ApiIntent,\n ApiIntentCreated,\n ApiMetadataSignedUrl,\n ApiMetadataUpload,\n ApiPortalMe,\n ApiPortalKey,\n ApiPortalKeyCreated,\n ApiUsageDay,\n ApiWebhookEndpoint,\n ApiWebhookCreated,\n CreateWebhookParams,\n CreateListingIntentParams,\n MakeOfferIntentParams,\n FulfillOrderIntentParams,\n CancelOrderIntentParams,\n CreateMintIntentParams,\n CreateCollectionIntentParams,\n CreateCounterOfferIntentParams,\n CreateRemixOfferParams,\n AutoRemixOfferParams,\n ConfirmSelfRemixParams,\n ConfirmRemixOfferParams,\n ApiResponse,\n CollectionSort,\n CollectionTokensSort,\n PopClaimStatus,\n PopBatchEligibilityItem,\n DropMintStatus,\n} from \"../types/api.js\";\n\nfunction deriveErrorCode(status: number): MedialaneErrorCode {\n if (status === 404) return \"TOKEN_NOT_FOUND\";\n if (status === 429) return \"RATE_LIMITED\";\n if (status === 410) return \"INTENT_EXPIRED\";\n if (status === 401 || status === 403) return \"UNAUTHORIZED\";\n if (status === 400) return \"INVALID_PARAMS\";\n return \"UNKNOWN\";\n}\n\nexport class MedialaneApiError extends Error {\n readonly code: MedialaneErrorCode;\n constructor(\n public readonly status: number,\n message: string,\n /** Parsed `Retry-After` (ms) when the server sent one — used by withRetry on 429. */\n public readonly retryAfterMs?: number,\n ) {\n super(message);\n this.name = \"MedialaneApiError\";\n this.code = deriveErrorCode(status);\n }\n}\n\n/** Parse an HTTP `Retry-After` header (delta-seconds or HTTP-date) to milliseconds. */\nexport function parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now());\n return undefined;\n}\n\nexport class ApiClient {\n private readonly baseHeaders: Record<string, string>;\n private readonly retryOptions: RetryOptions | undefined;\n\n constructor(\n private readonly baseUrl: string,\n apiKey?: string,\n retryOptions?: RetryOptions,\n private readonly chain: Chain = \"STARKNET\"\n ) {\n this.baseHeaders = apiKey ? { \"x-api-key\": apiKey } : {};\n this.retryOptions = retryOptions;\n }\n\n /** Normalize an address for this client's chain (chain-scoped — Decision B). */\n private addr(a: string): string {\n return normalizeAddress(this.chain, a);\n }\n\n /**\n * The one HTTP path for the whole client: base headers (incl. x-api-key),\n * JSON error unwrapping, and `withRetry` (5xx/network only — 4xx never\n * retried). `allow404`/`allow403` turn those statuses into a `null` result\n * instead of a throw, for \"profile may not exist\" / \"not a holder\" reads —\n * so no method needs to hand-roll `fetch` to get that behavior.\n */\n private async request<T>(\n path: string,\n init?: RequestInit,\n opts?: { allow404?: boolean; allow403?: boolean },\n ): Promise<T> {\n const url = `${this.baseUrl.replace(/\\/$/, \"\")}${path}`;\n const headers: Record<string, string> = { ...this.baseHeaders };\n if (!(init?.body instanceof FormData)) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n const allowed = (status: number): boolean =>\n (opts?.allow404 === true && status === 404) || (opts?.allow403 === true && status === 403);\n\n const res = await withRetry(async () => {\n const response = await fetch(url, {\n ...init,\n headers: { ...headers, ...(init?.headers as Record<string, string> | undefined) },\n });\n if (!response.ok && !allowed(response.status)) {\n const text = await response.text().catch(() => response.statusText);\n let message = text;\n try {\n const body = JSON.parse(text) as { error?: string };\n if (body.error) message = body.error;\n } catch {\n // use raw text\n }\n throw new MedialaneApiError(response.status, message, parseRetryAfter(response.headers.get(\"retry-after\")));\n }\n return response;\n }, this.retryOptions);\n\n if (allowed(res.status)) return null as T;\n return res.json() as Promise<T>;\n }\n\n private get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: \"GET\" });\n }\n\n private post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(path, { method: \"POST\", body: JSON.stringify(body) });\n }\n\n private patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(path, { method: \"PATCH\", body: JSON.stringify(body) });\n }\n\n private del<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: \"DELETE\" });\n }\n\n /** Bearer header for Clerk-JWT-authenticated routes. */\n private bearer(clerkToken: string): Record<string, string> {\n return { Authorization: `Bearer ${clerkToken}` };\n }\n\n // ─── Orders ────────────────────────────────────────────────────────────────\n\n getOrders(query: ApiOrdersQuery = {}): Promise<ApiResponse<ApiOrder[]>> {\n const params = new URLSearchParams();\n if (query.status) params.set(\"status\", query.status);\n if (query.collection) params.set(\"collection\", query.collection);\n if (query.currency) params.set(\"currency\", query.currency);\n if (query.sort) params.set(\"sort\", query.sort);\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n if (query.offerer) params.set(\"offerer\", this.addr(query.offerer));\n if (query.minPrice) params.set(\"minPrice\", query.minPrice);\n if (query.maxPrice) params.set(\"maxPrice\", query.maxPrice);\n if (query.chain) params.set(\"chain\", query.chain);\n const qs = params.toString();\n return this.get<ApiResponse<ApiOrder[]>>(`/v1/orders${qs ? `?${qs}` : \"\"}`);\n }\n\n getOrder(orderHash: string): Promise<ApiResponse<ApiOrder>> {\n return this.get<ApiResponse<ApiOrder>>(`/v1/orders/${orderHash}`);\n }\n\n getActiveOrdersForToken(contract: string, tokenId: string): Promise<ApiResponse<ApiOrder[]>> {\n return this.get<ApiResponse<ApiOrder[]>>(`/v1/orders/token/${this.addr(contract)}/${tokenId}`);\n }\n\n getOrdersByUser(address: string, page = 1, limit = 20): Promise<ApiResponse<ApiOrder[]>> {\n return this.get<ApiResponse<ApiOrder[]>>(\n `/v1/orders/user/${this.addr(address)}?page=${page}&limit=${limit}`\n );\n }\n\n // ─── Tokens ────────────────────────────────────────────────────────────────\n\n getToken(contract: string, tokenId: string, wait = false): Promise<ApiResponse<ApiToken>> {\n return this.get<ApiResponse<ApiToken>>(\n `/v1/tokens/${contract}/${tokenId}${wait ? \"?wait=true\" : \"\"}`\n );\n }\n\n getTokensByOwner(address: string, page = 1, limit = 20): Promise<ApiResponse<ApiToken[]>> {\n return this.get<ApiResponse<ApiToken[]>>(\n `/v1/tokens/owned/${this.addr(address)}?page=${page}&limit=${limit}`\n );\n }\n\n getTokenHistory(\n contract: string,\n tokenId: string,\n page = 1,\n limit = 20\n ): Promise<ApiResponse<ApiActivity[]>> {\n return this.get<ApiResponse<ApiActivity[]>>(\n `/v1/tokens/${contract}/${tokenId}/history?page=${page}&limit=${limit}`\n );\n }\n\n // ─── Collections ───────────────────────────────────────────────────────────\n\n getCollections(\n page = 1,\n limit = 20,\n isKnown?: boolean,\n sort?: CollectionSort,\n service?: string,\n chain?: ChainFilter\n ): Promise<ApiResponse<ApiCollection[]>> {\n const params = new URLSearchParams({ page: String(page), limit: String(limit) });\n if (isKnown !== undefined) params.set(\"isKnown\", String(isKnown));\n if (sort) params.set(\"sort\", sort);\n if (service) params.set(\"service\", service);\n if (chain) params.set(\"chain\", chain);\n return this.get<ApiResponse<ApiCollection[]>>(`/v1/collections?${params}`);\n }\n\n getCollectionsByOwner(owner: string, page = 1, limit = 50): Promise<ApiResponse<ApiCollection[]>> {\n const params = new URLSearchParams({ owner: this.addr(owner), page: String(page), limit: String(limit) });\n return this.get<ApiResponse<ApiCollection[]>>(`/v1/collections?${params}`);\n }\n\n getCollection(contract: string): Promise<ApiResponse<ApiCollection>> {\n return this.get<ApiResponse<ApiCollection>>(`/v1/collections/${this.addr(contract)}`);\n }\n\n getCollectionTokens(\n contract: string,\n page = 1,\n limit = 20,\n sort: CollectionTokensSort = \"recent\"\n ): Promise<ApiResponse<ApiToken[]>> {\n return this.get<ApiResponse<ApiToken[]>>(\n `/v1/collections/${this.addr(contract)}/tokens?page=${page}&limit=${limit}&sort=${sort}`\n );\n }\n\n // ─── Activities ────────────────────────────────────────────────────────────\n\n getActivities(query: ApiActivitiesQuery = {}): Promise<ApiResponse<ApiActivity[]>> {\n const params = new URLSearchParams();\n if (query.type) params.set(\"type\", query.type);\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n if (query.chain) params.set(\"chain\", query.chain);\n const qs = params.toString();\n return this.get<ApiResponse<ApiActivity[]>>(`/v1/activities${qs ? `?${qs}` : \"\"}`);\n }\n\n getActivitiesByAddress(\n address: string,\n page = 1,\n limit = 20\n ): Promise<ApiResponse<ApiActivity[]>> {\n return this.get<ApiResponse<ApiActivity[]>>(\n `/v1/activities/${this.addr(address)}?page=${page}&limit=${limit}`\n );\n }\n\n // ─── Comments ──────────────────────────────────────────────────────────────\n\n getTokenComments(\n contract: string,\n tokenId: string,\n opts: { page?: number; limit?: number } = {}\n ): Promise<ApiResponse<ApiComment[]>> {\n const params = new URLSearchParams();\n if (opts.page !== undefined) params.set(\"page\", String(opts.page));\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n const qs = params.toString();\n return this.get<ApiResponse<ApiComment[]>>(\n `/v1/tokens/${this.addr(contract)}/${tokenId}/comments${qs ? `?${qs}` : \"\"}`\n );\n }\n\n // ─── Search ────────────────────────────────────────────────────────────────\n\n search(q: string, limit = 10, chain?: ChainFilter): Promise<ApiResponse<ApiSearchResult> & { query: string }> {\n const params = new URLSearchParams({ q, limit: String(limit) });\n if (chain) params.set(\"chain\", chain);\n return this.get<ApiResponse<ApiSearchResult> & { query: string }>(\n `/v1/search?${params.toString()}`\n );\n }\n\n // ─── Intents ───────────────────────────────────────────────────────────────\n\n createListingIntent(\n params: CreateListingIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/listing\", params);\n }\n\n createOfferIntent(\n params: MakeOfferIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/offer\", params);\n }\n\n createFulfillIntent(\n params: FulfillOrderIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/fulfill\", params);\n }\n\n createCancelIntent(\n params: CancelOrderIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/cancel\", params);\n }\n\n getIntent(id: string): Promise<ApiResponse<ApiIntent>> {\n return this.get<ApiResponse<ApiIntent>>(`/v1/intents/${id}`);\n }\n\n submitIntentSignature(id: string, signature: string[]): Promise<ApiResponse<ApiIntent>> {\n return this.patch<ApiResponse<ApiIntent>>(`/v1/intents/${id}/signature`, { signature });\n }\n\n confirmIntent(id: string, txHash: string): Promise<ApiResponse<ApiIntent>> {\n return this.patch<ApiResponse<ApiIntent>>(`/v1/intents/${id}/confirm`, { txHash });\n }\n\n createMintIntent(params: CreateMintIntentParams): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/mint\", params);\n }\n\n createCollectionIntent(params: CreateCollectionIntentParams): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/create-collection\", params);\n }\n\n /**\n * Create a counter-offer intent. The seller proposes a new price in response\n * to a buyer's active bid. clerkToken is optional — the endpoint authenticates\n * via the tenant API key; pass a Clerk JWT only if your backend requires it.\n */\n createCounterOfferIntent(\n params: CreateCounterOfferIntentParams,\n clerkToken?: string\n ): Promise<ApiResponse<ApiIntentCreated>> {\n const extraHeaders: Record<string, string> = clerkToken ? { \"Authorization\": `Bearer ${clerkToken}` } : {};\n return this.request<ApiResponse<ApiIntentCreated>>(\"/v1/intents/counter-offer\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: extraHeaders,\n });\n }\n\n /**\n * Fetch counter-offers. Pass `originalOrderHash` (buyer view) or\n * `sellerAddress` (seller view) — at least one is required.\n */\n getCounterOffers(query: ApiCounterOffersQuery): Promise<ApiResponse<ApiOrder[]>> {\n const params = new URLSearchParams();\n if (query.originalOrderHash) params.set(\"originalOrderHash\", query.originalOrderHash);\n if (query.sellerAddress) params.set(\"sellerAddress\", query.sellerAddress);\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n return this.get<ApiResponse<ApiOrder[]>>(`/v1/orders/counter-offers?${params}`);\n }\n\n // ─── Metadata ──────────────────────────────────────────────────────────────\n\n getMetadataSignedUrl(): Promise<ApiResponse<ApiMetadataSignedUrl>> {\n return this.get<ApiResponse<ApiMetadataSignedUrl>>(\"/v1/metadata/signed-url\");\n }\n\n uploadMetadata(metadata: Record<string, unknown>): Promise<ApiResponse<ApiMetadataUpload>> {\n return this.post<ApiResponse<ApiMetadataUpload>>(\"/v1/metadata/upload\", metadata);\n }\n\n resolveMetadata(uri: string): Promise<ApiResponse<unknown>> {\n const params = new URLSearchParams({ uri });\n return this.get<ApiResponse<unknown>>(`/v1/metadata/resolve?${params.toString()}`);\n }\n\n uploadFile(file: File): Promise<ApiResponse<ApiMetadataUpload>> {\n const formData = new FormData();\n formData.append(\"file\", file);\n // Content-Type is intentionally omitted — request() detects FormData and\n // lets the runtime set multipart/form-data with the correct boundary.\n return this.request<ApiResponse<ApiMetadataUpload>>(\"/v1/metadata/upload-file\", {\n method: \"POST\",\n body: formData,\n });\n }\n\n // ─── Portal (tenant self-service) ──────────────────────────────────────────\n\n getMe(): Promise<ApiResponse<ApiPortalMe>> {\n return this.get<ApiResponse<ApiPortalMe>>(\"/v1/portal/me\");\n }\n\n getApiKeys(): Promise<ApiResponse<ApiPortalKey[]>> {\n return this.get<ApiResponse<ApiPortalKey[]>>(\"/v1/portal/keys\");\n }\n\n createApiKey(label?: string): Promise<ApiResponse<ApiPortalKeyCreated>> {\n return this.post<ApiResponse<ApiPortalKeyCreated>>(\"/v1/portal/keys\", label ? { label } : {});\n }\n\n deleteApiKey(id: string): Promise<ApiResponse<{ id: string; status: string }>> {\n return this.del<ApiResponse<{ id: string; status: string }>>(`/v1/portal/keys/${id}`);\n }\n\n getUsage(): Promise<ApiResponse<ApiUsageDay[]>> {\n return this.get<ApiResponse<ApiUsageDay[]>>(\"/v1/portal/usage\");\n }\n\n getWebhooks(): Promise<ApiResponse<ApiWebhookEndpoint[]>> {\n return this.get<ApiResponse<ApiWebhookEndpoint[]>>(\"/v1/portal/webhooks\");\n }\n\n createWebhook(params: CreateWebhookParams): Promise<ApiResponse<ApiWebhookCreated>> {\n return this.post<ApiResponse<ApiWebhookCreated>>(\"/v1/portal/webhooks\", params);\n }\n\n deleteWebhook(id: string): Promise<ApiResponse<{ id: string; status: string }>> {\n return this.del<ApiResponse<{ id: string; status: string }>>(\n `/v1/portal/webhooks/${id}`\n );\n }\n\n // ─── Collection Claims ──────────────────────────────────────────────────────\n\n /**\n * Path 1: On-chain auto claim. Sends both x-api-key (tenant auth) and\n * Authorization: Bearer (Clerk JWT) simultaneously.\n */\n async claimCollection(\n contractAddress: string,\n walletAddress: string,\n clerkToken: string\n ): Promise<{ verified: boolean; collection?: ApiCollection; reason?: string }> {\n return this.request(\"/v1/collections/claim\", {\n method: \"POST\",\n body: JSON.stringify({ contractAddress, walletAddress }),\n headers: this.bearer(clerkToken),\n });\n }\n\n /**\n * Path 3: Manual off-chain claim request (email-based).\n */\n requestCollectionClaim(params: {\n contractAddress: string;\n walletAddress?: string;\n email: string;\n notes?: string;\n }): Promise<{ claim: ApiCollectionClaim }> {\n return this.request(\"/v1/collections/claim/request\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n // ─── Collection Profiles ────────────────────────────────────────────────────\n\n getCollectionProfile(contractAddress: string): Promise<ApiCollectionProfile | null> {\n return this.request<ApiCollectionProfile | null>(\n `/v1/collections/${this.addr(contractAddress)}/profile`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n /**\n * Update collection profile. Requires Clerk JWT for ownership check.\n */\n updateCollectionProfile(\n contractAddress: string,\n data: Partial<Omit<ApiCollectionProfile, \"contractAddress\" | \"chain\" | \"updatedBy\" | \"updatedAt\">>,\n clerkToken: string\n ): Promise<ApiCollectionProfile> {\n return this.request<ApiCollectionProfile>(\n `/v1/collections/${this.addr(contractAddress)}/profile`,\n { method: \"PATCH\", body: JSON.stringify(data), headers: this.bearer(clerkToken) },\n );\n }\n\n getGatedContent(\n contractAddress: string,\n clerkToken: string\n ): Promise<{ title: string; url: string; type: string } | null> {\n return this.request<{ title: string; url: string; type: string } | null>(\n `/v1/collections/${this.addr(contractAddress)}/gated-content`,\n { method: \"GET\", headers: this.bearer(clerkToken) },\n { allow404: true, allow403: true },\n );\n }\n\n // ─── Creator Profiles ───────────────────────────────────────────────────────\n\n /** List all creators with an approved username. */\n getCreators(opts: { search?: string; page?: number; limit?: number } = {}): Promise<ApiCreatorListResult> {\n const params = new URLSearchParams();\n if (opts.search) params.set(\"search\", opts.search);\n if (opts.page) params.set(\"page\", String(opts.page));\n if (opts.limit) params.set(\"limit\", String(opts.limit));\n const qs = params.toString();\n return this.get<ApiCreatorListResult>(`/v1/creators${qs ? `?${qs}` : \"\"}`);\n }\n\n getCreatorProfile(walletAddress: string): Promise<ApiCreatorProfile | null> {\n return this.request<ApiCreatorProfile | null>(\n `/v1/creators/${this.addr(walletAddress)}/profile`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n /** Resolve a username slug to a creator profile (public). */\n getCreatorByUsername(username: string): Promise<ApiCreatorProfile | null> {\n return this.request<ApiCreatorProfile | null>(\n `/v1/creators/by-username/${encodeURIComponent(username.toLowerCase().trim())}`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n /**\n * Update creator profile. Requires Clerk JWT; wallet must match authenticated user.\n */\n updateCreatorProfile(\n walletAddress: string,\n data: Partial<Omit<ApiCreatorProfile, \"walletAddress\" | \"chain\" | \"updatedAt\">>,\n clerkToken: string\n ): Promise<ApiCreatorProfile> {\n return this.request<ApiCreatorProfile>(\n `/v1/creators/${this.addr(walletAddress)}/profile`,\n { method: \"PATCH\", body: JSON.stringify(data), headers: this.bearer(clerkToken) },\n );\n }\n\n // ─── Collection Slug Claims ───────────────────────────────────────────────────\n\n /** Check if a collection slug is available (public, no auth). */\n checkCollectionSlugAvailability(slug: string): Promise<{ available: boolean; reason?: string }> {\n return this.get<{ available: boolean; reason?: string }>(\n `/v1/collection-slug-claims/check/${encodeURIComponent(slug.toLowerCase().trim())}`,\n );\n }\n\n /** Submit a slug claim for a collection. Requires Clerk JWT — caller must be the collection owner. */\n submitCollectionSlugClaim(\n contractAddress: string,\n slug: string,\n clerkToken: string,\n notifyEmail?: string\n ): Promise<{ claim: ApiCollectionSlugClaim }> {\n return this.request<{ claim: ApiCollectionSlugClaim }>(\"/v1/collection-slug-claims\", {\n method: \"POST\",\n body: JSON.stringify({ contractAddress, slug, notifyEmail }),\n headers: this.bearer(clerkToken),\n });\n }\n\n /** Returns all slug claims submitted by the authenticated wallet. Requires Clerk JWT. */\n getMyCollectionSlugClaims(clerkToken: string): Promise<{ claims: ApiCollectionSlugClaim[] }> {\n return this.request<{ claims: ApiCollectionSlugClaim[] }>(\"/v1/collection-slug-claims/me\", {\n method: \"GET\",\n headers: this.bearer(clerkToken),\n });\n }\n\n /** Resolve a collection slug to a full collection. Returns null if not found. */\n getCollectionBySlug(slug: string): Promise<ApiCollection | null> {\n return this.request<ApiCollection | null>(\n `/v1/collections/by-slug/${encodeURIComponent(slug.toLowerCase().trim())}`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n // ─── User Wallet ─────────────────────────────────────────────────────────────\n\n /**\n * Upsert the authenticated user's wallet address in the backend DB.\n * Call after onboarding when ChipiPay confirms the wallet address.\n * Requires Clerk JWT; no tenant API key needed.\n */\n /**\n * Frictionless wallet registration. Tenant API key only (no Clerk JWT required).\n * Idempotent — backend's ensureAccountForWallet upserts and upgrades existing\n * UNKNOWN walletType rows when a more specific value is supplied.\n */\n async registerUser(params: {\n walletAddress: string;\n // Free-form wallet-software label (\"braavos\" / \"ready\" / \"chipipay\" / …).\n // The backend lowercases it into Identity.provider and never gates on it\n // (07-identity §II) — so it's a plain string, not a closed enum.\n walletType?: string;\n appSource?: ApiAppSource;\n chain?: ApiChain;\n }): Promise<{\n accountId: string;\n publicId: string;\n walletAddress: string;\n chain: string;\n // The wallet identity's free-form provider label, echoed back from\n // Identity.provider (\"braavos\" / \"chipipay\" / \"unknown\" / …).\n provider: string;\n appSource: ApiAppSource;\n createdAt: string;\n }> {\n return this.post(\"/v1/users/register\", params);\n }\n\n async upsertMyWallet(\n clerkToken: string,\n options: {\n // Free-form provider label (see registerUser); lowercased into\n // Identity.provider by the backend, never gated on.\n walletType?: string;\n appSource?: ApiAppSource;\n // 07-identity §I: the Wallet identifier is (chain, address). v1\n // backend rejects anything other than STARKNET on this route (the\n // auth path can only prove Starknet ownership); the field exists\n // so the year-2 multichain shape is locked in.\n chain?: ApiChain;\n } = {},\n ): Promise<ApiUserWallet> {\n const body: Record<string, string> = {\n walletType: options.walletType ?? \"UNKNOWN\",\n appSource: options.appSource ?? \"MEDIALANE_SDK\",\n };\n if (options.chain) body.chain = options.chain;\n return this.request<ApiUserWallet>(\"/v1/users/me\", {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: this.bearer(clerkToken),\n });\n }\n\n /**\n * Get the authenticated user's stored wallet address from the backend DB.\n * Returns null if the user has not completed onboarding yet.\n * Requires Clerk JWT; no tenant API key needed.\n */\n getMyWallet(clerkToken: string): Promise<ApiUserWallet | null> {\n return this.request<ApiUserWallet | null>(\n \"/v1/users/me\",\n { method: \"GET\", headers: this.bearer(clerkToken) },\n { allow404: true },\n );\n }\n\n // ─── Remix Licensing ─────────────────────────────────────────────────────────\n\n /**\n * Get public remixes of a token (open to everyone).\n */\n getTokenRemixes(\n contract: string,\n tokenId: string,\n opts: { page?: number; limit?: number } = {}\n ): Promise<ApiResponse<ApiPublicRemix[]>> {\n const params = new URLSearchParams();\n if (opts.page !== undefined) params.set(\"page\", String(opts.page));\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n const qs = params.toString();\n return this.get<ApiResponse<ApiPublicRemix[]>>(\n `/v1/tokens/${this.addr(contract)}/${tokenId}/remixes${qs ? `?${qs}` : \"\"}`\n );\n }\n\n /**\n * Submit a custom remix offer for a token. Requires Clerk JWT.\n */\n submitRemixOffer(\n params: CreateRemixOfferParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(\"/v1/remix-offers\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Submit an auto remix offer for a token with an open license. Requires Clerk JWT.\n */\n submitAutoRemixOffer(\n params: AutoRemixOfferParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(\"/v1/remix-offers/auto\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Record a self-remix (owner remixing their own token). Requires Clerk JWT.\n */\n confirmSelfRemix(\n params: ConfirmSelfRemixParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(\"/v1/remix-offers/self/confirm\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * List remix offers by role. Requires Clerk JWT.\n * role=\"creator\" — offers where you are the original creator.\n * role=\"requester\" — offers you made.\n */\n getRemixOffers(\n query: ApiRemixOffersQuery,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer[]>> {\n const params = new URLSearchParams({ role: query.role });\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n return this.request<ApiResponse<ApiRemixOffer[]>>(`/v1/remix-offers?${params}`, {\n method: \"GET\",\n headers: this.bearer(clerkToken),\n });\n }\n\n /**\n * Get a single remix offer. Clerk JWT optional (price/currency hidden for non-participants).\n */\n getRemixOffer(id: string, clerkToken?: string): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}`, {\n method: \"GET\",\n headers: clerkToken ? this.bearer(clerkToken) : undefined,\n });\n }\n\n /**\n * Creator approves a remix offer (authorises the requester to mint). Requires Clerk JWT.\n */\n confirmRemixOffer(\n id: string,\n params: ConfirmRemixOfferParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}/confirm`, {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Creator rejects a remix offer. Requires Clerk JWT.\n */\n rejectRemixOffer(id: string, clerkToken: string): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}/reject`, {\n method: \"POST\",\n body: JSON.stringify({}),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Requester extends the expiry of a pending remix offer by 1–30 days.\n * Requires Clerk JWT.\n */\n extendRemixOffer(id: string, days: number, clerkToken: string): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}/extend`, {\n method: \"POST\",\n body: JSON.stringify({ days }),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n // ─── POP Protocol ──────────────────────────────────────────────────────────\n\n getPopCollections(opts: { page?: number; limit?: number; sort?: CollectionSort } = {}): Promise<ApiResponse<ApiCollection[]>> {\n return this.getCollections(opts.page ?? 1, opts.limit ?? 20, undefined, opts.sort, \"POP_PROTOCOL\");\n }\n\n async getPopEligibility(collection: string, wallet: string): Promise<PopClaimStatus> {\n const res = await this.get<{ data: PopClaimStatus }>(\n `/v1/pop/eligibility/${this.addr(collection)}/${this.addr(wallet)}`\n );\n return res.data;\n }\n\n async getPopEligibilityBatch(collection: string, wallets: string[]): Promise<PopBatchEligibilityItem[]> {\n const params = new URLSearchParams({ wallets: wallets.map((w) => this.addr(w)).join(\",\") });\n const res = await this.get<{ data: PopBatchEligibilityItem[] }>(\n `/v1/pop/eligibility/${this.addr(collection)}?${params}`\n );\n return res.data;\n }\n\n // ─── Coins (fungible — ERC-20 etc.) ───────────────────────────────────────────\n // Coins are a separate model from Collections (spec 2026-06-14). Price/liquidity\n // is read live from Ekubo (CreatorCoinService.getPrice), never from these.\n\n getCoins(opts: ApiCoinsQuery = {}): Promise<ApiResponse<ApiCoin[]>> {\n const params = new URLSearchParams();\n if (opts.page) params.set(\"page\", String(opts.page));\n if (opts.limit) params.set(\"limit\", String(opts.limit));\n if (opts.service) params.set(\"service\", opts.service);\n if (opts.chain) params.set(\"chain\", opts.chain);\n const qs = params.toString();\n return this.get<ApiResponse<ApiCoin[]>>(`/v1/coins${qs ? `?${qs}` : \"\"}`);\n }\n\n getCoin(contract: string): Promise<{ data: ApiCoin }> {\n return this.get<{ data: ApiCoin }>(`/v1/coins/${this.addr(contract)}`);\n }\n\n // ─── Collection Drop ────────────────────────────────────────────────────────\n\n getDropCollections(opts: { page?: number; limit?: number; sort?: CollectionSort } = {}): Promise<ApiResponse<ApiCollection[]>> {\n return this.getCollections(opts.page ?? 1, opts.limit ?? 20, undefined, opts.sort, \"COLLECTION_DROP\");\n }\n\n async getDropMintStatus(collection: string, wallet: string): Promise<DropMintStatus> {\n const res = await this.get<{ data: DropMintStatus }>(\n `/v1/drop/mint-status/${this.addr(collection)}/${this.addr(wallet)}`\n );\n return res.data;\n }\n\n // ─── Rewards (v0.49.0) ─────────────────────────────────────────────────────\n // Scores are recomputed on a schedule by the backend (~15 min) — reads only.\n\n /** Score + level + progress + badges for one address (zeroed for unknown). */\n async getRewards(address: string): Promise<ApiUserRewards> {\n const res = await this.get<{ data: ApiUserRewards }>(`/v1/rewards/${this.addr(address)}`);\n return res.data;\n }\n\n /** Paginated XP leaderboard. */\n getRewardsLeaderboard(page = 1, limit = 50): Promise<ApiResponse<ApiRewardsLeaderboardEntry[]>> {\n return this.get<ApiResponse<ApiRewardsLeaderboardEntry[]>>(`/v1/rewards?page=${page}&limit=${limit}`);\n }\n\n /** Point-event history for an address. */\n getRewardsEvents(address: string, page = 1, limit = 20): Promise<ApiResponse<ApiPointEvent[]>> {\n return this.get<ApiResponse<ApiPointEvent[]>>(\n `/v1/rewards/${this.addr(address)}/events?page=${page}&limit=${limit}`\n );\n }\n\n /** Reward configuration: level ladder, enabled action XP values, badge catalog. */\n async getRewardsConfig(): Promise<ApiRewardsConfig> {\n const res = await this.get<{ data: ApiRewardsConfig }>(`/v1/rewards/config`);\n return res.data;\n }\n\n /** Minimal level info for up to 50 addresses — one call per list page. */\n async getRewardsBatch(addresses: string[]): Promise<ApiRewardsBatchEntry[]> {\n if (addresses.length === 0) return [];\n const params = new URLSearchParams({ addresses: addresses.map((a) => this.addr(a)).join(\",\") });\n const res = await this.get<{ data: ApiRewardsBatchEntry[] }>(`/v1/rewards/batch?${params}`);\n return res.data;\n }\n}\n","export type IPType =\n | \"Audio\"\n | \"Art\"\n | \"Documents\"\n | \"NFT\"\n | \"Video\"\n | \"Photography\"\n | \"Patents\"\n | \"Posts\"\n | \"Publications\"\n | \"RWA\"\n | \"Software\"\n | \"Custom\";\n\nexport type CollectionSort = \"recent\" | \"supply\" | \"floor\" | \"volume\" | \"name\";\n\nexport type CollectionTokensSort = \"recent\" | \"oldest\" | \"name\" | \"price\";\n\n/** Bounded capability set (05-service-model §III). Expand the union when a\n * service needs behavior outside it — never make it free-form. */\nexport type ServiceCapability =\n | \"list\" | \"buy\" | \"make_offer\" | \"cancel\"\n | \"transfer\" | \"burn\"\n | \"mint\" | \"claim\" | \"airdrop\"\n | \"remix\" | \"license\"\n | \"subscribe\" | \"redeem\"\n | \"launch\" | \"swap\"\n | \"sponsor\";\n\n/** A service that bakes enforcement into its own contract declares it here\n * (04-licensing-model §V, 05-service-model §IV). Absence/all-falsey =\n * soft enforcement (the 00-principles §9 default). */\nexport interface EnforcementDeclaration {\n royalty?: \"erc2981\" | \"service-split\" | \"none\";\n escrow?: boolean;\n timeLock?: boolean;\n revocable?: boolean;\n}\n\n/** An on-chain event the service emits. The indexer consumes this list to\n * decide what to poll and how to parse — the year-2 \"data-driven event\n * parser registry\" foundation (02-protocol-app-split §V).\n *\n * The Cairo selector is derivable from `name` via\n * `starknet.hash.getSelectorFromName(name)` — not stored to avoid\n * duplication and keep the SDK runtime-free of pre-computed hashes.\n */\nexport interface ServiceEventDeclaration {\n /** Cairo event struct name (e.g. \"OrderCreated\", \"CollectionCreated\"). */\n name: string;\n /**\n * Where this event is emitted:\n * - \"factory\": at the service's `onchain.factoryAddress` (fixed address).\n * Examples: marketplace OrderCreated, factory CollectionCreated.\n * - \"instance\": at the address of each deployed collection contract\n * (variable; the indexer iterates discovered instances).\n * Examples: ERC-721 Transfer, POP AllowlistUpdated.\n */\n emittedBy: \"factory\" | \"instance\";\n /**\n * Polling cadence the indexer should use:\n * - \"fast\" (default): every indexer tick (~6s). Right for low-volume\n * protocol events like order/factory events.\n * - \"slow\": a separate slower loop (~2min). Right for\n * high-volume per-instance events like Transfer\n * and AllowlistUpdated — polling them every tick\n * against every known instance is RPC-expensive.\n */\n poll?: \"fast\" | \"slow\";\n}\n\n/** Declarative description of a service (05-service-model §II).\n * SDK-resident in v1; on-chain registry in year 2. */\nexport interface ServiceDefinition {\n /** Stable kebab-case id. NO version number (05 §II). */\n id: string;\n displayName: string;\n description: string;\n standard: \"ERC721\" | \"ERC1155\" | \"ERC20\" | \"UNKNOWN\";\n provenance: \"MEDIALANE\" | \"EXTERNAL\";\n onchain?: Partial<Record<import(\"../chains.js\").Chain, {\n factoryAddress?: string;\n classHash?: string;\n startBlock?: number;\n }>>;\n /** Drives the dapp asset/collection page variant. */\n uiVariant: string;\n capabilities: ServiceCapability[];\n /** Events the indexer should poll + parse for this service.\n * Optional during the year-1 transition — backend hand-coded pollers\n * (medialane-backend/src/mirror/poller.ts) take precedence today.\n * Populated here so consumers and the future data-driven indexer can\n * read what events a service emits without code-spelunking. */\n events?: ServiceEventDeclaration[];\n metadataSchema?: {\n requiredTraits?: string[];\n /** Canonical platform default is \"CC BY-SA\" (04-licensing-model §III). */\n licenseDefault?: string;\n enforcement?: EnforcementDeclaration;\n };\n}\n\nexport interface ApiCollectionsQuery {\n page?: number;\n limit?: number;\n isKnown?: boolean;\n sort?: CollectionSort;\n owner?: string;\n /** Filter by service id. */\n service?: string;\n}\n\n/**\n * Order lifecycle states. **Four canonical values** per `01-core-model §V`.\n *\n * The legacy `\"COUNTER_OFFERED\"` value was removed in 0.23.0 (audit P0-1\n * Phase D). Counter-offers are linked orders via `parentOrderHash`, not a\n * third lifecycle state on the parent bid. Use `ApiOrder.hasActiveCounterOffer`\n * (added in 0.22.0) for the \"this bid has been countered\" affordance.\n */\nexport type OrderStatus = \"ACTIVE\" | \"FULFILLED\" | \"CANCELLED\" | \"EXPIRED\";\nexport type SortOrder = \"price_asc\" | \"price_desc\" | \"recent\";\nexport type ActivityType = \"mint\" | \"transfer\" | \"sale\" | \"listing\" | \"offer\" | \"cancelled\";\nexport type IntentType = \"CREATE_LISTING\" | \"MAKE_OFFER\" | \"FULFILL_ORDER\" | \"CANCEL_ORDER\" | \"MINT\" | \"CREATE_COLLECTION\" | \"COUNTER_OFFER\";\nexport type IntentStatus = \"PENDING\" | \"SIGNED\" | \"SUBMITTED\" | \"CONFIRMED\" | \"FAILED\" | \"EXPIRED\";\nexport type WebhookEventType = \"ORDER_CREATED\" | \"ORDER_FULFILLED\" | \"ORDER_CANCELLED\" | \"TRANSFER\";\nexport type WebhookStatus = \"ACTIVE\" | \"DISABLED\";\nexport type ApiKeyStatus = \"ACTIVE\" | \"REVOKED\";\nexport type TenantPlan = \"FREE\" | \"PREMIUM\";\n\n// ─── Shared ───────────────────────────────────────────────────────────────────\n\nexport interface ApiMeta {\n page: number;\n limit: number;\n total?: number;\n}\n\nexport interface ApiResponse<T> {\n data: T;\n meta?: ApiMeta;\n}\n\n// ─── Orders ───────────────────────────────────────────────────────────────────\n\n/** Cross-chain read filter — a concrete chain, or \"all\" for aggregation\n * (platform-federation spec §2.3). Omitted = the backend default (STARKNET). */\nexport type ChainFilter = import(\"../chains.js\").Chain | \"all\";\n\nexport interface ApiOrdersQuery {\n chain?: ChainFilter;\n status?: OrderStatus;\n collection?: string;\n currency?: string;\n sort?: SortOrder;\n page?: number;\n limit?: number;\n offerer?: string;\n minPrice?: string;\n maxPrice?: string;\n}\n\nexport interface ApiOrderOffer {\n itemType: string;\n token: string;\n identifier: string;\n startAmount: string;\n endAmount: string;\n}\n\nexport interface ApiOrderConsideration extends ApiOrderOffer {\n recipient: string;\n}\n\nexport interface ApiOrderPrice {\n raw: string | null;\n formatted: string | null;\n currency: string | null;\n decimals: number;\n}\n\nexport interface ApiOrderTxHash {\n created: string | null;\n fulfilled: string | null;\n cancelled: string | null;\n}\n\nexport interface ApiOrderTokenMeta {\n name: string | null;\n image: string | null;\n description: string | null;\n}\n\nexport interface ApiOrder {\n id: string;\n chain: string;\n orderHash: string;\n offerer: string;\n offer: ApiOrderOffer;\n consideration: ApiOrderConsideration;\n startTime: string;\n endTime: string;\n status: OrderStatus;\n fulfiller: string | null;\n nftContract: string | null;\n nftTokenId: string | null;\n price: ApiOrderPrice;\n txHash: ApiOrderTxHash;\n createdBlockNumber: string;\n /** ERC-1155 only: units still available after the last partial fill. Null for ERC-721 or unfilled orders. */\n remainingAmount: string | null;\n createdAt: string;\n updatedAt: string;\n /** Embedded token metadata (name/image/description). Null when not yet indexed. */\n token: ApiOrderTokenMeta | null;\n /** Set when this is a counter-offer listing — points to the original buyer bid.\n * Now always emitted by the backend (was conditional); kept optional in the\n * type for back-compat with older response shapes. */\n parentOrderHash?: string | null;\n /** Optional seller message accompanying a counter-offer. */\n counterOfferMessage?: string | null;\n /** True when this order is a bid (ERC-20 offer) AND at least one ACTIVE counter\n * exists with `parentOrderHash = this.orderHash`. Set by endpoints that compute\n * it (currently `GET /v1/orders/user/:address` and `GET /v1/orders/:orderHash`);\n * undefined on endpoints that don't.\n *\n * Use this instead of `status === \"COUNTER_OFFERED\"` for \"this bid has been\n * countered\" affordances. The status pattern is being phased out per\n * 01-core-model §V — counter-offers are linked orders, not a lifecycle state. */\n hasActiveCounterOffer?: boolean;\n}\n\n// ─── IP / IPFS Metadata types ──────────────────────────────────────────────────\n\n/**\n * A single OpenSea-compatible ERC-721 attribute.\n * Medialane embeds licensing, provenance, and IP metadata as attributes.\n */\nexport interface IpAttribute {\n trait_type: string;\n value: string;\n}\n\n/**\n * Full on-chain + IPFS metadata for a Medialane IP NFT.\n * Conforms to the OpenSea ERC-721 metadata standard and embeds\n * Berne Convention-compatible licensing data in `attributes`.\n *\n * Common licensing attributes (all optional — absent on pre-v2 tokens):\n * License · Commercial Use · Derivatives · Attribution · Territory\n * AI Policy · Royalty · Standard (\"Berne Convention\") · Registration\n */\nexport interface IpNftMetadata {\n name: string;\n description?: string;\n image?: string | null;\n external_url?: string;\n attributes?: IpAttribute[];\n /** Populated by the indexer for fast access — not stored in IPFS */\n ipType?: string | null;\n licenseType?: string | null;\n commercialUse?: string | null;\n derivatives?: string | null;\n attribution?: string | null;\n territory?: string | null;\n aiPolicy?: string | null;\n royalty?: string | null;\n registration?: string | null;\n}\n\n// ─── Tokens ───────────────────────────────────────────────────────────────────\n\n/** Indexed token metadata as returned by the Medialane API. */\nexport interface ApiTokenMetadata {\n name: string | null;\n description: string | null;\n image: string | null;\n /** Parsed OpenSea-standard attributes array. Null when metadata hasn't been fetched. */\n attributes: IpAttribute[] | null;\n /** Short-circuit fields extracted from attributes by the indexer */\n ipType: string | null;\n licenseType: string | null;\n commercialUse: string | null;\n derivatives: string | null;\n attribution: string | null;\n territory: string | null;\n aiPolicy: string | null;\n royalty: string | null;\n registration: string | null;\n author: string | null;\n}\n\n/** Per-holder balance entry. Present for ERC-1155 (multi-holder); single entry for ERC-721. */\nexport interface ApiTokenBalance {\n owner: string;\n /** Quantity held. Always \"1\" for ERC-721. */\n amount: string;\n}\n\nexport interface ApiToken {\n id: string;\n chain: string;\n contractAddress: string;\n tokenId: string;\n /** @deprecated Use `balances` for ownership checks — always null after ERC-1155 migration. */\n owner: string | null;\n tokenUri: string | null;\n metadataStatus: \"PENDING\" | \"FETCHING\" | \"FETCHED\" | \"FAILED\";\n /** Token standard derived from the parent collection. Use this to determine ERC-721 vs ERC-1155 behavior. */\n standard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n metadata: ApiTokenMetadata;\n /** Current holders with amounts. Only present on single-token fetches; null on list responses. */\n balances: ApiTokenBalance[] | null;\n activeOrders: ApiOrder[];\n createdAt: string;\n updatedAt: string;\n}\n\n// ─── Collections ──────────────────────────────────────────────────────────────\n\nexport interface ApiCollection {\n id: string;\n chain: string;\n contractAddress: string;\n collectionId: string | null;\n name: string | null;\n symbol: string | null;\n description: string | null;\n image: string | null;\n owner: string | null;\n startBlock: string;\n metadataStatus: \"PENDING\" | \"FETCHING\" | \"FETCHED\" | \"FAILED\";\n /** Token standard detected via ERC-165. Collection is NFT-only since the\n * 2026-06-14 coin split — fungible coins are `ApiCoin`, served by getCoins(). */\n standard: \"ERC721\" | \"ERC1155\";\n isKnown: boolean;\n /** Hidden by ops/admin (content moderation). When true, list endpoints\n * already filter the row out; single-collection fetches still return\n * it so the UI can render a \"hidden\" banner instead of a 404. */\n isHidden: boolean;\n /** Promoted on homepage / browse surfaces. */\n isFeatured: boolean;\n /** Stable Medialane service ID, or null for external collections.\n * Resolve via getService() (05-service-model). Primary field. */\n service: string | null;\n claimedBy: string | null;\n profile?: ApiCollectionProfile | null;\n floorPrice: string | null;\n totalVolume: string | null;\n holderCount: number | null;\n totalSupply: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A fungible coin (ERC-20 today; SPL/etc. later). Distinct from ApiCollection:\n * a coin has a supply + decimals + a market price (read live from Ekubo), no\n * tokens, no orders. Served by getCoins()/getCoin() (spec 2026-06-14). */\nexport interface ApiCoin {\n id: string;\n chain: string;\n contractAddress: string;\n standard: \"ERC20\";\n /** \"creator-coin\" | \"external-erc20\" */\n service: string;\n name: string | null;\n symbol: string | null;\n decimals: number;\n /** Fungible supply as a decimal string — NOT an item count. */\n totalSupply: string | null;\n description: string | null;\n image: string | null;\n creator: string | null;\n startBlock: string;\n isHidden: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiCoinsQuery {\n chain?: ChainFilter;\n page?: number;\n limit?: number;\n /** Filter by coin service id (\"creator-coin\" | \"external-erc20\"). */\n service?: string;\n}\n\n// ─── Activities ───────────────────────────────────────────────────────────────\n\nexport interface ApiActivityPrice {\n raw: string | null;\n formatted: string | null;\n currency: string | null;\n}\n\nexport interface ApiActivity {\n type: ActivityType;\n // Transfer fields\n contractAddress?: string;\n tokenId?: string;\n from?: string;\n to?: string;\n blockNumber?: string;\n /** ERC-1155 quantity (transfer/mint rows). \"1\" for ERC-721. */\n amount?: string;\n // Order fields\n orderHash?: string;\n nftContract?: string;\n nftTokenId?: string;\n offerer?: string;\n fulfiller?: string | null;\n price?: ApiActivityPrice;\n /** Token standard — present on order rows. */\n tokenStandard?: \"ERC721\" | \"ERC1155\";\n txHash: string | null;\n timestamp: string;\n /** Batch-enriched token metadata — avoids per-row fetches. */\n token?: { name: string | null; image: string | null } | null;\n}\n\nexport interface ApiActivitiesQuery {\n chain?: ChainFilter;\n type?: ActivityType;\n page?: number;\n limit?: number;\n}\n\n// ─── Comments ─────────────────────────────────────────────────────────────────\n\nexport interface ApiComment {\n id: string;\n chain: string; // \"starknet\"\n contractAddress: string; // normalized 0x-padded Starknet address\n tokenId: string;\n author: string; // normalized 0x-padded Starknet address\n content: string; // sanitized plain text\n txHash: string | null;\n blockNumber: string; // BigInt serialized as string\n postedAt: string; // ISO 8601 derived from blockTimestamp — use for display\n}\n\n// ─── Search ───────────────────────────────────────────────────────────────────\n\nexport interface ApiSearchTokenResult {\n contractAddress: string;\n tokenId: string;\n name: string | null;\n image: string | null;\n owner: string;\n metadataStatus: string;\n}\n\nexport interface ApiSearchCollectionResult {\n contractAddress: string;\n name: string | null;\n image: string | null;\n totalSupply: number | null;\n floorPrice: string | null;\n holderCount: number | null;\n}\n\nexport interface ApiSearchCreatorResult {\n walletAddress: string;\n username: string | null;\n displayName: string | null;\n bio: string | null;\n avatarImage: string | null;\n}\n\nexport interface ApiSearchResult {\n tokens: ApiSearchTokenResult[];\n collections: ApiSearchCollectionResult[];\n creators: ApiSearchCreatorResult[];\n}\n\n// ─── Intents ──────────────────────────────────────────────────────────────────\n\nexport interface ApiIntent {\n id: string;\n chain: string;\n type: IntentType;\n status: IntentStatus;\n requester: string;\n typedData: unknown;\n calls: unknown;\n signature: string[];\n txHash: string | null;\n orderHash: string | null;\n /** Set on COUNTER_OFFER intents — the original bid order hash being countered. */\n parentOrderHash?: string | null;\n /** Optional seller message on counter-offer intents. */\n counterOfferMessage?: string | null;\n expiresAt: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A single Starknet call as returned in intent calldata. */\nexport interface IntentCall {\n contractAddress: string;\n entrypoint: string;\n calldata: string[];\n}\n\n/**\n * Response from any `createXIntent` call. Discriminated on `requiresSignature`:\n * • true — SNIP-12 intent (listing / offer / cancel / counter-offer). Sign\n * `typedData`, then call `submitIntentSignature(id, sig)` to obtain\n * the executable calls.\n * • false — prebuilt intent (fulfill / mint / create-collection). `calls` are\n * ready to execute directly; there is no signature step.\n *\n * The discriminant makes the wrong access a compile error: `typedData` does not\n * exist on the `false` variant, nor `calls` on the `true` variant. Consumers\n * MUST narrow on `requiresSignature` before reading either.\n */\nexport type ApiIntentCreated =\n | { id: string; expiresAt: string; requiresSignature: true; typedData: unknown }\n | { id: string; expiresAt: string; requiresSignature: false; calls: IntentCall[] };\n\nexport interface CreateListingIntentParams {\n offerer: string;\n nftContract: string;\n tokenId: string;\n currency: string;\n price: string;\n endTime: number;\n salt?: string;\n /** Number of units to list — required for ERC-1155, omit for ERC-721. */\n amount?: string;\n}\n\nexport interface MakeOfferIntentParams {\n offerer: string;\n nftContract: string;\n tokenId: string;\n currency: string;\n price: string;\n endTime: number;\n salt?: string;\n /** Caller hint — \"ERC1155\" creates the bid on the ERC-1155 marketplace. */\n tokenStandard?: string;\n /** ERC-1155 only: number of editions requested. Defaults to 1. */\n quantity?: string;\n}\n\nexport interface FulfillOrderIntentParams {\n fulfiller: string;\n orderHash: string;\n /** Caller hint — \"ERC1155\" forces 1155 routing even if the order isn't in the DB yet */\n tokenStandard?: string;\n /** ERC-1155 only: units to purchase (1 ≤ quantity ≤ remaining_amount). Defaults to 1. */\n quantity?: string;\n}\n\nexport interface CancelOrderIntentParams {\n offerer: string;\n orderHash: string;\n /** Caller hint — \"ERC1155\" forces 1155 routing even if the order isn't in the DB yet */\n tokenStandard?: string;\n}\n\nexport interface CreateMintIntentParams {\n /** Collection owner wallet address — must be the collection owner on-chain */\n owner: string;\n collectionId: string;\n recipient: string;\n tokenUri: string;\n /**\n * EIP-2981 secondary-sale royalty in basis points (0–10_000). Set once at mint;\n * receiver is the immutable creator. Required since MIP v0.4.0 — pass 0 for none.\n */\n royaltyBps: number;\n /** Optional: override the default collection contract address */\n collectionContract?: string;\n}\n\nexport interface CreateCollectionIntentParams {\n owner: string;\n name: string;\n symbol: string;\n /** Optional description stored server-side and surfaced on the collection page. */\n description?: string;\n /** Optional IPFS image URI (ipfs://...) for the collection cover image. */\n image?: string;\n /** Base URI for token metadata. Defaults to empty string if not provided. */\n baseUri?: string;\n /** Optional: override the default collection contract address */\n collectionContract?: string;\n}\n\nexport interface CreateCounterOfferIntentParams {\n /** Wallet address of the NFT owner making the counter-offer. */\n sellerAddress: string;\n /** Order hash of the original buyer bid being countered. */\n originalOrderHash: string;\n /** Counter price as a raw wei integer string (not human-readable). */\n priceRaw: string;\n /** Duration in seconds the counter-offer will be valid (3600–2592000). */\n durationSeconds: number;\n /** Optional message from the seller to the buyer. Max 500 chars. */\n message?: string;\n}\n\nexport interface ApiCounterOffersQuery {\n /** Original bid order hash — returns the counter-offer for this specific bid. */\n originalOrderHash?: string;\n /** Seller address — returns all counter-offers sent by this seller. */\n sellerAddress?: string;\n page?: number;\n limit?: number;\n}\n\n// ─── Remix Licensing ──────────────────────────────────────────────────────────\n\nexport const OPEN_LICENSES = [\"CC0\", \"CC BY\", \"CC BY-SA\", \"CC BY-NC\"] as const;\nexport type OpenLicense = (typeof OPEN_LICENSES)[number];\n\nexport type RemixOfferStatus =\n | \"PENDING\"\n | \"AUTO_PENDING\"\n | \"APPROVED\"\n | \"COMPLETED\"\n | \"REJECTED\"\n | \"EXPIRED\"\n | \"SELF_MINTED\";\n\nexport interface ApiRemixOfferPrice {\n raw: string;\n formatted: string;\n currency: string;\n decimals: number;\n}\n\nexport interface ApiRemixOffer {\n id: string;\n status: RemixOfferStatus;\n originalContract: string;\n originalTokenId: string;\n creatorAddress: string;\n requesterAddress: string | null;\n message?: string | null;\n /** Visible only to creator and requester — includes formatted price */\n price?: ApiRemixOfferPrice;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n royaltyPct: number | null;\n approvedCollection: string | null;\n remixContract: string | null;\n remixTokenId: string | null;\n orderHash: string | null;\n createdAt: string;\n expiresAt: string;\n updatedAt: string;\n}\n\n/** Public remix record — price/currency omitted for non-participants */\nexport interface ApiPublicRemix {\n id: string;\n remixContract: string | null;\n remixTokenId: string | null;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n createdAt: string;\n}\n\nexport interface CreateRemixOfferParams {\n originalContract: string;\n originalTokenId: string;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n royaltyPct?: number;\n proposedPrice?: string;\n proposedCurrency?: string;\n message?: string;\n /** Offer validity in days (server default applies if omitted) */\n expiresInDays?: number;\n}\n\nexport interface AutoRemixOfferParams {\n originalContract: string;\n originalTokenId: string;\n licenseType: string;\n}\n\nexport interface ConfirmSelfRemixParams {\n originalContract: string;\n originalTokenId: string;\n remixContract: string;\n remixTokenId: string;\n /** On-chain transaction hash of the mint tx */\n txHash?: string;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n royaltyPct?: number;\n}\n\nexport interface ConfirmRemixOfferParams {\n approvedCollection: string;\n remixContract: string;\n remixTokenId: string;\n orderHash?: string;\n}\n\nexport interface ApiRemixOffersQuery {\n /** \"creator\" = offers where you are the original creator; \"requester\" = offers you made */\n role: \"creator\" | \"requester\";\n page?: number;\n limit?: number;\n}\n\n// ─── Metadata ─────────────────────────────────────────────────────────────────\n\nexport interface ApiMetadataSignedUrl {\n url: string;\n}\n\nexport interface ApiMetadataUpload {\n cid: string;\n url: string;\n}\n\n// ─── Portal (tenant self-service) ─────────────────────────────────────────────\n\nexport interface ApiPortalMe {\n id: string;\n name: string;\n email: string;\n plan: TenantPlan;\n status: string;\n}\n\nexport interface ApiPortalKey {\n id: string;\n prefix: string;\n label: string;\n status: ApiKeyStatus;\n lastUsedAt: string | null;\n createdAt: string;\n}\n\nexport interface ApiPortalKeyCreated {\n id: string;\n prefix: string;\n label: string | null;\n /** Plaintext key — shown ONCE at creation */\n plaintext: string;\n}\n\nexport interface ApiUsageDay {\n day: string;\n requests: number;\n}\n\nexport interface ApiWebhookEndpoint {\n id: string;\n url: string;\n events: WebhookEventType[];\n status: WebhookStatus;\n createdAt: string;\n}\n\nexport interface ApiWebhookCreated extends ApiWebhookEndpoint {\n /** Signing secret — shown ONCE at creation, not stored in plaintext */\n secret: string;\n}\n\nexport interface CreateWebhookParams {\n url: string;\n events: WebhookEventType[];\n label?: string;\n}\n\n// ─── Collection & Creator Profiles ────────────────────────────────────────────\n\nexport interface ApiCollectionProfile {\n contractAddress: string;\n chain: string;\n displayName: string | null;\n description: string | null;\n image: string | null;\n bannerImage: string | null;\n websiteUrl: string | null;\n twitterUrl: string | null;\n discordUrl: string | null;\n telegramUrl: string | null;\n hasGatedContent: boolean;\n gatedContentTitle: string | null;\n slug: string | null;\n updatedBy: string | null;\n updatedAt: string;\n}\n\nexport interface ApiCollectionSlugClaim {\n id: string;\n slug: string;\n contractAddress: string;\n chain: string;\n walletAddress: string;\n status: \"PENDING\" | \"APPROVED\" | \"REJECTED\";\n adminNotes: string | null;\n notifyEmail: string | null;\n reviewedAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiCreatorProfile {\n walletAddress: string;\n chain: string;\n username: string | null;\n displayName: string | null;\n bio: string | null;\n avatarImage: string | null;\n bannerImage: string | null;\n /** Computed fallback used by the creator-list / creator-page endpoints\n * ONLY when both `avatarImage` and `bannerImage` are null: image of\n * any collection owned by this creator. Undefined on profile-detail\n * endpoints where this lookup isn't performed. UI may use this to\n * populate hero banners without an extra fetch. */\n collectionImage?: string | null;\n websiteUrl: string | null;\n twitterUrl: string | null;\n discordUrl: string | null;\n telegramUrl: string | null;\n updatedAt: string;\n}\n\nexport interface ApiCreatorListResult {\n creators: ApiCreatorProfile[];\n total: number;\n page: number;\n limit: number;\n}\n\n// ─── User Wallet ───────────────────────────────────────────────────────────────\n\nexport type ApiAppSource =\n | \"MEDIALANE_STARKNET\" // the Starknet dapp (renamed from MEDIALANE_DAPP — the platform is multichain)\n | \"MEDIALANE_IO\"\n | \"MEDIALANE_PORTAL\"\n | \"MEDIALANE_SDK\"\n // Deprecated alias for MEDIALANE_STARKNET. The backend still accepts it (normalizes\n // to MEDIALANE_STARKNET) so existing apps keep working; migrate to MEDIALANE_STARKNET\n // and drop this in a later major.\n | \"MEDIALANE_DAPP\";\n\n// 07-identity §I: the Wallet identifier is (chain, address). Mirrors\n// the backend Chain enum. v1 callers only ever pass STARKNET; the rest\n// are present so the type doesn't need a breaking change when SIWE/SIWB\n// authentication lands and other chains become callable.\nexport type ApiChain = \"STARKNET\" | \"ETHEREUM\" | \"SOLANA\" | \"BASE\" | \"BITCOIN\";\n\nexport interface ApiUserWallet {\n walletAddress: string;\n}\n\n// ─── Collection Claims ─────────────────────────────────────────────────────────\n\nexport interface ApiCollectionClaim {\n id: string;\n contractAddress: string;\n chain: string;\n claimantAddress: string | null;\n status: \"PENDING\" | \"AUTO_APPROVED\" | \"APPROVED\" | \"REJECTED\";\n verificationMethod: \"ONCHAIN\" | \"SIGNATURE\" | \"MANUAL\";\n createdAt: string;\n}\n\nexport interface ApiAdminCollectionClaim extends ApiCollectionClaim {\n claimantEmail: string | null;\n notes: string | null;\n adminNotes: string | null;\n reviewedBy: string | null;\n reviewedAt: string | null;\n updatedAt: string;\n}\n\n// ─── POP Protocol ──────────────────────────────────────────────────────────────\n\nexport interface PopClaimStatus {\n isEligible: boolean;\n hasClaimed: boolean;\n tokenId: string | null;\n}\n\nexport interface PopBatchEligibilityItem extends PopClaimStatus {\n wallet: string;\n}\n\nexport type PopEventType =\n | \"Conference\"\n | \"Bootcamp\"\n | \"Workshop\"\n | \"Hackathon\"\n | \"Meetup\"\n | \"Course\"\n | \"Other\";\n\n// ─── Collection Drop ───────────────────────────────────────────────────────────\n\nexport interface DropMintStatus {\n mintedByWallet: number;\n totalMinted: number;\n}\n\n// ─── Rewards (v0.49.0) ─────────────────────────────────────────────────────────\n\nexport interface ApiRewardsBadge {\n key: string;\n name: string;\n description: string;\n icon: string;\n color: string;\n category: string;\n}\n\nexport interface ApiRewardsLevel {\n level: number;\n name: string;\n xpRequired: number;\n badgeColor: string;\n description: string | null;\n}\n\nexport interface ApiUserRewards {\n address: string;\n accountId: string | null;\n publicId: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n nextLevel: { level: number; name: string; xpRequired: number } | null;\n progressPct: number;\n breakdown: Record<string, number>;\n badges: ApiRewardsBadge[];\n computedAt: string | null;\n}\n\nexport interface ApiRewardsLeaderboardEntry {\n rank: number;\n address: string;\n accountId: string | null;\n publicId: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface ApiRewardsConfig {\n levels: ApiRewardsLevel[];\n actions: { type: string; label: string; xp: number; dailyCap: number | null }[];\n badges: ApiRewardsBadge[];\n}\n\nexport interface ApiRewardsBatchEntry {\n address: string;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface ApiPointEvent {\n id: string;\n actionType: string;\n xp: number;\n multiplier: number;\n finalXp: number;\n txHash: string | null;\n createdAt: string;\n}\n","import { getCoordinates } from \"./chains.js\";\n\n// Flat per-chain contract constants. Chain-named (each contract is deployed on a\n// specific chain), derived from the chains.ts registry so there is one source.\nconst SN = getCoordinates(\"STARKNET\");\n\n// ── Marketplace ───────────────────────────────────────────────────────────────\nexport const STARKNET_MARKETPLACE_721_CONTRACT = SN.marketplace721!;\nexport const STARKNET_MARKETPLACE_721_CLASS_HASH = SN.marketplace721ClassHash!;\nexport const STARKNET_MARKETPLACE_721_START_BLOCK = SN.marketplace721StartBlock!;\nexport const STARKNET_MARKETPLACE_1155_CONTRACT = SN.marketplace1155!;\nexport const STARKNET_MARKETPLACE_1155_CLASS_HASH = SN.marketplace1155ClassHash!;\nexport const STARKNET_MARKETPLACE_1155_START_BLOCK = SN.marketplace1155StartBlock!;\n\n// ── Collections ───────────────────────────────────────────────────────────────\nexport const STARKNET_COLLECTION_721_CONTRACT = SN.collection721!;\nexport const STARKNET_COLLECTION_721_START_BLOCK = SN.collection721StartBlock!;\nexport const STARKNET_IPNFT_CLASS_HASH = SN.ipNftClassHash!;\nexport const STARKNET_IPCOLLECTION_CLASS_HASH = SN.ipCollectionClassHash!;\nexport const STARKNET_COLLECTION_1155_CONTRACT = SN.collection1155!;\nexport const STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH = SN.collection1155FactoryClassHash!;\nexport const STARKNET_COLLECTION_1155_CLASS_HASH = SN.collection1155ClassHash!;\nexport const STARKNET_COLLECTION_1155_START_BLOCK = SN.collection1155StartBlock!;\n\n// ── POP / Drop / Comments ─────────────────────────────────────────────────────\nexport const STARKNET_POP_FACTORY_CONTRACT = SN.popFactory!;\nexport const STARKNET_POP_COLLECTION_CLASS_HASH = SN.popCollectionClassHash!;\nexport const STARKNET_DROP_FACTORY_CONTRACT = SN.dropFactory!;\nexport const STARKNET_DROP_COLLECTION_CLASS_HASH = SN.dropCollectionClassHash!;\nexport const STARKNET_NFTCOMMENTS_CONTRACT = SN.nftComments!;\n\n// ── IP Tickets / IP Club / IP Sponsorship ─────────────────────────────────────\n// Not yet deployed — these resolve to `undefined` at runtime until chains.ts's\n// STARKNET coordinates are populated (Phase 3/4 deploy). The `!` assertion\n// mirrors the existing convention above; falsy-guard callers (`if (X && ...)`)\n// still behave correctly regardless.\nexport const STARKNET_IP_TICKETS_FACTORY_CONTRACT = SN.ipTicketsFactory!;\nexport const STARKNET_IP_TICKET_COLLECTION_CLASS_HASH = SN.ipTicketCollectionClassHash!;\nexport const STARKNET_IP_CLUB_FACTORY_CONTRACT = SN.ipClubFactory!;\nexport const STARKNET_IP_CLUB_COLLECTION_CLASS_HASH = SN.ipClubCollectionClassHash!;\nexport const STARKNET_IP_SPONSORSHIP_CONTRACT = SN.ipSponsorship!;\nexport const STARKNET_IP_SPONSORSHIP_CLASS_HASH = SN.ipSponsorshipClassHash!;\n\n// ── Creator Coin (Ekubo) ──────────────────────────────────────────────────────\nexport const STARKNET_CREATOR_COIN_FACTORY_CONTRACT = SN.creatorCoinFactory!;\nexport const STARKNET_CREATOR_COIN_EKUBO_LAUNCHER = SN.creatorCoinEkuboLauncher!;\nexport const STARKNET_CREATOR_COIN_CLASS_HASH = SN.creatorCoinClassHash!;\nexport const STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH = SN.creatorCoinFactoryClassHash!;\nexport const STARKNET_CREATOR_COIN_START_BLOCK = SN.creatorCoinStartBlock!;\nexport const STARKNET_EKUBO_CORE = SN.ekuboCore!;\n\n// ── Tokens (chain-agnostic) ───────────────────────────────────────────────────\nexport const SUPPORTED_TOKENS = [\n {\n // Circle-native USDC on Starknet (canonical)\n symbol: \"USDC\",\n address:\n \"0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb\",\n decimals: 6,\n listable: true,\n },\n {\n symbol: \"USDT\",\n address:\n \"0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8\",\n decimals: 6,\n listable: true,\n },\n {\n symbol: \"ETH\",\n address:\n \"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7\",\n decimals: 18,\n listable: true,\n },\n {\n symbol: \"STRK\",\n address:\n \"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d\",\n decimals: 18,\n listable: true,\n },\n {\n symbol: \"WBTC\",\n address:\n \"0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac\",\n decimals: 8,\n listable: true,\n },\n] as const;\n\nexport type SupportedTokenSymbol = (typeof SUPPORTED_TOKENS)[number][\"symbol\"];\n\n/** Default currency for listings and offers — Circle-native USDC on Starknet. */\nexport const DEFAULT_CURRENCY: SupportedTokenSymbol = \"USDC\";\n","import type { Chain } from \"./chains.js\";\n\n/** Chains that resolve in a URL today. Extend when a second chain is displayable. */\nexport const SUPPORTED_URL_CHAINS = [\"STARKNET\"] as const satisfies readonly Chain[];\n\n/** Chain enum → lowercase URL slug. The ONLY place the slug literal is produced. */\nexport function chainSlug(chain: Chain): string {\n return chain.toLowerCase();\n}\n\n/** URL slug → Chain enum, or null for an unknown/unsupported slug (caller 404s). */\nexport function chainFromSlug(slug: string): Chain | null {\n const upper = slug.toUpperCase() as Chain;\n return (SUPPORTED_URL_CHAINS as readonly Chain[]).includes(upper) ? upper : null;\n}\n\n/** Nullish contract/token/address values coerce to \"\" — an absent id was never\n * a valid link anyway, and this keeps callers free of artificial null guards. */\ntype Idish = string | number | null | undefined;\nconst seg = (v: Idish): string => (v == null ? \"\" : String(v));\n\nexport function assetHref(chain: Chain, contract: Idish, tokenId: Idish): string {\n return `/asset/${chainSlug(chain)}/${seg(contract)}/${seg(tokenId)}`;\n}\n\nexport function collectionHref(chain: Chain, contract: Idish): string {\n return `/collections/${chainSlug(chain)}/${seg(contract)}`;\n}\n\nexport function coinHref(chain: Chain, address: Idish): string {\n return `/coins/${chainSlug(chain)}/${seg(address)}`;\n}\n","import type { ServiceDefinition, ServiceCapability } from \"../types/api.js\";\nimport { getStarknetCoordinates } from \"../chains.js\";\n\n// The registry re-projects a service's chain coordinates into the generic\n// `onchain` shape (factoryAddress/classHash/startBlock). Single source = the\n// chain registry. Only STARKNET is populated today.\nconst SN = getStarknetCoordinates(\"STARKNET\");\n\n/**\n * The Medialane service registry (05-service-model §II, §VI).\n * Canonical long-form IDs (01-core-model §III). SDK-resident in v1;\n * on-chain registry later (08-dao-governance §IV).\n *\n * `onchain` is keyed per chain (spec 2026-06-13 §3.1, Decision A): the SDK\n * registry is the single source of a service's coordinates on each chain.\n * Only STARKNET is populated today; adding a chain adds a key here.\n *\n * Phase 2B.2 of the service-model refactor. `ip-erc721` has no dedicated\n * on-chain constant in src/constants.ts, so its `onchain` is omitted rather\n * than invented (the genesis contract address ships with that service).\n */\nconst SERVICES = {\n \"mip-erc721\": {\n id: \"mip-erc721\",\n displayName: \"IP Collection\",\n description: \"Tokenize intellectual property as a per-creator ERC-721 collection.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.collection721!,\n startBlock: SN.collection721StartBlock!,\n },\n },\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\", \"mint\", \"remix\", \"license\"],\n events: [\n { name: \"CollectionCreated\", emittedBy: \"factory\" },\n // Per-instance ERC-721 Transfer emitted by each deployed collection; not\n // yet declared here because the indexer polls discovered instances on a\n // slow schedule. Plan 2026-05-24-data-driven-event-registry.md covers\n // the migration.\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-erc721\": {\n id: \"ip-erc721\",\n displayName: \"Programmable IP (genesis)\",\n description: \"One shared ERC-721 contract; many wallets mint genesis pieces.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\", \"mint\", \"remix\", \"license\"],\n // No factory — single shared contract. Events declared when the genesis\n // contract address is wired into onchain.STARKNET.factoryAddress here.\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"mip-erc1155\": {\n id: \"mip-erc1155\",\n displayName: \"NFT Editions\",\n description: \"Per-creator ERC-1155 collection; creator mints editions.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.collection1155!,\n classHash: SN.collection1155ClassHash!,\n startBlock: SN.collection1155StartBlock!,\n },\n },\n uiVariant: \"edition\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\", \"mint\", \"remix\", \"license\"],\n events: [\n { name: \"CollectionDeployed\", emittedBy: \"factory\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"pop-protocol\": {\n id: \"pop-protocol\",\n displayName: \"POP Protocol\",\n description: \"Soulbound proof-of-presence collectibles per event.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.popFactory!,\n classHash: SN.popCollectionClassHash!,\n },\n },\n uiVariant: \"pop\",\n capabilities: [\"claim\", \"mint\"],\n events: [\n { name: \"CollectionCreated\", emittedBy: \"factory\" },\n { name: \"AllowlistUpdated\", emittedBy: \"instance\", poll: \"slow\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"drop-collection\": {\n id: \"drop-collection\",\n displayName: \"Collection Drop\",\n description: \"Sequential mint with claim windows + allowlist.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.dropFactory!,\n classHash: SN.dropCollectionClassHash!,\n },\n },\n uiVariant: \"drop\",\n capabilities: [\"claim\", \"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n events: [\n { name: \"DropCreated\", emittedBy: \"factory\" },\n { name: \"AllowlistUpdated\", emittedBy: \"instance\", poll: \"slow\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-tickets\": {\n id: \"ip-tickets\",\n displayName: \"IP Tickets\",\n description: \"Create verifiable on-chain tickets — mint to attendees, trade like any collection.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.ipTicketsFactory!,\n classHash: SN.ipTicketCollectionClassHash!,\n },\n },\n uiVariant: \"ticket\",\n capabilities: [\"mint\", \"redeem\", \"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n events: [\n { name: \"CollectionDeployed\", emittedBy: \"factory\" },\n { name: \"TicketCreated\", emittedBy: \"instance\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-club\": {\n id: \"ip-club\",\n displayName: \"IP Club\",\n description: \"Membership clubs — create tiers, mint membership cards, trade like any collection.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.ipClubFactory!,\n classHash: SN.ipClubCollectionClassHash!,\n },\n },\n uiVariant: \"club\",\n capabilities: [\"mint\", \"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n events: [\n { name: \"ClubDeployed\", emittedBy: \"factory\" },\n { name: \"MembershipCreated\", emittedBy: \"instance\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-sponsorship\": {\n id: \"ip-sponsorship\",\n displayName: \"IP Sponsorship\",\n description: \"Sponsorship offers and licenses anchored to an existing Medialane asset.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.ipSponsorship!,\n classHash: SN.ipSponsorshipClassHash!,\n startBlock: SN.ipSponsorshipStartBlock!,\n },\n },\n uiVariant: \"standard\",\n // v3: one contract is both the offer/bid/proposal registry and the\n // issued license collection (a real, standard ERC-721 minted internally\n // — no separate receipt contract). `transfer` reflects that a license is\n // freely transferable at the protocol layer; transferable/expiry intent\n // is declarative (carried in metadata + LicenseMinted), never\n // contract-enforced. Supersedes the 2026-07-02 v2 `ip-sponsorship`\n // (registry-only) + `ip-sponsorship-license` (non-authoritative receipt\n // via a dedicated ip-erc721 instance) pair — retired as of this redesign.\n capabilities: [\"sponsor\", \"transfer\"],\n events: [\n { name: \"OfferCreated\", emittedBy: \"factory\" },\n { name: \"ProposalCreated\", emittedBy: \"factory\" },\n { name: \"LicenseMinted\", emittedBy: \"factory\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"creator-coin\": {\n id: \"creator-coin\",\n displayName: \"Creator Coin\",\n description:\n \"Launch a fixed-supply social token with permanently-locked Ekubo liquidity.\",\n standard: \"ERC20\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.creatorCoinFactory!,\n classHash: SN.creatorCoinFactoryClassHash!,\n startBlock: SN.creatorCoinStartBlock!,\n },\n },\n uiVariant: \"coin\",\n // `swap` is a UI affordance (05 §III): the marketplace renders an embedded\n // Ekubo swap (via StarkZapp) for the coin. Settlement is Ekubo — Medialane\n // operates NO trading venue and custodies nothing. No venue service exists\n // for coins (unlike NFTs, whose Medialane marketplace contract settles them).\n capabilities: [\"launch\", \"swap\", \"transfer\"],\n events: [\n { name: \"CreatorCoinCreated\", emittedBy: \"factory\" },\n { name: \"CreatorCoinLaunched\", emittedBy: \"factory\" },\n ],\n },\n \"medialane-marketplace-erc721\": {\n id: \"medialane-marketplace-erc721\",\n displayName: \"Medialane Marketplace (ERC-721)\",\n description: \"ERC-721 order matching venue.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.marketplace721!,\n classHash: SN.marketplace721ClassHash!,\n startBlock: SN.marketplace721StartBlock!,\n },\n },\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\"],\n events: [\n { name: \"OrderCreated\", emittedBy: \"factory\" },\n { name: \"OrderFulfilled\", emittedBy: \"factory\" },\n { name: \"OrderCancelled\", emittedBy: \"factory\" },\n ],\n },\n \"medialane-marketplace-erc1155\": {\n id: \"medialane-marketplace-erc1155\",\n displayName: \"Medialane Marketplace (ERC-1155)\",\n description: \"ERC-1155 order matching venue.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.marketplace1155!,\n classHash: SN.marketplace1155ClassHash!,\n startBlock: SN.marketplace1155StartBlock!,\n },\n },\n uiVariant: \"edition\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\"],\n events: [\n { name: \"OrderCreated\", emittedBy: \"factory\" },\n { name: \"OrderFulfilled\", emittedBy: \"factory\" },\n { name: \"OrderCancelled\", emittedBy: \"factory\" },\n ],\n },\n \"external-erc20\": {\n id: \"external-erc20\",\n displayName: \"External ERC-20\",\n description:\n \"An ERC-20 token (e.g. an unrug memecoin or a partner coin) not deployed via a Medialane service. Brought in by owner claim or admin/partnership — never bulk-indexed. Generalizes to future chains.\",\n standard: \"ERC20\",\n provenance: \"EXTERNAL\",\n uiVariant: \"coin\",\n capabilities: [\"swap\", \"transfer\"],\n },\n \"external-erc721\": {\n id: \"external-erc721\",\n displayName: \"External ERC-721\",\n description: \"ERC-721 contract not deployed via a Medialane service.\",\n standard: \"ERC721\",\n provenance: \"EXTERNAL\",\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n },\n \"external-erc1155\": {\n id: \"external-erc1155\",\n displayName: \"External ERC-1155\",\n description: \"ERC-1155 contract not deployed via a Medialane service.\",\n standard: \"ERC1155\",\n provenance: \"EXTERNAL\",\n uiVariant: \"edition\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n },\n} as const satisfies Record<string, ServiceDefinition>;\n\n/**\n * Literal-union of every registered service ID. Use this as the type for\n * `Collection.service` write sites in consumers — typos like \"pop_protocol\"\n * (underscore instead of hyphen) become compile errors.\n *\n * `getService()` still accepts loose `string` for read-side lookups where the\n * value came from the DB and is trusted to already be valid.\n */\nexport type ServiceId = keyof typeof SERVICES;\n\n/** Type guard: narrows a string to ServiceId if it's registered. */\nexport function isServiceId(id: string | null | undefined): id is ServiceId {\n return typeof id === \"string\" && id in SERVICES;\n}\n\n/** Lookup. Returns undefined for unregistered service IDs — callers should\n * treat that as a data error, since every Collection.service value is\n * expected to map to a registered ServiceDefinition. */\nexport function getService(id: string | null | undefined): ServiceDefinition | undefined {\n return id && id in SERVICES ? (SERVICES as Record<string, ServiceDefinition>)[id] : undefined;\n}\n\n/** All registered services (e.g. the launchpad grid). */\nexport function listServices(): ServiceDefinition[] {\n return Object.values(SERVICES);\n}\n\n/** Services that declare a capability (e.g. \"where can users mint\"). */\nexport function getServicesByCapability(cap: ServiceCapability): ServiceDefinition[] {\n return Object.values(SERVICES).filter(\n (s) => (s.capabilities as readonly ServiceCapability[]).includes(cap),\n );\n}\n\n/** Whether a service declares a given capability — e.g. whether an asset\n * type is transferable. Returns false for an unregistered/missing id rather\n * than throwing, since callers use this for UI copy, not authority checks. */\nexport function hasCapability(\n id: string | null | undefined,\n cap: ServiceCapability,\n): boolean {\n return getService(id)?.capabilities.includes(cap) ?? false;\n}\n","import { SUPPORTED_TOKENS } from \"../constants.js\";\n\nexport type SupportedToken = (typeof SUPPORTED_TOKENS)[number];\n\n/**\n * Parse a human-readable amount (e.g. \"1.5\") to its raw integer string\n * representation given the token's decimal places.\n * Uses pure BigInt arithmetic to avoid floating point precision loss.\n */\nexport function parseAmount(human: string, decimals: number): string {\n const [whole, frac = \"\"] = human.split(\".\");\n const fracPadded = frac.padEnd(decimals, \"0\").slice(0, decimals);\n return (BigInt(whole) * BigInt(10) ** BigInt(decimals) + BigInt(fracPadded)).toString();\n}\n\n/**\n * Format a raw integer string (e.g. \"1500000\") to a human-readable decimal\n * string given the token's decimal places.\n */\nexport function formatAmount(raw: string, decimals: number): string {\n const value = BigInt(raw);\n const factor = 10n ** BigInt(decimals);\n const whole = value / factor;\n const remainder = value % factor;\n const fractional = remainder.toString().padStart(decimals, \"0\");\n return `${whole}.${fractional}`;\n}\n\n/**\n * Find a supported token by its contract address.\n *\n * Compares by numeric felt value so a caller-supplied address that isn't\n * zero-padded to 64 hex chars (`0x33068f6…`) still matches the stored padded\n * form (`0x033068f6…`) — a bare `.toLowerCase()` string compare would miss it,\n * the exact padding trap the address invariant warns against. Non-hex inputs\n * fall back to a case-insensitive string compare.\n */\nexport function getTokenByAddress(address: string): SupportedToken | undefined {\n let target: bigint | null = null;\n try {\n target = BigInt(address);\n } catch {\n target = null;\n }\n return SUPPORTED_TOKENS.find((t) => {\n if (target !== null) {\n try {\n return BigInt(t.address) === target;\n } catch {\n /* stored address not hex — fall through to string compare */\n }\n }\n return t.address.toLowerCase() === address.toLowerCase();\n });\n}\n\n/**\n * Find a supported token by its symbol (case-insensitive).\n */\nexport function getTokenBySymbol(symbol: string): SupportedToken | undefined {\n const upper = symbol.toUpperCase();\n return SUPPORTED_TOKENS.find((t) => t.symbol === upper);\n}\n\n/**\n * Return all tokens available for use in listing and offer dialogs.\n * Tokens with listable: false appear only as marketplace filter chips.\n */\nexport function getListableTokens(): ReadonlyArray<SupportedToken> {\n return SUPPORTED_TOKENS.filter((t) => t.listable);\n}\n","/**\n * Recursively convert all BigInt values to their decimal string representations.\n * Required before JSON serialisation and before passing objects to starknet.js\n * functions that expect string felts.\n */\nexport function stringifyBigInts(obj: unknown): unknown {\n if (typeof obj === \"bigint\") {\n return obj.toString();\n }\n if (Array.isArray(obj)) {\n return obj.map(stringifyBigInts);\n }\n if (obj !== null && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj as Record<string, unknown>).map(([key, value]) => [\n key,\n stringifyBigInts(value),\n ])\n );\n }\n return obj;\n}\n\n/**\n * Convert a u256 represented as { low: string; high: string } to a single BigInt.\n */\nexport function u256ToBigInt(low: string, high: string): bigint {\n return BigInt(low) + (BigInt(high) << 128n);\n}\n","/**\n * Resilient Starknet RPC helpers — the single source of truth for \"what counts\n * as a transient RPC failure\" and the public fallback endpoint list, shared by\n * every Medialane app:\n * - dapp / io `starknetProvider` singletons (RpcProvider.baseFetch)\n * - io `/api/rpc` server-side proxy (upstream rotation)\n * - backend circuit breaker + receipt-rotation paths\n *\n * Motivation (2026-06-03): Alchemy's Starknet mainnet endpoint intermittently\n * returns HTTP 503 with the JSON-RPC envelope `-32001 \"Unable to complete\n * request at this time.\"` (~1 in 6 calls, while its status page reads green).\n * A single blip inside a `waitForTransaction` poll loop stalls mints/listings.\n * Failing over to a public endpoint recovers silently.\n */\n\n/**\n * Ordered public Starknet **mainnet** RPC endpoints (no API key required),\n * used as fallback after an app's configured primary (e.g. Alchemy) returns a\n * transient error. lava.build — RPC spec 0.8.1, permissive CORS — so it is\n * safe for browser `baseFetch` use as well as server-side rotation.\n *\n * blastapi.io and free-rpc.nethermind.io were removed (2026-07-04) — long\n * confirmed dead/unreliable in production; do not re-add them.\n */\nexport const PUBLIC_RPC_FALLBACKS: readonly string[] = [\n \"https://rpc.starknet.lava.build\",\n];\n\n/**\n * Matches transient failure signals in a raw response body or JSON-RPC error\n * message. Deterministic Starknet contract errors (revert / invalid params —\n * small positive JSON-RPC codes) MUST NOT match: they propagate verbatim so\n * callers see the real failure. Note `-32000` is intentionally absent — the io\n * `/api/rpc` proxy uses it for \"Unauthorized\", which must not trigger failover.\n */\nconst TRANSIENT_BODY_RE =\n /\"code\"\\s*:\\s*-32001|\"code\"\\s*:\\s*-32603|unable to complete|rate.?limit|too many|throttl|exceed.*quota|temporarily unavailable|service unavailable|overload|gateway.*time|upstream.*time|backend.*error/i;\n\n/**\n * Is this RPC response worth retrying against another endpoint?\n *\n * Accepts either an HTTP status + raw text body (client `baseFetch` path) or a\n * parsed JSON-RPC envelope (server proxy path). For parsed envelopes the\n * server-defined error-code range (`-32099..-32000`) is treated as transient;\n * for raw text only the explicit `-32001`/`-32603` codes + message hints match,\n * so a `-32000` \"Unauthorized\" text body is never mistaken for transient.\n */\nexport function isTransientRpcError(input: { status?: number; body?: unknown }): boolean {\n const { status, body } = input;\n if (typeof status === \"number\" && (status === 429 || status >= 500)) return true;\n if (body == null) return false;\n\n // Parsed JSON-RPC envelope: inspect error.code numerically.\n if (typeof body === \"object\") {\n const err = (body as { error?: { code?: unknown; message?: unknown } }).error;\n if (!err || typeof err !== \"object\") return false;\n const code = (err as { code?: unknown }).code;\n if (typeof code === \"number\") {\n if (code === 429) return true;\n if (code >= -32099 && code <= -32000) return true; // server-defined range (incl. -32001)\n if (code === -32603) return true; // generic internal error\n }\n const message = (err as { message?: unknown }).message;\n return typeof message === \"string\" ? TRANSIENT_BODY_RE.test(message) : false;\n }\n\n // Raw text body (client baseFetch path).\n return TRANSIENT_BODY_RE.test(String(body));\n}\n\nexport interface FailoverFetchOptions {\n /** Underlying fetch to wrap (e.g. one that adds a timeout). Defaults to the global `fetch`. */\n baseFetch?: typeof fetch;\n /** Invoked each time an endpoint is abandoned for the next one. */\n onFailover?: (info: { url: string; status?: number; error?: unknown }) => void;\n}\n\n/**\n * Build a `fetch` suitable for `RpcProvider.baseFetch` that tries each URL in\n * `urls` in order, advancing to the next only on a transient failure (network\n * error, 5xx/429, or a transient JSON-RPC envelope). The provider's own\n * `nodeUrl` argument is ignored — routing is controlled entirely by `urls` —\n * so callers should set `nodeUrl: urls[0]` (used only for spec negotiation).\n *\n * @example\n * const urls = [primaryAlchemyUrl, ...PUBLIC_RPC_FALLBACKS];\n * new RpcProvider({ nodeUrl: urls[0], baseFetch: createFailoverFetch(urls) });\n */\nexport function createFailoverFetch(\n urls: string[],\n options: FailoverFetchOptions = {},\n): typeof fetch {\n const endpoints = urls.filter((u): u is string => Boolean(u));\n if (endpoints.length === 0) {\n throw new Error(\"createFailoverFetch: at least one RPC URL is required\");\n }\n const doFetch = options.baseFetch ?? fetch;\n\n const failover = async (_input: unknown, init?: RequestInit): Promise<Response> => {\n let lastError: unknown;\n\n for (let i = 0; i < endpoints.length; i++) {\n const url = endpoints[i];\n const isLast = i === endpoints.length - 1;\n try {\n const res = await doFetch(url, init);\n const text = await res.text();\n const rebuilt = () =>\n new Response(text, { status: res.status, statusText: res.statusText, headers: res.headers });\n\n if (isLast || !isTransientRpcError({ status: res.status, body: text })) {\n return rebuilt();\n }\n options.onFailover?.({ url, status: res.status });\n } catch (err) {\n lastError = err;\n if (isLast) throw err;\n options.onFailover?.({ url, error: err });\n }\n }\n\n // Loop always returns/throws on the last endpoint; this satisfies the type checker.\n throw lastError ?? new Error(\"createFailoverFetch: all endpoints failed\");\n };\n\n return failover as unknown as typeof fetch;\n}\n"]}
1
+ {"version":3,"sources":["../src/chains.ts","../src/fee/config.ts","../src/config.ts","../src/utils/address.ts","../src/utils/retry.ts","../src/api/client.ts","../src/types/api.ts","../src/constants.ts","../src/routes.ts","../src/services/registry.ts","../src/utils/token.ts","../src/utils/bigint.ts","../src/utils/rpc.ts"],"names":["z","keccak_256","base58","base32","SN"],"mappings":"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","file":"index.cjs","sourcesContent":["// Single source of per-chain coordinates for Medialane's own services\n// (spec 2026-06-13 §3.1, Decision A). Keyed by CHAIN ALONE — Medialane is\n// mainnet-only, so there is no network axis (refines decisions.md D-9).\n\n/** Mirrors the backend Prisma `Chain` enum. */\nexport const CHAINS = [\"STARKNET\", \"ETHEREUM\", \"SOLANA\", \"BASE\", \"STELLAR\", \"BITCOIN\"] as const;\nexport type Chain = (typeof CHAINS)[number];\n\n/** Starknet coordinates of Medialane services + venues. All fields optional\n * because not every service exists on every chain. */\nexport interface StarknetCoordinates {\n rpcUrl: string;\n marketplace721?: `0x${string}`;\n marketplace721ClassHash?: `0x${string}`;\n marketplace721StartBlock?: number;\n marketplace1155?: `0x${string}`;\n marketplace1155ClassHash?: `0x${string}`;\n marketplace1155StartBlock?: number;\n collection721?: `0x${string}`;\n collection721StartBlock?: number;\n ipNftClassHash?: `0x${string}`;\n ipCollectionClassHash?: `0x${string}`;\n collection1155?: `0x${string}`;\n collection1155FactoryClassHash?: `0x${string}`;\n collection1155ClassHash?: `0x${string}`;\n collection1155StartBlock?: number;\n popFactory?: `0x${string}`;\n popCollectionClassHash?: `0x${string}`;\n dropFactory?: `0x${string}`;\n dropCollectionClassHash?: `0x${string}`;\n nftComments?: `0x${string}`;\n creatorCoinFactory?: `0x${string}`;\n creatorCoinEkuboLauncher?: `0x${string}`;\n creatorCoinClassHash?: `0x${string}`;\n creatorCoinFactoryClassHash?: `0x${string}`;\n creatorCoinStartBlock?: number;\n ekuboCore?: `0x${string}`;\n ipTicketsFactory?: `0x${string}`;\n ipTicketCollectionClassHash?: `0x${string}`;\n ipTicketsFactoryClassHash?: `0x${string}`;\n ipTicketsStartBlock?: number;\n ipClubFactory?: `0x${string}`;\n ipClubFactoryClassHash?: `0x${string}`;\n ipClubCollectionClassHash?: `0x${string}`;\n ipClubFactoryStartBlock?: number;\n ipSponsorship?: `0x${string}`;\n ipSponsorshipClassHash?: `0x${string}`;\n ipSponsorshipStartBlock?: number;\n}\n\n/** Coordinates per chain. Only STARKNET is populated today; adding a chain\n * means adding an entry here (litmus test, spec §7). */\n/** EVM coordinates — one shape for Ethereum and Base (same bytecode, two\n * chains). Populated at deploy time (federation Phase 4). */\nexport interface EvmCoordinates {\n rpcUrl: string;\n marketplace721?: `0x${string}`;\n marketplace721StartBlock?: number;\n marketplace1155?: `0x${string}`;\n marketplace1155StartBlock?: number;\n mipRegistry?: `0x${string}`;\n mipRegistryStartBlock?: number;\n mipEditionsRegistry?: `0x${string}`;\n mipEditionsRegistryStartBlock?: number;\n}\n\n/** Solana coordinates — base58 program ids. Populated at deploy time. */\nexport interface SolanaCoordinates {\n rpcUrl: string;\n mipCollectionsProgram?: string;\n marketplaceProgram?: string;\n startSlot?: number;\n}\n\n/** Stellar (Soroban) coordinates — strkey contract ids. Populated at deploy\n * time; the registry takes the collection WASM hash as a constructor arg. */\nexport interface StellarCoordinates {\n rpcUrl: string;\n mipRegistry?: string;\n marketplace?: string;\n collectionWasmHash?: string;\n startLedger?: number;\n}\n\n/** Per-chain coordinate shapes. Every chain is an equal entry — no chain is\n * privileged in core (chain-sovereignty I2/I4). */\nexport interface CoordinatesByChain {\n STARKNET?: StarknetCoordinates;\n ETHEREUM?: EvmCoordinates;\n BASE?: EvmCoordinates;\n SOLANA?: SolanaCoordinates;\n STELLAR?: StellarCoordinates;\n BITCOIN?: never;\n}\n\n/** @deprecated Renamed — use `StarknetCoordinates` (coordinates are per-chain-shaped). */\nexport type ChainCoordinates = StarknetCoordinates;\n\nconst COORDINATES: CoordinatesByChain = {\n STARKNET: {\n rpcUrl: \"https://rpc.starknet.lava.build\",\n marketplace721: \"0x03eda9a2b6ad90845a43591bac8083ebaf677d51fdf20f503b2c01889e3131fc\",\n marketplace721ClassHash: \"0x0700d9230d07e5203e27778c0dc70f9134d2b25bf319f7cf8348dc66a6923e90\",\n marketplace721StartBlock: 11198146,\n marketplace1155: \"0x07c4ce1c19ea48cc11135ed22b19ff745f5aec508c3828593002e4f76fdb1b38\",\n marketplace1155ClassHash: \"0x0242f5c388da7cee2d99e2a69453c8159bf927fbec4e797a3cfdcbbcb5b68328\",\n marketplace1155StartBlock: 11198267,\n collection721: \"0x0225c3ae09506b8d97adc39649ca740dad5aac195b7f5f0441cc1852947acaea\",\n collection721StartBlock: 11198496,\n ipNftClassHash: \"0x012d3ae40ba35c7e2be0946532dac60e48932447912fdf96b674da67c029b9cc\",\n ipCollectionClassHash: \"0x022155a1a130a40e57aac4b89c07fab3f616bc351b1270fc40f756b963afe8b4\",\n collection1155: \"0x015368976d46fae5bfa1c58600f641d5aa5dbbf53ebc6b78aa3922194aad3551\",\n collection1155FactoryClassHash: \"0x04eb6b419770f13bd191f120b9fc9ee624c0613ad4490062d293ca2016b3b1d2\",\n collection1155ClassHash: \"0x06cf3f5a2322dac35e07a6064a5b8802f19fda8aa3f4726f0cb7bc05dea1bd78\",\n collection1155StartBlock: 11199527,\n popFactory: \"0x00b32c34b427d8f346b5843ada6a37bd3368d879fc752cd52b68a87287f60111\",\n popCollectionClassHash: \"0x077c421686f10851872561953ea16898d933364b7f8937a5d7e2b1ba0a36263f\",\n dropFactory: \"0x03587f42e29daee1b193f6cf83bf8627908ed6632d0d83fcb26225c50547d800\",\n dropCollectionClassHash: \"0x00092e72cdb63067521e803aaf7d4101c3e3ce026ae6bc045ec4228027e58282\",\n nftComments: \"0x02cdac70c94447189af0389dfea63f4d5e4154ea8a563de288a5ab1c39e37843\",\n creatorCoinFactory: \"0x50fa807b5274079fb19374673d7bab6d2dc3af7e1032ea43eb6e44bcbde4c3c\",\n creatorCoinEkuboLauncher: \"0x4f7fceb5ac10f12f9544a09580592e5bdf1b7f04f48765eecf12286d8ccb7b4\",\n creatorCoinClassHash: \"0x743e4c8a5b96bb83bbf4af04edbbb482d5ece89eed9b729a79fb7df0cd0b6b6\",\n creatorCoinFactoryClassHash: \"0x51765926b1344c9a20b8cd4b5abe7b7d47375ae97cf6804db3ea5d4b05a9b55\",\n creatorCoinStartBlock: 10474544,\n ekuboCore: \"0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b\",\n ipTicketsFactory: \"0x0767bf5b57e1f812463159b5ed683183e1b0c3f942b74871b5c6cd6a93c15e99\",\n ipTicketCollectionClassHash: \"0x0449e8eb7c117740d07cb8e0157d32c8ba3d19d1cfd2784ed5e139f5a1e04acc\",\n ipTicketsFactoryClassHash: \"0x04a739ac3a673ebd0db96bb24475600797c3ed34827e79517f9b2b1640276e6a\",\n ipTicketsStartBlock: 11933694,\n ipClubFactory: \"0x06a0b0be16d70c78f2e18119dbf90e5911cbfd5d8d484bc555dc61d96f56a2b9\",\n ipClubFactoryClassHash: \"0x05d9d431bd3532b1fa4d5bab572f49c5ad8034ee3cc83951aa41ae82c9cad266\",\n ipClubCollectionClassHash: \"0x05b8477c72e6bf0cf64967d71155021fd4d77d9a57e8805c6b40709121c002c5\",\n ipClubFactoryStartBlock: 11928775,\n // v3 redesign (deployed 2026-07-15): single contract is both the\n // offer/bid/proposal registry and the license collection (embeds\n // ERC721Component directly) — no separate receipt contract, no\n // set_minter bootstrap. Supersedes the 2026-07-02 v2 address, which had\n // zero offers/licenses ever issued (clean cutover, no reclassification).\n ipSponsorship: \"0x03729ebe0fedf29ec97fca34db09174772af7f870af26a26e024a61040143e5c\",\n ipSponsorshipClassHash: \"0x0626daac2ed7e2bf630ef5b10104b3202db1559216c0c1a504c0e99be2fbfec3\",\n ipSponsorshipStartBlock: 11896456,\n },\n};\n\nexport function getCoordinates(chain: \"STARKNET\"): StarknetCoordinates;\nexport function getCoordinates(chain: \"ETHEREUM\" | \"BASE\"): EvmCoordinates;\nexport function getCoordinates(chain: \"SOLANA\"): SolanaCoordinates;\nexport function getCoordinates(chain: \"STELLAR\"): StellarCoordinates;\nexport function getCoordinates(\n chain: Chain,\n): StarknetCoordinates | EvmCoordinates | SolanaCoordinates | StellarCoordinates;\nexport function getCoordinates(\n chain: Chain,\n): StarknetCoordinates | EvmCoordinates | SolanaCoordinates | StellarCoordinates {\n const c = COORDINATES[chain];\n if (!c) throw new Error(`No coordinates configured for chain \"${chain}\"`);\n return c;\n}\n\nexport const DEFAULT_CHAIN: Chain = \"STARKNET\";\n\n/** Typed Starknet coordinates for Starknet-only modules; throws when the\n * client is scoped to another chain. */\nexport function getStarknetCoordinates(chain: Chain): StarknetCoordinates {\n if (chain !== \"STARKNET\") {\n throw new Error(`This module is Starknet-only (client chain: \"${chain}\")`);\n }\n return getCoordinates(\"STARKNET\");\n}\n","import { z } from \"zod\";\n\nexport const FeeConfigSchema = z.object({\n enabled: z.boolean().default(true),\n fundAddress: z.string().min(1).optional(),\n marketplaceBps: z.number().int().min(0).max(10000).default(100),\n launchpadBps: z.number().int().min(0).max(10000).default(100),\n});\n\nexport type FeeConfig = z.input<typeof FeeConfigSchema>;\n\nexport interface ResolvedFeeConfig {\n enabled: boolean;\n fundAddress: string | undefined;\n marketplaceBps: number;\n launchpadBps: number;\n}\n\nexport function resolveFeeConfig(raw: FeeConfig | undefined): ResolvedFeeConfig {\n const p = FeeConfigSchema.parse(raw ?? {});\n return {\n enabled: p.enabled,\n fundAddress: p.fundAddress,\n marketplaceBps: p.marketplaceBps,\n launchpadBps: p.launchpadBps,\n };\n}\n","import { z } from \"zod\";\nimport { CHAINS, getCoordinates, DEFAULT_CHAIN, type Chain } from \"./chains.js\";\nimport type { RetryOptions } from \"./utils/retry.js\";\nimport { FeeConfigSchema, resolveFeeConfig, type ResolvedFeeConfig } from \"./fee/index.js\";\n\nexport const MedialaneConfigSchema = z.object({\n // Chain-scoped client (spec 2026-06-13 Decision B): one client per chain,\n // coordinates resolved from the registry. Replaces the removed `network` axis.\n chain: z.enum(CHAINS).default(DEFAULT_CHAIN),\n rpcUrl: z.string().url().optional(),\n backendUrl: z.string().url().optional(),\n apiKey: z.string().optional(),\n // Per-contract overrides remain for tests/forks; default from the registry.\n marketplace721Contract: z.string().optional(),\n marketplaceContract: z.string().optional(),\n marketplace1155Contract: z.string().optional(),\n collection721Contract: z.string().optional(),\n collectionContract: z.string().optional(),\n collection1155Contract: z.string().optional(),\n retryOptions: z.object({\n maxAttempts: z.number().int().min(1).max(10).optional(),\n baseDelayMs: z.number().int().min(0).optional(),\n maxDelayMs: z.number().int().min(0).optional(),\n }).optional(),\n feeConfig: FeeConfigSchema.optional(),\n});\n\nexport type MedialaneConfig = z.input<typeof MedialaneConfigSchema>;\n\nexport interface ResolvedConfig {\n chain: Chain;\n rpcUrl: string;\n backendUrl: string | undefined;\n apiKey: string | undefined;\n marketplace721Contract: string;\n marketplaceContract: string;\n marketplace1155Contract: string;\n collection721Contract: string;\n collectionContract: string;\n collection1155Contract: string;\n retryOptions?: RetryOptions;\n feeConfig: ResolvedFeeConfig;\n}\n\nexport function resolveConfig(raw: MedialaneConfig): ResolvedConfig {\n const parsed = MedialaneConfigSchema.parse(raw);\n const coords = getCoordinates(parsed.chain);\n // The resolved contract fields are the Starknet module surface; on other\n // chains they stay unset and the per-chain adapters resolve their own\n // coordinates.\n const sn = (parsed.chain === \"STARKNET\" ? coords : {}) as import(\"./chains.js\").StarknetCoordinates;\n\n const marketplace721Contract =\n parsed.marketplace721Contract ?? parsed.marketplaceContract ?? sn.marketplace721!;\n const collection721Contract =\n parsed.collection721Contract ?? parsed.collectionContract ?? sn.collection721!;\n\n return {\n chain: parsed.chain,\n rpcUrl: parsed.rpcUrl ?? coords.rpcUrl,\n backendUrl: parsed.backendUrl,\n apiKey: parsed.apiKey,\n marketplace721Contract,\n marketplaceContract: marketplace721Contract,\n marketplace1155Contract: parsed.marketplace1155Contract ?? sn.marketplace1155!,\n collection721Contract,\n collectionContract: collection721Contract,\n collection1155Contract: parsed.collection1155Contract ?? sn.collection1155!,\n retryOptions: parsed.retryOptions,\n feeConfig: resolveFeeConfig(parsed.feeConfig),\n };\n}\n","import { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport { base32, base58 } from \"@scure/base\";\nimport type { Chain } from \"../chains.js\";\n\n/**\n * Normalize an address to its chain's canonical form. The single source of\n * address normalization across Medialane (07-identity §I; spec 2026-06-13 §3.2).\n * `medialane-backend` re-exports this; do not maintain a parallel copy.\n *\n * - STARKNET: 0x-prefixed 64-char lowercase hex (felt, zero-padded).\n * - ETHEREUM / BASE: EIP-55 mixed-case checksum.\n * - SOLANA: base58, validated as a 32-byte public key, returned verbatim.\n * - STELLAR: strkey (G… account / C… contract), CRC16-XModem-verified,\n * canonical uppercase.\n * - BITCOIN: not implemented — a non-foreclosed seam, gated on a future\n * Bitcoin fork (chain-sovereignty §2); never a built path today.\n */\nexport function normalizeAddress(chain: Chain, address: string): string {\n switch (chain) {\n case \"STARKNET\":\n return normalizeStarknet(address);\n case \"ETHEREUM\":\n case \"BASE\":\n return normalizeEvm(address);\n case \"SOLANA\":\n return normalizeSolana(address);\n case \"STELLAR\":\n return normalizeStellar(address);\n case \"BITCOIN\":\n throw new Error(\"BITCOIN address normalization not implemented\");\n }\n}\n\nfunction normalizeStarknet(address: string): string {\n try {\n const hex = BigInt(address).toString(16);\n return \"0x\" + hex.padStart(64, \"0\").toLowerCase();\n } catch {\n throw new Error(`Invalid STARKNET address: \"${address}\"`);\n }\n}\n\nfunction normalizeEvm(address: string): string {\n const m = /^0x([0-9a-fA-F]{40})$/.exec(address);\n if (!m) throw new Error(`Invalid ETHEREUM/BASE address: \"${address}\"`);\n const lower = m[1].toLowerCase();\n // EIP-55: keccak256 of the lowercase hex (ASCII, no 0x); uppercase the i-th\n // hex char when the i-th nibble of the hash is >= 8.\n const hash = keccak_256(new TextEncoder().encode(lower));\n let out = \"0x\";\n for (let i = 0; i < 40; i++) {\n const nibble = (hash[i >> 1]! >> (i % 2 === 0 ? 4 : 0)) & 0xf;\n out += nibble >= 8 ? lower[i]!.toUpperCase() : lower[i];\n }\n return out;\n}\n\nfunction normalizeSolana(address: string): string {\n try {\n const bytes = base58.decode(address);\n if (bytes.length !== 32) throw new Error(\"not a 32-byte key\");\n return address; // base58 is canonical and case-sensitive — return as-is\n } catch {\n throw new Error(`Invalid SOLANA address: \"${address}\"`);\n }\n}\n\n/** Stellar strkey version bytes: 'G' account (6<<3), 'C' contract (2<<3). */\nconst STELLAR_VERSION_BYTES = new Set([6 << 3, 2 << 3]);\n\nfunction normalizeStellar(address: string): string {\n const upper = address.toUpperCase();\n if (!/^[GC][A-Z2-7]{55}$/.test(upper)) {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n let decoded: Uint8Array;\n try {\n decoded = base32.decode(upper);\n } catch {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n if (decoded.length !== 35 || !STELLAR_VERSION_BYTES.has(decoded[0]!)) {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n const payload = decoded.subarray(0, 33);\n const checksum = decoded[33]! | (decoded[34]! << 8);\n if (crc16xmodem(payload) !== checksum) {\n throw new Error(`Invalid STELLAR address: \"${address}\"`);\n }\n return upper;\n}\n\n/** CRC16-XModem (poly 0x1021, init 0x0000) — the strkey checksum. */\nfunction crc16xmodem(bytes: Uint8Array): number {\n let crc = 0;\n for (const byte of bytes) {\n crc ^= byte << 8;\n for (let i = 0; i < 8; i++) {\n crc = crc & 0x8000 ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff;\n }\n }\n return crc;\n}\n\n/**\n * Normalize a felt/hash (tx hash, order hash) to 0x-prefixed 64-char lowercase\n * hex. Starknet-shaped; chain-scoped at call sites that handle other chains'\n * hashes.\n */\nexport function normalizeHash(hash: string): string {\n try {\n const hex = BigInt(hash).toString(16);\n return \"0x\" + hex.padStart(64, \"0\").toLowerCase();\n } catch {\n throw new Error(`Invalid hash: \"${hash}\"`);\n }\n}\n\n/** Shorten an address to \"0x1234...abcd\" form, normalized for its chain. */\nexport function shortenAddress(chain: Chain, address: string, chars = 4): string {\n const norm = normalizeAddress(chain, address);\n return `${norm.slice(0, chars + 2)}...${norm.slice(-chars)}`;\n}\n","import { MedialaneApiError } from \"../api/client.js\";\n\nexport interface RetryOptions {\n maxAttempts?: number;\n baseDelayMs?: number;\n maxDelayMs?: number;\n}\n\nconst DEFAULT_MAX_ATTEMPTS = 3;\nconst DEFAULT_BASE_DELAY_MS = 300;\nconst DEFAULT_MAX_DELAY_MS = 5000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n opts?: RetryOptions\n): Promise<T> {\n const maxAttempts = opts?.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;\n const baseDelayMs = opts?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS;\n const maxDelayMs = opts?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n\n // Don't retry 4xx client errors — EXCEPT 429 (rate limited), which is\n // transient and clears with a short wait.\n if (err instanceof MedialaneApiError && err.status < 500 && err.status !== 429) {\n throw err;\n }\n\n // Retry on 5xx, 429, or network errors (TypeError from fetch).\n const isRetryable =\n (err instanceof MedialaneApiError && (err.status >= 500 || err.status === 429)) ||\n err instanceof TypeError;\n\n if (!isRetryable || attempt === maxAttempts - 1) {\n throw err;\n }\n\n // Prefer the server's Retry-After when it gave one (429 rate limits),\n // otherwise exponential backoff with jitter. Either way capped at\n // maxDelayMs so a client never hangs on a long server-asked wait.\n const retryAfterMs = err instanceof MedialaneApiError ? err.retryAfterMs : undefined;\n const backoff = baseDelayMs * Math.pow(2, attempt) + Math.random() * baseDelayMs;\n const delay = Math.min(retryAfterMs ?? backoff, maxDelayMs);\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n","import { normalizeAddress } from \"../utils/address.js\";\nimport type { Chain } from \"../chains.js\";\nimport type { ChainFilter } from \"../types/api.js\";\nimport type { MedialaneErrorCode } from \"../types/errors.js\";\nimport { withRetry, type RetryOptions } from \"../utils/retry.js\";\nimport type {\n ApiOrder,\n ApiOrdersQuery,\n ApiCounterOffersQuery,\n ApiToken,\n ApiCollection,\n ApiCoin,\n ApiUserRewards,\n ApiRewardsLeaderboardEntry,\n ApiRewardsConfig,\n ApiRewardsBatchEntry,\n ApiPointEvent,\n ApiCoinsQuery,\n ApiCollectionProfile,\n ApiCreatorProfile,\n ApiCreatorListResult,\n ApiCollectionClaim,\n ApiCollectionSlugClaim,\n ApiUserWallet,\n ApiAppSource,\n ApiChain,\n ApiActivity,\n ApiActivitiesQuery,\n ApiComment,\n ApiRemixOffer,\n ApiRemixOffersQuery,\n ApiPublicRemix,\n ApiSearchResult,\n ApiIntent,\n ApiIntentCreated,\n ApiMetadataSignedUrl,\n ApiMetadataUpload,\n ApiPortalMe,\n ApiPortalKey,\n ApiPortalKeyCreated,\n ApiUsageDay,\n ApiWebhookEndpoint,\n ApiWebhookCreated,\n CreateWebhookParams,\n CreateListingIntentParams,\n MakeOfferIntentParams,\n FulfillOrderIntentParams,\n CancelOrderIntentParams,\n CreateMintIntentParams,\n CreateCollectionIntentParams,\n CreateCounterOfferIntentParams,\n CreateRemixOfferParams,\n AutoRemixOfferParams,\n ConfirmSelfRemixParams,\n ConfirmRemixOfferParams,\n ApiResponse,\n CollectionSort,\n CollectionTokensSort,\n PopClaimStatus,\n PopBatchEligibilityItem,\n DropMintStatus,\n} from \"../types/api.js\";\n\nfunction deriveErrorCode(status: number): MedialaneErrorCode {\n if (status === 404) return \"TOKEN_NOT_FOUND\";\n if (status === 429) return \"RATE_LIMITED\";\n if (status === 410) return \"INTENT_EXPIRED\";\n if (status === 401 || status === 403) return \"UNAUTHORIZED\";\n if (status === 400) return \"INVALID_PARAMS\";\n return \"UNKNOWN\";\n}\n\nexport class MedialaneApiError extends Error {\n readonly code: MedialaneErrorCode;\n constructor(\n public readonly status: number,\n message: string,\n /** Parsed `Retry-After` (ms) when the server sent one — used by withRetry on 429. */\n public readonly retryAfterMs?: number,\n ) {\n super(message);\n this.name = \"MedialaneApiError\";\n this.code = deriveErrorCode(status);\n }\n}\n\n/** Parse an HTTP `Retry-After` header (delta-seconds or HTTP-date) to milliseconds. */\nexport function parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const seconds = Number(value);\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n const date = Date.parse(value);\n if (!Number.isNaN(date)) return Math.max(0, date - Date.now());\n return undefined;\n}\n\nexport class ApiClient {\n private readonly baseHeaders: Record<string, string>;\n private readonly retryOptions: RetryOptions | undefined;\n\n constructor(\n private readonly baseUrl: string,\n apiKey?: string,\n retryOptions?: RetryOptions,\n private readonly chain: Chain = \"STARKNET\"\n ) {\n this.baseHeaders = apiKey ? { \"x-api-key\": apiKey } : {};\n this.retryOptions = retryOptions;\n }\n\n /** Normalize an address for this client's chain (chain-scoped — Decision B). */\n private addr(a: string): string {\n return normalizeAddress(this.chain, a);\n }\n\n /**\n * The one HTTP path for the whole client: base headers (incl. x-api-key),\n * JSON error unwrapping, and `withRetry` (5xx/network only — 4xx never\n * retried). `allow404`/`allow403` turn those statuses into a `null` result\n * instead of a throw, for \"profile may not exist\" / \"not a holder\" reads —\n * so no method needs to hand-roll `fetch` to get that behavior.\n */\n private async request<T>(\n path: string,\n init?: RequestInit,\n opts?: { allow404?: boolean; allow403?: boolean },\n ): Promise<T> {\n const url = `${this.baseUrl.replace(/\\/$/, \"\")}${path}`;\n const headers: Record<string, string> = { ...this.baseHeaders };\n if (!(init?.body instanceof FormData)) {\n headers[\"Content-Type\"] = \"application/json\";\n }\n const allowed = (status: number): boolean =>\n (opts?.allow404 === true && status === 404) || (opts?.allow403 === true && status === 403);\n\n const res = await withRetry(async () => {\n const response = await fetch(url, {\n ...init,\n headers: { ...headers, ...(init?.headers as Record<string, string> | undefined) },\n });\n if (!response.ok && !allowed(response.status)) {\n const text = await response.text().catch(() => response.statusText);\n let message = text;\n try {\n const body = JSON.parse(text) as { error?: string };\n if (body.error) message = body.error;\n } catch {\n // use raw text\n }\n throw new MedialaneApiError(response.status, message, parseRetryAfter(response.headers.get(\"retry-after\")));\n }\n return response;\n }, this.retryOptions);\n\n if (allowed(res.status)) return null as T;\n return res.json() as Promise<T>;\n }\n\n private get<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: \"GET\" });\n }\n\n private post<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(path, { method: \"POST\", body: JSON.stringify(body) });\n }\n\n private patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(path, { method: \"PATCH\", body: JSON.stringify(body) });\n }\n\n private del<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: \"DELETE\" });\n }\n\n /** Bearer header for Clerk-JWT-authenticated routes. */\n private bearer(clerkToken: string): Record<string, string> {\n return { Authorization: `Bearer ${clerkToken}` };\n }\n\n // ─── Orders ────────────────────────────────────────────────────────────────\n\n getOrders(query: ApiOrdersQuery = {}): Promise<ApiResponse<ApiOrder[]>> {\n const params = new URLSearchParams();\n if (query.status) params.set(\"status\", query.status);\n if (query.collection) params.set(\"collection\", query.collection);\n if (query.currency) params.set(\"currency\", query.currency);\n if (query.sort) params.set(\"sort\", query.sort);\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n if (query.offerer) params.set(\"offerer\", this.addr(query.offerer));\n if (query.minPrice) params.set(\"minPrice\", query.minPrice);\n if (query.maxPrice) params.set(\"maxPrice\", query.maxPrice);\n if (query.chain) params.set(\"chain\", query.chain);\n const qs = params.toString();\n return this.get<ApiResponse<ApiOrder[]>>(`/v1/orders${qs ? `?${qs}` : \"\"}`);\n }\n\n getOrder(orderHash: string): Promise<ApiResponse<ApiOrder>> {\n return this.get<ApiResponse<ApiOrder>>(`/v1/orders/${orderHash}`);\n }\n\n getActiveOrdersForToken(contract: string, tokenId: string): Promise<ApiResponse<ApiOrder[]>> {\n return this.get<ApiResponse<ApiOrder[]>>(`/v1/orders/token/${this.addr(contract)}/${tokenId}`);\n }\n\n getOrdersByUser(address: string, page = 1, limit = 20): Promise<ApiResponse<ApiOrder[]>> {\n return this.get<ApiResponse<ApiOrder[]>>(\n `/v1/orders/user/${this.addr(address)}?page=${page}&limit=${limit}`\n );\n }\n\n // ─── Tokens ────────────────────────────────────────────────────────────────\n\n getToken(contract: string, tokenId: string, wait = false): Promise<ApiResponse<ApiToken>> {\n return this.get<ApiResponse<ApiToken>>(\n `/v1/tokens/${contract}/${tokenId}${wait ? \"?wait=true\" : \"\"}`\n );\n }\n\n getTokensByOwner(address: string, page = 1, limit = 20): Promise<ApiResponse<ApiToken[]>> {\n return this.get<ApiResponse<ApiToken[]>>(\n `/v1/tokens/owned/${this.addr(address)}?page=${page}&limit=${limit}`\n );\n }\n\n getTokenHistory(\n contract: string,\n tokenId: string,\n page = 1,\n limit = 20\n ): Promise<ApiResponse<ApiActivity[]>> {\n return this.get<ApiResponse<ApiActivity[]>>(\n `/v1/tokens/${contract}/${tokenId}/history?page=${page}&limit=${limit}`\n );\n }\n\n // ─── Collections ───────────────────────────────────────────────────────────\n\n getCollections(\n page = 1,\n limit = 20,\n isKnown?: boolean,\n sort?: CollectionSort,\n service?: string,\n chain?: ChainFilter\n ): Promise<ApiResponse<ApiCollection[]>> {\n const params = new URLSearchParams({ page: String(page), limit: String(limit) });\n if (isKnown !== undefined) params.set(\"isKnown\", String(isKnown));\n if (sort) params.set(\"sort\", sort);\n if (service) params.set(\"service\", service);\n if (chain) params.set(\"chain\", chain);\n return this.get<ApiResponse<ApiCollection[]>>(`/v1/collections?${params}`);\n }\n\n getCollectionsByOwner(owner: string, page = 1, limit = 50): Promise<ApiResponse<ApiCollection[]>> {\n const params = new URLSearchParams({ owner: this.addr(owner), page: String(page), limit: String(limit) });\n return this.get<ApiResponse<ApiCollection[]>>(`/v1/collections?${params}`);\n }\n\n getCollection(contract: string): Promise<ApiResponse<ApiCollection>> {\n return this.get<ApiResponse<ApiCollection>>(`/v1/collections/${this.addr(contract)}`);\n }\n\n getCollectionTokens(\n contract: string,\n page = 1,\n limit = 20,\n sort: CollectionTokensSort = \"recent\"\n ): Promise<ApiResponse<ApiToken[]>> {\n return this.get<ApiResponse<ApiToken[]>>(\n `/v1/collections/${this.addr(contract)}/tokens?page=${page}&limit=${limit}&sort=${sort}`\n );\n }\n\n // ─── Activities ────────────────────────────────────────────────────────────\n\n getActivities(query: ApiActivitiesQuery = {}): Promise<ApiResponse<ApiActivity[]>> {\n const params = new URLSearchParams();\n if (query.type) params.set(\"type\", query.type);\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n if (query.chain) params.set(\"chain\", query.chain);\n const qs = params.toString();\n return this.get<ApiResponse<ApiActivity[]>>(`/v1/activities${qs ? `?${qs}` : \"\"}`);\n }\n\n getActivitiesByAddress(\n address: string,\n page = 1,\n limit = 20\n ): Promise<ApiResponse<ApiActivity[]>> {\n return this.get<ApiResponse<ApiActivity[]>>(\n `/v1/activities/${this.addr(address)}?page=${page}&limit=${limit}`\n );\n }\n\n // ─── Comments ──────────────────────────────────────────────────────────────\n\n getTokenComments(\n contract: string,\n tokenId: string,\n opts: { page?: number; limit?: number } = {}\n ): Promise<ApiResponse<ApiComment[]>> {\n const params = new URLSearchParams();\n if (opts.page !== undefined) params.set(\"page\", String(opts.page));\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n const qs = params.toString();\n return this.get<ApiResponse<ApiComment[]>>(\n `/v1/tokens/${this.addr(contract)}/${tokenId}/comments${qs ? `?${qs}` : \"\"}`\n );\n }\n\n // ─── Search ────────────────────────────────────────────────────────────────\n\n search(q: string, limit = 10, chain?: ChainFilter): Promise<ApiResponse<ApiSearchResult> & { query: string }> {\n const params = new URLSearchParams({ q, limit: String(limit) });\n if (chain) params.set(\"chain\", chain);\n return this.get<ApiResponse<ApiSearchResult> & { query: string }>(\n `/v1/search?${params.toString()}`\n );\n }\n\n // ─── Intents ───────────────────────────────────────────────────────────────\n\n createListingIntent(\n params: CreateListingIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/listing\", params);\n }\n\n createOfferIntent(\n params: MakeOfferIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/offer\", params);\n }\n\n createFulfillIntent(\n params: FulfillOrderIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/fulfill\", params);\n }\n\n createCancelIntent(\n params: CancelOrderIntentParams\n ): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/cancel\", params);\n }\n\n getIntent(id: string): Promise<ApiResponse<ApiIntent>> {\n return this.get<ApiResponse<ApiIntent>>(`/v1/intents/${id}`);\n }\n\n submitIntentSignature(id: string, signature: string[]): Promise<ApiResponse<ApiIntent>> {\n return this.patch<ApiResponse<ApiIntent>>(`/v1/intents/${id}/signature`, { signature });\n }\n\n confirmIntent(id: string, txHash: string): Promise<ApiResponse<ApiIntent>> {\n return this.patch<ApiResponse<ApiIntent>>(`/v1/intents/${id}/confirm`, { txHash });\n }\n\n createMintIntent(params: CreateMintIntentParams): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/mint\", params);\n }\n\n createCollectionIntent(params: CreateCollectionIntentParams): Promise<ApiResponse<ApiIntentCreated>> {\n return this.post<ApiResponse<ApiIntentCreated>>(\"/v1/intents/create-collection\", params);\n }\n\n /**\n * Create a counter-offer intent. The seller proposes a new price in response\n * to a buyer's active bid. clerkToken is optional — the endpoint authenticates\n * via the tenant API key; pass a Clerk JWT only if your backend requires it.\n */\n createCounterOfferIntent(\n params: CreateCounterOfferIntentParams,\n clerkToken?: string\n ): Promise<ApiResponse<ApiIntentCreated>> {\n const extraHeaders: Record<string, string> = clerkToken ? { \"Authorization\": `Bearer ${clerkToken}` } : {};\n return this.request<ApiResponse<ApiIntentCreated>>(\"/v1/intents/counter-offer\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: extraHeaders,\n });\n }\n\n /**\n * Fetch counter-offers. Pass `originalOrderHash` (buyer view) or\n * `sellerAddress` (seller view) — at least one is required.\n */\n getCounterOffers(query: ApiCounterOffersQuery): Promise<ApiResponse<ApiOrder[]>> {\n const params = new URLSearchParams();\n if (query.originalOrderHash) params.set(\"originalOrderHash\", query.originalOrderHash);\n if (query.sellerAddress) params.set(\"sellerAddress\", query.sellerAddress);\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n return this.get<ApiResponse<ApiOrder[]>>(`/v1/orders/counter-offers?${params}`);\n }\n\n // ─── Metadata ──────────────────────────────────────────────────────────────\n\n getMetadataSignedUrl(): Promise<ApiResponse<ApiMetadataSignedUrl>> {\n return this.get<ApiResponse<ApiMetadataSignedUrl>>(\"/v1/metadata/signed-url\");\n }\n\n uploadMetadata(metadata: Record<string, unknown>): Promise<ApiResponse<ApiMetadataUpload>> {\n return this.post<ApiResponse<ApiMetadataUpload>>(\"/v1/metadata/upload\", metadata);\n }\n\n resolveMetadata(uri: string): Promise<ApiResponse<unknown>> {\n const params = new URLSearchParams({ uri });\n return this.get<ApiResponse<unknown>>(`/v1/metadata/resolve?${params.toString()}`);\n }\n\n uploadFile(file: File): Promise<ApiResponse<ApiMetadataUpload>> {\n const formData = new FormData();\n formData.append(\"file\", file);\n // Content-Type is intentionally omitted — request() detects FormData and\n // lets the runtime set multipart/form-data with the correct boundary.\n return this.request<ApiResponse<ApiMetadataUpload>>(\"/v1/metadata/upload-file\", {\n method: \"POST\",\n body: formData,\n });\n }\n\n // ─── Portal (tenant self-service) ──────────────────────────────────────────\n\n getMe(): Promise<ApiResponse<ApiPortalMe>> {\n return this.get<ApiResponse<ApiPortalMe>>(\"/v1/portal/me\");\n }\n\n getApiKeys(): Promise<ApiResponse<ApiPortalKey[]>> {\n return this.get<ApiResponse<ApiPortalKey[]>>(\"/v1/portal/keys\");\n }\n\n createApiKey(label?: string): Promise<ApiResponse<ApiPortalKeyCreated>> {\n return this.post<ApiResponse<ApiPortalKeyCreated>>(\"/v1/portal/keys\", label ? { label } : {});\n }\n\n deleteApiKey(id: string): Promise<ApiResponse<{ id: string; status: string }>> {\n return this.del<ApiResponse<{ id: string; status: string }>>(`/v1/portal/keys/${id}`);\n }\n\n getUsage(): Promise<ApiResponse<ApiUsageDay[]>> {\n return this.get<ApiResponse<ApiUsageDay[]>>(\"/v1/portal/usage\");\n }\n\n getWebhooks(): Promise<ApiResponse<ApiWebhookEndpoint[]>> {\n return this.get<ApiResponse<ApiWebhookEndpoint[]>>(\"/v1/portal/webhooks\");\n }\n\n createWebhook(params: CreateWebhookParams): Promise<ApiResponse<ApiWebhookCreated>> {\n return this.post<ApiResponse<ApiWebhookCreated>>(\"/v1/portal/webhooks\", params);\n }\n\n deleteWebhook(id: string): Promise<ApiResponse<{ id: string; status: string }>> {\n return this.del<ApiResponse<{ id: string; status: string }>>(\n `/v1/portal/webhooks/${id}`\n );\n }\n\n // ─── Collection Claims ──────────────────────────────────────────────────────\n\n /**\n * Path 1: On-chain auto claim. Sends both x-api-key (tenant auth) and\n * Authorization: Bearer (Clerk JWT) simultaneously.\n */\n async claimCollection(\n contractAddress: string,\n walletAddress: string,\n clerkToken: string\n ): Promise<{ verified: boolean; collection?: ApiCollection; reason?: string }> {\n return this.request(\"/v1/collections/claim\", {\n method: \"POST\",\n body: JSON.stringify({ contractAddress, walletAddress }),\n headers: this.bearer(clerkToken),\n });\n }\n\n /**\n * Path 3: Manual off-chain claim request (email-based).\n */\n requestCollectionClaim(params: {\n contractAddress: string;\n walletAddress?: string;\n email: string;\n notes?: string;\n }): Promise<{ claim: ApiCollectionClaim }> {\n return this.request(\"/v1/collections/claim/request\", {\n method: \"POST\",\n body: JSON.stringify(params),\n });\n }\n\n // ─── Collection Profiles ────────────────────────────────────────────────────\n\n getCollectionProfile(contractAddress: string): Promise<ApiCollectionProfile | null> {\n return this.request<ApiCollectionProfile | null>(\n `/v1/collections/${this.addr(contractAddress)}/profile`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n /**\n * Update collection profile. Requires Clerk JWT for ownership check.\n */\n updateCollectionProfile(\n contractAddress: string,\n data: Partial<Omit<ApiCollectionProfile, \"contractAddress\" | \"chain\" | \"updatedBy\" | \"updatedAt\">>,\n clerkToken: string\n ): Promise<ApiCollectionProfile> {\n return this.request<ApiCollectionProfile>(\n `/v1/collections/${this.addr(contractAddress)}/profile`,\n { method: \"PATCH\", body: JSON.stringify(data), headers: this.bearer(clerkToken) },\n );\n }\n\n getGatedContent(\n contractAddress: string,\n clerkToken: string\n ): Promise<{ title: string; url: string; type: string } | null> {\n return this.request<{ title: string; url: string; type: string } | null>(\n `/v1/collections/${this.addr(contractAddress)}/gated-content`,\n { method: \"GET\", headers: this.bearer(clerkToken) },\n { allow404: true, allow403: true },\n );\n }\n\n // ─── Creator Profiles ───────────────────────────────────────────────────────\n\n /** List all creators with an approved username. */\n getCreators(opts: { search?: string; page?: number; limit?: number } = {}): Promise<ApiCreatorListResult> {\n const params = new URLSearchParams();\n if (opts.search) params.set(\"search\", opts.search);\n if (opts.page) params.set(\"page\", String(opts.page));\n if (opts.limit) params.set(\"limit\", String(opts.limit));\n const qs = params.toString();\n return this.get<ApiCreatorListResult>(`/v1/creators${qs ? `?${qs}` : \"\"}`);\n }\n\n getCreatorProfile(walletAddress: string): Promise<ApiCreatorProfile | null> {\n return this.request<ApiCreatorProfile | null>(\n `/v1/creators/${this.addr(walletAddress)}/profile`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n /** Resolve a username slug to a creator profile (public). */\n getCreatorByUsername(username: string): Promise<ApiCreatorProfile | null> {\n return this.request<ApiCreatorProfile | null>(\n `/v1/creators/by-username/${encodeURIComponent(username.toLowerCase().trim())}`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n /**\n * Update creator profile. Requires Clerk JWT; wallet must match authenticated user.\n */\n updateCreatorProfile(\n walletAddress: string,\n data: Partial<Omit<ApiCreatorProfile, \"walletAddress\" | \"chain\" | \"updatedAt\">>,\n clerkToken: string\n ): Promise<ApiCreatorProfile> {\n return this.request<ApiCreatorProfile>(\n `/v1/creators/${this.addr(walletAddress)}/profile`,\n { method: \"PATCH\", body: JSON.stringify(data), headers: this.bearer(clerkToken) },\n );\n }\n\n // ─── Collection Slug Claims ───────────────────────────────────────────────────\n\n /** Check if a collection slug is available (public, no auth). */\n checkCollectionSlugAvailability(slug: string): Promise<{ available: boolean; reason?: string }> {\n return this.get<{ available: boolean; reason?: string }>(\n `/v1/collection-slug-claims/check/${encodeURIComponent(slug.toLowerCase().trim())}`,\n );\n }\n\n /** Submit a slug claim for a collection. Requires Clerk JWT — caller must be the collection owner. */\n submitCollectionSlugClaim(\n contractAddress: string,\n slug: string,\n clerkToken: string,\n notifyEmail?: string\n ): Promise<{ claim: ApiCollectionSlugClaim }> {\n return this.request<{ claim: ApiCollectionSlugClaim }>(\"/v1/collection-slug-claims\", {\n method: \"POST\",\n body: JSON.stringify({ contractAddress, slug, notifyEmail }),\n headers: this.bearer(clerkToken),\n });\n }\n\n /** Returns all slug claims submitted by the authenticated wallet. Requires Clerk JWT. */\n getMyCollectionSlugClaims(clerkToken: string): Promise<{ claims: ApiCollectionSlugClaim[] }> {\n return this.request<{ claims: ApiCollectionSlugClaim[] }>(\"/v1/collection-slug-claims/me\", {\n method: \"GET\",\n headers: this.bearer(clerkToken),\n });\n }\n\n /** Resolve a collection slug to a full collection. Returns null if not found. */\n getCollectionBySlug(slug: string): Promise<ApiCollection | null> {\n return this.request<ApiCollection | null>(\n `/v1/collections/by-slug/${encodeURIComponent(slug.toLowerCase().trim())}`,\n { method: \"GET\" },\n { allow404: true },\n );\n }\n\n // ─── User Wallet ─────────────────────────────────────────────────────────────\n\n /**\n * Upsert the authenticated user's wallet address in the backend DB.\n * Call after onboarding when ChipiPay confirms the wallet address.\n * Requires Clerk JWT; no tenant API key needed.\n */\n /**\n * Frictionless wallet registration. Tenant API key only (no Clerk JWT required).\n * Idempotent — backend's ensureAccountForWallet upserts and upgrades existing\n * UNKNOWN walletType rows when a more specific value is supplied.\n */\n async registerUser(params: {\n walletAddress: string;\n // Free-form wallet-software label (\"braavos\" / \"ready\" / \"chipipay\" / …).\n // The backend lowercases it into Identity.provider and never gates on it\n // (07-identity §II) — so it's a plain string, not a closed enum.\n walletType?: string;\n appSource?: ApiAppSource;\n chain?: ApiChain;\n }): Promise<{\n accountId: string;\n publicId: string;\n walletAddress: string;\n chain: string;\n // The wallet identity's free-form provider label, echoed back from\n // Identity.provider (\"braavos\" / \"chipipay\" / \"unknown\" / …).\n provider: string;\n appSource: ApiAppSource;\n createdAt: string;\n }> {\n return this.post(\"/v1/users/register\", params);\n }\n\n async upsertMyWallet(\n clerkToken: string,\n options: {\n // Free-form provider label (see registerUser); lowercased into\n // Identity.provider by the backend, never gated on.\n walletType?: string;\n appSource?: ApiAppSource;\n // 07-identity §I: the Wallet identifier is (chain, address). v1\n // backend rejects anything other than STARKNET on this route (the\n // auth path can only prove Starknet ownership); the field exists\n // so the year-2 multichain shape is locked in.\n chain?: ApiChain;\n } = {},\n ): Promise<ApiUserWallet> {\n const body: Record<string, string> = {\n walletType: options.walletType ?? \"UNKNOWN\",\n appSource: options.appSource ?? \"MEDIALANE_SDK\",\n };\n if (options.chain) body.chain = options.chain;\n return this.request<ApiUserWallet>(\"/v1/users/me\", {\n method: \"POST\",\n body: JSON.stringify(body),\n headers: this.bearer(clerkToken),\n });\n }\n\n /**\n * Get the authenticated user's stored wallet address from the backend DB.\n * Returns null if the user has not completed onboarding yet.\n * Requires Clerk JWT; no tenant API key needed.\n */\n getMyWallet(clerkToken: string): Promise<ApiUserWallet | null> {\n return this.request<ApiUserWallet | null>(\n \"/v1/users/me\",\n { method: \"GET\", headers: this.bearer(clerkToken) },\n { allow404: true },\n );\n }\n\n // ─── Remix Licensing ─────────────────────────────────────────────────────────\n\n /**\n * Get public remixes of a token (open to everyone).\n */\n getTokenRemixes(\n contract: string,\n tokenId: string,\n opts: { page?: number; limit?: number } = {}\n ): Promise<ApiResponse<ApiPublicRemix[]>> {\n const params = new URLSearchParams();\n if (opts.page !== undefined) params.set(\"page\", String(opts.page));\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n const qs = params.toString();\n return this.get<ApiResponse<ApiPublicRemix[]>>(\n `/v1/tokens/${this.addr(contract)}/${tokenId}/remixes${qs ? `?${qs}` : \"\"}`\n );\n }\n\n /**\n * Submit a custom remix offer for a token. Requires Clerk JWT.\n */\n submitRemixOffer(\n params: CreateRemixOfferParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(\"/v1/remix-offers\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Submit an auto remix offer for a token with an open license. Requires Clerk JWT.\n */\n submitAutoRemixOffer(\n params: AutoRemixOfferParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(\"/v1/remix-offers/auto\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Record a self-remix (owner remixing their own token). Requires Clerk JWT.\n */\n confirmSelfRemix(\n params: ConfirmSelfRemixParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(\"/v1/remix-offers/self/confirm\", {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * List remix offers by role. Requires Clerk JWT.\n * role=\"creator\" — offers where you are the original creator.\n * role=\"requester\" — offers you made.\n */\n getRemixOffers(\n query: ApiRemixOffersQuery,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer[]>> {\n const params = new URLSearchParams({ role: query.role });\n if (query.page !== undefined) params.set(\"page\", String(query.page));\n if (query.limit !== undefined) params.set(\"limit\", String(query.limit));\n return this.request<ApiResponse<ApiRemixOffer[]>>(`/v1/remix-offers?${params}`, {\n method: \"GET\",\n headers: this.bearer(clerkToken),\n });\n }\n\n /**\n * Get a single remix offer. Clerk JWT optional (price/currency hidden for non-participants).\n */\n getRemixOffer(id: string, clerkToken?: string): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}`, {\n method: \"GET\",\n headers: clerkToken ? this.bearer(clerkToken) : undefined,\n });\n }\n\n /**\n * Creator approves a remix offer (authorises the requester to mint). Requires Clerk JWT.\n */\n confirmRemixOffer(\n id: string,\n params: ConfirmRemixOfferParams,\n clerkToken: string\n ): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}/confirm`, {\n method: \"POST\",\n body: JSON.stringify(params),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Creator rejects a remix offer. Requires Clerk JWT.\n */\n rejectRemixOffer(id: string, clerkToken: string): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}/reject`, {\n method: \"POST\",\n body: JSON.stringify({}),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n /**\n * Requester extends the expiry of a pending remix offer by 1–30 days.\n * Requires Clerk JWT.\n */\n extendRemixOffer(id: string, days: number, clerkToken: string): Promise<ApiResponse<ApiRemixOffer>> {\n return this.request<ApiResponse<ApiRemixOffer>>(`/v1/remix-offers/${id}/extend`, {\n method: \"POST\",\n body: JSON.stringify({ days }),\n headers: { \"Authorization\": `Bearer ${clerkToken}` },\n });\n }\n\n // ─── POP Protocol ──────────────────────────────────────────────────────────\n\n getPopCollections(opts: { page?: number; limit?: number; sort?: CollectionSort } = {}): Promise<ApiResponse<ApiCollection[]>> {\n return this.getCollections(opts.page ?? 1, opts.limit ?? 20, undefined, opts.sort, \"POP_PROTOCOL\");\n }\n\n async getPopEligibility(collection: string, wallet: string): Promise<PopClaimStatus> {\n const res = await this.get<{ data: PopClaimStatus }>(\n `/v1/pop/eligibility/${this.addr(collection)}/${this.addr(wallet)}`\n );\n return res.data;\n }\n\n async getPopEligibilityBatch(collection: string, wallets: string[]): Promise<PopBatchEligibilityItem[]> {\n const params = new URLSearchParams({ wallets: wallets.map((w) => this.addr(w)).join(\",\") });\n const res = await this.get<{ data: PopBatchEligibilityItem[] }>(\n `/v1/pop/eligibility/${this.addr(collection)}?${params}`\n );\n return res.data;\n }\n\n // ─── Coins (fungible — ERC-20 etc.) ───────────────────────────────────────────\n // Coins are a separate model from Collections (spec 2026-06-14). Price/liquidity\n // is read live from Ekubo (CreatorCoinService.getPrice), never from these.\n\n getCoins(opts: ApiCoinsQuery = {}): Promise<ApiResponse<ApiCoin[]>> {\n const params = new URLSearchParams();\n if (opts.page) params.set(\"page\", String(opts.page));\n if (opts.limit) params.set(\"limit\", String(opts.limit));\n if (opts.service) params.set(\"service\", opts.service);\n if (opts.chain) params.set(\"chain\", opts.chain);\n const qs = params.toString();\n return this.get<ApiResponse<ApiCoin[]>>(`/v1/coins${qs ? `?${qs}` : \"\"}`);\n }\n\n getCoin(contract: string): Promise<{ data: ApiCoin }> {\n return this.get<{ data: ApiCoin }>(`/v1/coins/${this.addr(contract)}`);\n }\n\n // ─── Collection Drop ────────────────────────────────────────────────────────\n\n getDropCollections(opts: { page?: number; limit?: number; sort?: CollectionSort } = {}): Promise<ApiResponse<ApiCollection[]>> {\n return this.getCollections(opts.page ?? 1, opts.limit ?? 20, undefined, opts.sort, \"COLLECTION_DROP\");\n }\n\n async getDropMintStatus(collection: string, wallet: string): Promise<DropMintStatus> {\n const res = await this.get<{ data: DropMintStatus }>(\n `/v1/drop/mint-status/${this.addr(collection)}/${this.addr(wallet)}`\n );\n return res.data;\n }\n\n // ─── Rewards (v0.49.0) ─────────────────────────────────────────────────────\n // Scores are recomputed on a schedule by the backend (~15 min) — reads only.\n\n /** Score + level + progress + badges for one address (zeroed for unknown). */\n async getRewards(address: string): Promise<ApiUserRewards> {\n const res = await this.get<{ data: ApiUserRewards }>(`/v1/rewards/${this.addr(address)}`);\n return res.data;\n }\n\n /** Paginated XP leaderboard. */\n getRewardsLeaderboard(page = 1, limit = 50): Promise<ApiResponse<ApiRewardsLeaderboardEntry[]>> {\n return this.get<ApiResponse<ApiRewardsLeaderboardEntry[]>>(`/v1/rewards?page=${page}&limit=${limit}`);\n }\n\n /** Point-event history for an address. */\n getRewardsEvents(address: string, page = 1, limit = 20): Promise<ApiResponse<ApiPointEvent[]>> {\n return this.get<ApiResponse<ApiPointEvent[]>>(\n `/v1/rewards/${this.addr(address)}/events?page=${page}&limit=${limit}`\n );\n }\n\n /** Reward configuration: level ladder, enabled action XP values, badge catalog. */\n async getRewardsConfig(): Promise<ApiRewardsConfig> {\n const res = await this.get<{ data: ApiRewardsConfig }>(`/v1/rewards/config`);\n return res.data;\n }\n\n /** Minimal level info for up to 50 addresses — one call per list page. */\n async getRewardsBatch(addresses: string[]): Promise<ApiRewardsBatchEntry[]> {\n if (addresses.length === 0) return [];\n const params = new URLSearchParams({ addresses: addresses.map((a) => this.addr(a)).join(\",\") });\n const res = await this.get<{ data: ApiRewardsBatchEntry[] }>(`/v1/rewards/batch?${params}`);\n return res.data;\n }\n}\n","export type IPType =\n | \"Audio\"\n | \"Art\"\n | \"Documents\"\n | \"NFT\"\n | \"Video\"\n | \"Photography\"\n | \"Patents\"\n | \"Posts\"\n | \"Publications\"\n | \"RWA\"\n | \"Software\"\n | \"Custom\";\n\nexport type CollectionSort = \"recent\" | \"supply\" | \"floor\" | \"volume\" | \"name\";\n\nexport type CollectionTokensSort = \"recent\" | \"oldest\" | \"name\" | \"price\";\n\n/** Bounded capability set (05-service-model §III). Expand the union when a\n * service needs behavior outside it — never make it free-form. */\nexport type ServiceCapability =\n | \"list\" | \"buy\" | \"make_offer\" | \"cancel\"\n | \"transfer\" | \"burn\"\n | \"mint\" | \"claim\" | \"airdrop\"\n | \"remix\" | \"license\"\n | \"subscribe\" | \"redeem\"\n | \"launch\" | \"swap\"\n | \"sponsor\";\n\n/** A service that bakes enforcement into its own contract declares it here\n * (04-licensing-model §V, 05-service-model §IV). Absence/all-falsey =\n * soft enforcement (the 00-principles §9 default). */\nexport interface EnforcementDeclaration {\n royalty?: \"erc2981\" | \"service-split\" | \"none\";\n escrow?: boolean;\n timeLock?: boolean;\n revocable?: boolean;\n}\n\n/** An on-chain event the service emits. The indexer consumes this list to\n * decide what to poll and how to parse — the year-2 \"data-driven event\n * parser registry\" foundation (02-protocol-app-split §V).\n *\n * The Cairo selector is derivable from `name` via\n * `starknet.hash.getSelectorFromName(name)` — not stored to avoid\n * duplication and keep the SDK runtime-free of pre-computed hashes.\n */\nexport interface ServiceEventDeclaration {\n /** Cairo event struct name (e.g. \"OrderCreated\", \"CollectionCreated\"). */\n name: string;\n /**\n * Where this event is emitted:\n * - \"factory\": at the service's `onchain.factoryAddress` (fixed address).\n * Examples: marketplace OrderCreated, factory CollectionCreated.\n * - \"instance\": at the address of each deployed collection contract\n * (variable; the indexer iterates discovered instances).\n * Examples: ERC-721 Transfer, POP AllowlistUpdated.\n */\n emittedBy: \"factory\" | \"instance\";\n /**\n * Polling cadence the indexer should use:\n * - \"fast\" (default): every indexer tick (~6s). Right for low-volume\n * protocol events like order/factory events.\n * - \"slow\": a separate slower loop (~2min). Right for\n * high-volume per-instance events like Transfer\n * and AllowlistUpdated — polling them every tick\n * against every known instance is RPC-expensive.\n */\n poll?: \"fast\" | \"slow\";\n}\n\n/** Declarative description of a service (05-service-model §II).\n * SDK-resident in v1; on-chain registry in year 2. */\nexport interface ServiceDefinition {\n /** Stable kebab-case id. NO version number (05 §II). */\n id: string;\n displayName: string;\n description: string;\n standard: \"ERC721\" | \"ERC1155\" | \"ERC20\" | \"UNKNOWN\";\n provenance: \"MEDIALANE\" | \"EXTERNAL\";\n onchain?: Partial<Record<import(\"../chains.js\").Chain, {\n factoryAddress?: string;\n classHash?: string;\n startBlock?: number;\n }>>;\n /** Drives the dapp asset/collection page variant. */\n uiVariant: string;\n capabilities: ServiceCapability[];\n /** Events the indexer should poll + parse for this service.\n * Optional during the year-1 transition — backend hand-coded pollers\n * (medialane-backend/src/mirror/poller.ts) take precedence today.\n * Populated here so consumers and the future data-driven indexer can\n * read what events a service emits without code-spelunking. */\n events?: ServiceEventDeclaration[];\n metadataSchema?: {\n requiredTraits?: string[];\n /** Canonical platform default is \"CC BY-SA\" (04-licensing-model §III). */\n licenseDefault?: string;\n enforcement?: EnforcementDeclaration;\n };\n}\n\nexport interface ApiCollectionsQuery {\n page?: number;\n limit?: number;\n isKnown?: boolean;\n sort?: CollectionSort;\n owner?: string;\n /** Filter by service id. */\n service?: string;\n}\n\n/**\n * Order lifecycle states. **Four canonical values** per `01-core-model §V`.\n *\n * The legacy `\"COUNTER_OFFERED\"` value was removed in 0.23.0 (audit P0-1\n * Phase D). Counter-offers are linked orders via `parentOrderHash`, not a\n * third lifecycle state on the parent bid. Use `ApiOrder.hasActiveCounterOffer`\n * (added in 0.22.0) for the \"this bid has been countered\" affordance.\n */\nexport type OrderStatus = \"ACTIVE\" | \"FULFILLED\" | \"CANCELLED\" | \"EXPIRED\";\nexport type SortOrder = \"price_asc\" | \"price_desc\" | \"recent\";\nexport type ActivityType = \"mint\" | \"transfer\" | \"sale\" | \"listing\" | \"offer\" | \"cancelled\";\nexport type IntentType = \"CREATE_LISTING\" | \"MAKE_OFFER\" | \"FULFILL_ORDER\" | \"CANCEL_ORDER\" | \"MINT\" | \"CREATE_COLLECTION\" | \"COUNTER_OFFER\";\nexport type IntentStatus = \"PENDING\" | \"SIGNED\" | \"SUBMITTED\" | \"CONFIRMED\" | \"FAILED\" | \"EXPIRED\";\nexport type WebhookEventType = \"ORDER_CREATED\" | \"ORDER_FULFILLED\" | \"ORDER_CANCELLED\" | \"TRANSFER\";\nexport type WebhookStatus = \"ACTIVE\" | \"DISABLED\";\nexport type ApiKeyStatus = \"ACTIVE\" | \"REVOKED\";\nexport type TenantPlan = \"FREE\" | \"PREMIUM\";\n\n// ─── Shared ───────────────────────────────────────────────────────────────────\n\nexport interface ApiMeta {\n page: number;\n limit: number;\n total?: number;\n}\n\nexport interface ApiResponse<T> {\n data: T;\n meta?: ApiMeta;\n}\n\n// ─── Orders ───────────────────────────────────────────────────────────────────\n\n/** Cross-chain read filter — a concrete chain, or \"all\" for aggregation\n * (platform-federation spec §2.3). Omitted = the backend default (STARKNET). */\nexport type ChainFilter = import(\"../chains.js\").Chain | \"all\";\n\nexport interface ApiOrdersQuery {\n chain?: ChainFilter;\n status?: OrderStatus;\n collection?: string;\n currency?: string;\n sort?: SortOrder;\n page?: number;\n limit?: number;\n offerer?: string;\n minPrice?: string;\n maxPrice?: string;\n}\n\nexport interface ApiOrderOffer {\n itemType: string;\n token: string;\n identifier: string;\n startAmount: string;\n endAmount: string;\n}\n\nexport interface ApiOrderConsideration extends ApiOrderOffer {\n recipient: string;\n}\n\nexport interface ApiOrderPrice {\n raw: string | null;\n formatted: string | null;\n currency: string | null;\n decimals: number;\n}\n\nexport interface ApiOrderTxHash {\n created: string | null;\n fulfilled: string | null;\n cancelled: string | null;\n}\n\nexport interface ApiOrderTokenMeta {\n name: string | null;\n image: string | null;\n description: string | null;\n}\n\nexport interface ApiOrder {\n id: string;\n chain: string;\n orderHash: string;\n offerer: string;\n offer: ApiOrderOffer;\n consideration: ApiOrderConsideration;\n startTime: string;\n endTime: string;\n status: OrderStatus;\n fulfiller: string | null;\n nftContract: string | null;\n nftTokenId: string | null;\n price: ApiOrderPrice;\n txHash: ApiOrderTxHash;\n createdBlockNumber: string;\n /** ERC-1155 only: units still available after the last partial fill. Null for ERC-721 or unfilled orders. */\n remainingAmount: string | null;\n createdAt: string;\n updatedAt: string;\n /** Embedded token metadata (name/image/description). Null when not yet indexed. */\n token: ApiOrderTokenMeta | null;\n /** Set when this is a counter-offer listing — points to the original buyer bid.\n * Now always emitted by the backend (was conditional); kept optional in the\n * type for back-compat with older response shapes. */\n parentOrderHash?: string | null;\n /** Optional seller message accompanying a counter-offer. */\n counterOfferMessage?: string | null;\n /** True when this order is a bid (ERC-20 offer) AND at least one ACTIVE counter\n * exists with `parentOrderHash = this.orderHash`. Set by endpoints that compute\n * it (currently `GET /v1/orders/user/:address` and `GET /v1/orders/:orderHash`);\n * undefined on endpoints that don't.\n *\n * Use this instead of `status === \"COUNTER_OFFERED\"` for \"this bid has been\n * countered\" affordances. The status pattern is being phased out per\n * 01-core-model §V — counter-offers are linked orders, not a lifecycle state. */\n hasActiveCounterOffer?: boolean;\n}\n\n// ─── IP / IPFS Metadata types ──────────────────────────────────────────────────\n\n/**\n * A single OpenSea-compatible ERC-721 attribute.\n * Medialane embeds licensing, provenance, and IP metadata as attributes.\n */\nexport interface IpAttribute {\n trait_type: string;\n value: string;\n}\n\n/**\n * Full on-chain + IPFS metadata for a Medialane IP NFT.\n * Conforms to the OpenSea ERC-721 metadata standard and embeds\n * Berne Convention-compatible licensing data in `attributes`.\n *\n * Common licensing attributes (all optional — absent on pre-v2 tokens):\n * License · Commercial Use · Derivatives · Attribution · Territory\n * AI Policy · Royalty · Standard (\"Berne Convention\") · Registration\n */\nexport interface IpNftMetadata {\n name: string;\n description?: string;\n image?: string | null;\n external_url?: string;\n attributes?: IpAttribute[];\n /** Populated by the indexer for fast access — not stored in IPFS */\n ipType?: string | null;\n licenseType?: string | null;\n commercialUse?: string | null;\n derivatives?: string | null;\n attribution?: string | null;\n territory?: string | null;\n aiPolicy?: string | null;\n royalty?: string | null;\n registration?: string | null;\n}\n\n// ─── Tokens ───────────────────────────────────────────────────────────────────\n\n/** Indexed token metadata as returned by the Medialane API. */\nexport interface ApiTokenMetadata {\n name: string | null;\n description: string | null;\n image: string | null;\n /** data: or ipfs:// URI to a fully self-contained animated/interactive renderer (OpenSea-baseline `animation_url`). Null until indexed. */\n animationUrl: string | null;\n /** Parsed OpenSea-standard attributes array. Null when metadata hasn't been fetched. */\n attributes: IpAttribute[] | null;\n /** Short-circuit fields extracted from attributes by the indexer */\n ipType: string | null;\n licenseType: string | null;\n commercialUse: string | null;\n derivatives: string | null;\n attribution: string | null;\n territory: string | null;\n aiPolicy: string | null;\n royalty: string | null;\n registration: string | null;\n author: string | null;\n}\n\n/** Per-holder balance entry. Present for ERC-1155 (multi-holder); single entry for ERC-721. */\nexport interface ApiTokenBalance {\n owner: string;\n /** Quantity held. Always \"1\" for ERC-721. */\n amount: string;\n}\n\nexport interface ApiToken {\n id: string;\n chain: string;\n contractAddress: string;\n tokenId: string;\n /** @deprecated Use `balances` for ownership checks — always null after ERC-1155 migration. */\n owner: string | null;\n tokenUri: string | null;\n metadataStatus: \"PENDING\" | \"FETCHING\" | \"FETCHED\" | \"FAILED\";\n /** Token standard derived from the parent collection. Use this to determine ERC-721 vs ERC-1155 behavior. */\n standard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n metadata: ApiTokenMetadata;\n /** Current holders with amounts. Only present on single-token fetches; null on list responses. */\n balances: ApiTokenBalance[] | null;\n activeOrders: ApiOrder[];\n createdAt: string;\n updatedAt: string;\n}\n\n// ─── Collections ──────────────────────────────────────────────────────────────\n\nexport interface ApiCollection {\n id: string;\n chain: string;\n contractAddress: string;\n collectionId: string | null;\n name: string | null;\n symbol: string | null;\n description: string | null;\n image: string | null;\n owner: string | null;\n startBlock: string;\n metadataStatus: \"PENDING\" | \"FETCHING\" | \"FETCHED\" | \"FAILED\";\n /** Token standard detected via ERC-165. Collection is NFT-only since the\n * 2026-06-14 coin split — fungible coins are `ApiCoin`, served by getCoins(). */\n standard: \"ERC721\" | \"ERC1155\";\n isKnown: boolean;\n /** Hidden by ops/admin (content moderation). When true, list endpoints\n * already filter the row out; single-collection fetches still return\n * it so the UI can render a \"hidden\" banner instead of a 404. */\n isHidden: boolean;\n /** Promoted on homepage / browse surfaces. */\n isFeatured: boolean;\n /** Stable Medialane service ID, or null for external collections.\n * Resolve via getService() (05-service-model). Primary field. */\n service: string | null;\n claimedBy: string | null;\n profile?: ApiCollectionProfile | null;\n floorPrice: string | null;\n totalVolume: string | null;\n holderCount: number | null;\n totalSupply: number | null;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A fungible coin (ERC-20 today; SPL/etc. later). Distinct from ApiCollection:\n * a coin has a supply + decimals + a market price (read live from Ekubo), no\n * tokens, no orders. Served by getCoins()/getCoin() (spec 2026-06-14). */\nexport interface ApiCoin {\n id: string;\n chain: string;\n contractAddress: string;\n standard: \"ERC20\";\n /** \"creator-coin\" | \"external-erc20\" */\n service: string;\n name: string | null;\n symbol: string | null;\n decimals: number;\n /** Fungible supply as a decimal string — NOT an item count. */\n totalSupply: string | null;\n description: string | null;\n image: string | null;\n creator: string | null;\n startBlock: string;\n isHidden: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiCoinsQuery {\n chain?: ChainFilter;\n page?: number;\n limit?: number;\n /** Filter by coin service id (\"creator-coin\" | \"external-erc20\"). */\n service?: string;\n}\n\n// ─── Activities ───────────────────────────────────────────────────────────────\n\nexport interface ApiActivityPrice {\n raw: string | null;\n formatted: string | null;\n currency: string | null;\n}\n\nexport interface ApiActivity {\n type: ActivityType;\n // Transfer fields\n contractAddress?: string;\n tokenId?: string;\n from?: string;\n to?: string;\n blockNumber?: string;\n /** ERC-1155 quantity (transfer/mint rows). \"1\" for ERC-721. */\n amount?: string;\n // Order fields\n orderHash?: string;\n nftContract?: string;\n nftTokenId?: string;\n offerer?: string;\n fulfiller?: string | null;\n price?: ApiActivityPrice;\n /** Token standard — present on order rows. */\n tokenStandard?: \"ERC721\" | \"ERC1155\";\n txHash: string | null;\n timestamp: string;\n /** Batch-enriched token metadata — avoids per-row fetches. */\n token?: { name: string | null; image: string | null } | null;\n}\n\nexport interface ApiActivitiesQuery {\n chain?: ChainFilter;\n type?: ActivityType;\n page?: number;\n limit?: number;\n}\n\n// ─── Comments ─────────────────────────────────────────────────────────────────\n\nexport interface ApiComment {\n id: string;\n chain: string; // \"starknet\"\n contractAddress: string; // normalized 0x-padded Starknet address\n tokenId: string;\n author: string; // normalized 0x-padded Starknet address\n content: string; // sanitized plain text\n txHash: string | null;\n blockNumber: string; // BigInt serialized as string\n postedAt: string; // ISO 8601 derived from blockTimestamp — use for display\n}\n\n// ─── Search ───────────────────────────────────────────────────────────────────\n\nexport interface ApiSearchTokenResult {\n contractAddress: string;\n tokenId: string;\n name: string | null;\n image: string | null;\n owner: string;\n metadataStatus: string;\n}\n\nexport interface ApiSearchCollectionResult {\n contractAddress: string;\n name: string | null;\n image: string | null;\n totalSupply: number | null;\n floorPrice: string | null;\n holderCount: number | null;\n}\n\nexport interface ApiSearchCreatorResult {\n walletAddress: string;\n username: string | null;\n displayName: string | null;\n bio: string | null;\n avatarImage: string | null;\n}\n\nexport interface ApiSearchResult {\n tokens: ApiSearchTokenResult[];\n collections: ApiSearchCollectionResult[];\n creators: ApiSearchCreatorResult[];\n}\n\n// ─── Intents ──────────────────────────────────────────────────────────────────\n\nexport interface ApiIntent {\n id: string;\n chain: string;\n type: IntentType;\n status: IntentStatus;\n requester: string;\n typedData: unknown;\n calls: unknown;\n signature: string[];\n txHash: string | null;\n orderHash: string | null;\n /** Set on COUNTER_OFFER intents — the original bid order hash being countered. */\n parentOrderHash?: string | null;\n /** Optional seller message on counter-offer intents. */\n counterOfferMessage?: string | null;\n expiresAt: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/** A single Starknet call as returned in intent calldata. */\nexport interface IntentCall {\n contractAddress: string;\n entrypoint: string;\n calldata: string[];\n}\n\n/**\n * Response from any `createXIntent` call. Discriminated on `requiresSignature`:\n * • true — SNIP-12 intent (listing / offer / cancel / counter-offer). Sign\n * `typedData`, then call `submitIntentSignature(id, sig)` to obtain\n * the executable calls.\n * • false — prebuilt intent (fulfill / mint / create-collection). `calls` are\n * ready to execute directly; there is no signature step.\n *\n * The discriminant makes the wrong access a compile error: `typedData` does not\n * exist on the `false` variant, nor `calls` on the `true` variant. Consumers\n * MUST narrow on `requiresSignature` before reading either.\n */\nexport type ApiIntentCreated =\n | { id: string; expiresAt: string; requiresSignature: true; typedData: unknown }\n | { id: string; expiresAt: string; requiresSignature: false; calls: IntentCall[] };\n\nexport interface CreateListingIntentParams {\n offerer: string;\n nftContract: string;\n tokenId: string;\n currency: string;\n price: string;\n endTime: number;\n salt?: string;\n /** Number of units to list — required for ERC-1155, omit for ERC-721. */\n amount?: string;\n}\n\nexport interface MakeOfferIntentParams {\n offerer: string;\n nftContract: string;\n tokenId: string;\n currency: string;\n price: string;\n endTime: number;\n salt?: string;\n /** Caller hint — \"ERC1155\" creates the bid on the ERC-1155 marketplace. */\n tokenStandard?: string;\n /** ERC-1155 only: number of editions requested. Defaults to 1. */\n quantity?: string;\n}\n\nexport interface FulfillOrderIntentParams {\n fulfiller: string;\n orderHash: string;\n /** Caller hint — \"ERC1155\" forces 1155 routing even if the order isn't in the DB yet */\n tokenStandard?: string;\n /** ERC-1155 only: units to purchase (1 ≤ quantity ≤ remaining_amount). Defaults to 1. */\n quantity?: string;\n}\n\nexport interface CancelOrderIntentParams {\n offerer: string;\n orderHash: string;\n /** Caller hint — \"ERC1155\" forces 1155 routing even if the order isn't in the DB yet */\n tokenStandard?: string;\n}\n\nexport interface CreateMintIntentParams {\n /** Collection owner wallet address — must be the collection owner on-chain */\n owner: string;\n collectionId: string;\n recipient: string;\n tokenUri: string;\n /**\n * EIP-2981 secondary-sale royalty in basis points (0–10_000). Set once at mint;\n * receiver is the immutable creator. Required since MIP v0.4.0 — pass 0 for none.\n */\n royaltyBps: number;\n /** Optional: override the default collection contract address */\n collectionContract?: string;\n}\n\nexport interface CreateCollectionIntentParams {\n owner: string;\n name: string;\n symbol: string;\n /** Optional description stored server-side and surfaced on the collection page. */\n description?: string;\n /** Optional IPFS image URI (ipfs://...) for the collection cover image. */\n image?: string;\n /** Base URI for token metadata. Defaults to empty string if not provided. */\n baseUri?: string;\n /** Optional: override the default collection contract address */\n collectionContract?: string;\n}\n\nexport interface CreateCounterOfferIntentParams {\n /** Wallet address of the NFT owner making the counter-offer. */\n sellerAddress: string;\n /** Order hash of the original buyer bid being countered. */\n originalOrderHash: string;\n /** Counter price as a raw wei integer string (not human-readable). */\n priceRaw: string;\n /** Duration in seconds the counter-offer will be valid (3600–2592000). */\n durationSeconds: number;\n /** Optional message from the seller to the buyer. Max 500 chars. */\n message?: string;\n}\n\nexport interface ApiCounterOffersQuery {\n /** Original bid order hash — returns the counter-offer for this specific bid. */\n originalOrderHash?: string;\n /** Seller address — returns all counter-offers sent by this seller. */\n sellerAddress?: string;\n page?: number;\n limit?: number;\n}\n\n// ─── Remix Licensing ──────────────────────────────────────────────────────────\n\nexport const OPEN_LICENSES = [\"CC0\", \"CC BY\", \"CC BY-SA\", \"CC BY-NC\"] as const;\nexport type OpenLicense = (typeof OPEN_LICENSES)[number];\n\nexport type RemixOfferStatus =\n | \"PENDING\"\n | \"AUTO_PENDING\"\n | \"APPROVED\"\n | \"COMPLETED\"\n | \"REJECTED\"\n | \"EXPIRED\"\n | \"SELF_MINTED\";\n\nexport interface ApiRemixOfferPrice {\n raw: string;\n formatted: string;\n currency: string;\n decimals: number;\n}\n\nexport interface ApiRemixOffer {\n id: string;\n status: RemixOfferStatus;\n originalContract: string;\n originalTokenId: string;\n creatorAddress: string;\n requesterAddress: string | null;\n message?: string | null;\n /** Visible only to creator and requester — includes formatted price */\n price?: ApiRemixOfferPrice;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n royaltyPct: number | null;\n approvedCollection: string | null;\n remixContract: string | null;\n remixTokenId: string | null;\n orderHash: string | null;\n createdAt: string;\n expiresAt: string;\n updatedAt: string;\n}\n\n/** Public remix record — price/currency omitted for non-participants */\nexport interface ApiPublicRemix {\n id: string;\n remixContract: string | null;\n remixTokenId: string | null;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n createdAt: string;\n}\n\nexport interface CreateRemixOfferParams {\n originalContract: string;\n originalTokenId: string;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n royaltyPct?: number;\n proposedPrice?: string;\n proposedCurrency?: string;\n message?: string;\n /** Offer validity in days (server default applies if omitted) */\n expiresInDays?: number;\n}\n\nexport interface AutoRemixOfferParams {\n originalContract: string;\n originalTokenId: string;\n licenseType: string;\n}\n\nexport interface ConfirmSelfRemixParams {\n originalContract: string;\n originalTokenId: string;\n remixContract: string;\n remixTokenId: string;\n /** On-chain transaction hash of the mint tx */\n txHash?: string;\n licenseType: string;\n commercial: boolean;\n derivatives: boolean;\n royaltyPct?: number;\n}\n\nexport interface ConfirmRemixOfferParams {\n approvedCollection: string;\n remixContract: string;\n remixTokenId: string;\n orderHash?: string;\n}\n\nexport interface ApiRemixOffersQuery {\n /** \"creator\" = offers where you are the original creator; \"requester\" = offers you made */\n role: \"creator\" | \"requester\";\n page?: number;\n limit?: number;\n}\n\n// ─── Metadata ─────────────────────────────────────────────────────────────────\n\nexport interface ApiMetadataSignedUrl {\n url: string;\n}\n\nexport interface ApiMetadataUpload {\n cid: string;\n url: string;\n}\n\n// ─── Portal (tenant self-service) ─────────────────────────────────────────────\n\nexport interface ApiPortalMe {\n id: string;\n name: string;\n email: string;\n plan: TenantPlan;\n status: string;\n}\n\nexport interface ApiPortalKey {\n id: string;\n prefix: string;\n label: string;\n status: ApiKeyStatus;\n lastUsedAt: string | null;\n createdAt: string;\n}\n\nexport interface ApiPortalKeyCreated {\n id: string;\n prefix: string;\n label: string | null;\n /** Plaintext key — shown ONCE at creation */\n plaintext: string;\n}\n\nexport interface ApiUsageDay {\n day: string;\n requests: number;\n}\n\nexport interface ApiWebhookEndpoint {\n id: string;\n url: string;\n events: WebhookEventType[];\n status: WebhookStatus;\n createdAt: string;\n}\n\nexport interface ApiWebhookCreated extends ApiWebhookEndpoint {\n /** Signing secret — shown ONCE at creation, not stored in plaintext */\n secret: string;\n}\n\nexport interface CreateWebhookParams {\n url: string;\n events: WebhookEventType[];\n label?: string;\n}\n\n// ─── Collection & Creator Profiles ────────────────────────────────────────────\n\nexport interface ApiCollectionProfile {\n contractAddress: string;\n chain: string;\n displayName: string | null;\n description: string | null;\n image: string | null;\n bannerImage: string | null;\n websiteUrl: string | null;\n twitterUrl: string | null;\n discordUrl: string | null;\n telegramUrl: string | null;\n hasGatedContent: boolean;\n gatedContentTitle: string | null;\n slug: string | null;\n updatedBy: string | null;\n updatedAt: string;\n}\n\nexport interface ApiCollectionSlugClaim {\n id: string;\n slug: string;\n contractAddress: string;\n chain: string;\n walletAddress: string;\n status: \"PENDING\" | \"APPROVED\" | \"REJECTED\";\n adminNotes: string | null;\n notifyEmail: string | null;\n reviewedAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ApiCreatorProfile {\n walletAddress: string;\n chain: string;\n username: string | null;\n displayName: string | null;\n bio: string | null;\n avatarImage: string | null;\n /** Computed fallback used by the creator-list / creator-page endpoints\n * ONLY when `avatarImage` is null: image of any collection owned by\n * this creator. Undefined on profile-detail endpoints where this\n * lookup isn't performed. UI may use this to populate hero banners\n * without an extra fetch. */\n collectionImage?: string | null;\n websiteUrl: string | null;\n twitterUrl: string | null;\n discordUrl: string | null;\n telegramUrl: string | null;\n updatedAt: string;\n}\n\nexport interface ApiCreatorListResult {\n creators: ApiCreatorProfile[];\n total: number;\n page: number;\n limit: number;\n}\n\n// ─── User Wallet ───────────────────────────────────────────────────────────────\n\nexport type ApiAppSource =\n | \"MEDIALANE_STARKNET\" // the Starknet dapp (renamed from MEDIALANE_DAPP — the platform is multichain)\n | \"MEDIALANE_IO\"\n | \"MEDIALANE_PORTAL\"\n | \"MEDIALANE_SDK\"\n // Deprecated alias for MEDIALANE_STARKNET. The backend still accepts it (normalizes\n // to MEDIALANE_STARKNET) so existing apps keep working; migrate to MEDIALANE_STARKNET\n // and drop this in a later major.\n | \"MEDIALANE_DAPP\";\n\n// 07-identity §I: the Wallet identifier is (chain, address). Mirrors\n// the backend Chain enum. v1 callers only ever pass STARKNET; the rest\n// are present so the type doesn't need a breaking change when SIWE/SIWB\n// authentication lands and other chains become callable.\nexport type ApiChain = \"STARKNET\" | \"ETHEREUM\" | \"SOLANA\" | \"BASE\" | \"BITCOIN\";\n\nexport interface ApiUserWallet {\n walletAddress: string;\n}\n\n// ─── Collection Claims ─────────────────────────────────────────────────────────\n\nexport interface ApiCollectionClaim {\n id: string;\n contractAddress: string;\n chain: string;\n claimantAddress: string | null;\n status: \"PENDING\" | \"AUTO_APPROVED\" | \"APPROVED\" | \"REJECTED\";\n verificationMethod: \"ONCHAIN\" | \"SIGNATURE\" | \"MANUAL\";\n createdAt: string;\n}\n\nexport interface ApiAdminCollectionClaim extends ApiCollectionClaim {\n claimantEmail: string | null;\n notes: string | null;\n adminNotes: string | null;\n reviewedBy: string | null;\n reviewedAt: string | null;\n updatedAt: string;\n}\n\n// ─── POP Protocol ──────────────────────────────────────────────────────────────\n\nexport interface PopClaimStatus {\n isEligible: boolean;\n hasClaimed: boolean;\n tokenId: string | null;\n}\n\nexport interface PopBatchEligibilityItem extends PopClaimStatus {\n wallet: string;\n}\n\nexport type PopEventType =\n | \"Conference\"\n | \"Bootcamp\"\n | \"Workshop\"\n | \"Hackathon\"\n | \"Meetup\"\n | \"Course\"\n | \"Other\";\n\n// ─── Collection Drop ───────────────────────────────────────────────────────────\n\nexport interface DropMintStatus {\n mintedByWallet: number;\n totalMinted: number;\n}\n\n// ─── Rewards (v0.49.0) ─────────────────────────────────────────────────────────\n\nexport interface ApiRewardsBadge {\n key: string;\n name: string;\n description: string;\n icon: string;\n color: string;\n category: string;\n}\n\nexport interface ApiRewardsLevel {\n level: number;\n name: string;\n xpRequired: number;\n badgeColor: string;\n description: string | null;\n}\n\nexport interface ApiUserRewards {\n address: string;\n accountId: string | null;\n publicId: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n nextLevel: { level: number; name: string; xpRequired: number } | null;\n progressPct: number;\n breakdown: Record<string, number>;\n badges: ApiRewardsBadge[];\n computedAt: string | null;\n}\n\nexport interface ApiRewardsLeaderboardEntry {\n rank: number;\n address: string;\n accountId: string | null;\n publicId: string | null;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface ApiRewardsConfig {\n levels: ApiRewardsLevel[];\n actions: { type: string; label: string; xp: number; dailyCap: number | null }[];\n badges: ApiRewardsBadge[];\n}\n\nexport interface ApiRewardsBatchEntry {\n address: string;\n totalXp: number;\n currentLevel: number;\n currentLevelName: string;\n badgeColor: string;\n}\n\nexport interface ApiPointEvent {\n id: string;\n actionType: string;\n xp: number;\n multiplier: number;\n finalXp: number;\n txHash: string | null;\n createdAt: string;\n}\n","import { getCoordinates } from \"./chains.js\";\n\n// Flat per-chain contract constants. Chain-named (each contract is deployed on a\n// specific chain), derived from the chains.ts registry so there is one source.\nconst SN = getCoordinates(\"STARKNET\");\n\n// ── Marketplace ───────────────────────────────────────────────────────────────\nexport const STARKNET_MARKETPLACE_721_CONTRACT = SN.marketplace721!;\nexport const STARKNET_MARKETPLACE_721_CLASS_HASH = SN.marketplace721ClassHash!;\nexport const STARKNET_MARKETPLACE_721_START_BLOCK = SN.marketplace721StartBlock!;\nexport const STARKNET_MARKETPLACE_1155_CONTRACT = SN.marketplace1155!;\nexport const STARKNET_MARKETPLACE_1155_CLASS_HASH = SN.marketplace1155ClassHash!;\nexport const STARKNET_MARKETPLACE_1155_START_BLOCK = SN.marketplace1155StartBlock!;\n\n// ── Collections ───────────────────────────────────────────────────────────────\nexport const STARKNET_COLLECTION_721_CONTRACT = SN.collection721!;\nexport const STARKNET_COLLECTION_721_START_BLOCK = SN.collection721StartBlock!;\nexport const STARKNET_IPNFT_CLASS_HASH = SN.ipNftClassHash!;\nexport const STARKNET_IPCOLLECTION_CLASS_HASH = SN.ipCollectionClassHash!;\nexport const STARKNET_COLLECTION_1155_CONTRACT = SN.collection1155!;\nexport const STARKNET_COLLECTION_1155_FACTORY_CLASS_HASH = SN.collection1155FactoryClassHash!;\nexport const STARKNET_COLLECTION_1155_CLASS_HASH = SN.collection1155ClassHash!;\nexport const STARKNET_COLLECTION_1155_START_BLOCK = SN.collection1155StartBlock!;\n\n// ── POP / Drop / Comments ─────────────────────────────────────────────────────\nexport const STARKNET_POP_FACTORY_CONTRACT = SN.popFactory!;\nexport const STARKNET_POP_COLLECTION_CLASS_HASH = SN.popCollectionClassHash!;\nexport const STARKNET_DROP_FACTORY_CONTRACT = SN.dropFactory!;\nexport const STARKNET_DROP_COLLECTION_CLASS_HASH = SN.dropCollectionClassHash!;\nexport const STARKNET_NFTCOMMENTS_CONTRACT = SN.nftComments!;\n\n// ── IP Tickets / IP Club / IP Sponsorship ─────────────────────────────────────\n// Not yet deployed — these resolve to `undefined` at runtime until chains.ts's\n// STARKNET coordinates are populated (Phase 3/4 deploy). The `!` assertion\n// mirrors the existing convention above; falsy-guard callers (`if (X && ...)`)\n// still behave correctly regardless.\nexport const STARKNET_IP_TICKETS_FACTORY_CONTRACT = SN.ipTicketsFactory!;\nexport const STARKNET_IP_TICKET_COLLECTION_CLASS_HASH = SN.ipTicketCollectionClassHash!;\nexport const STARKNET_IP_CLUB_FACTORY_CONTRACT = SN.ipClubFactory!;\nexport const STARKNET_IP_CLUB_COLLECTION_CLASS_HASH = SN.ipClubCollectionClassHash!;\nexport const STARKNET_IP_SPONSORSHIP_CONTRACT = SN.ipSponsorship!;\nexport const STARKNET_IP_SPONSORSHIP_CLASS_HASH = SN.ipSponsorshipClassHash!;\n\n// ── Creator Coin (Ekubo) ──────────────────────────────────────────────────────\nexport const STARKNET_CREATOR_COIN_FACTORY_CONTRACT = SN.creatorCoinFactory!;\nexport const STARKNET_CREATOR_COIN_EKUBO_LAUNCHER = SN.creatorCoinEkuboLauncher!;\nexport const STARKNET_CREATOR_COIN_CLASS_HASH = SN.creatorCoinClassHash!;\nexport const STARKNET_CREATOR_COIN_FACTORY_CLASS_HASH = SN.creatorCoinFactoryClassHash!;\nexport const STARKNET_CREATOR_COIN_START_BLOCK = SN.creatorCoinStartBlock!;\nexport const STARKNET_EKUBO_CORE = SN.ekuboCore!;\n\n// ── Tokens (chain-agnostic) ───────────────────────────────────────────────────\nexport const SUPPORTED_TOKENS = [\n {\n // Circle-native USDC on Starknet (canonical)\n symbol: \"USDC\",\n address:\n \"0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb\",\n decimals: 6,\n listable: true,\n },\n {\n symbol: \"USDT\",\n address:\n \"0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8\",\n decimals: 6,\n listable: true,\n },\n {\n symbol: \"ETH\",\n address:\n \"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7\",\n decimals: 18,\n listable: true,\n },\n {\n symbol: \"STRK\",\n address:\n \"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d\",\n decimals: 18,\n listable: true,\n },\n {\n symbol: \"WBTC\",\n address:\n \"0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac\",\n decimals: 8,\n listable: true,\n },\n] as const;\n\nexport type SupportedTokenSymbol = (typeof SUPPORTED_TOKENS)[number][\"symbol\"];\n\n/** Default currency for listings and offers — Circle-native USDC on Starknet. */\nexport const DEFAULT_CURRENCY: SupportedTokenSymbol = \"USDC\";\n","import type { Chain } from \"./chains.js\";\n\n/** Chains that resolve in a URL today. Extend when a second chain is displayable. */\nexport const SUPPORTED_URL_CHAINS = [\"STARKNET\"] as const satisfies readonly Chain[];\n\n/** Chain enum → lowercase URL slug. The ONLY place the slug literal is produced. */\nexport function chainSlug(chain: Chain): string {\n return chain.toLowerCase();\n}\n\n/** URL slug → Chain enum, or null for an unknown/unsupported slug (caller 404s). */\nexport function chainFromSlug(slug: string): Chain | null {\n const upper = slug.toUpperCase() as Chain;\n return (SUPPORTED_URL_CHAINS as readonly Chain[]).includes(upper) ? upper : null;\n}\n\n/** Nullish contract/token/address values coerce to \"\" — an absent id was never\n * a valid link anyway, and this keeps callers free of artificial null guards. */\ntype Idish = string | number | null | undefined;\nconst seg = (v: Idish): string => (v == null ? \"\" : String(v));\n\nexport function assetHref(chain: Chain, contract: Idish, tokenId: Idish): string {\n return `/asset/${chainSlug(chain)}/${seg(contract)}/${seg(tokenId)}`;\n}\n\nexport function collectionHref(chain: Chain, contract: Idish): string {\n return `/collections/${chainSlug(chain)}/${seg(contract)}`;\n}\n\nexport function coinHref(chain: Chain, address: Idish): string {\n return `/coins/${chainSlug(chain)}/${seg(address)}`;\n}\n","import type { ServiceDefinition, ServiceCapability } from \"../types/api.js\";\nimport { getStarknetCoordinates } from \"../chains.js\";\n\n// The registry re-projects a service's chain coordinates into the generic\n// `onchain` shape (factoryAddress/classHash/startBlock). Single source = the\n// chain registry. Only STARKNET is populated today.\nconst SN = getStarknetCoordinates(\"STARKNET\");\n\n/**\n * The Medialane service registry (05-service-model §II, §VI).\n * Canonical long-form IDs (01-core-model §III). SDK-resident in v1;\n * on-chain registry later (08-dao-governance §IV).\n *\n * `onchain` is keyed per chain (spec 2026-06-13 §3.1, Decision A): the SDK\n * registry is the single source of a service's coordinates on each chain.\n * Only STARKNET is populated today; adding a chain adds a key here.\n *\n * Phase 2B.2 of the service-model refactor. `ip-erc721` has no dedicated\n * on-chain constant in src/constants.ts, so its `onchain` is omitted rather\n * than invented (the genesis contract address ships with that service).\n */\nconst SERVICES = {\n \"mip-erc721\": {\n id: \"mip-erc721\",\n displayName: \"IP Collection\",\n description: \"Tokenize intellectual property as a per-creator ERC-721 collection.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.collection721!,\n startBlock: SN.collection721StartBlock!,\n },\n },\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\", \"mint\", \"remix\", \"license\"],\n events: [\n { name: \"CollectionCreated\", emittedBy: \"factory\" },\n // Per-instance ERC-721 Transfer emitted by each deployed collection; not\n // yet declared here because the indexer polls discovered instances on a\n // slow schedule. Plan 2026-05-24-data-driven-event-registry.md covers\n // the migration.\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-erc721\": {\n id: \"ip-erc721\",\n displayName: \"Programmable IP (genesis)\",\n description: \"One shared ERC-721 contract; many wallets mint genesis pieces.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\", \"mint\", \"remix\", \"license\"],\n // No factory — single shared contract. Events declared when the genesis\n // contract address is wired into onchain.STARKNET.factoryAddress here.\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"mip-erc1155\": {\n id: \"mip-erc1155\",\n displayName: \"NFT Editions\",\n description: \"Per-creator ERC-1155 collection; creator mints editions.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.collection1155!,\n classHash: SN.collection1155ClassHash!,\n startBlock: SN.collection1155StartBlock!,\n },\n },\n uiVariant: \"edition\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\", \"mint\", \"remix\", \"license\"],\n events: [\n { name: \"CollectionDeployed\", emittedBy: \"factory\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"pop-protocol\": {\n id: \"pop-protocol\",\n displayName: \"POP Protocol\",\n description: \"Soulbound proof-of-presence collectibles per event.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.popFactory!,\n classHash: SN.popCollectionClassHash!,\n },\n },\n uiVariant: \"pop\",\n capabilities: [\"claim\", \"mint\"],\n events: [\n { name: \"CollectionCreated\", emittedBy: \"factory\" },\n { name: \"AllowlistUpdated\", emittedBy: \"instance\", poll: \"slow\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"drop-collection\": {\n id: \"drop-collection\",\n displayName: \"Collection Drop\",\n description: \"Sequential mint with claim windows + allowlist.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.dropFactory!,\n classHash: SN.dropCollectionClassHash!,\n },\n },\n uiVariant: \"drop\",\n capabilities: [\"claim\", \"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n events: [\n { name: \"DropCreated\", emittedBy: \"factory\" },\n { name: \"AllowlistUpdated\", emittedBy: \"instance\", poll: \"slow\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-tickets\": {\n id: \"ip-tickets\",\n displayName: \"IP Tickets\",\n description: \"Create verifiable on-chain tickets — mint to attendees, trade like any collection.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.ipTicketsFactory!,\n classHash: SN.ipTicketCollectionClassHash!,\n },\n },\n uiVariant: \"ticket\",\n capabilities: [\"mint\", \"redeem\", \"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n events: [\n { name: \"CollectionDeployed\", emittedBy: \"factory\" },\n { name: \"TicketCreated\", emittedBy: \"instance\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-club\": {\n id: \"ip-club\",\n displayName: \"IP Club\",\n description: \"Membership clubs — create tiers, mint membership cards, trade like any collection.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.ipClubFactory!,\n classHash: SN.ipClubCollectionClassHash!,\n },\n },\n uiVariant: \"club\",\n capabilities: [\"mint\", \"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n events: [\n { name: \"ClubDeployed\", emittedBy: \"factory\" },\n { name: \"MembershipCreated\", emittedBy: \"instance\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"ip-sponsorship\": {\n id: \"ip-sponsorship\",\n displayName: \"IP Sponsorship\",\n description: \"Sponsorship offers and licenses anchored to an existing Medialane asset.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.ipSponsorship!,\n classHash: SN.ipSponsorshipClassHash!,\n startBlock: SN.ipSponsorshipStartBlock!,\n },\n },\n uiVariant: \"standard\",\n // v3: one contract is both the offer/bid/proposal registry and the\n // issued license collection (a real, standard ERC-721 minted internally\n // — no separate receipt contract). `transfer` reflects that a license is\n // freely transferable at the protocol layer; transferable/expiry intent\n // is declarative (carried in metadata + LicenseMinted), never\n // contract-enforced. Supersedes the 2026-07-02 v2 `ip-sponsorship`\n // (registry-only) + `ip-sponsorship-license` (non-authoritative receipt\n // via a dedicated ip-erc721 instance) pair — retired as of this redesign.\n capabilities: [\"sponsor\", \"transfer\"],\n events: [\n { name: \"OfferCreated\", emittedBy: \"factory\" },\n { name: \"ProposalCreated\", emittedBy: \"factory\" },\n { name: \"LicenseMinted\", emittedBy: \"factory\" },\n ],\n metadataSchema: { licenseDefault: \"CC BY-SA\" },\n },\n \"creator-coin\": {\n id: \"creator-coin\",\n displayName: \"Creator Coin\",\n description:\n \"Launch a fixed-supply social token with permanently-locked Ekubo liquidity.\",\n standard: \"ERC20\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.creatorCoinFactory!,\n classHash: SN.creatorCoinFactoryClassHash!,\n startBlock: SN.creatorCoinStartBlock!,\n },\n },\n uiVariant: \"coin\",\n // `swap` is a UI affordance (05 §III): the marketplace renders an embedded\n // Ekubo swap (via StarkZapp) for the coin. Settlement is Ekubo — Medialane\n // operates NO trading venue and custodies nothing. No venue service exists\n // for coins (unlike NFTs, whose Medialane marketplace contract settles them).\n capabilities: [\"launch\", \"swap\", \"transfer\"],\n events: [\n { name: \"CreatorCoinCreated\", emittedBy: \"factory\" },\n { name: \"CreatorCoinLaunched\", emittedBy: \"factory\" },\n ],\n },\n \"medialane-marketplace-erc721\": {\n id: \"medialane-marketplace-erc721\",\n displayName: \"Medialane Marketplace (ERC-721)\",\n description: \"ERC-721 order matching venue.\",\n standard: \"ERC721\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.marketplace721!,\n classHash: SN.marketplace721ClassHash!,\n startBlock: SN.marketplace721StartBlock!,\n },\n },\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\"],\n events: [\n { name: \"OrderCreated\", emittedBy: \"factory\" },\n { name: \"OrderFulfilled\", emittedBy: \"factory\" },\n { name: \"OrderCancelled\", emittedBy: \"factory\" },\n ],\n },\n \"medialane-marketplace-erc1155\": {\n id: \"medialane-marketplace-erc1155\",\n displayName: \"Medialane Marketplace (ERC-1155)\",\n description: \"ERC-1155 order matching venue.\",\n standard: \"ERC1155\",\n provenance: \"MEDIALANE\",\n onchain: {\n STARKNET: {\n factoryAddress: SN.marketplace1155!,\n classHash: SN.marketplace1155ClassHash!,\n startBlock: SN.marketplace1155StartBlock!,\n },\n },\n uiVariant: \"edition\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\"],\n events: [\n { name: \"OrderCreated\", emittedBy: \"factory\" },\n { name: \"OrderFulfilled\", emittedBy: \"factory\" },\n { name: \"OrderCancelled\", emittedBy: \"factory\" },\n ],\n },\n \"external-erc20\": {\n id: \"external-erc20\",\n displayName: \"External ERC-20\",\n description:\n \"An ERC-20 token (e.g. an unrug memecoin or a partner coin) not deployed via a Medialane service. Brought in by owner claim or admin/partnership — never bulk-indexed. Generalizes to future chains.\",\n standard: \"ERC20\",\n provenance: \"EXTERNAL\",\n uiVariant: \"coin\",\n capabilities: [\"swap\", \"transfer\"],\n },\n \"external-erc721\": {\n id: \"external-erc721\",\n displayName: \"External ERC-721\",\n description: \"ERC-721 contract not deployed via a Medialane service.\",\n standard: \"ERC721\",\n provenance: \"EXTERNAL\",\n uiVariant: \"standard\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n },\n \"external-erc1155\": {\n id: \"external-erc1155\",\n displayName: \"External ERC-1155\",\n description: \"ERC-1155 contract not deployed via a Medialane service.\",\n standard: \"ERC1155\",\n provenance: \"EXTERNAL\",\n uiVariant: \"edition\",\n capabilities: [\"list\", \"buy\", \"make_offer\", \"cancel\", \"transfer\"],\n },\n} as const satisfies Record<string, ServiceDefinition>;\n\n/**\n * Literal-union of every registered service ID. Use this as the type for\n * `Collection.service` write sites in consumers — typos like \"pop_protocol\"\n * (underscore instead of hyphen) become compile errors.\n *\n * `getService()` still accepts loose `string` for read-side lookups where the\n * value came from the DB and is trusted to already be valid.\n */\nexport type ServiceId = keyof typeof SERVICES;\n\n/** Type guard: narrows a string to ServiceId if it's registered. */\nexport function isServiceId(id: string | null | undefined): id is ServiceId {\n return typeof id === \"string\" && id in SERVICES;\n}\n\n/** Lookup. Returns undefined for unregistered service IDs — callers should\n * treat that as a data error, since every Collection.service value is\n * expected to map to a registered ServiceDefinition. */\nexport function getService(id: string | null | undefined): ServiceDefinition | undefined {\n return id && id in SERVICES ? (SERVICES as Record<string, ServiceDefinition>)[id] : undefined;\n}\n\n/** All registered services (e.g. the launchpad grid). */\nexport function listServices(): ServiceDefinition[] {\n return Object.values(SERVICES);\n}\n\n/** Services that declare a capability (e.g. \"where can users mint\"). */\nexport function getServicesByCapability(cap: ServiceCapability): ServiceDefinition[] {\n return Object.values(SERVICES).filter(\n (s) => (s.capabilities as readonly ServiceCapability[]).includes(cap),\n );\n}\n\n/** Whether a service declares a given capability — e.g. whether an asset\n * type is transferable. Returns false for an unregistered/missing id rather\n * than throwing, since callers use this for UI copy, not authority checks. */\nexport function hasCapability(\n id: string | null | undefined,\n cap: ServiceCapability,\n): boolean {\n return getService(id)?.capabilities.includes(cap) ?? false;\n}\n","import { SUPPORTED_TOKENS } from \"../constants.js\";\n\nexport type SupportedToken = (typeof SUPPORTED_TOKENS)[number];\n\n/**\n * Parse a human-readable amount (e.g. \"1.5\") to its raw integer string\n * representation given the token's decimal places.\n * Uses pure BigInt arithmetic to avoid floating point precision loss.\n */\nexport function parseAmount(human: string, decimals: number): string {\n const [whole, frac = \"\"] = human.split(\".\");\n const fracPadded = frac.padEnd(decimals, \"0\").slice(0, decimals);\n return (BigInt(whole) * BigInt(10) ** BigInt(decimals) + BigInt(fracPadded)).toString();\n}\n\n/**\n * Format a raw integer string (e.g. \"1500000\") to a human-readable decimal\n * string given the token's decimal places.\n */\nexport function formatAmount(raw: string, decimals: number): string {\n const value = BigInt(raw);\n const factor = 10n ** BigInt(decimals);\n const whole = value / factor;\n const remainder = value % factor;\n const fractional = remainder.toString().padStart(decimals, \"0\");\n return `${whole}.${fractional}`;\n}\n\n/**\n * Find a supported token by its contract address.\n *\n * Compares by numeric felt value so a caller-supplied address that isn't\n * zero-padded to 64 hex chars (`0x33068f6…`) still matches the stored padded\n * form (`0x033068f6…`) — a bare `.toLowerCase()` string compare would miss it,\n * the exact padding trap the address invariant warns against. Non-hex inputs\n * fall back to a case-insensitive string compare.\n */\nexport function getTokenByAddress(address: string): SupportedToken | undefined {\n let target: bigint | null = null;\n try {\n target = BigInt(address);\n } catch {\n target = null;\n }\n return SUPPORTED_TOKENS.find((t) => {\n if (target !== null) {\n try {\n return BigInt(t.address) === target;\n } catch {\n /* stored address not hex — fall through to string compare */\n }\n }\n return t.address.toLowerCase() === address.toLowerCase();\n });\n}\n\n/**\n * Find a supported token by its symbol (case-insensitive).\n */\nexport function getTokenBySymbol(symbol: string): SupportedToken | undefined {\n const upper = symbol.toUpperCase();\n return SUPPORTED_TOKENS.find((t) => t.symbol === upper);\n}\n\n/**\n * Return all tokens available for use in listing and offer dialogs.\n * Tokens with listable: false appear only as marketplace filter chips.\n */\nexport function getListableTokens(): ReadonlyArray<SupportedToken> {\n return SUPPORTED_TOKENS.filter((t) => t.listable);\n}\n","/**\n * Recursively convert all BigInt values to their decimal string representations.\n * Required before JSON serialisation and before passing objects to starknet.js\n * functions that expect string felts.\n */\nexport function stringifyBigInts(obj: unknown): unknown {\n if (typeof obj === \"bigint\") {\n return obj.toString();\n }\n if (Array.isArray(obj)) {\n return obj.map(stringifyBigInts);\n }\n if (obj !== null && typeof obj === \"object\") {\n return Object.fromEntries(\n Object.entries(obj as Record<string, unknown>).map(([key, value]) => [\n key,\n stringifyBigInts(value),\n ])\n );\n }\n return obj;\n}\n\n/**\n * Convert a u256 represented as { low: string; high: string } to a single BigInt.\n */\nexport function u256ToBigInt(low: string, high: string): bigint {\n return BigInt(low) + (BigInt(high) << 128n);\n}\n","/**\n * Resilient Starknet RPC helpers — the single source of truth for \"what counts\n * as a transient RPC failure\" and the public fallback endpoint list, shared by\n * every Medialane app:\n * - dapp / io `starknetProvider` singletons (RpcProvider.baseFetch)\n * - io `/api/rpc` server-side proxy (upstream rotation)\n * - backend circuit breaker + receipt-rotation paths\n *\n * Motivation (2026-06-03): Alchemy's Starknet mainnet endpoint intermittently\n * returns HTTP 503 with the JSON-RPC envelope `-32001 \"Unable to complete\n * request at this time.\"` (~1 in 6 calls, while its status page reads green).\n * A single blip inside a `waitForTransaction` poll loop stalls mints/listings.\n * Failing over to a public endpoint recovers silently.\n */\n\n/**\n * Ordered public Starknet **mainnet** RPC endpoints (no API key required),\n * used as fallback after an app's configured primary (e.g. Alchemy) returns a\n * transient error. lava.build — RPC spec 0.8.1, permissive CORS — so it is\n * safe for browser `baseFetch` use as well as server-side rotation.\n *\n * blastapi.io and free-rpc.nethermind.io were removed (2026-07-04) — long\n * confirmed dead/unreliable in production; do not re-add them.\n */\nexport const PUBLIC_RPC_FALLBACKS: readonly string[] = [\n \"https://rpc.starknet.lava.build\",\n];\n\n/**\n * Matches transient failure signals in a raw response body or JSON-RPC error\n * message. Deterministic Starknet contract errors (revert / invalid params —\n * small positive JSON-RPC codes) MUST NOT match: they propagate verbatim so\n * callers see the real failure. Note `-32000` is intentionally absent — the io\n * `/api/rpc` proxy uses it for \"Unauthorized\", which must not trigger failover.\n */\nconst TRANSIENT_BODY_RE =\n /\"code\"\\s*:\\s*-32001|\"code\"\\s*:\\s*-32603|unable to complete|rate.?limit|too many|throttl|exceed.*quota|temporarily unavailable|service unavailable|overload|gateway.*time|upstream.*time|backend.*error/i;\n\n/**\n * Is this RPC response worth retrying against another endpoint?\n *\n * Accepts either an HTTP status + raw text body (client `baseFetch` path) or a\n * parsed JSON-RPC envelope (server proxy path). For parsed envelopes the\n * server-defined error-code range (`-32099..-32000`) is treated as transient;\n * for raw text only the explicit `-32001`/`-32603` codes + message hints match,\n * so a `-32000` \"Unauthorized\" text body is never mistaken for transient.\n */\nexport function isTransientRpcError(input: { status?: number; body?: unknown }): boolean {\n const { status, body } = input;\n if (typeof status === \"number\" && (status === 429 || status >= 500)) return true;\n if (body == null) return false;\n\n // Parsed JSON-RPC envelope: inspect error.code numerically.\n if (typeof body === \"object\") {\n const err = (body as { error?: { code?: unknown; message?: unknown } }).error;\n if (!err || typeof err !== \"object\") return false;\n const code = (err as { code?: unknown }).code;\n if (typeof code === \"number\") {\n if (code === 429) return true;\n if (code >= -32099 && code <= -32000) return true; // server-defined range (incl. -32001)\n if (code === -32603) return true; // generic internal error\n }\n const message = (err as { message?: unknown }).message;\n return typeof message === \"string\" ? TRANSIENT_BODY_RE.test(message) : false;\n }\n\n // Raw text body (client baseFetch path).\n return TRANSIENT_BODY_RE.test(String(body));\n}\n\nexport interface FailoverFetchOptions {\n /** Underlying fetch to wrap (e.g. one that adds a timeout). Defaults to the global `fetch`. */\n baseFetch?: typeof fetch;\n /** Invoked each time an endpoint is abandoned for the next one. */\n onFailover?: (info: { url: string; status?: number; error?: unknown }) => void;\n}\n\n/**\n * Build a `fetch` suitable for `RpcProvider.baseFetch` that tries each URL in\n * `urls` in order, advancing to the next only on a transient failure (network\n * error, 5xx/429, or a transient JSON-RPC envelope). The provider's own\n * `nodeUrl` argument is ignored — routing is controlled entirely by `urls` —\n * so callers should set `nodeUrl: urls[0]` (used only for spec negotiation).\n *\n * @example\n * const urls = [primaryAlchemyUrl, ...PUBLIC_RPC_FALLBACKS];\n * new RpcProvider({ nodeUrl: urls[0], baseFetch: createFailoverFetch(urls) });\n */\nexport function createFailoverFetch(\n urls: string[],\n options: FailoverFetchOptions = {},\n): typeof fetch {\n const endpoints = urls.filter((u): u is string => Boolean(u));\n if (endpoints.length === 0) {\n throw new Error(\"createFailoverFetch: at least one RPC URL is required\");\n }\n const doFetch = options.baseFetch ?? fetch;\n\n const failover = async (_input: unknown, init?: RequestInit): Promise<Response> => {\n let lastError: unknown;\n\n for (let i = 0; i < endpoints.length; i++) {\n const url = endpoints[i];\n const isLast = i === endpoints.length - 1;\n try {\n const res = await doFetch(url, init);\n const text = await res.text();\n const rebuilt = () =>\n new Response(text, { status: res.status, statusText: res.statusText, headers: res.headers });\n\n if (isLast || !isTransientRpcError({ status: res.status, body: text })) {\n return rebuilt();\n }\n options.onFailover?.({ url, status: res.status });\n } catch (err) {\n lastError = err;\n if (isLast) throw err;\n options.onFailover?.({ url, error: err });\n }\n }\n\n // Loop always returns/throws on the last endpoint; this satisfies the type checker.\n throw lastError ?? new Error(\"createFailoverFetch: all endpoints failed\");\n };\n\n return failover as unknown as typeof fetch;\n}\n"]}