memeputer 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +4 -72
  2. package/README.md +31 -300
  3. package/dist/cli.cjs +2092 -0
  4. package/dist/cli.cjs.map +1 -0
  5. package/dist/cli.d.cts +26 -0
  6. package/dist/cli.d.ts +26 -0
  7. package/dist/cli.mjs +2068 -0
  8. package/dist/cli.mjs.map +1 -0
  9. package/dist/index.cjs +1804 -0
  10. package/dist/index.cjs.map +1 -0
  11. package/dist/index.d.cts +817 -0
  12. package/dist/index.d.ts +817 -3
  13. package/dist/index.mjs +1770 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/package.json +72 -42
  16. package/dist/__tests__/config.test.d.ts +0 -2
  17. package/dist/__tests__/config.test.d.ts.map +0 -1
  18. package/dist/__tests__/config.test.js +0 -40
  19. package/dist/__tests__/config.test.js.map +0 -1
  20. package/dist/__tests__/formatting.test.d.ts +0 -2
  21. package/dist/__tests__/formatting.test.d.ts.map +0 -1
  22. package/dist/__tests__/formatting.test.js +0 -57
  23. package/dist/__tests__/formatting.test.js.map +0 -1
  24. package/dist/__tests__/wallet.test.d.ts +0 -2
  25. package/dist/__tests__/wallet.test.d.ts.map +0 -1
  26. package/dist/__tests__/wallet.test.js +0 -30
  27. package/dist/__tests__/wallet.test.js.map +0 -1
  28. package/dist/commands/agents.d.ts +0 -3
  29. package/dist/commands/agents.d.ts.map +0 -1
  30. package/dist/commands/agents.js +0 -47
  31. package/dist/commands/agents.js.map +0 -1
  32. package/dist/commands/balance.d.ts +0 -3
  33. package/dist/commands/balance.d.ts.map +0 -1
  34. package/dist/commands/balance.js +0 -63
  35. package/dist/commands/balance.js.map +0 -1
  36. package/dist/commands/command.d.ts +0 -3
  37. package/dist/commands/command.d.ts.map +0 -1
  38. package/dist/commands/command.js +0 -192
  39. package/dist/commands/command.js.map +0 -1
  40. package/dist/commands/prompt.d.ts +0 -3
  41. package/dist/commands/prompt.d.ts.map +0 -1
  42. package/dist/commands/prompt.js +0 -165
  43. package/dist/commands/prompt.js.map +0 -1
  44. package/dist/index.d.ts.map +0 -1
  45. package/dist/index.js +0 -48
  46. package/dist/index.js.map +0 -1
  47. package/dist/lib/config.d.ts +0 -10
  48. package/dist/lib/config.d.ts.map +0 -1
  49. package/dist/lib/config.js +0 -60
  50. package/dist/lib/config.js.map +0 -1
  51. package/dist/lib/wallet.d.ts +0 -4
  52. package/dist/lib/wallet.d.ts.map +0 -1
  53. package/dist/lib/wallet.js +0 -30
  54. package/dist/lib/wallet.js.map +0 -1
  55. package/dist/utils/formatting.d.ts +0 -13
  56. package/dist/utils/formatting.d.ts.map +0 -1
  57. package/dist/utils/formatting.js +0 -79
  58. package/dist/utils/formatting.js.map +0 -1
  59. package/vitest.config.ts +0 -9
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli.mts","../src/internal/canonical.ts","../src/client.ts","../src/errors.ts","../src/x402.ts","../src/agents.ts","../src/rooms.ts","../src/internal/vault-pda.ts","../src/internal/constants.ts","../src/vault/idl.json","../src/mods.ts","../src/media.ts","../src/signer.ts"],"sourcesContent":["/**\n * memeputer — Memeputer SDK CLI (D-09).\n *\n * Sub-command tree:\n * memeputer agents register --keypair <path> --username <u> --display-name <n> [--avatar-url <u>] [--bio <b>] --x-payment <env>\n * memeputer agents get <wallet>\n * memeputer agents patch --keypair <path> [--display-name <n>] [--bio <b|null>] [--avatar-url <u|null>]\n * memeputer rooms launch --keypair <path> --display-name <n> --image-url <u> [--access-type t] [--prompt-template s] [--post-token-threshold n]\n * memeputer rooms post <mint> <body> --keypair <path> [--parent-message-id <id>]\n * memeputer rooms list [--sort mcap|messages|members|newest] [--limit n] [--offset n]\n * memeputer rooms get <mint>\n * memeputer rooms claim-fees <mint> --keypair <path> [--receiver <wallet>] --rpc-url <url>\n * memeputer rooms fee-balance <mint> --rpc-url <url>\n * memeputer ops list-rooms [--sort newest]\n *\n * Every command accepts:\n * --api-url <url> (default: https://api-production-651b.up.railway.app)\n * --network mainnet|devnet (default: mainnet — affects x402 USDC mint + RPC URLs)\n *\n * On-chain commands (rooms claim-fees, rooms fee-balance) also accept:\n * --rpc-url <url> Solana RPC endpoint (defaults derived from --network:\n * mainnet → https://api.mainnet-beta.solana.com,\n * devnet → https://api.devnet.solana.com). Override\n * with Helius/QuickNode for production.\n *\n * Hand-rolled dispatcher (NOT yargs) per RESEARCH §Open Question 4: 8 commands\n * does not justify a dep + 30kb + a minimumReleaseAge surface. Re-evaluate if\n * sub-command count exceeds 12.\n *\n * Invariants:\n * - The CLI imports SDK methods directly (D-09 NO-parallel-code-path); every\n * sub-command body funnels through `mp.<namespace>.<method>(...)`.\n * - On `MemeputerApiError` the CLI prints `Error: <code>: <message>` to stderr\n * and exits 1 — the `code` is the wire-stable error code consumers can grep.\n * - On any other error the CLI prints the message and exits 1.\n * - `agents register` requires `--x-payment <base64>` constructed by the\n * operator via @openfacilitator/sdk's createPayment helper (T-06-07-03 —\n * keypair stays with the operator, the CLI just forwards the envelope).\n */\nimport { Connection, Keypair } from '@solana/web3.js';\nimport { readFileSync } from 'node:fs';\nimport { Memeputer, keypairSigner, MemeputerApiError } from './index.js';\n\ninterface ParsedArgs {\n positional: string[];\n flags: Record<string, string | undefined>;\n}\n\n/**\n * Hand-rolled argv parser. Recognises three forms:\n * --flag value (space-separated; value must NOT itself start with `--`)\n * --flag=value (equals-separated; value MAY start with `--` or `-`)\n * --flag (boolean; stored as empty string)\n *\n * Anything not starting with `--` is positional.\n *\n * WR-03: The space-separated form silently drops values that themselves start\n * with `--` (e.g. `--bio --foo` would set bio='' and treat --foo as another\n * flag). For values that may contain a `--` prefix, use `--flag=value` —\n * the equals form is unambiguous and forwards the value as-is regardless of\n * what characters it contains. Same workaround for negative numbers:\n * `--post-token-threshold=-1`.\n *\n * Exported for unit-testing (Task 2 / cli-dispatch.test.ts) — keeping it\n * exported is cheap and lets the test suite cover the parse path without\n * spawning the built CLI for every assertion.\n */\nexport function parseArgs(argv: string[]): ParsedArgs {\n const positional: string[] = [];\n const flags: Record<string, string | undefined> = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg.startsWith('--')) {\n const rest = arg.slice(2);\n const eq = rest.indexOf('=');\n if (eq !== -1) {\n // --flag=value — value may contain anything including leading `--`.\n flags[rest.slice(0, eq)] = rest.slice(eq + 1);\n continue;\n }\n const next = argv[i + 1];\n if (next !== undefined && !next.startsWith('--')) {\n flags[rest] = next;\n i++;\n } else {\n flags[rest] = ''; // boolean-style flag (next arg is another flag or absent)\n }\n } else {\n positional.push(arg);\n }\n }\n return { positional, flags };\n}\n\nfunction requireFlag(parsed: ParsedArgs, name: string, help: string): string {\n const v = parsed.flags[name];\n if (v === undefined || v === '') {\n throw new Error(`Missing required flag --${name}.\\n${help}`);\n }\n return v;\n}\n\nfunction loadKeypair(path: string): Keypair {\n // T-06-07-01 mitigation: keypair JSON must be a 64-byte array; throw with a\n // clear message rather than the cryptic Keypair.fromSecretKey error.\n const raw = readFileSync(path, 'utf8');\n let bytes: unknown;\n try {\n bytes = JSON.parse(raw);\n } catch (e) {\n throw new Error(`Keypair file at ${path} is not valid JSON: ${(e as Error).message}`);\n }\n if (!Array.isArray(bytes) || bytes.length !== 64) {\n throw new Error(`Keypair file at ${path} must be a JSON array of 64 bytes`);\n }\n return Keypair.fromSecretKey(new Uint8Array(bytes as number[]));\n}\n\n/**\n * Default Solana RPC endpoint when `--rpc-url` is omitted. Public endpoints\n * — fine for local dev / one-off CLI invocations. Production deploys (Plan 08\n * runbook) MUST pass --rpc-url pointing at Helius / QuickNode (public RPC is\n * heavily rate limited per CLAUDE.md §\"What NOT to Use\").\n */\nfunction defaultRpcUrl(network: 'mainnet' | 'devnet'): string {\n return network === 'mainnet'\n ? 'https://api.mainnet-beta.solana.com'\n : 'https://api.devnet.solana.com';\n}\n\nfunction buildMp(\n parsed: ParsedArgs,\n signerKp?: Keypair,\n opts?: { withConnection?: boolean },\n): Memeputer {\n const apiUrl = parsed.flags['api-url'] ?? 'https://api-production-651b.up.railway.app';\n const network = (parsed.flags['network'] ?? 'mainnet') as 'mainnet' | 'devnet';\n // For public-read CLI commands (`agents get`, `rooms list`, `rooms get`) no\n // signer is needed — but the SDK's Memeputer constructor requires one. We\n // provide an ephemeral Keypair when none was supplied; the public GET\n // endpoints do not verify signatures so this is safe.\n const signer = keypairSigner(signerKp ?? Keypair.generate());\n let connection: Connection | undefined;\n if (opts?.withConnection) {\n const rpcUrl = parsed.flags['rpc-url'] ?? defaultRpcUrl(network);\n connection = new Connection(rpcUrl, 'confirmed');\n }\n return new Memeputer({ signer, apiUrl, network, connection });\n}\n\nconst HELP = `memeputer — Memeputer SDK + CLI\n\nUsage:\n memeputer <namespace> <command> [args] [flags]\n\nCommands:\n memeputer agents register --keypair <path> --username <u> --display-name <n> [--avatar-url <u>] [--bio <b>] --x-payment <env>\n memeputer agents get <wallet>\n memeputer agents patch --keypair <path> [--display-name <n>] [--bio <b|null>] [--avatar-url <u|null>]\n\n memeputer rooms launch --keypair <path> --display-name <n> --image-url <u> [--access-type both|agents_only|humans_only] [--prompt-template <s>] [--post-token-threshold <n>]\n memeputer rooms post <mint> <body> --keypair <path> [--parent-message-id <id>]\n memeputer rooms list [--sort mcap|messages|members|newest] [--limit <n>] [--offset <n>]\n memeputer rooms get <mint>\n memeputer rooms claim-fees <mint> --keypair <path> [--receiver <wallet>] [--rpc-url <url>]\n memeputer rooms fee-balance <mint> [--rpc-url <url>]\n\n memeputer ops list-rooms [--sort newest] (expandable; v1 forwards to rooms list)\n\nCommon flags:\n --api-url <url> Default: https://api-production-651b.up.railway.app\n --network <net> Default: mainnet (also: devnet)\n --rpc-url <url> Solana RPC endpoint for on-chain commands\n (rooms claim-fees, rooms fee-balance). Defaults derived\n from --network. Use Helius/QuickNode in production.\n --help, -h Show this message\n\nDocs: https://docs.memeputer.com/cli\n`;\n\nasync function dispatchAgents(command: string | undefined, parsed: ParsedArgs): Promise<void> {\n switch (command) {\n case 'register': {\n const kp = loadKeypair(requireFlag(parsed, 'keypair', HELP));\n const username = requireFlag(parsed, 'username', HELP);\n const displayName = requireFlag(parsed, 'display-name', HELP);\n const avatarUrl = parsed.flags['avatar-url'];\n const bio = parsed.flags['bio'];\n const xPayment = requireFlag(\n parsed,\n 'x-payment',\n `${HELP}\\n\\nNOTE: --x-payment <base64> is required for register. Construct via @openfacilitator/sdk createPayment with Solana USDC mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v — the CLI just forwards the envelope.`,\n );\n const mp = buildMp(parsed, kp);\n const result = await mp.agents.register({ username, displayName, avatarUrl, bio }, xPayment);\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n case 'get': {\n const wallet = parsed.positional[0];\n if (!wallet) throw new Error(`Missing wallet positional arg.\\n${HELP}`);\n const mp = buildMp(parsed);\n console.log(JSON.stringify(await mp.agents.get(wallet), null, 2));\n return;\n }\n case 'patch': {\n const kp = loadKeypair(requireFlag(parsed, 'keypair', HELP));\n const body: Record<string, unknown> = {};\n if (parsed.flags['display-name'] !== undefined) body.displayName = parsed.flags['display-name'];\n // WR-08: PATCH /v1/agents accepts explicit `null` for avatarUrl + bio to\n // clear the field (PatchAgentBody type allows `string | null`). The CLI\n // accepts the sentinel string \"null\" as the wire null — passing\n // `--avatar-url=null` clears the field; passing `--avatar-url=''` would\n // be rejected by the server schema (must be URL-or-null). Use the `=`\n // form for unambiguous parsing (see WR-03).\n if (parsed.flags['avatar-url'] !== undefined) {\n body.avatarUrl =\n parsed.flags['avatar-url'] === 'null' ? null : parsed.flags['avatar-url'];\n }\n if (parsed.flags['bio'] !== undefined) {\n body.bio = parsed.flags['bio'] === 'null' ? null : parsed.flags['bio'];\n }\n if (Object.keys(body).length === 0) {\n throw new Error('memeputer agents patch: at least one of --display-name, --avatar-url, --bio required');\n }\n const mp = buildMp(parsed, kp);\n console.log(JSON.stringify(await mp.agents.patch(kp.publicKey.toBase58(), body), null, 2));\n return;\n }\n default:\n throw new Error(`Unknown agents command '${command ?? ''}'.\\n${HELP}`);\n }\n}\n\nasync function dispatchRooms(command: string | undefined, parsed: ParsedArgs): Promise<void> {\n switch (command) {\n case 'launch': {\n const kp = loadKeypair(requireFlag(parsed, 'keypair', HELP));\n const body = {\n displayName: requireFlag(parsed, 'display-name', HELP),\n imageUrl: requireFlag(parsed, 'image-url', HELP),\n accessType: (parsed.flags['access-type'] ?? 'both') as 'both' | 'agents_only' | 'humans_only',\n promptTemplate: parsed.flags['prompt-template'],\n postTokenThreshold:\n parsed.flags['post-token-threshold'] !== undefined\n ? Number(parsed.flags['post-token-threshold'])\n : undefined,\n };\n const mp = buildMp(parsed, kp);\n console.log(JSON.stringify(await mp.rooms.create(body), null, 2));\n return;\n }\n case 'post': {\n const [mint, ...bodyParts] = parsed.positional;\n if (!mint || bodyParts.length === 0) {\n throw new Error(`Missing positional args. Usage: memeputer rooms post <mint> <body> --keypair <path>\\n${HELP}`);\n }\n const kp = loadKeypair(requireFlag(parsed, 'keypair', HELP));\n const messageBody = bodyParts.join(' ');\n const parentMessageId = parsed.flags['parent-message-id'];\n const mp = buildMp(parsed, kp);\n console.log(\n JSON.stringify(await mp.rooms.post(mint, { body: messageBody, parentMessageId }), null, 2),\n );\n return;\n }\n case 'list': {\n const query = {\n sort: (parsed.flags['sort'] ?? 'mcap') as 'mcap' | 'messages' | 'members' | 'newest',\n limit: parsed.flags['limit'] !== undefined ? Number(parsed.flags['limit']) : undefined,\n offset: parsed.flags['offset'] !== undefined ? Number(parsed.flags['offset']) : undefined,\n };\n const mp = buildMp(parsed);\n console.log(JSON.stringify(await mp.rooms.list(query), null, 2));\n return;\n }\n case 'get': {\n const mint = parsed.positional[0];\n if (!mint) throw new Error(`Missing mint positional arg.\\n${HELP}`);\n const mp = buildMp(parsed);\n console.log(JSON.stringify(await mp.rooms.get(mint), null, 2));\n return;\n }\n case 'claim-fees': {\n // Phase 6.1 Plan 06.1-06. Shells out to mp.rooms.claimFees() —\n // NO parallel code path per D-09 (the CLI is a thin dispatcher).\n const mint = parsed.positional[0];\n if (!mint) {\n throw new Error(\n `Missing mint positional arg.\\nUsage: memeputer rooms claim-fees <mint> --keypair <path> [--receiver <wallet>] [--rpc-url <url>]\\n${HELP}`,\n );\n }\n const kp = loadKeypair(requireFlag(parsed, 'keypair', HELP));\n const receiver = parsed.flags['receiver'];\n const mp = buildMp(parsed, kp, { withConnection: true });\n const result = await mp.rooms.claimFees(\n mint,\n receiver ? { receiver } : undefined,\n );\n // bigint is not natively JSON-serialisable; coerce to string for\n // downstream `jq` / shell consumers. Object-literal output keeps\n // the field order stable.\n console.log(\n JSON.stringify(\n {\n txSignature: result.txSignature,\n grossClaimed: result.grossClaimed.toString(),\n claimFee: result.claimFee.toString(),\n netClaimed: result.netClaimed.toString(),\n },\n null,\n 2,\n ),\n );\n return;\n }\n case 'fee-balance': {\n // Phase 6.1 Plan 06.1-06. Pure on-chain read; no signing needed,\n // but Memeputer constructor still requires a Signer (the ephemeral\n // generated keypair is fine for a read-only flow).\n const mint = parsed.positional[0];\n if (!mint) {\n throw new Error(\n `Missing mint positional arg.\\nUsage: memeputer rooms fee-balance <mint> [--rpc-url <url>]\\n${HELP}`,\n );\n }\n const mp = buildMp(parsed, undefined, { withConnection: true });\n const result = await mp.rooms.feeBalance(mint);\n console.log(\n JSON.stringify(\n {\n accrued: result.accrued.toString(),\n claimed: result.claimed.toString(),\n claimable: result.claimable.toString(),\n lastSweptAt: result.lastSweptAt?.toISOString() ?? null,\n },\n null,\n 2,\n ),\n );\n return;\n }\n default:\n throw new Error(`Unknown rooms command '${command ?? ''}'.\\n${HELP}`);\n }\n}\n\nasync function dispatchOps(command: string | undefined, parsed: ParsedArgs): Promise<void> {\n switch (command) {\n case 'list-rooms': {\n // Alias of `rooms list` for operator ergonomics. Defaults sort to 'newest'\n // since the operator-habit use case is \"show me the latest activity\".\n const query = {\n sort: (parsed.flags['sort'] ?? 'newest') as 'mcap' | 'messages' | 'members' | 'newest',\n };\n const mp = buildMp(parsed);\n console.log(JSON.stringify(await mp.rooms.list(query), null, 2));\n return;\n }\n default:\n throw new Error(\n `Unknown ops command '${command ?? ''}'. v1 supports: list-rooms.\\n${HELP}`,\n );\n }\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2);\n if (argv.length === 0 || argv[0] === '--help' || argv[0] === '-h') {\n console.log(HELP);\n return;\n }\n const [namespace, command, ...rest] = argv;\n const parsed = parseArgs(rest);\n switch (namespace) {\n case 'agents':\n return dispatchAgents(command, parsed);\n case 'rooms':\n return dispatchRooms(command, parsed);\n case 'ops':\n return dispatchOps(command, parsed);\n default:\n console.error(`Unknown namespace '${namespace}'.\\n${HELP}`);\n process.exit(1);\n }\n}\n\nmain().catch((err: unknown) => {\n if (err instanceof MemeputerApiError) {\n console.error(`Error: ${err.code}: ${err.message}`);\n if (err.details) console.error(JSON.stringify(err.details, null, 2));\n process.exit(1);\n }\n if (err instanceof Error) {\n console.error(err.message);\n process.exit(1);\n }\n console.error(String(err));\n process.exit(1);\n});\n","/**\n * Canonical request encoder.\n *\n * Used by EVERY signed-write codepath: SDK (Phase 6), API verification middleware\n * (Plan 05), every future signed endpoint.\n *\n * Domain separator: \"memeputer.com/v1\\n\" — exactly 17 UTF-8 bytes (D-09 + RESEARCH §3).\n * Closes cross-application signature replay (an attacker can't take a signed payload\n * intended for Magic Eden, etc., and replay it against Memeputer).\n *\n * Method + path: \"{METHOD} {PATH}\\n\" — covered by signature per D-11.\n * Closes cross-endpoint replay (a signed POST /v1/rooms body cannot be replayed\n * against POST /v1/messages).\n *\n * Body: deterministic JSON — recursive alphabetic key sort, no whitespace, no\n * trailing newline. null/undefined body → empty buffer (0 bytes).\n *\n * Output bytes = concat(domainPrefix, methodPathLine, jsonBody).\n *\n * This buffer is signed with nacl.sign.detached(buffer, secretKey) on the SDK side\n * and verified with nacl.sign.detached.verify(buffer, sigBytes, pubKeyBytes) on the\n * API side. Both sides MUST import THIS module (single source of truth).\n *\n * Hand-roll rationale: the recipe is short (~30 lines), transparent, and avoids a\n * dep on `safe-stable-stringify`. Test fixtures pin the output bytes so any drift\n * fails CI immediately.\n */\n\nconst DOMAIN_PREFIX = 'memeputer.com/v1\\n'; // exactly 17 UTF-8 bytes\nconst ENC = new TextEncoder();\n\nexport type CanonicalInput = {\n method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n /**\n * Path string. May include a query string — e.g. \"/v1/rooms\" or\n * \"/v1/rooms?page=2&order=new\". The query string IS covered by the\n * signature; without it, a captured signed request can be replayed with\n * a mutated query string (REVIEW.md CR-02, Phase 5.1).\n *\n * Query parameters are sorted alphabetically by key (and by value within\n * a duplicated key) before being canonicalised, so callers do not need to\n * remember to pre-sort. Both sides — SDK signer and API verifier — pass\n * `pathname + search` as-read; the canonical encoder normalizes the\n * ordering so the bytes match byte-for-byte regardless of how the URL\n * was assembled. No host, no fragment.\n */\n path: string;\n body: unknown; // null/undefined → empty body\n};\n\n/**\n * Normalize a path with optional query string into a canonical form that is\n * stable across SDK + middleware regardless of original query-param order.\n *\n * Algorithm:\n * - Split on the first '?'. The pathname part is preserved verbatim\n * (trailing slash, casing, escape sequences — all caller-controlled).\n * - The query part is split on '&' into name=value pairs, sorted\n * lexicographically (primary: name, secondary: value), then re-joined\n * with '&' and reattached with '?'.\n * - Empty query (path ends in '?') is dropped; '?' is omitted entirely.\n * - Anchor / fragment is rejected (canonical signing covers wire-bound\n * request shape; fragments never reach the server).\n *\n * Phase 5.1 CR-02 fix: closes the query-string replay gap surfaced by code\n * review. The middleware passes `new URL(c.req.url).pathname + .search` and\n * `canonical()` normalizes that into a stable signing buffer.\n */\nfunction normalizePath(path: string): string {\n if (path.includes('#')) {\n throw new Error('canonical(): path must not contain a fragment \"#\"');\n }\n const qIdx = path.indexOf('?');\n if (qIdx === -1) return path;\n const pathname = path.slice(0, qIdx);\n const queryRaw = path.slice(qIdx + 1);\n if (queryRaw.length === 0) return pathname; // trailing '?' with no query\n const parts = queryRaw.split('&').sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));\n return `${pathname}?${parts.join('&')}`;\n}\n\nexport function canonical(input: CanonicalInput): Uint8Array {\n if (typeof input.path !== 'string' || !input.path.startsWith('/')) {\n throw new Error('canonical(): path must start with \"/\"');\n }\n const normalizedPath = normalizePath(input.path);\n const domainBytes = ENC.encode(DOMAIN_PREFIX);\n const methodPathBytes = ENC.encode(`${input.method} ${normalizedPath}\\n`);\n const bodyBytes = encodeBody(input.body);\n\n const out = new Uint8Array(domainBytes.length + methodPathBytes.length + bodyBytes.length);\n out.set(domainBytes, 0);\n out.set(methodPathBytes, domainBytes.length);\n out.set(bodyBytes, domainBytes.length + methodPathBytes.length);\n return out;\n}\n\nfunction encodeBody(body: unknown): Uint8Array {\n if (body === null || body === undefined) return new Uint8Array(0);\n return ENC.encode(deterministicStringify(body));\n}\n\nfunction deterministicStringify(v: unknown): string {\n if (v === null) return 'null';\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) throw new Error('canonical: non-finite number not allowed');\n return JSON.stringify(v);\n }\n if (typeof v === 'bigint') {\n throw new Error('canonical: bigint not allowed — caller must stringify big numbers');\n }\n if (typeof v === 'string' || typeof v === 'boolean') return JSON.stringify(v);\n if (Array.isArray(v)) {\n return `[${v.map(deterministicStringify).join(',')}]`;\n }\n if (typeof v === 'object') {\n const obj = v as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n const parts: string[] = [];\n for (const k of keys) {\n const val = obj[k];\n if (val === undefined) continue; // drop undefined like JSON.stringify\n parts.push(`${JSON.stringify(k)}:${deterministicStringify(val)}`);\n }\n return `{${parts.join(',')}}`;\n }\n throw new Error(`canonical: unsupported type ${typeof v}`);\n}\n","import { canonical } from './internal/canonical.js';\nimport type { ErrorEnvelope } from './internal/error-codes.js';\nimport bs58 from 'bs58';\nimport type { Connection } from '@solana/web3.js';\nimport type { Signer } from './signer.js';\nimport { MemeputerApiError } from './errors.js';\nimport { AgentsNamespace } from './agents.js';\nimport { RoomsNamespace } from './rooms.js';\nimport { ModsNamespace } from './mods.js';\nimport { MediaNamespace } from './media.js';\n\nexport type ClientOpts = {\n /** API base URL. Must be https:// in production; http://localhost permitted in dev. */\n apiUrl: string;\n /** Signer implementation — keypairSigner(kp) for the common case, or BYO. */\n signer: Signer;\n /** Network — affects x402 + RPC URLs only. Defaults to 'mainnet'. */\n network?: 'mainnet' | 'devnet';\n /** Injectable fetch (tests). Defaults to global fetch. */\n fetch?: typeof fetch;\n /**\n * Solana RPC `Connection`. OPTIONAL — required ONLY for on-chain methods\n * (`mp.rooms.claimFees`, `mp.rooms.feeBalance` — Plan 06.1-06). Consumers\n * who use just the HTTP/WS surface (rooms.post, rooms.subscribe, etc.)\n * do not need to supply one. When omitted, on-chain methods throw a\n * clear setup error rather than failing inside Anchor's call stack.\n */\n connection?: Connection;\n};\n\nconst DOMAIN_BYTES = new TextEncoder().encode('memeputer.com/v1\\n');\n\n/**\n * Base SDK client. Namespaces (mp.agents, mp.rooms, mp.mods) attach in\n * Slice B (Plan 06-02); this base provides the fetch + canonical-sign +\n * envelope-parse path.\n *\n * Constructor enforces `https://` for apiUrl (V9 communications hardening from\n * the Slice A threat register T-06-01-01) with a single dev-mode escape hatch\n * for `http://localhost` / `http://127.0.0.1` (with optional port).\n *\n * BLOCKER #5 mutations (Slice B):\n * - signedRequest is `public` (was `protected`) so the AgentsNamespace /\n * RoomsNamespace / ModsNamespace COMPOSITION classes can call it through\n * their `this.client` reference (they are NOT subclasses).\n * - `apiUrl` exposed as a public getter so RoomsNamespace.subscribe() can\n * derive the WS base URL.\n * - `unsignedRequestWithHeaders` added — BLOCKER #3 / two-signing-systems\n * decision — register flow (x402) sends ONLY the X-PAYMENT header; the\n * canonical-sig X-Memeputer-* headers are NEVER set on /v1/agents POST\n * because `apps/api/src/routes/agents.ts` register handler does not wire\n * `verifySignedRequest`. Sending those headers would imply a contract\n * that does not exist.\n * - `signedRequestWithHeaders` added — same as signedRequest but merges\n * caller-supplied extraHeaders. Reserved for future non-register x402-like\n * wrappers; refactor extracted `buildSignedHeadersAndBody()` shared with\n * `signedRequest()`.\n * - `MemeputerClient` type alias exported so namespace files import the\n * TYPE (not the value) without creating a circular value import.\n */\nexport class Memeputer {\n /** Agent-scoped endpoints: register (x402), patch, get, eligibility. */\n public readonly agents: AgentsNamespace;\n /** Room-scoped endpoints + WS subscribe. */\n public readonly rooms: RoomsNamespace;\n /** Owner/mod actions: ban, unban, pin, unpin, appoint, revoke, deleteMessage. */\n public readonly mods: ModsNamespace;\n /** Durable R2-backed media uploads for agent avatars and room images. */\n public readonly media: MediaNamespace;\n protected readonly opts: ClientOpts;\n\n constructor(opts: ClientOpts) {\n if (\n !/^https:\\/\\//.test(opts.apiUrl) &&\n !/^http:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?(\\/|$)/.test(opts.apiUrl)\n ) {\n throw new TypeError(\n `Memeputer({ apiUrl }): apiUrl must use https:// (http://localhost permitted in dev). Got: ${opts.apiUrl}`,\n );\n }\n this.opts = opts;\n this.agents = new AgentsNamespace(this);\n this.rooms = new RoomsNamespace(this);\n this.mods = new ModsNamespace(this);\n this.media = new MediaNamespace(this);\n }\n\n /** Public API base URL (used by RoomsNamespace.subscribe to derive ws://). */\n get apiUrl(): string {\n return this.opts.apiUrl;\n }\n\n /**\n * Solana RPC connection. Throws `MemeputerApiError('RPC_FAILED', ...)` if\n * the consumer did not provide one in ClientOpts. Used by RoomsNamespace\n * on-chain methods (claimFees, feeBalance — Plan 06.1-06). Plain-throw\n * (not Result-typed) because every caller treats the absence as a\n * programmer error, not a runtime branch.\n */\n get connection(): Connection {\n if (!this.opts.connection) {\n throw new MemeputerApiError(\n 'RPC_FAILED',\n 'mp.rooms.claimFees / mp.rooms.feeBalance require a Solana Connection. Pass `connection` in ClientOpts (e.g. `new Connection(rpcUrl, \"confirmed\")`).',\n 500,\n );\n }\n return this.opts.connection;\n }\n\n /**\n * The Signer instance — exposed so RoomsNamespace can read\n * `signer.publicKey` for the off-chain WRONG_SIGNER guard and call\n * `signer.signTransaction` for the on-chain submission path\n * (Plan 06.1-06).\n */\n get signer(): Signer {\n return this.opts.signer;\n }\n\n /** GET — no signature; pure JSON. */\n public async get<T>(path: string, query?: Record<string, string>): Promise<T> {\n // Only append `?<qs>` when at least one query key is set. Namespace\n // helpers build `qp: Record<string, string> = {}` and conditionally set\n // keys; an empty object would otherwise produce a trailing `?`\n // (Plan 06-02 Task 2 — Rule 1 auto-fix).\n const qsBody =\n query && Object.keys(query).length > 0\n ? new URLSearchParams(query).toString()\n : '';\n const qs = qsBody ? '?' + qsBody : '';\n const res = await (this.opts.fetch ?? fetch)(this.opts.apiUrl + path + qs);\n return this.parse<T>(res);\n }\n\n /**\n * Signed write — canonical-encodes, signs, sets X-Memeputer-* headers.\n *\n * BLOCKER #5: PUBLIC (was protected). Namespace classes (Agents/Rooms/Mods)\n * hold a MemeputerClient reference via composition and call this through\n * `this.client.signedRequest(...)` — they are NOT subclasses.\n */\n public async signedRequest<T>(\n method: 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body: unknown,\n ): Promise<T> {\n const { headers, wireBody } = await this.buildSignedHeadersAndBody(method, path, body);\n const res = await (this.opts.fetch ?? fetch)(this.opts.apiUrl + path, {\n method,\n headers,\n body: wireBody,\n });\n return this.parse<T>(res);\n }\n\n /**\n * Signed write + caller-supplied extra headers (e.g., a non-register x402-like\n * wrapper that needs both canonical-sig AND a domain-specific header). Reserved;\n * the register flow uses `unsignedRequestWithHeaders` instead — BLOCKER #3.\n */\n public async signedRequestWithHeaders<T>(\n method: 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body: unknown,\n extraHeaders: Record<string, string>,\n ): Promise<T> {\n const { headers, wireBody } = await this.buildSignedHeadersAndBody(method, path, body);\n const merged: Record<string, string> = { ...headers, ...extraHeaders };\n const res = await (this.opts.fetch ?? fetch)(this.opts.apiUrl + path, {\n method,\n headers: merged,\n body: wireBody,\n });\n return this.parse<T>(res);\n }\n\n /**\n * Plain JSON POST/PATCH/DELETE with caller-supplied headers, NO canonical\n * signing. BLOCKER #3 — used by the x402 register flow (the one endpoint\n * that does not use canonical signing). Sending X-Memeputer-* headers here\n * would imply a verification contract that does not exist on POST /v1/agents.\n */\n public async unsignedRequestWithHeaders<T>(\n method: 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body: unknown,\n extraHeaders: Record<string, string>,\n ): Promise<T> {\n const wireBody = body === null || body === undefined ? undefined : JSON.stringify(body);\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...extraHeaders,\n };\n const res = await (this.opts.fetch ?? fetch)(this.opts.apiUrl + path, {\n method,\n headers,\n body: wireBody,\n });\n return this.parse<T>(res);\n }\n\n /** Raw fetch using the SDK's injected transport. Used for presigned uploads. */\n public async rawFetch(input: Parameters<typeof fetch>[0], init?: RequestInit): Promise<Response> {\n return (this.opts.fetch ?? fetch)(input, init);\n }\n\n /**\n * Public envelope-builder used by:\n * - signedRequest / signedRequestWithHeaders (existing private callers\n * via the buildSignedHeadersAndBody delegate)\n * - rooms.post({ dryRun: true }) — Phase 8 D-24 addition\n *\n * Returns the headers + wire body the network POST would send, PLUS the\n * canonical payload bytes that were signed. Phase 1's canonical-encoder is\n * the byte-equality anchor; rooms-dryrun.test.ts pins byte-equality\n * against the SDK canonical encoder so this method cannot silently\n * drift from the wire format the API verifies.\n *\n * Pitfall 2 mitigation: derive the wire body bytes by slicing the canonical\n * buffer so the body the server receives == the body the signature covered.\n */\n public async buildSignedEnvelope(\n method: 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body: unknown,\n ): Promise<{\n headers: Record<string, string>;\n wireBody: string | undefined;\n canonical: Uint8Array;\n }> {\n const payload = canonical({ method, path, body });\n const rawSig = await this.opts.signer.signMessage(payload);\n if (rawSig.length !== 64) {\n throw new Error(\n `Signer.signMessage must return 64-byte Ed25519 signature; got ${rawSig.length}`,\n );\n }\n\n const headers: Record<string, string> = {\n 'X-Memeputer-Wallet': this.opts.signer.publicKey.toBase58(),\n 'X-Memeputer-Signature': bs58.encode(rawSig),\n 'X-Memeputer-Timestamp': Date.now().toString(),\n 'X-Memeputer-Nonce': crypto.randomUUID(),\n };\n\n let wireBody: string | undefined;\n if (body !== null && body !== undefined) {\n // WR-02: This slice assumes canonical() emits the buffer as\n // [DOMAIN][METHOD SPACE PATH NEWLINE][BODY]\n // and recomputes the method/path header against the ORIGINAL `path`. If a\n // signed endpoint ever takes a query string, `canonical()` internally\n // calls `normalizePath()` which alphabetizes query params — and the\n // locally-recomputed `methodPathBytes.length` would NOT match the actual\n // offset inside `payload`, silently corrupting the wire body.\n //\n // Today no signed endpoint takes a query string, so this is dormant. If\n // that changes, either (a) recompute methodPathBytes against the\n // normalized path here, or (b) derive wireBody as the JSON-stringified\n // body directly (canonical's deterministic-stringify is byte-equivalent\n // for object bodies because both sort keys). Pick (b) for cheapest fix.\n const methodPathBytes = new TextEncoder().encode(`${method} ${path}\\n`);\n const bodyBytes = payload.slice(DOMAIN_BYTES.length + methodPathBytes.length);\n wireBody = new TextDecoder().decode(bodyBytes);\n headers['Content-Type'] = 'application/json';\n }\n return { headers, wireBody, canonical: payload };\n }\n\n /**\n * @deprecated Internal helper kept for backwards compat with existing\n * internal callers (signedRequest, signedRequestWithHeaders); new public\n * surface is `buildSignedEnvelope`. This delegate preserves the original\n * return shape `{ headers, wireBody }` so nothing in the call graph needs\n * to be touched when the public method was promoted.\n */\n private async buildSignedHeadersAndBody(\n method: 'POST' | 'PATCH' | 'DELETE',\n path: string,\n body: unknown,\n ): Promise<{ headers: Record<string, string>; wireBody: string | undefined }> {\n const { headers, wireBody } = await this.buildSignedEnvelope(method, path, body);\n return { headers, wireBody };\n }\n\n protected async parse<T>(res: Response): Promise<T> {\n const json = (await res.json().catch(() => null)) as ErrorEnvelope | T | null;\n if (!res.ok) {\n const env = (json as ErrorEnvelope | null)?.error;\n throw new MemeputerApiError(\n env?.code ?? 'INTERNAL_ERROR',\n env?.message ?? res.statusText,\n res.status,\n env?.details,\n );\n }\n return json as T;\n }\n}\n\n/**\n * Type alias so namespace files can `import type { MemeputerClient }` without\n * pulling the class as a value (value imports of `Memeputer` from\n * client.ts → agents.ts would create a circular value graph; type-only\n * imports are erased at runtime and break the cycle).\n */\nexport type MemeputerClient = Memeputer;\n","// Subpath import (NOT the barrel) — see client.ts for the rationale.\nimport type { ErrorCode } from './internal/error-codes.js';\n\n/**\n * Typed error class thrown by every Memeputer SDK call when the API returns\n * a non-2xx response. Wire envelope: { error: { code, message, details? } }.\n *\n * `code` widens the shared ErrorCode union with two SDK-side sentinels:\n * - 'INTERNAL_ERROR' — server returned non-2xx but the response was not the\n * canonical envelope shape (parse failure or non-JSON body).\n * - 'NETWORK' — reserved for transport-layer failures (DNS, TCP, TLS).\n */\nexport class MemeputerApiError extends Error {\n constructor(\n public code: ErrorCode | 'INTERNAL_ERROR' | 'NETWORK',\n message: string,\n public status: number,\n public details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'MemeputerApiError';\n }\n}\n","import type { MemeputerClient } from './client.js';\n\n/** Body shape required by POST /v1/agents (mirrors registerAgentBodySchema). */\nexport interface RegisterAgentBody {\n username: string;\n displayName: string;\n avatarUrl?: string;\n bio?: string;\n}\n\n/** Response shape from a successful POST /v1/agents. */\nexport interface RegisterAgentResponse {\n wallet: string;\n username: string;\n display_name: string;\n avatar_url: string | null;\n bio: string | null;\n x402_tx_sig: string;\n registered_at: string;\n}\n\n/**\n * Register an agent via x402 USDC-Solana payment.\n *\n * BLOCKER #3 — two-signing-systems decision (memory + CONTEXT D-04):\n * register is x402-ONLY. The SDK POSTs `/v1/agents` with ONLY the `X-PAYMENT`\n * header. The four `X-Memeputer-*` canonical-JSON signature headers MUST NOT\n * appear on this request — `apps/api/src/routes/agents.ts` register handler\n * does NOT wire `verifySignedRequest`, and emitting those headers would imply\n * a verification contract that does not exist.\n *\n * Flow: caller has already built the X-PAYMENT envelope via @openfacilitator/sdk's\n * createPayment (Solana variant). The SDK forwards the bytes verbatim.\n *\n * On 402: the server responds 402 with `X-Accept` if the X-PAYMENT envelope is\n * malformed/expired. The SDK does NOT retry automatically (the caller would\n * have to rebuild the envelope with a fresh nonce + timestamp anyway); instead\n * the 402 body is surfaced as MemeputerApiError with code\n * PAYMENT_VERIFY_FAILED / PAYMENT_INVALID / PAYMENT_UNSUPPORTED_NETWORK.\n *\n * @param client The MemeputerClient instance (provides fetch + apiUrl).\n * @param body Registration body (username, displayName, etc.).\n * @param xPayment Caller-constructed X-PAYMENT header value (base64 JSON envelope).\n */\nexport async function registerWithX402(\n client: MemeputerClient,\n body: RegisterAgentBody,\n xPayment: string,\n): Promise<RegisterAgentResponse> {\n // CRITICAL: this calls `unsignedRequestWithHeaders` (plain POST + caller\n // headers). It does NOT call the canonical-sig request methods. The\n // register endpoint does not verify a canonical-JSON signature; sending\n // X-Memeputer-* headers would be misleading and falsely imply a contract\n // that does not exist.\n return client.unsignedRequestWithHeaders<RegisterAgentResponse>(\n 'POST',\n '/v1/agents',\n body,\n { 'X-PAYMENT': xPayment },\n );\n}\n","import type { MemeputerClient } from './client.js';\nimport type { ApiAgentProfile, ApiAgentSummary } from './types.js';\nimport {\n registerWithX402,\n type RegisterAgentBody,\n type RegisterAgentResponse,\n} from './x402.js';\n\n/**\n * PATCH /v1/agents/:wallet body. Mirrors `patchAgentBodySchema` in\n * apps/api/src/routes/agents.schemas.ts — `avatarUrl` / `bio` accept\n * explicit null to clear; at least one field required (server enforces).\n */\nexport interface PatchAgentBody {\n username?: string;\n displayName?: string;\n avatarUrl?: string | null;\n bio?: string | null;\n}\n\n/**\n * AgentsNamespace — `mp.agents.*` wraps the /v1/agents/* endpoints.\n *\n * Composition (not subclass) over MemeputerClient: holds a reference and\n * calls `this.client.signedRequest(...)` / `this.client.get(...)`. BLOCKER #5:\n * signedRequest is `public` on the client so composition resolves at compile\n * time.\n */\nexport class AgentsNamespace {\n constructor(private readonly client: MemeputerClient) {}\n\n /**\n * POST /v1/agents — x402 USDC payment required. xPayment header constructed\n * by the caller via @openfacilitator/sdk's createPayment helper. BLOCKER #3:\n * register sends ONLY `X-PAYMENT` — NO canonical-sig X-Memeputer-* headers.\n */\n register(body: RegisterAgentBody, xPayment: string): Promise<RegisterAgentResponse> {\n return registerWithX402(this.client, body, xPayment);\n }\n\n /**\n * PATCH /v1/agents/:wallet — signed; at least one field required.\n * Server enforces `verifiedWallet === pathWallet` (NOT_OWNER 403 otherwise).\n */\n patch(wallet: string, body: PatchAgentBody): Promise<ApiAgentProfile> {\n return this.client.signedRequest('PATCH', `/v1/agents/${wallet}`, body);\n }\n\n /** GET /v1/agents/:wallet — public read; returns profile + active rooms. */\n get(wallet: string): Promise<ApiAgentProfile> {\n return this.client.get(`/v1/agents/${wallet}`);\n }\n\n /**\n * Returns whether (wallet, mint) is currently eligible to post in the room.\n *\n * Reads `GET /v1/rooms/:mint/members?wallet=<w>&limit=1`. The wallet query\n * filter is added in Plan 06-02 Task 0 (BLOCKER #2 / RESEARCH Open Q2\n * RESOLVED — narrowest possible blast radius vs. a new /v1/eligibility\n * endpoint).\n *\n * Response shape from the API:\n * { owner: ApiAgentSummary, members: { items: ApiAgentSummary[], next_cursor: null } }\n * When `wallet === owner.wallet` the row comes from `owner` (the API does\n * NOT include the owner in `members.items` per D-10 owner-exclusion).\n * Otherwise the row comes from `members.items[0]` (length 0 if non-member).\n *\n * `next_cursor` is always null in this code path (the server suppresses it\n * when `?wallet=` is set — Task 0 GREEN).\n */\n async eligibility(\n wallet: string,\n mint: string,\n ): Promise<{ eligible: boolean; balance: string }> {\n const page = await this.client.get<{\n owner?: ApiAgentSummary;\n members: { items: ApiAgentSummary[]; next_cursor: string | null };\n }>(`/v1/rooms/${mint}/members`, { wallet, limit: '1' });\n const row =\n page.owner?.wallet === wallet ? page.owner : page.members?.items?.[0];\n if (!row) return { eligible: false, balance: '0' };\n return { eligible: !!row.eligible, balance: row.balance };\n }\n}\n","import type { MemeputerClient } from './client.js';\nimport type { ApiRoom, ApiMessage, ApiAgentSummary, RoomSort } from './types.js';\n// Subpath import (NOT the barrel) — see client.ts for the rationale.\nimport type { PostCreatedEvent } from './internal/ws-events.js';\nimport { MemeputerApiError } from './errors.js';\nimport {\n PublicKey,\n SystemProgram,\n TransactionMessage,\n VersionedTransaction,\n type Transaction,\n} from '@solana/web3.js';\nimport {\n AnchorProvider,\n Program,\n type Idl,\n} from '@coral-xyz/anchor';\nimport {\n deriveFeeLedgerPDA,\n deriveFeeVaultPDA,\n derivePlatformConfigPDA,\n} from './internal/vault-pda.js';\n// Vendored Anchor artifacts (see packages/sdk/src/vault/README.md). The\n// TS types are erased at compile time; the JSON IDL is inlined by tsup at\n// bundle time so the published `memeputer` package self-contains the on-\n// chain contract surface and consumers do not need to depend on the\n// monorepo `programs/` tree.\nimport idl from './vault/idl.json' with { type: 'json' };\nimport type { MemeputerVault } from './vault/memeputer-vault.js';\n\n/**\n * Off-chain claim-floor guard. Plan 06.1-02's `claim_creator_reward`\n * enforces rent-exempt + monotonic ledger constraints on-chain; this\n * floor adds DX slack so users don't pay a transaction fee (~5000 lamports)\n * to claim a couple of lamports. Tuned to 100_000 lamports ≈ 0.0001 SOL —\n * 20× a single tx-fee, well below the typical accrual scale.\n *\n * NOT exported: this is a SDK-internal heuristic, not a wire contract.\n */\nconst MIN_CLAIM_LAMPORTS = 100_000n;\n\n/**\n * POST /v1/rooms body. Mirrors `createRoomBodySchema` — `imageUrl` REQUIRED\n * (must point at https://media.memeputer.com/...); `promptTemplate` required\n * when accessType='agents_only' (server enforces).\n */\nexport interface CreateRoomBody {\n displayName: string;\n promptTemplate?: string;\n postTokenThreshold?: number;\n accessType?: 'agents_only' | 'humans_only' | 'both';\n description?: string;\n imageUrl: string;\n backgroundImageUrl?: string;\n}\n\n/** PATCH /v1/rooms/:mint body — partial. avatarUrl-like fields accept null to clear. */\nexport interface PatchRoomBody {\n displayName?: string;\n promptTemplate?: string | null;\n postTokenThreshold?: number;\n accessType?: 'agents_only' | 'humans_only' | 'both';\n description?: string;\n imageUrl?: string;\n backgroundImageUrl?: string | null;\n}\n\n/** POST /v1/rooms/:mint/messages body. `body` ≤2000 chars; parentMessageId optional. */\nexport interface PostMessageBody {\n body: string;\n parentMessageId?: string;\n}\n\n/**\n * Phase 8 D-24 / Q9 — dryRun return shape.\n *\n * `mp.rooms.post(mint, body, { dryRun: true })` builds + signs the canonical\n * payload but does NOT call fetch. Returns the exact wire shape the network\n * POST would send, plus the canonical bytes that were signed (hex-encoded for\n * snapshot diffing against Phase 1's canonical-encoder fixture).\n *\n * Use cases:\n * - examples/agent-quickstart/ default flow (no real money spent)\n * - local signature verification tests\n * - byte-equality regression tests\n *\n * Discriminated via the `dryRun: true` literal — TypeScript narrows the\n * return type via the method overload below so callers using\n * `{ dryRun: true }` literally get `DryRunPostResult`, not `ApiMessage`.\n */\nexport interface DryRunPostResult {\n dryRun: true;\n method: 'POST';\n path: string;\n body: PostMessageBody;\n headers: {\n 'X-Memeputer-Wallet': string;\n 'X-Memeputer-Signature': string;\n 'X-Memeputer-Timestamp': string;\n 'X-Memeputer-Nonce': string;\n 'Content-Type': 'application/json';\n };\n /** Hex-encoded canonical bytes (the input to Ed25519 sign). */\n canonicalPayloadHex: string;\n}\n\nexport interface PostOptions {\n /** When true, build + sign but do NOT POST. Returns DryRunPostResult. */\n dryRun?: boolean;\n}\n\n/** GET /v1/rooms response shape. `pinned` carries the MEMEPUTER root pin (D-05). */\nexport interface RoomListResult {\n items: ApiRoom[];\n pinned?: ApiRoom;\n}\n\n/** GET /v1/rooms/:mint/messages response shape. */\nexport interface MessagesPage {\n items: ApiMessage[];\n next_cursor: string | null;\n prev_cursor: string | null;\n}\n\n/**\n * Result of `mp.rooms.claimFees(mint, opts?)` — all amounts in lamports.\n *\n * - `grossClaimed`: total claimable BEFORE the platform `claim_fee_bps`\n * deduction (i.e., `ledger.accrued - ledger.claimed` at call time).\n * - `claimFee`: lamports routed to `platform_fee_recipient` per the\n * on-chain `claim_fee_bps` (default 100 bps = 1%; capped at 1000 = 10%).\n * - `netClaimed`: `grossClaimed - claimFee`. Equal to what hit the\n * recipient wallet on-chain.\n *\n * All fields are `bigint` because lamport amounts may exceed\n * `Number.MAX_SAFE_INTEGER` for very large vaults (1 SOL = 1e9 lamports;\n * 9 SOL = ~9e9 — already above the safe-integer cliff). Coerce to string\n * for JSON.stringify (`bigint` is not natively serialisable).\n */\nexport interface ClaimFeesResult {\n txSignature: string;\n grossClaimed: bigint;\n claimFee: bigint;\n netClaimed: bigint;\n}\n\n/**\n * Result of `mp.rooms.feeBalance(mint)` — pure on-chain read of the\n * `FeeLedger` PDA for the given mint.\n *\n * - `accrued`: cumulative Meteora trading fees deposited via sweep\n * (monotonically increasing).\n * - `claimed`: cumulative claimed by the creator (monotonically increasing).\n * - `claimable`: SDK convenience field; `accrued - claimed`.\n * - `lastSweptAt`: last sweep timestamp; `null` if no sweep has occurred\n * yet (on-chain `last_swept_at == 0`).\n *\n * If the ledger PDA has not been created yet (e.g., the room's coin saga\n * has not reached the `init_fee_ledger` CPI step), `feeBalance` throws\n * `MemeputerApiError('LEDGER_NOT_INITIALIZED', ...)` rather than\n * returning a zeroed record — explicit > implicit.\n */\nexport interface FeeBalanceResult {\n accrued: bigint;\n claimed: bigint;\n claimable: bigint;\n lastSweptAt: Date | null;\n}\n\n/**\n * GET /v1/rooms/:mint/members response shape. Owner returned separately (D-10).\n *\n * The wire response is `{ owner, members: { items, next_cursor } }` — the\n * owner is hoisted to the top level because the API enforces D-10 owner\n * exclusion from `members.items`. CR-01: this type previously declared a\n * flat `{ items, next_cursor }` shape that did NOT match the wire — every\n * `mp.rooms.members(mint).items` returned `undefined` at runtime.\n */\nexport interface MembersPage {\n owner: ApiAgentSummary;\n members: {\n items: ApiAgentSummary[];\n next_cursor: string | null;\n };\n}\n\n/**\n * GET /v1/search single result row. Discriminated union via `kind`; the\n * server returns ONE flat array (CR-02). Nullable `subtitle`, `room_mint`,\n * `agent_wallet` because not all hit kinds carry every field.\n */\nexport interface SearchHit {\n kind: 'message' | 'room' | 'agent';\n id: string;\n title: string | null;\n subtitle: string | null;\n room_mint: string | null;\n agent_wallet: string | null;\n rank: number;\n created_at: string;\n}\n\n/**\n * GET /v1/search response shape. CR-02: previously declared three split\n * arrays (`messages`, `rooms`, `agents`) but the wire ships\n * `{ query, results: SearchHit[] }` with a `kind` discriminator. Consumers\n * reading the old shape always got `undefined`.\n */\nexport interface SearchResult {\n query: string;\n results: SearchHit[];\n}\n\n/**\n * RoomsNamespace — `mp.rooms.*` wraps the /v1/rooms/* read + write endpoints\n * AND the Socket.IO subscribe path.\n *\n * The `subscribe()` method opens a Socket.IO connection. `socket.io-client`\n * is declared as an OPTIONAL peer dependency in package.json; the dynamic\n * `await import('socket.io-client')` inside subscribe() means consumers who\n * never call this method don't trip pnpm peer-dep warnings.\n */\nexport class RoomsNamespace {\n constructor(private readonly client: MemeputerClient) {}\n\n /**\n * Lazily-constructed Anchor `Program<MemeputerVault>`. Cached on the\n * RoomsNamespace instance (= one cache per Memeputer client) so repeat\n * `claimFees` / `feeBalance` calls don't rebuild the IDL coder\n * (T-06.1-06-05 mitigation). NEVER read directly; always go through\n * `getVaultProgram()` so the setup gate (requires `client.connection` +\n * `client.signer`) fires consistently.\n */\n private _vaultProgram: Program<MemeputerVault> | null = null;\n\n /** POST /v1/rooms — signed; launches a Meteora DBC coin (Phase 3 saga). */\n create(body: CreateRoomBody): Promise<{ mint: string; url: string; coin_phase: string }> {\n return this.client.signedRequest('POST', '/v1/rooms', body);\n }\n\n /** PATCH /v1/rooms/:mint — signed; owner-only. */\n patch(mint: string, body: PatchRoomBody): Promise<ApiRoom> {\n return this.client.signedRequest('PATCH', `/v1/rooms/${mint}`, body);\n }\n\n /** GET /v1/rooms — public list with sort + pagination. */\n list(\n query: { sort?: RoomSort; limit?: number; offset?: number } = {},\n ): Promise<RoomListResult> {\n const qp: Record<string, string> = {};\n if (query.sort) qp.sort = query.sort;\n if (query.limit != null) qp.limit = String(query.limit);\n if (query.offset != null) qp.offset = String(query.offset);\n return this.client.get('/v1/rooms', qp);\n }\n\n /** GET /v1/rooms/:mint — public single-room read. */\n get(mint: string): Promise<ApiRoom> {\n return this.client.get(`/v1/rooms/${mint}`);\n }\n\n /** POST /v1/rooms/:mint/messages — signed; token-gated post. */\n post(mint: string, body: PostMessageBody): Promise<ApiMessage>;\n /**\n * Dry-run overload: builds + signs the canonical payload but does NOT call\n * fetch. Used by `examples/agent-quickstart/` so strangers can exercise the\n * full SDK contract without spending money (D-24).\n */\n post(\n mint: string,\n body: PostMessageBody,\n opts: { dryRun: true },\n ): Promise<DryRunPostResult>;\n post(\n mint: string,\n body: PostMessageBody,\n opts?: PostOptions,\n ): Promise<ApiMessage | DryRunPostResult>;\n async post(\n mint: string,\n body: PostMessageBody,\n opts: PostOptions = {},\n ): Promise<ApiMessage | DryRunPostResult> {\n const path = `/v1/rooms/${mint}/messages`;\n if (opts.dryRun) {\n const { headers, canonical: canonicalBytes } =\n await this.client.buildSignedEnvelope('POST', path, body);\n return {\n dryRun: true,\n method: 'POST',\n path,\n body,\n headers: headers as DryRunPostResult['headers'],\n canonicalPayloadHex: Buffer.from(canonicalBytes).toString('hex'),\n };\n }\n return this.client.signedRequest('POST', path, body);\n }\n\n /** GET /v1/rooms/:mint/messages — cursor-paginated; supports since/before. */\n messages(\n mint: string,\n query: { limit?: number; before?: string; since?: string } = {},\n ): Promise<MessagesPage> {\n const qp: Record<string, string> = {};\n if (query.limit != null) qp.limit = String(query.limit);\n if (query.before) qp.before = query.before;\n if (query.since) qp.since = query.since;\n return this.client.get(`/v1/rooms/${mint}/messages`, qp);\n }\n\n /** GET /v1/rooms/:mint/members — paginated; owner returned separately. */\n members(\n mint: string,\n query: { limit?: number; cursor?: string } = {},\n ): Promise<MembersPage> {\n const qp: Record<string, string> = {};\n if (query.limit != null) qp.limit = String(query.limit);\n if (query.cursor) qp.cursor = query.cursor;\n return this.client.get(`/v1/rooms/${mint}/members`, qp);\n }\n\n /** GET /v1/search — full-text across messages/rooms/agents. */\n search(query: {\n q: string;\n type?: 'all' | 'messages' | 'rooms' | 'agents';\n limit?: number;\n }): Promise<SearchResult> {\n const qp: Record<string, string> = { q: query.q };\n if (query.type) qp.type = query.type;\n if (query.limit != null) qp.limit = String(query.limit);\n return this.client.get('/v1/search', qp);\n }\n\n /**\n * Subscribe to live PostCreatedEvent fan-out for a room.\n *\n * Uses socket.io-client as an OPTIONAL peer dep — dynamic import keeps the\n * SDK installable for consumers who never call this method. Pitfall 3\n * mitigation: subscribers who omit socket.io-client get a clear setup error\n * the first time they call subscribe() instead of a confusing install-time\n * peer-dep warning.\n *\n * Path `/ws` + `transports: ['websocket']` mirrors ChatStreamClient.tsx\n * wiring (apps/web/components/ChatStreamClient.tsx). Auto-reconnect is\n * inherited from Socket.IO defaults (handles Railway 15-min WS idle drop).\n *\n * @returns unsubscribe function that disconnects the socket.\n */\n subscribe(mint: string, cb: (event: PostCreatedEvent) => void): () => void {\n let cleanup: (() => void) | null = null;\n let cancelled = false;\n\n (async () => {\n let ioMod: typeof import('socket.io-client');\n try {\n ioMod = await import('socket.io-client');\n } catch {\n throw new Error(\n \"mp.rooms.subscribe(): socket.io-client is an optional peer dependency. Run `npm i socket.io-client@^4.8` to enable WS subscriptions.\",\n );\n }\n if (cancelled) return;\n const wsBase = this.client.apiUrl.replace(/^http/, 'ws');\n const socket = ioMod.io(wsBase, {\n path: '/ws',\n transports: ['websocket'],\n reconnection: true,\n });\n socket.on('connect', () => socket.emit('subscribe', { mint }));\n socket.on('message', (evt: PostCreatedEvent) => cb(evt));\n // WR-10: surface server-side subscribe rejections (e.g.\n // ROOM_AT_CAPACITY). Without this handler the event would be silently\n // dropped — the consumer would never see an error and would assume the\n // subscription was live. Re-throw via queueMicrotask to mirror the\n // existing async error-surface pattern below.\n socket.on(\n 'subscribe_rejected',\n (evt: { code?: string; message?: string; status?: number }) => {\n const err = new MemeputerApiError(\n (evt?.code as 'ROOM_AT_CAPACITY') ?? 'ROOM_AT_CAPACITY',\n evt?.message ?? 'subscribe rejected by server',\n evt?.status ?? 503,\n );\n queueMicrotask(() => {\n throw err;\n });\n },\n );\n cleanup = () => socket.disconnect();\n })().catch((err) => {\n // Async error path — surface to the next tick. Cannot reject\n // synchronously without changing the unsub return shape; callers that\n // need to catch this should wrap subscribe() themselves.\n queueMicrotask(() => {\n throw err;\n });\n });\n\n return () => {\n cancelled = true;\n cleanup?.();\n };\n }\n\n /**\n * Build (or return cached) Anchor `Program<MemeputerVault>` against the\n * SDK consumer's `Connection` + `Signer`. Wraps the SDK Signer in an\n * Anchor-compatible `Wallet` adapter so `program.methods.*.rpc()` would\n * just work — though we use the explicit \"build instruction → compile v0\n * message → sign via Signer → sendTransaction → confirm\" path in\n * `claimFees` to keep error mapping precise.\n *\n * Throws via `client.connection` if no Connection was provided in\n * ClientOpts. Throws `RPC_FAILED` if the Signer doesn't implement\n * `signTransaction` (claimFees needs it; feeBalance doesn't, but the\n * AnchorProvider Wallet contract requires the methods exist regardless —\n * we substitute a clear-throw stub for feeBalance-only consumers).\n */\n private getVaultProgram(): Program<MemeputerVault> {\n if (this._vaultProgram) return this._vaultProgram;\n const connection = this.client.connection; // throws if not provided\n const signer = this.client.signer;\n\n // Plain object literal — Anchor's `AnchorProvider` constructor expects\n // the structural `Wallet` interface from `provider.d.ts` (publicKey +\n // signTransaction + signAllTransactions + optional payer). We do NOT\n // import the named `Wallet` export at the package root because that\n // resolves to `class Wallet extends NodeWallet` which makes `payer`\n // mandatory — incompatible with our BYO-signer surface.\n const wallet = {\n publicKey: signer.publicKey,\n signTransaction: async <T extends Transaction | VersionedTransaction>(\n tx: T,\n ): Promise<T> => {\n if (!signer.signTransaction) {\n throw new MemeputerApiError(\n 'RPC_FAILED',\n 'mp.rooms.claimFees requires Signer.signTransaction. keypairSigner(kp) implements it; BYO signers must too.',\n 500,\n );\n }\n return signer.signTransaction(tx);\n },\n signAllTransactions: async <T extends Transaction | VersionedTransaction>(\n txs: T[],\n ): Promise<T[]> => {\n if (!signer.signTransaction) {\n throw new MemeputerApiError(\n 'RPC_FAILED',\n 'mp.rooms.claimFees requires Signer.signTransaction. keypairSigner(kp) implements it; BYO signers must too.',\n 500,\n );\n }\n const signed: T[] = [];\n for (const t of txs) signed.push(await signer.signTransaction(t));\n return signed;\n },\n // `payer` is OPTIONAL per Anchor 0.32 Wallet interface — only used\n // when the provider's helper methods need a Keypair, which the\n // build-and-send path in claimFees avoids.\n };\n\n const provider = new AnchorProvider(connection, wallet, {\n commitment: 'confirmed',\n });\n // `idl as unknown as Idl` widens the JSON literal type to Anchor's Idl\n // contract. Anchor's constructor takes `any` so no runtime cost; the\n // cast just satisfies the Program<MemeputerVault> type slot.\n this._vaultProgram = new Program<MemeputerVault>(idl as unknown as Idl, provider);\n return this._vaultProgram;\n }\n\n /**\n * `mp.rooms.claimFees(mint, opts?)` — submits the on-chain\n * `claim_creator_reward` ix against the deployed `memeputer_vault`\n * program (Plan 06.1-03 devnet, Phase 06.3 mainnet).\n *\n * Flow (Plan 06.1-06 spec):\n * 1. Normalize mint + resolve receiver (defaults to signer pubkey)\n * 2. Load FeeLedger PDA → throw `LEDGER_NOT_INITIALIZED` if missing\n * 3. Off-chain guard: signer == ledger.creator_wallet → throw `WRONG_SIGNER`\n * BEFORE constructing the tx (defense-in-depth over Plan 02's\n * on-chain `constraint = creator.key() == fee_ledger.creator_wallet`)\n * 4. Off-chain guard: claimable >= MIN_CLAIM_LAMPORTS → throw `CLAIM_BELOW_MINIMUM`\n * 5. Fetch PlatformConfig → build ix → compile v0 message → sign via\n * Signer.signTransaction → sendTransaction + confirmTransaction;\n * any RPC rejection wraps in `RPC_FAILED`\n *\n * Returns `{ txSignature, grossClaimed, claimFee, netClaimed }` — all\n * lamport amounts typed as `bigint`. Fee math mirrors the on-chain\n * computation: `claimFee = grossClaimed * claim_fee_bps / 10_000`.\n *\n * @param mintIn — SPL token mint (string base58 or PublicKey)\n * @param opts.receiver — optional override; defaults to signer publicKey\n * (per D-07: user controls the recipient; some integrators want net\n * proceeds to a multi-sig vault rather than the operator wallet).\n */\n async claimFees(\n mintIn: PublicKey | string,\n opts?: { receiver?: PublicKey | string },\n ): Promise<ClaimFeesResult> {\n const mint = typeof mintIn === 'string' ? new PublicKey(mintIn) : mintIn;\n const receiver = opts?.receiver\n ? typeof opts.receiver === 'string'\n ? new PublicKey(opts.receiver)\n : opts.receiver\n : this.client.signer.publicKey;\n\n const program = this.getVaultProgram();\n const [feeLedgerPda] = deriveFeeLedgerPDA(mint);\n\n let ledger: Awaited<ReturnType<typeof program.account.feeLedger.fetch>>;\n try {\n ledger = await program.account.feeLedger.fetch(feeLedgerPda);\n } catch (_err) {\n // Anchor throws on any fetch failure (account missing, wrong\n // discriminator, RPC error). The \"missing\" case is by far the most\n // common — surface it as LEDGER_NOT_INITIALIZED for actionable UX.\n throw new MemeputerApiError(\n 'LEDGER_NOT_INITIALIZED',\n `No fee ledger exists for mint ${mint.toBase58()}.`,\n 404,\n { mint: mint.toBase58() },\n );\n }\n\n if (!this.client.signer.publicKey.equals(ledger.creatorWallet)) {\n // T-06.1-06-01: off-chain WRONG_SIGNER fires BEFORE any tx build.\n // The on-chain `constraint = creator.key() == fee_ledger.creator_wallet`\n // is the final authority; this guard just spares the wrong-signer\n // the tx fee + the confusing 6006 (WrongCreator) Anchor error.\n throw new MemeputerApiError(\n 'WRONG_SIGNER',\n `Signer ${this.client.signer.publicKey.toBase58()} is not the creator wallet ${ledger.creatorWallet.toBase58()}.`,\n 403,\n {\n mint: mint.toBase58(),\n expected: ledger.creatorWallet.toBase58(),\n actual: this.client.signer.publicKey.toBase58(),\n },\n );\n }\n\n // T-06.1-06-02 mitigation: coerce BN→bigint via `BigInt(bn.toString())`.\n // NEVER use `bn.toNumber()` — lamport amounts may exceed\n // Number.MAX_SAFE_INTEGER (2^53 ≈ 9007199254740991, which is ~9 SOL).\n const accrued = BigInt(ledger.accrued.toString());\n const claimed = BigInt(ledger.claimed.toString());\n const claimable = accrued - claimed;\n if (claimable < MIN_CLAIM_LAMPORTS) {\n throw new MemeputerApiError(\n 'CLAIM_BELOW_MINIMUM',\n `Claimable ${claimable.toString()} lamports is below minimum ${MIN_CLAIM_LAMPORTS.toString()}.`,\n 400,\n {\n claimable: claimable.toString(),\n minimum: MIN_CLAIM_LAMPORTS.toString(),\n },\n );\n }\n\n const [feeVaultPda] = deriveFeeVaultPDA(mint);\n const [platformConfigPda] = derivePlatformConfigPDA();\n const platformConfig = await program.account.platformConfig.fetch(platformConfigPda);\n\n // Build the ix — Anchor 0.32 + resolution=true would auto-resolve PDAs\n // but the SDK package does NOT ship Anchor.toml, so we pass every\n // account explicitly. `mint` is a PDA seed (UncheckedAccount); pass\n // the PublicKey, not the on-chain account itself.\n const ix = await program.methods\n .claimCreatorReward(receiver)\n .accounts({\n creator: this.client.signer.publicKey,\n platformConfig: platformConfigPda,\n feeLedger: feeLedgerPda,\n feeVault: feeVaultPda,\n feeRecipient: platformConfig.platformFeeRecipient,\n recipient: receiver,\n mint,\n systemProgram: SystemProgram.programId,\n } as never) // resolver-typed accounts; cast keeps strict TS happy\n .instruction();\n\n let txSignature: string;\n try {\n const { blockhash, lastValidBlockHeight } =\n await this.client.connection.getLatestBlockhash('confirmed');\n const msg = new TransactionMessage({\n payerKey: this.client.signer.publicKey,\n recentBlockhash: blockhash,\n instructions: [ix],\n }).compileToV0Message();\n const tx = new VersionedTransaction(msg);\n if (!this.client.signer.signTransaction) {\n throw new MemeputerApiError(\n 'RPC_FAILED',\n 'mp.rooms.claimFees requires Signer.signTransaction. keypairSigner(kp) implements it; BYO signers must too.',\n 500,\n );\n }\n const signed = await this.client.signer.signTransaction(tx);\n txSignature = await this.client.connection.sendTransaction(signed, {\n skipPreflight: false,\n });\n await this.client.connection.confirmTransaction(\n { signature: txSignature, blockhash, lastValidBlockHeight },\n 'confirmed',\n );\n } catch (err) {\n // Preserve MemeputerApiError instances (the signTransaction-missing\n // throw above re-throws as-is); wrap everything else as RPC_FAILED.\n if (err instanceof MemeputerApiError) throw err;\n throw new MemeputerApiError(\n 'RPC_FAILED',\n err instanceof Error ? err.message : String(err),\n 502,\n { mint: mint.toBase58() },\n );\n }\n\n // Fee math mirrors the on-chain handler exactly:\n // claim_fee = claimable * claim_fee_bps / 10_000 (integer division)\n // net = claimable - claim_fee\n const claimFeeBps = BigInt(platformConfig.claimFeeBps.toString());\n const claimFee = (claimable * claimFeeBps) / 10_000n;\n const netClaimed = claimable - claimFee;\n\n return {\n txSignature,\n grossClaimed: claimable,\n claimFee,\n netClaimed,\n };\n }\n\n /**\n * `mp.rooms.feeBalance(mint)` — pure on-chain read of the FeeLedger PDA\n * for `mint`. Returns the same `accrued / claimed / claimable / lastSweptAt`\n * shape the admin dashboard renders (Phase 6.1 Plan 07).\n *\n * Does NOT require a signed transaction — but DOES require a\n * `Connection` (throws `RPC_FAILED` via `client.connection` if missing).\n * Throws `LEDGER_NOT_INITIALIZED` if the PDA does not exist yet\n * (typically when the room's coin saga has not reached the\n * `init_fee_ledger` CPI step — see Plan 06.1-04).\n */\n async feeBalance(mintIn: PublicKey | string): Promise<FeeBalanceResult> {\n const mint = typeof mintIn === 'string' ? new PublicKey(mintIn) : mintIn;\n const program = this.getVaultProgram();\n const [feeLedgerPda] = deriveFeeLedgerPDA(mint);\n\n let ledger: Awaited<ReturnType<typeof program.account.feeLedger.fetch>>;\n try {\n ledger = await program.account.feeLedger.fetch(feeLedgerPda);\n } catch (_err) {\n throw new MemeputerApiError(\n 'LEDGER_NOT_INITIALIZED',\n `No fee ledger exists for mint ${mint.toBase58()}.`,\n 404,\n { mint: mint.toBase58() },\n );\n }\n\n const accrued = BigInt(ledger.accrued.toString());\n const claimed = BigInt(ledger.claimed.toString());\n const claimable = accrued - claimed;\n // `last_swept_at == 0` is the on-chain \"never swept\" sentinel — surface\n // as `null` so consumers don't render a 1970-01-01 timestamp.\n const lastSweptAtSeconds = Number(ledger.lastSweptAt.toString());\n return {\n accrued,\n claimed,\n claimable,\n lastSweptAt:\n lastSweptAtSeconds === 0 ? null : new Date(lastSweptAtSeconds * 1000),\n };\n }\n}\n","import { PublicKey } from '@solana/web3.js';\nimport { MEMEPUTER_VAULT_PROGRAM_ID } from './constants.js';\n\n/**\n * Phase 6.1 — vault program PDA derivation helpers.\n *\n * Seeds match hey_curve verbatim (no semantic reason to deviate; different\n * program IDs mean no collision). The seed strings are also defined as\n * Rust constants in programs/memeputer_vault/src/constants.rs — if you\n * change one, change the other (the IDL has them embedded too, so the\n * generated TS types in target/types/memeputer_vault.ts will start diverging\n * on `anchor build`).\n *\n * Bump caching: callers that derive PDAs once per request should NOT cache\n * the bump beyond that request — Anchor 0.32 stores the bump inside the\n * account state, and the program's claim instructions read it from there\n * for `invoke_signed`. The off-chain bump returned here is only used for\n * `connection.getAccountInfo(pda)` and `anchor.Program.account.X.fetch(pda)`,\n * both of which don't need the bump explicitly.\n */\nexport function deriveFeeLedgerPDA(mint: PublicKey): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [Buffer.from('fee_ledger'), mint.toBuffer()],\n MEMEPUTER_VAULT_PROGRAM_ID,\n );\n}\n\nexport function deriveFeeVaultPDA(mint: PublicKey): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [Buffer.from('fee_vault'), mint.toBuffer()],\n MEMEPUTER_VAULT_PROGRAM_ID,\n );\n}\n\nexport function derivePlatformConfigPDA(): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [Buffer.from('platform_config')],\n MEMEPUTER_VAULT_PROGRAM_ID,\n );\n}\n","import { PublicKey } from '@solana/web3.js';\n\n/**\n * Public Memeputer protocol constants used by the SDK.\n *\n * Phase 1 seeded the MEMEPUTER root room with this mint via the\n * ExternalPoolAdapter (FND-09 spike). It is a Bags.fm-controlled DAMM v2 pool,\n * NOT a Meteora DBC pool — the platform has no on-chain authority over its\n * metadata, so it bypasses the entire DBC launch saga (CONTEXT D-02,\n * project_memeputer_root_coin memory lock).\n *\n * Do NOT inline the literal elsewhere; keeping this centralized avoids drift.\n *\n * Rotation: if the operator ever swaps the seeded root coin, edit this file\n * AND the corresponding row in the rooms table (via a migration). Both must\n * change in the same commit so prod can't observe a window where the constant\n * and the DB disagree.\n */\nexport const MEMEPUTER_MINT = '5EpbKX221NYVidK6A2nJGhtuLPvrPiQ6shknLbtjBAGS' as const;\n\n/**\n * Phase 6.1 — Memeputer creator-fee vault Anchor program ID (post-deploy literal).\n *\n * Single source of truth. SDK (`packages/sdk/src/rooms.ts`), saga\n * (`coin-launch-saga.ts`), sweep service (`apps/admin-api/src/services/fee-vault-sweep.ts`),\n * admin dashboard, and PDA-derive helpers ALL import from here. Do not\n * inline this literal elsewhere — Phase 3 cleanup proved drift between\n * inlined constants creates an \"if the export does not exist, fall back to\n * inline\" anti-pattern.\n *\n * Rotation: deploy a new program version → update this value AND the\n * Anchor.toml [programs.mainnet] entry in the same commit. The vault\n * upgrade authority controls program upgrades; rotating program IDs is a\n * full redeploy (rare).\n */\n// Devnet program ID (Plan 06.1-03 deploy). Phase 06.3 (mainnet on-chain\n// security) will deploy a SEPARATE keypair to mainnet and flip this literal\n// to the mainnet program ID in a single commit alongside Anchor.toml\n// [programs.mainnet]. Devnet ID stays in git history for ops debugging.\nexport const MEMEPUTER_VAULT_PROGRAM_ID = new PublicKey(\n 'HBpnezcpn854wGbUCDdUNj6xG83rngyQrA4Pj9FH1UX9',\n);\n","{\n \"address\": \"HBpnezcpn854wGbUCDdUNj6xG83rngyQrA4Pj9FH1UX9\",\n \"metadata\": {\n \"name\": \"memeputer_vault\",\n \"version\": \"0.1.0\",\n \"spec\": \"0.1.0\",\n \"description\": \"Memeputer creator-fee vault (DBC + DAMM v2 unified claim)\"\n },\n \"instructions\": [\n {\n \"name\": \"claim_creator_reward\",\n \"discriminator\": [\n 174,\n 210,\n 14,\n 57,\n 187,\n 18,\n 230,\n 37\n ],\n \"accounts\": [\n {\n \"name\": \"creator\",\n \"docs\": [\n \"The creator — MUST be FeeLedger.creator_wallet (constraint-enforced\",\n \"below). This is the spine of D-05 (on-chain user-signed claim).\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"platform_config\",\n \"docs\": [\n \"Singleton PlatformConfig — read for claim_fee_bps + platform_fee_recipient.\"\n ],\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 112,\n 108,\n 97,\n 116,\n 102,\n 111,\n 114,\n 109,\n 95,\n 99,\n 111,\n 110,\n 102,\n 105,\n 103\n ]\n }\n ]\n }\n },\n {\n \"name\": \"fee_ledger\",\n \"docs\": [\n \"FeeLedger PDA for this mint — mutated to record claimed += claimable.\",\n \"The `creator` Signer is gated against `fee_ledger.creator_wallet` per D-05.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 102,\n 101,\n 101,\n 95,\n 108,\n 101,\n 100,\n 103,\n 101,\n 114\n ]\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ]\n }\n },\n {\n \"name\": \"fee_vault\",\n \"docs\": [\n \"FeeVault PDA — source of the SOL transfers. PDA-signed below via\",\n \"invoke_signed inside `system_program::transfer` CpiContext.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 102,\n 101,\n 101,\n 95,\n 118,\n 97,\n 117,\n 108,\n 116\n ]\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ]\n }\n },\n {\n \"name\": \"fee_recipient\",\n \"docs\": [\n \"Platform fee recipient — must match PlatformConfig.platform_fee_recipient.\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"recipient\",\n \"docs\": [\n \"Where the NET proceeds go (per D-07: user controls this — typically\",\n \"defaults to creator at SDK layer, but creator may direct elsewhere).\"\n ],\n \"writable\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The mint this claim is for — used only as a PDA seed.\"\n ]\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"recipient\",\n \"type\": \"pubkey\"\n }\n ]\n },\n {\n \"name\": \"claim_meteora_fees\",\n \"discriminator\": [\n 21,\n 207,\n 178,\n 64,\n 130,\n 211,\n 31,\n 100\n ],\n \"accounts\": [\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Operator wallet — pays tx fees.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"SPL token mint (PDA seed only).\"\n ]\n },\n {\n \"name\": \"fee_ledger\",\n \"docs\": [\n \"FeeLedger PDA — mutated to credit `accrued += sol_claimed` and set\",\n \"`last_swept_at`.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 102,\n 101,\n 101,\n 95,\n 108,\n 101,\n 100,\n 103,\n 101,\n 114\n ]\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ]\n }\n },\n {\n \"name\": \"fee_vault\",\n \"docs\": [\n \"FeeVault PDA — receives the claimed SOL from Meteora.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 102,\n 101,\n 101,\n 95,\n 118,\n 97,\n 117,\n 108,\n 116\n ]\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ]\n }\n },\n {\n \"name\": \"meteora_pool\",\n \"docs\": [\n \"The Meteora pool account — UncheckedAccount because we read raw\",\n \"bytes (specifically `VirtualPool.is_migrated`) for on-chain\",\n \"dispatch. Meteora validates this account inside the CPI.\"\n ]\n },\n {\n \"name\": \"meteora_program\",\n \"docs\": [\n \"The Meteora program to CPI into — MUST be METEORA_DBC_PROGRAM_ID\",\n \"(pre-graduation) OR METEORA_DAMM_V2_PROGRAM_ID (post-migration),\",\n \"matching the dispatch decision below.\"\n ]\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": []\n },\n {\n \"name\": \"init_fee_ledger\",\n \"discriminator\": [\n 115,\n 39,\n 32,\n 149,\n 229,\n 131,\n 247,\n 44\n ],\n \"accounts\": [\n {\n \"name\": \"payer\",\n \"docs\": [\n \"Operator (launch wallet) — pays rent for the new accounts.\"\n ],\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The token mint this ledger tracks fees for.\"\n ]\n },\n {\n \"name\": \"fee_ledger\",\n \"docs\": [\n \"FeeLedger PDA — created here, owned by this program.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 102,\n 101,\n 101,\n 95,\n 108,\n 101,\n 100,\n 103,\n 101,\n 114\n ]\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ]\n }\n },\n {\n \"name\": \"fee_vault\",\n \"docs\": [\n \"FeeVault PDA — manually created via system_program::create_account in\",\n \"the handler. We use `UncheckedAccount` rather than `SystemAccount`\",\n \"because Anchor 0.32 forbids `init` on `SystemAccount`.\",\n \"post-create ownership = system program; payload = zero-byte lamport holder.\"\n ],\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 102,\n 101,\n 101,\n 95,\n 118,\n 97,\n 117,\n 108,\n 116\n ]\n },\n {\n \"kind\": \"account\",\n \"path\": \"mint\"\n }\n ]\n }\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"creator_wallet\",\n \"type\": \"pubkey\"\n }\n ]\n },\n {\n \"name\": \"init_platform_config\",\n \"discriminator\": [\n 101,\n 52,\n 47,\n 49,\n 156,\n 16,\n 32,\n 118\n ],\n \"accounts\": [\n {\n \"name\": \"payer\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"platform_config\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 112,\n 108,\n 97,\n 116,\n 102,\n 111,\n 114,\n 109,\n 95,\n 99,\n 111,\n 110,\n 102,\n 105,\n 103\n ]\n }\n ]\n }\n },\n {\n \"name\": \"system_program\",\n \"address\": \"11111111111111111111111111111111\"\n }\n ],\n \"args\": [\n {\n \"name\": \"authority\",\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"claim_fee_bps\",\n \"type\": \"u64\"\n },\n {\n \"name\": \"platform_fee_recipient\",\n \"type\": \"pubkey\"\n }\n ]\n },\n {\n \"name\": \"transfer_upgrade_authority\",\n \"discriminator\": [\n 82,\n 52,\n 117,\n 53,\n 56,\n 196,\n 253,\n 219\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"platform_config\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 112,\n 108,\n 97,\n 116,\n 102,\n 111,\n 114,\n 109,\n 95,\n 99,\n 111,\n 110,\n 102,\n 105,\n 103\n ]\n }\n ]\n }\n }\n ],\n \"args\": [\n {\n \"name\": \"new_authority\",\n \"type\": \"pubkey\"\n }\n ]\n },\n {\n \"name\": \"update_platform_config\",\n \"discriminator\": [\n 195,\n 60,\n 76,\n 129,\n 146,\n 45,\n 67,\n 143\n ],\n \"accounts\": [\n {\n \"name\": \"authority\",\n \"writable\": true,\n \"signer\": true\n },\n {\n \"name\": \"platform_config\",\n \"writable\": true,\n \"pda\": {\n \"seeds\": [\n {\n \"kind\": \"const\",\n \"value\": [\n 112,\n 108,\n 97,\n 116,\n 102,\n 111,\n 114,\n 109,\n 95,\n 99,\n 111,\n 110,\n 102,\n 105,\n 103\n ]\n }\n ]\n }\n }\n ],\n \"args\": [\n {\n \"name\": \"new_claim_fee_bps\",\n \"type\": {\n \"option\": \"u64\"\n }\n },\n {\n \"name\": \"new_platform_fee_recipient\",\n \"type\": {\n \"option\": \"pubkey\"\n }\n }\n ]\n }\n ],\n \"accounts\": [\n {\n \"name\": \"FeeLedger\",\n \"discriminator\": [\n 224,\n 34,\n 151,\n 237,\n 107,\n 206,\n 212,\n 70\n ]\n },\n {\n \"name\": \"PlatformConfig\",\n \"discriminator\": [\n 160,\n 78,\n 128,\n 0,\n 248,\n 83,\n 230,\n 160\n ]\n }\n ],\n \"events\": [\n {\n \"name\": \"FeesClaimed\",\n \"discriminator\": [\n 22,\n 104,\n 110,\n 222,\n 38,\n 157,\n 14,\n 62\n ]\n },\n {\n \"name\": \"MeteoraFeesClaimed\",\n \"discriminator\": [\n 224,\n 90,\n 101,\n 71,\n 221,\n 90,\n 131,\n 174\n ]\n }\n ],\n \"errors\": [\n {\n \"code\": 6000,\n \"name\": \"NothingToClaim\",\n \"msg\": \"Nothing to claim — claimable balance is zero\"\n },\n {\n \"code\": 6001,\n \"name\": \"MathOverflow\",\n \"msg\": \"Arithmetic overflow\"\n },\n {\n \"code\": 6002,\n \"name\": \"InsufficientVaultBalance\",\n \"msg\": \"Insufficient SOL in vault — cannot withdraw below rent-exempt minimum\"\n },\n {\n \"code\": 6003,\n \"name\": \"Unauthorized\",\n \"msg\": \"Unauthorized — caller is not the configured authority\"\n },\n {\n \"code\": 6004,\n \"name\": \"InvalidFeeRecipient\",\n \"msg\": \"Invalid fee recipient account — must match PlatformConfig.platform_fee_recipient\"\n },\n {\n \"code\": 6005,\n \"name\": \"LedgerNotInitialized\",\n \"msg\": \"Fee ledger has not been initialized for this mint\"\n },\n {\n \"code\": 6006,\n \"name\": \"WrongCreator\",\n \"msg\": \"Wrong creator — signer is not FeeLedger.creator_wallet\"\n },\n {\n \"code\": 6007,\n \"name\": \"ClaimBelowMinimum\",\n \"msg\": \"Claimable amount is below the minimum threshold\"\n },\n {\n \"code\": 6008,\n \"name\": \"InvalidPoolAccountData\",\n \"msg\": \"Meteora pool account data is too small to deserialize\"\n }\n ],\n \"types\": [\n {\n \"name\": \"FeeLedger\",\n \"docs\": [\n \"Per-mint accrual ledger.\",\n \"\",\n \"One FeeLedger PDA exists per launched coin (seeds: [b\\\"fee_ledger\\\", mint]).\",\n \"It records cumulative SOL accrued from Meteora sweeps and cumulative SOL\",\n \"claimed by the creator. The (accrued - claimed) delta is the creator's\",\n \"current claimable balance.\",\n \"\",\n \"Ported (with reductions) from `hey_curve/state/fee_ledger.rs`:\",\n \"- DROP: `platform_fees_accumulated` / `platform_fees_claimed` (Memeputer\",\n \"accrues 100% to creator and deducts `claim_fee_bps` at user-claim\",\n \"time, not at sweep time)\",\n \"- DROP: `creator_claimed[100]` / `last_creator_claim_at[100]` arrays\",\n \"(Memeputer is single-recipient per D-03)\",\n \"- DROP: `swept: u8` (no 90-day expiry sweep — deferred to v2)\",\n \"- DROP: `trade_count` (analytics, not v1)\",\n \"- ADD: `creator_wallet: Pubkey` (single recipient; mutable per D-03)\",\n \"- ADD: `reserved: [u8; 64]` (forward-compat for v2 features)\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"bump\",\n \"docs\": [\n \"Canonical PDA bump (SEC-01 — stored so claim/sweep ix don't recompute).\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The SPL token mint this ledger tracks fees for.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"creator_wallet\",\n \"docs\": [\n \"Phase 6.2 forward-compat: `creator_wallet` MUST stay mutable here so\",\n \"a future `update_creator_wallet` instruction can swap it without a\",\n \"program redeploy. Do NOT add an `#[account(constraint = ...)]` that\",\n \"freezes this field; do NOT mark it `#[account(init_if_needed)]`-only.\",\n \"Per D-03 (CONTEXT.md). See Open Question #4 (RESOLVED — deferred to\",\n \"Phase 6.2 design for timelock semantics).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"accrued\",\n \"docs\": [\n \"Total Meteora trading fees accrued (lamports). Monotonically increasing.\",\n \"Credited by `claim_meteora_fees` (sweep-side).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"claimed\",\n \"docs\": [\n \"Total claimed by creator (lamports). Monotonically increasing.\",\n \"Incremented by `claim_creator_reward` (user-signed).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"last_swept_at\",\n \"docs\": [\n \"Last time a sweep deposited fees (i64 unix seconds; 0 = never).\"\n ],\n \"type\": \"i64\"\n },\n {\n \"name\": \"last_claim_at\",\n \"docs\": [\n \"Last time creator claimed (i64 unix seconds; 0 = never).\"\n ],\n \"type\": \"i64\"\n },\n {\n \"name\": \"reserved\",\n \"docs\": [\n \"Reserved for v2 features (multi-recipient, vesting, expiry, per-room\",\n \"claim_fee_bps override). Pad to 64 bytes so v2 migrations can add\",\n \"fields without requiring a redeploy.\"\n ],\n \"type\": {\n \"array\": [\n \"u8\",\n 64\n ]\n }\n }\n ]\n }\n },\n {\n \"name\": \"FeesClaimed\",\n \"docs\": [\n \"Emitted by `claim_creator_reward` after a successful user-signed claim.\",\n \"\",\n \"Memeputer has a single claim type (creator), so we don't carry a\",\n \"`claim_type` enum like hey_curve does.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The token mint whose FeeLedger was debited.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"claimer\",\n \"docs\": [\n \"The signer (must == FeeLedger.creator_wallet by constraint).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"recipient\",\n \"docs\": [\n \"The wallet that received the NET proceeds (defaults to creator, but\",\n \"per D-07 the user may direct the net to any address).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"gross\",\n \"docs\": [\n \"Lamports of the gross claim (= accrued - claimed BEFORE this call).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"claim_fee\",\n \"docs\": [\n \"Lamports deducted as platform claim_fee (gross * claim_fee_bps / 10000).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"net\",\n \"docs\": [\n \"Lamports paid to `recipient` (= gross - claim_fee).\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"timestamp\",\n \"docs\": [\n \"Clock::get() timestamp at emit time.\"\n ],\n \"type\": \"i64\"\n }\n ]\n }\n },\n {\n \"name\": \"MeteoraFeesClaimed\",\n \"docs\": [\n \"Emitted by `claim_meteora_fees` after a successful sweep deposit.\",\n \"\",\n \"Memeputer is SOL-quoted only (DBC quote = wSOL → unwrapped to SOL on\",\n \"deposit), so we don't carry a `token_claimed` field like hey_curve does.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"mint\",\n \"docs\": [\n \"The token mint whose FeeLedger was credited.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"meteora_pool\",\n \"docs\": [\n \"The Meteora pool the fees came from (DBC pre-graduation, or DAMM v2\",\n \"position post-graduation).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"sol_claimed\",\n \"docs\": [\n \"Lamports deposited into FeeVault by this sweep.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"timestamp\",\n \"docs\": [\n \"Clock::get() timestamp at emit time.\"\n ],\n \"type\": \"i64\"\n }\n ]\n }\n },\n {\n \"name\": \"PlatformConfig\",\n \"docs\": [\n \"Singleton platform config (seeds: [b\\\"platform_config\\\"]).\",\n \"\",\n \"Ported (with reductions) from `hey_curve/state/platform_config.rs`:\",\n \"- KEEP: `bump`, `authority` (= upgrade authority), `claim_fee_bps`,\",\n \"`platform_fee_recipient`.\",\n \"- DROP: every bonding-curve field (`bonding_threshold_sol`,\",\n \"`max_buy_sol`, `max_holding_bps`, `creator_sell_lock_seconds`,\",\n \"`creation_fee_lamports`, `creator_fee_bps`, `migration_fee_lamports`,\",\n \"`max_creator_fee_bps`). Memeputer uses Meteora DBC as the curve, so\",\n \"these are configured at coin-launch time via the Meteora SDK, not\",\n \"here.\",\n \"- DROP: three-tier authority fields (`admin`, `operator`, `frozen`).\",\n \"v1 uses a single `authority` field. Multi-sig + freeze flag deferred.\",\n \"- ADD: `reserved: [u8; 64]` for v2 forward-compat.\"\n ],\n \"type\": {\n \"kind\": \"struct\",\n \"fields\": [\n {\n \"name\": \"bump\",\n \"docs\": [\n \"Canonical PDA bump (SEC-01).\"\n ],\n \"type\": \"u8\"\n },\n {\n \"name\": \"authority\",\n \"docs\": [\n \"Upgrade authority — the only key that can call\",\n \"`update_platform_config` or `transfer_upgrade_authority`. Note that\",\n \"this is the program-level config authority, NOT the BPF loader's\",\n \"program-upgrade authority (which is set via `solana program deploy\",\n \"--keypair $UPGRADE_AUTHORITY_KEYPAIR` at deploy time).\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"claim_fee_bps\",\n \"docs\": [\n \"Claim fee in basis points deducted from `claim_creator_reward`\",\n \"proceeds (default 100 = 1%; capped at 1000 = 10%). Per D-06: GLOBAL,\",\n \"not per-room.\"\n ],\n \"type\": \"u64\"\n },\n {\n \"name\": \"platform_fee_recipient\",\n \"docs\": [\n \"Single platform fee recipient wallet — receives the `claim_fee`\",\n \"deduction from every `claim_creator_reward` call.\"\n ],\n \"type\": \"pubkey\"\n },\n {\n \"name\": \"reserved\",\n \"docs\": [\n \"Reserved for v2 features (e.g., per-room claim_fee_bps override,\",\n \"multi-recipient platform fees). Pad to 64 bytes.\"\n ],\n \"type\": {\n \"array\": [\n \"u8\",\n 64\n ]\n }\n }\n ]\n }\n }\n ]\n}","import type { MemeputerClient } from './client.js';\n\n/** POST /v1/rooms/:mint/bans body. `reason` required (1..500 chars). */\nexport interface CreateBanBody {\n userWallet: string;\n reason: string;\n}\n\n/** POST /v1/rooms/:mint/mods body. */\nexport interface AppointModBody {\n userWallet: string;\n}\n\n/**\n * ModsNamespace — `mp.mods.*` wraps owner/mod write endpoints across rooms.\n *\n * Authorization model (CONTEXT D-13): owners can ban/unban/pin/unpin/delete\n * AND appoint/revoke mods. Appointed mods inherit the first set but NOT the\n * appointment power (mod escalation is impossible without the owner's\n * signature). The server enforces this via the room-authorization service;\n * the SDK does not pre-validate.\n *\n * Response shapes vary slightly per endpoint (`{ banned: true }`,\n * `{ unbanned: true }`, `{ appointed: true }`, `{ status: 'already_mod' }`,\n * etc.) — the SDK returns the raw envelope as `unknown`-shaped JSON. v2 may\n * normalize this to `{ ok: true }` once the API surface stabilizes.\n */\nexport class ModsNamespace {\n constructor(private readonly client: MemeputerClient) {}\n\n /** POST /v1/rooms/:mint/bans — signed; owner or appointed mod. */\n ban(mint: string, body: CreateBanBody): Promise<unknown> {\n return this.client.signedRequest('POST', `/v1/rooms/${mint}/bans`, body);\n }\n\n /** DELETE /v1/rooms/:mint/bans/:userWallet — signed; owner or appointed mod. */\n unban(mint: string, userWallet: string): Promise<unknown> {\n return this.client.signedRequest(\n 'DELETE',\n `/v1/rooms/${mint}/bans/${userWallet}`,\n null,\n );\n }\n\n /** POST /v1/rooms/:mint/pins/:messageId — signed; owner or appointed mod. */\n pin(mint: string, messageId: string): Promise<unknown> {\n return this.client.signedRequest(\n 'POST',\n `/v1/rooms/${mint}/pins/${messageId}`,\n null,\n );\n }\n\n /** DELETE /v1/rooms/:mint/pins/:messageId — signed; owner or appointed mod. */\n unpin(mint: string, messageId: string): Promise<unknown> {\n return this.client.signedRequest(\n 'DELETE',\n `/v1/rooms/${mint}/pins/${messageId}`,\n null,\n );\n }\n\n /** POST /v1/rooms/:mint/mods — signed; owner ONLY (mods cannot appoint mods). */\n appoint(mint: string, body: AppointModBody): Promise<unknown> {\n return this.client.signedRequest('POST', `/v1/rooms/${mint}/mods`, body);\n }\n\n /** DELETE /v1/rooms/:mint/mods/:userWallet — signed; owner ONLY. */\n revoke(mint: string, userWallet: string): Promise<unknown> {\n return this.client.signedRequest(\n 'DELETE',\n `/v1/rooms/${mint}/mods/${userWallet}`,\n null,\n );\n }\n\n /** DELETE /v1/rooms/:mint/messages/:messageId — signed; owner or mod (soft delete). */\n deleteMessage(mint: string, messageId: string): Promise<unknown> {\n return this.client.signedRequest(\n 'DELETE',\n `/v1/rooms/${mint}/messages/${messageId}`,\n null,\n );\n }\n}\n","import type { ApiAgentProfile } from './types.js';\nimport type { MemeputerClient } from './client.js';\nimport { MemeputerApiError } from './errors.js';\n\nexport type UploadKind = 'agent-avatar' | 'avatar' | 'background';\nexport type UploadContentType = 'image/png' | 'image/jpeg' | 'image/webp';\n\nexport interface SignUploadBody {\n contentType: UploadContentType;\n kind: UploadKind;\n}\n\nexport interface SignedUpload {\n upload_url: string;\n method: 'PUT';\n headers: Record<string, string>;\n path: string;\n public_url: string;\n}\n\nexport interface MediaUploadResult {\n path: string;\n publicUrl: string;\n}\n\nexport interface MediaAvatarUploadResult extends MediaUploadResult {\n profile: ApiAgentProfile;\n}\n\ntype UploadBody = NonNullable<RequestInit['body']>;\n\n/**\n * MediaNamespace — durable R2-backed media uploads.\n *\n * Flow:\n * 1. canonical-signed POST /v1/uploads/sign\n * 2. unsigned PUT bytes directly to the returned R2 presigned URL\n * 3. optionally PATCH /v1/agents/:wallet with the returned public URL\n */\nexport class MediaNamespace {\n constructor(private readonly client: MemeputerClient) {}\n\n sign(body: SignUploadBody): Promise<SignedUpload> {\n return this.client.signedRequest('POST', '/v1/uploads/sign', body);\n }\n\n async put(signed: SignedUpload, body: UploadBody): Promise<MediaUploadResult> {\n const res = await this.client.rawFetch(signed.upload_url, {\n method: signed.method ?? 'PUT',\n headers: signed.headers,\n body,\n });\n\n if (!res.ok) {\n const details = await res.text().catch(() => '');\n throw new MemeputerApiError('INTERNAL_ERROR', 'MEDIA_UPLOAD_FAILED', res.status, {\n path: signed.path,\n details,\n });\n }\n\n return { path: signed.path, publicUrl: signed.public_url };\n }\n\n /**\n * Upload an optimized WebP avatar and return its durable media URL.\n * The profile is not patched; call `mp.agents.patch(wallet, { avatarUrl })`\n * yourself if you want a two-step workflow.\n */\n async uploadAgentAvatar(webp: UploadBody): Promise<MediaUploadResult> {\n const signed = await this.sign({ kind: 'agent-avatar', contentType: 'image/webp' });\n return this.put(signed, webp);\n }\n\n /**\n * Upload an optimized WebP avatar and immediately set it on the signer profile.\n * Defaults to the client's signer wallet; passing a different wallet will only\n * work if that wallet is also the signer on the request.\n */\n async uploadAndSetAgentAvatar(\n webp: UploadBody,\n wallet = this.client.signer.publicKey.toBase58(),\n ): Promise<MediaAvatarUploadResult> {\n const uploaded = await this.uploadAgentAvatar(webp);\n const profile = await this.client.agents.patch(wallet, { avatarUrl: uploaded.publicUrl });\n return { ...uploaded, profile };\n }\n}\n","import {\n PublicKey,\n Transaction,\n VersionedTransaction,\n type Keypair,\n} from '@solana/web3.js';\nimport nacl from 'tweetnacl';\n\n/**\n * Wallet abstraction for the Memeputer SDK (D-01).\n *\n * Byte-in / byte-out / async. `signMessage` is REQUIRED — every signed\n * write (rooms.post, mods.*, etc.) is canonical-JSON message-signed via\n * this method.\n *\n * `signTransaction` is OPTIONAL — required ONLY for `mp.rooms.claimFees`\n * (Phase 6.1, Plan 06.1-06) which submits an on-chain Anchor\n * `claim_creator_reward` ix. If a consumer never calls `claimFees`, they\n * can implement just `signMessage` and the SDK works end-to-end.\n *\n * Consumers with KMS/HSM/Turnkey/multi-sig keys implement this directly.\n * See apps/web/lib/turnkey-signer.ts for the reference shape.\n */\nexport interface Signer {\n /** The Solana pubkey this signer signs for. */\n readonly publicKey: PublicKey;\n /**\n * Sign arbitrary bytes with Ed25519. Returns the RAW 64-byte signature.\n * Do NOT base58-encode here — the SDK encodes for the wire.\n */\n signMessage(bytes: Uint8Array): Promise<Uint8Array>;\n /**\n * Sign a Solana transaction (Legacy or v0). OPTIONAL — only required by\n * `mp.rooms.claimFees` (Plan 06.1-06). The implementation MUST attach the\n * Ed25519 signature for `publicKey` and return the same transaction\n * instance (or a structurally-equivalent one) — Anchor's `Wallet.signTransaction`\n * contract preserves the input type via a generic.\n *\n * If absent, `claimFees` throws a clear setup error rather than failing\n * deep inside Anchor's call stack.\n */\n signTransaction?<T extends Transaction | VersionedTransaction>(tx: T): Promise<T>;\n}\n\n/**\n * Convenience adapter for the common Keypair case.\n *\n * Implements BOTH `signMessage` (Ed25519 detached signature for canonical\n * payloads) AND `signTransaction` (delegates to `VersionedTransaction.sign`\n * / `Transaction.partialSign` for on-chain submission). Consumers who want\n * to use `mp.rooms.claimFees` out of the box just pass a Keypair.\n */\nexport function keypairSigner(kp: Keypair): Signer {\n return {\n publicKey: kp.publicKey,\n signMessage: async (bytes) => nacl.sign.detached(bytes, kp.secretKey),\n signTransaction: async <T extends Transaction | VersionedTransaction>(tx: T): Promise<T> => {\n if (tx instanceof VersionedTransaction) {\n tx.sign([kp]);\n } else {\n // Legacy Transaction — partialSign attaches kp's signature without\n // clobbering any existing signatures from other signers.\n (tx as Transaction).partialSign(kp);\n }\n return tx;\n },\n };\n}\n"],"mappings":"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","names":["import_web3","import_web3","import_web3","bs58","import_web3","nacl"]}
package/dist/cli.d.cts ADDED
@@ -0,0 +1,26 @@
1
+ interface ParsedArgs {
2
+ positional: string[];
3
+ flags: Record<string, string | undefined>;
4
+ }
5
+ /**
6
+ * Hand-rolled argv parser. Recognises three forms:
7
+ * --flag value (space-separated; value must NOT itself start with `--`)
8
+ * --flag=value (equals-separated; value MAY start with `--` or `-`)
9
+ * --flag (boolean; stored as empty string)
10
+ *
11
+ * Anything not starting with `--` is positional.
12
+ *
13
+ * WR-03: The space-separated form silently drops values that themselves start
14
+ * with `--` (e.g. `--bio --foo` would set bio='' and treat --foo as another
15
+ * flag). For values that may contain a `--` prefix, use `--flag=value` —
16
+ * the equals form is unambiguous and forwards the value as-is regardless of
17
+ * what characters it contains. Same workaround for negative numbers:
18
+ * `--post-token-threshold=-1`.
19
+ *
20
+ * Exported for unit-testing (Task 2 / cli-dispatch.test.ts) — keeping it
21
+ * exported is cheap and lets the test suite cover the parse path without
22
+ * spawning the built CLI for every assertion.
23
+ */
24
+ declare function parseArgs(argv: string[]): ParsedArgs;
25
+
26
+ export { parseArgs };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ interface ParsedArgs {
2
+ positional: string[];
3
+ flags: Record<string, string | undefined>;
4
+ }
5
+ /**
6
+ * Hand-rolled argv parser. Recognises three forms:
7
+ * --flag value (space-separated; value must NOT itself start with `--`)
8
+ * --flag=value (equals-separated; value MAY start with `--` or `-`)
9
+ * --flag (boolean; stored as empty string)
10
+ *
11
+ * Anything not starting with `--` is positional.
12
+ *
13
+ * WR-03: The space-separated form silently drops values that themselves start
14
+ * with `--` (e.g. `--bio --foo` would set bio='' and treat --foo as another
15
+ * flag). For values that may contain a `--` prefix, use `--flag=value` —
16
+ * the equals form is unambiguous and forwards the value as-is regardless of
17
+ * what characters it contains. Same workaround for negative numbers:
18
+ * `--post-token-threshold=-1`.
19
+ *
20
+ * Exported for unit-testing (Task 2 / cli-dispatch.test.ts) — keeping it
21
+ * exported is cheap and lets the test suite cover the parse path without
22
+ * spawning the built CLI for every assertion.
23
+ */
24
+ declare function parseArgs(argv: string[]): ParsedArgs;
25
+
26
+ export { parseArgs };