@playmos/sdk 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/{chunk-TMBBEGIF.js → chunk-VYR6BBHF.js} +0 -2
- package/dist/{errors-DMtMpbR6.d.cts → errors-CdVzHuhY.d.cts} +69 -12
- package/dist/{errors-DMtMpbR6.d.ts → errors-CdVzHuhY.d.ts} +69 -12
- package/dist/index.cjs +361 -114
- package/dist/index.d.cts +68 -16
- package/dist/index.d.ts +68 -16
- package/dist/index.js +361 -117
- package/dist/server.cjs +0 -2
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -3
- package/package.json +6 -3
- package/dist/chunk-TMBBEGIF.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/server.cjs.map +0 -1
- package/dist/server.js.map +0 -1
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/ids.ts","../src/money.ts","../src/validation.ts","../src/http.ts","../src/wallet.ts","../src/chain/abis.ts","../src/chain/batch.ts","../src/chain/calls.ts","../src/mock.ts","../src/x402.ts","../src/client.ts","../src/payout.ts","../src/settlement.ts"],"names":["encodeFunctionData","ADDRESS_RE","round","payment","requireAddress"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Environment resolution + the canonical address book.\n *\n * The API key prefix selects the environment (Stripe's ergonomic): pk_test_* →\n * Base Sepolia + the sandbox service; pk_live_* → Base mainnet + production. An\n * explicit `network` override always wins.\n */\n\nimport { AuthError } from \"./errors.js\";\nimport type { Network } from \"./types.js\";\n\nexport const CHAIN_ID: Record<Network, number> = {\n base: 8453,\n \"base-sepolia\": 84532,\n};\n\n/**\n * Circle USDC. Sepolia value fixes #336 (the vendored SDK shipped 0x0 here).\n * Verified against the game-hub deploy scripts + kit config.\n */\nexport const USDC_ADDRESS: Record<Network, `0x${string}`> = {\n base: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"base-sepolia\": \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n};\n\nexport const DEFAULT_API_BASE_URL: Record<Network, string> = {\n base: \"https://api.playmos.io/v1\",\n \"base-sepolia\": \"https://api.sandbox.playmos.io/v1\",\n};\n\nexport interface ResolvedEnv {\n network: Network;\n chainId: number;\n apiBaseUrl: string;\n isTest: boolean;\n}\n\n/** Validate the key and resolve the environment it implies. */\nexport function resolveEnv(\n apiKey: string,\n networkOverride?: Network,\n apiBaseUrlOverride?: string,\n): ResolvedEnv {\n if (typeof apiKey !== \"string\" || apiKey.trim() === \"\") {\n throw new AuthError(\"Missing apiKey. Pass a pk_test_… or pk_live_… key.\");\n }\n const isTest = apiKey.startsWith(\"pk_test_\") || apiKey.startsWith(\"sk_test_\");\n const isLive = apiKey.startsWith(\"pk_live_\") || apiKey.startsWith(\"sk_live_\");\n if (!isTest && !isLive) {\n throw new AuthError(\n 'Malformed apiKey. Expected a \"pk_test_\", \"pk_live_\", \"sk_test_\", or \"sk_live_\" prefix.',\n { keyPreview: apiKey.slice(0, 8) },\n );\n }\n const network: Network = networkOverride ?? (isTest ? \"base-sepolia\" : \"base\");\n return {\n network,\n chainId: CHAIN_ID[network],\n apiBaseUrl: apiBaseUrlOverride ?? DEFAULT_API_BASE_URL[network],\n isTest,\n };\n}\n","/**\n * ULID generation (fixes #341/C — the `pay_mock_${Date.now()}` collision bug).\n *\n * A ULID is a 26-char Crockford-base32 string: 48 bits of millisecond timestamp\n * (lexicographically sortable) + 80 bits of cryptographic randomness. Within the\n * same millisecond we increment the random component monotonically, so even 50+\n * ids minted in a tight loop are unique and ordered. Uses Web Crypto\n * (`crypto.getRandomValues`), available in browsers and Node ≥ 18.\n */\n\nconst ENCODING = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\"; // Crockford base32 (no I,L,O,U)\nconst TIME_LEN = 10;\nconst RANDOM_LEN = 16;\n\nfunction getCrypto(): Crypto {\n const c = (globalThis as { crypto?: Crypto }).crypto;\n if (!c || typeof c.getRandomValues !== \"function\") {\n throw new Error(\"Web Crypto (crypto.getRandomValues) is not available in this runtime.\");\n }\n return c;\n}\n\nfunction encodeTime(now: number, len: number): string {\n let mod: number;\n let str = \"\";\n for (let i = len - 1; i >= 0; i--) {\n mod = now % 32;\n str = ENCODING[mod] + str;\n now = (now - mod) / 32;\n }\n return str;\n}\n\n// Monotonic state so ids minted in the same millisecond stay unique + ordered.\nlet lastTime = -1;\nlet lastRandom: number[] = [];\n\nfunction randomBytes(len: number): number[] {\n const bytes = new Uint8Array(len);\n getCrypto().getRandomValues(bytes);\n return Array.from(bytes, (b) => b % 32);\n}\n\nfunction incrementRandom(arr: number[]): number[] {\n const out = arr.slice();\n for (let i = out.length - 1; i >= 0; i--) {\n const v = out[i] ?? 0;\n if (v < 31) {\n out[i] = v + 1;\n return out;\n }\n out[i] = 0;\n }\n // Overflow (astronomically unlikely) — reseed.\n return randomBytes(out.length);\n}\n\n/** Generate a monotonic ULID (26 chars, uppercase Crockford base32). */\nexport function ulid(seedTime?: number): string {\n const now = seedTime ?? Date.now();\n let random: number[];\n if (now === lastTime) {\n random = incrementRandom(lastRandom);\n } else {\n random = randomBytes(RANDOM_LEN);\n }\n lastTime = now;\n lastRandom = random;\n return encodeTime(now, TIME_LEN) + random.map((r) => ENCODING[r]).join(\"\");\n}\n\n/** `${prefix}_${ulid()}` — e.g. `pay_01J…`, `entry_01J…`, `idem_01J…`. */\nexport function prefixedId(prefix: string): string {\n return `${prefix}_${ulid()}`;\n}\n","/**\n * Money math — exact, integer-only, in USDC micro-units (6 decimals).\n *\n * USD amounts are decimal strings (\"4.99\") to avoid float corruption. Internally\n * every value is a BigInt count of micro-USDC (1 USDC = 1_000_000 micro), so the\n * split is bit-exact and always sums back to the input — no wei is ever lost.\n *\n * The split arithmetic MIRRORS the contracts (floor division, exactly like\n * Solidity `amount * bps / 10000`), so the SDK receipt matches what settles\n * on-chain. The contract remains the source of truth; these numbers are the\n * faithful preview.\n */\n\nimport { InvalidAmountError } from \"./errors.js\";\n\nexport const USDC_DECIMALS = 6;\nexport const MICRO_PER_USDC = 1_000_000n;\n\nconst AMOUNT_RE = /^\\d+(\\.\\d{1,2})?$/;\n\n/**\n * Parse a USD decimal string (≤ 2 dp, > 0) into micro-USDC.\n * Throws {@link InvalidAmountError} on anything that isn't a clean positive price.\n */\nexport function parseUsdToMicro(amount: string): bigint {\n if (typeof amount !== \"string\" || amount.trim() === \"\" || !AMOUNT_RE.test(amount)) {\n throw new InvalidAmountError(amount);\n }\n const parts = amount.split(\".\");\n const whole = parts[0] ?? \"0\";\n const frac = parts[1] ?? \"\";\n const fracPadded = (frac + \"000000\").slice(0, USDC_DECIMALS);\n const micro = BigInt(whole) * MICRO_PER_USDC + BigInt(fracPadded);\n if (micro <= 0n) throw new InvalidAmountError(amount);\n return micro;\n}\n\n/**\n * Format micro-USDC back to a USD decimal string. Keeps full precision (up to 6\n * dp) but trims trailing zeros to a minimum of 2 dp — so \"$4.99\" stays \"4.99\"\n * while a 1% fee of $4.99 renders its exact \"0.0499\", not a lossy \"0.05\".\n */\nexport function formatMicroToUsd(micro: bigint): string {\n const neg = micro < 0n;\n const abs = neg ? -micro : micro;\n const whole = abs / MICRO_PER_USDC;\n const frac = abs % MICRO_PER_USDC;\n let fracStr = frac.toString().padStart(USDC_DECIMALS, \"0\").replace(/0+$/, \"\");\n if (fracStr.length < 2) fracStr = fracStr.padEnd(2, \"0\");\n return `${neg ? \"-\" : \"\"}${whole.toString()}.${fracStr}`;\n}\n\n/** External-studio IAP split (99/1 by default). Floor-matches `PlaymosPay.pay`. */\nexport function computeIapSplit(\n amountMicro: bigint,\n feeBps: number,\n): { feeMicro: bigint; netMicro: bigint } {\n const feeMicro = (amountMicro * BigInt(feeBps)) / 10_000n;\n const netMicro = amountMicro - feeMicro;\n return { feeMicro, netMicro };\n}\n\n/**\n * Skill-game prize-pool split (60/30/10 by default). Floor-matches the on-chain\n * `EconomyConfig`. Any 1–2 micro rounding remainder is assigned to the pool so\n * the three parts sum EXACTLY to the entry (invariant asserted below).\n */\nexport function computePoolSplit(\n amountMicro: bigint,\n poolBps: number,\n seedBps: number,\n rakeBps: number,\n): { poolMicro: bigint; seedMicro: bigint; rakeMicro: bigint } {\n if (poolBps + seedBps + rakeBps !== 10_000) {\n throw new Error(`pool/seed/rake bps must sum to 10000, got ${poolBps + seedBps + rakeBps}`);\n }\n const seedMicro = (amountMicro * BigInt(seedBps)) / 10_000n;\n const rakeMicro = (amountMicro * BigInt(rakeBps)) / 10_000n;\n const poolMicro = amountMicro - seedMicro - rakeMicro; // remainder → pool\n return { poolMicro, seedMicro, rakeMicro };\n}\n","/**\n * Client-side input validation (fixes #342/D — \"-1\", \"0\", \"abc\", \"\", 18-dp all\n * used to succeed). Every check throws a typed error BEFORE any network or chain\n * call, exactly like Stripe.\n */\n\nimport { InvalidAmountError, MissingFieldError } from \"./errors.js\";\nimport { parseUsdToMicro } from \"./money.js\";\n\n/**\n * Validate a USD amount string and return its micro-USDC value.\n * Rejects: empty, non-numeric, ≤ 0, or more than 2 decimal places.\n */\nexport function validateAmount(amount: unknown): bigint {\n if (typeof amount !== \"string\") throw new InvalidAmountError(amount);\n return parseUsdToMicro(amount); // throws InvalidAmountError on bad format / ≤ 0\n}\n\n/** Require a non-empty, trimmed string field. */\nexport function requireField(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new MissingFieldError(field);\n }\n return value;\n}\n\n/** Metadata guard: at most 20 string→string entries (per docs §3). */\nexport function validateMetadata(metadata: unknown): Record<string, string> | undefined {\n if (metadata == null) return undefined;\n if (typeof metadata !== \"object\" || Array.isArray(metadata)) {\n throw new MissingFieldError(\"metadata (must be an object of string values)\");\n }\n const entries = Object.entries(metadata as Record<string, unknown>);\n if (entries.length > 20) {\n throw new InvalidAmountError(`metadata: at most 20 keys allowed, got ${entries.length}`);\n }\n const out: Record<string, string> = {};\n for (const [k, v] of entries) {\n if (typeof v !== \"string\") {\n throw new MissingFieldError(`metadata.${k} (values must be strings)`);\n }\n out[k] = v;\n }\n return out;\n}\n","/**\n * Thin REST client for the Playmos service. Every SDK method that touches the\n * backend (create intent, verify, payouts, agents) goes through here. `verify()`\n * hits `GET /payments/:id`, which the service resolves by READING THE CHAIN — so\n * the SDK never trusts a client claim or a mutable counter (#337 root fix).\n *\n * Automatic backoff/retry (#50 + BB-GATEB-002):\n * - HTTP **429** (rate limit): always retried with exponential backoff + jitter\n * (honors `Retry-After` when present).\n * - HTTP **502 / 503 / 504** (gateway / DO via_upstream HTML): GET always retried;\n * POST only when an `idempotency-key` is present so a retried write never\n * double-broadcasts. Opt out: `retry: false` or `retry: { maxRetries: 0 }`.\n */\n\nimport { ApiError, AuthError } from \"./errors.js\";\n\n/** Options for {@link HttpClient.post}. */\nexport interface HttpPostOptions {\n idempotencyKey?: string;\n /**\n * HTTP statuses to treat as success in addition to 2xx.\n * Used by x402 challenge mint, which correctly returns **402 Payment Required**.\n */\n acceptStatuses?: number[];\n}\n\nexport interface HttpClient {\n post<T>(path: string, body: unknown, opts?: HttpPostOptions): Promise<T>;\n get<T>(path: string): Promise<T>;\n}\n\n/** Tuning for the automatic 429 retry (all optional; sane defaults). */\nexport interface RetryOptions {\n /** Max automatic retries on HTTP 429. `0` disables retrying entirely. Default 2 (→ up to 3 attempts). */\n maxRetries?: number;\n /** Base backoff in ms; the wait grows exponentially per attempt (2^n). Default 500. */\n baseDelayMs?: number;\n /** Ceiling for any single backoff wait, including a server `Retry-After`. Default 20000. */\n maxDelayMs?: number;\n}\n\n/** Resolved (no-undefined) retry config used internally. */\ninterface ResolvedRetry {\n maxRetries: number;\n baseDelayMs: number;\n maxDelayMs: number;\n}\n\n/** Fold the caller's opt-out/override into concrete numbers. `false` == retries off. */\nexport function resolveRetry(retry?: boolean | RetryOptions): ResolvedRetry {\n const off = { maxRetries: 0, baseDelayMs: 500, maxDelayMs: 20_000 };\n if (retry === false) return off;\n const r = retry === true || retry === undefined ? {} : retry;\n return {\n maxRetries: r.maxRetries ?? 2,\n baseDelayMs: r.baseDelayMs ?? 500,\n maxDelayMs: r.maxDelayMs ?? 20_000,\n };\n}\n\nconst sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\n/**\n * How long to wait before the next attempt. Prefer the server's `Retry-After`\n * (delta-seconds or an HTTP-date) when it's present and sane; otherwise use\n * exponential backoff (`base * 2^attempt`) with a little jitter to avoid a\n * thundering herd. Always clamped to `[0, maxDelayMs]`.\n */\nfunction backoffMs(res: Response, attempt: number, cfg: ResolvedRetry): number {\n const header = res.headers.get(\"retry-after\");\n if (header) {\n const secs = Number(header);\n let ms: number;\n if (Number.isFinite(secs)) {\n ms = secs * 1000; // delta-seconds form\n } else {\n const at = Date.parse(header); // HTTP-date form\n ms = Number.isNaN(at) ? NaN : at - Date.now();\n }\n if (Number.isFinite(ms) && ms >= 0) return Math.min(ms, cfg.maxDelayMs);\n }\n const expo = cfg.baseDelayMs * 2 ** attempt;\n const jitter = Math.random() * cfg.baseDelayMs;\n return Math.min(expo + jitter, cfg.maxDelayMs);\n}\n\nexport function createHttpClient(\n baseUrl: string,\n apiKey: string,\n retry?: boolean | RetryOptions,\n): HttpClient {\n const base = baseUrl.replace(/\\/+$/, \"\");\n const cfg = resolveRetry(retry);\n\n /**\n * Run the request, converting a TRANSPORT failure (DNS/NXDOMAIN, connection\n * refused, TLS, abort/timeout — i.e. `fetch()` itself throws) into a typed,\n * actionable `ApiError`. HTTP error *responses* (non-2xx) are NOT caught here;\n * they flow through `handle()` unchanged. `detail.cause` carries the underlying\n * error; `detail.transport: true` distinguishes this from a status failure.\n */\n async function send(url: string, init: RequestInit): Promise<Response> {\n try {\n return await fetch(url, init);\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ApiError(\n `Could not reach the Playmos API at ${url} (network error: ${cause}). Check the service is running and apiBaseUrl is correct.`,\n { url, cause, transport: true },\n );\n }\n }\n\n /**\n * `send`, plus automatic backoff/retry (#50 + BB-GATEB-002):\n * - HTTP **429** — always retryable\n * - HTTP **502 / 503 / 504** (DO via_upstream / gateway) — GET always; POST only when\n * an `idempotency-key` is present (never double-broadcast). Gate B 504 HTML case.\n */\n function hasIdempotencyKey(init: RequestInit): boolean {\n const h = init.headers;\n if (!h) return false;\n if (h instanceof Headers) {\n return Boolean(h.get(\"idempotency-key\") || h.get(\"Idempotency-Key\"));\n }\n if (Array.isArray(h)) {\n return h.some(([k]) => String(k).toLowerCase() === \"idempotency-key\");\n }\n const rec = h as Record<string, string>;\n return Object.keys(rec).some((k) => k.toLowerCase() === \"idempotency-key\" && !!rec[k]);\n }\n\n function isRetryable(res: Response, init: RequestInit): boolean {\n if (res.status === 429) return true;\n if (res.status === 502 || res.status === 503 || res.status === 504) {\n const method = (init.method ?? \"GET\").toUpperCase();\n if (method === \"GET\" || method === \"HEAD\") return true;\n return hasIdempotencyKey(init);\n }\n return false;\n }\n\n async function sendWithRetry(url: string, init: RequestInit): Promise<Response> {\n let res = await send(url, init);\n for (let attempt = 0; attempt < cfg.maxRetries && isRetryable(res, init); attempt++) {\n await sleep(backoffMs(res, attempt, cfg));\n res = await send(url, init);\n }\n return res;\n }\n\n async function handle<T>(res: Response, acceptStatuses?: number[]): Promise<T> {\n let text: string;\n try {\n text = await res.text();\n } catch (err) {\n const cause = err instanceof Error ? err.message : String(err);\n throw new ApiError(\n `Could not read the response from the Playmos API at ${res.url} (network error: ${cause}). Check the service is running and apiBaseUrl is correct.`,\n { url: res.url, cause, transport: true },\n );\n }\n let json: unknown;\n try {\n json = text ? JSON.parse(text) : {};\n } catch {\n // DO App Platform often returns HTML on 502/504 (via_upstream) when a long\n // server-settle exceeds the edge timeout — not a typed JSON error.\n const gateway = res.status === 502 || res.status === 503 || res.status === 504;\n const msg = gateway\n ? `Sandbox gateway timeout (${res.status}) from ${res.url} — the request likely exceeded the platform limit while settling on-chain. Retry with the same idempotency key (safe); prefer a dedicated Base Sepolia RPC on the service (BB-GATEB-002).`\n : `Non-JSON response (${res.status}) from ${res.url}`;\n throw new ApiError(msg, { status: res.status, body: text.slice(0, 500), gateway });\n }\n if (res.ok || (acceptStatuses !== undefined && acceptStatuses.includes(res.status))) {\n return json as T;\n }\n const errBody = json as { error?: { code?: string; message?: string } };\n const message = errBody?.error?.message ?? `Request failed with ${res.status}`;\n if (res.status === 401 || res.status === 403 || errBody?.error?.code === \"auth\") {\n throw new AuthError(message, { status: res.status });\n }\n throw new ApiError(message, { status: res.status, code: errBody?.error?.code });\n }\n\n return {\n async post<T>(path: string, body: unknown, opts?: HttpPostOptions): Promise<T> {\n const headers: Record<string, string> = {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${apiKey}`,\n };\n if (opts?.idempotencyKey) headers[\"idempotency-key\"] = opts.idempotencyKey;\n const res = await sendWithRetry(`${base}${path}`, { method: \"POST\", headers, body: JSON.stringify(body) });\n return handle<T>(res, opts?.acceptStatuses);\n },\n async get<T>(path: string): Promise<T> {\n const res = await sendWithRetry(`${base}${path}`, {\n method: \"GET\",\n headers: { authorization: `Bearer ${apiKey}` },\n });\n return handle<T>(res);\n },\n };\n}\n","/**\n * Wallet resolution — pruned to the two connectors V1 actually supports\n * (`base-account`, `injected`), fixing the old surface that advertised four and\n * silently no-op'd (#335/E).\n */\n\nimport { WalletConnectionError } from \"./errors.js\";\nimport type { Eip1193Provider, WalletConfig } from \"./types.js\";\n\ninterface WithEthereum {\n ethereum?: Eip1193Provider;\n}\n\n/**\n * Resolve an EIP-1193 provider from config. Precedence:\n * 1. an explicitly supplied `wallet.provider`\n * 2. `injected` → globalThis.ethereum (browser wallet)\n * 3. `base-account` → expects the Base Account SDK to have injected a provider;\n * the host app passes it via `wallet.provider` in headless/SSR contexts.\n */\nexport function resolveProvider(wallet?: WalletConfig): Eip1193Provider {\n if (wallet?.provider) return wallet.provider;\n\n const injected = (globalThis as WithEthereum).ethereum;\n const connector = wallet?.connector ?? \"base-account\";\n\n if (connector === \"injected\") {\n if (!injected) {\n throw new WalletConnectionError(\n \"No injected wallet found (globalThis.ethereum is undefined). Open in a wallet browser or pass wallet.provider.\",\n );\n }\n return injected;\n }\n\n // base-account: prefer an injected Base Account provider; otherwise instruct\n // the host to supply one. We do NOT hard-depend on the Base Account SDK so the\n // package stays light and server-safe.\n if (injected) return injected;\n throw new WalletConnectionError(\n \"base-account connector needs a provider. In the Base App it is injected automatically; \" +\n \"elsewhere, create one with @base-org/account and pass it as wallet.provider.\",\n );\n}\n\n/**\n * Is a real wallet actually available to sign for the player? Used by the\n * auto no-wallet routing (0.1.4): when this is false on a test/sandbox key, the\n * SDK routes to the service's server-settle path so the developer needs zero\n * wallet/crypto. Detection (mirrors {@link resolveProvider} precedence):\n * 1. an explicit `wallet.provider` counts as available (don't force a connect);\n * 2. otherwise a provider must resolve (config or globalThis.ethereum) AND we\n * must be able to actually read an account from it.\n * Never throws — any failure to resolve/connect means \"no wallet\".\n */\nexport async function walletAvailable(wallet?: WalletConfig): Promise<boolean> {\n // An explicitly-supplied provider is treated as available without forcing an\n // eth_requestAccounts round-trip (the host owns its own connect UX).\n if (wallet?.provider) return true;\n\n let provider: Eip1193Provider;\n try {\n provider = resolveProvider(wallet);\n } catch {\n return false; // no config.provider and no injectable globalThis.ethereum\n }\n try {\n await getAccount(provider);\n return true;\n } catch {\n return false; // provider present but no account could be resolved\n }\n}\n\n/** Read the connected account (first address). */\nexport async function getAccount(provider: Eip1193Provider): Promise<`0x${string}`> {\n try {\n const accounts = (await provider.request({ method: \"eth_requestAccounts\" })) as string[];\n const addr = accounts?.[0];\n if (!addr) throw new Error(\"no account\");\n return addr as `0x${string}`;\n } catch (e) {\n throw new WalletConnectionError(\"Could not read the player's wallet account.\", {\n cause: (e as { message?: string })?.message,\n });\n }\n}\n","/** Minimal viem const-typed ABIs for the on-chain calls the SDK builds. */\n\nexport const erc20Abi = [\n {\n type: \"function\",\n name: \"approve\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"spender\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"balanceOf\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ type: \"uint256\" }],\n },\n] as const;\n\n/** PlaymosPay — external-studio IAP, 99/1 atomic split. */\nexport const playmosPayAbi = [\n {\n type: \"function\",\n name: \"pay\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"paymentId\", type: \"bytes32\" },\n { name: \"studio\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [],\n },\n] as const;\n\n/** PrizePool V2 — skill-game entry + operator lifecycle + settle (issue #13). */\nexport const prizePoolAbi = [\n {\n type: \"function\",\n name: \"openRound\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"roundId\", type: \"bytes32\" },\n { name: \"series\", type: \"bytes32\" },\n { name: \"entry\", type: \"uint256\" },\n ],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"enter\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"roundId\", type: \"bytes32\" },\n { name: \"identity\", type: \"bytes32\" },\n ],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"lockRound\",\n stateMutability: \"nonpayable\",\n inputs: [{ name: \"roundId\", type: \"bytes32\" }],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"settle\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"roundId\", type: \"bytes32\" },\n { name: \"winners\", type: \"address[]\" },\n { name: \"amounts\", type: \"uint256[]\" },\n ],\n outputs: [],\n },\n {\n type: \"function\",\n name: \"getRound\",\n stateMutability: \"view\",\n inputs: [{ name: \"roundId\", type: \"bytes32\" }],\n outputs: [\n { name: \"state\", type: \"uint8\" },\n { name: \"series\", type: \"bytes32\" },\n { name: \"entry\", type: \"uint256\" },\n { name: \"pot\", type: \"uint256\" },\n { name: \"entrantCount\", type: \"uint256\" },\n { name: \"payable_\", type: \"uint256\" },\n { name: \"inheritedSeed\", type: \"uint256\" },\n { name: \"lockedAt\", type: \"uint256\" },\n ],\n },\n {\n type: \"function\",\n name: \"hasEntered\",\n stateMutability: \"view\",\n inputs: [\n { name: \"roundId\", type: \"bytes32\" },\n { name: \"identity\", type: \"bytes32\" },\n ],\n outputs: [{ type: \"bool\" }],\n },\n {\n type: \"function\",\n name: \"withdrawable\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ type: \"uint256\" }],\n },\n {\n type: \"function\",\n name: \"withdraw\",\n stateMutability: \"nonpayable\",\n inputs: [],\n outputs: [{ name: \"amount\", type: \"uint256\" }],\n },\n] as const;\n","/**\n * EIP-5792 batch primitives — ported from the proven game-hub `payEntryOnchain`\n * path (`OnchainEntry.ts`). One `wallet_sendCalls` sends `approve` + the settling\n * call as ONE atomic confirmation; the paymaster sponsors gas when configured.\n * The player sees a single Apple-Pay-style sheet.\n */\n\nimport { numberToHex } from \"viem\";\nimport { InsufficientGasError, PaymentFailedError, WalletConnectionError } from \"../errors.js\";\nimport { erc20Abi } from \"./abis.js\";\nimport { encodeFunctionData } from \"viem\";\nimport type { Eip1193Provider } from \"../types.js\";\n\nexport interface Call {\n to: `0x${string}`;\n data: `0x${string}`;\n}\n\nexport type OnchainStatus = \"PENDING\" | \"CONFIRMED\" | \"FAILED\";\n\n/**\n * Send an atomic approve+call batch via EIP-5792. Returns the calls id; poll\n * {@link waitForCalls} for the terminal status.\n */\nexport async function sendCalls(\n provider: Eip1193Provider,\n from: `0x${string}`,\n chainId: number,\n calls: Call[],\n paymasterUrl?: string,\n): Promise<{ id: string }> {\n const params: Record<string, unknown> = {\n version: \"2.0.0\",\n from,\n chainId: numberToHex(chainId),\n atomicRequired: true,\n calls,\n };\n if (paymasterUrl) {\n params.capabilities = { paymasterService: { url: paymasterUrl } };\n }\n\n let result: unknown;\n try {\n result = await provider.request({ method: \"wallet_sendCalls\", params: [params] });\n } catch (e) {\n const msg = (e as { message?: string })?.message ?? String(e);\n // A user rejection or closed sheet surfaces as a wallet-connection error.\n if (/reject|denied|cancel|closed/i.test(msg)) {\n throw new WalletConnectionError(\"The player cancelled or closed the payment sheet.\", { cause: msg });\n }\n throw new PaymentFailedError(\"wallet_sendCalls failed.\", { cause: msg });\n }\n // EIP-5792 evolved: newer wallets return `{ id }`, older ones a bare string.\n const id = typeof result === \"string\" ? result : ((result as { id?: string })?.id ?? \"\");\n if (!id) throw new PaymentFailedError(\"Wallet returned no calls id.\");\n return { id };\n}\n\n/** Poll EIP-5792 calls status until terminal or timeout, then map to our status. */\nexport async function waitForCalls(\n provider: Eip1193Provider,\n id: string,\n timeoutMs = 60_000,\n): Promise<{ status: OnchainStatus; txHash?: `0x${string}` }> {\n if (!id) return { status: \"FAILED\" };\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const res = (await provider.request({\n method: \"wallet_getCallsStatus\",\n params: [id],\n })) as { status?: number | string; receipts?: { transactionHash?: `0x${string}` }[] } | null;\n const s = String(res?.status ?? \"\").toUpperCase();\n const txHash = res?.receipts?.[0]?.transactionHash;\n if (s === \"200\" || s === \"CONFIRMED\" || s === \"SUCCESS\") return { status: \"CONFIRMED\", txHash };\n if (s === \"400\" || s === \"500\" || s === \"FAILED\" || s === \"REVERTED\") return { status: \"FAILED\", txHash };\n await new Promise((r) => setTimeout(r, 900));\n }\n return { status: \"PENDING\" };\n}\n\n/** Encode an ERC-20 approve calldata. */\nexport function encodeApprove(spender: `0x${string}`, amountUnits: bigint): `0x${string}` {\n return encodeFunctionData({ abi: erc20Abi, functionName: \"approve\", args: [spender, amountUnits] });\n}\n\n/** Base mainnet / unknown L2 — comfortable floor (~0.0002 ETH). */\nexport const GAS_FLOOR_WEI_DEFAULT = 200_000_000_000_000n;\n/**\n * Base Sepolia (84532) — lower floor (~0.00005 ETH). Gate B BB-GATEB-003: wallets\n * with ~0.0002 ETH could still mine approve+pay on Sepolia but tripped the old\n * mainnet-sized floor after dust gas spends left them at 0.00019….\n */\nexport const GAS_FLOOR_WEI_BASE_SEPOLIA = 50_000_000_000_000n;\n/** chainId for Base Sepolia. */\nexport const CHAIN_ID_BASE_SEPOLIA = 84532;\n\n/** Pick the gas pre-check floor for a chain. Override with explicit `minWei` if needed. */\nexport function gasFloorWei(chainId: number): bigint {\n return chainId === CHAIN_ID_BASE_SEPOLIA ? GAS_FLOOR_WEI_BASE_SEPOLIA : GAS_FLOOR_WEI_DEFAULT;\n}\n\n/**\n * Low-ETH pre-check for `gas: \"player\"` (spec §7). Reads the player's native ETH\n * balance and throws {@link InsufficientGasError} BEFORE building a doomed tx.\n * Uses the wallet's own `eth_getBalance` so no separate RPC is needed.\n *\n * Floor is chain-aware (Base Sepolia is lower — BB-GATEB-003). Pass `minWei` to\n * override. Comparison is strict `<` so balance === floor is allowed.\n */\nexport async function assertEnoughGas(\n provider: Eip1193Provider,\n from: `0x${string}`,\n minWei?: bigint,\n): Promise<void> {\n let floor = minWei;\n if (floor === undefined) {\n let chainId = 0;\n try {\n const hex = (await provider.request({ method: \"eth_chainId\", params: [] })) as string;\n chainId = Number(BigInt(hex));\n } catch {\n /* fall through to default floor */\n }\n floor = gasFloorWei(chainId);\n }\n let balance: bigint;\n try {\n const hex = (await provider.request({ method: \"eth_getBalance\", params: [from, \"latest\"] })) as string;\n balance = BigInt(hex);\n } catch {\n return; // If we can't read it, don't block — the tx will surface a real error.\n }\n if (balance < floor) {\n throw new InsufficientGasError({\n balanceWei: balance.toString(),\n minWei: floor.toString(),\n });\n }\n}\n","/**\n * Builders for the two settling calls. Both mirror the proven entry batch:\n * [approve(spender, amount), settle(...)] sent atomically via EIP-5792.\n */\n\nimport { encodeFunctionData, keccak256, toBytes } from \"viem\";\nimport { playmosPayAbi, prizePoolAbi } from \"./abis.js\";\nimport { encodeApprove, type Call } from \"./batch.js\";\n\n/** The server derives these identically (keccak256 of UTF-8 bytes) so the\n * off-chain record and the on-chain call line up. */\nexport const toBytes32 = (s: string): `0x${string}` => keccak256(toBytes(s));\n\n/** External-studio IAP: approve USDC → PlaymosPay, then PlaymosPay.pay(). */\nexport function buildIapCalls(args: {\n usdc: `0x${string}`;\n playmosPay: `0x${string}`;\n paymentId: string;\n studio: `0x${string}`;\n amountUnits: bigint;\n}): Call[] {\n const payData = encodeFunctionData({\n abi: playmosPayAbi,\n functionName: \"pay\",\n args: [toBytes32(args.paymentId), args.studio, args.amountUnits],\n });\n return [\n { to: args.usdc, data: encodeApprove(args.playmosPay, args.amountUnits) },\n { to: args.playmosPay, data: payData },\n ];\n}\n\n/** Skill-game entry: approve USDC → PrizePool, then PrizePool.enter(). */\nexport function buildEntryCalls(args: {\n usdc: `0x${string}`;\n prizePool: `0x${string}`;\n roundKey: string;\n identity: string;\n amountUnits: bigint;\n}): Call[] {\n const enterData = encodeFunctionData({\n abi: prizePoolAbi,\n functionName: \"enter\",\n args: [toBytes32(args.roundKey), toBytes32(args.identity)],\n });\n return [\n { to: args.usdc, data: encodeApprove(args.prizePool, args.amountUnits) },\n { to: args.prizePool, data: enterData },\n ];\n}\n\n/** Winner claim: PrizePool.withdraw() pull-payment (no approve — balance already credited). Issue #41. */\nexport function buildWithdrawCall(prizePool: `0x${string}`): Call {\n const data = encodeFunctionData({\n abi: prizePoolAbi,\n functionName: \"withdraw\",\n args: [],\n });\n return { to: prizePool, data };\n}\n","/**\n * The explicit, clearly-labeled offline unit-test helper (`new Playmos({ mock:true })`).\n *\n * Instant, deterministic, no network, no chain — for a studio's CI. Crucially it\n * is NOT the sandbox and NOT the default, and it never emits a synthetic\n * `\"mocked\"` status (the P0 finding #340). Mock results carry `mock: true` and\n * use the REAL status union, so test code exercises the same shape as production.\n */\n\nimport { computeIapSplit, computePoolSplit, formatMicroToUsd } from \"./money.js\";\nimport { prefixedId } from \"./ids.js\";\nimport type { Network, Payment } from \"./types.js\";\n\nconst MOCK_TX = \"0x000000000000000000000000000000000000000000000000000000000000mock\" as `0x${string}`;\n\nexport function mockIapPayment(args: {\n amountMicro: bigint;\n feeBps: number;\n sku: string;\n playerId: string;\n chain: Network;\n metadata?: Record<string, string>;\n}): Payment {\n const { feeMicro, netMicro } = computeIapSplit(args.amountMicro, args.feeBps);\n return {\n id: prefixedId(\"pay\"),\n status: \"confirmed\",\n kind: \"iap\",\n amount: formatMicroToUsd(args.amountMicro),\n fee: formatMicroToUsd(feeMicro),\n net: formatMicroToUsd(netMicro),\n sku: args.sku,\n playerId: args.playerId,\n txHash: MOCK_TX,\n chain: args.chain,\n createdAt: new Date().toISOString(),\n metadata: args.metadata,\n mock: true,\n };\n}\n\nexport function mockEntryPayment(args: {\n amountMicro: bigint;\n poolBps: number;\n seedBps: number;\n rakeBps: number;\n gameId: string;\n roundId: string;\n playerId: string;\n chain: Network;\n metadata?: Record<string, string>;\n /**\n * B2 / hub kit: exact on-chain round key the server will hasEntered.\n * When set, MUST appear on the returned Payment.roundKey (issue #204).\n * Defaults to roundId only when the caller did not pin a key.\n */\n roundKey?: string;\n /** B2: exact identity (e.g. wallet#nonce) for hasEntered. */\n identity?: string;\n}): Payment {\n const { poolMicro, seedMicro, rakeMicro } = computePoolSplit(\n args.amountMicro,\n args.poolBps,\n args.seedBps,\n args.rakeBps,\n );\n // Honor pinned roundKey when provided — never silently drop B2 pins (#204).\n const roundKey = args.roundKey && args.roundKey.trim() !== \"\" ? args.roundKey : args.roundId;\n return {\n id: prefixedId(\"entry\"),\n status: \"confirmed\",\n kind: \"entry\",\n amount: formatMicroToUsd(args.amountMicro),\n fee: formatMicroToUsd(rakeMicro), // the 10% take\n net: formatMicroToUsd(poolMicro + seedMicro), // escrowed to the pool\n split: {\n pool: formatMicroToUsd(poolMicro),\n seed: formatMicroToUsd(seedMicro),\n rake: formatMicroToUsd(rakeMicro),\n },\n gameId: args.gameId,\n roundId: args.roundId,\n roundKey,\n identity: args.identity,\n // Deterministic mock pool address so claim-flow unit tests can assert shape (#41).\n prizePoolAddress: \"0x0000000000000000000000000000000000000001\" as `0x${string}`,\n playerId: args.playerId,\n txHash: MOCK_TX,\n chain: args.chain,\n createdAt: new Date().toISOString(),\n metadata: args.metadata,\n mock: true,\n };\n}\n\n/** Offline verify shape for mock payments — real status union, no network (#204). */\nexport function mockVerifyResult(payment: Payment): Payment & { mock: true } {\n return { ...payment, mock: true };\n}\n","/**\n * x402 helpers — Phase 4 P3 (#153).\n *\n * Pure builders for studios that mint their own HTTP 402 responses on Playmos\n * rails, plus the wire-shape types the SDK client uses for\n * `playmos.x402.challenge` / `fulfill` / `pay`.\n *\n * V1 routes (ADR): `POST /v1/x402/challenges` + `POST /v1/x402/settle` only.\n * Resource-style URLs are **not** in V1 — `pay({ payTo, amount })` wraps those\n * two calls. See `docs/design/PHASE-4-X402-ADR.md`.\n *\n * Honesty: V1 is an **x402-shaped** API (headers + PaymentRequirement +\n * Playmos payload rules). Stock TransferWithAuthorization settle is wired\n * behind #161 Option B (CREATE2 splitter); claim language stays \"x402-shaped\"\n * until Gate X X3b is green with a BaseScan hash.\n */\n\nimport type { Network } from \"./types.js\";\nimport type { PaymentRequirement } from \"./settlement.js\";\nimport { ConfigError, MissingFieldError } from \"./errors.js\";\nimport { parseUsdToMicro } from \"./money.js\";\n\n// ─── Wire shapes ─────────────────────────────────────────────────────────────\n\n/** x402-shaped PAYMENT-REQUIRED object (wire matrix §4) with Playmos extensions. */\nexport interface X402PaymentRequired {\n scheme: \"exact\";\n /** CAIP-2 network id (`eip155:84532` for Base Sepolia). */\n network: string;\n /** Atomic USDC (6 dp) as a decimal string. */\n maxAmountRequired: string;\n asset: string;\n payTo: `0x${string}`;\n /**\n * Stock-client EIP-712 domain + Playmos seller hint (#161).\n * `name` / `version` are read from the live USDC token — never hardcoded.\n */\n extra?: {\n name: string;\n version: string;\n playmosSeller?: string;\n playmosRequirementId?: string;\n };\n /** Required Playmos extension — settlement idempotency anchor. */\n playmosRequirementId: string;\n /** USD decimal string (Playmos money convention). */\n amount: string;\n playmosNetwork: Network;\n expiresAt: string;\n terms?: string | null;\n feeBps?: number | null;\n feeSink?: string | null;\n /** Economic seller when `payTo` is a CREATE2 clone address (#161). */\n playmosSeller?: string;\n}\n\n/** Input to `playmos.x402.challenge(...)` — mints a server-authoritative requirement. */\nexport interface X402ChallengeInput {\n /** Recipient wallet. */\n payTo: `0x${string}`;\n /** USD decimal string (\"0.50\"). */\n amount: string;\n /**\n * Money intent. V1 service supports `\"transfer\"` only today; `marketplace.buy`\n * is ADR D1 but lands after listing plumbing.\n */\n intent?: \"transfer\" | \"marketplace.buy\";\n /** Per-call fee bps (same model as `transfer()`). Default 0. */\n feeBps?: number;\n /** Fee destination when feeBps > 0. */\n feeSink?: `0x${string}`;\n /** Optional terms/memo. */\n terms?: string;\n /** Relative TTL ms (service default 15 min). */\n expiresInMs?: number;\n /** Supply a deterministic requirement id; else the service mints `preq_…`. */\n id?: string;\n}\n\n/** What `playmos.x402.challenge` resolves to (402 body, already success). */\nexport interface X402ChallengeResult {\n requirement: PaymentRequirement;\n paymentRequired: X402PaymentRequired;\n feeBps: number;\n feeSink: string | null;\n}\n\n/**\n * Payload modes the Playmos settle path accepts.\n * Stock modes require PLAYMOS_X402_SPLITTER_FACTORY_ADDRESS (#161 Option B).\n * Claim \"interop\" only after Gate X X3b + BaseScan hash.\n */\nexport type X402PayloadMode =\n | \"server-signer\"\n | \"eip3009-auth\"\n | \"tx-hash\"\n | \"transfer-with-authorization\"\n | \"x402-exact-stock\";\n\n/** Authorization body for `playmos.x402.fulfill` / settle. */\nexport interface X402FulfillAuthorization {\n mode?: X402PayloadMode;\n /** Payer address. Optional for server-signer (service fills sandbox signer). */\n from?: `0x${string}`;\n /** Optional; if set must match the server-minted challenge (fee authority). */\n feeBps?: number;\n feeSink?: `0x${string}`;\n /** EIP-3009 ReceiveWithAuthorization fields (mode eip3009-auth). */\n authorization?: Record<string, unknown>;\n /** Prior broadcast tx (mode tx-hash). */\n txHash?: `0x${string}`;\n /** Extra opaque fields forwarded into the payload. */\n [key: string]: unknown;\n}\n\n/** Result of `playmos.x402.fulfill` / `pay`. */\nexport interface X402SettleResult {\n requirementId: string;\n status: \"settled\" | \"pending\" | \"failed\" | string;\n txHash?: `0x${string}` | null;\n idempotentReplay: boolean;\n verifiedVia?: string;\n feeBps: number;\n fee: string;\n net: string;\n requirement: PaymentRequirement;\n success: boolean;\n}\n\n/**\n * One-shot helper input — sequences challenge + settle.\n *\n * **Not** a resource URL. ADR locks V1 senior DX as:\n * `playmos.x402.pay({ payTo, amount, … })`\n * wrapping `POST /v1/x402/challenges` then `POST /v1/x402/settle`.\n * Resource-style `pay({ url })` is deferred V1.1+.\n */\nexport interface X402PayInput extends X402ChallengeInput {\n /**\n * Settle mode. Defaults to `\"server-signer\"` (sandbox convenience).\n * Required on the wire; the SDK always sends an explicit mode (fail-closed).\n */\n mode?: X402PayloadMode;\n /** Payer when not using server-signer default. */\n from?: `0x${string}`;\n /** EIP-3009 auth blob when mode is eip3009-auth. */\n authorization?: Record<string, unknown>;\n /** Prior tx when mode is tx-hash. */\n txHash?: `0x${string}`;\n}\n\n// ─── Pure helpers (studio server + client shared) ────────────────────────────\n\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\n\nfunction requireAddress(value: unknown, field: string): `0x${string}` {\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new MissingFieldError(field);\n }\n if (!ADDRESS_RE.test(value)) {\n throw new ConfigError(`${field} must be a 0x-prefixed 20-byte address, got: ${JSON.stringify(value)}`, {\n field,\n value,\n });\n }\n return value.toLowerCase() as `0x${string}`;\n}\n\n/** Map Playmos network enum → CAIP-2 (wire matrix). */\nexport function networkToCaip2(network: Network): string {\n if (network === \"base\") return \"eip155:8453\";\n if (network === \"base-sepolia\") return \"eip155:84532\";\n throw new ConfigError(`Unknown network for x402: ${JSON.stringify(network)}`, { network });\n}\n\n/**\n * Playmos {@link PaymentRequirement} → x402-shaped PAYMENT-REQUIRED object.\n * Mirrors `service/src/routes/x402.ts` `toX402PaymentRequired` so studio-minted\n * challenges match the official service shape.\n */\nexport function toX402PaymentRequired(\n req: PaymentRequirement,\n extras?: { feeBps?: number; feeSink?: string | null },\n): X402PaymentRequired {\n const amountMicro = parseUsdToMicro(req.amount);\n const out: X402PaymentRequired = {\n scheme: \"exact\",\n network: networkToCaip2(req.network),\n maxAmountRequired: amountMicro.toString(),\n // Service V1 emits the asset symbol; address is implied by network + config.\n asset: \"USDC\",\n payTo: req.payTo,\n playmosRequirementId: req.id,\n amount: req.amount,\n playmosNetwork: req.network,\n expiresAt: req.expiresAt,\n terms: req.terms ?? null,\n feeBps: extras?.feeBps ?? null,\n feeSink: extras?.feeSink ?? null,\n };\n return out;\n}\n\n/** UTF-8 JSON → base64 (browser + Node). */\nexport function encodePaymentHeader(obj: unknown): string {\n const json = JSON.stringify(obj);\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(json, \"utf8\").toString(\"base64\");\n }\n const bytes = new TextEncoder().encode(json);\n let bin = \"\";\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]!);\n return btoa(bin);\n}\n\n/** Base64 JSON header → object. Throws ConfigError on bad input. */\nexport function decodePaymentHeader(header: string): unknown {\n if (typeof header !== \"string\" || header.trim() === \"\") {\n throw new ConfigError(\"payment header must be a non-empty base64 JSON string\");\n }\n try {\n let json: string;\n if (typeof Buffer !== \"undefined\") {\n json = Buffer.from(header, \"base64\").toString(\"utf8\");\n } else {\n const bin = atob(header);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n json = new TextDecoder().decode(bytes);\n }\n return JSON.parse(json);\n } catch (err) {\n throw new ConfigError(\"invalid base64 JSON payment header\", {\n cause: err instanceof Error ? err.message : String(err),\n });\n }\n}\n\n/**\n * Studio server helper: build a 402 Payment Required response for a Playmos\n * {@link PaymentRequirement}. Use this when your API challenges buyers and\n * Playmos settles via `POST /v1/x402/settle` (or `playmos.x402.fulfill`).\n *\n * Does **not** hit the network — pure. For official mint + fee authority, prefer\n * `playmos.x402.challenge` (server-persisted challenge store).\n *\n * @example\n * ```ts\n * import { createPaymentRequirement, createX402Challenge } from \"@playmos/sdk\";\n *\n * const requirement = createPaymentRequirement({\n * payTo: \"0x…\", amount: \"0.50\", network: \"base-sepolia\",\n * });\n * const challenge = createX402Challenge(requirement, { feeBps: 0 });\n * // res.status(402).set(challenge.headers).json(challenge.body)\n * ```\n */\nexport function createX402Challenge(\n requirement: PaymentRequirement,\n extras?: { feeBps?: number; feeSink?: string | null },\n): {\n status: 402;\n headers: { \"PAYMENT-REQUIRED\": string; \"Content-Type\": string };\n body: {\n error: { code: \"payment_required\"; message: string };\n requirement: PaymentRequirement;\n paymentRequired: X402PaymentRequired;\n feeBps: number;\n feeSink: string | null;\n };\n paymentRequired: X402PaymentRequired;\n} {\n if (!requirement || typeof requirement !== \"object\") {\n throw new ConfigError(\"createX402Challenge requires a PaymentRequirement\");\n }\n if (typeof requirement.id !== \"string\" || !requirement.id.startsWith(\"preq_\")) {\n throw new ConfigError('PaymentRequirement.id must be a \"preq_…\" string', { id: requirement.id });\n }\n requireAddress(requirement.payTo, \"payTo\");\n parseUsdToMicro(requirement.amount);\n\n const feeBps = extras?.feeBps ?? 0;\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(\n `feeBps must be an integer in [0, 10000], got: ${JSON.stringify(extras?.feeBps)}`,\n { feeBps: extras?.feeBps },\n );\n }\n const feeSink = extras?.feeSink ?? null;\n if (feeBps > 0 && feeSink) requireAddress(feeSink, \"feeSink\");\n\n const paymentRequired = toX402PaymentRequired(requirement, { feeBps, feeSink });\n return {\n status: 402,\n headers: {\n \"PAYMENT-REQUIRED\": encodePaymentHeader(paymentRequired),\n \"Content-Type\": \"application/json\",\n },\n body: {\n error: { code: \"payment_required\", message: \"Payment Required\" },\n requirement,\n paymentRequired,\n feeBps,\n feeSink,\n },\n paymentRequired,\n };\n}\n\n/** Client-side validation shared by challenge / pay (throws before network). */\nexport function validateX402ChallengeInput(input: X402ChallengeInput): {\n payTo: `0x${string}`;\n amount: string;\n intent: \"transfer\" | \"marketplace.buy\";\n feeBps: number;\n feeSink?: `0x${string}`;\n terms?: string;\n expiresInMs?: number;\n id?: string;\n} {\n if (!input || typeof input !== \"object\") {\n throw new ConfigError(\"x402 challenge input is required\");\n }\n // Resource-URL surface is deferred (ADR) — fail loud if callers pass the old sketch.\n if (\"url\" in (input as object) && (input as { url?: unknown }).url !== undefined) {\n throw new ConfigError(\n 'playmos.x402 does not accept { url } in V1 — use pay({ payTo, amount }) wrapping challenges+settle (ADR: resource URLs deferred V1.1+). See docs/design/PHASE-4-X402-ADR.md.',\n { field: \"url\" },\n );\n }\n const payTo = requireAddress(input.payTo, \"payTo\");\n parseUsdToMicro(input.amount); // InvalidAmountError\n const intent = input.intent ?? \"transfer\";\n if (intent !== \"transfer\" && intent !== \"marketplace.buy\") {\n throw new ConfigError(\n `x402 intent must be \"transfer\" or \"marketplace.buy\", got: ${JSON.stringify(input.intent)}`,\n { intent: input.intent },\n );\n }\n const feeBps = input.feeBps ?? 0;\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(\n `feeBps must be an integer in [0, 10000], got: ${JSON.stringify(input.feeBps)}`,\n { feeBps: input.feeBps },\n );\n }\n const feeSink =\n input.feeSink === undefined ? undefined : requireAddress(input.feeSink, \"feeSink\");\n return {\n payTo,\n amount: input.amount,\n intent,\n feeBps,\n ...(feeSink !== undefined ? { feeSink } : {}),\n ...(input.terms !== undefined ? { terms: input.terms } : {}),\n ...(input.expiresInMs !== undefined ? { expiresInMs: input.expiresInMs } : {}),\n ...(input.id !== undefined ? { id: input.id } : {}),\n };\n}\n","/**\n * The Playmos client — `new Playmos({ apiKey })` → `pay()`, `enterRound()`,\n * `verify()`, `webhooks`, `payouts`, `agents`.\n *\n * Real behavior, no `\"mocked\"` status anywhere. The chain calls use the proven\n * EIP-5792 approve+call batch; `verify()` resolves by the service's on-chain\n * read; ids are ULIDs; inputs are validated client-side; idempotency is honored.\n */\n\nimport { encodeFunctionData, decodeFunctionResult } from \"viem\";\nimport {\n ApiError,\n ConfigError,\n MissingFieldError,\n NothingToWithdrawError,\n PaymentFailedError,\n} from \"./errors.js\";\nimport { resolveEnv, USDC_ADDRESS, type ResolvedEnv } from \"./config.js\";\nimport { prefixedId } from \"./ids.js\";\nimport { requireField, validateAmount, validateMetadata } from \"./validation.js\";\nimport { computeIapSplit, computePoolSplit, formatMicroToUsd } from \"./money.js\";\nimport { createHttpClient, type HttpClient } from \"./http.js\";\nimport { resolveProvider, getAccount, walletAvailable } from \"./wallet.js\";\nimport { assertEnoughGas, sendCalls, waitForCalls } from \"./chain/batch.js\";\nimport { buildIapCalls, buildEntryCalls, buildWithdrawCall } from \"./chain/calls.js\";\nimport { prizePoolAbi } from \"./chain/abis.js\";\nimport { mockIapPayment, mockEntryPayment, mockVerifyResult } from \"./mock.js\";\nimport { validateX402ChallengeInput } from \"./x402.js\";\nimport type {\n X402ChallengeInput,\n X402ChallengeResult,\n X402FulfillAuthorization,\n X402PayInput,\n X402SettleResult,\n} from \"./x402.js\";\nimport type { PaymentRequirement, X402PayloadAuthorization } from \"./settlement.js\";\nimport type {\n AgentWallet,\n AgentFundResult,\n EnterRoundInput,\n EscrowHoldInput,\n EscrowHoldResult,\n EscrowResolveResult,\n Listing,\n MarketplaceListInput,\n MarketplaceGetResult,\n MarketplaceSaleResult,\n Payment,\n PayInput,\n PlaymosConfig,\n PrizeBalance,\n RoundOpenInput,\n RoundSettleInput,\n RoundState,\n SettleRoundResult,\n TransferConfirmOptions,\n TransferInput,\n TransferReconcile,\n TransferResult,\n VerifyResult,\n WaitOptions,\n WebhookEvent,\n WithdrawResult,\n} from \"./types.js\";\n\n/** Fee tiers, keyed to who owns the game (spec §4). Contract-enforced on-chain;\n * these are the SDK's faithful preview of the split. */\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\n\n/** Validate a required 0x-address field (transfer from/to/feeSink), or throw a typed ConfigError. */\nfunction requireAddressField(value: unknown, field: string): `0x${string}` {\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new MissingFieldError(field);\n }\n if (!ADDRESS_RE.test(value)) {\n throw new ConfigError(\n `${field} must be a 0x-prefixed 20-byte wallet address (Phase 1a transfers settle server-held wallets), got: ${JSON.stringify(value)}`,\n { field, value },\n );\n }\n return value.toLowerCase() as `0x${string}`;\n}\n\n/** An identity field on a transfer: a raw 0x address (validated) OR a game NPC id (the service resolves it). */\nfunction partyRef(value: unknown, field: string): string {\n if (typeof value !== \"string\" || value.trim() === \"\") throw new MissingFieldError(field);\n if (value.startsWith(\"0x\")) return requireAddressField(value, field);\n return value; // an NPC id — the service maps id → wallet\n}\n\nconst IAP_FEE_BPS = 100; // external studios → 1%\nconst POOL_BPS = 6000; // 60% this round's pool\nconst SEED_BPS = 3000; // 30% next round's seed\nconst RAKE_BPS = 1000; // 10% Playmos take\n\n/**\n * Shape the service returns from POST /payments with `settle: \"server\"` — the\n * sandbox server-settle path. The service signed + submitted the on-chain txn\n * itself, so `payment` is already confirmed with a real `txHash` (no client\n * signing). Tolerant to extra fields.\n */\ninterface ServerSettleResponse {\n payment: Payment & { splitBps?: { pool: number; seed: number; rake: number } };\n settledBy?: \"server\";\n signer?: `0x${string}`;\n /** Present on intent + server-settle responses — PrizePool / PlaymosPay address. */\n clientParams?: CreateIntentResponse[\"clientParams\"];\n}\n\n/** Shape the service returns from POST /payments. Tolerant to extra fields. */\ninterface CreateIntentResponse {\n payment: Payment;\n clientParams?: {\n contract?: \"playmosPay\" | \"prizePool\";\n contractAddress?: `0x${string}`;\n usdc?: `0x${string}`;\n // The service emits `amountMicro`; older shapes used `amountUnits`. Accept both.\n amountUnits?: string;\n amountMicro?: string;\n studio?: `0x${string}`;\n /** Server payment id — keccak256'd on-chain; must match verifyIap expected id. */\n paymentId?: string;\n // Service emits roundId + roundKey (same string) + identity — byte-identical\n // to hasEntered args after keccak256 (integration seam #3 / #345).\n roundKey?: string;\n roundId?: string;\n identity?: string;\n paymasterUrl?: string;\n };\n}\n\nexport class Playmos {\n readonly config: PlaymosConfig;\n readonly env: ResolvedEnv;\n private readonly http: HttpClient;\n\n /**\n * Webhook helpers. Signature verification is **server-only** (Node `crypto`) and\n * lives on `@playmos/sdk/server` so browser bundlers never see `node:crypto` (#9).\n *\n * import { verifyWebhook } from \"@playmos/sdk/server\";\n * const event = verifyWebhook(rawBody, req.headers[\"x-playmos-signature\"], secret);\n */\n readonly webhooks = {\n /**\n * @deprecated Use `import { verifyWebhook } from \"@playmos/sdk/server\"` instead.\n * Throws if called — kept as a discoverable pointer so call sites fail loudly\n * with a fix instruction rather than a silent missing method.\n */\n verify: (\n _rawBody: string | Buffer,\n _signatureHeader: string | string[] | undefined,\n _secret: string,\n ): WebhookEvent => {\n throw new ConfigError(\n 'playmos.webhooks.verify is server-only and no longer ships in the browser entry (issue #9). Use: import { verifyWebhook } from \"@playmos/sdk/server\"',\n { entry: \"@playmos/sdk/server\" },\n );\n },\n };\n\n readonly payouts = {\n /** Choose how the studio is paid: \"usdc\" (default) or \"fiat\" (Bridge). */\n setMode: (mode: \"usdc\" | \"fiat\"): Promise<{ mode: \"usdc\" | \"fiat\" }> =>\n this.http.post(\"/payouts/mode\", { mode }),\n /** Create a Bridge KYC onboarding link (fiat payout). */\n createOnboardingLink: (): Promise<{ url: string }> =>\n this.http.post(\"/payouts/onboarding_link\", {}),\n };\n\n /**\n * `x402` — Phase 4 HTTP 402 / x402-shaped adapter (#153).\n *\n * V1 surface (ADR):\n * - `challenge` → `POST /v1/x402/challenges` (returns 402; treated as success)\n * - `fulfill` → `POST /v1/x402/settle`\n * - `pay` → challenge then fulfill (senior DX ≤15 lines)\n *\n * **Not** resource URLs (`pay({ url })` is V1.1+). **Not** stock third-party\n * x402 client interop (X3b deferred until #161). Requires `sk_test_` +\n * Base Sepolia; flag `PLAYMOS_X402_ENABLED` on the service.\n *\n * ```ts\n * const playmos = new Playmos({ apiKey: process.env.PLAYMOS_SK!, network: \"base-sepolia\" });\n * const result = await playmos.x402.pay({\n * payTo: \"0x…\",\n * amount: \"0.50\",\n * feeBps: 0,\n * });\n * // result.txHash → BaseScan\n * ```\n */\n readonly x402 = {\n /**\n * Mint a server-authoritative PaymentRequirement (HTTP 402).\n * Fee terms are stored server-side — settle rejects payload disagreement.\n */\n challenge: async (input: X402ChallengeInput): Promise<X402ChallengeResult> => {\n this.assertX402Allowed();\n const body = validateX402ChallengeInput(input);\n // Service currently supports transfer only; fail client-side for marketplace.buy\n // until listing plumbing lands (ADR D1 includes it; service returns 400 today).\n if (body.intent === \"marketplace.buy\") {\n throw new ConfigError(\n 'x402 challenge intent \"marketplace.buy\" is not supported yet (V1 service: \"transfer\" only; marketplace.buy follows).',\n { intent: body.intent },\n );\n }\n const res = await this.http.post<{\n requirement: PaymentRequirement;\n paymentRequired: X402ChallengeResult[\"paymentRequired\"];\n feeBps: number;\n feeSink: string | null;\n }>(\"/x402/challenges\", body, { acceptStatuses: [402] });\n return {\n requirement: res.requirement,\n paymentRequired: res.paymentRequired,\n feeBps: res.feeBps ?? body.feeBps,\n feeSink: res.feeSink ?? body.feeSink ?? null,\n };\n },\n\n /**\n * Settle a previously minted challenge with an `x402-payload` authorization.\n * Defaults mode to `server-signer` when omitted (explicit on the wire — fail-closed\n * materialize still requires mode; the route also defaults for this path).\n */\n fulfill: async (\n requirement: PaymentRequirement,\n authorization?: X402FulfillAuthorization | X402PayloadAuthorization,\n ): Promise<X402SettleResult> => {\n this.assertX402Allowed();\n if (!requirement || typeof requirement !== \"object\") {\n throw new ConfigError(\"fulfill requires a PaymentRequirement from challenge()\");\n }\n if (typeof requirement.id !== \"string\" || requirement.id.trim() === \"\") {\n throw new MissingFieldError(\"requirement.id\");\n }\n\n let payload: Record<string, unknown>;\n if (authorization && typeof authorization === \"object\" && \"kind\" in authorization) {\n const a = authorization as X402PayloadAuthorization;\n if (a.kind !== \"x402-payload\") {\n throw new ConfigError('authorization.kind must be \"x402-payload\"', { kind: a.kind });\n }\n payload = { ...(a.payload ?? {}) };\n } else {\n payload = { ...((authorization as X402FulfillAuthorization | undefined) ?? {}) };\n }\n // Fee terms are server-authoritative (challenge store). Strip caller fee fields so\n // fulfill matches pay() — never forward dead/mismatch bait (A residual NIT on #164).\n delete payload.feeBps;\n delete payload.feeSink;\n // Mode: default server-signer only for empty Playmos helper payloads.\n // Never invent mode when nested auth/signature is present (stock shape) — that would\n // greenwash interop (A residual #166 RED). Route also fails closed without explicit mode.\n if (payload.mode === undefined || (typeof payload.mode === \"string\" && payload.mode.trim() === \"\")) {\n const hasNestedAuth =\n payload.authorization !== undefined ||\n payload.signature !== undefined ||\n payload.paymentPayload !== undefined;\n if (hasNestedAuth) {\n throw new ConfigError(\n 'fulfill: payload.mode is required when authorization/signature is present — stock-shaped payloads are not auto-mapped to server-signer (V1: no interop; set mode explicitly or see #161)',\n { field: \"mode\" },\n );\n }\n payload.mode = \"server-signer\";\n }\n if (payload.scheme === undefined) payload.scheme = \"exact\";\n if (payload.requirementId === undefined) payload.requirementId = requirement.id;\n\n const res = await this.http.post<{\n settlement: {\n success: boolean;\n requirementId: string;\n status: string;\n txHash?: `0x${string}` | null;\n idempotentReplay: boolean;\n verifiedVia?: string;\n feeBps: number;\n fee: string;\n net: string;\n };\n requirement: PaymentRequirement;\n }>(\"/x402/settle\", {\n requirement,\n authorization: { kind: \"x402-payload\", payload },\n });\n\n const s = res.settlement;\n return {\n requirementId: s.requirementId,\n status: s.status,\n txHash: s.txHash ?? null,\n idempotentReplay: Boolean(s.idempotentReplay),\n verifiedVia: s.verifiedVia,\n feeBps: s.feeBps,\n fee: s.fee,\n net: s.net,\n requirement: res.requirement,\n success: s.success,\n };\n },\n\n /**\n * Senior DX: mint challenge + settle in one call.\n * Wraps challenges + settle only — **not** `pay({ url })` (ADR).\n */\n pay: async (input: X402PayInput): Promise<X402SettleResult> => {\n this.assertX402Allowed();\n // validate early (includes { url } rejection) before either network call\n validateX402ChallengeInput(input);\n const challenge = await this.x402.challenge(input);\n // Do not echo feeBps/feeSink into the payload — server challenge is authoritative.\n // Only pass mode/from/auth fields the payer controls.\n const auth: X402FulfillAuthorization = {\n mode: input.mode ?? \"server-signer\",\n };\n if (input.from !== undefined) auth.from = input.from;\n if (input.authorization !== undefined) auth.authorization = input.authorization;\n if (input.txHash !== undefined) auth.txHash = input.txHash;\n return this.x402.fulfill(challenge.requirement, auth);\n },\n };\n\n /**\n * Skill/contest **round lifecycle** (issue #13) — closes the enterRound loop.\n *\n * Scores never leave the studio. Flow:\n * rounds.open → players enterRound → studio scores → rounds.lock →\n * rounds.settle({ ranking }) → contract pays winners.\n *\n * Operator txs are signed by the Playmos service (OPERATOR_ROLE key).\n */\n /** Offline mock store for rounds.open/lock/settle/get when `mock: true` (3-game dogfood). */\n private readonly mockRounds = new Map<string, RoundState>();\n\n readonly rounds = {\n open: async (input: RoundOpenInput): Promise<RoundState> => {\n requireField(input?.gameId, \"gameId\");\n requireField(input?.roundId, \"roundId\");\n requireField(input?.entryAmount, \"entryAmount\");\n if (!input?.payout || typeof input.payout !== \"object\") {\n throw new ConfigError(\"payout rule is required (winner-take-all | top-n | custom)\");\n }\n validateAmount(input.entryAmount);\n if (this.config.mock) {\n const roundKey = input.roundKey ?? input.roundId;\n const existing = this.mockRounds.get(input.roundId);\n if (existing?.status === \"open\" || existing?.status === \"locked\") {\n // Idempotent — mirrors service store + SeriesRoundActive graceful path.\n return existing;\n }\n if (existing?.status === \"settled\") {\n throw new ApiError(`round ${input.roundId} already settled`, {\n status: 409,\n code: \"conflict\",\n });\n }\n const round: RoundState = {\n roundId: input.roundId,\n gameId: input.gameId,\n roundKey,\n status: \"open\",\n entryAmount: input.entryAmount,\n pool: null,\n entrants: 0,\n payout: input.payout,\n closeAt: input.closeAt,\n openTxHash:\n \"0x000000000000000000000000000000000000000000000000000000000000mock\" as `0x${string}`,\n prizePoolAddress:\n (this.config.contracts?.prizePool as `0x${string}` | undefined) ??\n (\"0x0000000000000000000000000000000000000002\" as `0x${string}`),\n };\n this.mockRounds.set(input.roundId, round);\n return round;\n }\n const { round } = await this.http.post<{ round: RoundState }>(\"/rounds\", {\n gameId: input.gameId,\n roundId: input.roundId,\n entryAmount: input.entryAmount,\n payout: input.payout,\n closeAt: input.closeAt,\n seriesKey: input.seriesKey,\n roundKey: input.roundKey,\n });\n return round;\n },\n lock: async (input: { roundId: string; gameId?: string }): Promise<RoundState> => {\n requireField(input?.roundId, \"roundId\");\n if (this.config.mock) {\n const existing = this.mockRounds.get(input.roundId);\n if (!existing) {\n throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: \"not_found\" });\n }\n if (existing.status === \"locked\" || existing.status === \"settled\") return existing;\n if (existing.status !== \"open\") {\n throw new ApiError(`round ${input.roundId} is not open (status=${existing.status})`, {\n status: 409,\n code: \"conflict\",\n });\n }\n const locked: RoundState = {\n ...existing,\n status: \"locked\",\n // Mock payable pool ≈ 60% of entry × max(1, entrants) for shape only — not money truth.\n pool: existing.pool ?? existing.entryAmount,\n entrants: existing.entrants ?? 0,\n lockTxHash:\n \"0x000000000000000000000000000000000000000000000000000000000000loc1\" as `0x${string}`,\n };\n this.mockRounds.set(input.roundId, locked);\n return locked;\n }\n const { round } = await this.http.post<{ round: RoundState }>(\n `/rounds/${encodeURIComponent(input.roundId)}/lock`,\n { gameId: input.gameId },\n );\n return round;\n },\n settle: async (input: RoundSettleInput): Promise<SettleRoundResult> => {\n requireField(input?.roundId, \"roundId\");\n if (!input?.results) throw new ConfigError(\"results are required (ranking or winners)\");\n if (this.config.mock) {\n const existing = this.mockRounds.get(input.roundId);\n if (!existing) {\n throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: \"not_found\" });\n }\n if (existing.status === \"settled\" && existing.settleTxHash) {\n return {\n roundId: input.roundId,\n txHash: existing.settleTxHash,\n poolPaid: existing.pool ?? \"0\",\n winners:\n \"winners\" in input.results\n ? input.results.winners\n : input.results.ranking.map((wallet) => ({\n wallet,\n amount: existing.pool ?? existing.entryAmount,\n })),\n status: \"settled\",\n };\n }\n if (existing.status !== \"locked\" && existing.status !== \"open\") {\n throw new ApiError(`round ${input.roundId} cannot settle (status=${existing.status})`, {\n status: 409,\n code: \"conflict\",\n });\n }\n const winners =\n \"winners\" in input.results\n ? input.results.winners\n : input.results.ranking.map((wallet, i) => ({\n wallet,\n // Winner-take-all mock shape when ranking only.\n amount: i === 0 ? (existing.pool ?? existing.entryAmount) : \"0\",\n }));\n const settleTxHash =\n \"0x000000000000000000000000000000000000000000000000000000000000set1\" as `0x${string}`;\n const poolPaid = existing.pool ?? existing.entryAmount;\n const settled: RoundState = {\n ...existing,\n status: \"settled\",\n settleTxHash,\n pool: poolPaid,\n };\n this.mockRounds.set(input.roundId, settled);\n return {\n roundId: input.roundId,\n txHash: settleTxHash,\n poolPaid,\n winners,\n status: \"settled\",\n };\n }\n const { settle } = await this.http.post<{ settle: SettleRoundResult }>(\n `/rounds/${encodeURIComponent(input.roundId)}/settle`,\n { gameId: input.gameId, results: input.results },\n );\n return settle;\n },\n get: async (input: { roundId: string }): Promise<RoundState> => {\n requireField(input?.roundId, \"roundId\");\n if (this.config.mock) {\n const existing = this.mockRounds.get(input.roundId);\n if (!existing) {\n throw new ApiError(`unknown round: ${input.roundId}`, { status: 404, code: \"not_found\" });\n }\n return existing;\n }\n const { round } = await this.http.get<{ round: RoundState }>(\n `/rounds/${encodeURIComponent(input.roundId)}`,\n );\n return round;\n },\n\n /**\n * Read a wallet's **claimable** prize balance for a round (issue #41).\n * Prefers the service chain read (`GET /v1/rounds/:id/prize?wallet=`); falls\n * back to a direct eth_call when `prizePoolAddress` is supplied and no wallet\n * connector is needed for the read path… actually uses service first, then\n * on-chain via the player's provider if the service is unavailable.\n */\n prize: async (input: {\n roundId: string;\n wallet: `0x${string}`;\n /** Optional override if you already hold the pool address from enterRound. */\n prizePoolAddress?: `0x${string}`;\n }): Promise<PrizeBalance> => {\n requireField(input?.roundId, \"roundId\");\n const wallet = requireAddressField(input?.wallet, \"wallet\");\n // 1) Service path — authoritative when rounds are operator-managed.\n try {\n const res = await this.http.get<{ prize: PrizeBalance }>(\n `/rounds/${encodeURIComponent(input.roundId)}/prize?wallet=${encodeURIComponent(wallet)}`,\n );\n return res.prize;\n } catch (e) {\n // Fall through to direct eth_call if we have an address (offline/kit path).\n if (!input.prizePoolAddress && !(e instanceof ApiError)) throw e;\n if (!input.prizePoolAddress) throw e;\n }\n const prizePoolAddress = requireAddressField(input.prizePoolAddress, \"prizePoolAddress\");\n const claimableMicro = await this.readWithdrawable(prizePoolAddress, wallet);\n return {\n roundId: input.roundId,\n prizePoolAddress,\n wallet,\n claimable: formatMicroToUsd(claimableMicro),\n claimableMicro: claimableMicro.toString(),\n };\n },\n\n /**\n * Winner **claim** — call PrizePool.withdraw() from the player's wallet (issue #41).\n * Pull-payment: credits from settle live in `withdrawable[msg.sender]`. No approve needed.\n * Pass either `prizePoolAddress` (from enterRound / rounds.get) or `roundId` (service resolves).\n */\n withdraw: async (input: {\n prizePoolAddress?: `0x${string}`;\n roundId?: string;\n /** Pre-check claimable; default true. Set false only if you already called `prize()`. */\n checkBalance?: boolean;\n }): Promise<WithdrawResult> => {\n if (this.config.mock) {\n return {\n prizePoolAddress:\n (input.prizePoolAddress as `0x${string}`) ??\n (\"0x0000000000000000000000000000000000000001\" as `0x${string}`),\n amount: \"0.00\",\n amountMicro: \"0\",\n txHash: \"0x000000000000000000000000000000000000000000000000000000000000mock\" as `0x${string}`,\n status: \"confirmed\",\n };\n }\n\n let prizePool = input.prizePoolAddress\n ? requireAddressField(input.prizePoolAddress, \"prizePoolAddress\")\n : undefined;\n if (!prizePool) {\n requireField(input?.roundId, \"roundId\");\n const round = await this.rounds.get({ roundId: input.roundId! });\n if (!round.prizePoolAddress) {\n throw new ConfigError(\n \"rounds.get did not return prizePoolAddress — pass prizePoolAddress from enterRound or configure contracts.prizePool\",\n );\n }\n prizePool = round.prizePoolAddress;\n }\n\n const provider = resolveProvider(this.config.wallet);\n if (this.config.gas?.mode === \"player\") {\n const from0 = await getAccount(provider);\n await assertEnoughGas(provider, from0);\n }\n const from = await getAccount(provider);\n\n let amountMicro = 0n;\n if (input.checkBalance !== false) {\n amountMicro = await this.readWithdrawable(prizePool, from);\n if (amountMicro === 0n) {\n throw new NothingToWithdrawError({ prizePoolAddress: prizePool, wallet: from });\n }\n }\n\n const call = buildWithdrawCall(prizePool);\n const paymasterUrl =\n this.config.gas?.mode === \"sponsored\" ? this.config.gas.paymasterUrl : undefined;\n let txHash: `0x${string}` | undefined;\n let status: WithdrawResult[\"status\"] = \"pending\";\n try {\n const { id: callsId } = await sendCalls(\n provider,\n from,\n this.env.chainId,\n [call],\n paymasterUrl,\n );\n const waited = await waitForCalls(provider, callsId);\n txHash = waited.txHash;\n status =\n waited.status === \"CONFIRMED\"\n ? \"confirmed\"\n : waited.status === \"FAILED\"\n ? \"failed\"\n : \"pending\";\n } catch (e) {\n const msg = (e as Error)?.message ?? String(e);\n if (/NothingToWithdraw|nothing to withdraw/i.test(msg)) {\n throw new NothingToWithdrawError({ prizePoolAddress: prizePool, wallet: from, cause: msg });\n }\n if (e instanceof NothingToWithdrawError || e instanceof PaymentFailedError) throw e;\n throw new PaymentFailedError(\"PrizePool.withdraw() failed.\", { cause: msg });\n }\n\n if (status === \"failed\") {\n throw new PaymentFailedError(\"PrizePool.withdraw() did not confirm on-chain.\", {\n prizePoolAddress: prizePool,\n txHash,\n });\n }\n\n // If we skipped pre-check, amount is unknown — re-read would be 0 post-claim; use pre-check value.\n if (amountMicro === 0n && input.checkBalance === false) {\n // Best-effort: amount not available without a receipt decode; leave 0 and surface tx.\n }\n\n return {\n prizePoolAddress: prizePool,\n amount: formatMicroToUsd(amountMicro),\n amountMicro: amountMicro.toString(),\n txHash,\n status,\n };\n },\n };\n\n /**\n * `agents` — assign wallets to the NPCs YOUR game already owns, so they can transact USDC in your economy.\n * The game creates the NPCs; the SDK only creates the WALLET for a game-supplied id. Engine-agnostic\n * (Unity/Unreal/Godot/web all call the same REST). Requires a secret test key (`sk_test_`) on the sandbox.\n */\n readonly agents = {\n /** Assign (or return) the wallet for a game NPC id. Idempotent — safe to call wherever your NPCs spawn. */\n createWallet: async (input: { agentId: string }): Promise<AgentWallet> => {\n requireField(input?.agentId, \"agentId\");\n const { agent } = await this.http.post<{ agent: AgentWallet }>(\"/agents/wallets\", { agentId: input.agentId });\n return agent;\n },\n /** Resolve one NPC's wallet by your id. */\n wallet: async (agentId: string): Promise<AgentWallet> => {\n requireField(agentId, \"agentId\");\n const { agent } = await this.http.get<{ agent: AgentWallet }>(`/agents/wallets/${encodeURIComponent(agentId)}`);\n return agent;\n },\n /** List the NPC wallets you've assigned in this studio. */\n list: async (): Promise<AgentWallet[]> => {\n const { agents } = await this.http.get<{ agents: AgentWallet[] }>(\"/agents/wallets\");\n return agents;\n },\n /** Sandbox faucet: fund an NPC with USDC from your treasury (per-NPC lifetime cap). */\n fund: (input: { agentId: string; amount: string; idempotencyKey?: string }): Promise<AgentFundResult> => {\n requireField(input?.agentId, \"agentId\");\n validateAmount(input.amount);\n // Auto-send an idempotency key (body + header) like transfer — so the SDK's 429 auto-retry (and any\n // network retry) re-hits the SAME requirement (`preq_<key>`) instead of minting a fresh id, which\n // combined with server-side reserve-before-settle could otherwise double-reserve/double-fund (issue #54).\n const idempotencyKey = input.idempotencyKey ?? prefixedId(\"idem\");\n return this.http.post<AgentFundResult>(\n `/agents/wallets/${encodeURIComponent(input.agentId)}/fund`,\n { amount: input.amount, idempotencyKey },\n { idempotencyKey },\n );\n },\n /** NPC→NPC (or →player) USDC transfer, by id. A thin alias of `playmos.transfer` (which is canonical). */\n pay: (input: { from: string; to: string; amount: string; feeBps?: number; feeSink?: `0x${string}` }): Promise<TransferResult> => {\n requireField(input?.from, \"from\");\n requireField(input?.to, \"to\");\n return this.transfer({ from: input.from, to: input.to, amount: input.amount, feeBps: input.feeBps, feeSink: input.feeSink });\n },\n };\n\n /**\n * `escrow` — the fair-exchange primitive (Phase 2): lock the payer's USDC on-chain the instant a deal\n * opens (`hold`), then move it exactly once — `release` (→ payee, fee skimmed) XOR `refund` (→ payer,\n * 100%). The contract holds the funds trustlessly; YOUR game decides the rule (who resolves, and when).\n * A `deadline` auto-refund guarantees funds never get stuck. Pass the `hold` result's `id` to the rest.\n */\n readonly escrow = {\n /** Open a deal: lock `amount` of the payer's USDC into the on-chain escrow. Retries are idempotent.\n * `async` so client-side validation surfaces as a rejected promise, not a synchronous throw. */\n hold: async (input: EscrowHoldInput): Promise<EscrowHoldResult> => {\n const amountMicro = validateAmount(input.amount);\n const payer = input.payer === undefined ? undefined : requireAddressField(input.payer, \"payer\");\n const payee = requireAddressField(input.payee, \"payee\");\n const feeBps = input.feeBps ?? 0;\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(\n `feeBps must be an integer in [0, 10000] (fee is taken at release only; refunds are 100%), got: ${JSON.stringify(input.feeBps)}`,\n { feeBps: input.feeBps },\n );\n }\n // Optional on sandbox (service supplies a default sink, advertised on /health) / required on live\n // (an omitted sink 400s at the service); validate a supplied sink's shape either way. (#49/#58)\n const feeSink = input.feeSink === undefined ? undefined : requireAddressField(input.feeSink, \"feeSink\");\n const resolver = input.resolver === undefined ? undefined : requireAddressField(input.resolver, \"resolver\");\n const idempotencyKey = input.idempotencyKey ?? prefixedId(\"idem\");\n const feeMicro = (amountMicro * BigInt(feeBps)) / 10_000n;\n const { escrow } = await this.http.post<{ escrow: EscrowHoldResult }>(\n \"/escrows\",\n {\n payer,\n payee,\n amount: input.amount,\n feeBps,\n feeSink,\n resolver,\n expiresIn: input.expiresIn,\n deadline: input.deadline,\n memo: input.memo,\n idempotencyKey,\n },\n { idempotencyKey },\n );\n return {\n ...escrow,\n payee: escrow.payee ?? payee,\n amount: escrow.amount ?? formatMicroToUsd(amountMicro),\n feeBps: escrow.feeBps ?? feeBps,\n feeSink: escrow.feeSink ?? feeSink ?? null,\n resolver: escrow.resolver ?? resolver ?? null,\n feeAtRelease: escrow.feeAtRelease ?? formatMicroToUsd(feeMicro),\n netAtRelease: escrow.netAtRelease ?? formatMicroToUsd(amountMicro - feeMicro),\n idempotentReplay: Boolean(escrow.idempotentReplay),\n };\n },\n /** Release a held deal to the payee (fee skimmed). `escrowId` is the `hold` result's `id`. */\n release: async (input: { escrowId: string }): Promise<EscrowResolveResult> => {\n requireField(input?.escrowId, \"escrowId\");\n const { escrow } = await this.http.post<{ escrow: EscrowResolveResult }>(`/escrows/${encodeURIComponent(input.escrowId)}/release`, {});\n return escrow;\n },\n /** Refund a held deal to the payer (100%, untaxed). `escrowId` is the `hold` result's `id`. */\n refund: async (input: { escrowId: string }): Promise<EscrowResolveResult> => {\n requireField(input?.escrowId, \"escrowId\");\n const { escrow } = await this.http.post<{ escrow: EscrowResolveResult }>(`/escrows/${encodeURIComponent(input.escrowId)}/refund`, {});\n return escrow;\n },\n /** Verify a deal's on-chain state (reconciles a `settling` hold wedged by a crash). */\n get: async (escrowId: string): Promise<EscrowResolveResult> => {\n requireField(escrowId, \"escrowId\");\n const { escrow } = await this.http.get<{ escrow: EscrowResolveResult }>(`/escrows/${encodeURIComponent(escrowId)}`);\n return escrow;\n },\n };\n\n /**\n * `marketplace` — list an item, and the seller is paid ONLY when it's bought (Phase 3a, off-chain items).\n * Built on `escrow`: `buy` locks the buyer's USDC on-chain, `confirm` (after your game server delivers the\n * item) pays the seller, and a no-delivery/timeout `refund`s the buyer. `deliver: true` on `buy` collapses\n * lock+pay into one call when your server delivers synchronously. On-chain items are Phase 3b.\n */\n readonly marketplace = {\n /** List an off-chain item for sale. No money moves. Idempotent on `idempotencyKey`. */\n list: async (input: MarketplaceListInput): Promise<Listing> => {\n if (!input?.item || (input.item as { kind?: string }).kind !== \"offchain\") {\n throw new ConfigError('marketplace.list requires item = { kind: \"offchain\", sku: \"<your-item-id>\" } (on-chain items are Phase 3b)', { item: input?.item });\n }\n validateAmount(input.price);\n const seller = requireAddressField(input.seller, \"seller\"); // required — never the signer\n const feeBps = input.feeBps;\n if (feeBps !== undefined && (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000)) {\n throw new ConfigError(`feeBps must be an integer in [0, 10000], got: ${JSON.stringify(feeBps)}`, { feeBps });\n }\n const feeSink = input.feeSink === undefined ? undefined : requireAddressField(input.feeSink, \"feeSink\");\n const { listing } = await this.http.post<{ listing: Listing }>(\"/listings\", {\n seller,\n item: input.item,\n price: input.price,\n feeBps,\n feeSink,\n deliveryWindow: input.deliveryWindow,\n expiresIn: input.expiresIn,\n gameId: input.gameId,\n idempotencyKey: input.idempotencyKey,\n });\n return listing;\n },\n /** Buy a listing: lock the buyer's USDC in escrow. Pass `deliver: true` to also pay the seller in one call. */\n buy: async (input: { listingId: string; buyer?: `0x${string}`; deliver?: boolean }): Promise<MarketplaceSaleResult> => {\n requireField(input?.listingId, \"listingId\");\n const buyer = input.buyer === undefined ? undefined : requireAddressField(input.buyer, \"buyer\");\n return this.http.post<MarketplaceSaleResult>(`/listings/${encodeURIComponent(input.listingId)}/buy`, { buyer, deliver: input.deliver === true });\n },\n /** Confirm delivery → the seller is paid (release), fee skimmed. */\n confirm: async (input: { listingId: string }): Promise<MarketplaceSaleResult> => {\n requireField(input?.listingId, \"listingId\");\n return this.http.post<MarketplaceSaleResult>(`/listings/${encodeURIComponent(input.listingId)}/confirm`, {});\n },\n /** Refund the buyer 100% (seller couldn't deliver / dispute / timeout). */\n refund: async (input: { listingId: string }): Promise<MarketplaceSaleResult> => {\n requireField(input?.listingId, \"listingId\");\n return this.http.post<MarketplaceSaleResult>(`/listings/${encodeURIComponent(input.listingId)}/refund`, {});\n },\n /** Delist an unsold listing (pure DB, no tx). */\n cancel: async (input: { listingId: string }): Promise<Listing> => {\n requireField(input?.listingId, \"listingId\");\n const { listing } = await this.http.post<{ listing: Listing }>(`/listings/${encodeURIComponent(input.listingId)}/cancel`, {});\n return listing;\n },\n /** Fetch a listing + its on-chain-verified sale status. */\n get: async (listingId: string): Promise<MarketplaceGetResult> => {\n requireField(listingId, \"listingId\");\n return this.http.get<MarketplaceGetResult>(`/listings/${encodeURIComponent(listingId)}`);\n },\n };\n\n /**\n * Offline mock payments for this client instance — so `verify(id)` after\n * `mock: true` pay/enterRound does not hit the live API (#204).\n */\n private readonly mockPayments = new Map<string, Payment>();\n\n constructor(config: PlaymosConfig) {\n this.config = config;\n this.env = resolveEnv(config.apiKey, config.network, config.apiBaseUrl);\n // retry defaults ON (auto 429 backoff); `retry: false` / `{ maxRetries: 0 }` opts out (#50).\n this.http = createHttpClient(this.env.apiBaseUrl, config.apiKey, config.retry);\n }\n\n /** Connect the player's wallet and return their address. */\n async connect(): Promise<`0x${string}`> {\n // Offline mock: no wallet provider required (#204 / Path B entryProvider CI).\n if (this.config.mock) {\n return \"0x0000000000000000000000000000000000000001\";\n }\n return getAccount(resolveProvider(this.config.wallet));\n }\n\n /**\n * A DROP-IN payment provider for game kits that expect `{ connect, payEntry }`\n * (e.g. the Playmos game-hub kit). No custom adapter needed — the game dev just\n * does: `gameConfig.paymentProvider = playmos.entryProvider({ gameId })`.\n * The kit hands `payEntry` its own on-chain `roundKey` + `identity`; we thread\n * them straight through so the on-chain entry and the game server's `hasEntered`\n * check line up.\n */\n entryProvider(cfg: { gameId: string }): {\n connect(): Promise<string>;\n payEntry(req: { roundKey: string; identity: string; wallet: string; entryUnits: bigint }): Promise<{\n paymentId: string;\n /** Lowercase product status (matches Payment.status) — 0.3.3+; kits should compare case-insensitively. */\n status: \"confirmed\" | \"failed\" | \"pending\";\n txHash?: string;\n onchain: boolean;\n /** The on-chain identity actually entered — reconcile with `hasEntered`. */\n identity?: string;\n }>;\n } {\n return {\n connect: () => this.connect(),\n payEntry: async (req) => {\n const entry = await this.enterRound({\n gameId: cfg.gameId,\n // Studio roundId for bookkeeping; pin roundKey separately for hasEntered.\n roundId: req.roundKey,\n roundKey: req.roundKey,\n identity: req.identity,\n amount: formatMicroToUsd(req.entryUnits),\n playerId: req.wallet,\n });\n // Normalize to lowercase — Payment + Path B use \"confirmed\", not kit-style \"CONFIRMED\".\n const raw = String(entry.status ?? \"pending\").toLowerCase();\n const status: \"confirmed\" | \"failed\" | \"pending\" =\n raw === \"confirmed\" ? \"confirmed\" : raw === \"failed\" ? \"failed\" : \"pending\";\n // Mock path is offline — must NOT claim onchain (kit would POST /entry/confirm).\n // Live/server-settle/client-signed entries are on-chain truth.\n const onchain = !entry.mock;\n return {\n paymentId: entry.id,\n status,\n ...(entry.txHash ? { txHash: entry.txHash } : {}),\n onchain,\n identity: entry.identity ?? req.identity,\n };\n },\n };\n }\n\n private rememberMock(payment: Payment): Payment {\n if (payment.mock) this.mockPayments.set(payment.id, payment);\n return payment;\n }\n\n /** External-studio IAP (1%). Returns a real confirmed Payment with a txHash. */\n async pay(input: PayInput): Promise<Payment> {\n const amountMicro = validateAmount(input.amount);\n requireField(input.sku, \"sku\");\n requireField(input.playerId, \"playerId\");\n const metadata = validateMetadata(input.metadata);\n const idempotencyKey = input.idempotencyKey ?? prefixedId(\"idem\");\n\n if (this.config.mock) {\n return this.rememberMock(\n mockIapPayment({\n amountMicro,\n feeBps: IAP_FEE_BPS,\n sku: input.sku,\n playerId: input.playerId,\n chain: this.env.network,\n metadata,\n }),\n );\n }\n\n // Auto no-wallet routing (0.1.4): on a test/sandbox key with NO wallet\n // available, let the SERVICE sign + submit on-chain (server-settle) so the\n // developer needs zero wallet/crypto. Sandbox-only — a live key with no\n // wallet keeps today's behavior (the client-signed path throws below).\n if (this.env.isTest && !(await walletAvailable(this.config.wallet))) {\n const res = await this.http.post<ServerSettleResponse>(\n \"/payments\",\n { kind: \"iap\", amount: input.amount, sku: input.sku, playerId: input.playerId, gameId: input.gameId, studio: input.studio, metadata, settle: \"server\" },\n { idempotencyKey },\n );\n return this.mapServerPayment(res.payment, \"iap\", amountMicro);\n }\n\n const intent = await this.http.post<CreateIntentResponse>(\n \"/payments\",\n { kind: \"iap\", amount: input.amount, sku: input.sku, playerId: input.playerId, gameId: input.gameId, studio: input.studio, metadata },\n { idempotencyKey },\n );\n\n const provider = resolveProvider(this.config.wallet);\n if (this.config.gas?.mode === \"player\") {\n const from0 = await getAccount(provider);\n await assertEnoughGas(provider, from0);\n }\n const from = await getAccount(provider);\n\n const usdc = intent.clientParams?.usdc ?? this.config.contracts?.usdc ?? USDC_ADDRESS[this.env.network];\n const playmosPay = intent.clientParams?.contractAddress ?? this.config.contracts?.playmosPay;\n // Prefer service clientParams.studio (game.studioPayoutAddress) over caller input —\n // the service is source of truth for who receives 99% (issue #3 / #345 seam 1).\n const studio = intent.clientParams?.studio ?? input.studio;\n if (!playmosPay) throw new ConfigError(\"No PlaymosPay contract address (service intent + config.contracts both empty).\");\n if (!studio) throw new ConfigError(\"No studio payout address for this payment (service must return clientParams.studio).\");\n if (!intent.clientParams?.studio && input.studio) {\n // Soft warn path: using client fallback only when service omitted studio.\n // Prefer fixing the game row over relying on input.studio long-term.\n }\n const amountUnits = this.resolveUnits(intent, amountMicro);\n // paymentId bytes32 = keccak256(UTF-8 payment.id) — same as service verifyIap.\n const paymentId = intent.clientParams?.paymentId ?? intent.payment.id;\n\n const calls = buildIapCalls({ usdc, playmosPay, paymentId, studio, amountUnits });\n const { id: callsId } = await sendCalls(provider, from, this.env.chainId, calls, this.sponsorUrl(intent));\n const { txHash } = await waitForCalls(provider, callsId);\n\n return this.settle(intent.payment.id, txHash);\n }\n\n /** Playmos-owned skill-game entry (10%, 60/30/10 prize pool). Closes #343. */\n async enterRound(input: EnterRoundInput): Promise<Payment> {\n const amountMicro = validateAmount(input.amount);\n requireField(input.gameId, \"gameId\");\n requireField(input.roundId, \"roundId\");\n requireField(input.playerId, \"playerId\");\n const metadata = validateMetadata(input.metadata);\n const idempotencyKey = input.idempotencyKey ?? prefixedId(\"idem\");\n\n if (this.config.mock) {\n return this.rememberMock(\n mockEntryPayment({\n amountMicro,\n poolBps: POOL_BPS,\n seedBps: SEED_BPS,\n rakeBps: RAKE_BPS,\n gameId: input.gameId,\n roundId: input.roundId,\n playerId: input.playerId,\n chain: this.env.network,\n metadata,\n // B2 pins — must survive mock path for hub hasEntered parity (#204).\n roundKey: input.roundKey,\n identity: input.identity,\n }),\n );\n }\n\n // Auto no-wallet routing (0.1.4): test/sandbox key + NO wallet → the service\n // settles the entry on-chain for us (server-settle). entryProvider().payEntry\n // inherits this automatically since it calls enterRound(). Sandbox-only.\n if (this.env.isTest && !(await walletAvailable(this.config.wallet))) {\n const res = await this.http.post<ServerSettleResponse>(\n \"/payments\",\n { kind: \"entry\", amount: input.amount, gameId: input.gameId, roundId: input.roundKey ?? input.roundId, identity: input.identity, playerId: input.playerId, metadata, settle: \"server\" },\n { idempotencyKey },\n );\n const payment = this.mapServerPayment(res.payment, \"entry\", amountMicro);\n // Prefer the identity the caller pinned; else whatever the service echoed.\n if (input.identity) payment.identity = input.identity;\n // Issue #41 — surface PrizePool + roundKey so winners can claim later without re-deriving.\n const pool = res.clientParams?.contractAddress ?? this.config.contracts?.prizePool;\n if (pool) payment.prizePoolAddress = pool.toLowerCase() as `0x${string}`;\n // Prefer service echo, then caller B2 pin, then derived ids (#201 / #204).\n payment.roundKey =\n res.clientParams?.roundKey ??\n input.roundKey ??\n res.clientParams?.roundId ??\n payment.roundId ??\n input.roundId;\n return payment;\n }\n\n const intent = await this.http.post<CreateIntentResponse>(\n \"/payments\",\n // When the game supplies its own roundKey, that IS the round the service\n // stores + verifies against (so on-chain enter and server hasEntered align).\n { kind: \"entry\", amount: input.amount, gameId: input.gameId, roundId: input.roundKey ?? input.roundId, identity: input.identity, playerId: input.playerId, metadata },\n { idempotencyKey },\n );\n\n const provider = resolveProvider(this.config.wallet);\n if (this.config.gas?.mode === \"player\") {\n const from0 = await getAccount(provider);\n await assertEnoughGas(provider, from0);\n }\n const from = await getAccount(provider);\n\n const usdc = intent.clientParams?.usdc ?? this.config.contracts?.usdc ?? USDC_ADDRESS[this.env.network];\n const prizePool = intent.clientParams?.contractAddress ?? this.config.contracts?.prizePool;\n if (!prizePool) throw new ConfigError(\"No PrizePool contract address for this game (service intent + config.contracts both empty).\");\n // Seam #3: on-chain enter must use the EXACT strings the service stored and will\n // hasEntered. Prefer clientParams (service echo) over inventing gameId:roundId,\n // which diverges from payment.roundId and breaks verify.\n const roundKey =\n intent.clientParams?.roundKey ??\n intent.clientParams?.roundId ??\n input.roundKey ??\n intent.payment.roundId ??\n input.roundId;\n if (!roundKey) throw new ConfigError(\"No roundKey/roundId for enterRound (service clientParams missing).\");\n const identity =\n intent.clientParams?.identity ??\n input.identity ??\n intent.payment.identity ??\n `${from}#${idempotencyKey}`;\n const amountUnits = this.resolveUnits(intent, amountMicro);\n\n const calls = buildEntryCalls({ usdc, prizePool, roundKey, identity, amountUnits });\n const { id: callsId } = await sendCalls(provider, from, this.env.chainId, calls, this.sponsorUrl(intent));\n const { txHash } = await waitForCalls(provider, callsId);\n\n // Surface the EXACT on-chain identity we entered with so the caller can\n // reconcile against their server's `hasEntered(roundKey, identity)`.\n const payment = await this.settle(intent.payment.id, txHash);\n payment.identity = identity;\n // Issue #41 — winners need the pool address later for prize() / withdraw().\n payment.prizePoolAddress = prizePool.toLowerCase() as `0x${string}`;\n payment.roundKey = roundKey;\n return payment;\n }\n\n /**\n * `transfers` — read-back / confirmation for a prior `transfer()` (issues #27, #47).\n * `get` reconciles once against chain truth; `wait` polls it to a terminal state\n * for you (no hand-rolled loop). Both cover the gasless agent path.\n */\n readonly transfers = {\n /** One-shot reconcile of a transfer against chain truth. */\n get: async (transferId: string): Promise<TransferReconcile> => {\n requireField(transferId, \"transferId\");\n const res = await this.http.get<{ transfer: TransferReconcile }>(\n `/transfers/${encodeURIComponent(transferId)}`,\n );\n return res.transfer;\n },\n\n /**\n * Block until a transfer reaches a terminal state — `settled` or `failed` —\n * instead of hand-rolling a poll loop (#47). Polls `transfers.get(id)` every\n * `intervalMs` (default 1000) until terminal, then RESOLVES with the final\n * reconcile. Throws a typed `ApiError` (`detail.timeout`) if neither\n * `timeoutMs` (default 30000) nor `maxAttempts` (default 40) is reached first.\n *\n * A `failed` transfer is a legitimate outcome, so it RESOLVES (status\n * \"failed\") — inspect `result.status`; it does not throw.\n */\n wait: async (transferId: string, opts?: WaitOptions): Promise<TransferReconcile> => {\n requireField(transferId, \"transferId\");\n const intervalMs = opts?.intervalMs ?? 1000;\n const timeoutMs = opts?.timeoutMs ?? 30_000;\n const maxAttempts = opts?.maxAttempts ?? 40;\n const deadline = Date.now() + timeoutMs;\n let last: TransferReconcile | undefined;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n last = await this.transfers.get(transferId);\n if (last.status === \"settled\" || last.status === \"failed\") return last;\n if (Date.now() + intervalMs > deadline) break;\n await new Promise((r) => setTimeout(r, intervalMs));\n }\n throw new ApiError(\n `Timed out waiting for transfer ${transferId} to settle (last status: ${last?.status ?? \"unknown\"}). ` +\n `It may still settle — re-check with playmos.transfers.get(\"${transferId}\").`,\n { transferId, timeout: true, lastStatus: last?.status ?? \"unknown\" },\n );\n },\n };\n\n /**\n * `transfer` — the value-movement base primitive (Phase 1a): move USDC from one wallet to another,\n * with a per-call fee. The GAME LOGIC is the authority — you already decided the move is valid — so\n * this is a direct, unconditional push (use `escrow`/`marketplace` when a trust boundary needs fair\n * exchange). The service settles it through the protocol-agnostic settlement core (idempotent,\n * reserve-before-broadcast) and the on-chain PlaymosTransfer / PlaymosTransferAuth contracts.\n *\n * Fee is per-call: `feeBps` 0–10000 (+ `feeSink`). `feeBps: 0` is an untaxed reward/faucet transfer.\n * Retries are safe: pass the same `idempotencyKey` and a re-call NEVER broadcasts a second tx —\n * it returns the cached result (`idempotentReplay: true`).\n *\n * Confirmation: treat `status === \"settled\" && txHash` as final. If `settling`, either call\n * `playmos.transfers.wait(id)`, or pass `{ confirm: true }` here to block until terminal in one\n * call (#47). BaseScan: `https://sepolia.basescan.org/tx/<txHash>`.\n *\n * NPC `from` requires `sk_test_` and settles gaslessly (NPC signs; service relays).\n */\n async transfer(input: TransferInput, opts?: TransferConfirmOptions): Promise<TransferResult> {\n const amountMicro = validateAmount(input.amount);\n // `from` is optional in the sandbox: omit it and the service defaults it to its server-held signer\n // wallet (Phase 1a's only payer). A supplied value is still validated so a typo surfaces early.\n const from = input.from === undefined ? undefined : partyRef(input.from, \"from\");\n const to = partyRef(input.to, \"to\");\n const feeBps = input.feeBps ?? 0;\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(\n `feeBps must be an integer in [0, 10000] (0 = untaxed reward/faucet; 500 = 5%; 10000 = 100%), got: ${JSON.stringify(input.feeBps)}`,\n { feeBps: input.feeBps },\n );\n }\n // feeSink is OPTIONAL on the sandbox — the service supplies a default sink (advertised on /health)\n // so agent scripts move value without wiring a treasury — and REQUIRED on live, where an omitted\n // sink surfaces as a service 400 (server authority). Either way, validate a supplied sink's shape\n // so a typo surfaces client-side. Matches marketplace.list. (#49/#58)\n const feeSink = input.feeSink === undefined ? undefined : requireAddressField(input.feeSink, \"feeSink\");\n const idempotencyKey = input.idempotencyKey ?? prefixedId(\"idem\");\n\n const res = await this.http.post<{ transfer: {\n id: string;\n status: \"settled\" | \"failed\" | \"settling\";\n txHash?: `0x${string}`;\n from: `0x${string}`;\n to: `0x${string}`;\n amount: string;\n fee: string;\n net: string;\n feeBps: number;\n feeSink?: `0x${string}` | null;\n memo?: string | null;\n idempotentReplay: boolean;\n } }>(\n \"/transfers\",\n { from, to, amount: input.amount, memo: input.memo, feeBps, feeSink, idempotencyKey },\n { idempotencyKey },\n );\n\n const t = res.transfer;\n // Prefer the service's authoritative figures; fall back to the exact local floor math.\n const feeMicro = (amountMicro * BigInt(feeBps)) / 10_000n;\n const out: TransferResult = {\n id: t.id,\n status: t.status,\n txHash: t.txHash,\n from: t.from, // the service's resolved payer address (omitted when it's the redacted treasury signer)\n to: t.to, // the service's resolved payee address\n amount: t.amount ?? formatMicroToUsd(amountMicro),\n fee: t.fee ?? formatMicroToUsd(feeMicro),\n net: t.net ?? formatMicroToUsd(amountMicro - feeMicro),\n feeBps: t.feeBps ?? feeBps,\n feeSink: t.feeSink ?? feeSink ?? null,\n memo: t.memo ?? input.memo ?? null,\n idempotentReplay: Boolean(t.idempotentReplay),\n };\n\n // `{ confirm: true }` — block until terminal so the caller never hand-rolls a\n // poll loop (#47). Only needed when the POST came back `settling`; a transfer\n // that already `settled`/`failed` is returned as-is.\n if (opts?.confirm && out.status === \"settling\") {\n const final = await this.transfers.wait(out.id, opts);\n out.status = final.status as TransferResult[\"status\"];\n out.txHash = (final.txHash ?? out.txHash) as `0x${string}` | undefined;\n }\n return out;\n }\n\n /** Verify a payment by the service's on-chain read (spec §6.1). Idempotent. */\n async verify(paymentId: string): Promise<VerifyResult> {\n requireField(paymentId, \"paymentId\");\n // Offline mock: resolve from this client's mock store — never hit live API (#204).\n if (this.config.mock) {\n const cached = this.mockPayments.get(paymentId);\n if (!cached) {\n throw new ApiError(`payment not found: ${paymentId}`, { status: 404, code: \"not_found\" });\n }\n const m = mockVerifyResult(cached);\n return {\n id: m.id,\n status: m.status,\n amount: m.amount,\n fee: m.fee,\n net: m.net,\n txHash: m.txHash,\n playerId: m.playerId ?? \"\",\n sku: m.sku,\n roundId: m.roundId,\n chain: m.chain,\n verifiedVia: \"cache\",\n };\n }\n return this.http.get<VerifyResult>(`/payments/${encodeURIComponent(paymentId)}`);\n }\n\n // ---- internals ---------------------------------------------------------\n\n /**\n * x402 V1 is Base Sepolia + test keys only (ADR D5). Fail closed before any\n * network call so mainnet / live keys never silently hit the adapter.\n */\n private assertX402Allowed(): void {\n if (!this.env.isTest || this.env.network !== \"base-sepolia\") {\n throw new ConfigError(\n 'playmos.x402 is Base Sepolia / test-key only in V1 (ADR D5). Use apiKey sk_test_… and network \"base-sepolia\".',\n { network: this.env.network, isTest: this.env.isTest },\n );\n }\n }\n\n /**\n * Map a server-settled payment (from the `settle: \"server\"` response) into the\n * SDK's `Payment` shape. The service already signed + confirmed on-chain, so we\n * pass its authoritative `status`/`txHash`/amounts straight through and, for an\n * entry, derive the 60/30/10 USD `split` locally (exactly as the mock + the\n * contract compute it) from the parsed amount.\n */\n private mapServerPayment(\n p: ServerSettleResponse[\"payment\"],\n kind: \"iap\" | \"entry\",\n amountMicro: bigint,\n ): Payment {\n const payment: Payment = {\n id: p.id,\n status: p.status,\n kind: p.kind ?? kind,\n amount: p.amount,\n fee: p.fee,\n net: p.net,\n sku: p.sku,\n roundId: p.roundId,\n gameId: p.gameId,\n playerId: p.playerId ?? \"\",\n txHash: p.txHash,\n chain: this.env.network,\n createdAt: p.createdAt ?? new Date().toISOString(),\n metadata: p.metadata,\n identity: p.identity,\n };\n if ((p.kind ?? kind) === \"entry\") {\n const { poolMicro, seedMicro, rakeMicro } = computePoolSplit(amountMicro, POOL_BPS, SEED_BPS, RAKE_BPS);\n payment.split = {\n pool: formatMicroToUsd(poolMicro),\n seed: formatMicroToUsd(seedMicro),\n rake: formatMicroToUsd(rakeMicro),\n };\n }\n return payment;\n }\n\n /** Prefer the service's authoritative micro-USDC amount; fall back to the\n * locally-parsed value if the service didn't echo one. */\n private resolveUnits(intent: CreateIntentResponse, local: bigint): bigint {\n const fromServer = intent.clientParams?.amountUnits ?? intent.clientParams?.amountMicro;\n return fromServer ? BigInt(fromServer) : local;\n }\n\n /**\n * Read PrizePool.withdrawable[wallet] via eth_call (issue #41).\n * Uses the wallet provider when present; otherwise a public Base Sepolia RPC in test.\n */\n private async readWithdrawable(\n prizePool: `0x${string}`,\n wallet: `0x${string}`,\n ): Promise<bigint> {\n const data = encodeFunctionData({\n abi: prizePoolAbi,\n functionName: \"withdrawable\",\n args: [wallet],\n });\n let raw: `0x${string}`;\n try {\n if (await walletAvailable(this.config.wallet)) {\n const provider = resolveProvider(this.config.wallet);\n raw = (await provider.request({\n method: \"eth_call\",\n params: [{ to: prizePool, data }, \"latest\"],\n })) as `0x${string}`;\n } else {\n // No wallet — public RPC eth_call (sandbox / server tooling).\n const rpc =\n this.env.network === \"base\"\n ? \"https://mainnet.base.org\"\n : \"https://sepolia.base.org\";\n const res = await fetch(rpc, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_call\",\n params: [{ to: prizePool, data }, \"latest\"],\n }),\n });\n const json = (await res.json()) as { result?: string; error?: { message?: string } };\n if (!json.result) {\n throw new ApiError(\n `eth_call withdrawable failed: ${json.error?.message ?? \"no result\"}`,\n { prizePool, wallet },\n );\n }\n raw = json.result as `0x${string}`;\n }\n } catch (e) {\n if (e instanceof ApiError) throw e;\n throw new ApiError(`Could not read withdrawable balance: ${(e as Error).message}`, {\n prizePool,\n wallet,\n });\n }\n return decodeFunctionResult({\n abi: prizePoolAbi,\n functionName: \"withdrawable\",\n data: raw,\n }) as bigint;\n }\n\n private sponsorUrl(intent: CreateIntentResponse): string | undefined {\n if (this.config.gas?.mode === \"player\") return undefined;\n return this.config.gas?.paymasterUrl ?? intent.clientParams?.paymasterUrl;\n }\n\n /**\n * After the batch lands, resolve the authoritative status via the service's\n * on-chain read. Polls briefly; returns the merged Payment with the real txHash.\n */\n private async settle(paymentId: string, txHash?: `0x${string}`, timeoutMs = 30_000): Promise<Payment> {\n // Report the settlement txHash we observed locally so the service can VERIFY\n // IT ON-CHAIN. We only say WHICH tx landed; the service reads the chain and\n // decides confirmed/failed (trust stays on-chain — anti-#337). Non-fatal on\n // failure: fall back to polling verify.\n if (txHash) {\n try {\n await this.http.post(`/payments/${encodeURIComponent(paymentId)}/tx`, { txHash });\n } catch {\n /* ignore — the verify poll below still resolves the authoritative status */\n }\n }\n const deadline = Date.now() + timeoutMs;\n let last: VerifyResult | undefined;\n while (Date.now() < deadline) {\n last = await this.verify(paymentId);\n if (last.status === \"confirmed\" || last.status === \"failed\") break;\n // If the service can't read the chain (degraded), polling will never\n // confirm — return the honest cached status now instead of spinning.\n if (last.chainReads === \"degraded\" || last.verifiedVia === \"degraded\") break;\n await new Promise((r) => setTimeout(r, 1200));\n }\n return {\n id: paymentId,\n status: last?.status ?? \"pending\",\n kind: last?.roundId ? \"entry\" : \"iap\",\n amount: last?.amount ?? \"0\",\n fee: last?.fee ?? \"0\",\n net: last?.net ?? \"0\",\n sku: last?.sku,\n roundId: last?.roundId,\n playerId: last?.playerId ?? \"\",\n txHash: last?.txHash ?? txHash,\n chain: this.env.network,\n createdAt: new Date().toISOString(),\n };\n }\n}\n\n/** Local preview of a split without any network — handy for UIs. */\nexport function previewIapSplit(amount: string): { amount: string; fee: string; net: string } {\n const micro = validateAmount(amount);\n const { feeMicro, netMicro } = computeIapSplit(micro, IAP_FEE_BPS);\n return { amount: formatMicroToUsd(micro), fee: formatMicroToUsd(feeMicro), net: formatMicroToUsd(netMicro) };\n}\n\n/**\n * Local preview of a `transfer` fee split without any network — handy for UIs and quotes. Mirrors the\n * on-chain floor math: `fee = floor(amount * feeBps / 10000)`, `net = amount − fee` (dust → payee).\n */\nexport function previewTransferSplit(amount: string, feeBps: number): { amount: string; fee: string; net: string; feeBps: number } {\n const micro = validateAmount(amount);\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(`feeBps must be an integer in [0, 10000], got: ${JSON.stringify(feeBps)}`, { feeBps });\n }\n const feeMicro = (micro * BigInt(feeBps)) / 10_000n;\n return { amount: formatMicroToUsd(micro), fee: formatMicroToUsd(feeMicro), net: formatMicroToUsd(micro - feeMicro), feeBps };\n}\n\n/**\n * Local preview of what an escrow `release` would pay out, without any network. Mirrors the on-chain\n * floor math: `fee = floor(amount * feeBps / 10000)`, `net = amount − fee` (dust → payee). A `refund`\n * returns the full `amount` with no fee, so it needs no preview.\n */\nexport function previewEscrowFee(amount: string, feeBps: number): { amount: string; fee: string; net: string; feeBps: number } {\n const micro = validateAmount(amount);\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(`feeBps must be an integer in [0, 10000], got: ${JSON.stringify(feeBps)}`, { feeBps });\n }\n const feeMicro = (micro * BigInt(feeBps)) / 10_000n;\n return { amount: formatMicroToUsd(micro), fee: formatMicroToUsd(feeMicro), net: formatMicroToUsd(micro - feeMicro), feeBps };\n}\n\n/**\n * Local preview of a marketplace sale's payout, without any network. Mirrors the on-chain floor math\n * (`fee = floor(price * feeBps / 10000)`, `net = price − fee`, dust → seller). A no-sale/refund pays 0.\n */\nexport function previewMarketplaceSplit(price: string, feeBps: number): { price: string; fee: string; net: string; feeBps: number } {\n const micro = validateAmount(price);\n if (!Number.isInteger(feeBps) || feeBps < 0 || feeBps > 10_000) {\n throw new ConfigError(`feeBps must be an integer in [0, 10000], got: ${JSON.stringify(feeBps)}`, { feeBps });\n }\n const feeMicro = (micro * BigInt(feeBps)) / 10_000n;\n return { price: formatMicroToUsd(micro), fee: formatMicroToUsd(feeMicro), net: formatMicroToUsd(micro - feeMicro), feeBps };\n}\n\n/** Local preview of the 60/30/10 entry split without any network. */\nexport function previewPoolSplit(amount: string): { amount: string; pool: string; seed: string; rake: string } {\n const micro = validateAmount(amount);\n const { poolMicro, seedMicro, rakeMicro } = computePoolSplit(micro, POOL_BPS, SEED_BPS, RAKE_BPS);\n return {\n amount: formatMicroToUsd(micro),\n pool: formatMicroToUsd(poolMicro),\n seed: formatMicroToUsd(seedMicro),\n rake: formatMicroToUsd(rakeMicro),\n };\n}\n","/**\n * payout.ts — pure payout math for skill/contest settlement (issue #13).\n *\n * Scores NEVER enter this module. The studio ranks wallets (best-first) from its\n * own leaderboard; we only turn that ranking + a payout rule into integer USDC\n * base-unit amounts that sum EXACTLY to the payable pool.\n *\n * No network, no chain — fully unit-testable.\n */\n\nexport type PayoutRule =\n | { kind: \"winner-take-all\" }\n | { kind: \"top-n\"; splitsBps: number[] } // e.g. top3 = [5000, 3000, 2000] (sum 10000)\n | { kind: \"custom\"; amounts: string[] }; // exact USD strings per rank (\"1.50\")\n\nexport class PayoutError extends Error {\n code = \"payout_invalid\" as const;\n constructor(message: string) {\n super(message);\n this.name = \"PayoutError\";\n }\n}\n\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\nconst BPS = 10_000n;\n\nfunction requireAddress(w: string, i: number): `0x${string}` {\n if (!ADDRESS_RE.test(w)) {\n throw new PayoutError(`ranking[${i}] must be a 0x-prefixed 20-byte address, got: ${JSON.stringify(w)}`);\n }\n return w.toLowerCase() as `0x${string}`;\n}\n\n/**\n * Parse a USD decimal string into micro-USDC (6 dp). Allows up to 6 fractional\n * digits for custom amounts that already match on-chain micro precision.\n */\nfunction parseUsdToMicroLoose(amount: string): bigint {\n if (typeof amount !== \"string\" || !/^\\d+(\\.\\d{1,6})?$/.test(amount.trim())) {\n throw new PayoutError(`invalid USD amount: ${JSON.stringify(amount)}`);\n }\n const [wholeRaw, frac = \"\"] = amount.trim().split(\".\");\n const whole = wholeRaw ?? \"0\";\n const fracPadded = (frac + \"000000\").slice(0, 6);\n const micro = BigInt(whole) * 1_000_000n + BigInt(fracPadded);\n if (micro <= 0n) throw new PayoutError(`amount must be > 0, got: ${JSON.stringify(amount)}`);\n return micro;\n}\n\n/**\n * Apply the studio's payout rule to a payable pool and ranking (best-first).\n *\n * - Integer math only (bigint micro-USDC).\n * - Sum of amounts == pool exactly; any remainder from floor division goes to rank 1.\n * - Rejects empty ranking, bad splits, more winners than ranking, zero pool.\n */\nexport function computePayout(\n pool: bigint,\n ranking: `0x${string}`[],\n rule: PayoutRule,\n): { wallet: `0x${string}`; amount: bigint }[] {\n if (typeof pool !== \"bigint\" || pool <= 0n) {\n throw new PayoutError(`pool must be a positive bigint (micro-USDC), got: ${String(pool)}`);\n }\n if (!Array.isArray(ranking) || ranking.length === 0) {\n throw new PayoutError(\"ranking must be a non-empty array of wallets (best-first)\");\n }\n const wallets = ranking.map((w, i) => requireAddress(w, i));\n // Dedup check\n const seen = new Set<string>();\n for (const w of wallets) {\n if (seen.has(w)) throw new PayoutError(`duplicate wallet in ranking: ${w}`);\n seen.add(w);\n }\n\n if (rule.kind === \"winner-take-all\") {\n return [{ wallet: wallets[0]!, amount: pool }];\n }\n\n if (rule.kind === \"top-n\") {\n const splits = rule.splitsBps;\n if (!Array.isArray(splits) || splits.length === 0) {\n throw new PayoutError(\"top-n splitsBps must be a non-empty array\");\n }\n if (splits.length > wallets.length) {\n throw new PayoutError(\n `top-n needs ${splits.length} ranked wallets but ranking only has ${wallets.length}`,\n );\n }\n let sumBps = 0;\n for (const b of splits) {\n if (!Number.isInteger(b) || b <= 0 || b > 10_000) {\n throw new PayoutError(`each splitsBps entry must be an integer in (0, 10000], got: ${b}`);\n }\n sumBps += b;\n }\n if (sumBps !== 10_000) {\n throw new PayoutError(`splitsBps must sum to 10000, got ${sumBps}`);\n }\n // Floor each share; remainder (dust) → rank 1 so sum is exact.\n const out: { wallet: `0x${string}`; amount: bigint }[] = [];\n let allocated = 0n;\n for (let i = 0; i < splits.length; i++) {\n const amt = (pool * BigInt(splits[i]!)) / BPS;\n out.push({ wallet: wallets[i]!, amount: amt });\n allocated += amt;\n }\n const remainder = pool - allocated;\n if (remainder < 0n) throw new PayoutError(\"internal: allocated more than pool\");\n out[0] = { wallet: out[0]!.wallet, amount: out[0]!.amount + remainder };\n // Drop zero amounts if any (shouldn't after remainder to first unless pool tiny)\n const filtered = out.filter((x) => x.amount > 0n);\n if (filtered.length === 0) throw new PayoutError(\"payout produced no positive amounts\");\n const total = filtered.reduce((s, x) => s + x.amount, 0n);\n if (total !== pool) throw new PayoutError(`internal: sum ${total} != pool ${pool}`);\n return filtered;\n }\n\n if (rule.kind === \"custom\") {\n const amounts = rule.amounts;\n if (!Array.isArray(amounts) || amounts.length === 0) {\n throw new PayoutError(\"custom amounts must be a non-empty array of USD strings\");\n }\n if (amounts.length > wallets.length) {\n throw new PayoutError(\n `custom amounts has ${amounts.length} entries but ranking only has ${wallets.length}`,\n );\n }\n const out: { wallet: `0x${string}`; amount: bigint }[] = [];\n let total = 0n;\n for (let i = 0; i < amounts.length; i++) {\n const amt = parseUsdToMicroLoose(amounts[i]!);\n out.push({ wallet: wallets[i]!, amount: amt });\n total += amt;\n }\n if (total !== pool) {\n throw new PayoutError(\n `custom amounts sum to ${total} micro-USDC but pool is ${pool} — must match exactly`,\n );\n }\n return out;\n }\n\n throw new PayoutError(`unknown payout rule kind: ${JSON.stringify((rule as { kind: unknown }).kind)}`);\n}\n","/**\n * settlement.ts — the x402-ready settlement CORE contract (Phase 0).\n *\n * Two shared shapes every value-movement primitive (`transfer`, `escrow`,\n * `marketplace`) AND the future x402 adapter build on. The whole point of\n * naming them now is that x402 later becomes a thin HTTP-402 adapter with zero\n * rework — see `docs/design/transfer-escrow-marketplace-spec.md` §\"Architecture:\n * x402-ready by design\".\n *\n * PaymentRequirement — WHAT must be paid. A plain, JSON-safe object. A direct\n * SDK call creates one and satisfies it immediately; an x402 \"402 Payment\n * Required\" challenge is literally this object serialized onto the wire. So\n * it is designed to round-trip to/from an HTTP 402 body with zero loss —\n * `parsePaymentRequirement(serializePaymentRequirement(req))` is `req`.\n *\n * Authorization — HOW a settlement is authorized. A discriminated union so the\n * settlement core never bakes in \"direct SDK signature\": today a\n * `wallet-signature` (implemented), tomorrow an `x402-payload` (declared,\n * not settled yet). This union is the seam that keeps x402 out of the core.\n *\n * Nothing here touches the network or the chain — these are the shared data\n * shapes the SDK produces and the service's protocol-agnostic settlement core\n * consumes.\n */\n\nimport type { Network } from \"./types.js\";\nimport { CHAIN_ID } from \"./config.js\";\nimport { InvalidAmountError, MissingFieldError, ConfigError } from \"./errors.js\";\nimport { parseUsdToMicro } from \"./money.js\";\nimport { prefixedId } from \"./ids.js\";\n\n/** The only settlement asset in V1. Named so an x402 challenge carries it verbatim. */\nexport type SettlementAsset = \"USDC\";\n\n/**\n * The shared payment contract — WHAT must be paid, independent of HOW it was\n * requested (direct SDK call today, x402 challenge tomorrow).\n *\n * Every field is a JSON primitive so the object is byte-stable across an HTTP\n * 402 body: mint it once, and both the direct path and the x402 path settle the\n * exact same requirement, idempotent on `id`.\n */\nexport interface PaymentRequirement {\n /** The anchor id (`preq_<ulid>`). Settlement idempotency key + x402 challenge id. */\n id: string;\n /** The recipient wallet (the payee). Checksummed or lowercase 0x-address. */\n payTo: `0x${string}`;\n /** USD decimal string (\"5.00\") — same money convention as `pay()`/`enterRound()`. */\n amount: string;\n /** Only USDC in V1. */\n asset: SettlementAsset;\n /** Which chain settles this requirement. */\n network: Network;\n /** Optional free-form terms/memo, echoed on the receipt and in the 402 body. */\n terms?: string;\n /** ISO-8601 expiry. A challenge/authorization presented after this is rejected. */\n expiresAt: string;\n}\n\nconst ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;\nconst DEFAULT_TTL_MS = 15 * 60 * 1000; // 15 min — a sane challenge window.\n\n/** Assert a value is a 0x-prefixed 20-byte address, or throw a typed error. */\nfunction requireAddress(value: unknown, field: string): `0x${string}` {\n if (typeof value !== \"string\" || value.trim() === \"\") {\n throw new MissingFieldError(field);\n }\n if (!ADDRESS_RE.test(value)) {\n throw new ConfigError(`${field} must be a 0x-prefixed 20-byte address, got: ${JSON.stringify(value)}`, {\n field,\n value,\n });\n }\n return value as `0x${string}`;\n}\n\n/** Assert a value is a known network, or throw a typed error. */\nfunction requireNetwork(value: unknown): Network {\n if (value === \"base\" || value === \"base-sepolia\") return value;\n throw new ConfigError(`Unknown network: ${JSON.stringify(value)}. Expected one of ${Object.keys(CHAIN_ID).join(\", \")}.`, {\n field: \"network\",\n value,\n });\n}\n\nexport interface CreatePaymentRequirementInput {\n /** Recipient wallet. */\n payTo: `0x${string}`;\n /** USD decimal string (\"5.00\"). */\n amount: string;\n /** Settlement chain. */\n network: Network;\n /** Defaults to \"USDC\". */\n asset?: SettlementAsset;\n /** Optional terms/memo. */\n terms?: string;\n /** Absolute ISO expiry. Overrides `expiresInMs`. Defaults to now + 15 min. */\n expiresAt?: string;\n /** Relative TTL from now, in ms. Ignored if `expiresAt` is set. */\n expiresInMs?: number;\n /** Supply for a deterministic id (e.g. to reuse an upstream id); else a `preq_<ulid>` is minted. */\n id?: string;\n /** Injectable clock for deterministic tests. */\n now?: () => Date;\n}\n\n/**\n * Build a validated {@link PaymentRequirement}. This is the single producer the\n * direct primitives (`transfer`/`escrow`/`marketplace`) and — later — the x402\n * adapter both call, so every requirement on the wire is shaped identically.\n * Pure: no network, no chain, no id collisions (monotonic ULID).\n */\nexport function createPaymentRequirement(input: CreatePaymentRequirementInput): PaymentRequirement {\n const now = (input.now ?? (() => new Date()))();\n const payTo = requireAddress(input.payTo, \"payTo\");\n const network = requireNetwork(input.network);\n const asset: SettlementAsset = input.asset ?? \"USDC\";\n if (asset !== \"USDC\") {\n throw new ConfigError(`Unsupported asset: ${JSON.stringify(asset)}. Only \"USDC\" is supported.`, { asset });\n }\n // Validates format + positivity; throws InvalidAmountError on bad input.\n parseUsdToMicro(input.amount);\n\n const expiresAt =\n input.expiresAt ?? new Date(now.getTime() + (input.expiresInMs ?? DEFAULT_TTL_MS)).toISOString();\n\n const req: PaymentRequirement = {\n id: input.id ?? prefixedId(\"preq\"),\n payTo,\n amount: input.amount,\n asset,\n network,\n expiresAt,\n };\n if (input.terms !== undefined) req.terms = input.terms;\n return req;\n}\n\n/**\n * Serialize a requirement to a plain, JSON-safe object — the exact body an x402\n * \"402 Payment Required\" response carries. Undefined optionals are omitted so\n * the shape is stable across `JSON.stringify` → `JSON.parse` → re-parse.\n */\nexport function serializePaymentRequirement(req: PaymentRequirement): Record<string, unknown> {\n const body: Record<string, unknown> = {\n id: req.id,\n payTo: req.payTo,\n amount: req.amount,\n asset: req.asset,\n network: req.network,\n expiresAt: req.expiresAt,\n };\n if (req.terms !== undefined) body.terms = req.terms;\n return body;\n}\n\n/**\n * Parse + validate an untrusted object (an HTTP 402 body, a queue message, a\n * direct call) back into a {@link PaymentRequirement}. This is the exact decoder\n * the x402 adapter reuses — it must reject anything malformed with a typed error.\n */\nexport function parsePaymentRequirement(input: unknown): PaymentRequirement {\n if (typeof input !== \"object\" || input === null || Array.isArray(input)) {\n throw new ConfigError(\"PaymentRequirement must be a JSON object.\", { input });\n }\n const o = input as Record<string, unknown>;\n const id = o.id;\n if (typeof id !== \"string\" || id.trim() === \"\") throw new MissingFieldError(\"id\");\n if (o.asset !== \"USDC\") {\n throw new ConfigError(`PaymentRequirement.asset must be \"USDC\", got: ${JSON.stringify(o.asset)}.`, {\n asset: o.asset,\n });\n }\n const payTo = requireAddress(o.payTo, \"payTo\");\n const network = requireNetwork(o.network);\n if (typeof o.amount !== \"string\") throw new InvalidAmountError(o.amount);\n parseUsdToMicro(o.amount); // throws InvalidAmountError on bad format / ≤ 0\n if (typeof o.expiresAt !== \"string\" || o.expiresAt.trim() === \"\") throw new MissingFieldError(\"expiresAt\");\n if (o.terms !== undefined && typeof o.terms !== \"string\") {\n throw new ConfigError(\"PaymentRequirement.terms must be a string when present.\", { terms: o.terms });\n }\n\n const req: PaymentRequirement = {\n id,\n payTo,\n amount: o.amount,\n asset: \"USDC\",\n network,\n expiresAt: o.expiresAt,\n };\n if (o.terms !== undefined) req.terms = o.terms as string;\n return req;\n}\n\n// ─── Authorization — HOW a settlement is authorized (the x402 seam) ───────────\n\n/**\n * A settlement authorized by a wallet — the ONLY variant implemented in Phase 0.\n * Covers both signer models the primitives support:\n * - server-held NPC/agent wallets (the service signs) and\n * - player Base Accounts (the client signs) —\n * carrying either the settlement `txHash` the client already broadcast, or a\n * `signature` + `payload` (e.g. EIP-3009 / EIP-5792 batch params) the service\n * submits. Phase 0 only READS `txHash`; the signed-submit path lands in Phase 1.\n */\nexport interface WalletSignatureAuthorization {\n kind: \"wallet-signature\";\n /** The wallet that authorized the move (payer / signer). */\n from: `0x${string}`;\n /** A settlement tx the client already broadcast (client-signed path). */\n txHash?: `0x${string}`;\n /** An off-chain signature the service submits on the payer's behalf. */\n signature?: `0x${string}`;\n /** Opaque protocol-specific authorization data (EIP-5792 calls, EIP-3009, …). */\n payload?: Record<string, unknown>;\n}\n\n/**\n * A settlement authorized by an x402 payment payload (the `X-PAYMENT` header).\n * DECLARED for the Phase 4 HTTP-402 adapter so the core's type surface is final\n * now — but NOT settled in Phase 0: `settle()` throws a clear \"not implemented\n * yet\" for this variant. This is the seam that keeps x402 out of the core.\n */\nexport interface X402PayloadAuthorization {\n kind: \"x402-payload\";\n /** The raw, opaque x402 payment payload decoded from the request. */\n payload: Record<string, unknown>;\n}\n\n/** How a settlement is authorized — protocol-agnostic by construction. */\nexport type Authorization = WalletSignatureAuthorization | X402PayloadAuthorization;\n\n/** Narrow to the implemented wallet-signature variant. */\nexport function isWalletSignatureAuthorization(\n auth: Authorization,\n): auth is WalletSignatureAuthorization {\n return auth.kind === \"wallet-signature\";\n}\n\n/** Narrow to the declared-but-unimplemented x402 variant. */\nexport function isX402PayloadAuthorization(auth: Authorization): auth is X402PayloadAuthorization {\n return auth.kind === \"x402-payload\";\n}\n"]}
|
package/dist/server.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/webhooks.ts"],"names":["createHmac","timingSafeEqual"],"mappings":"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","file":"server.cjs","sourcesContent":["/**\n * Typed, actionable errors — the Stripe bar (spec §11).\n *\n * Every error carries a stable machine-readable `code` and is thrown at the\n * EARLIEST possible layer: input errors fire client-side before any network or\n * chain call, so a studio never pays gas to discover a typo.\n */\n\nexport type PlaymosErrorCode =\n | \"invalid_amount\"\n | \"missing_field\"\n | \"insufficient_gas\"\n | \"wallet_connection\"\n | \"payment_failed\"\n | \"auth\"\n | \"api_error\"\n | \"config\"\n | \"nothing_to_withdraw\";\n\nexport class PlaymosError extends Error {\n readonly code: PlaymosErrorCode;\n /** Optional machine context (e.g. the offending field, the http status). */\n readonly detail?: Record<string, unknown>;\n\n constructor(code: PlaymosErrorCode, message: string, detail?: Record<string, unknown>) {\n super(message);\n this.name = new.target.name;\n this.code = code;\n this.detail = detail;\n // Restore prototype chain for `instanceof` across transpile targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/** amount ≤ 0, non-numeric, empty, or more than 2 decimal places. */\nexport class InvalidAmountError extends PlaymosError {\n constructor(amount: unknown) {\n super(\n \"invalid_amount\",\n `Invalid amount: ${JSON.stringify(amount)}. Provide a positive USD decimal string with at most 2 decimals, e.g. \"4.99\".`,\n { amount },\n );\n }\n}\n\n/** A required field (sku, playerId, gameId, roundId, agentId…) was empty. */\nexport class MissingFieldError extends PlaymosError {\n constructor(field: string) {\n super(\"missing_field\", `Missing required field: \"${field}\".`, { field });\n }\n}\n\n/** gas mode \"player\" and the player's ETH is too low to cover gas (pre-check, §7). */\nexport class InsufficientGasError extends PlaymosError {\n constructor(detail?: Record<string, unknown>) {\n super(\n \"insufficient_gas\",\n \"The player's wallet has too little ETH to pay gas. Ask them to add a little ETH, or switch to gas.mode: \\\"sponsored\\\".\",\n detail,\n );\n }\n}\n\n/** The player closed or failed the wallet sheet, or no provider is available. */\nexport class WalletConnectionError extends PlaymosError {\n constructor(message = \"Could not connect the player's wallet.\", detail?: Record<string, unknown>) {\n super(\"wallet_connection\", message, detail);\n }\n}\n\n/** The on-chain settlement reverted, was cancelled, or timed out. */\nexport class PaymentFailedError extends PlaymosError {\n constructor(message = \"The on-chain payment did not complete.\", detail?: Record<string, unknown>) {\n super(\"payment_failed\", message, detail);\n }\n}\n\n/** Bad, missing, or wrong-environment API key (e.g. a pk_test_ key on a live route). */\nexport class AuthError extends PlaymosError {\n constructor(message = \"Invalid or missing API key.\", detail?: Record<string, unknown>) {\n super(\"auth\", message, detail);\n }\n}\n\n/** The Playmos service returned a non-2xx we don't have a more specific error for. */\nexport class ApiError extends PlaymosError {\n constructor(message: string, detail?: Record<string, unknown>) {\n super(\"api_error\", message, detail);\n }\n}\n\n/** SDK misconfiguration (e.g. a missing contract address for on-chain mode). */\nexport class ConfigError extends PlaymosError {\n constructor(message: string, detail?: Record<string, unknown>) {\n super(\"config\", message, detail);\n }\n}\n\n/**\n * PrizePool.withdraw() would transfer 0 (NothingToWithdraw) — pre-check or on-chain.\n * Issue #41: typed surface so studios never show a raw contract revert to winners.\n */\nexport class NothingToWithdrawError extends PlaymosError {\n constructor(detail?: Record<string, unknown>) {\n super(\n \"nothing_to_withdraw\",\n \"Nothing to withdraw — this wallet has no credited prize balance on this PrizePool (round not settled for them, or already claimed).\",\n detail,\n );\n }\n}\n","/**\n * Webhook signature verification (spec §6.2) — server-side only.\n *\n * Signature scheme (mirrors the Playmos service byte-for-byte):\n * header `X-Playmos-Signature: t=<unixSeconds>,v1=<hex>`\n * where <hex> = HMAC_SHA256(secret, `${t}.${rawBody}`)\n *\n * Verify BEFORE trusting an event. Uses node:crypto (constant-time compare) and\n * rejects stale timestamps to blunt replay. Throws on any mismatch.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { PlaymosError } from \"./errors.js\";\nimport type { WebhookEvent } from \"./types.js\";\n\nexport class WebhookSignatureError extends PlaymosError {\n constructor(message: string) {\n super(\"api_error\", `Webhook signature verification failed: ${message}`);\n }\n}\n\nfunction parseHeader(header: string): { t: number; v1: string } {\n const parts = Object.fromEntries(\n header.split(\",\").map((kv) => {\n const [k, v] = kv.split(\"=\");\n return [k?.trim(), v?.trim()];\n }),\n );\n const t = Number(parts[\"t\"]);\n const v1 = parts[\"v1\"];\n if (!Number.isFinite(t) || !v1) throw new WebhookSignatureError(\"malformed signature header\");\n return { t, v1 };\n}\n\nfunction computeSignature(secret: string, t: number, rawBody: string): string {\n return createHmac(\"sha256\", secret).update(`${t}.${rawBody}`).digest(\"hex\");\n}\n\n/**\n * Verify a webhook and return the parsed event. `rawBody` MUST be the exact raw\n * request bytes (use express.raw / fastify rawBody) — a re-serialized JSON body\n * will not match the signature.\n */\nexport function verifyWebhook(\n rawBody: string | Buffer,\n signatureHeader: string | string[] | undefined,\n secret: string,\n opts: { toleranceSeconds?: number } = {},\n): WebhookEvent {\n if (!signatureHeader || Array.isArray(signatureHeader)) {\n throw new WebhookSignatureError(\"missing signature header\");\n }\n if (!secret) throw new WebhookSignatureError(\"missing signing secret\");\n\n const body = typeof rawBody === \"string\" ? rawBody : rawBody.toString(\"utf8\");\n const { t, v1 } = parseHeader(signatureHeader);\n\n const tolerance = opts.toleranceSeconds ?? 300;\n const nowSec = Math.floor(Date.now() / 1000);\n if (Math.abs(nowSec - t) > tolerance) {\n throw new WebhookSignatureError(`timestamp outside tolerance (${tolerance}s)`);\n }\n\n const expected = computeSignature(secret, t, body);\n const a = Buffer.from(expected, \"hex\");\n const b = Buffer.from(v1, \"hex\");\n if (a.length !== b.length || !timingSafeEqual(a, b)) {\n throw new WebhookSignatureError(\"signature mismatch\");\n }\n\n return JSON.parse(body) as WebhookEvent;\n}\n"]}
|
package/dist/server.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhooks.ts"],"names":[],"mappings":";;;AAeO,IAAM,qBAAA,GAAN,cAAoC,YAAA,CAAa;AAAA,EACtD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,WAAA,EAAa,CAAA,uCAAA,EAA0C,OAAO,CAAA,CAAE,CAAA;AAAA,EACxE;AACF;AAEA,SAAS,YAAY,MAAA,EAA2C;AAC9D,EAAA,MAAM,QAAQ,MAAA,CAAO,WAAA;AAAA,IACnB,OAAO,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,EAAA,KAAO;AAC5B,MAAA,MAAM,CAAC,CAAA,EAAG,CAAC,CAAA,GAAI,EAAA,CAAG,MAAM,GAAG,CAAA;AAC3B,MAAA,OAAO,CAAC,CAAA,EAAG,IAAA,EAAK,EAAG,CAAA,EAAG,MAAM,CAAA;AAAA,IAC9B,CAAC;AAAA,GACH;AACA,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAC,CAAA;AAC3B,EAAA,MAAM,EAAA,GAAK,MAAM,IAAI,CAAA;AACrB,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAC,EAAA,EAAI,MAAM,IAAI,qBAAA,CAAsB,4BAA4B,CAAA;AAC5F,EAAA,OAAO,EAAE,GAAG,EAAA,EAAG;AACjB;AAEA,SAAS,gBAAA,CAAiB,MAAA,EAAgB,CAAA,EAAW,OAAA,EAAyB;AAC5E,EAAA,OAAO,UAAA,CAAW,QAAA,EAAU,MAAM,CAAA,CAAE,MAAA,CAAO,CAAA,EAAG,CAAC,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AAC5E;AAOO,SAAS,cACd,OAAA,EACA,eAAA,EACA,MAAA,EACA,IAAA,GAAsC,EAAC,EACzB;AACd,EAAA,IAAI,CAAC,eAAA,IAAmB,KAAA,CAAM,OAAA,CAAQ,eAAe,CAAA,EAAG;AACtD,IAAA,MAAM,IAAI,sBAAsB,0BAA0B,CAAA;AAAA,EAC5D;AACA,EAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,sBAAsB,wBAAwB,CAAA;AAErE,EAAA,MAAM,OAAO,OAAO,OAAA,KAAY,WAAW,OAAA,GAAU,OAAA,CAAQ,SAAS,MAAM,CAAA;AAC5E,EAAA,MAAM,EAAE,CAAA,EAAG,EAAA,EAAG,GAAI,YAAY,eAAe,CAAA;AAE7C,EAAA,MAAM,SAAA,GAAY,KAAK,gBAAA,IAAoB,GAAA;AAC3C,EAAA,MAAM,SAAS,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AAC3C,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,MAAA,GAAS,CAAC,IAAI,SAAA,EAAW;AACpC,IAAA,MAAM,IAAI,qBAAA,CAAsB,CAAA,6BAAA,EAAgC,SAAS,CAAA,EAAA,CAAI,CAAA;AAAA,EAC/E;AAEA,EAAA,MAAM,QAAA,GAAW,gBAAA,CAAiB,MAAA,EAAQ,CAAA,EAAG,IAAI,CAAA;AACjD,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AACrC,EAAA,MAAM,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,EAAA,EAAI,KAAK,CAAA;AAC/B,EAAA,IAAI,CAAA,CAAE,WAAW,CAAA,CAAE,MAAA,IAAU,CAAC,eAAA,CAAgB,CAAA,EAAG,CAAC,CAAA,EAAG;AACnD,IAAA,MAAM,IAAI,sBAAsB,oBAAoB,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AACxB","file":"server.js","sourcesContent":["/**\n * Webhook signature verification (spec §6.2) — server-side only.\n *\n * Signature scheme (mirrors the Playmos service byte-for-byte):\n * header `X-Playmos-Signature: t=<unixSeconds>,v1=<hex>`\n * where <hex> = HMAC_SHA256(secret, `${t}.${rawBody}`)\n *\n * Verify BEFORE trusting an event. Uses node:crypto (constant-time compare) and\n * rejects stale timestamps to blunt replay. Throws on any mismatch.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { PlaymosError } from \"./errors.js\";\nimport type { WebhookEvent } from \"./types.js\";\n\nexport class WebhookSignatureError extends PlaymosError {\n constructor(message: string) {\n super(\"api_error\", `Webhook signature verification failed: ${message}`);\n }\n}\n\nfunction parseHeader(header: string): { t: number; v1: string } {\n const parts = Object.fromEntries(\n header.split(\",\").map((kv) => {\n const [k, v] = kv.split(\"=\");\n return [k?.trim(), v?.trim()];\n }),\n );\n const t = Number(parts[\"t\"]);\n const v1 = parts[\"v1\"];\n if (!Number.isFinite(t) || !v1) throw new WebhookSignatureError(\"malformed signature header\");\n return { t, v1 };\n}\n\nfunction computeSignature(secret: string, t: number, rawBody: string): string {\n return createHmac(\"sha256\", secret).update(`${t}.${rawBody}`).digest(\"hex\");\n}\n\n/**\n * Verify a webhook and return the parsed event. `rawBody` MUST be the exact raw\n * request bytes (use express.raw / fastify rawBody) — a re-serialized JSON body\n * will not match the signature.\n */\nexport function verifyWebhook(\n rawBody: string | Buffer,\n signatureHeader: string | string[] | undefined,\n secret: string,\n opts: { toleranceSeconds?: number } = {},\n): WebhookEvent {\n if (!signatureHeader || Array.isArray(signatureHeader)) {\n throw new WebhookSignatureError(\"missing signature header\");\n }\n if (!secret) throw new WebhookSignatureError(\"missing signing secret\");\n\n const body = typeof rawBody === \"string\" ? rawBody : rawBody.toString(\"utf8\");\n const { t, v1 } = parseHeader(signatureHeader);\n\n const tolerance = opts.toleranceSeconds ?? 300;\n const nowSec = Math.floor(Date.now() / 1000);\n if (Math.abs(nowSec - t) > tolerance) {\n throw new WebhookSignatureError(`timestamp outside tolerance (${tolerance}s)`);\n }\n\n const expected = computeSignature(secret, t, body);\n const a = Buffer.from(expected, \"hex\");\n const b = Buffer.from(v1, \"hex\");\n if (a.length !== b.length || !timingSafeEqual(a, b)) {\n throw new WebhookSignatureError(\"signature mismatch\");\n }\n\n return JSON.parse(body) as WebhookEvent;\n}\n"]}
|