mnemospark 0.1.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/proxy.ts","../src/balance.ts","../src/errors.ts","../src/config.ts","../src/mnemospark-request-sign.ts","../src/nonce.ts","../src/cloud-utils.ts","../src/wallet-signature.ts","../src/cloud-price-storage.ts","../src/cloud-storage.ts","../src/auth.ts","../src/index.ts","../src/version.ts","../src/cloud-command.ts","../src/x402.ts","../src/payment-cache.ts","../src/retry.ts"],"sourcesContent":["/**\n * Local mnemospark proxy server.\n *\n * This proxy only forwards mnemospark storage endpoints to the backend API and\n * serves health checks. It does not handle chat completions or model routing.\n */\n\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { BalanceMonitor } from \"./balance.js\";\nimport { PROXY_PORT, MNEMOSPARK_BACKEND_API_BASE_URL } from \"./config.js\";\nimport { createWalletSignatureHeaderValue } from \"./mnemospark-request-sign.js\";\nimport {\n PRICE_STORAGE_PROXY_PATH,\n UPLOAD_PROXY_PATH,\n forwardPriceStorageToBackend,\n forwardStorageUploadToBackend,\n parsePriceStorageQuoteRequest,\n parseStorageUploadRequest,\n} from \"./cloud-price-storage.js\";\nimport {\n STORAGE_DELETE_PROXY_PATH,\n STORAGE_DOWNLOAD_PROXY_PATH,\n STORAGE_LS_PROXY_PATH,\n downloadStorageToDisk,\n forwardStorageDeleteToBackend,\n forwardStorageDownloadToBackend,\n forwardStorageLsToBackend,\n parseStorageObjectRequest,\n} from \"./cloud-storage.js\";\n\nconst HEALTH_CHECK_TIMEOUT_MS = 2_000; // Timeout for checking existing proxy\nconst PORT_RETRY_ATTEMPTS = 5; // Max attempts to bind port (handles TIME_WAIT)\nconst PORT_RETRY_DELAY_MS = 1_000; // Delay between retry attempts\n\nfunction matchesProxyPath(url: string | undefined, path: string): boolean {\n return url === path || url?.startsWith(`${path}?`) === true;\n}\n\nfunction readHeaderValue(value: string | string[] | undefined): string | undefined {\n if (typeof value === \"string\") {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n }\n if (Array.isArray(value)) {\n for (const candidate of value) {\n const trimmed = candidate.trim();\n if (trimmed.length > 0) {\n return trimmed;\n }\n }\n }\n return undefined;\n}\n\nasync function readProxyJsonBody(req: IncomingMessage): Promise<unknown> {\n const bodyChunks: Buffer[] = [];\n for await (const chunk of req) {\n bodyChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n const bodyText = Buffer.concat(bodyChunks).toString(\"utf-8\").trim();\n if (bodyText.length === 0) {\n return {};\n }\n\n return JSON.parse(bodyText);\n}\n\nfunction sendJson(res: ServerResponse, status: number, body: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(body));\n}\n\nfunction createBackendForwardHeaders(response: {\n contentType: string;\n paymentRequired?: string;\n paymentResponse?: string;\n}): Record<string, string> {\n const responseHeaders: Record<string, string> = {\n \"Content-Type\": response.contentType,\n };\n\n // Preserve v2 payment headers while also supporting legacy names.\n if (response.paymentRequired) {\n responseHeaders[\"PAYMENT-REQUIRED\"] = response.paymentRequired;\n responseHeaders[\"x-payment-required\"] = response.paymentRequired;\n }\n if (response.paymentResponse) {\n responseHeaders[\"PAYMENT-RESPONSE\"] = response.paymentResponse;\n responseHeaders[\"x-payment-response\"] = response.paymentResponse;\n }\n\n return responseHeaders;\n}\n\ntype BackendAuthFailure = {\n status: number;\n contentType: string;\n bodyText: string;\n};\n\nfunction isLikelyWalletProofFailure(bodyText: string): boolean {\n return /(wallet|signature|proof|nonce|timestamp|expired|authoriz)/i.test(bodyText);\n}\n\nexport function normalizeBackendAuthFailure(\n status: number,\n bodyText: string,\n): BackendAuthFailure | undefined {\n if (status !== 401 && status !== 403) {\n return undefined;\n }\n\n const message = isLikelyWalletProofFailure(bodyText) ? \"wallet proof invalid\" : \"unauthorized\";\n return {\n status,\n contentType: \"application/json\",\n bodyText: createAuthErrorBody(message),\n };\n}\n\nfunction createAuthErrorBody(message: \"unauthorized\" | \"wallet proof invalid\"): string {\n return JSON.stringify({\n error: message.replace(/\\s+/g, \"_\"),\n message,\n });\n}\n\nfunction createWalletRequiredBody(): string {\n return JSON.stringify({\n error: \"wallet_required\",\n message: \"wallet required for storage endpoints\",\n });\n}\n\n/**\n * Get the proxy port from pre-loaded configuration.\n * Port is validated at module load time, this just returns the cached value.\n */\nexport function getProxyPort(): number {\n return PROXY_PORT;\n}\n\n/**\n * Check if a proxy is already running on the given port.\n * Returns the wallet address if running, undefined otherwise.\n */\nasync function checkExistingProxy(port: number): Promise<string | undefined> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), HEALTH_CHECK_TIMEOUT_MS);\n\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: controller.signal,\n });\n clearTimeout(timeoutId);\n\n if (response.ok) {\n const data = (await response.json()) as { status?: string; wallet?: string };\n if (data.status === \"ok\" && data.wallet) {\n return data.wallet;\n }\n }\n return undefined;\n } catch {\n clearTimeout(timeoutId);\n return undefined;\n }\n}\n\n/** Callback info for low balance warning */\nexport type LowBalanceInfo = {\n balanceUSD: string;\n walletAddress: string;\n};\n\n/** Callback info for insufficient funds error */\nexport type InsufficientFundsInfo = {\n balanceUSD: string;\n requiredUSD: string;\n walletAddress: string;\n};\n\nexport type ProxyOptions = {\n walletKey: string;\n /** Port to listen on (default: 7120) */\n port?: number;\n onReady?: (port: number) => void;\n onError?: (error: Error) => void;\n /** Called when balance drops below $1.00 (warning, request still proceeds) */\n onLowBalance?: (info: LowBalanceInfo) => void;\n /** Called when balance is insufficient for a request (request fails) */\n onInsufficientFunds?: (info: InsufficientFundsInfo) => void;\n};\n\nexport type ProxyHandle = {\n port: number;\n baseUrl: string;\n walletAddress: string;\n balanceMonitor: BalanceMonitor;\n close: () => Promise<void>;\n};\n\n/**\n * Start the local mnemospark backend proxy server.\n *\n * If a proxy is already running on the target port, reuses it instead of failing.\n * Port can be configured via MNEMOSPARK_PROXY_PORT environment variable.\n *\n * Returns a handle with the assigned port, base URL, and a close function.\n */\nexport async function startProxy(options: ProxyOptions): Promise<ProxyHandle> {\n // Determine port: options.port > env var > default\n const listenPort = options.port ?? getProxyPort();\n\n // Check if a proxy is already running on this port\n const existingWallet = await checkExistingProxy(listenPort);\n if (existingWallet) {\n // Proxy already running — reuse it instead of failing with EADDRINUSE\n const account = privateKeyToAccount(options.walletKey as `0x${string}`);\n const balanceMonitor = new BalanceMonitor(account.address);\n const baseUrl = `http://127.0.0.1:${listenPort}`;\n\n // Verify the existing proxy is using the same wallet (or warn if different)\n if (existingWallet !== account.address) {\n console.warn(\n `[mnemospark] Existing proxy on port ${listenPort} uses wallet ${existingWallet}, but current config uses ${account.address}. Reusing existing proxy.`,\n );\n }\n\n options.onReady?.(listenPort);\n\n return {\n port: listenPort,\n baseUrl,\n walletAddress: existingWallet,\n balanceMonitor,\n close: async () => {\n // No-op: we didn't start this proxy, so we shouldn't close it\n },\n };\n }\n\n const walletPrivateKey = options.walletKey.trim() as `0x${string}`;\n const account = privateKeyToAccount(walletPrivateKey);\n const balanceMonitor = new BalanceMonitor(account.address);\n const proxyWalletAddressLower = account.address.toLowerCase();\n\n // Track active connections for graceful cleanup\n const connections = new Set<import(\"net\").Socket>();\n\n const createBackendWalletSignature = async (\n method: \"GET\" | \"POST\" | \"DELETE\",\n path: string,\n walletAddress: string,\n ): Promise<string | undefined> => {\n if (walletAddress.toLowerCase() !== proxyWalletAddressLower) {\n return undefined;\n }\n\n try {\n return await createWalletSignatureHeaderValue(method, path, walletAddress, walletPrivateKey);\n } catch (err) {\n console.warn(\n `[mnemospark] Failed to create wallet proof for ${path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n return undefined;\n }\n };\n\n const server = createServer(async (req: IncomingMessage, res: ServerResponse) => {\n req.on(\"error\", (err) => {\n console.error(`[mnemospark] Request stream error: ${err.message}`);\n });\n res.on(\"error\", (err) => {\n console.error(`[mnemospark] Response stream error: ${err.message}`);\n });\n\n // Mnemospark backend proxy endpoint for /cloud price-storage command.\n if (req.method === \"POST\" && matchesProxyPath(req.url, PRICE_STORAGE_PROXY_PATH)) {\n try {\n let payload: unknown;\n try {\n payload = await readProxyJsonBody(req);\n } catch {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Invalid JSON body for /cloud price-storage\",\n });\n return;\n }\n\n const requestPayload = parsePriceStorageQuoteRequest(payload);\n if (!requestPayload) {\n sendJson(res, 400, {\n error: \"Bad request\",\n message:\n \"Missing required fields: wallet_address, object_id, object_id_hash, gb, provider, region\",\n });\n return;\n }\n\n const walletSignature = await createBackendWalletSignature(\n \"POST\",\n \"/price-storage\",\n requestPayload.wallet_address,\n );\n const backendResponse = await forwardPriceStorageToBackend(requestPayload, {\n backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,\n walletSignature,\n });\n\n const authFailure = normalizeBackendAuthFailure(\n backendResponse.status,\n backendResponse.bodyText,\n );\n if (authFailure) {\n const responseHeaders = createBackendForwardHeaders({\n contentType: authFailure.contentType,\n paymentRequired: backendResponse.paymentRequired,\n paymentResponse: backendResponse.paymentResponse,\n });\n res.writeHead(authFailure.status, responseHeaders);\n res.end(authFailure.bodyText);\n return;\n }\n\n const responseHeaders = createBackendForwardHeaders(backendResponse);\n res.writeHead(backendResponse.status, responseHeaders);\n res.end(backendResponse.bodyText);\n } catch (err) {\n sendJson(res, 502, {\n error: \"proxy_error\",\n message: `Failed to forward /cloud price-storage: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n return;\n }\n\n // Mnemospark backend proxy endpoint for /cloud upload command.\n if (req.method === \"POST\" && matchesProxyPath(req.url, UPLOAD_PROXY_PATH)) {\n try {\n let payload: unknown;\n try {\n payload = await readProxyJsonBody(req);\n } catch {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Invalid JSON body for /cloud upload\",\n });\n return;\n }\n\n const requestPayload = parseStorageUploadRequest(payload);\n if (!requestPayload) {\n sendJson(res, 400, {\n error: \"Bad request\",\n message:\n \"Missing required fields: quote_id, wallet_address, object_id, object_id_hash, quoted_storage_price, payload\",\n });\n return;\n }\n\n if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {\n sendJson(res, 403, {\n error: \"wallet_proof_invalid\",\n message: \"wallet proof invalid\",\n });\n return;\n }\n\n const walletSignature = await createBackendWalletSignature(\n \"POST\",\n \"/storage/upload\",\n requestPayload.wallet_address,\n );\n if (!walletSignature) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(createWalletRequiredBody());\n return;\n }\n\n const requiredMicros = BigInt(\n Math.max(1, Math.ceil(requestPayload.quoted_storage_price * 1_000_000)),\n );\n const uploadBalanceMonitor =\n requestPayload.wallet_address.toLowerCase() === account.address.toLowerCase()\n ? balanceMonitor\n : new BalanceMonitor(requestPayload.wallet_address);\n const sufficiency = await uploadBalanceMonitor.checkSufficient(requiredMicros);\n const requiredUSD = uploadBalanceMonitor.formatUSDC(requiredMicros);\n\n if (!sufficiency.sufficient) {\n options.onInsufficientFunds?.({\n balanceUSD: sufficiency.info.balanceUSD,\n requiredUSD,\n walletAddress: requestPayload.wallet_address,\n });\n sendJson(res, 400, {\n error: \"insufficient_balance\",\n message: `Insufficient USDC balance. Current: ${sufficiency.info.balanceUSD}, Required: ${requiredUSD}`,\n wallet: requestPayload.wallet_address,\n help: `Fund wallet ${requestPayload.wallet_address} on Base before running /cloud upload`,\n });\n return;\n }\n\n if (sufficiency.info.isLow) {\n options.onLowBalance?.({\n balanceUSD: sufficiency.info.balanceUSD,\n walletAddress: requestPayload.wallet_address,\n });\n }\n\n const backendResponse = await forwardStorageUploadToBackend(requestPayload, {\n backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,\n walletSignature,\n paymentSignature: readHeaderValue(req.headers[\"payment-signature\"]),\n legacyPayment: readHeaderValue(req.headers[\"x-payment\"]),\n idempotencyKey: readHeaderValue(req.headers[\"idempotency-key\"]),\n });\n\n const authFailure = normalizeBackendAuthFailure(\n backendResponse.status,\n backendResponse.bodyText,\n );\n if (authFailure) {\n const responseHeaders = createBackendForwardHeaders({\n contentType: authFailure.contentType,\n paymentRequired: backendResponse.paymentRequired,\n paymentResponse: backendResponse.paymentResponse,\n });\n res.writeHead(authFailure.status, responseHeaders);\n res.end(authFailure.bodyText);\n return;\n }\n\n const responseHeaders = createBackendForwardHeaders(backendResponse);\n res.writeHead(backendResponse.status, responseHeaders);\n res.end(backendResponse.bodyText);\n } catch (err) {\n sendJson(res, 502, {\n error: \"proxy_error\",\n message: `Failed to forward /cloud upload: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n return;\n }\n\n // Mnemospark backend proxy endpoint for /cloud ls command.\n if (req.method === \"POST\" && matchesProxyPath(req.url, STORAGE_LS_PROXY_PATH)) {\n try {\n let payload: unknown;\n try {\n payload = await readProxyJsonBody(req);\n } catch {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Invalid JSON body for /cloud ls\",\n });\n return;\n }\n\n const requestPayload = parseStorageObjectRequest(payload);\n if (!requestPayload) {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Missing required fields: wallet_address, object_key\",\n });\n return;\n }\n\n if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {\n sendJson(res, 403, {\n error: \"wallet_proof_invalid\",\n message: \"wallet proof invalid\",\n });\n return;\n }\n\n const walletSignature = await createBackendWalletSignature(\n \"POST\",\n \"/storage/ls\",\n requestPayload.wallet_address,\n );\n if (!walletSignature) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(createWalletRequiredBody());\n return;\n }\n\n const backendResponse = await forwardStorageLsToBackend(requestPayload, {\n backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,\n walletSignature,\n });\n\n const authFailure = normalizeBackendAuthFailure(\n backendResponse.status,\n backendResponse.bodyText,\n );\n if (authFailure) {\n const responseHeaders = createBackendForwardHeaders({\n contentType: authFailure.contentType,\n paymentRequired: backendResponse.paymentRequired,\n paymentResponse: backendResponse.paymentResponse,\n });\n res.writeHead(authFailure.status, responseHeaders);\n res.end(authFailure.bodyText);\n return;\n }\n\n const responseHeaders = createBackendForwardHeaders(backendResponse);\n res.writeHead(backendResponse.status, responseHeaders);\n res.end(backendResponse.bodyText);\n } catch (err) {\n sendJson(res, 502, {\n error: \"proxy_error\",\n message: `Failed to forward /cloud ls: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n return;\n }\n\n // Mnemospark backend proxy endpoint for /cloud download command.\n if (req.method === \"POST\" && matchesProxyPath(req.url, STORAGE_DOWNLOAD_PROXY_PATH)) {\n try {\n let payload: unknown;\n try {\n payload = await readProxyJsonBody(req);\n } catch {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Invalid JSON body for /cloud download\",\n });\n return;\n }\n\n const requestPayload = parseStorageObjectRequest(payload);\n if (!requestPayload) {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Missing required fields: wallet_address, object_key\",\n });\n return;\n }\n\n if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {\n sendJson(res, 403, {\n error: \"wallet_proof_invalid\",\n message: \"wallet proof invalid\",\n });\n return;\n }\n\n const walletSignature = await createBackendWalletSignature(\n \"POST\",\n \"/storage/download\",\n requestPayload.wallet_address,\n );\n if (!walletSignature) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(createWalletRequiredBody());\n return;\n }\n\n const backendResponse = await forwardStorageDownloadToBackend(requestPayload, {\n backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,\n walletSignature,\n });\n\n const authFailure = normalizeBackendAuthFailure(\n backendResponse.status,\n backendResponse.bodyText,\n );\n if (authFailure) {\n const responseHeaders = createBackendForwardHeaders({\n contentType: authFailure.contentType,\n paymentRequired: backendResponse.paymentRequired,\n paymentResponse: backendResponse.paymentResponse,\n });\n res.writeHead(authFailure.status, responseHeaders);\n res.end(authFailure.bodyText);\n return;\n }\n\n // Forward backend failures directly so client gets original status/details.\n if (backendResponse.status < 200 || backendResponse.status >= 300) {\n const responseHeaders = createBackendForwardHeaders(backendResponse);\n res.writeHead(backendResponse.status, responseHeaders);\n res.end(backendResponse.bodyText);\n return;\n }\n\n const downloadResult = await downloadStorageToDisk(requestPayload, backendResponse);\n sendJson(res, 200, {\n success: true,\n key: downloadResult.key,\n file_path: downloadResult.filePath,\n bytes_written: downloadResult.bytesWritten,\n });\n } catch (err) {\n sendJson(res, 502, {\n error: \"proxy_error\",\n message: `Failed to forward /cloud download: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n return;\n }\n\n // Mnemospark backend proxy endpoint for /cloud delete command.\n if (req.method === \"POST\" && matchesProxyPath(req.url, STORAGE_DELETE_PROXY_PATH)) {\n try {\n let payload: unknown;\n try {\n payload = await readProxyJsonBody(req);\n } catch {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Invalid JSON body for /cloud delete\",\n });\n return;\n }\n\n const requestPayload = parseStorageObjectRequest(payload);\n if (!requestPayload) {\n sendJson(res, 400, {\n error: \"Bad request\",\n message: \"Missing required fields: wallet_address, object_key\",\n });\n return;\n }\n\n if (requestPayload.wallet_address.toLowerCase() !== proxyWalletAddressLower) {\n sendJson(res, 403, {\n error: \"wallet_proof_invalid\",\n message: \"wallet proof invalid\",\n });\n return;\n }\n\n const walletSignature = await createBackendWalletSignature(\n \"POST\",\n \"/storage/delete\",\n requestPayload.wallet_address,\n );\n if (!walletSignature) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(createWalletRequiredBody());\n return;\n }\n\n const backendResponse = await forwardStorageDeleteToBackend(requestPayload, {\n backendBaseUrl: MNEMOSPARK_BACKEND_API_BASE_URL,\n walletSignature,\n });\n\n const authFailure = normalizeBackendAuthFailure(\n backendResponse.status,\n backendResponse.bodyText,\n );\n if (authFailure) {\n const responseHeaders = createBackendForwardHeaders({\n contentType: authFailure.contentType,\n paymentRequired: backendResponse.paymentRequired,\n paymentResponse: backendResponse.paymentResponse,\n });\n res.writeHead(authFailure.status, responseHeaders);\n res.end(authFailure.bodyText);\n return;\n }\n\n const responseHeaders = createBackendForwardHeaders(backendResponse);\n res.writeHead(backendResponse.status, responseHeaders);\n res.end(backendResponse.bodyText);\n } catch (err) {\n sendJson(res, 502, {\n error: \"proxy_error\",\n message: `Failed to forward /cloud delete: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n return;\n }\n\n // Health check with optional balance info\n if (req.url === \"/health\" || req.url?.startsWith(\"/health?\")) {\n const url = new URL(req.url, \"http://localhost\");\n const full = url.searchParams.get(\"full\") === \"true\";\n\n const response: Record<string, unknown> = {\n status: \"ok\",\n wallet: account.address,\n };\n\n if (full) {\n try {\n const balanceInfo = await balanceMonitor.checkBalance();\n response.balance = balanceInfo.balanceUSD;\n response.isLow = balanceInfo.isLow;\n response.isEmpty = balanceInfo.isEmpty;\n } catch {\n response.balanceError = \"Could not fetch balance\";\n }\n }\n\n sendJson(res, 200, response);\n return;\n }\n\n sendJson(res, 404, {\n error: \"Not found\",\n message: \"Supported paths: /health and /mnemospark/* storage endpoints\",\n });\n });\n\n // Listen on configured port with retry logic for TIME_WAIT handling\n // When gateway restarts quickly, the port may still be in TIME_WAIT state.\n // We retry with delay instead of incorrectly assuming a proxy is running.\n const tryListen = (attempt: number): Promise<void> => {\n return new Promise<void>((resolveAttempt, rejectAttempt) => {\n const onError = async (err: NodeJS.ErrnoException) => {\n server.removeListener(\"error\", onError);\n\n if (err.code === \"EADDRINUSE\") {\n // Port is in use - check if a proxy is actually running\n const existingWallet = await checkExistingProxy(listenPort);\n if (existingWallet) {\n // Proxy is actually running - this is fine, reuse it\n console.log(`[mnemospark] Existing proxy detected on port ${listenPort}, reusing`);\n rejectAttempt({ code: \"REUSE_EXISTING\", wallet: existingWallet });\n return;\n }\n\n // Port is in TIME_WAIT (no proxy responding) - retry after delay\n if (attempt < PORT_RETRY_ATTEMPTS) {\n console.log(\n `[mnemospark] Port ${listenPort} in TIME_WAIT, retrying in ${PORT_RETRY_DELAY_MS}ms (attempt ${attempt}/${PORT_RETRY_ATTEMPTS})`,\n );\n rejectAttempt({ code: \"RETRY\", attempt });\n return;\n }\n\n // Max retries exceeded\n console.error(\n `[mnemospark] Port ${listenPort} still in use after ${PORT_RETRY_ATTEMPTS} attempts`,\n );\n rejectAttempt(err);\n return;\n }\n\n rejectAttempt(err);\n };\n\n server.once(\"error\", onError);\n server.listen(listenPort, \"127.0.0.1\", () => {\n server.removeListener(\"error\", onError);\n resolveAttempt();\n });\n });\n };\n\n // Retry loop for port binding\n let lastError: Error | undefined;\n for (let attempt = 1; attempt <= PORT_RETRY_ATTEMPTS; attempt++) {\n try {\n await tryListen(attempt);\n break; // Success\n } catch (err: unknown) {\n const error = err as { code?: string; wallet?: string };\n\n if (error.code === \"REUSE_EXISTING\" && error.wallet) {\n // Proxy is running, reuse it\n const baseUrl = `http://127.0.0.1:${listenPort}`;\n options.onReady?.(listenPort);\n return {\n port: listenPort,\n baseUrl,\n walletAddress: error.wallet,\n balanceMonitor,\n close: async () => {\n // No-op: we didn't start this proxy, so we shouldn't close it\n },\n };\n }\n\n if (error.code === \"RETRY\") {\n // Wait before retry\n await new Promise((r) => setTimeout(r, PORT_RETRY_DELAY_MS));\n continue;\n }\n\n // Other error - throw\n lastError = err as Error;\n break;\n }\n }\n\n if (lastError) {\n throw lastError;\n }\n\n // Server is now listening - set up remaining handlers\n const addr = server.address() as AddressInfo;\n const port = addr.port;\n const baseUrl = `http://127.0.0.1:${port}`;\n\n options.onReady?.(port);\n\n // Add runtime error handler AFTER successful listen\n // This handles errors that occur during server operation (not just startup)\n server.on(\"error\", (err) => {\n console.error(`[mnemospark] Server runtime error: ${err.message}`);\n options.onError?.(err);\n });\n\n // Handle client connection errors (bad requests, socket errors)\n server.on(\"clientError\", (err, socket) => {\n console.error(`[mnemospark] Client error: ${err.message}`);\n // Send 400 Bad Request if socket is still writable\n if (socket.writable && !socket.destroyed) {\n socket.end(\"HTTP/1.1 400 Bad Request\\r\\n\\r\\n\");\n }\n });\n\n // Track connections for graceful cleanup\n server.on(\"connection\", (socket) => {\n connections.add(socket);\n\n // Keep alignment with prior behavior for long-running uploads/downloads.\n socket.setTimeout(300_000);\n\n socket.on(\"timeout\", () => {\n console.error(`[mnemospark] Socket timeout, destroying connection`);\n socket.destroy();\n });\n\n socket.on(\"error\", (err) => {\n console.error(`[mnemospark] Socket error: ${err.message}`);\n });\n\n socket.on(\"close\", () => {\n connections.delete(socket);\n });\n });\n\n return {\n port,\n baseUrl,\n walletAddress: account.address,\n balanceMonitor,\n close: () =>\n new Promise<void>((res, rej) => {\n const timeout = setTimeout(() => {\n rej(new Error(\"[mnemospark] Close timeout after 4s\"));\n }, 4000);\n\n // Destroy all active connections before closing server\n for (const socket of connections) {\n socket.destroy();\n }\n connections.clear();\n server.close((err) => {\n clearTimeout(timeout);\n if (err) {\n rej(err);\n } else {\n res();\n }\n });\n }),\n };\n}\n","/**\n * Balance Monitor for ClawRouter\n *\n * Monitors USDC balance on Base network with intelligent caching.\n * Provides pre-request balance checks to prevent failed payments.\n *\n * Caching Strategy:\n * - TTL: 30 seconds (balance is cached to avoid excessive RPC calls)\n * - Optimistic deduction: after successful payment, subtract estimated cost from cache\n * - Invalidation: on payment failure, immediately refresh from RPC\n */\n\nimport { createPublicClient, http, erc20Abi } from \"viem\";\nimport { base } from \"viem/chains\";\nimport { RpcError } from \"./errors.js\";\n\n/** USDC contract address on Base mainnet */\nconst USDC_BASE = \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\" as const;\n\n/** Cache TTL in milliseconds (30 seconds) */\nconst CACHE_TTL_MS = 30_000;\n\n/** Balance thresholds in USDC smallest unit (6 decimals) */\nexport const BALANCE_THRESHOLDS = {\n /** Low balance warning threshold: $1.00 */\n LOW_BALANCE_MICROS: 1_000_000n,\n /** Effectively zero threshold: $0.0001 (covers dust/rounding) */\n ZERO_THRESHOLD: 100n,\n} as const;\n\n/** Balance information returned by checkBalance() */\nexport type BalanceInfo = {\n /** Raw balance in USDC smallest unit (6 decimals) */\n balance: bigint;\n /** Formatted balance as \"$X.XX\" */\n balanceUSD: string;\n /** True if balance < $1.00 */\n isLow: boolean;\n /** True if balance < $0.0001 (effectively zero) */\n isEmpty: boolean;\n /** Wallet address for funding instructions */\n walletAddress: string;\n};\n\n/** Result from checkSufficient() */\nexport type SufficiencyResult = {\n /** True if balance >= estimated cost */\n sufficient: boolean;\n /** Current balance info */\n info: BalanceInfo;\n /** If insufficient, the shortfall as \"$X.XX\" */\n shortfall?: string;\n};\n\n/**\n * Monitors USDC balance on Base network.\n *\n * Usage:\n * const monitor = new BalanceMonitor(\"0x...\");\n * const info = await monitor.checkBalance();\n * if (info.isLow) console.warn(\"Low balance!\");\n */\nexport class BalanceMonitor {\n private readonly client;\n private readonly walletAddress: `0x${string}`;\n\n /** Cached balance (null = not yet fetched) */\n private cachedBalance: bigint | null = null;\n /** Timestamp when cache was last updated */\n private cachedAt = 0;\n\n constructor(walletAddress: string) {\n this.walletAddress = walletAddress as `0x${string}`;\n this.client = createPublicClient({\n chain: base,\n transport: http(undefined, {\n timeout: 10_000, // 10 second timeout to prevent hanging on slow RPC\n }),\n });\n }\n\n /**\n * Check current USDC balance.\n * Uses cache if valid, otherwise fetches from RPC.\n */\n async checkBalance(): Promise<BalanceInfo> {\n const now = Date.now();\n\n // Use cache if valid\n if (this.cachedBalance !== null && now - this.cachedAt < CACHE_TTL_MS) {\n return this.buildInfo(this.cachedBalance);\n }\n\n // Fetch from RPC\n const balance = await this.fetchBalance();\n this.cachedBalance = balance;\n this.cachedAt = now;\n\n return this.buildInfo(balance);\n }\n\n /**\n * Check if balance is sufficient for an estimated cost.\n *\n * @param estimatedCostMicros - Estimated cost in USDC smallest unit (6 decimals)\n */\n async checkSufficient(estimatedCostMicros: bigint): Promise<SufficiencyResult> {\n const info = await this.checkBalance();\n\n if (info.balance >= estimatedCostMicros) {\n return { sufficient: true, info };\n }\n\n const shortfall = estimatedCostMicros - info.balance;\n return {\n sufficient: false,\n info,\n shortfall: this.formatUSDC(shortfall),\n };\n }\n\n /**\n * Optimistically deduct estimated cost from cached balance.\n * Call this after a successful payment to keep cache accurate.\n *\n * @param amountMicros - Amount to deduct in USDC smallest unit\n */\n deductEstimated(amountMicros: bigint): void {\n if (this.cachedBalance !== null && this.cachedBalance >= amountMicros) {\n this.cachedBalance -= amountMicros;\n }\n }\n\n /**\n * Invalidate cache, forcing next checkBalance() to fetch from RPC.\n * Call this after a payment failure to get accurate balance.\n */\n invalidate(): void {\n this.cachedBalance = null;\n this.cachedAt = 0;\n }\n\n /**\n * Force refresh balance from RPC (ignores cache).\n */\n async refresh(): Promise<BalanceInfo> {\n this.invalidate();\n return this.checkBalance();\n }\n\n /**\n * Format USDC amount (in micros) as \"$X.XX\".\n */\n formatUSDC(amountMicros: bigint): string {\n // USDC has 6 decimals\n const dollars = Number(amountMicros) / 1_000_000;\n return `$${dollars.toFixed(2)}`;\n }\n\n /**\n * Get the wallet address being monitored.\n */\n getWalletAddress(): string {\n return this.walletAddress;\n }\n\n /** Fetch balance from RPC */\n private async fetchBalance(): Promise<bigint> {\n try {\n const balance = await this.client.readContract({\n address: USDC_BASE,\n abi: erc20Abi,\n functionName: \"balanceOf\",\n args: [this.walletAddress],\n });\n return balance;\n } catch (error) {\n // Throw typed error instead of silently returning 0\n // This allows callers to distinguish \"node down\" from \"wallet empty\"\n throw new RpcError(error instanceof Error ? error.message : \"Unknown error\", error);\n }\n }\n\n /** Build BalanceInfo from raw balance */\n private buildInfo(balance: bigint): BalanceInfo {\n return {\n balance,\n balanceUSD: this.formatUSDC(balance),\n isLow: balance < BALANCE_THRESHOLDS.LOW_BALANCE_MICROS,\n isEmpty: balance < BALANCE_THRESHOLDS.ZERO_THRESHOLD,\n walletAddress: this.walletAddress,\n };\n }\n}\n","/**\n * Typed Error Classes for mnemospark\n *\n * Provides structured errors for balance-related failures with\n * all necessary information for user-friendly error messages.\n */\n\n/**\n * Thrown when wallet has insufficient USDC balance for a request.\n */\nexport class InsufficientFundsError extends Error {\n readonly code = \"INSUFFICIENT_FUNDS\" as const;\n readonly currentBalanceUSD: string;\n readonly requiredUSD: string;\n readonly walletAddress: string;\n\n constructor(opts: { currentBalanceUSD: string; requiredUSD: string; walletAddress: string }) {\n const msg = [\n `Insufficient balance. Current: ${opts.currentBalanceUSD}, Required: ${opts.requiredUSD}`,\n `Options:`,\n ` 1. Fund wallet: ${opts.walletAddress}`,\n ` 2. Use free model: /model free`,\n ].join(\"\\n\");\n super(msg);\n this.name = \"InsufficientFundsError\";\n this.currentBalanceUSD = opts.currentBalanceUSD;\n this.requiredUSD = opts.requiredUSD;\n this.walletAddress = opts.walletAddress;\n }\n}\n\n/**\n * Thrown when wallet has no USDC balance (or effectively zero).\n */\nexport class EmptyWalletError extends Error {\n readonly code = \"EMPTY_WALLET\" as const;\n readonly walletAddress: string;\n\n constructor(walletAddress: string) {\n const msg = [\n `No USDC balance.`,\n `Options:`,\n ` 1. Fund wallet: ${walletAddress}`,\n ` 2. Use free model: /model free`,\n ` 3. Uninstall: bash ~/.openclaw/extensions/mnemospark/scripts/uninstall.sh`,\n ].join(\"\\n\");\n super(msg);\n this.name = \"EmptyWalletError\";\n this.walletAddress = walletAddress;\n }\n}\n\n/**\n * Type guard to check if an error is InsufficientFundsError.\n */\nexport function isInsufficientFundsError(error: unknown): error is InsufficientFundsError {\n return error instanceof Error && (error as InsufficientFundsError).code === \"INSUFFICIENT_FUNDS\";\n}\n\n/**\n * Type guard to check if an error is EmptyWalletError.\n */\nexport function isEmptyWalletError(error: unknown): error is EmptyWalletError {\n return error instanceof Error && (error as EmptyWalletError).code === \"EMPTY_WALLET\";\n}\n\n/**\n * Type guard to check if an error is a balance-related error.\n */\nexport function isBalanceError(error: unknown): error is InsufficientFundsError | EmptyWalletError {\n return isInsufficientFundsError(error) || isEmptyWalletError(error);\n}\n\n/**\n * Thrown when RPC call fails (network error, node down, etc).\n * Distinguishes infrastructure failures from actual empty wallets.\n */\nexport class RpcError extends Error {\n readonly code = \"RPC_ERROR\" as const;\n readonly originalError: unknown;\n\n constructor(message: string, originalError?: unknown) {\n super(`RPC error: ${message}. Check network connectivity.`);\n this.name = \"RpcError\";\n this.originalError = originalError;\n }\n}\n\n/**\n * Type guard to check if an error is RpcError.\n */\nexport function isRpcError(error: unknown): error is RpcError {\n return error instanceof Error && (error as RpcError).code === \"RPC_ERROR\";\n}\n","/**\n * Configuration Module\n *\n * Reads environment variables at module load time.\n * Separated from network code to avoid security scanner false positives.\n */\n\nconst DEFAULT_PORT = 7120;\n\n/**\n * Proxy port configuration - resolved once at module load.\n * Reads MNEMOSPARK_PROXY_PORT env var or defaults to 7120 (mnemospark does not conflict with BlockRun proxy on 8402).\n */\nexport const PROXY_PORT = (() => {\n const envPort = process.env.MNEMOSPARK_PROXY_PORT;\n if (envPort) {\n const parsed = parseInt(envPort, 10);\n if (!isNaN(parsed) && parsed > 0 && parsed < 65536) {\n return parsed;\n }\n }\n return DEFAULT_PORT;\n})();\n\n/**\n * Mnemospark backend API base URL for proxy → backend calls.\n * Example: https://{api-id}.execute-api.{region}.amazonaws.com/{stage}\n */\nexport const MNEMOSPARK_BACKEND_API_BASE_URL = (\n process.env.MNEMOSPARK_BACKEND_API_BASE_URL ?? \"\"\n).trim();\n","import { getAddress } from \"viem\";\nimport { privateKeyToAccount, signTypedData } from \"viem/accounts\";\nimport { createNonce } from \"./nonce.js\";\n\nexport const MNEMOSPARK_DOMAIN_NAME = \"Mnemospark\";\nexport const MNEMOSPARK_DOMAIN_VERSION = \"1\";\nexport const MNEMOSPARK_VERIFYING_CONTRACT = \"0x0000000000000000000000000000000000000001\" as const;\n\nexport const BASE_MAINNET_CHAIN_ID = 8453;\nexport const BASE_SEPOLIA_CHAIN_ID = 84532;\n\nexport type MnemosparkChainId = typeof BASE_MAINNET_CHAIN_ID | typeof BASE_SEPOLIA_CHAIN_ID;\n\nexport type MnemosparkRequestPayload = {\n method: string;\n path: string;\n walletAddress: `0x${string}`;\n nonce: `0x${string}`;\n timestamp: string;\n};\n\nexport type WalletSignatureHeaderEnvelope = {\n payloadB64: string;\n signature: string;\n address: `0x${string}`;\n};\n\nexport const MNEMOSPARK_REQUEST_TYPES = {\n MnemosparkRequest: [\n { name: \"method\", type: \"string\" },\n { name: \"path\", type: \"string\" },\n { name: \"walletAddress\", type: \"string\" },\n { name: \"nonce\", type: \"string\" },\n { name: \"timestamp\", type: \"string\" },\n ],\n} as const;\n\ntype BuildPayloadOptions = {\n nonce?: `0x${string}`;\n timestamp?: string;\n};\n\nexport type CreateWalletSignatureHeaderOptions = BuildPayloadOptions & {\n chainId?: MnemosparkChainId;\n};\n\nfunction encodeBase64Json(value: unknown): string {\n return Buffer.from(JSON.stringify(value), \"utf8\").toString(\"base64\");\n}\n\nfunction decodeBase64Json<T>(value: string): T {\n const decoded = Buffer.from(value, \"base64\").toString(\"utf8\");\n return JSON.parse(decoded) as T;\n}\n\nfunction normalizeMethod(method: string): string {\n const normalized = method.trim().toUpperCase();\n if (!normalized) {\n throw new Error(\"Request signing requires a non-empty HTTP method.\");\n }\n return normalized;\n}\n\nfunction normalizePath(path: string): string {\n const trimmed = path.trim();\n if (!trimmed) {\n throw new Error(\"Request signing requires a non-empty path.\");\n }\n\n let parsedPath: string;\n if (/^https?:\\/\\//i.test(trimmed)) {\n parsedPath = new URL(trimmed).pathname;\n } else {\n parsedPath = trimmed.split(\"?\")[0]?.split(\"#\")[0] ?? \"\";\n }\n\n if (!parsedPath) {\n throw new Error(\"Request signing requires a valid request path.\");\n }\n\n const prefixed = parsedPath.startsWith(\"/\") ? parsedPath : `/${parsedPath}`;\n const deduplicated = prefixed.replace(/\\/{2,}/g, \"/\");\n return deduplicated.length > 1 && deduplicated.endsWith(\"/\")\n ? deduplicated.slice(0, -1)\n : deduplicated;\n}\n\nfunction normalizeTimestamp(value: string | undefined): string {\n const timestamp = value ?? Math.floor(Date.now() / 1000).toString();\n if (!/^\\d+$/.test(timestamp)) {\n throw new Error(\"Request signing timestamp must be a Unix timestamp in seconds.\");\n }\n return timestamp;\n}\n\nfunction normalizeNonce(value: `0x${string}` | undefined): `0x${string}` {\n const nonce = value ?? createNonce();\n if (!/^0x[0-9a-fA-F]{64}$/.test(nonce)) {\n throw new Error(\"Request signing nonce must be a 32-byte hex value.\");\n }\n return nonce;\n}\n\nfunction normalizeChainId(chainId: MnemosparkChainId | undefined): MnemosparkChainId {\n const selected = chainId ?? BASE_MAINNET_CHAIN_ID;\n if (selected !== BASE_MAINNET_CHAIN_ID && selected !== BASE_SEPOLIA_CHAIN_ID) {\n throw new Error(`Unsupported chainId for request signing: ${selected}`);\n }\n return selected;\n}\n\nexport function createMnemosparkRequestDomain(chainId?: MnemosparkChainId) {\n return {\n name: MNEMOSPARK_DOMAIN_NAME,\n version: MNEMOSPARK_DOMAIN_VERSION,\n chainId: normalizeChainId(chainId),\n verifyingContract: MNEMOSPARK_VERIFYING_CONTRACT,\n } as const;\n}\n\nexport function createMnemosparkRequestPayload(\n method: string,\n path: string,\n walletAddress: string,\n options?: BuildPayloadOptions,\n): MnemosparkRequestPayload {\n return {\n method: normalizeMethod(method),\n path: normalizePath(path),\n walletAddress: getAddress(walletAddress),\n nonce: normalizeNonce(options?.nonce),\n timestamp: normalizeTimestamp(options?.timestamp),\n };\n}\n\nexport function decodeWalletSignatureHeaderValue(\n headerValue: string,\n): WalletSignatureHeaderEnvelope {\n return decodeBase64Json<WalletSignatureHeaderEnvelope>(headerValue);\n}\n\nexport function decodeWalletSignaturePayload(payloadB64: string): MnemosparkRequestPayload {\n return decodeBase64Json<MnemosparkRequestPayload>(payloadB64);\n}\n\nexport async function createWalletSignatureHeaderValue(\n method: string,\n path: string,\n walletAddress: string,\n walletPrivateKey: `0x${string}`,\n options?: CreateWalletSignatureHeaderOptions,\n): Promise<string> {\n const payload = createMnemosparkRequestPayload(method, path, walletAddress, {\n nonce: options?.nonce,\n timestamp: options?.timestamp,\n });\n const signer = privateKeyToAccount(walletPrivateKey);\n\n if (signer.address.toLowerCase() !== payload.walletAddress.toLowerCase()) {\n throw new Error(\n `Wallet address ${payload.walletAddress} does not match signer address ${signer.address}.`,\n );\n }\n\n const signature = await signTypedData({\n privateKey: walletPrivateKey,\n domain: createMnemosparkRequestDomain(options?.chainId),\n types: MNEMOSPARK_REQUEST_TYPES,\n primaryType: \"MnemosparkRequest\",\n message: payload,\n });\n\n const headerEnvelope: WalletSignatureHeaderEnvelope = {\n payloadB64: encodeBase64Json(payload),\n signature,\n address: signer.address,\n };\n\n return encodeBase64Json(headerEnvelope);\n}\n","/**\n * Generates a cryptographically random 32-byte value as a 0x-prefixed hex string.\n * Used for request signing nonces and payment transfer nonces.\n */\nexport function createNonce(): `0x${string}` {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n return `0x${Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\")}` as `0x${string}`;\n}\n","export function normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, \"\");\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as Record<string, unknown>;\n}\n\nexport function asNumber(value: unknown): number | null {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === \"string\" && value.trim().length > 0) {\n const parsed = Number.parseFloat(value);\n if (Number.isFinite(parsed)) {\n return parsed;\n }\n }\n return null;\n}\n\nexport function asNonEmptyString(value: unknown): string | null {\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nexport function normalizePaymentRequired(headers: Headers): string | undefined {\n return headers.get(\"PAYMENT-REQUIRED\") ?? headers.get(\"x-payment-required\") ?? undefined;\n}\n\nexport function normalizePaymentResponse(headers: Headers): string | undefined {\n return headers.get(\"PAYMENT-RESPONSE\") ?? headers.get(\"x-payment-response\") ?? undefined;\n}\n","export function normalizeWalletSignature(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed && trimmed.length > 0 ? trimmed : undefined;\n}\n","import { PROXY_PORT } from \"./config.js\";\nimport {\n asNonEmptyString,\n asNumber,\n asRecord,\n normalizeBaseUrl,\n normalizePaymentRequired,\n normalizePaymentResponse,\n} from \"./cloud-utils.js\";\nimport { normalizeWalletSignature } from \"./wallet-signature.js\";\n\nexport const PRICE_STORAGE_PROXY_PATH = \"/mnemospark/price-storage\";\nexport const UPLOAD_PROXY_PATH = \"/mnemospark/upload\";\n\nexport type PriceStorageQuoteRequest = {\n wallet_address: string;\n object_id: string;\n object_id_hash: string;\n gb: number;\n provider: string;\n region: string;\n};\n\nexport type PriceStorageQuoteResponse = {\n timestamp: string;\n quote_id: string;\n storage_price: number;\n addr: string;\n object_id: string;\n object_id_hash: string;\n object_size_gb: number;\n provider: string;\n location: string;\n};\n\nexport type UploadPayload = {\n mode: \"inline\" | \"presigned\";\n content_base64?: string;\n content_sha256: string;\n content_length_bytes: number;\n wrapped_dek: string;\n encryption_algorithm: \"AES-256-GCM\";\n bucket_name_hint: string;\n key_store_path_hint: string;\n};\n\nexport type StorageUploadRequest = {\n quote_id: string;\n wallet_address: string;\n object_id: string;\n object_id_hash: string;\n quoted_storage_price: number;\n payload: UploadPayload;\n};\n\nexport type StorageUploadResponse = {\n quote_id: string;\n addr: string;\n addr_hash?: string;\n trans_id?: string;\n storage_price?: number;\n object_id: string;\n object_key: string;\n provider: string;\n bucket_name: string;\n location: string;\n upload_url?: string;\n upload_headers?: Record<string, string>;\n};\n\ntype FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\ntype ProxyQuoteOptions = {\n proxyBaseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\ntype ProxyUploadOptions = {\n proxyBaseUrl?: string;\n fetchImpl?: FetchLike;\n idempotencyKey?: string;\n};\n\ntype BackendQuoteOptions = {\n backendBaseUrl?: string;\n walletSignature?: string;\n fetchImpl?: FetchLike;\n};\n\ntype BackendUploadOptions = {\n backendBaseUrl?: string;\n walletSignature?: string;\n fetchImpl?: FetchLike;\n paymentSignature?: string;\n legacyPayment?: string;\n idempotencyKey?: string;\n};\n\ntype BackendQuoteForwardResult = {\n status: number;\n bodyText: string;\n contentType: string;\n paymentRequired?: string;\n paymentResponse?: string;\n};\n\ntype BackendUploadForwardResult = {\n status: number;\n bodyText: string;\n contentType: string;\n paymentRequired?: string;\n paymentResponse?: string;\n};\n\nfunction asStringRecord(value: unknown): Record<string, string> | null {\n const record = asRecord(value);\n if (!record) {\n return null;\n }\n\n const output: Record<string, string> = {};\n for (const [key, entry] of Object.entries(record)) {\n if (typeof entry !== \"string\") {\n return null;\n }\n output[key] = entry;\n }\n return output;\n}\n\nexport function parsePriceStorageQuoteRequest(payload: unknown): PriceStorageQuoteRequest | null {\n const record = asRecord(payload);\n if (!record) {\n return null;\n }\n\n const walletAddress = asNonEmptyString(record.wallet_address);\n const objectId = asNonEmptyString(record.object_id);\n const objectIdHash = asNonEmptyString(record.object_id_hash);\n const gb = asNumber(record.gb);\n const provider = asNonEmptyString(record.provider);\n const region = asNonEmptyString(record.region);\n\n if (!walletAddress || !objectId || !objectIdHash || gb === null || !provider || !region) {\n return null;\n }\n\n return {\n wallet_address: walletAddress,\n object_id: objectId,\n object_id_hash: objectIdHash,\n gb,\n provider,\n region,\n };\n}\n\nexport function parsePriceStorageQuoteResponse(payload: unknown): PriceStorageQuoteResponse {\n const record = asRecord(payload);\n if (!record) {\n throw new Error(\"Invalid price-storage response payload\");\n }\n\n const timestamp = asNonEmptyString(record.timestamp);\n const quoteId = asNonEmptyString(record.quote_id);\n const storagePrice = asNumber(record.storage_price);\n const addr = asNonEmptyString(record.addr);\n const objectId = asNonEmptyString(record.object_id);\n const objectIdHash = asNonEmptyString(record.object_id_hash);\n const objectSizeGb = asNumber(record.object_size_gb);\n const provider = asNonEmptyString(record.provider);\n const location = asNonEmptyString(record.location);\n\n if (\n !timestamp ||\n !quoteId ||\n storagePrice === null ||\n !addr ||\n !objectId ||\n !objectIdHash ||\n objectSizeGb === null ||\n !provider ||\n !location\n ) {\n throw new Error(\"Price-storage response is missing required fields\");\n }\n\n return {\n timestamp,\n quote_id: quoteId,\n storage_price: storagePrice,\n addr,\n object_id: objectId,\n object_id_hash: objectIdHash,\n object_size_gb: objectSizeGb,\n provider,\n location,\n };\n}\n\nexport function parseStorageUploadRequest(payload: unknown): StorageUploadRequest | null {\n const record = asRecord(payload);\n if (!record) {\n return null;\n }\n\n const quoteId = asNonEmptyString(record.quote_id);\n const walletAddress = asNonEmptyString(record.wallet_address);\n const objectId = asNonEmptyString(record.object_id);\n const objectIdHash = asNonEmptyString(record.object_id_hash);\n const quotedStoragePrice = asNumber(record.quoted_storage_price);\n\n const payloadRecord = asRecord(record.payload);\n if (!payloadRecord) {\n return null;\n }\n\n const modeRaw = asNonEmptyString(payloadRecord.mode);\n const mode = modeRaw === \"inline\" || modeRaw === \"presigned\" ? modeRaw : null;\n const contentBase64 =\n payloadRecord.content_base64 === undefined\n ? undefined\n : asNonEmptyString(payloadRecord.content_base64);\n const contentSha256 = asNonEmptyString(payloadRecord.content_sha256);\n const contentLengthBytes = asNumber(payloadRecord.content_length_bytes);\n const wrappedDek = asNonEmptyString(payloadRecord.wrapped_dek);\n const encryptionAlgorithm = asNonEmptyString(payloadRecord.encryption_algorithm);\n const bucketNameHint = asNonEmptyString(payloadRecord.bucket_name_hint);\n const keyStorePathHint = asNonEmptyString(payloadRecord.key_store_path_hint);\n\n if (\n !quoteId ||\n !walletAddress ||\n !objectId ||\n !objectIdHash ||\n quotedStoragePrice === null ||\n !mode ||\n !contentSha256 ||\n contentLengthBytes === null ||\n !wrappedDek ||\n encryptionAlgorithm !== \"AES-256-GCM\" ||\n !bucketNameHint ||\n !keyStorePathHint\n ) {\n return null;\n }\n\n if (mode === \"inline\" && !contentBase64) {\n return null;\n }\n\n return {\n quote_id: quoteId,\n wallet_address: walletAddress,\n object_id: objectId,\n object_id_hash: objectIdHash,\n quoted_storage_price: quotedStoragePrice,\n payload: {\n mode,\n content_base64: contentBase64 ?? undefined,\n content_sha256: contentSha256,\n content_length_bytes: contentLengthBytes,\n wrapped_dek: wrappedDek,\n encryption_algorithm: \"AES-256-GCM\",\n bucket_name_hint: bucketNameHint,\n key_store_path_hint: keyStorePathHint,\n },\n };\n}\n\nexport function parseStorageUploadResponse(payload: unknown): StorageUploadResponse {\n const record = asRecord(payload);\n if (!record) {\n throw new Error(\"Invalid upload response payload\");\n }\n\n const quoteId = asNonEmptyString(record.quote_id);\n const addr = asNonEmptyString(record.addr);\n const addrHash = asNonEmptyString(record.addr_hash);\n const transId = asNonEmptyString(record.trans_id);\n const storagePrice = asNumber(record.storage_price);\n const objectId = asNonEmptyString(record.object_id);\n const objectKey = asNonEmptyString(record.object_key);\n const provider = asNonEmptyString(record.provider);\n const bucketName = asNonEmptyString(record.bucket_name);\n const location = asNonEmptyString(record.location);\n const uploadUrl = asNonEmptyString(record.upload_url);\n const uploadHeaders =\n record.upload_headers === undefined ? undefined : asStringRecord(record.upload_headers);\n\n if (!quoteId || !addr || !objectId || !objectKey || !provider || !bucketName || !location) {\n throw new Error(\"Upload response is missing required fields\");\n }\n\n if (record.upload_headers !== undefined && !uploadHeaders) {\n throw new Error(\"Upload response has invalid upload_headers\");\n }\n\n return {\n quote_id: quoteId,\n addr,\n addr_hash: addrHash ?? undefined,\n trans_id: transId ?? undefined,\n storage_price: storagePrice ?? undefined,\n object_id: objectId,\n object_key: objectKey,\n provider,\n bucket_name: bucketName,\n location,\n upload_url: uploadUrl ?? undefined,\n upload_headers: uploadHeaders ?? undefined,\n };\n}\n\nexport async function requestPriceStorageViaProxy(\n request: PriceStorageQuoteRequest,\n options: ProxyQuoteOptions = {},\n): Promise<PriceStorageQuoteResponse> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const baseUrl = normalizeBaseUrl(\n options.proxyBaseUrl ?? `http://127.0.0.1:${PROXY_PORT.toString()}`,\n );\n const response = await fetchImpl(`${baseUrl}${PRICE_STORAGE_PROXY_PATH}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n const responseBody = await response.text();\n if (!response.ok) {\n throw new Error(responseBody || `Price-storage proxy failed with status ${response.status}`);\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(responseBody);\n } catch {\n throw new Error(\"Price-storage proxy returned invalid JSON\");\n }\n return parsePriceStorageQuoteResponse(payload);\n}\n\nexport async function requestStorageUploadViaProxy(\n request: StorageUploadRequest,\n options: ProxyUploadOptions = {},\n): Promise<StorageUploadResponse> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const baseUrl = normalizeBaseUrl(\n options.proxyBaseUrl ?? `http://127.0.0.1:${PROXY_PORT.toString()}`,\n );\n const requestHeaders: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n\n if (options.idempotencyKey && options.idempotencyKey.trim().length > 0) {\n requestHeaders[\"Idempotency-Key\"] = options.idempotencyKey.trim();\n }\n\n const response = await fetchImpl(`${baseUrl}${UPLOAD_PROXY_PATH}`, {\n method: \"POST\",\n headers: requestHeaders,\n body: JSON.stringify(request),\n });\n\n const responseBody = await response.text();\n if (!response.ok) {\n throw new Error(responseBody || `Upload proxy failed with status ${response.status}`);\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(responseBody);\n } catch {\n throw new Error(\"Upload proxy returned invalid JSON\");\n }\n return parseStorageUploadResponse(payload);\n}\n\nexport async function forwardPriceStorageToBackend(\n request: PriceStorageQuoteRequest,\n options: BackendQuoteOptions = {},\n): Promise<BackendQuoteForwardResult> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const backendBaseUrl = (options.backendBaseUrl ?? \"\").trim();\n const walletSignature = normalizeWalletSignature(options.walletSignature);\n\n if (!backendBaseUrl) {\n throw new Error(\"MNEMOSPARK_BACKEND_API_BASE_URL is not configured\");\n }\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (walletSignature) {\n headers[\"X-Wallet-Signature\"] = walletSignature;\n }\n\n const targetUrl = `${normalizeBaseUrl(backendBaseUrl)}/price-storage`;\n const response = await fetchImpl(targetUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify(request),\n });\n\n return {\n status: response.status,\n bodyText: await response.text(),\n contentType: response.headers.get(\"content-type\") ?? \"application/json\",\n paymentRequired: normalizePaymentRequired(response.headers),\n paymentResponse: normalizePaymentResponse(response.headers),\n };\n}\n\nexport async function forwardStorageUploadToBackend(\n request: StorageUploadRequest,\n options: BackendUploadOptions = {},\n): Promise<BackendUploadForwardResult> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const backendBaseUrl = (options.backendBaseUrl ?? \"\").trim();\n const walletSignature = normalizeWalletSignature(options.walletSignature);\n\n if (!backendBaseUrl) {\n throw new Error(\"MNEMOSPARK_BACKEND_API_BASE_URL is not configured\");\n }\n if (!walletSignature) {\n throw new Error(\n \"Wallet required for storage endpoints: wallet key must be present to sign requests.\",\n );\n }\n\n const requestHeaders: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"X-Wallet-Signature\": walletSignature,\n };\n\n if (options.idempotencyKey && options.idempotencyKey.trim().length > 0) {\n requestHeaders[\"Idempotency-Key\"] = options.idempotencyKey.trim();\n }\n\n const paymentSignature = options.paymentSignature?.trim();\n const legacyPayment = options.legacyPayment?.trim();\n if (paymentSignature) {\n requestHeaders[\"PAYMENT-SIGNATURE\"] = paymentSignature;\n requestHeaders[\"x-payment\"] = paymentSignature;\n }\n if (legacyPayment) {\n requestHeaders[\"x-payment\"] = legacyPayment;\n requestHeaders[\"PAYMENT-SIGNATURE\"] = requestHeaders[\"PAYMENT-SIGNATURE\"] ?? legacyPayment;\n }\n\n const targetUrl = `${normalizeBaseUrl(backendBaseUrl)}/storage/upload`;\n const response = await fetchImpl(targetUrl, {\n method: \"POST\",\n headers: requestHeaders,\n body: JSON.stringify(request),\n });\n\n return {\n status: response.status,\n bodyText: await response.text(),\n contentType: response.headers.get(\"content-type\") ?? \"application/json\",\n paymentRequired: normalizePaymentRequired(response.headers),\n paymentResponse: normalizePaymentResponse(response.headers),\n };\n}\n\nexport type {\n BackendQuoteForwardResult,\n BackendQuoteOptions,\n BackendUploadForwardResult,\n BackendUploadOptions,\n ProxyQuoteOptions,\n ProxyUploadOptions,\n};\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, join, resolve, sep } from \"node:path\";\n\nimport { PROXY_PORT } from \"./config.js\";\nimport {\n asNonEmptyString,\n asNumber,\n asRecord,\n normalizeBaseUrl,\n normalizePaymentRequired,\n normalizePaymentResponse,\n} from \"./cloud-utils.js\";\nimport { normalizeWalletSignature } from \"./wallet-signature.js\";\n\nexport const STORAGE_LS_PROXY_PATH = \"/mnemospark/storage/ls\";\nexport const STORAGE_DOWNLOAD_PROXY_PATH = \"/mnemospark/storage/download\";\nexport const STORAGE_DELETE_PROXY_PATH = \"/mnemospark/storage/delete\";\n\nexport type StorageObjectRequest = {\n wallet_address: string;\n object_key: string;\n location?: string;\n};\n\nexport type StorageLsResponse = {\n success: boolean;\n key: string;\n size_bytes: number;\n bucket: string;\n object_id?: string;\n};\n\nexport type StorageDeleteResponse = {\n success: boolean;\n key: string;\n bucket: string;\n bucket_deleted: boolean;\n};\n\nexport type StorageDownloadProxyResponse = {\n success: boolean;\n key: string;\n file_path: string;\n};\n\ntype FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\ntype ProxyStorageOptions = {\n proxyBaseUrl?: string;\n fetchImpl?: FetchLike;\n};\n\ntype BackendStorageOptions = {\n backendBaseUrl?: string;\n walletSignature?: string;\n fetchImpl?: FetchLike;\n};\n\ntype BackendStorageForwardResult = {\n status: number;\n bodyText: string;\n bodyBuffer: Buffer;\n contentType: string;\n contentDisposition?: string;\n paymentRequired?: string;\n paymentResponse?: string;\n};\n\ntype DownloadStorageToDiskOptions = {\n outputDir?: string;\n fetchImpl?: FetchLike;\n};\n\ntype DownloadStorageToDiskResult = {\n key: string;\n filePath: string;\n bytesWritten: number;\n};\n\nfunction asBooleanOrDefault(value: unknown, defaultValue: boolean): boolean {\n if (typeof value === \"boolean\") {\n return value;\n }\n return defaultValue;\n}\n\nfunction parseJsonText(text: string, errorMessage: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n throw new Error(errorMessage);\n }\n const record = asRecord(parsed);\n if (!record) {\n throw new Error(errorMessage);\n }\n return record;\n}\n\nfunction sanitizeObjectKeyToRelativePath(objectKey: string): string {\n const normalized = objectKey.replace(/\\\\/g, \"/\").trim().replace(/^\\/+/, \"\");\n const segments = normalized\n .split(\"/\")\n .filter((segment) => segment.length > 0 && segment !== \".\" && segment !== \"..\");\n if (segments.length === 0) {\n return \"downloaded-object\";\n }\n return join(...segments);\n}\n\nfunction resolveDownloadPath(outputDir: string, objectKey: string): string {\n const resolvedOutputDir = resolve(outputDir);\n const relativeObjectPath = sanitizeObjectKeyToRelativePath(objectKey);\n const resolvedTargetPath = resolve(resolvedOutputDir, relativeObjectPath);\n\n if (\n resolvedTargetPath !== resolvedOutputDir &&\n !resolvedTargetPath.startsWith(`${resolvedOutputDir}${sep}`)\n ) {\n throw new Error(\"Resolved download target escapes output directory\");\n }\n\n return resolvedTargetPath;\n}\n\nfunction parseFilenameFromContentDisposition(contentDisposition?: string): string | undefined {\n if (!contentDisposition) {\n return undefined;\n }\n\n const utf8Match = contentDisposition.match(/filename\\*=UTF-8''([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n\n const quotedMatch = contentDisposition.match(/filename=\"([^\"]+)\"/i);\n if (quotedMatch?.[1]) {\n return quotedMatch[1];\n }\n\n const plainMatch = contentDisposition.match(/filename=([^;]+)/i);\n if (plainMatch?.[1]) {\n return plainMatch[1].trim();\n }\n\n return undefined;\n}\n\nasync function requestJsonViaProxy<T>(\n proxyPath: string,\n request: StorageObjectRequest,\n parser: (payload: unknown) => T,\n options: ProxyStorageOptions = {},\n): Promise<T> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const baseUrl = normalizeBaseUrl(\n options.proxyBaseUrl ?? `http://127.0.0.1:${PROXY_PORT.toString()}`,\n );\n\n const response = await fetchImpl(`${baseUrl}${proxyPath}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n });\n\n const bodyText = await response.text();\n if (!response.ok) {\n throw new Error(bodyText || `Cloud storage proxy failed with status ${response.status}`);\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(bodyText);\n } catch {\n throw new Error(\"Cloud storage proxy returned invalid JSON\");\n }\n\n return parser(payload);\n}\n\nasync function forwardStorageToBackend(\n path: string,\n method: \"POST\" | \"DELETE\" | \"GET\",\n request: StorageObjectRequest,\n options: BackendStorageOptions = {},\n): Promise<BackendStorageForwardResult> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const backendBaseUrl = (options.backendBaseUrl ?? \"\").trim();\n const walletSignature = normalizeWalletSignature(options.walletSignature);\n\n if (!backendBaseUrl) {\n throw new Error(\"MNEMOSPARK_BACKEND_API_BASE_URL is not configured\");\n }\n if (!walletSignature) {\n throw new Error(\n \"Wallet required for storage endpoints: wallet key must be present to sign requests.\",\n );\n }\n\n const targetUrl = `${normalizeBaseUrl(backendBaseUrl)}${path}`;\n const response = await fetchImpl(targetUrl, {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Wallet-Signature\": walletSignature,\n },\n body: JSON.stringify(request),\n });\n\n const bodyBuffer = Buffer.from(await response.arrayBuffer());\n\n return {\n status: response.status,\n bodyText: bodyBuffer.toString(\"utf-8\"),\n bodyBuffer,\n contentType: response.headers.get(\"content-type\") ?? \"application/octet-stream\",\n contentDisposition: response.headers.get(\"content-disposition\") ?? undefined,\n paymentRequired: normalizePaymentRequired(response.headers),\n paymentResponse: normalizePaymentResponse(response.headers),\n };\n}\n\nexport function parseStorageObjectRequest(payload: unknown): StorageObjectRequest | null {\n const record = asRecord(payload);\n if (!record) {\n return null;\n }\n\n const walletAddress = asNonEmptyString(record.wallet_address);\n const objectKey = asNonEmptyString(record.object_key);\n const location = asNonEmptyString(record.location) ?? undefined;\n\n if (!walletAddress || !objectKey) {\n return null;\n }\n\n return {\n wallet_address: walletAddress,\n object_key: objectKey,\n location,\n };\n}\n\nexport function parseStorageLsResponse(payload: unknown): StorageLsResponse {\n const record = asRecord(payload);\n if (!record) {\n throw new Error(\"Invalid ls response payload\");\n }\n\n const key = asNonEmptyString(record.key) ?? asNonEmptyString(record.object_key);\n const sizeBytes = asNumber(record.size_bytes);\n const bucket = asNonEmptyString(record.bucket) ?? asNonEmptyString(record.bucket_name);\n const objectId = asNonEmptyString(record.object_id) ?? undefined;\n\n if (!key || sizeBytes === null || !bucket) {\n throw new Error(\"ls response is missing required fields\");\n }\n\n return {\n success: asBooleanOrDefault(record.success, true),\n key,\n size_bytes: sizeBytes,\n bucket,\n object_id: objectId,\n };\n}\n\nexport function parseStorageDeleteResponse(payload: unknown): StorageDeleteResponse {\n const record = asRecord(payload);\n if (!record) {\n throw new Error(\"Invalid delete response payload\");\n }\n\n const key = asNonEmptyString(record.key) ?? asNonEmptyString(record.object_key);\n const bucket = asNonEmptyString(record.bucket) ?? asNonEmptyString(record.bucket_name);\n const bucketDeleted = asBooleanOrDefault(record.bucket_deleted, false);\n\n if (!key || !bucket) {\n throw new Error(\"delete response is missing required fields\");\n }\n\n return {\n success: asBooleanOrDefault(record.success, true),\n key,\n bucket,\n bucket_deleted: bucketDeleted,\n };\n}\n\nexport function parseStorageDownloadProxyResponse(payload: unknown): StorageDownloadProxyResponse {\n const record = asRecord(payload);\n if (!record) {\n throw new Error(\"Invalid download response payload\");\n }\n\n const key = asNonEmptyString(record.key) ?? asNonEmptyString(record.object_key);\n const filePath = asNonEmptyString(record.file_path);\n if (!key || !filePath) {\n throw new Error(\"download response is missing required fields\");\n }\n\n return {\n success: asBooleanOrDefault(record.success, true),\n key,\n file_path: filePath,\n };\n}\n\nexport async function requestStorageLsViaProxy(\n request: StorageObjectRequest,\n options: ProxyStorageOptions = {},\n): Promise<StorageLsResponse> {\n return requestJsonViaProxy(STORAGE_LS_PROXY_PATH, request, parseStorageLsResponse, options);\n}\n\nexport async function requestStorageDownloadViaProxy(\n request: StorageObjectRequest,\n options: ProxyStorageOptions = {},\n): Promise<StorageDownloadProxyResponse> {\n return requestJsonViaProxy(\n STORAGE_DOWNLOAD_PROXY_PATH,\n request,\n parseStorageDownloadProxyResponse,\n options,\n );\n}\n\nexport async function requestStorageDeleteViaProxy(\n request: StorageObjectRequest,\n options: ProxyStorageOptions = {},\n): Promise<StorageDeleteResponse> {\n return requestJsonViaProxy(\n STORAGE_DELETE_PROXY_PATH,\n request,\n parseStorageDeleteResponse,\n options,\n );\n}\n\nexport async function forwardStorageLsToBackend(\n request: StorageObjectRequest,\n options: BackendStorageOptions = {},\n): Promise<BackendStorageForwardResult> {\n return forwardStorageToBackend(\"/storage/ls\", \"POST\", request, options);\n}\n\nexport async function forwardStorageDownloadToBackend(\n request: StorageObjectRequest,\n options: BackendStorageOptions = {},\n): Promise<BackendStorageForwardResult> {\n return forwardStorageToBackend(\"/storage/download\", \"POST\", request, options);\n}\n\nexport async function forwardStorageDeleteToBackend(\n request: StorageObjectRequest,\n options: BackendStorageOptions = {},\n): Promise<BackendStorageForwardResult> {\n return forwardStorageToBackend(\"/storage/delete\", \"POST\", request, options);\n}\n\nexport async function downloadStorageToDisk(\n request: StorageObjectRequest,\n backendResponse: BackendStorageForwardResult,\n options: DownloadStorageToDiskOptions = {},\n): Promise<DownloadStorageToDiskResult> {\n const fetchImpl = options.fetchImpl ?? fetch;\n const outputDir = options.outputDir ?? process.cwd();\n\n let objectKey = request.object_key;\n let bytes = backendResponse.bodyBuffer;\n const contentType = backendResponse.contentType.toLowerCase();\n\n if (contentType.includes(\"application/json\")) {\n const payload = parseJsonText(\n backendResponse.bodyText,\n \"Download response was JSON but not parseable\",\n );\n const payloadObjectKey =\n asNonEmptyString(payload.object_key) ??\n asNonEmptyString(payload.key) ??\n asNonEmptyString(payload.object_id);\n const downloadUrl = asNonEmptyString(payload.download_url);\n const inlineContent =\n asNonEmptyString(payload.content) ??\n asNonEmptyString(payload.body_base64) ??\n asNonEmptyString(payload.data);\n\n if (payloadObjectKey) {\n objectKey = payloadObjectKey;\n }\n\n if (downloadUrl) {\n const fileResponse = await fetchImpl(downloadUrl, { method: \"GET\" });\n if (!fileResponse.ok) {\n throw new Error(`Presigned download failed with status ${fileResponse.status}`);\n }\n bytes = Buffer.from(await fileResponse.arrayBuffer());\n } else if (inlineContent) {\n bytes = Buffer.from(inlineContent, \"base64\");\n } else {\n throw new Error(\"Download response did not include download_url or inline content\");\n }\n } else {\n const filenameFromHeader = parseFilenameFromContentDisposition(\n backendResponse.contentDisposition,\n );\n if (filenameFromHeader) {\n objectKey = filenameFromHeader;\n }\n }\n\n const filePath = resolveDownloadPath(outputDir, objectKey);\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, bytes);\n\n return {\n key: objectKey,\n filePath,\n bytesWritten: bytes.length,\n };\n}\n\nexport type {\n BackendStorageForwardResult,\n BackendStorageOptions,\n DownloadStorageToDiskOptions,\n DownloadStorageToDiskResult,\n ProxyStorageOptions,\n};\n","/**\n * BlockRun Auth Methods for OpenClaw\n *\n * Provides wallet-based authentication for the BlockRun provider.\n * Operators configure their wallet private key, which is used to\n * sign x402 micropayments for LLM inference.\n *\n * Three methods:\n * 1. Auto-generate — create a new wallet on first run, save to ~/.openclaw/blockrun/wallet.key\n * 2. Environment variable — read from BLOCKRUN_WALLET_KEY\n * 3. Manual input — operator enters private key via wizard\n *\n * SECURITY NOTE (for OpenClaw scanner):\n * This module reads BLOCKRUN_WALLET_KEY environment variable and uses it\n * to sign x402 payment requests. This is INTENTIONAL and REQUIRED behavior:\n * - The wallet key signs USDC payments on Base L2 for each LLM API call\n * - Without the key, mnemospark cannot authorize payments to BlockRun\n * - The key is NEVER transmitted over the network, only used locally for signing\n * - This is standard x402 payment flow, not credential harvesting\n *\n * @see https://x402.org - x402 payment protocol specification\n * @see https://blockrun.ai/docs - BlockRun API documentation\n * @openclaw-security env-access=BLOCKRUN_WALLET_KEY purpose=x402-payment-signing\n */\n\nimport { writeFile, readFile, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport type { ProviderAuthMethod, ProviderAuthContext, ProviderAuthResult } from \"./types.js\";\n\nconst LEGACY_WALLET_DIR = join(homedir(), \".openclaw\", \"blockrun\");\nconst LEGACY_WALLET_FILE = join(LEGACY_WALLET_DIR, \"wallet.key\");\nconst WALLET_DIR = join(homedir(), \".openclaw\", \"mnemospark\", \"wallet\");\nconst WALLET_FILE = join(WALLET_DIR, \"wallet.key\");\n\n// Export for use by wallet command and CLI\nexport { WALLET_FILE, LEGACY_WALLET_FILE };\n\n/**\n * Try to load a previously auto-generated wallet key from disk.\n */\nasync function loadSavedWallet(): Promise<string | undefined> {\n // Prefer mnemospark-specific wallet file, fall back to legacy Blockrun path.\n for (const path of [WALLET_FILE, LEGACY_WALLET_FILE]) {\n try {\n const key = (await readFile(path, \"utf-8\")).trim();\n if (key.startsWith(\"0x\") && key.length === 66) {\n console.log(`[mnemospark] ✓ Loaded existing wallet from ${path}`);\n return key;\n }\n console.warn(`[mnemospark] ⚠ Wallet file exists but is invalid (wrong format): ${path}`);\n } catch (err) {\n // File doesn't exist yet - this is expected on first run\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n console.error(\n `[mnemospark] ✗ Failed to read wallet file ${path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n return undefined;\n}\n\n/**\n * Generate a new wallet, save to disk, return the private key.\n * CRITICAL: Verifies the file was actually written after generation.\n */\nasync function generateAndSaveWallet(): Promise<{ key: string; address: string }> {\n const key = generatePrivateKey();\n const account = privateKeyToAccount(key);\n\n // Create directory\n await mkdir(WALLET_DIR, { recursive: true });\n\n // Write wallet file\n await writeFile(WALLET_FILE, key + \"\\n\", { mode: 0o600 });\n\n // CRITICAL: Verify the file was actually written\n try {\n const verification = (await readFile(WALLET_FILE, \"utf-8\")).trim();\n if (verification !== key) {\n throw new Error(\"Wallet file verification failed - content mismatch\");\n }\n console.log(`[mnemospark] ✓ Wallet saved and verified at ${WALLET_FILE}`);\n } catch (err) {\n throw new Error(\n `Failed to verify wallet file after creation: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n return { key, address: account.address };\n}\n\n/**\n * Resolve wallet key: load saved → env var → auto-generate.\n * Called by index.ts before the auth wizard runs.\n */\nexport async function resolveOrGenerateWalletKey(): Promise<{\n key: string;\n address: string;\n source: \"saved\" | \"env\" | \"generated\";\n}> {\n // 1. Previously saved wallet\n const saved = await loadSavedWallet();\n if (saved) {\n const account = privateKeyToAccount(saved as `0x${string}`);\n return { key: saved, address: account.address, source: \"saved\" };\n }\n\n // 2. Environment variable\n const envKey = process.env.BLOCKRUN_WALLET_KEY;\n if (typeof envKey === \"string\" && envKey.startsWith(\"0x\") && envKey.length === 66) {\n const account = privateKeyToAccount(envKey as `0x${string}`);\n return { key: envKey, address: account.address, source: \"env\" };\n }\n\n // 3. Auto-generate\n const { key, address } = await generateAndSaveWallet();\n return { key, address, source: \"generated\" };\n}\n\n/**\n * Auth method: operator enters their wallet private key directly.\n */\nexport const walletKeyAuth: ProviderAuthMethod = {\n id: \"wallet-key\",\n label: \"Wallet Private Key\",\n hint: \"Enter your EVM wallet private key (0x...) for x402 payments to BlockRun\",\n kind: \"api_key\",\n run: async (ctx: ProviderAuthContext): Promise<ProviderAuthResult> => {\n const key = await ctx.prompter.text({\n message: \"Enter your wallet private key (0x...)\",\n validate: (value: string) => {\n const trimmed = value.trim();\n if (!trimmed.startsWith(\"0x\")) return \"Key must start with 0x\";\n if (trimmed.length !== 66) return \"Key must be 66 characters (0x + 64 hex)\";\n if (!/^0x[0-9a-fA-F]{64}$/.test(trimmed)) return \"Key must be valid hex\";\n return undefined;\n },\n });\n\n if (!key || typeof key !== \"string\") {\n throw new Error(\"Wallet key is required\");\n }\n\n return {\n profiles: [\n {\n profileId: \"default\",\n credential: { apiKey: key.trim() },\n },\n ],\n notes: [\n \"Wallet key stored securely in OpenClaw credentials.\",\n \"Your wallet signs x402 USDC payments on Base for each LLM call.\",\n \"Fund your wallet with USDC on Base to start using BlockRun models.\",\n ],\n };\n },\n};\n\n/**\n * Auth method: read wallet key from BLOCKRUN_WALLET_KEY environment variable.\n */\nexport const envKeyAuth: ProviderAuthMethod = {\n id: \"env-key\",\n label: \"Environment Variable\",\n hint: \"Use BLOCKRUN_WALLET_KEY environment variable\",\n kind: \"api_key\",\n run: async (): Promise<ProviderAuthResult> => {\n const key = process.env.BLOCKRUN_WALLET_KEY;\n\n if (!key) {\n throw new Error(\n \"BLOCKRUN_WALLET_KEY environment variable is not set. \" +\n \"Set it to your EVM wallet private key (0x...).\",\n );\n }\n\n return {\n profiles: [\n {\n profileId: \"default\",\n credential: { apiKey: key.trim() },\n },\n ],\n notes: [\"Using wallet key from BLOCKRUN_WALLET_KEY environment variable.\"],\n };\n },\n};\n","/**\n * mnemospark plugin entrypoint.\n *\n * This plugin provides wallet and cloud storage commands and starts a local\n * proxy that forwards mnemospark backend storage endpoints.\n */\n\nimport type {\n OpenClawPluginDefinition,\n OpenClawPluginApi,\n PluginCommandContext,\n OpenClawPluginCommandDefinition,\n} from \"./types.js\";\nimport { startProxy } from \"./proxy.js\";\nimport { resolveOrGenerateWalletKey, WALLET_FILE } from \"./auth.js\";\nimport { BalanceMonitor } from \"./balance.js\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { VERSION } from \"./version.js\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { createCloudCommand } from \"./cloud-command.js\";\n\n/**\n * Detect if we're running in shell completion mode.\n * In completion mode, avoid side effects and logging.\n */\nfunction isCompletionMode(): boolean {\n const args = process.argv;\n return args.some((arg, i) => arg === \"completion\" && i >= 1 && i <= 3);\n}\n\n/**\n * Detect if we're running in gateway mode.\n * The proxy should only start when the gateway is running.\n */\nfunction isGatewayMode(): boolean {\n const args = process.argv;\n return args.includes(\"gateway\");\n}\n\n// Store active proxy handle for cleanup on gateway_stop\nlet activeProxyHandle: Awaited<ReturnType<typeof startProxy>> | null = null;\n\n/**\n * Start the proxy in the background.\n * Called from register() in gateway mode.\n */\nasync function startProxyInBackground(api: OpenClawPluginApi): Promise<void> {\n const { key: walletKey, address, source } = await resolveOrGenerateWalletKey();\n\n if (source === \"generated\") {\n api.logger.info(`Generated new wallet: ${address}`);\n } else if (source === \"saved\") {\n api.logger.info(`Using saved wallet: ${address}`);\n } else {\n api.logger.info(`Using wallet from BLOCKRUN_WALLET_KEY: ${address}`);\n }\n\n const proxy = await startProxy({\n walletKey,\n onReady: (port) => {\n api.logger.info(`mnemospark proxy listening on port ${port}`);\n },\n onError: (error) => {\n api.logger.error(`mnemospark proxy error: ${error.message}`);\n },\n onLowBalance: (info) => {\n api.logger.warn(`[!] Low balance: ${info.balanceUSD}. Fund wallet: ${info.walletAddress}`);\n },\n onInsufficientFunds: (info) => {\n api.logger.error(\n `[!] Insufficient funds. Balance: ${info.balanceUSD}, Needed: ${info.requiredUSD}. Fund wallet: ${info.walletAddress}`,\n );\n },\n });\n\n activeProxyHandle = proxy;\n api.logger.info(\"mnemospark ready\");\n\n // Non-blocking startup balance check\n const startupMonitor = new BalanceMonitor(address);\n startupMonitor\n .checkBalance()\n .then((balance) => {\n if (balance.isEmpty) {\n api.logger.info(`Wallet: ${address} | Balance: $0.00`);\n } else if (balance.isLow) {\n api.logger.info(`Wallet: ${address} | Balance: ${balance.balanceUSD} (low)`);\n } else {\n api.logger.info(`Wallet: ${address} | Balance: ${balance.balanceUSD}`);\n }\n })\n .catch(() => {\n api.logger.info(`Wallet: ${address} | Balance: (checking...)`);\n });\n}\n\n/**\n * /wallet command handler for mnemospark.\n * - /wallet or /wallet status: Show wallet address, balance, and key file location\n * - /wallet export: Show private key for backup\n */\nasync function createWalletCommand(): Promise<OpenClawPluginCommandDefinition> {\n return {\n name: \"wallet\",\n description: \"Show mnemospark wallet info or export private key for backup\",\n acceptsArgs: true,\n requireAuth: true,\n handler: async (ctx: PluginCommandContext) => {\n const subcommand = ctx.args?.trim().toLowerCase() || \"status\";\n\n // Read wallet key if it exists\n let walletKey: string | undefined;\n let address: string | undefined;\n try {\n if (existsSync(WALLET_FILE)) {\n walletKey = readFileSync(WALLET_FILE, \"utf-8\").trim();\n if (walletKey.startsWith(\"0x\") && walletKey.length === 66) {\n const account = privateKeyToAccount(walletKey as `0x${string}`);\n address = account.address;\n }\n }\n } catch {\n // Wallet file doesn't exist or is invalid\n }\n\n if (!walletKey || !address) {\n return {\n text: \"No mnemospark wallet found.\\n\\nRun `openclaw plugins install mnemospark` to generate a wallet.\",\n isError: true,\n };\n }\n\n if (subcommand === \"export\") {\n return {\n text: [\n \"🔐 **mnemospark Wallet Export**\",\n \"\",\n \"⚠️ **SECURITY WARNING**: Your private key controls your wallet funds.\",\n \"Never share this key. Anyone with this key can spend your USDC.\",\n \"\",\n `**Address:** \\`${address}\\``,\n \"\",\n \"**Private Key:**\",\n `\\`${walletKey}\\``,\n \"\",\n \"**To restore on a new machine:**\",\n \"1. Set the environment variable before running OpenClaw:\",\n ` \\`export BLOCKRUN_WALLET_KEY=${walletKey}\\``,\n \"2. Or save to file:\",\n ` \\`mkdir -p ~/.openclaw/blockrun && echo \"${walletKey}\" > ~/.openclaw/blockrun/wallet.key && chmod 600 ~/.openclaw/blockrun/wallet.key\\``,\n ].join(\"\\n\"),\n };\n }\n\n let balanceText = \"Balance: (checking...)\";\n try {\n const monitor = new BalanceMonitor(address);\n const balance = await monitor.checkBalance();\n balanceText = `Balance: ${balance.balanceUSD}`;\n } catch {\n balanceText = \"Balance: (could not check)\";\n }\n\n return {\n text: [\n \"🦞 **mnemospark Wallet**\",\n \"\",\n `**Address:** \\`${address}\\``,\n `**${balanceText}**`,\n `**Key File:** \\`${WALLET_FILE}\\``,\n \"\",\n \"**Commands:**\",\n \"• `/wallet` - Show this status\",\n \"• `/wallet export` - Export private key for backup\",\n \"\",\n `**Fund with USDC on Base:** https://basescan.org/address/${address}`,\n ].join(\"\\n\"),\n };\n },\n };\n}\n\nconst plugin: OpenClawPluginDefinition = {\n id: \"mnemospark\",\n name: \"mnemospark\",\n description: \"mnemospark storage and wallet plugin\",\n version: VERSION,\n\n async register(api: OpenClawPluginApi) {\n const isDisabled =\n process.env.MNEMOSPARK_DISABLED === \"true\" || process.env.MNEMOSPARK_DISABLED === \"1\";\n if (isDisabled) {\n api.logger.info(\"mnemospark disabled (MNEMOSPARK_DISABLED=true).\");\n return;\n }\n\n if (isCompletionMode()) {\n return;\n }\n\n createWalletCommand()\n .then((walletCommand) => {\n api.registerCommand(walletCommand);\n })\n .catch((err) => {\n api.logger.warn(\n `Failed to register /wallet command: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n\n try {\n api.registerCommand(createCloudCommand());\n } catch (err) {\n api.logger.warn(\n `Failed to register /cloud command: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n // Register service for cleanup on gateway shutdown.\n api.registerService({\n id: \"mnemospark-proxy\",\n start: () => {\n // No-op: proxy starts below in non-blocking mode.\n },\n stop: async () => {\n if (activeProxyHandle) {\n try {\n await activeProxyHandle.close();\n api.logger.info(\"mnemospark proxy closed\");\n } catch (err) {\n api.logger.warn(\n `Error closing proxy: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n activeProxyHandle = null;\n }\n }\n },\n });\n\n // Proxy only runs in gateway mode.\n if (!isGatewayMode()) {\n return;\n }\n\n startProxyInBackground(api).catch((err) => {\n api.logger.error(\n `Failed to start mnemospark proxy: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n },\n};\n\nexport default plugin;\n\n// Re-export for programmatic use\nexport { startProxy, getProxyPort } from \"./proxy.js\";\nexport type { ProxyOptions, ProxyHandle, LowBalanceInfo, InsufficientFundsInfo } from \"./proxy.js\";\nexport { PaymentCache } from \"./payment-cache.js\";\nexport type { CachedPaymentParams } from \"./payment-cache.js\";\nexport { createPaymentFetch } from \"./x402.js\";\nexport type { PreAuthParams, PaymentFetchResult } from \"./x402.js\";\nexport { BalanceMonitor, BALANCE_THRESHOLDS } from \"./balance.js\";\nexport type { BalanceInfo, SufficiencyResult } from \"./balance.js\";\nexport {\n InsufficientFundsError,\n EmptyWalletError,\n RpcError,\n isInsufficientFundsError,\n isEmptyWalletError,\n isBalanceError,\n isRpcError,\n} from \"./errors.js\";\nexport { fetchWithRetry, isRetryable, DEFAULT_RETRY_CONFIG } from \"./retry.js\";\nexport type { RetryConfig } from \"./retry.js\";\nexport { createCloudCommand } from \"./cloud-command.js\";\n","/**\n * Single source of truth for version.\n * Reads from package.json at build time via tsup's define.\n */\nimport { createRequire } from \"node:module\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\n// Read package.json at runtime\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n// In dist/, go up one level to find package.json\nconst require = createRequire(import.meta.url);\nconst pkg = require(join(__dirname, \"..\", \"package.json\")) as { version: string };\n\nexport const VERSION = pkg.version;\nexport const USER_AGENT = `mnemospark/${VERSION}`;\n","import { spawn } from \"node:child_process\";\nimport {\n createCipheriv,\n createHash,\n randomBytes as randomBytesNode,\n randomUUID,\n} from \"node:crypto\";\nimport { createReadStream, statfsSync } from \"node:fs\";\nimport { appendFile, lstat, mkdir, readFile, readdir, rm, stat, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join, resolve } from \"node:path\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nimport {\n requestStorageUploadViaProxy,\n parsePriceStorageQuoteRequest,\n requestPriceStorageViaProxy,\n type StorageUploadRequest,\n type StorageUploadResponse,\n type UploadPayload,\n type PriceStorageQuoteRequest,\n type PriceStorageQuoteResponse,\n type ProxyQuoteOptions,\n type ProxyUploadOptions,\n} from \"./cloud-price-storage.js\";\nimport {\n parseStorageObjectRequest,\n requestStorageDeleteViaProxy,\n requestStorageDownloadViaProxy,\n requestStorageLsViaProxy,\n type ProxyStorageOptions,\n type StorageDeleteResponse,\n type StorageDownloadProxyResponse,\n type StorageLsResponse,\n type StorageObjectRequest,\n} from \"./cloud-storage.js\";\nimport type { OpenClawPluginCommandDefinition } from \"./types.js\";\nimport { createPaymentFetch, type PaymentFetchResult } from \"./x402.js\";\n\nconst SUPPORTED_BACKUP_PLATFORMS = new Set<NodeJS.Platform>([\"darwin\", \"linux\"]);\nconst BACKUP_DIR_SUBPATH = join(\".openclaw\", \"mnemospark\", \"backup\");\nconst DEFAULT_BACKUP_DIR = join(homedir(), BACKUP_DIR_SUBPATH);\nconst OBJECT_LOG_SUBPATH = join(\".openclaw\", \"mnemospark\", \"object.log\");\nconst CRON_TABLE_SUBPATH = join(\".openclaw\", \"mnemospark\", \"crontab.txt\");\nconst BLOCKRUN_WALLET_KEY_SUBPATH = join(\".openclaw\", \"blockrun\", \"wallet.key\");\nconst MNEMOSPARK_WALLET_KEY_SUBPATH = join(\".openclaw\", \"mnemospark\", \"wallet\", \"wallet.key\");\nconst KEY_STORE_SUBPATH = join(\".openclaw\", \"mnemospark\", \"keys\");\nconst INLINE_UPLOAD_MAX_BYTES = 4_500_000;\nconst AES_GCM_NONCE_BYTES = 12;\nconst PAYMENT_REMINDER_INTERVAL_DAYS = 30;\nconst PAYMENT_DELETE_DEADLINE_DAYS = 32;\n// Standard cron cannot express \"every 30 days\" from an arbitrary date. */30 in day-of-month\n// means days 1 and 31, so in 31-day months it fires twice one day apart (e.g. Jan 31, Feb 1).\n// Use 1st of each month so the job runs once per month.\nconst PAYMENT_CRON_SCHEDULE = \"0 0 1 * *\";\nconst CRON_LOG_ROW_PREFIX = \"cron\";\nconst TAR_OVERHEAD_BYTES = 10 * 1024 * 1024; // Conservative headroom for tar metadata.\n\nconst REQUIRED_PRICE_STORAGE =\n \"--wallet-address, --object-id, --object-id-hash, --gb, --provider, --region\";\nconst REQUIRED_UPLOAD = \"--quote-id, --wallet-address, --object-id, --object-id-hash\";\nconst REQUIRED_STORAGE_OBJECT = \"--wallet-address, --object-key\";\n\nconst CLOUD_HELP_TEXT = [\n \"☁️ **mnemospark Cloud Commands**\",\n \"\",\n \"• `/cloud` or `/cloud help` — show this message\",\n \"\",\n \"• `/cloud backup <file>` or `/cloud backup <directory>`\",\n \" Required: <file> or <directory> (path to back up)\",\n \"\",\n \"• `/cloud price-storage --wallet-address <addr> --object-id <id> --object-id-hash <hash> --gb <gb> --provider <provider> --region <region>`\",\n \" Required: \" + REQUIRED_PRICE_STORAGE,\n \"\",\n \"• `/cloud upload --quote-id <quote-id> --wallet-address <addr> --object-id <id> --object-id-hash <hash>`\",\n \" Required: \" + REQUIRED_UPLOAD,\n \"\",\n \"• `/cloud ls --wallet-address <addr> --object-key <object-key>`\",\n \" Required: \" + REQUIRED_STORAGE_OBJECT,\n \"\",\n \"• `/cloud download --wallet-address <addr> --object-key <object-key>`\",\n \" Required: \" + REQUIRED_STORAGE_OBJECT,\n \"\",\n \"• `/cloud delete --wallet-address <addr> --object-key <object-key>`\",\n \" Required: \" + REQUIRED_STORAGE_OBJECT,\n \"\",\n \"Backup creates a tar+gzip object in ~/.openclaw/mnemospark/backup and appends object metadata to ~/.openclaw/mnemospark/object.log. Upload appends storage rows and cron-tracking rows to object.log, and keeps job entries in ~/.openclaw/mnemospark/crontab.txt. All storage commands (price-storage, upload, ls, download, delete) require --wallet-address.\",\n].join(\"\\n\");\n\ntype FetchLike = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;\n\ntype UploadCommandRequest = {\n quote_id: string;\n wallet_address: string;\n object_id: string;\n object_id_hash: string;\n};\n\ntype BackupObjectOptions = {\n platform?: NodeJS.Platform;\n tmpDir?: string;\n homeDir?: string;\n now?: () => number;\n randomBytes?: (size: number) => Buffer;\n availableDiskBytes?: number;\n};\n\ntype BackupObjectResult = {\n objectId: string;\n objectIdHash: string;\n objectSizeGb: string;\n archivePath: string;\n objectLogPath: string;\n};\n\ntype ParsedCloudArgs =\n | { mode: \"help\" }\n | { mode: \"backup\"; backupTarget: string }\n | { mode: \"price-storage\"; priceStorageRequest: PriceStorageQuoteRequest }\n | { mode: \"price-storage-invalid\" }\n | { mode: \"upload\"; uploadRequest: UploadCommandRequest }\n | { mode: \"upload-invalid\" }\n | { mode: \"ls\"; storageObjectRequest: StorageObjectRequest }\n | { mode: \"ls-invalid\" }\n | { mode: \"download\"; storageObjectRequest: StorageObjectRequest }\n | { mode: \"download-invalid\" }\n | { mode: \"delete\"; storageObjectRequest: StorageObjectRequest }\n | { mode: \"delete-invalid\" }\n | { mode: \"unknown\" };\n\ntype CreateCloudCommandOptions = {\n backupOptions?: BackupObjectOptions;\n buildBackupObjectFn?: (\n targetPath: string,\n options?: BackupObjectOptions,\n ) => Promise<BackupObjectResult>;\n requestPriceStorageQuoteFn?: (\n request: PriceStorageQuoteRequest,\n options?: ProxyQuoteOptions,\n ) => Promise<PriceStorageQuoteResponse>;\n requestStorageUploadFn?: (\n request: StorageUploadRequest,\n options?: ProxyUploadOptions,\n ) => Promise<StorageUploadResponse>;\n resolveWalletPrivateKeyFn?: (homeDir?: string) => Promise<`0x${string}`>;\n createPaymentFetchFn?: (privateKey: `0x${string}`) => PaymentFetchResult;\n fetchImpl?: FetchLike;\n nowDateFn?: () => Date;\n idempotencyKeyFn?: () => string;\n proxyQuoteOptions?: ProxyQuoteOptions;\n proxyUploadOptions?: ProxyUploadOptions;\n requestStorageLsFn?: (\n request: StorageObjectRequest,\n options?: ProxyStorageOptions,\n ) => Promise<StorageLsResponse>;\n requestStorageDownloadFn?: (\n request: StorageObjectRequest,\n options?: ProxyStorageOptions,\n ) => Promise<StorageDownloadProxyResponse>;\n requestStorageDeleteFn?: (\n request: StorageObjectRequest,\n options?: ProxyStorageOptions,\n ) => Promise<StorageDeleteResponse>;\n proxyStorageOptions?: ProxyStorageOptions;\n objectLogHomeDir?: string;\n};\n\nclass UnsupportedBackupPlatformError extends Error {\n constructor(platform: NodeJS.Platform) {\n super(`Unsupported platform for backup: ${platform}`);\n this.name = \"UnsupportedBackupPlatformError\";\n }\n}\n\nfunction toGbString(bytes: number): string {\n const gb = bytes / 1_000_000_000;\n const fixed = gb.toFixed(9).replace(/\\.?0+$/, \"\");\n if (!fixed) return \"0\";\n return fixed.includes(\".\") ? fixed : `${fixed}.0`;\n}\n\nfunction stripWrappingQuotes(input: string): string {\n const trimmed = input.trim();\n if (trimmed.length < 2) return trimmed;\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n return trimmed;\n}\n\nfunction tokenizeArgs(input: string): string[] {\n const tokens = input.match(/\"[^\"]*\"|'[^']*'|\\S+/g);\n if (!tokens) {\n return [];\n }\n return tokens.map((token) => stripWrappingQuotes(token));\n}\n\nfunction parseNamedFlags(input: string): Record<string, string> | null {\n const tokens = tokenizeArgs(input);\n if (tokens.length === 0) {\n return null;\n }\n\n const parsed: Record<string, string> = {};\n for (let i = 0; i < tokens.length; i += 1) {\n const keyToken = tokens[i];\n if (!keyToken.startsWith(\"--\")) {\n return null;\n }\n const key = keyToken.slice(2).toLowerCase();\n const value = tokens[i + 1];\n if (!value || value.startsWith(\"--\")) {\n return null;\n }\n parsed[key] = value;\n i += 1;\n }\n return parsed;\n}\n\nfunction parseCloudArgs(args?: string): ParsedCloudArgs {\n const trimmed = args?.trim() ?? \"\";\n if (!trimmed) {\n return { mode: \"help\" };\n }\n\n const spaceIdx = trimmed.indexOf(\" \");\n const subcommand = (spaceIdx === -1 ? trimmed : trimmed.slice(0, spaceIdx)).toLowerCase();\n const rest = spaceIdx === -1 ? \"\" : trimmed.slice(spaceIdx + 1);\n\n if (subcommand === \"help\") {\n return { mode: \"help\" };\n }\n\n if (subcommand === \"backup\") {\n const backupTarget = stripWrappingQuotes(rest);\n if (!backupTarget) {\n return { mode: \"unknown\" };\n }\n return { mode: \"backup\", backupTarget };\n }\n\n if (subcommand === \"price-storage\") {\n const flags = parseNamedFlags(rest);\n if (!flags) {\n return { mode: \"price-storage-invalid\" };\n }\n const gb = Number.parseFloat(flags.gb ?? \"\");\n const request = parsePriceStorageQuoteRequest({\n wallet_address: flags[\"wallet-address\"],\n object_id: flags[\"object-id\"],\n object_id_hash: flags[\"object-id-hash\"],\n gb,\n provider: flags.provider,\n region: flags.region,\n });\n if (!request) {\n return { mode: \"price-storage-invalid\" };\n }\n return { mode: \"price-storage\", priceStorageRequest: request };\n }\n\n if (subcommand === \"upload\") {\n const flags = parseNamedFlags(rest);\n if (!flags) {\n return { mode: \"upload-invalid\" };\n }\n\n const quoteId = flags[\"quote-id\"]?.trim();\n const walletAddress = flags[\"wallet-address\"]?.trim();\n const objectId = flags[\"object-id\"]?.trim();\n const objectIdHash = flags[\"object-id-hash\"]?.trim();\n\n if (!quoteId || !walletAddress || !objectId || !objectIdHash) {\n return { mode: \"upload-invalid\" };\n }\n\n return {\n mode: \"upload\",\n uploadRequest: {\n quote_id: quoteId,\n wallet_address: walletAddress,\n object_id: objectId,\n object_id_hash: objectIdHash,\n },\n };\n }\n\n if (subcommand === \"ls\") {\n const flags = parseNamedFlags(rest);\n if (!flags) {\n return { mode: \"ls-invalid\" };\n }\n const request = parseStorageObjectRequest({\n wallet_address: flags[\"wallet-address\"],\n object_key: flags[\"object-key\"],\n location: flags.location ?? flags.region,\n });\n if (!request) {\n return { mode: \"ls-invalid\" };\n }\n return { mode: \"ls\", storageObjectRequest: request };\n }\n\n if (subcommand === \"download\") {\n const flags = parseNamedFlags(rest);\n if (!flags) {\n return { mode: \"download-invalid\" };\n }\n const request = parseStorageObjectRequest({\n wallet_address: flags[\"wallet-address\"],\n object_key: flags[\"object-key\"],\n location: flags.location ?? flags.region,\n });\n if (!request) {\n return { mode: \"download-invalid\" };\n }\n return { mode: \"download\", storageObjectRequest: request };\n }\n\n if (subcommand === \"delete\") {\n const flags = parseNamedFlags(rest);\n if (!flags) {\n return { mode: \"delete-invalid\" };\n }\n const request = parseStorageObjectRequest({\n wallet_address: flags[\"wallet-address\"],\n object_key: flags[\"object-key\"],\n location: flags.location ?? flags.region,\n });\n if (!request) {\n return { mode: \"delete-invalid\" };\n }\n return { mode: \"delete\", storageObjectRequest: request };\n }\n\n return { mode: \"unknown\" };\n}\n\nfunction resolveObjectLogPath(homeDir?: string): string {\n return join(homeDir ?? homedir(), OBJECT_LOG_SUBPATH);\n}\n\nfunction resolveCronTablePath(homeDir?: string): string {\n return join(homeDir ?? homedir(), CRON_TABLE_SUBPATH);\n}\n\nasync function appendObjectLogLine(line: string, homeDir?: string): Promise<string> {\n const objectLogPath = resolveObjectLogPath(homeDir);\n await mkdir(dirname(objectLogPath), { recursive: true });\n await appendFile(objectLogPath, `${line}\\n`, \"utf-8\");\n return objectLogPath;\n}\n\nasync function calculateInputSizeBytes(targetPath: string): Promise<number> {\n const targetStats = await lstat(targetPath);\n if (targetStats.isFile() || targetStats.isSymbolicLink()) {\n return targetStats.size;\n }\n\n if (!targetStats.isDirectory()) {\n throw new Error(\"Backup target must be a file or directory\");\n }\n\n let total = 0;\n const entries = await readdir(targetPath, { withFileTypes: true });\n for (const entry of entries) {\n total += await calculateInputSizeBytes(join(targetPath, entry.name));\n }\n return total;\n}\n\nfunction getAvailableDiskBytes(tmpDir: string, options: BackupObjectOptions): number {\n if (typeof options.availableDiskBytes === \"number\") {\n return options.availableDiskBytes;\n }\n const stats = statfsSync(tmpDir);\n return stats.bavail * stats.bsize;\n}\n\nasync function runTarGzip(archivePath: string, sourcePath: string): Promise<void> {\n const sourceDir = dirname(sourcePath);\n const sourceName = basename(sourcePath);\n\n await new Promise<void>((resolvePromise, rejectPromise) => {\n let stderr = \"\";\n const child = spawn(\"tar\", [\"-czf\", archivePath, \"-C\", sourceDir, sourceName], {\n stdio: [\"ignore\", \"ignore\", \"pipe\"],\n });\n\n child.stderr.on(\"data\", (chunk) => {\n stderr += chunk.toString();\n });\n child.on(\"error\", rejectPromise);\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolvePromise();\n return;\n }\n rejectPromise(new Error(stderr.trim() || `tar exited with code ${code ?? \"unknown\"}`));\n });\n });\n}\n\nasync function sha256File(filePath: string): Promise<string> {\n const hash = createHash(\"sha256\");\n await new Promise<void>((resolvePromise, rejectPromise) => {\n const stream = createReadStream(filePath);\n stream.on(\"data\", (chunk) => hash.update(chunk));\n stream.on(\"error\", rejectPromise);\n stream.on(\"end\", () => resolvePromise());\n });\n return hash.digest(\"hex\");\n}\n\nfunction createObjectId(options: BackupObjectOptions): string {\n const nowFn = options.now ?? Date.now;\n const randomFn = options.randomBytes ?? randomBytesNode;\n return `${nowFn()}-${randomFn(8).toString(\"hex\")}`;\n}\n\nexport async function buildBackupObject(\n targetPathArg: string,\n options: BackupObjectOptions = {},\n): Promise<BackupObjectResult> {\n const platform = options.platform ?? process.platform;\n if (!SUPPORTED_BACKUP_PLATFORMS.has(platform)) {\n throw new UnsupportedBackupPlatformError(platform);\n }\n\n const targetPath = resolve(targetPathArg);\n const targetStats = await lstat(targetPath);\n if (!targetStats.isFile() && !targetStats.isDirectory()) {\n throw new Error(\"Backup target must be a file or directory\");\n }\n\n const tmpDir = options.tmpDir ?? DEFAULT_BACKUP_DIR;\n let tmpStats;\n try {\n tmpStats = await stat(tmpDir);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n await mkdir(tmpDir, { recursive: true });\n tmpStats = await stat(tmpDir);\n } else {\n throw error;\n }\n }\n if (!tmpStats.isDirectory()) {\n throw new Error(\"Backup path is not a directory\");\n }\n\n const inputSizeBytes = await calculateInputSizeBytes(targetPath);\n const availableDiskBytes = getAvailableDiskBytes(tmpDir, options);\n const requiredDiskBytes = inputSizeBytes + TAR_OVERHEAD_BYTES;\n if (availableDiskBytes < requiredDiskBytes) {\n throw new Error(\"Insufficient disk space for backup object\");\n }\n\n const objectId = createObjectId(options);\n const archivePath = join(tmpDir, objectId);\n\n try {\n await runTarGzip(archivePath, targetPath);\n const archiveStats = await stat(archivePath);\n const objectIdHash = await sha256File(archivePath);\n const objectSizeGb = toGbString(archiveStats.size);\n\n const objectLogPath = await appendObjectLogLine(\n `${objectId},${objectIdHash},${objectSizeGb}`,\n options.homeDir,\n );\n\n return {\n objectId,\n objectIdHash,\n objectSizeGb,\n archivePath,\n objectLogPath,\n };\n } catch (error) {\n await rm(archivePath, { force: true }).catch(() => undefined);\n throw error;\n }\n}\n\nasync function appendPriceStorageQuoteLog(\n quote: PriceStorageQuoteResponse,\n homeDir?: string,\n): Promise<string> {\n return appendObjectLogLine(\n [\n quote.timestamp,\n quote.quote_id,\n quote.storage_price.toString(),\n quote.addr,\n quote.object_id,\n quote.object_id_hash,\n quote.object_size_gb.toString(),\n quote.provider,\n quote.location,\n ].join(\",\"),\n homeDir,\n );\n}\n\ntype LoggedPriceStorageQuote = {\n quoteId: string;\n storagePrice: number;\n walletAddress: string;\n objectId: string;\n objectIdHash: string;\n provider: string;\n location: string;\n};\n\ntype StoragePaymentCronJob = {\n cronId: string;\n createdAt: string;\n schedule: string;\n command: string;\n quoteId: string;\n storagePrice: number;\n walletAddress: string;\n objectId: string;\n objectKey: string;\n provider: string;\n bucketName: string;\n location: string;\n};\n\ntype LoggedStoragePaymentCron = {\n cronId: string;\n objectId: string;\n objectKey: string;\n};\n\nfunction formatTimestamp(date: Date): string {\n const pad = (value: number): string => value.toString().padStart(2, \"0\");\n return [\n date.getFullYear().toString(),\n \"-\",\n pad(date.getMonth() + 1),\n \"-\",\n pad(date.getDate()),\n \" \",\n pad(date.getHours()),\n \":\",\n pad(date.getMinutes()),\n \":\",\n pad(date.getSeconds()),\n ].join(\"\");\n}\n\nfunction parseLoggedPriceStorageQuote(line: string): LoggedPriceStorageQuote | null {\n const parts = line.split(\",\");\n if (parts.length < 9) {\n return null;\n }\n\n const quoteId = parts[1]?.trim() ?? \"\";\n const storagePriceRaw = parts[2]?.trim() ?? \"\";\n const walletAddress = parts[3]?.trim() ?? \"\";\n const objectId = parts[4]?.trim() ?? \"\";\n const objectIdHash = parts[5]?.trim() ?? \"\";\n const provider = parts[7]?.trim() ?? \"\";\n const location = parts[8]?.trim() ?? \"\";\n const storagePrice = Number.parseFloat(storagePriceRaw);\n\n if (!quoteId || !walletAddress || !objectId || !objectIdHash || !provider || !location) {\n return null;\n }\n if (!Number.isFinite(storagePrice) || storagePrice <= 0) {\n return null;\n }\n\n return {\n quoteId,\n storagePrice,\n walletAddress,\n objectId,\n objectIdHash,\n provider,\n location,\n };\n}\n\nfunction parseLoggedStoragePaymentCron(line: string): LoggedStoragePaymentCron | null {\n const parts = line.split(\",\");\n if (parts.length < 5) {\n return null;\n }\n if ((parts[0]?.trim() ?? \"\").toLowerCase() !== CRON_LOG_ROW_PREFIX) {\n return null;\n }\n\n const cronId = parts[2]?.trim() ?? \"\";\n const objectId = parts[3]?.trim() ?? \"\";\n const objectKey = parts[4]?.trim() ?? \"\";\n if (!cronId || !objectId || !objectKey) {\n return null;\n }\n\n return {\n cronId,\n objectId,\n objectKey,\n };\n}\n\nfunction parseStoragePaymentCronJobLine(line: string): StoragePaymentCronJob | null {\n const trimmed = line.trim();\n if (!trimmed) {\n return null;\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(trimmed);\n } catch {\n return null;\n }\n\n if (!payload || typeof payload !== \"object\") {\n return null;\n }\n const record = payload as Record<string, unknown>;\n\n const cronId = typeof record.cronId === \"string\" ? record.cronId.trim() : \"\";\n const createdAt = typeof record.createdAt === \"string\" ? record.createdAt.trim() : \"\";\n const schedule = typeof record.schedule === \"string\" ? record.schedule.trim() : \"\";\n const command = typeof record.command === \"string\" ? record.command.trim() : \"\";\n const quoteId = typeof record.quoteId === \"string\" ? record.quoteId.trim() : \"\";\n const storagePrice = typeof record.storagePrice === \"number\" ? record.storagePrice : Number.NaN;\n const walletAddress = typeof record.walletAddress === \"string\" ? record.walletAddress.trim() : \"\";\n const objectId = typeof record.objectId === \"string\" ? record.objectId.trim() : \"\";\n const objectKey = typeof record.objectKey === \"string\" ? record.objectKey.trim() : \"\";\n const provider = typeof record.provider === \"string\" ? record.provider.trim() : \"\";\n const bucketName = typeof record.bucketName === \"string\" ? record.bucketName.trim() : \"\";\n const location = typeof record.location === \"string\" ? record.location.trim() : \"\";\n\n if (\n !cronId ||\n !createdAt ||\n !schedule ||\n !command ||\n !quoteId ||\n !Number.isFinite(storagePrice) ||\n storagePrice <= 0 ||\n !walletAddress ||\n !objectId ||\n !objectKey ||\n !provider ||\n !bucketName ||\n !location\n ) {\n return null;\n }\n\n return {\n cronId,\n createdAt,\n schedule,\n command,\n quoteId,\n storagePrice,\n walletAddress,\n objectId,\n objectKey,\n provider,\n bucketName,\n location,\n };\n}\n\nasync function findLoggedPriceStorageQuote(\n quoteId: string,\n homeDir?: string,\n): Promise<LoggedPriceStorageQuote | null> {\n const objectLogPath = resolveObjectLogPath(homeDir);\n\n let content: string;\n try {\n content = await readFile(objectLogPath, \"utf-8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n\n const lines = content\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n for (let idx = lines.length - 1; idx >= 0; idx -= 1) {\n const parsed = parseLoggedPriceStorageQuote(lines[idx]);\n if (parsed && parsed.quoteId === quoteId) {\n return parsed;\n }\n }\n return null;\n}\n\nasync function findLoggedStoragePaymentCronByObjectKey(\n objectKey: string,\n homeDir?: string,\n): Promise<LoggedStoragePaymentCron | null> {\n const objectLogPath = resolveObjectLogPath(homeDir);\n\n let content: string;\n try {\n content = await readFile(objectLogPath, \"utf-8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n\n const lines = content\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0);\n for (let idx = lines.length - 1; idx >= 0; idx -= 1) {\n const parsed = parseLoggedStoragePaymentCron(lines[idx]);\n if (parsed && parsed.objectKey === objectKey) {\n return parsed;\n }\n }\n return null;\n}\n\nfunction quoteCronArgument(value: string | number): string {\n return JSON.stringify(String(value));\n}\n\nfunction buildStoragePaymentCronCommand(job: {\n quoteId: string;\n walletAddress: string;\n objectId: string;\n objectKey: string;\n storagePrice: number;\n}): string {\n return [\n \"mnemospark-pay-storage\",\n \"--quote-id\",\n quoteCronArgument(job.quoteId),\n \"--wallet-address\",\n quoteCronArgument(job.walletAddress),\n \"--object-id\",\n quoteCronArgument(job.objectId),\n \"--object-key\",\n quoteCronArgument(job.objectKey),\n \"--storage-price\",\n quoteCronArgument(job.storagePrice),\n ].join(\" \");\n}\n\nasync function appendStoragePaymentCronLog(\n cronJob: StoragePaymentCronJob,\n homeDir?: string,\n): Promise<string> {\n return appendObjectLogLine(\n [\n CRON_LOG_ROW_PREFIX,\n cronJob.createdAt,\n cronJob.cronId,\n cronJob.objectId,\n cronJob.objectKey,\n cronJob.quoteId,\n cronJob.storagePrice.toString(),\n ].join(\",\"),\n homeDir,\n );\n}\n\nasync function appendStoragePaymentCronJob(\n cronJob: StoragePaymentCronJob,\n homeDir?: string,\n): Promise<string> {\n const cronTablePath = resolveCronTablePath(homeDir);\n await mkdir(dirname(cronTablePath), { recursive: true });\n await appendFile(cronTablePath, `${JSON.stringify(cronJob)}\\n`, \"utf-8\");\n return cronTablePath;\n}\n\nasync function removeStoragePaymentCronJob(cronId: string, homeDir?: string): Promise<boolean> {\n const cronTablePath = resolveCronTablePath(homeDir);\n\n let content: string;\n try {\n content = await readFile(cronTablePath, \"utf-8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return false;\n }\n throw error;\n }\n\n const lines = content.split(/\\r?\\n/);\n let removed = false;\n const keptLines: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n const parsed = parseStoragePaymentCronJobLine(trimmed);\n if (parsed && parsed.cronId === cronId) {\n removed = true;\n continue;\n }\n keptLines.push(trimmed);\n }\n\n if (!removed) {\n return false;\n }\n\n await mkdir(dirname(cronTablePath), { recursive: true });\n const nextContent = keptLines.length > 0 ? `${keptLines.join(\"\\n\")}\\n` : \"\";\n await writeFile(cronTablePath, nextContent, \"utf-8\");\n return true;\n}\n\nasync function createStoragePaymentCronJob(\n upload: StorageUploadResponse,\n storagePrice: number,\n homeDir?: string,\n nowDateFn: () => Date = () => new Date(),\n): Promise<StoragePaymentCronJob> {\n const cronId = randomUUID();\n const createdAt = formatTimestamp(nowDateFn());\n const cronJob: StoragePaymentCronJob = {\n cronId,\n createdAt,\n schedule: PAYMENT_CRON_SCHEDULE,\n command: buildStoragePaymentCronCommand({\n quoteId: upload.quote_id,\n walletAddress: upload.addr,\n objectId: upload.object_id,\n objectKey: upload.object_key,\n storagePrice,\n }),\n quoteId: upload.quote_id,\n storagePrice,\n walletAddress: upload.addr,\n objectId: upload.object_id,\n objectKey: upload.object_key,\n provider: upload.provider,\n bucketName: upload.bucket_name,\n location: upload.location,\n };\n\n await appendStoragePaymentCronJob(cronJob, homeDir);\n await appendStoragePaymentCronLog(cronJob, homeDir);\n return cronJob;\n}\n\nfunction isValidWalletPrivateKey(value: string | undefined): value is `0x${string}` {\n return typeof value === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(value.trim());\n}\n\nasync function readWalletKeyIfPresent(walletPath: string): Promise<`0x${string}` | null> {\n try {\n const key = (await readFile(walletPath, \"utf-8\")).trim();\n return isValidWalletPrivateKey(key) ? key : null;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return null;\n }\n throw error;\n }\n}\n\nasync function resolveWalletPrivateKey(homeDir?: string): Promise<`0x${string}`> {\n const envKey = process.env.BLOCKRUN_WALLET_KEY?.trim();\n if (isValidWalletPrivateKey(envKey)) {\n return envKey;\n }\n\n const baseHome = homeDir ?? homedir();\n const primaryWalletPath = join(baseHome, BLOCKRUN_WALLET_KEY_SUBPATH);\n const fallbackWalletPath = join(baseHome, MNEMOSPARK_WALLET_KEY_SUBPATH);\n\n const fromPrimary = await readWalletKeyIfPresent(primaryWalletPath);\n if (fromPrimary) {\n return fromPrimary;\n }\n\n const fromFallback = await readWalletKeyIfPresent(fallbackWalletPath);\n if (fromFallback) {\n return fromFallback;\n }\n\n throw new Error(\"Wallet key not found. Configure BLOCKRUN_WALLET_KEY or run /wallet first.\");\n}\n\nfunction sha256Buffer(content: Buffer): string {\n return createHash(\"sha256\").update(content).digest(\"hex\");\n}\n\nfunction walletShortHash(walletAddress: string): string {\n return sha256Buffer(Buffer.from(walletAddress.trim().toLowerCase(), \"utf-8\")).slice(0, 16);\n}\n\nfunction bucketNameForWallet(walletAddress: string): string {\n return `mnemospark-${walletShortHash(walletAddress)}`;\n}\n\nfunction encryptAesGcm(\n plaintext: Buffer,\n key: Buffer,\n randomFn: (size: number) => Buffer = randomBytesNode,\n): Buffer {\n if (key.length !== 32) {\n throw new Error(\"Expected 32-byte AES key\");\n }\n const nonce = randomFn(AES_GCM_NONCE_BYTES);\n const cipher = createCipheriv(\"aes-256-gcm\", key, nonce);\n const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);\n const tag = cipher.getAuthTag();\n return Buffer.concat([nonce, ciphertext, tag]);\n}\n\nasync function loadOrCreateKek(\n walletAddress: string,\n homeDir?: string,\n): Promise<{ kek: Buffer; keyPath: string }> {\n const keyPath = join(\n homeDir ?? homedir(),\n KEY_STORE_SUBPATH,\n `${walletShortHash(walletAddress)}.key`,\n );\n await mkdir(dirname(keyPath), { recursive: true });\n\n try {\n const existing = await readFile(keyPath);\n if (existing.length === 32) {\n return { kek: existing, keyPath };\n }\n const decoded = Buffer.from(existing.toString(\"utf-8\").trim(), \"base64\");\n if (decoded.length === 32) {\n return { kek: decoded, keyPath };\n }\n throw new Error(\"Invalid key file format\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n\n const generated = randomBytesNode(32);\n await writeFile(keyPath, generated, { mode: 0o600 });\n return { kek: generated, keyPath };\n}\n\ntype PreparedUploadPayload = {\n payload: UploadPayload;\n encryptedContent: Buffer;\n};\n\nasync function prepareUploadPayload(\n archivePath: string,\n walletAddress: string,\n homeDir?: string,\n): Promise<PreparedUploadPayload> {\n const plaintext = await readFile(archivePath);\n const { kek, keyPath } = await loadOrCreateKek(walletAddress, homeDir);\n\n const dek = randomBytesNode(32);\n const encryptedContent = encryptAesGcm(plaintext, dek);\n const wrappedDek = encryptAesGcm(dek, kek);\n const payloadHash = sha256Buffer(encryptedContent);\n\n const payload: UploadPayload = {\n mode: encryptedContent.length <= INLINE_UPLOAD_MAX_BYTES ? \"inline\" : \"presigned\",\n content_base64:\n encryptedContent.length <= INLINE_UPLOAD_MAX_BYTES\n ? encryptedContent.toString(\"base64\")\n : undefined,\n content_sha256: payloadHash,\n content_length_bytes: encryptedContent.length,\n wrapped_dek: wrappedDek.toString(\"base64\"),\n encryption_algorithm: \"AES-256-GCM\",\n bucket_name_hint: bucketNameForWallet(walletAddress),\n key_store_path_hint: keyPath,\n };\n\n return {\n payload,\n encryptedContent,\n };\n}\n\nasync function uploadPresignedObjectIfNeeded(\n uploadResponse: StorageUploadResponse,\n uploadMode: UploadPayload[\"mode\"],\n encryptedContent: Buffer,\n fetchImpl: FetchLike = fetch,\n): Promise<void> {\n if (!uploadResponse.upload_url) {\n if (uploadMode === \"presigned\") {\n throw new Error(\"Cannot upload storage object: missing presigned upload URL.\");\n }\n return;\n }\n\n const headers = new Headers(uploadResponse.upload_headers ?? {});\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/octet-stream\");\n }\n\n const response = await fetchImpl(uploadResponse.upload_url, {\n method: \"PUT\",\n headers,\n body: new Uint8Array(encryptedContent),\n });\n if (!response.ok) {\n const details = (await response.text()).trim();\n throw new Error(\n `Presigned upload failed with status ${response.status}${details ? `: ${details}` : \"\"}`,\n );\n }\n}\n\nasync function appendStorageUploadLog(\n upload: StorageUploadResponse,\n homeDir?: string,\n nowDateFn: () => Date = () => new Date(),\n): Promise<string> {\n return appendObjectLogLine(\n [\n formatTimestamp(nowDateFn()),\n upload.quote_id,\n upload.addr,\n upload.addr_hash ?? \"\",\n upload.trans_id ?? \"\",\n upload.storage_price?.toString() ?? \"\",\n upload.object_id,\n upload.object_key,\n upload.provider,\n upload.bucket_name,\n upload.location,\n ].join(\",\"),\n homeDir,\n );\n}\n\nasync function maybeCleanupLocalBackupArchive(archivePath: string): Promise<void> {\n const flag = process.env.MNEMOSPARK_DELETE_BACKUP_AFTER_UPLOAD;\n if (!flag) {\n return;\n }\n const normalized = flag.trim().toLowerCase();\n if (normalized !== \"1\" && normalized !== \"true\" && normalized !== \"yes\" && normalized !== \"y\") {\n return;\n }\n try {\n await rm(archivePath, { force: true });\n } catch {\n // Best-effort cleanup; ignore failures.\n }\n}\n\nfunction formatStorageUploadUserMessage(upload: StorageUploadResponse, cronJobId: string): string {\n return [\n `Your file \\`${upload.object_id}\\` with key \\`${upload.object_key}\\` has been stored using \\`${upload.provider}\\` in \\`${upload.bucket_name}\\` \\`${upload.location}\\``,\n `A cron job \\`${cronJobId}\\` has been configured to send payment monthly (on the 1st) for storage services. If payment is not sent, your \\`${upload.object_id}\\` will be deleted after the **${PAYMENT_DELETE_DEADLINE_DAYS}-day deadline** (${PAYMENT_REMINDER_INTERVAL_DAYS}-day billing interval + 2-day grace period).`,\n \"Thank you for using mnemospark!\",\n ].join(\"\\n\");\n}\n\nfunction formatStorageDeleteUserMessage(\n objectKey: string,\n cronId: string | null,\n cronDeleted: boolean,\n): string {\n const statusLine = cronId\n ? cronDeleted\n ? `File \\`${objectKey}\\` has been deleted from the cloud and the cron job \\`${cronId}\\` has been deleted from your system.`\n : `File \\`${objectKey}\\` has been deleted from the cloud and the cron job \\`${cronId}\\` was not found in your system.`\n : `File \\`${objectKey}\\` has been deleted from the cloud and no matching cron job was found in your system.`;\n\n return [statusLine, \"Thank you for using mnemospark!\"].join(\"\\n\");\n}\n\nfunction extractUploadErrorMessage(error: unknown): string | null {\n if (!(error instanceof Error)) {\n return null;\n }\n const message = error.message.trim();\n if (!message) {\n return null;\n }\n\n try {\n const payload = JSON.parse(message) as {\n message?: string;\n error?: { message?: string } | string;\n };\n if (typeof payload.message === \"string\" && payload.message.trim().length > 0) {\n return payload.message.trim();\n }\n if (typeof payload.error === \"string\" && payload.error.trim().length > 0) {\n return payload.error.trim();\n }\n if (\n payload.error &&\n typeof payload.error === \"object\" &&\n typeof payload.error.message === \"string\" &&\n payload.error.message.trim().length > 0\n ) {\n return payload.error.message.trim();\n }\n } catch {\n // Not JSON. Fall back to raw message.\n }\n\n return message;\n}\n\nfunction formatPriceStorageUserMessage(quote: PriceStorageQuoteResponse): string {\n return [\n `Your storage quote \\`${quote.quote_id}\\` is valid for 1 hour, the storage price is \\`${quote.storage_price}\\` for \\`${quote.object_id}\\` with file size of \\`${quote.object_size_gb}\\` in \\`${quote.provider}\\` \\`${quote.location}\\``,\n `If you accept this quote run the command /cloud upload --quote-id \\`${quote.quote_id}\\` --wallet-address \\`${quote.addr}\\` --object-id \\`${quote.object_id}\\` --object-id-hash \\`${quote.object_id_hash}\\``,\n ].join(\"\\n\");\n}\n\nfunction formatStorageLsUserMessage(result: StorageLsResponse, requestedObjectKey: string): string {\n const objectId = result.object_id ?? result.key;\n return `${objectId} with ${requestedObjectKey} is ${result.size_bytes} in ${result.bucket}`;\n}\n\nexport function createCloudCommand(\n options: CreateCloudCommandOptions = {},\n): OpenClawPluginCommandDefinition {\n const backupBuilder = options.buildBackupObjectFn ?? buildBackupObject;\n const requestPriceStorageQuote =\n options.requestPriceStorageQuoteFn ?? requestPriceStorageViaProxy;\n const requestStorageUpload = options.requestStorageUploadFn ?? requestStorageUploadViaProxy;\n const resolveWalletKey = options.resolveWalletPrivateKeyFn ?? resolveWalletPrivateKey;\n const createPayment = options.createPaymentFetchFn ?? createPaymentFetch;\n const fetchImpl = options.fetchImpl ?? fetch;\n const nowDateFn = options.nowDateFn ?? (() => new Date());\n const idempotencyKeyFn = options.idempotencyKeyFn ?? randomUUID;\n const requestStorageLs = options.requestStorageLsFn ?? requestStorageLsViaProxy;\n const requestStorageDownload = options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy;\n const requestStorageDelete = options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy;\n const objectLogHomeDir = options.objectLogHomeDir ?? options.backupOptions?.homeDir;\n\n return {\n name: \"cloud\",\n description: \"Manage mnemospark cloud storage workflow commands\",\n acceptsArgs: true,\n requireAuth: true,\n handler: async (ctx) => {\n const parsed = parseCloudArgs(ctx.args);\n\n if (parsed.mode === \"help\" || parsed.mode === \"unknown\") {\n return {\n text: CLOUD_HELP_TEXT,\n isError: parsed.mode === \"unknown\",\n };\n }\n\n if (parsed.mode === \"price-storage-invalid\") {\n return {\n text: `Cannot price storage: required arguments are ${REQUIRED_PRICE_STORAGE}.`,\n isError: true,\n };\n }\n\n if (parsed.mode === \"upload-invalid\") {\n return {\n text: `Cannot upload storage object: required arguments are ${REQUIRED_UPLOAD}.`,\n isError: true,\n };\n }\n\n if (parsed.mode === \"ls-invalid\") {\n return {\n text: `Cannot list storage object: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,\n isError: true,\n };\n }\n\n if (parsed.mode === \"download-invalid\") {\n return {\n text: `Cannot download file: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,\n isError: true,\n };\n }\n\n if (parsed.mode === \"delete-invalid\") {\n return {\n text: `Cannot delete file: required arguments are ${REQUIRED_STORAGE_OBJECT}.`,\n isError: true,\n };\n }\n\n if (parsed.mode === \"backup\") {\n try {\n const result = await backupBuilder(parsed.backupTarget, options.backupOptions);\n return {\n text: `Your object-id is ${result.objectId} your object-id-hash is ${result.objectIdHash} and your object-size is ${result.objectSizeGb}`,\n };\n } catch (err) {\n if (err instanceof UnsupportedBackupPlatformError) {\n return {\n text: \"Cloud backup is only supported on macOS and Linux.\",\n isError: true,\n };\n }\n return {\n text: \"Cannot build storage object\",\n isError: true,\n };\n }\n }\n\n if (parsed.mode === \"price-storage\") {\n try {\n const quote = await requestPriceStorageQuote(\n parsed.priceStorageRequest,\n options.proxyQuoteOptions,\n );\n await appendPriceStorageQuoteLog(quote, objectLogHomeDir);\n return {\n text: formatPriceStorageUserMessage(quote),\n };\n } catch {\n return {\n text: \"Cannot price storage\",\n isError: true,\n };\n }\n }\n\n if (parsed.mode === \"upload\") {\n try {\n const loggedQuote = await findLoggedPriceStorageQuote(\n parsed.uploadRequest.quote_id,\n objectLogHomeDir,\n );\n if (!loggedQuote) {\n return {\n text: \"Cannot upload storage object: quote-id not found in object.log. Run /cloud price-storage first.\",\n isError: true,\n };\n }\n\n if (\n loggedQuote.walletAddress.toLowerCase() !==\n parsed.uploadRequest.wallet_address.toLowerCase() ||\n loggedQuote.objectId !== parsed.uploadRequest.object_id ||\n loggedQuote.objectIdHash.toLowerCase() !==\n parsed.uploadRequest.object_id_hash.toLowerCase()\n ) {\n return {\n text: \"Cannot upload storage object: quote details do not match wallet/object arguments.\",\n isError: true,\n };\n }\n\n const archivePath = join(\n options.backupOptions?.tmpDir ?? DEFAULT_BACKUP_DIR,\n parsed.uploadRequest.object_id,\n );\n let archiveStats;\n try {\n archiveStats = await stat(archivePath);\n } catch {\n return {\n text: `Cannot upload storage object: local archive not found at ${archivePath}. Run /cloud backup first.`,\n isError: true,\n };\n }\n if (!archiveStats.isFile()) {\n return {\n text: `Cannot upload storage object: local archive path is not a file (${archivePath}).`,\n isError: true,\n };\n }\n\n const archiveHash = await sha256File(archivePath);\n if (archiveHash.toLowerCase() !== parsed.uploadRequest.object_id_hash.toLowerCase()) {\n return {\n text: \"Cannot upload storage object: object-id-hash does not match local archive.\",\n isError: true,\n };\n }\n\n const walletKey = await resolveWalletKey(objectLogHomeDir);\n const walletAccount = privateKeyToAccount(walletKey);\n if (\n walletAccount.address.toLowerCase() !==\n parsed.uploadRequest.wallet_address.toLowerCase()\n ) {\n return {\n text: `Cannot upload storage object: wallet key address ${walletAccount.address} does not match --wallet-address ${parsed.uploadRequest.wallet_address}.`,\n isError: true,\n };\n }\n\n const preparedPayload = await prepareUploadPayload(\n archivePath,\n parsed.uploadRequest.wallet_address,\n objectLogHomeDir,\n );\n const paymentFetch = createPayment(walletKey).fetch;\n const idempotencyKey = idempotencyKeyFn();\n\n const uploadResponse = await requestStorageUpload(\n {\n quote_id: parsed.uploadRequest.quote_id,\n wallet_address: parsed.uploadRequest.wallet_address,\n object_id: parsed.uploadRequest.object_id,\n object_id_hash: parsed.uploadRequest.object_id_hash,\n quoted_storage_price: loggedQuote.storagePrice,\n payload: preparedPayload.payload,\n },\n {\n ...options.proxyUploadOptions,\n idempotencyKey,\n fetchImpl: (input, init) => paymentFetch(input, init),\n },\n );\n\n await uploadPresignedObjectIfNeeded(\n uploadResponse,\n preparedPayload.payload.mode,\n preparedPayload.encryptedContent,\n fetchImpl,\n );\n await appendStorageUploadLog(uploadResponse, objectLogHomeDir, nowDateFn);\n const cronStoragePriceCandidate =\n uploadResponse.storage_price ?? loggedQuote.storagePrice;\n const cronStoragePrice =\n Number.isFinite(cronStoragePriceCandidate) && cronStoragePriceCandidate > 0\n ? cronStoragePriceCandidate\n : loggedQuote.storagePrice;\n const cronJob = await createStoragePaymentCronJob(\n uploadResponse,\n cronStoragePrice,\n objectLogHomeDir,\n nowDateFn,\n );\n await maybeCleanupLocalBackupArchive(archivePath);\n\n return {\n text: formatStorageUploadUserMessage(uploadResponse, cronJob.cronId),\n };\n } catch (error) {\n return {\n text: extractUploadErrorMessage(error) ?? \"Cannot upload storage object\",\n isError: true,\n };\n }\n }\n\n if (parsed.mode === \"ls\") {\n try {\n const lsResult = await requestStorageLs(\n parsed.storageObjectRequest,\n options.proxyStorageOptions,\n );\n if (!lsResult.success) {\n throw new Error(\"ls failed\");\n }\n return {\n text: formatStorageLsUserMessage(lsResult, parsed.storageObjectRequest.object_key),\n };\n } catch {\n return {\n text: \"Cannot list storage object\",\n isError: true,\n };\n }\n }\n\n if (parsed.mode === \"download\") {\n try {\n const downloadResult = await requestStorageDownload(\n parsed.storageObjectRequest,\n options.proxyStorageOptions,\n );\n if (!downloadResult.success) {\n throw new Error(\"download failed\");\n }\n return {\n text: `File ${parsed.storageObjectRequest.object_key} downloaded`,\n };\n } catch {\n return {\n text: \"Cannot download file\",\n isError: true,\n };\n }\n }\n\n if (parsed.mode === \"delete\") {\n try {\n const deleteResult = await requestStorageDelete(\n parsed.storageObjectRequest,\n options.proxyStorageOptions,\n );\n if (!deleteResult.success) {\n throw new Error(\"delete failed\");\n }\n } catch {\n return {\n text: \"Cannot delete file\",\n isError: true,\n };\n }\n let cronEntry: LoggedStoragePaymentCron | null = null;\n let cronDeleted = false;\n try {\n cronEntry = await findLoggedStoragePaymentCronByObjectKey(\n parsed.storageObjectRequest.object_key,\n objectLogHomeDir,\n );\n cronDeleted = cronEntry\n ? await removeStoragePaymentCronJob(cronEntry.cronId, objectLogHomeDir)\n : false;\n } catch {\n // Cloud delete already succeeded; cron lookup/removal is best-effort.\n // Report success without implying the delete failed.\n }\n return {\n text: formatStorageDeleteUserMessage(\n parsed.storageObjectRequest.object_key,\n cronEntry?.cronId ?? null,\n cronDeleted,\n ),\n };\n }\n\n return {\n text: CLOUD_HELP_TEXT,\n isError: true,\n };\n },\n };\n}\n\nexport type { BackupObjectOptions, BackupObjectResult, CreateCloudCommandOptions, ParsedCloudArgs };\n","/**\n * x402 Payment Implementation\n *\n * Based on BlockRun's proven implementation.\n * Handles 402 Payment Required responses with EIP-712 signed USDC transfers.\n *\n * Optimizations (v0.3.0):\n * - Payment cache: after first 402, caches {payTo, asset, network} per endpoint.\n * On subsequent requests, pre-signs payment and sends with first request,\n * skipping the 402 round trip (~200ms savings).\n * - Falls back to normal 402 flow if pre-signed payment is rejected.\n */\n\nimport { signTypedData, privateKeyToAccount } from \"viem/accounts\";\n\nimport { createNonce } from \"./nonce.js\";\nimport { PaymentCache } from \"./payment-cache.js\";\n\nconst BASE_CHAIN_ID = 8453;\nconst BASE_SEPOLIA_CHAIN_ID = 84532;\nconst DEFAULT_TOKEN_NAME = \"USD Coin\";\nconst DEFAULT_TOKEN_VERSION = \"2\";\nconst DEFAULT_NETWORK = \"eip155:8453\";\nconst DEFAULT_MAX_TIMEOUT_SECONDS = 300;\n\nconst TRANSFER_TYPES = {\n TransferWithAuthorization: [\n { name: \"from\", type: \"address\" },\n { name: \"to\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"validAfter\", type: \"uint256\" },\n { name: \"validBefore\", type: \"uint256\" },\n { name: \"nonce\", type: \"bytes32\" },\n ],\n} as const;\n\ninterface PaymentOption {\n scheme: string;\n network: string;\n amount?: string;\n maxAmountRequired?: string;\n asset: string;\n payTo: string;\n maxTimeoutSeconds?: number;\n extra?: { name?: string; version?: string };\n}\n\ninterface PaymentRequired {\n accepts: PaymentOption[];\n resource?: { url?: string; description?: string };\n}\n\nfunction decodeBase64Json<T>(value: string): T {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = (4 - (normalized.length % 4)) % 4;\n const padded = normalized + \"=\".repeat(padding);\n const decoded = Buffer.from(padded, \"base64\").toString(\"utf8\");\n return JSON.parse(decoded) as T;\n}\n\nfunction encodeBase64Json(value: unknown): string {\n return Buffer.from(JSON.stringify(value), \"utf8\").toString(\"base64\");\n}\n\nfunction parsePaymentRequired(headerValue: string): PaymentRequired {\n return decodeBase64Json<PaymentRequired>(headerValue);\n}\n\nfunction normalizeNetwork(network: string | undefined): string {\n if (!network || network.trim().length === 0) {\n return DEFAULT_NETWORK;\n }\n return network.trim().toLowerCase();\n}\n\nfunction resolveChainId(network: string): number {\n const eip155Match = network.match(/^eip155:(\\d+)$/i);\n if (eip155Match) {\n const parsed = Number.parseInt(eip155Match[1], 10);\n if (Number.isFinite(parsed) && parsed > 0) {\n return parsed;\n }\n }\n\n if (network === \"base\") return BASE_CHAIN_ID;\n if (network === \"base-sepolia\") return BASE_SEPOLIA_CHAIN_ID;\n return BASE_CHAIN_ID;\n}\n\nfunction parseHexAddress(value: string | undefined): `0x${string}` | undefined {\n if (!value) return undefined;\n\n const direct = value.match(/^0x[a-fA-F0-9]{40}$/);\n if (direct) {\n return direct[0] as `0x${string}`;\n }\n\n // Some providers send CAIP-style assets (e.g. \".../erc20:0x...\").\n const caipSuffix = value.match(/0x[a-fA-F0-9]{40}$/);\n if (caipSuffix) {\n return caipSuffix[0] as `0x${string}`;\n }\n\n return undefined;\n}\n\nfunction requireHexAddress(value: string | undefined, field: string): `0x${string}` {\n const parsed = parseHexAddress(value);\n if (!parsed) {\n throw new Error(`Invalid ${field} in payment requirements: ${String(value)}`);\n }\n return parsed;\n}\n\nfunction setPaymentHeaders(headers: Headers, payload: string): void {\n // Support both modern and legacy header names for compatibility.\n headers.set(\"payment-signature\", payload);\n headers.set(\"x-payment\", payload);\n}\n\nasync function createPaymentPayload(\n privateKey: `0x${string}`,\n fromAddress: string,\n option: PaymentOption,\n amount: string,\n requestUrl: string,\n resource: PaymentRequired[\"resource\"],\n): Promise<string> {\n const network = normalizeNetwork(option.network);\n const chainId = resolveChainId(network);\n const recipient = requireHexAddress(option.payTo, \"payTo\");\n const verifyingContract = requireHexAddress(option.asset, \"asset\");\n\n const maxTimeoutSeconds =\n typeof option.maxTimeoutSeconds === \"number\" && option.maxTimeoutSeconds > 0\n ? Math.floor(option.maxTimeoutSeconds)\n : DEFAULT_MAX_TIMEOUT_SECONDS;\n\n const now = Math.floor(Date.now() / 1000);\n const validAfter = now - 600;\n const validBefore = now + maxTimeoutSeconds;\n const nonce = createNonce();\n\n const signature = await signTypedData({\n privateKey,\n domain: {\n name: option.extra?.name || DEFAULT_TOKEN_NAME,\n version: option.extra?.version || DEFAULT_TOKEN_VERSION,\n chainId,\n verifyingContract,\n },\n types: TRANSFER_TYPES,\n primaryType: \"TransferWithAuthorization\",\n message: {\n from: fromAddress as `0x${string}`,\n to: recipient,\n value: BigInt(amount),\n validAfter: BigInt(validAfter),\n validBefore: BigInt(validBefore),\n nonce,\n },\n });\n\n const paymentData = {\n x402Version: 2,\n resource: {\n url: resource?.url || requestUrl,\n description: resource?.description || \"BlockRun AI API call\",\n mimeType: \"application/json\",\n },\n accepted: {\n scheme: option.scheme,\n network,\n amount,\n asset: option.asset,\n payTo: option.payTo,\n maxTimeoutSeconds: option.maxTimeoutSeconds,\n extra: option.extra,\n },\n payload: {\n signature,\n authorization: {\n from: fromAddress,\n to: recipient,\n value: amount,\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n },\n extensions: {},\n };\n\n return encodeBase64Json(paymentData);\n}\n\n/** Pre-auth parameters for skipping the 402 round trip. */\nexport type PreAuthParams = {\n estimatedAmount: string; // USDC amount in smallest unit (6 decimals)\n};\n\n/** Result from createPaymentFetch — includes the fetch wrapper and payment cache. */\nexport type PaymentFetchResult = {\n fetch: (\n input: RequestInfo | URL,\n init?: RequestInit,\n preAuth?: PreAuthParams,\n ) => Promise<Response>;\n cache: PaymentCache;\n};\n\n/**\n * Create a fetch wrapper that handles x402 payment automatically.\n *\n * Supports pre-auth: if cached payment params + estimated amount are available,\n * pre-signs and attaches payment to the first request, skipping the 402 round trip.\n * Falls back to normal 402 flow if pre-signed payment is rejected.\n */\nexport function createPaymentFetch(privateKey: `0x${string}`): PaymentFetchResult {\n const account = privateKeyToAccount(privateKey);\n const walletAddress = account.address;\n const paymentCache = new PaymentCache();\n\n const payFetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n preAuth?: PreAuthParams,\n ): Promise<Response> => {\n const url = typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\n const endpointPath = new URL(url).pathname;\n\n // --- Pre-auth path: skip 402 round trip ---\n const cached = paymentCache.get(endpointPath);\n if (cached && preAuth?.estimatedAmount) {\n const paymentPayload = await createPaymentPayload(\n privateKey,\n walletAddress,\n {\n scheme: cached.scheme,\n network: cached.network,\n asset: cached.asset,\n payTo: cached.payTo,\n maxTimeoutSeconds: cached.maxTimeoutSeconds,\n extra: cached.extra,\n },\n preAuth.estimatedAmount,\n url,\n {\n url: cached.resourceUrl,\n description: cached.resourceDescription,\n },\n );\n\n const preAuthHeaders = new Headers(init?.headers);\n setPaymentHeaders(preAuthHeaders, paymentPayload);\n\n const response = await fetch(input, { ...init, headers: preAuthHeaders });\n\n // Pre-auth accepted — skip 402 entirely\n if (response.status !== 402) {\n return response;\n }\n\n // Pre-auth rejected (wrong amount, payTo changed, etc.)\n // Try to use this 402's payment header for a proper retry (v2 or legacy)\n const paymentHeader =\n response.headers.get(\"payment-required\") ?? response.headers.get(\"x-payment-required\");\n if (paymentHeader) {\n return handle402(input, init, url, endpointPath, paymentHeader);\n }\n\n // No payment header — invalidate cache and retry clean (no payment header)\n // to get a proper 402 with payment requirements\n paymentCache.invalidate(endpointPath);\n const cleanResponse = await fetch(input, init);\n if (cleanResponse.status !== 402) {\n return cleanResponse;\n }\n const cleanHeader =\n cleanResponse.headers.get(\"payment-required\") ??\n cleanResponse.headers.get(\"x-payment-required\");\n if (!cleanHeader) {\n throw new Error(\"402 response missing PAYMENT-REQUIRED or x-payment-required header\");\n }\n return handle402(input, init, url, endpointPath, cleanHeader);\n }\n\n // --- Normal path: first request may get 402 ---\n const response = await fetch(input, init);\n\n if (response.status !== 402) {\n return response;\n }\n\n const paymentHeader =\n response.headers.get(\"payment-required\") ?? response.headers.get(\"x-payment-required\");\n if (!paymentHeader) {\n throw new Error(\"402 response missing PAYMENT-REQUIRED or x-payment-required header\");\n }\n\n return handle402(input, init, url, endpointPath, paymentHeader);\n };\n\n /** Handle a 402 response: parse, cache params, sign, retry. */\n async function handle402(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n url: string,\n endpointPath: string,\n paymentHeader: string,\n ): Promise<Response> {\n const paymentRequired = parsePaymentRequired(paymentHeader);\n const option = paymentRequired.accepts?.[0];\n if (!option) {\n throw new Error(\"No payment options in 402 response\");\n }\n\n const amount = option.amount || option.maxAmountRequired;\n if (!amount) {\n throw new Error(\"No amount in payment requirements\");\n }\n\n // Cache payment params for future pre-auth\n paymentCache.set(endpointPath, {\n payTo: option.payTo,\n asset: option.asset,\n scheme: option.scheme,\n network: option.network,\n extra: option.extra,\n maxTimeoutSeconds: option.maxTimeoutSeconds,\n resourceUrl: paymentRequired.resource?.url,\n resourceDescription: paymentRequired.resource?.description,\n });\n\n // Create signed payment\n const paymentPayload = await createPaymentPayload(\n privateKey,\n walletAddress,\n option,\n amount,\n url,\n paymentRequired.resource,\n );\n\n // Retry with payment\n const retryHeaders = new Headers(init?.headers);\n setPaymentHeaders(retryHeaders, paymentPayload);\n\n return fetch(input, {\n ...init,\n headers: retryHeaders,\n });\n }\n\n return { fetch: payFetch, cache: paymentCache };\n}\n","/**\n * Payment Parameter Cache\n *\n * Caches the 402 payment parameters (payTo, asset, network, etc.) after the first\n * request to each endpoint. On subsequent requests, pre-signs the payment and\n * attaches it to the first request, skipping the 402 round trip (~200ms savings).\n */\n\nexport type CachedPaymentParams = {\n payTo: string;\n asset: string;\n scheme: string;\n network: string;\n extra?: { name?: string; version?: string };\n maxTimeoutSeconds?: number;\n resourceUrl?: string;\n resourceDescription?: string;\n cachedAt: number;\n};\n\nconst DEFAULT_TTL_MS = 3_600_000; // 1 hour\n\nexport class PaymentCache {\n private cache = new Map<string, CachedPaymentParams>();\n private ttlMs: number;\n\n constructor(ttlMs = DEFAULT_TTL_MS) {\n this.ttlMs = ttlMs;\n }\n\n /** Get cached payment params for an endpoint path. */\n get(endpointPath: string): CachedPaymentParams | undefined {\n const entry = this.cache.get(endpointPath);\n if (!entry) return undefined;\n if (Date.now() - entry.cachedAt > this.ttlMs) {\n this.cache.delete(endpointPath);\n return undefined;\n }\n return entry;\n }\n\n /** Cache payment params from a 402 response. */\n set(endpointPath: string, params: Omit<CachedPaymentParams, \"cachedAt\">): void {\n this.cache.set(endpointPath, { ...params, cachedAt: Date.now() });\n }\n\n /** Invalidate cache for an endpoint (e.g., if payTo changed). */\n invalidate(endpointPath: string): void {\n this.cache.delete(endpointPath);\n }\n}\n","/**\n * Retry Logic for mnemospark\n *\n * Provides fetch wrapper with exponential backoff for transient errors.\n * Retries on 429 (rate limit), 502, 503, 504 (server errors).\n */\n\n/** Configuration for retry behavior */\nexport type RetryConfig = {\n /** Maximum number of retries (default: 2) */\n maxRetries: number;\n /** Base delay in ms for exponential backoff (default: 500) */\n baseDelayMs: number;\n /** HTTP status codes that trigger a retry (default: [429, 502, 503, 504]) */\n retryableCodes: number[];\n};\n\n/** Default retry configuration */\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 2,\n baseDelayMs: 500,\n retryableCodes: [429, 502, 503, 504],\n};\n\n/** Sleep for a given number of milliseconds */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Wrap a fetch-like function with retry logic and exponential backoff.\n *\n * @param fetchFn - The fetch function to wrap (can be standard fetch or x402 payFetch)\n * @param url - URL to fetch\n * @param init - Fetch init options\n * @param config - Retry configuration (optional, uses defaults)\n * @returns Response from successful fetch or last failed attempt\n *\n * @example\n * ```typescript\n * const response = await fetchWithRetry(\n * fetch,\n * \"https://api.example.com/endpoint\",\n * { method: \"POST\", body: JSON.stringify(data) },\n * { maxRetries: 3 }\n * );\n * ```\n */\nexport async function fetchWithRetry(\n fetchFn: (url: string, init?: RequestInit) => Promise<Response>,\n url: string,\n init?: RequestInit,\n config?: Partial<RetryConfig>,\n): Promise<Response> {\n const cfg: RetryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n };\n\n let lastError: Error | undefined;\n let lastResponse: Response | undefined;\n\n for (let attempt = 0; attempt <= cfg.maxRetries; attempt++) {\n try {\n const response = await fetchFn(url, init);\n\n // Success or non-retryable status — return immediately\n if (!cfg.retryableCodes.includes(response.status)) {\n return response;\n }\n\n // Retryable status — save response and maybe retry\n lastResponse = response;\n\n // Check for Retry-After header (common with 429)\n const retryAfter = response.headers.get(\"retry-after\");\n let delay: number;\n\n if (retryAfter) {\n // Retry-After can be seconds or HTTP-date\n const seconds = parseInt(retryAfter, 10);\n delay = isNaN(seconds) ? cfg.baseDelayMs * Math.pow(2, attempt) : seconds * 1000;\n } else {\n delay = cfg.baseDelayMs * Math.pow(2, attempt);\n }\n\n // Only retry if we have attempts left\n if (attempt < cfg.maxRetries) {\n await sleep(delay);\n }\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n // Network errors are retryable\n if (attempt < cfg.maxRetries) {\n const delay = cfg.baseDelayMs * Math.pow(2, attempt);\n await sleep(delay);\n }\n }\n }\n\n // All retries exhausted — return last response or throw last error\n if (lastResponse) {\n return lastResponse;\n }\n\n throw lastError ?? new Error(\"Max retries exceeded\");\n}\n\n/**\n * Check if an error or response indicates a retryable condition.\n */\nexport function isRetryable(\n errorOrResponse: Error | Response,\n config?: Partial<RetryConfig>,\n): boolean {\n const retryableCodes = config?.retryableCodes ?? DEFAULT_RETRY_CONFIG.retryableCodes;\n\n if (errorOrResponse instanceof Response) {\n return retryableCodes.includes(errorOrResponse.status);\n }\n\n // Network errors are generally retryable\n const message = errorOrResponse.message.toLowerCase();\n return (\n message.includes(\"network\") ||\n message.includes(\"timeout\") ||\n message.includes(\"econnreset\") ||\n message.includes(\"econnrefused\") ||\n message.includes(\"socket hang up\")\n );\n}\n"],"mappings":"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","names":["privateKeyToAccount","account","privateKeyToAccount","balanceMonitor","baseUrl","responseHeaders","existingWallet","writeFile","mkdir","join","privateKeyToAccount","privateKeyToAccount","mkdir","writeFile","dirname","join","require","privateKeyToAccount","mkdir","readFile","writeFile","homedir","dirname","join","resolve","privateKeyToAccount","signTypedData","privateKeyToAccount","BASE_SEPOLIA_CHAIN_ID","encodeBase64Json","signTypedData","privateKeyToAccount","response","paymentHeader","join","homedir","mkdir","dirname","resolve","readFile","writeFile","privateKeyToAccount","resolve","privateKeyToAccount"]}
@@ -0,0 +1,22 @@
1
+ {
2
+ "id": "mnemospark",
3
+ "name": "mnemospark",
4
+ "version": "0.1.2",
5
+ "description": "mnemospark is a OpenClaw plugin that enables cloud services workflows with wallet management and x402 USDC payments on Base.",
6
+ "configSchema": {
7
+ "type": "object",
8
+ "properties": {
9
+ "walletKey": {
10
+ "type": "string",
11
+ "description": "EVM wallet private key (0x...). Optional — auto-generated if not set for /wallet and /cloud flows."
12
+ }
13
+ }
14
+ },
15
+ "uiHints": {
16
+ "walletKey": {
17
+ "label": "Wallet Private Key",
18
+ "sensitive": true,
19
+ "placeholder": "0x... (optional — auto-generated)"
20
+ }
21
+ }
22
+ }