@t2000/serve 10.29.1 → 10.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -432,7 +432,7 @@ async function respond402(runtime, args) {
|
|
|
432
432
|
return void 0;
|
|
433
433
|
}
|
|
434
434
|
})();
|
|
435
|
-
const wwwAuth = `Payment realm="${host ?? "x402"}", recipient="${runtime.payTo}", currency="${runtime.currency}", amount="${args.priceUsdc}"`;
|
|
435
|
+
const wwwAuth = `Payment realm="${host ?? "x402"}", recipient="${runtime.payTo}", currency="${runtime.currency.type}", amount="${args.priceUsdc}"`;
|
|
436
436
|
return json(
|
|
437
437
|
402,
|
|
438
438
|
{
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/discovery.ts","../src/chain.ts","../src/route.ts","../src/store.ts","../src/serve.ts","../src/next.ts"],"names":["USDC_TESTNET","USDC","SuiGrpcClient","X402_PAYMENT_HEADER","X402_PAYMENT_RESPONSE_HEADER","result","isX402EscrowHeader","parseX402Header","verifyX402Payment","settleX402Payment","encodeX402Response","createX402Requirements","X402_VERSION","isValidSuiAddress","normalizeSuiAddress","InMemoryDigestStore"],"mappings":"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","file":"index.cjs","sourcesContent":["import { USDC, USDC_TESTNET } from '@t2000/sui-x402';\nimport type { Serve } from './serve.js';\n\n// ---------------------------------------------------------------------------\n// Discovery docs — /openapi.json + /llms.txt.\n//\n// The shapes here are what the on-chain listing probe grades (the check\n// behind `t2 agent sell`) (was: apps/gateway/lib/\n// catalog-ingest.ts `gradeListing`): a warning-free listing needs info.title,\n// a one-paragraph info.description, a flat string `x-payment-info.price` per\n// paid operation, and an application/json requestBody schema with typed\n// properties. Everything serve can derive is emitted automatically; the JSON\n// request schema comes from the route's `inputSchema` (zod v4 users:\n// `z.toJSONSchema(schema)`).\n// ---------------------------------------------------------------------------\n\nexport function buildOpenApiDocument(serve: Serve, origin?: string): Record<string, unknown> {\n const base = serve.baseUrl ?? origin;\n const paths: Record<string, unknown> = {};\n\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const operation: Record<string, unknown> = {\n operationId: path.replace(/[^a-zA-Z0-9]+/g, '_'),\n summary: description ?? path,\n responses: {\n '200': outputSchema\n ? {\n description: 'Success',\n content: { 'application/json': { schema: outputSchema } },\n }\n : { description: 'Success' },\n ...(priceUsdc\n ? {\n '402': {\n description:\n 'Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header.',\n },\n }\n : {}),\n '422': { description: 'Invalid request body — never charged' },\n },\n };\n if (priceUsdc) {\n // Same shape the gateway's own /openapi.json emits: 'mpp' is the\n // protocol family, 'x402' the dialect; the x402 block mirrors the\n // static half of the live accepts[] entry (dynamic fields ride the 402).\n operation['x-payment-info'] = {\n pricingMode: 'fixed',\n price: priceUsdc,\n currency: 'USDC',\n protocols: ['mpp', 'x402'],\n x402: {\n scheme: 'exact',\n network: `sui:${serve.network}`,\n asset: (serve.network === 'testnet' ? USDC_TESTNET : USDC).type,\n payTo: serve.payTo,\n },\n };\n }\n if (inputSchema) {\n operation.requestBody = {\n required: true,\n content: { 'application/json': { schema: inputSchema } },\n };\n }\n paths[`/${path}`] = { post: operation };\n }\n\n return {\n openapi: '3.1.0',\n info: {\n title: serve.name ?? 'Paid API',\n version: '1.0.0',\n description:\n serve.description ??\n 'Agent-payable API. Every paid endpoint answers 402 with an x402 accepts[] envelope; payment settles in USDC on Sui.',\n },\n ...(base ? { servers: [{ url: base }] } : {}),\n paths,\n };\n}\n\nexport function buildLlmsTxt(serve: Serve, origin?: string): string {\n const base = serve.baseUrl ?? origin ?? '';\n const lines: string[] = [];\n lines.push(`# ${serve.name ?? 'Paid API'}`);\n lines.push('');\n if (serve.description) {\n lines.push(serve.description);\n lines.push('');\n }\n lines.push('## How to pay');\n lines.push('');\n lines.push(\n 'Endpoints below are paid per call in USDC on Sui (x402). An unpaid request returns',\n 'HTTP 402 with an `accepts[]` envelope; sign it and retry with the `X-PAYMENT` header.',\n 'Invalid input returns 422 before any payment is taken. A failed call is never charged.',\n '',\n 'Easiest client: `npm i -g @t2000/cli` then `t2 pay <url> --data \\'{...}\\'`,',\n 'or the t2000 MCP server (`t2000_pay`), or `@t2000/sdk` `pay()`.',\n '',\n );\n lines.push('## Endpoints');\n lines.push('');\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const price = priceUsdc ? `${priceUsdc} USDC per call` : 'free';\n lines.push(`### POST ${base}/${path} — ${price}`);\n if (description) lines.push(description);\n if (inputSchema) {\n lines.push('Request body (JSON Schema):');\n lines.push('```json');\n lines.push(JSON.stringify(inputSchema, null, 2));\n lines.push('```');\n }\n if (outputSchema) {\n lines.push('Response (JSON Schema — contentMediaType/format annotations name the deliverable types):');\n lines.push('```json');\n lines.push(JSON.stringify(outputSchema, null, 2));\n lines.push('```');\n }\n lines.push('');\n }\n lines.push(`Discovery: ${base}/openapi.json`);\n return lines.join('\\n');\n}\n","import { SuiGrpcClient } from '@mysten/sui/grpc';\nimport type { ServeNetwork } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Chain plumbing — same shape as the gateway's x402-dialect.ts (the reference\n// composition). All reads are gRPC; this package never touches JSON-RPC.\n//\n// Cache policy: the chain identifier (genesis digest) is immutable per\n// network — cached forever. The epoch advances ~daily and x402 requirements\n// are valid for [epoch, epoch+1], so a 10-minute TTL is conservatively fresh.\n// ---------------------------------------------------------------------------\n\nconst FULLNODE_URLS: Record<ServeNetwork, string> = {\n mainnet: 'https://fullnode.mainnet.sui.io:443',\n testnet: 'https://fullnode.testnet.sui.io:443',\n};\n\nconst EPOCH_TTL_MS = 10 * 60 * 1000;\n\nexport interface ChainInfo {\n chain: string;\n epoch: string;\n}\n\ninterface ChainState {\n client?: SuiGrpcClient;\n chainId?: string;\n epoch?: { value: string; fetchedAt: number };\n}\n\nconst state: Partial<Record<ServeNetwork, ChainState>> = {};\n\nexport function getGrpcClient(network: ServeNetwork, rpcUrl?: string): SuiGrpcClient {\n const s = (state[network] ??= {});\n if (!s.client) {\n s.client = new SuiGrpcClient({\n baseUrl: rpcUrl ?? FULLNODE_URLS[network],\n network,\n });\n }\n return s.client;\n}\n\nexport async function getChainInfo(network: ServeNetwork, rpcUrl?: string): Promise<ChainInfo> {\n const client = getGrpcClient(network, rpcUrl);\n const s = (state[network] ??= {});\n if (!s.chainId) {\n const res = await client.core.getChainIdentifier();\n s.chainId = res.chainIdentifier;\n }\n if (!s.epoch || Date.now() - s.epoch.fetchedAt > EPOCH_TTL_MS) {\n const res = await client.core.getCurrentSystemState();\n s.epoch = { value: String(res.systemState.epoch), fetchedAt: Date.now() };\n }\n return { chain: s.chainId, epoch: s.epoch.value };\n}\n\n/** Test seam — reset module caches between cases. */\nexport function __resetChainCaches(): void {\n delete state.mainnet;\n delete state.testnet;\n}\n\n/** Test seam — pre-seed chain info so tests never hit the network. */\nexport function __seedChainInfo(network: ServeNetwork, chain: string, epoch: string): void {\n const s = (state[network] ??= {});\n s.chainId = chain;\n s.epoch = { value: epoch, fetchedAt: Date.now() };\n}\n","import type { Currency, DigestStore } from '@t2000/sui-x402';\nimport {\n createX402Requirements,\n encodeX402Response,\n isX402EscrowHeader,\n parseX402Header,\n settleX402Payment,\n verifyX402Payment,\n X402_PAYMENT_HEADER,\n X402_PAYMENT_RESPONSE_HEADER,\n X402_VERSION,\n type X402SettleResponse,\n} from '@t2000/sui-x402';\nimport { getChainInfo, getGrpcClient } from './chain.js';\nimport type {\n BuiltRoute,\n HandlerContext,\n HandlerResult,\n ServeNetwork,\n ServeSchema,\n StandardSchemaLike,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// The paid-request lifecycle (SPEC_T2000_SERVE §3 — sign-then-settle,\n// handler-then-settle):\n//\n// no X-PAYMENT → 402 with the accepts[] envelope (never a charge;\n// the catalog probe and every discovery tool read\n// this, so it fires BEFORE body validation)\n// X-PAYMENT present:\n// 1. parse + STRUCTURAL verify (right amount/recipient/nonce — no RPC)\n// 2. challenge-once check (a signed payload is single-use)\n// 3. validate the body — invalid → 422, payment NEVER submitted\n// (the JMPR paid-422 class is impossible: the buyer keeps their money)\n// 4. run the handler — throws → 500, payment NEVER submitted\n// 5. settle (submit the buyer-signed gasless bytes; digest-once inside)\n// 6. consume the challenge, attach the X-PAYMENT-RESPONSE receipt\n//\n// Money only moves at step 5, after the seller has already produced the\n// result. A forged payload can waste seller compute (signature authority is\n// the chain at settle time), never buyer money.\n// ---------------------------------------------------------------------------\n\nexport interface RouteRuntime {\n payTo: string;\n network: ServeNetwork;\n currency: Currency;\n store: DigestStore;\n baseUrl?: string;\n rpcUrl?: string;\n /** B2 attributed reporting — unset = no report (see ServeConfig). */\n activityReportUrl?: string;\n}\n\nexport interface RouteOptions {\n path: string;\n description?: string;\n}\n\n/** Sanity cap on a per-call price — above this, the work is job-shaped\n * (escrow) rather than a per-call x402 Service. */\nconst CATALOG_PRICE_CAP_USDC = 5;\n\nconst CORS_HEADERS: Record<string, string> = {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'access-control-allow-headers': `content-type, ${X402_PAYMENT_HEADER}`,\n 'access-control-expose-headers': `${X402_PAYMENT_RESPONSE_HEADER}, WWW-Authenticate`,\n};\n\nfunction withCors(response: Response): Response {\n const headers = new Headers(response.headers);\n for (const [k, v] of Object.entries(CORS_HEADERS)) headers.set(k, v);\n return new Response(response.body, { status: response.status, headers });\n}\n\nfunction json(status: number, body: unknown, headers?: Record<string, string>): Response {\n return withCors(\n new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json', ...headers },\n }),\n );\n}\n\nfunction isStandardSchema(schema: ServeSchema): schema is StandardSchemaLike {\n return typeof schema === 'object' && schema !== null && '~standard' in schema;\n}\n\nasync function validateBody(\n schema: ServeSchema,\n value: unknown,\n): Promise<{ ok: true; data: unknown } | { ok: false; message: string }> {\n if (isStandardSchema(schema)) {\n const result = await schema['~standard'].validate(value);\n if (result.issues) {\n // Name the failing field — bare \"Invalid input\" ×N gives a paying\n // buyer's agent nothing to self-correct with.\n const message = result.issues\n .map((i) => {\n const path = (i.path ?? [])\n .map((seg) => (typeof seg === 'object' ? String(seg.key) : String(seg)))\n .join('.');\n return path ? `${path}: ${i.message}` : i.message;\n })\n .join('; ');\n return { ok: false, message };\n }\n return { ok: true, data: result.value };\n }\n const result = schema.safeParse(value);\n if (!result.success) {\n return { ok: false, message: result.error.message ?? 'invalid body' };\n }\n return { ok: true, data: result.data };\n}\n\n/** Positive decimal USDC string, max 6dp (atomic precision). */\nfunction assertValidPrice(price: string, path: string): void {\n if (!/^\\d+(\\.\\d{1,6})?$/.test(price) || Number(price) <= 0) {\n throw new Error(\n `[serve] Route \"${path}\": price must be a positive decimal USDC string with up to 6 decimals, got \"${price}\"`,\n );\n }\n if (Number(price) > CATALOG_PRICE_CAP_USDC) {\n console.warn(\n `[serve] Route \"${path}\": price ${price} USDC is above the ${CATALOG_PRICE_CAP_USDC} USDC listing cap — ` +\n 'the route works, but per-call x402 is the wrong shape for it. Job-class work belongs in `t2 service create` (escrow).',\n );\n }\n}\n\nexport class RouteBuilder<TBody = undefined> {\n private priceUsdc?: string;\n private bodySchema?: ServeSchema;\n private inputSchema?: Record<string, unknown>;\n private outputSchema?: Record<string, unknown>;\n private isFree = false;\n\n constructor(\n private readonly runtime: RouteRuntime,\n private readonly options: RouteOptions,\n private readonly register: (route: BuiltRoute) => void,\n ) {}\n\n /** Charge this many USDC per call (human units, e.g. \"0.01\"). */\n paid(priceUsdc: string): this {\n assertValidPrice(priceUsdc, this.options.path);\n this.priceUsdc = priceUsdc;\n this.isFree = false;\n return this;\n }\n\n /** Serve without payment (health checks, previews, docs). */\n unprotected(): this {\n this.isFree = true;\n this.priceUsdc = undefined;\n return this;\n }\n\n /**\n * Validate the JSON request body. zod v4 / valibot / arktype / anything\n * Standard-Schema, or anything with a zod-style safeParse.\n *\n * Pass the JSON Schema as the second argument to publish it in\n * /openapi.json + /llms.txt (zod v4: `z.toJSONSchema(schema)`) — buyers'\n * agents build request bodies from it, and the catalog grades listings\n * without one.\n */\n body<T>(schema: ServeSchema<T>, jsonSchema?: Record<string, unknown>): RouteBuilder<T> {\n this.bodySchema = schema;\n this.inputSchema = jsonSchema;\n return this as unknown as RouteBuilder<T>;\n }\n\n /**\n * Declare the 200 response's JSON Schema (zod v4: `z.toJSONSchema(schema)`).\n * Published in /openapi.json + /llms.txt so buyer agents know what they're\n * buying and buyer UIs can render the deliverable by TYPE instead of\n * sniffing it — annotate with `contentMediaType` (e.g. \"image/svg+xml\",\n * \"text/markdown\") and `format: \"color\"` where they apply. Declaration\n * only; responses are never validated at runtime.\n */\n response(jsonSchema: Record<string, unknown>): this {\n this.outputSchema = jsonSchema;\n return this;\n }\n\n handler(fn: (ctx: HandlerContext<TBody>) => HandlerResult | Promise<HandlerResult>): BuiltRoute {\n if (!this.isFree && !this.priceUsdc) {\n throw new Error(\n `[serve] Route \"${this.options.path}\": call .paid('<usdc>') or .unprotected() before .handler()`,\n );\n }\n const runtime = this.runtime;\n const { path, description } = this.options;\n const priceUsdc = this.priceUsdc;\n const bodySchema = this.bodySchema;\n\n const route = (async (req: Request): Promise<Response> => {\n if (req.method === 'OPTIONS') {\n return withCors(new Response(null, { status: 204 }));\n }\n\n // Read + parse the body once, up front. A missing/empty body on a\n // schema-less route is fine; JSON parse failures only matter when a\n // paid request must be validated (the unpaid 402 fires regardless).\n let parsedBody: unknown;\n let bodyParseError: string | undefined;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n const text = await req.text();\n if (text.trim().length > 0) {\n try {\n parsedBody = JSON.parse(text);\n } catch {\n bodyParseError = 'request body is not valid JSON';\n }\n }\n }\n\n const resource = (runtime.baseUrl ?? new URL(req.url).origin).replace(/\\/$/, '') + `/${path}`;\n\n const runHandler = async (payer?: string): Promise<Response> => {\n let validated: unknown = parsedBody;\n if (bodySchema) {\n // `paid: false` is machine-readable charge honesty — a 422 fires\n // BEFORE settlement, so the buyer always keeps their money.\n if (bodyParseError) {\n return json(422, { error: bodyParseError, paid: false });\n }\n const result = await validateBody(bodySchema, parsedBody ?? {});\n if (!result.ok) {\n return json(422, { error: result.message, paid: false });\n }\n validated = result.data;\n }\n const out = await fn({ body: validated as TBody, req, payer });\n if (out instanceof Response) return withCors(out);\n return json(200, out);\n };\n\n // Free route — no payment machinery at all.\n if (!priceUsdc) {\n try {\n return await runHandler();\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed:`, err);\n return json(500, { error: 'internal error' });\n }\n }\n\n const paymentHeader = req.headers.get(X402_PAYMENT_HEADER);\n\n // Unpaid → 402 with the accepts[] envelope. This fires before body\n // validation on purpose: the catalog probe (and every discovery tool)\n // POSTs `{}` and must see the challenge, and an unpaid request can\n // never be charged, so there is nothing to protect yet.\n if (!paymentHeader) {\n return await respond402(runtime, { resource, priceUsdc });\n }\n\n if (isX402EscrowHeader(paymentHeader)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error:\n 'this endpoint sells instant per-call work (settle-then-serve), not escrow jobs — retry with a signed x402 payment',\n });\n }\n\n // 1. Parse + structural verify — right terms, right recipient, right\n // nonce. No RPC, no state. Wrong-terms payloads never reach the\n // handler.\n let payment: ReturnType<typeof parseX402Header>;\n try {\n payment = parseX402Header(paymentHeader);\n verifyX402Payment({\n payment,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `invalid payment: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 2. Challenge-once — a signed payload is single-use even before it\n // settles (the settled digest is separately consumed inside\n // settleX402Payment, digest-once).\n const challengeKey = `challenge:${payment.payload.challengeId}`;\n if (await runtime.store.has(challengeKey)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: 'payment challenge already used — sign a fresh payment',\n });\n }\n\n // 3 + 4. Validate, then compute the result. Any failure here returns\n // WITHOUT settling — the buyer-signed bytes are never submitted.\n let served: Response;\n try {\n served = await runHandler(payment.payload.senderAddress);\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed (payment NOT settled):`, err);\n return json(500, { error: 'internal error — you were not charged' });\n }\n if (served.status >= 400) return served; // 422 etc. — not charged\n\n // 5. Settle — submit the buyer-signed gasless bytes, confirm the\n // on-chain balance change, record the digest (digest-once).\n let settle: X402SettleResponse;\n try {\n settle = await settleX402Payment({\n payment,\n client: getGrpcClient(runtime.network, runtime.rpcUrl),\n store: runtime.store,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `settlement failed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 6. Consume the challenge + attach the receipt.\n try {\n await runtime.store.set(challengeKey);\n } catch {\n // Digest-once already holds; challenge-once is defense in depth.\n }\n\n // B2: attributed activity report — AFTER a successful settle only,\n // strictly fire-and-forget (a dead report can never change the\n // buyer's 200 or the settle; SPEC_T2_ACTIVITY_X402 §7 lock 6).\n reportActivity(runtime, {\n digest: settle.transaction,\n payer: settle.payer,\n priceUsdc,\n resource,\n });\n\n const headers = new Headers(served.headers);\n headers.set(X402_PAYMENT_RESPONSE_HEADER, encodeX402Response(settle));\n return new Response(served.body, { status: served.status, headers });\n }) as BuiltRoute;\n\n route.meta = {\n path,\n priceUsdc,\n description,\n bodySchema,\n inputSchema: this.inputSchema,\n outputSchema: this.outputSchema,\n };\n this.register(route);\n return route;\n }\n}\n\n/** Fire-and-forget x402.paid report (B2). Never awaited into the response\n * path; short timeout; every failure swallowed. The report endpoint\n * chain-verifies the digest, so this carries claims, not trust. */\nfunction reportActivity(\n runtime: RouteRuntime,\n args: { digest: string; payer: string; priceUsdc: string; resource: string },\n): void {\n const url = runtime.activityReportUrl;\n if (!url) return;\n try {\n void fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n digest: args.digest,\n payTo: runtime.payTo,\n payer: args.payer,\n amountMicroUsdc: Math.round(Number(args.priceUsdc) * 1_000_000),\n network: `sui:${runtime.network}`,\n route: args.resource,\n source: 'serve',\n }),\n signal: AbortSignal.timeout(1500),\n }).catch(() => undefined);\n } catch {\n // even a sync throw (bad URL) must not touch the buyer's response\n }\n}\n\nasync function respond402(\n runtime: RouteRuntime,\n args: { resource: string; priceUsdc: string; error?: string },\n): Promise<Response> {\n try {\n const { chain, epoch } = await getChainInfo(runtime.network, runtime.rpcUrl);\n const requirements = createX402Requirements({\n challengeId: crypto.randomUUID(),\n amount: args.priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n resource: args.resource,\n network: runtime.network,\n chain,\n currentEpoch: epoch,\n });\n // Belt-and-suspenders for pre-0.2.2 discovery clients and dual-dialect\n // consumers: mirror the challenge into the MPP WWW-Authenticate shape.\n // The accepts[] body stays the authoritative envelope — the header carries\n // the same recipient/currency and the DECIMAL amount that dialect uses.\n const host = (() => {\n try {\n return new URL(args.resource).hostname;\n } catch {\n return undefined;\n }\n })();\n const wwwAuth = `Payment realm=\"${host ?? 'x402'}\", recipient=\"${runtime.payTo}\", currency=\"${runtime.currency}\", amount=\"${args.priceUsdc}\"`;\n return json(\n 402,\n {\n x402Version: X402_VERSION,\n error: args.error ?? 'Payment required',\n accepts: [requirements],\n },\n { 'WWW-Authenticate': wwwAuth },\n );\n } catch (err) {\n // Chain info unreachable — a 402 without the envelope is unpayable, so\n // be honest about the outage instead of serving a dead challenge.\n console.error('[serve] failed to build 402 challenge:', err);\n return json(503, { error: 'payment challenge temporarily unavailable' });\n }\n}\n\n","import type { DigestStore } from '@t2000/sui-x402';\n\nexport { InMemoryDigestStore } from '@t2000/sui-x402';\nexport type { DigestStore } from '@t2000/sui-x402';\n\n// ---------------------------------------------------------------------------\n// Upstash-REST digest store — the production replay store for serverless\n// hosts. Mirrors the gateway's upstash-digest-store.ts but speaks the\n// Upstash REST API over plain fetch (no @upstash/redis dependency).\n//\n// TTL: 72h. x402 payments are chain-valid for the whole ValidDuring window\n// ([minEpoch, minEpoch+1] ≈ up to ~48h on mainnet). Sui resubmission of an\n// executed tx is idempotent, so if the digest/challenge keys expired BEFORE\n// the window closed, a replayed X-PAYMENT would re-settle \"successfully\"\n// and serve again on a single payment. 72h > max window + drift.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 72 * 60 * 60;\nconst PREFIX = 'serve:digest:';\n\nexport interface UpstashDigestStoreOptions {\n url: string;\n token: string;\n /** Key TTL in seconds. Default 72h — do not lower below ~50h (see above). */\n ttlSeconds?: number;\n}\n\nexport class UpstashDigestStore implements DigestStore {\n private readonly url: string;\n private readonly token: string;\n private readonly ttlSeconds: number;\n\n constructor(options: UpstashDigestStoreOptions) {\n this.url = options.url.replace(/\\/$/, '');\n this.token = options.token;\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n }\n\n private async command(segments: string[]): Promise<unknown> {\n const res = await fetch(`${this.url}/${segments.map(encodeURIComponent).join('/')}`, {\n headers: { authorization: `Bearer ${this.token}` },\n });\n if (!res.ok) {\n throw new Error(`Upstash command failed: ${res.status} ${await res.text()}`);\n }\n const body = (await res.json()) as { result?: unknown; error?: string };\n if (body.error) throw new Error(`Upstash error: ${body.error}`);\n return body.result;\n }\n\n async has(digest: string): Promise<boolean> {\n const result = await this.command(['GET', PREFIX + digest]);\n return result !== null && result !== undefined;\n }\n\n async set(digest: string): Promise<void> {\n // SET key 1 EX <ttl> NX — atomic set-if-absent. A null result means the\n // key already existed: the digest (or challenge) was already consumed.\n const result = await this.command([\n 'SET',\n PREFIX + digest,\n '1',\n 'EX',\n String(this.ttlSeconds),\n 'NX',\n ]);\n if (result === null || result === undefined) {\n throw new Error(`Digest already used: ${digest}`);\n }\n }\n}\n","import { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { InMemoryDigestStore, USDC, USDC_TESTNET, type Currency } from '@t2000/sui-x402';\nimport { buildLlmsTxt, buildOpenApiDocument } from './discovery.js';\nimport { RouteBuilder, type RouteOptions, type RouteRuntime } from './route.js';\nimport { UpstashDigestStore } from './store.js';\nimport type { BuiltRoute, ServeConfig, ServeNetwork } from './types.js';\n\n/** The t2000.ai attributed-activity report endpoint — ONE canonical string\n * (matches the sdk's DEFAULT_ACTIVITY_REPORT_URL; tests assert equality). */\nexport const DEFAULT_ACTIVITY_REPORT_URL = 'https://t2000.ai/api/activity/x402';\n\n/** Explicit opt-out tokens for T2000_ACTIVITY_REPORT_URL (case-insensitive). */\nconst REPORT_OPT_OUT = new Set(['false', '0', 'off', 'none']);\n\nexport class Serve {\n private readonly runtime: RouteRuntime;\n /** Every route built through this instance, keyed by path (discovery). */\n readonly routes = new Map<string, BuiltRoute>();\n\n readonly payTo: string;\n readonly network: ServeNetwork;\n readonly name?: string;\n readonly description?: string;\n readonly baseUrl?: string;\n /** Where settled payments are reported (B2) — undefined = no report. */\n readonly activityReportUrl?: string;\n\n constructor(config: ServeConfig) {\n if (!config.payTo || !isValidSuiAddress(config.payTo)) {\n throw new Error(\n `[serve] payTo must be a valid Sui address (the wallet your payments settle to), got \"${config.payTo}\"`,\n );\n }\n this.payTo = normalizeSuiAddress(config.payTo);\n this.network = config.network ?? 'mainnet';\n this.name = config.name;\n this.description = config.description;\n this.baseUrl = config.baseUrl?.replace(/\\/$/, '');\n this.activityReportUrl = config.activityReportUrl;\n\n const currency: Currency = this.network === 'testnet' ? USDC_TESTNET : USDC;\n this.runtime = {\n payTo: this.payTo,\n network: this.network,\n currency,\n store: config.store ?? new InMemoryDigestStore(),\n baseUrl: this.baseUrl,\n rpcUrl: config.rpcUrl,\n activityReportUrl: this.activityReportUrl,\n };\n }\n\n /** Start building a route. Chain `.paid()` / `.body()` / `.handler()`. */\n route(options: RouteOptions): RouteBuilder {\n const path = options.path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!path) throw new Error('[serve] route path must be non-empty');\n return new RouteBuilder({ ...this.runtime }, { ...options, path }, (route) => {\n this.routes.set(path, route);\n });\n }\n\n /**\n * Discovery: GET handler for /openapi.json. OpenAPI 3.1 with the\n * `x-payment-info` pricing extension on every paid operation — the shape\n * x402 tooling (and any catalog built on it) indexes.\n *\n * export const GET = serve.openapi(); // app/openapi.json/route.ts\n */\n openapi(): (req: Request) => Response {\n return (req: Request) =>\n new Response(JSON.stringify(buildOpenApiDocument(this, new URL(req.url).origin), null, 2), {\n headers: { 'content-type': 'application/json', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * Discovery: GET handler for /llms.txt — plain-text guidance agents read\n * to understand what the API sells, what it costs, and how to pay.\n *\n * export const GET = serve.llms(); // app/llms.txt/route.ts\n */\n llms(): (req: Request) => Response {\n return (req: Request) =>\n new Response(buildLlmsTxt(this, new URL(req.url).origin), {\n headers: { 'content-type': 'text/plain; charset=utf-8', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * One fetch handler for the whole app — routes + discovery docs. For\n * fetch-native runtimes (Bun.serve, Deno.serve, Hono, Cloudflare Workers):\n *\n * Bun.serve({ fetch: serve.fetch });\n * app.all('*', (c) => serve.fetch(c.req.raw)); // Hono\n *\n * Next.js apps can skip this and export route handlers directly.\n */\n readonly fetch = async (req: Request): Promise<Response> => {\n const pathname = new URL(req.url).pathname.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (pathname === 'openapi.json') return this.openapi()(req);\n if (pathname === 'llms.txt') return this.llms()(req);\n const route = this.routes.get(pathname);\n if (route) return route(req);\n return new Response(\n JSON.stringify({ error: 'not found', discovery: ['/openapi.json', '/llms.txt'] }),\n { status: 404, headers: { 'content-type': 'application/json' } },\n );\n };\n\n /**\n * The command that sells this API as an x402 Service on your Agent ID,\n * once it is deployed. Listing is a separate, explicit step: the endpoint\n * is live-probed (it must answer 402 with a Sui challenge that pays YOUR\n * wallet) and then recorded on-chain, sponsored and gasless.\n *\n * This used to emit curls against the hosted mpp.t2000.ai catalog. That\n * proxy mall was purged 2026-08-01 (SPEC_T2_CLEANUP_USDC_ONLY) — there is\n * no central catalog to submit to. Your Agent ID IS the listing, and\n * buyers find it with `t2 services`.\n */\n catalogSubmitCommand(deployedUrl?: string): string {\n const base = (deployedUrl ?? this.baseUrl ?? 'https://<your-deployed-app>').replace(/\\/$/, '');\n const paidPaths = [...this.routes.values()].filter((r) => r.meta.priceUsdc);\n const example = paidPaths[0]?.meta.path ?? '<route>';\n return [\n '# Sell it as an x402 Service on your Agent ID (live-probed, gasless):',\n `npx @t2000/cli agent sell ${base}/${example}`,\n '# Buyers then find it with `t2 services` and pay per call with `t2 pay`.',\n ].join('\\n');\n }\n}\n\nexport function createServe(config: ServeConfig): Serve {\n return new Serve(config);\n}\n\n/**\n * Build a Serve from environment variables — the template-app path where\n * config lives in the host's env UI, not code.\n *\n * T2000_PAY_TO required — the seller's Sui address\n * T2000_NETWORK optional — 'mainnet' (default) | 'testnet'\n * T2000_BASE_URL optional — public URL of the deployed app\n * T2000_NAME optional — service name for discovery docs\n * T2000_DESCRIPTION optional — one-liner for discovery docs\n * T2000_ACTIVITY_REPORT_URL\n * optional — where settled payments are reported\n * (fire-and-forget x402.paid after each successful settle;\n * chain-verified server-side, never affects buyer\n * responses). DEFAULT-ON for FromEnv: unset →\n * https://t2000.ai/api/activity/x402 so new sellers appear\n * on the t2000.ai activity tape. Opt out with\n * `false` | `0` | `off` | `none` (case-insensitive), or\n * set a custom URL. (`new Serve({...})` without\n * activityReportUrl stays silent — only FromEnv defaults.)\n * KV_REST_API_URL / KV_REST_API_TOKEN\n * optional — enables the durable Upstash replay store\n * (REQUIRED in serverless production; without it replay\n * state is per-instance memory)\n *\n * Empty strings are treated as unset (the Vercel empty-env bug class).\n */\nexport function createServeFromEnv(env: Record<string, string | undefined> = process.env): Serve {\n const read = (key: string): string | undefined => {\n const v = env[key]?.trim();\n return v && v.length > 0 ? v : undefined;\n };\n\n const payTo = read('T2000_PAY_TO');\n if (!payTo) {\n throw new Error(\n '[serve] T2000_PAY_TO is not set (or is empty). Set it to the Sui address your payments should settle to — `t2 address` prints yours.',\n );\n }\n\n const network = read('T2000_NETWORK');\n if (network && network !== 'mainnet' && network !== 'testnet') {\n throw new Error(`[serve] T2000_NETWORK must be 'mainnet' or 'testnet', got \"${network}\"`);\n }\n\n const kvUrl = read('KV_REST_API_URL');\n const kvToken = read('KV_REST_API_TOKEN');\n const store =\n kvUrl && kvToken ? new UpstashDigestStore({ url: kvUrl, token: kvToken }) : undefined;\n\n if (!store) {\n console.warn(\n '[serve] No KV_REST_API_URL/KV_REST_API_TOKEN — using the in-memory replay store. ' +\n 'Fine for a single long-lived process; on serverless hosts set both so replay protection is durable.',\n );\n }\n\n return new Serve({\n payTo,\n network: (network as ServeNetwork | undefined) ?? 'mainnet',\n baseUrl: read('T2000_BASE_URL'),\n name: read('T2000_NAME'),\n description: read('T2000_DESCRIPTION'),\n activityReportUrl: resolveReportUrlFromEnv(read('T2000_ACTIVITY_REPORT_URL')),\n store,\n });\n}\n\n/** FromEnv activity-report resolution (B2 default-on): unset/empty →\n * the t2000.ai default; an explicit opt-out token → undefined (silent);\n * anything else is the seller's custom report URL. */\nfunction resolveReportUrlFromEnv(raw: string | undefined): string | undefined {\n if (raw === undefined) return DEFAULT_ACTIVITY_REPORT_URL;\n if (REPORT_OPT_OUT.has(raw.toLowerCase())) return undefined;\n return raw;\n}\n","import type { BuiltRoute } from './types.js';\n\n/**\n * Export a built route the way Next.js App Router needs it.\n *\n * Next dispatches ONLY the methods a route.ts exports — serve's own CORS\n * handling (OPTIONS → 204 with the ACAO headers) never runs if the file\n * exports just `POST`: the browser preflight gets Next's bare 204 with no\n * CORS headers, and every browser buyer (Passport, the store's Try it)\n * fails while CLI/server buyers — who never preflight — work fine. Fetch\n * runtimes mounted via a single handler (`serve.fetch`-style) don't have\n * this hole; it is a Next export contract, not a serve one.\n *\n * export const { POST, OPTIONS } = asNextRoute(\n * serve.route({ path: 'haiku' }).paid('0.01').handler(fn),\n * );\n */\nexport function asNextRoute(route: BuiltRoute): {\n POST: BuiltRoute;\n OPTIONS: BuiltRoute;\n} {\n return { POST: route, OPTIONS: route };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/discovery.ts","../src/chain.ts","../src/route.ts","../src/store.ts","../src/serve.ts","../src/next.ts"],"names":["USDC_TESTNET","USDC","SuiGrpcClient","X402_PAYMENT_HEADER","X402_PAYMENT_RESPONSE_HEADER","result","isX402EscrowHeader","parseX402Header","verifyX402Payment","settleX402Payment","encodeX402Response","createX402Requirements","X402_VERSION","isValidSuiAddress","normalizeSuiAddress","InMemoryDigestStore"],"mappings":"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","file":"index.cjs","sourcesContent":["import { USDC, USDC_TESTNET } from '@t2000/sui-x402';\nimport type { Serve } from './serve.js';\n\n// ---------------------------------------------------------------------------\n// Discovery docs — /openapi.json + /llms.txt.\n//\n// The shapes here are what the on-chain listing probe grades (the check\n// behind `t2 agent sell`) (was: apps/gateway/lib/\n// catalog-ingest.ts `gradeListing`): a warning-free listing needs info.title,\n// a one-paragraph info.description, a flat string `x-payment-info.price` per\n// paid operation, and an application/json requestBody schema with typed\n// properties. Everything serve can derive is emitted automatically; the JSON\n// request schema comes from the route's `inputSchema` (zod v4 users:\n// `z.toJSONSchema(schema)`).\n// ---------------------------------------------------------------------------\n\nexport function buildOpenApiDocument(serve: Serve, origin?: string): Record<string, unknown> {\n const base = serve.baseUrl ?? origin;\n const paths: Record<string, unknown> = {};\n\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const operation: Record<string, unknown> = {\n operationId: path.replace(/[^a-zA-Z0-9]+/g, '_'),\n summary: description ?? path,\n responses: {\n '200': outputSchema\n ? {\n description: 'Success',\n content: { 'application/json': { schema: outputSchema } },\n }\n : { description: 'Success' },\n ...(priceUsdc\n ? {\n '402': {\n description:\n 'Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header.',\n },\n }\n : {}),\n '422': { description: 'Invalid request body — never charged' },\n },\n };\n if (priceUsdc) {\n // Same shape the gateway's own /openapi.json emits: 'mpp' is the\n // protocol family, 'x402' the dialect; the x402 block mirrors the\n // static half of the live accepts[] entry (dynamic fields ride the 402).\n operation['x-payment-info'] = {\n pricingMode: 'fixed',\n price: priceUsdc,\n currency: 'USDC',\n protocols: ['mpp', 'x402'],\n x402: {\n scheme: 'exact',\n network: `sui:${serve.network}`,\n asset: (serve.network === 'testnet' ? USDC_TESTNET : USDC).type,\n payTo: serve.payTo,\n },\n };\n }\n if (inputSchema) {\n operation.requestBody = {\n required: true,\n content: { 'application/json': { schema: inputSchema } },\n };\n }\n paths[`/${path}`] = { post: operation };\n }\n\n return {\n openapi: '3.1.0',\n info: {\n title: serve.name ?? 'Paid API',\n version: '1.0.0',\n description:\n serve.description ??\n 'Agent-payable API. Every paid endpoint answers 402 with an x402 accepts[] envelope; payment settles in USDC on Sui.',\n },\n ...(base ? { servers: [{ url: base }] } : {}),\n paths,\n };\n}\n\nexport function buildLlmsTxt(serve: Serve, origin?: string): string {\n const base = serve.baseUrl ?? origin ?? '';\n const lines: string[] = [];\n lines.push(`# ${serve.name ?? 'Paid API'}`);\n lines.push('');\n if (serve.description) {\n lines.push(serve.description);\n lines.push('');\n }\n lines.push('## How to pay');\n lines.push('');\n lines.push(\n 'Endpoints below are paid per call in USDC on Sui (x402). An unpaid request returns',\n 'HTTP 402 with an `accepts[]` envelope; sign it and retry with the `X-PAYMENT` header.',\n 'Invalid input returns 422 before any payment is taken. A failed call is never charged.',\n '',\n 'Easiest client: `npm i -g @t2000/cli` then `t2 pay <url> --data \\'{...}\\'`,',\n 'or the t2000 MCP server (`t2000_pay`), or `@t2000/sdk` `pay()`.',\n '',\n );\n lines.push('## Endpoints');\n lines.push('');\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const price = priceUsdc ? `${priceUsdc} USDC per call` : 'free';\n lines.push(`### POST ${base}/${path} — ${price}`);\n if (description) lines.push(description);\n if (inputSchema) {\n lines.push('Request body (JSON Schema):');\n lines.push('```json');\n lines.push(JSON.stringify(inputSchema, null, 2));\n lines.push('```');\n }\n if (outputSchema) {\n lines.push('Response (JSON Schema — contentMediaType/format annotations name the deliverable types):');\n lines.push('```json');\n lines.push(JSON.stringify(outputSchema, null, 2));\n lines.push('```');\n }\n lines.push('');\n }\n lines.push(`Discovery: ${base}/openapi.json`);\n return lines.join('\\n');\n}\n","import { SuiGrpcClient } from '@mysten/sui/grpc';\nimport type { ServeNetwork } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Chain plumbing — same shape as the gateway's x402-dialect.ts (the reference\n// composition). All reads are gRPC; this package never touches JSON-RPC.\n//\n// Cache policy: the chain identifier (genesis digest) is immutable per\n// network — cached forever. The epoch advances ~daily and x402 requirements\n// are valid for [epoch, epoch+1], so a 10-minute TTL is conservatively fresh.\n// ---------------------------------------------------------------------------\n\nconst FULLNODE_URLS: Record<ServeNetwork, string> = {\n mainnet: 'https://fullnode.mainnet.sui.io:443',\n testnet: 'https://fullnode.testnet.sui.io:443',\n};\n\nconst EPOCH_TTL_MS = 10 * 60 * 1000;\n\nexport interface ChainInfo {\n chain: string;\n epoch: string;\n}\n\ninterface ChainState {\n client?: SuiGrpcClient;\n chainId?: string;\n epoch?: { value: string; fetchedAt: number };\n}\n\nconst state: Partial<Record<ServeNetwork, ChainState>> = {};\n\nexport function getGrpcClient(network: ServeNetwork, rpcUrl?: string): SuiGrpcClient {\n const s = (state[network] ??= {});\n if (!s.client) {\n s.client = new SuiGrpcClient({\n baseUrl: rpcUrl ?? FULLNODE_URLS[network],\n network,\n });\n }\n return s.client;\n}\n\nexport async function getChainInfo(network: ServeNetwork, rpcUrl?: string): Promise<ChainInfo> {\n const client = getGrpcClient(network, rpcUrl);\n const s = (state[network] ??= {});\n if (!s.chainId) {\n const res = await client.core.getChainIdentifier();\n s.chainId = res.chainIdentifier;\n }\n if (!s.epoch || Date.now() - s.epoch.fetchedAt > EPOCH_TTL_MS) {\n const res = await client.core.getCurrentSystemState();\n s.epoch = { value: String(res.systemState.epoch), fetchedAt: Date.now() };\n }\n return { chain: s.chainId, epoch: s.epoch.value };\n}\n\n/** Test seam — reset module caches between cases. */\nexport function __resetChainCaches(): void {\n delete state.mainnet;\n delete state.testnet;\n}\n\n/** Test seam — pre-seed chain info so tests never hit the network. */\nexport function __seedChainInfo(network: ServeNetwork, chain: string, epoch: string): void {\n const s = (state[network] ??= {});\n s.chainId = chain;\n s.epoch = { value: epoch, fetchedAt: Date.now() };\n}\n","import type { Currency, DigestStore } from '@t2000/sui-x402';\nimport {\n createX402Requirements,\n encodeX402Response,\n isX402EscrowHeader,\n parseX402Header,\n settleX402Payment,\n verifyX402Payment,\n X402_PAYMENT_HEADER,\n X402_PAYMENT_RESPONSE_HEADER,\n X402_VERSION,\n type X402SettleResponse,\n} from '@t2000/sui-x402';\nimport { getChainInfo, getGrpcClient } from './chain.js';\nimport type {\n BuiltRoute,\n HandlerContext,\n HandlerResult,\n ServeNetwork,\n ServeSchema,\n StandardSchemaLike,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// The paid-request lifecycle (SPEC_T2000_SERVE §3 — sign-then-settle,\n// handler-then-settle):\n//\n// no X-PAYMENT → 402 with the accepts[] envelope (never a charge;\n// the catalog probe and every discovery tool read\n// this, so it fires BEFORE body validation)\n// X-PAYMENT present:\n// 1. parse + STRUCTURAL verify (right amount/recipient/nonce — no RPC)\n// 2. challenge-once check (a signed payload is single-use)\n// 3. validate the body — invalid → 422, payment NEVER submitted\n// (the JMPR paid-422 class is impossible: the buyer keeps their money)\n// 4. run the handler — throws → 500, payment NEVER submitted\n// 5. settle (submit the buyer-signed gasless bytes; digest-once inside)\n// 6. consume the challenge, attach the X-PAYMENT-RESPONSE receipt\n//\n// Money only moves at step 5, after the seller has already produced the\n// result. A forged payload can waste seller compute (signature authority is\n// the chain at settle time), never buyer money.\n// ---------------------------------------------------------------------------\n\nexport interface RouteRuntime {\n payTo: string;\n network: ServeNetwork;\n currency: Currency;\n store: DigestStore;\n baseUrl?: string;\n rpcUrl?: string;\n /** B2 attributed reporting — unset = no report (see ServeConfig). */\n activityReportUrl?: string;\n}\n\nexport interface RouteOptions {\n path: string;\n description?: string;\n}\n\n/** Sanity cap on a per-call price — above this, the work is job-shaped\n * (escrow) rather than a per-call x402 Service. */\nconst CATALOG_PRICE_CAP_USDC = 5;\n\nconst CORS_HEADERS: Record<string, string> = {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'access-control-allow-headers': `content-type, ${X402_PAYMENT_HEADER}`,\n 'access-control-expose-headers': `${X402_PAYMENT_RESPONSE_HEADER}, WWW-Authenticate`,\n};\n\nfunction withCors(response: Response): Response {\n const headers = new Headers(response.headers);\n for (const [k, v] of Object.entries(CORS_HEADERS)) headers.set(k, v);\n return new Response(response.body, { status: response.status, headers });\n}\n\nfunction json(status: number, body: unknown, headers?: Record<string, string>): Response {\n return withCors(\n new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json', ...headers },\n }),\n );\n}\n\nfunction isStandardSchema(schema: ServeSchema): schema is StandardSchemaLike {\n return typeof schema === 'object' && schema !== null && '~standard' in schema;\n}\n\nasync function validateBody(\n schema: ServeSchema,\n value: unknown,\n): Promise<{ ok: true; data: unknown } | { ok: false; message: string }> {\n if (isStandardSchema(schema)) {\n const result = await schema['~standard'].validate(value);\n if (result.issues) {\n // Name the failing field — bare \"Invalid input\" ×N gives a paying\n // buyer's agent nothing to self-correct with.\n const message = result.issues\n .map((i) => {\n const path = (i.path ?? [])\n .map((seg) => (typeof seg === 'object' ? String(seg.key) : String(seg)))\n .join('.');\n return path ? `${path}: ${i.message}` : i.message;\n })\n .join('; ');\n return { ok: false, message };\n }\n return { ok: true, data: result.value };\n }\n const result = schema.safeParse(value);\n if (!result.success) {\n return { ok: false, message: result.error.message ?? 'invalid body' };\n }\n return { ok: true, data: result.data };\n}\n\n/** Positive decimal USDC string, max 6dp (atomic precision). */\nfunction assertValidPrice(price: string, path: string): void {\n if (!/^\\d+(\\.\\d{1,6})?$/.test(price) || Number(price) <= 0) {\n throw new Error(\n `[serve] Route \"${path}\": price must be a positive decimal USDC string with up to 6 decimals, got \"${price}\"`,\n );\n }\n if (Number(price) > CATALOG_PRICE_CAP_USDC) {\n console.warn(\n `[serve] Route \"${path}\": price ${price} USDC is above the ${CATALOG_PRICE_CAP_USDC} USDC listing cap — ` +\n 'the route works, but per-call x402 is the wrong shape for it. Job-class work belongs in `t2 service create` (escrow).',\n );\n }\n}\n\nexport class RouteBuilder<TBody = undefined> {\n private priceUsdc?: string;\n private bodySchema?: ServeSchema;\n private inputSchema?: Record<string, unknown>;\n private outputSchema?: Record<string, unknown>;\n private isFree = false;\n\n constructor(\n private readonly runtime: RouteRuntime,\n private readonly options: RouteOptions,\n private readonly register: (route: BuiltRoute) => void,\n ) {}\n\n /** Charge this many USDC per call (human units, e.g. \"0.01\"). */\n paid(priceUsdc: string): this {\n assertValidPrice(priceUsdc, this.options.path);\n this.priceUsdc = priceUsdc;\n this.isFree = false;\n return this;\n }\n\n /** Serve without payment (health checks, previews, docs). */\n unprotected(): this {\n this.isFree = true;\n this.priceUsdc = undefined;\n return this;\n }\n\n /**\n * Validate the JSON request body. zod v4 / valibot / arktype / anything\n * Standard-Schema, or anything with a zod-style safeParse.\n *\n * Pass the JSON Schema as the second argument to publish it in\n * /openapi.json + /llms.txt (zod v4: `z.toJSONSchema(schema)`) — buyers'\n * agents build request bodies from it, and the catalog grades listings\n * without one.\n */\n body<T>(schema: ServeSchema<T>, jsonSchema?: Record<string, unknown>): RouteBuilder<T> {\n this.bodySchema = schema;\n this.inputSchema = jsonSchema;\n return this as unknown as RouteBuilder<T>;\n }\n\n /**\n * Declare the 200 response's JSON Schema (zod v4: `z.toJSONSchema(schema)`).\n * Published in /openapi.json + /llms.txt so buyer agents know what they're\n * buying and buyer UIs can render the deliverable by TYPE instead of\n * sniffing it — annotate with `contentMediaType` (e.g. \"image/svg+xml\",\n * \"text/markdown\") and `format: \"color\"` where they apply. Declaration\n * only; responses are never validated at runtime.\n */\n response(jsonSchema: Record<string, unknown>): this {\n this.outputSchema = jsonSchema;\n return this;\n }\n\n handler(fn: (ctx: HandlerContext<TBody>) => HandlerResult | Promise<HandlerResult>): BuiltRoute {\n if (!this.isFree && !this.priceUsdc) {\n throw new Error(\n `[serve] Route \"${this.options.path}\": call .paid('<usdc>') or .unprotected() before .handler()`,\n );\n }\n const runtime = this.runtime;\n const { path, description } = this.options;\n const priceUsdc = this.priceUsdc;\n const bodySchema = this.bodySchema;\n\n const route = (async (req: Request): Promise<Response> => {\n if (req.method === 'OPTIONS') {\n return withCors(new Response(null, { status: 204 }));\n }\n\n // Read + parse the body once, up front. A missing/empty body on a\n // schema-less route is fine; JSON parse failures only matter when a\n // paid request must be validated (the unpaid 402 fires regardless).\n let parsedBody: unknown;\n let bodyParseError: string | undefined;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n const text = await req.text();\n if (text.trim().length > 0) {\n try {\n parsedBody = JSON.parse(text);\n } catch {\n bodyParseError = 'request body is not valid JSON';\n }\n }\n }\n\n const resource = (runtime.baseUrl ?? new URL(req.url).origin).replace(/\\/$/, '') + `/${path}`;\n\n const runHandler = async (payer?: string): Promise<Response> => {\n let validated: unknown = parsedBody;\n if (bodySchema) {\n // `paid: false` is machine-readable charge honesty — a 422 fires\n // BEFORE settlement, so the buyer always keeps their money.\n if (bodyParseError) {\n return json(422, { error: bodyParseError, paid: false });\n }\n const result = await validateBody(bodySchema, parsedBody ?? {});\n if (!result.ok) {\n return json(422, { error: result.message, paid: false });\n }\n validated = result.data;\n }\n const out = await fn({ body: validated as TBody, req, payer });\n if (out instanceof Response) return withCors(out);\n return json(200, out);\n };\n\n // Free route — no payment machinery at all.\n if (!priceUsdc) {\n try {\n return await runHandler();\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed:`, err);\n return json(500, { error: 'internal error' });\n }\n }\n\n const paymentHeader = req.headers.get(X402_PAYMENT_HEADER);\n\n // Unpaid → 402 with the accepts[] envelope. This fires before body\n // validation on purpose: the catalog probe (and every discovery tool)\n // POSTs `{}` and must see the challenge, and an unpaid request can\n // never be charged, so there is nothing to protect yet.\n if (!paymentHeader) {\n return await respond402(runtime, { resource, priceUsdc });\n }\n\n if (isX402EscrowHeader(paymentHeader)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error:\n 'this endpoint sells instant per-call work (settle-then-serve), not escrow jobs — retry with a signed x402 payment',\n });\n }\n\n // 1. Parse + structural verify — right terms, right recipient, right\n // nonce. No RPC, no state. Wrong-terms payloads never reach the\n // handler.\n let payment: ReturnType<typeof parseX402Header>;\n try {\n payment = parseX402Header(paymentHeader);\n verifyX402Payment({\n payment,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `invalid payment: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 2. Challenge-once — a signed payload is single-use even before it\n // settles (the settled digest is separately consumed inside\n // settleX402Payment, digest-once).\n const challengeKey = `challenge:${payment.payload.challengeId}`;\n if (await runtime.store.has(challengeKey)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: 'payment challenge already used — sign a fresh payment',\n });\n }\n\n // 3 + 4. Validate, then compute the result. Any failure here returns\n // WITHOUT settling — the buyer-signed bytes are never submitted.\n let served: Response;\n try {\n served = await runHandler(payment.payload.senderAddress);\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed (payment NOT settled):`, err);\n return json(500, { error: 'internal error — you were not charged' });\n }\n if (served.status >= 400) return served; // 422 etc. — not charged\n\n // 5. Settle — submit the buyer-signed gasless bytes, confirm the\n // on-chain balance change, record the digest (digest-once).\n let settle: X402SettleResponse;\n try {\n settle = await settleX402Payment({\n payment,\n client: getGrpcClient(runtime.network, runtime.rpcUrl),\n store: runtime.store,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `settlement failed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 6. Consume the challenge + attach the receipt.\n try {\n await runtime.store.set(challengeKey);\n } catch {\n // Digest-once already holds; challenge-once is defense in depth.\n }\n\n // B2: attributed activity report — AFTER a successful settle only,\n // strictly fire-and-forget (a dead report can never change the\n // buyer's 200 or the settle; SPEC_T2_ACTIVITY_X402 §7 lock 6).\n reportActivity(runtime, {\n digest: settle.transaction,\n payer: settle.payer,\n priceUsdc,\n resource,\n });\n\n const headers = new Headers(served.headers);\n headers.set(X402_PAYMENT_RESPONSE_HEADER, encodeX402Response(settle));\n return new Response(served.body, { status: served.status, headers });\n }) as BuiltRoute;\n\n route.meta = {\n path,\n priceUsdc,\n description,\n bodySchema,\n inputSchema: this.inputSchema,\n outputSchema: this.outputSchema,\n };\n this.register(route);\n return route;\n }\n}\n\n/** Fire-and-forget x402.paid report (B2). Never awaited into the response\n * path; short timeout; every failure swallowed. The report endpoint\n * chain-verifies the digest, so this carries claims, not trust. */\nfunction reportActivity(\n runtime: RouteRuntime,\n args: { digest: string; payer: string; priceUsdc: string; resource: string },\n): void {\n const url = runtime.activityReportUrl;\n if (!url) return;\n try {\n void fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n digest: args.digest,\n payTo: runtime.payTo,\n payer: args.payer,\n amountMicroUsdc: Math.round(Number(args.priceUsdc) * 1_000_000),\n network: `sui:${runtime.network}`,\n route: args.resource,\n source: 'serve',\n }),\n signal: AbortSignal.timeout(1500),\n }).catch(() => undefined);\n } catch {\n // even a sync throw (bad URL) must not touch the buyer's response\n }\n}\n\nasync function respond402(\n runtime: RouteRuntime,\n args: { resource: string; priceUsdc: string; error?: string },\n): Promise<Response> {\n try {\n const { chain, epoch } = await getChainInfo(runtime.network, runtime.rpcUrl);\n const requirements = createX402Requirements({\n challengeId: crypto.randomUUID(),\n amount: args.priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n resource: args.resource,\n network: runtime.network,\n chain,\n currentEpoch: epoch,\n });\n // Belt-and-suspenders for pre-0.2.2 discovery clients and dual-dialect\n // consumers: mirror the challenge into the MPP WWW-Authenticate shape.\n // The accepts[] body stays the authoritative envelope — the header carries\n // the same recipient/currency and the DECIMAL amount that dialect uses.\n // currency must be the coin TYPE STRING (the same identity the x402\n // asset field uses) — `Currency` is { type, decimals }, and object\n // interpolation shipped currency=\"[object Object]\" (beta #93, S.1002).\n const host = (() => {\n try {\n return new URL(args.resource).hostname;\n } catch {\n return undefined;\n }\n })();\n const wwwAuth = `Payment realm=\"${host ?? 'x402'}\", recipient=\"${runtime.payTo}\", currency=\"${runtime.currency.type}\", amount=\"${args.priceUsdc}\"`;\n return json(\n 402,\n {\n x402Version: X402_VERSION,\n error: args.error ?? 'Payment required',\n accepts: [requirements],\n },\n { 'WWW-Authenticate': wwwAuth },\n );\n } catch (err) {\n // Chain info unreachable — a 402 without the envelope is unpayable, so\n // be honest about the outage instead of serving a dead challenge.\n console.error('[serve] failed to build 402 challenge:', err);\n return json(503, { error: 'payment challenge temporarily unavailable' });\n }\n}\n\n","import type { DigestStore } from '@t2000/sui-x402';\n\nexport { InMemoryDigestStore } from '@t2000/sui-x402';\nexport type { DigestStore } from '@t2000/sui-x402';\n\n// ---------------------------------------------------------------------------\n// Upstash-REST digest store — the production replay store for serverless\n// hosts. Mirrors the gateway's upstash-digest-store.ts but speaks the\n// Upstash REST API over plain fetch (no @upstash/redis dependency).\n//\n// TTL: 72h. x402 payments are chain-valid for the whole ValidDuring window\n// ([minEpoch, minEpoch+1] ≈ up to ~48h on mainnet). Sui resubmission of an\n// executed tx is idempotent, so if the digest/challenge keys expired BEFORE\n// the window closed, a replayed X-PAYMENT would re-settle \"successfully\"\n// and serve again on a single payment. 72h > max window + drift.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 72 * 60 * 60;\nconst PREFIX = 'serve:digest:';\n\nexport interface UpstashDigestStoreOptions {\n url: string;\n token: string;\n /** Key TTL in seconds. Default 72h — do not lower below ~50h (see above). */\n ttlSeconds?: number;\n}\n\nexport class UpstashDigestStore implements DigestStore {\n private readonly url: string;\n private readonly token: string;\n private readonly ttlSeconds: number;\n\n constructor(options: UpstashDigestStoreOptions) {\n this.url = options.url.replace(/\\/$/, '');\n this.token = options.token;\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n }\n\n private async command(segments: string[]): Promise<unknown> {\n const res = await fetch(`${this.url}/${segments.map(encodeURIComponent).join('/')}`, {\n headers: { authorization: `Bearer ${this.token}` },\n });\n if (!res.ok) {\n throw new Error(`Upstash command failed: ${res.status} ${await res.text()}`);\n }\n const body = (await res.json()) as { result?: unknown; error?: string };\n if (body.error) throw new Error(`Upstash error: ${body.error}`);\n return body.result;\n }\n\n async has(digest: string): Promise<boolean> {\n const result = await this.command(['GET', PREFIX + digest]);\n return result !== null && result !== undefined;\n }\n\n async set(digest: string): Promise<void> {\n // SET key 1 EX <ttl> NX — atomic set-if-absent. A null result means the\n // key already existed: the digest (or challenge) was already consumed.\n const result = await this.command([\n 'SET',\n PREFIX + digest,\n '1',\n 'EX',\n String(this.ttlSeconds),\n 'NX',\n ]);\n if (result === null || result === undefined) {\n throw new Error(`Digest already used: ${digest}`);\n }\n }\n}\n","import { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { InMemoryDigestStore, USDC, USDC_TESTNET, type Currency } from '@t2000/sui-x402';\nimport { buildLlmsTxt, buildOpenApiDocument } from './discovery.js';\nimport { RouteBuilder, type RouteOptions, type RouteRuntime } from './route.js';\nimport { UpstashDigestStore } from './store.js';\nimport type { BuiltRoute, ServeConfig, ServeNetwork } from './types.js';\n\n/** The t2000.ai attributed-activity report endpoint — ONE canonical string\n * (matches the sdk's DEFAULT_ACTIVITY_REPORT_URL; tests assert equality). */\nexport const DEFAULT_ACTIVITY_REPORT_URL = 'https://t2000.ai/api/activity/x402';\n\n/** Explicit opt-out tokens for T2000_ACTIVITY_REPORT_URL (case-insensitive). */\nconst REPORT_OPT_OUT = new Set(['false', '0', 'off', 'none']);\n\nexport class Serve {\n private readonly runtime: RouteRuntime;\n /** Every route built through this instance, keyed by path (discovery). */\n readonly routes = new Map<string, BuiltRoute>();\n\n readonly payTo: string;\n readonly network: ServeNetwork;\n readonly name?: string;\n readonly description?: string;\n readonly baseUrl?: string;\n /** Where settled payments are reported (B2) — undefined = no report. */\n readonly activityReportUrl?: string;\n\n constructor(config: ServeConfig) {\n if (!config.payTo || !isValidSuiAddress(config.payTo)) {\n throw new Error(\n `[serve] payTo must be a valid Sui address (the wallet your payments settle to), got \"${config.payTo}\"`,\n );\n }\n this.payTo = normalizeSuiAddress(config.payTo);\n this.network = config.network ?? 'mainnet';\n this.name = config.name;\n this.description = config.description;\n this.baseUrl = config.baseUrl?.replace(/\\/$/, '');\n this.activityReportUrl = config.activityReportUrl;\n\n const currency: Currency = this.network === 'testnet' ? USDC_TESTNET : USDC;\n this.runtime = {\n payTo: this.payTo,\n network: this.network,\n currency,\n store: config.store ?? new InMemoryDigestStore(),\n baseUrl: this.baseUrl,\n rpcUrl: config.rpcUrl,\n activityReportUrl: this.activityReportUrl,\n };\n }\n\n /** Start building a route. Chain `.paid()` / `.body()` / `.handler()`. */\n route(options: RouteOptions): RouteBuilder {\n const path = options.path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!path) throw new Error('[serve] route path must be non-empty');\n return new RouteBuilder({ ...this.runtime }, { ...options, path }, (route) => {\n this.routes.set(path, route);\n });\n }\n\n /**\n * Discovery: GET handler for /openapi.json. OpenAPI 3.1 with the\n * `x-payment-info` pricing extension on every paid operation — the shape\n * x402 tooling (and any catalog built on it) indexes.\n *\n * export const GET = serve.openapi(); // app/openapi.json/route.ts\n */\n openapi(): (req: Request) => Response {\n return (req: Request) =>\n new Response(JSON.stringify(buildOpenApiDocument(this, new URL(req.url).origin), null, 2), {\n headers: { 'content-type': 'application/json', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * Discovery: GET handler for /llms.txt — plain-text guidance agents read\n * to understand what the API sells, what it costs, and how to pay.\n *\n * export const GET = serve.llms(); // app/llms.txt/route.ts\n */\n llms(): (req: Request) => Response {\n return (req: Request) =>\n new Response(buildLlmsTxt(this, new URL(req.url).origin), {\n headers: { 'content-type': 'text/plain; charset=utf-8', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * One fetch handler for the whole app — routes + discovery docs. For\n * fetch-native runtimes (Bun.serve, Deno.serve, Hono, Cloudflare Workers):\n *\n * Bun.serve({ fetch: serve.fetch });\n * app.all('*', (c) => serve.fetch(c.req.raw)); // Hono\n *\n * Next.js apps can skip this and export route handlers directly.\n */\n readonly fetch = async (req: Request): Promise<Response> => {\n const pathname = new URL(req.url).pathname.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (pathname === 'openapi.json') return this.openapi()(req);\n if (pathname === 'llms.txt') return this.llms()(req);\n const route = this.routes.get(pathname);\n if (route) return route(req);\n return new Response(\n JSON.stringify({ error: 'not found', discovery: ['/openapi.json', '/llms.txt'] }),\n { status: 404, headers: { 'content-type': 'application/json' } },\n );\n };\n\n /**\n * The command that sells this API as an x402 Service on your Agent ID,\n * once it is deployed. Listing is a separate, explicit step: the endpoint\n * is live-probed (it must answer 402 with a Sui challenge that pays YOUR\n * wallet) and then recorded on-chain, sponsored and gasless.\n *\n * This used to emit curls against the hosted mpp.t2000.ai catalog. That\n * proxy mall was purged 2026-08-01 (SPEC_T2_CLEANUP_USDC_ONLY) — there is\n * no central catalog to submit to. Your Agent ID IS the listing, and\n * buyers find it with `t2 services`.\n */\n catalogSubmitCommand(deployedUrl?: string): string {\n const base = (deployedUrl ?? this.baseUrl ?? 'https://<your-deployed-app>').replace(/\\/$/, '');\n const paidPaths = [...this.routes.values()].filter((r) => r.meta.priceUsdc);\n const example = paidPaths[0]?.meta.path ?? '<route>';\n return [\n '# Sell it as an x402 Service on your Agent ID (live-probed, gasless):',\n `npx @t2000/cli agent sell ${base}/${example}`,\n '# Buyers then find it with `t2 services` and pay per call with `t2 pay`.',\n ].join('\\n');\n }\n}\n\nexport function createServe(config: ServeConfig): Serve {\n return new Serve(config);\n}\n\n/**\n * Build a Serve from environment variables — the template-app path where\n * config lives in the host's env UI, not code.\n *\n * T2000_PAY_TO required — the seller's Sui address\n * T2000_NETWORK optional — 'mainnet' (default) | 'testnet'\n * T2000_BASE_URL optional — public URL of the deployed app\n * T2000_NAME optional — service name for discovery docs\n * T2000_DESCRIPTION optional — one-liner for discovery docs\n * T2000_ACTIVITY_REPORT_URL\n * optional — where settled payments are reported\n * (fire-and-forget x402.paid after each successful settle;\n * chain-verified server-side, never affects buyer\n * responses). DEFAULT-ON for FromEnv: unset →\n * https://t2000.ai/api/activity/x402 so new sellers appear\n * on the t2000.ai activity tape. Opt out with\n * `false` | `0` | `off` | `none` (case-insensitive), or\n * set a custom URL. (`new Serve({...})` without\n * activityReportUrl stays silent — only FromEnv defaults.)\n * KV_REST_API_URL / KV_REST_API_TOKEN\n * optional — enables the durable Upstash replay store\n * (REQUIRED in serverless production; without it replay\n * state is per-instance memory)\n *\n * Empty strings are treated as unset (the Vercel empty-env bug class).\n */\nexport function createServeFromEnv(env: Record<string, string | undefined> = process.env): Serve {\n const read = (key: string): string | undefined => {\n const v = env[key]?.trim();\n return v && v.length > 0 ? v : undefined;\n };\n\n const payTo = read('T2000_PAY_TO');\n if (!payTo) {\n throw new Error(\n '[serve] T2000_PAY_TO is not set (or is empty). Set it to the Sui address your payments should settle to — `t2 address` prints yours.',\n );\n }\n\n const network = read('T2000_NETWORK');\n if (network && network !== 'mainnet' && network !== 'testnet') {\n throw new Error(`[serve] T2000_NETWORK must be 'mainnet' or 'testnet', got \"${network}\"`);\n }\n\n const kvUrl = read('KV_REST_API_URL');\n const kvToken = read('KV_REST_API_TOKEN');\n const store =\n kvUrl && kvToken ? new UpstashDigestStore({ url: kvUrl, token: kvToken }) : undefined;\n\n if (!store) {\n console.warn(\n '[serve] No KV_REST_API_URL/KV_REST_API_TOKEN — using the in-memory replay store. ' +\n 'Fine for a single long-lived process; on serverless hosts set both so replay protection is durable.',\n );\n }\n\n return new Serve({\n payTo,\n network: (network as ServeNetwork | undefined) ?? 'mainnet',\n baseUrl: read('T2000_BASE_URL'),\n name: read('T2000_NAME'),\n description: read('T2000_DESCRIPTION'),\n activityReportUrl: resolveReportUrlFromEnv(read('T2000_ACTIVITY_REPORT_URL')),\n store,\n });\n}\n\n/** FromEnv activity-report resolution (B2 default-on): unset/empty →\n * the t2000.ai default; an explicit opt-out token → undefined (silent);\n * anything else is the seller's custom report URL. */\nfunction resolveReportUrlFromEnv(raw: string | undefined): string | undefined {\n if (raw === undefined) return DEFAULT_ACTIVITY_REPORT_URL;\n if (REPORT_OPT_OUT.has(raw.toLowerCase())) return undefined;\n return raw;\n}\n","import type { BuiltRoute } from './types.js';\n\n/**\n * Export a built route the way Next.js App Router needs it.\n *\n * Next dispatches ONLY the methods a route.ts exports — serve's own CORS\n * handling (OPTIONS → 204 with the ACAO headers) never runs if the file\n * exports just `POST`: the browser preflight gets Next's bare 204 with no\n * CORS headers, and every browser buyer (Passport, the store's Try it)\n * fails while CLI/server buyers — who never preflight — work fine. Fetch\n * runtimes mounted via a single handler (`serve.fetch`-style) don't have\n * this hole; it is a Next export contract, not a serve one.\n *\n * export const { POST, OPTIONS } = asNextRoute(\n * serve.route({ path: 'haiku' }).paid('0.01').handler(fn),\n * );\n */\nexport function asNextRoute(route: BuiltRoute): {\n POST: BuiltRoute;\n OPTIONS: BuiltRoute;\n} {\n return { POST: route, OPTIONS: route };\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -431,7 +431,7 @@ async function respond402(runtime, args) {
|
|
|
431
431
|
return void 0;
|
|
432
432
|
}
|
|
433
433
|
})();
|
|
434
|
-
const wwwAuth = `Payment realm="${host ?? "x402"}", recipient="${runtime.payTo}", currency="${runtime.currency}", amount="${args.priceUsdc}"`;
|
|
434
|
+
const wwwAuth = `Payment realm="${host ?? "x402"}", recipient="${runtime.payTo}", currency="${runtime.currency.type}", amount="${args.priceUsdc}"`;
|
|
435
435
|
return json(
|
|
436
436
|
402,
|
|
437
437
|
{
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/discovery.ts","../src/chain.ts","../src/route.ts","../src/store.ts","../src/serve.ts","../src/next.ts"],"names":["result","USDC_TESTNET","USDC","InMemoryDigestStore"],"mappings":"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","file":"index.js","sourcesContent":["import { USDC, USDC_TESTNET } from '@t2000/sui-x402';\nimport type { Serve } from './serve.js';\n\n// ---------------------------------------------------------------------------\n// Discovery docs — /openapi.json + /llms.txt.\n//\n// The shapes here are what the on-chain listing probe grades (the check\n// behind `t2 agent sell`) (was: apps/gateway/lib/\n// catalog-ingest.ts `gradeListing`): a warning-free listing needs info.title,\n// a one-paragraph info.description, a flat string `x-payment-info.price` per\n// paid operation, and an application/json requestBody schema with typed\n// properties. Everything serve can derive is emitted automatically; the JSON\n// request schema comes from the route's `inputSchema` (zod v4 users:\n// `z.toJSONSchema(schema)`).\n// ---------------------------------------------------------------------------\n\nexport function buildOpenApiDocument(serve: Serve, origin?: string): Record<string, unknown> {\n const base = serve.baseUrl ?? origin;\n const paths: Record<string, unknown> = {};\n\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const operation: Record<string, unknown> = {\n operationId: path.replace(/[^a-zA-Z0-9]+/g, '_'),\n summary: description ?? path,\n responses: {\n '200': outputSchema\n ? {\n description: 'Success',\n content: { 'application/json': { schema: outputSchema } },\n }\n : { description: 'Success' },\n ...(priceUsdc\n ? {\n '402': {\n description:\n 'Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header.',\n },\n }\n : {}),\n '422': { description: 'Invalid request body — never charged' },\n },\n };\n if (priceUsdc) {\n // Same shape the gateway's own /openapi.json emits: 'mpp' is the\n // protocol family, 'x402' the dialect; the x402 block mirrors the\n // static half of the live accepts[] entry (dynamic fields ride the 402).\n operation['x-payment-info'] = {\n pricingMode: 'fixed',\n price: priceUsdc,\n currency: 'USDC',\n protocols: ['mpp', 'x402'],\n x402: {\n scheme: 'exact',\n network: `sui:${serve.network}`,\n asset: (serve.network === 'testnet' ? USDC_TESTNET : USDC).type,\n payTo: serve.payTo,\n },\n };\n }\n if (inputSchema) {\n operation.requestBody = {\n required: true,\n content: { 'application/json': { schema: inputSchema } },\n };\n }\n paths[`/${path}`] = { post: operation };\n }\n\n return {\n openapi: '3.1.0',\n info: {\n title: serve.name ?? 'Paid API',\n version: '1.0.0',\n description:\n serve.description ??\n 'Agent-payable API. Every paid endpoint answers 402 with an x402 accepts[] envelope; payment settles in USDC on Sui.',\n },\n ...(base ? { servers: [{ url: base }] } : {}),\n paths,\n };\n}\n\nexport function buildLlmsTxt(serve: Serve, origin?: string): string {\n const base = serve.baseUrl ?? origin ?? '';\n const lines: string[] = [];\n lines.push(`# ${serve.name ?? 'Paid API'}`);\n lines.push('');\n if (serve.description) {\n lines.push(serve.description);\n lines.push('');\n }\n lines.push('## How to pay');\n lines.push('');\n lines.push(\n 'Endpoints below are paid per call in USDC on Sui (x402). An unpaid request returns',\n 'HTTP 402 with an `accepts[]` envelope; sign it and retry with the `X-PAYMENT` header.',\n 'Invalid input returns 422 before any payment is taken. A failed call is never charged.',\n '',\n 'Easiest client: `npm i -g @t2000/cli` then `t2 pay <url> --data \\'{...}\\'`,',\n 'or the t2000 MCP server (`t2000_pay`), or `@t2000/sdk` `pay()`.',\n '',\n );\n lines.push('## Endpoints');\n lines.push('');\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const price = priceUsdc ? `${priceUsdc} USDC per call` : 'free';\n lines.push(`### POST ${base}/${path} — ${price}`);\n if (description) lines.push(description);\n if (inputSchema) {\n lines.push('Request body (JSON Schema):');\n lines.push('```json');\n lines.push(JSON.stringify(inputSchema, null, 2));\n lines.push('```');\n }\n if (outputSchema) {\n lines.push('Response (JSON Schema — contentMediaType/format annotations name the deliverable types):');\n lines.push('```json');\n lines.push(JSON.stringify(outputSchema, null, 2));\n lines.push('```');\n }\n lines.push('');\n }\n lines.push(`Discovery: ${base}/openapi.json`);\n return lines.join('\\n');\n}\n","import { SuiGrpcClient } from '@mysten/sui/grpc';\nimport type { ServeNetwork } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Chain plumbing — same shape as the gateway's x402-dialect.ts (the reference\n// composition). All reads are gRPC; this package never touches JSON-RPC.\n//\n// Cache policy: the chain identifier (genesis digest) is immutable per\n// network — cached forever. The epoch advances ~daily and x402 requirements\n// are valid for [epoch, epoch+1], so a 10-minute TTL is conservatively fresh.\n// ---------------------------------------------------------------------------\n\nconst FULLNODE_URLS: Record<ServeNetwork, string> = {\n mainnet: 'https://fullnode.mainnet.sui.io:443',\n testnet: 'https://fullnode.testnet.sui.io:443',\n};\n\nconst EPOCH_TTL_MS = 10 * 60 * 1000;\n\nexport interface ChainInfo {\n chain: string;\n epoch: string;\n}\n\ninterface ChainState {\n client?: SuiGrpcClient;\n chainId?: string;\n epoch?: { value: string; fetchedAt: number };\n}\n\nconst state: Partial<Record<ServeNetwork, ChainState>> = {};\n\nexport function getGrpcClient(network: ServeNetwork, rpcUrl?: string): SuiGrpcClient {\n const s = (state[network] ??= {});\n if (!s.client) {\n s.client = new SuiGrpcClient({\n baseUrl: rpcUrl ?? FULLNODE_URLS[network],\n network,\n });\n }\n return s.client;\n}\n\nexport async function getChainInfo(network: ServeNetwork, rpcUrl?: string): Promise<ChainInfo> {\n const client = getGrpcClient(network, rpcUrl);\n const s = (state[network] ??= {});\n if (!s.chainId) {\n const res = await client.core.getChainIdentifier();\n s.chainId = res.chainIdentifier;\n }\n if (!s.epoch || Date.now() - s.epoch.fetchedAt > EPOCH_TTL_MS) {\n const res = await client.core.getCurrentSystemState();\n s.epoch = { value: String(res.systemState.epoch), fetchedAt: Date.now() };\n }\n return { chain: s.chainId, epoch: s.epoch.value };\n}\n\n/** Test seam — reset module caches between cases. */\nexport function __resetChainCaches(): void {\n delete state.mainnet;\n delete state.testnet;\n}\n\n/** Test seam — pre-seed chain info so tests never hit the network. */\nexport function __seedChainInfo(network: ServeNetwork, chain: string, epoch: string): void {\n const s = (state[network] ??= {});\n s.chainId = chain;\n s.epoch = { value: epoch, fetchedAt: Date.now() };\n}\n","import type { Currency, DigestStore } from '@t2000/sui-x402';\nimport {\n createX402Requirements,\n encodeX402Response,\n isX402EscrowHeader,\n parseX402Header,\n settleX402Payment,\n verifyX402Payment,\n X402_PAYMENT_HEADER,\n X402_PAYMENT_RESPONSE_HEADER,\n X402_VERSION,\n type X402SettleResponse,\n} from '@t2000/sui-x402';\nimport { getChainInfo, getGrpcClient } from './chain.js';\nimport type {\n BuiltRoute,\n HandlerContext,\n HandlerResult,\n ServeNetwork,\n ServeSchema,\n StandardSchemaLike,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// The paid-request lifecycle (SPEC_T2000_SERVE §3 — sign-then-settle,\n// handler-then-settle):\n//\n// no X-PAYMENT → 402 with the accepts[] envelope (never a charge;\n// the catalog probe and every discovery tool read\n// this, so it fires BEFORE body validation)\n// X-PAYMENT present:\n// 1. parse + STRUCTURAL verify (right amount/recipient/nonce — no RPC)\n// 2. challenge-once check (a signed payload is single-use)\n// 3. validate the body — invalid → 422, payment NEVER submitted\n// (the JMPR paid-422 class is impossible: the buyer keeps their money)\n// 4. run the handler — throws → 500, payment NEVER submitted\n// 5. settle (submit the buyer-signed gasless bytes; digest-once inside)\n// 6. consume the challenge, attach the X-PAYMENT-RESPONSE receipt\n//\n// Money only moves at step 5, after the seller has already produced the\n// result. A forged payload can waste seller compute (signature authority is\n// the chain at settle time), never buyer money.\n// ---------------------------------------------------------------------------\n\nexport interface RouteRuntime {\n payTo: string;\n network: ServeNetwork;\n currency: Currency;\n store: DigestStore;\n baseUrl?: string;\n rpcUrl?: string;\n /** B2 attributed reporting — unset = no report (see ServeConfig). */\n activityReportUrl?: string;\n}\n\nexport interface RouteOptions {\n path: string;\n description?: string;\n}\n\n/** Sanity cap on a per-call price — above this, the work is job-shaped\n * (escrow) rather than a per-call x402 Service. */\nconst CATALOG_PRICE_CAP_USDC = 5;\n\nconst CORS_HEADERS: Record<string, string> = {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'access-control-allow-headers': `content-type, ${X402_PAYMENT_HEADER}`,\n 'access-control-expose-headers': `${X402_PAYMENT_RESPONSE_HEADER}, WWW-Authenticate`,\n};\n\nfunction withCors(response: Response): Response {\n const headers = new Headers(response.headers);\n for (const [k, v] of Object.entries(CORS_HEADERS)) headers.set(k, v);\n return new Response(response.body, { status: response.status, headers });\n}\n\nfunction json(status: number, body: unknown, headers?: Record<string, string>): Response {\n return withCors(\n new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json', ...headers },\n }),\n );\n}\n\nfunction isStandardSchema(schema: ServeSchema): schema is StandardSchemaLike {\n return typeof schema === 'object' && schema !== null && '~standard' in schema;\n}\n\nasync function validateBody(\n schema: ServeSchema,\n value: unknown,\n): Promise<{ ok: true; data: unknown } | { ok: false; message: string }> {\n if (isStandardSchema(schema)) {\n const result = await schema['~standard'].validate(value);\n if (result.issues) {\n // Name the failing field — bare \"Invalid input\" ×N gives a paying\n // buyer's agent nothing to self-correct with.\n const message = result.issues\n .map((i) => {\n const path = (i.path ?? [])\n .map((seg) => (typeof seg === 'object' ? String(seg.key) : String(seg)))\n .join('.');\n return path ? `${path}: ${i.message}` : i.message;\n })\n .join('; ');\n return { ok: false, message };\n }\n return { ok: true, data: result.value };\n }\n const result = schema.safeParse(value);\n if (!result.success) {\n return { ok: false, message: result.error.message ?? 'invalid body' };\n }\n return { ok: true, data: result.data };\n}\n\n/** Positive decimal USDC string, max 6dp (atomic precision). */\nfunction assertValidPrice(price: string, path: string): void {\n if (!/^\\d+(\\.\\d{1,6})?$/.test(price) || Number(price) <= 0) {\n throw new Error(\n `[serve] Route \"${path}\": price must be a positive decimal USDC string with up to 6 decimals, got \"${price}\"`,\n );\n }\n if (Number(price) > CATALOG_PRICE_CAP_USDC) {\n console.warn(\n `[serve] Route \"${path}\": price ${price} USDC is above the ${CATALOG_PRICE_CAP_USDC} USDC listing cap — ` +\n 'the route works, but per-call x402 is the wrong shape for it. Job-class work belongs in `t2 service create` (escrow).',\n );\n }\n}\n\nexport class RouteBuilder<TBody = undefined> {\n private priceUsdc?: string;\n private bodySchema?: ServeSchema;\n private inputSchema?: Record<string, unknown>;\n private outputSchema?: Record<string, unknown>;\n private isFree = false;\n\n constructor(\n private readonly runtime: RouteRuntime,\n private readonly options: RouteOptions,\n private readonly register: (route: BuiltRoute) => void,\n ) {}\n\n /** Charge this many USDC per call (human units, e.g. \"0.01\"). */\n paid(priceUsdc: string): this {\n assertValidPrice(priceUsdc, this.options.path);\n this.priceUsdc = priceUsdc;\n this.isFree = false;\n return this;\n }\n\n /** Serve without payment (health checks, previews, docs). */\n unprotected(): this {\n this.isFree = true;\n this.priceUsdc = undefined;\n return this;\n }\n\n /**\n * Validate the JSON request body. zod v4 / valibot / arktype / anything\n * Standard-Schema, or anything with a zod-style safeParse.\n *\n * Pass the JSON Schema as the second argument to publish it in\n * /openapi.json + /llms.txt (zod v4: `z.toJSONSchema(schema)`) — buyers'\n * agents build request bodies from it, and the catalog grades listings\n * without one.\n */\n body<T>(schema: ServeSchema<T>, jsonSchema?: Record<string, unknown>): RouteBuilder<T> {\n this.bodySchema = schema;\n this.inputSchema = jsonSchema;\n return this as unknown as RouteBuilder<T>;\n }\n\n /**\n * Declare the 200 response's JSON Schema (zod v4: `z.toJSONSchema(schema)`).\n * Published in /openapi.json + /llms.txt so buyer agents know what they're\n * buying and buyer UIs can render the deliverable by TYPE instead of\n * sniffing it — annotate with `contentMediaType` (e.g. \"image/svg+xml\",\n * \"text/markdown\") and `format: \"color\"` where they apply. Declaration\n * only; responses are never validated at runtime.\n */\n response(jsonSchema: Record<string, unknown>): this {\n this.outputSchema = jsonSchema;\n return this;\n }\n\n handler(fn: (ctx: HandlerContext<TBody>) => HandlerResult | Promise<HandlerResult>): BuiltRoute {\n if (!this.isFree && !this.priceUsdc) {\n throw new Error(\n `[serve] Route \"${this.options.path}\": call .paid('<usdc>') or .unprotected() before .handler()`,\n );\n }\n const runtime = this.runtime;\n const { path, description } = this.options;\n const priceUsdc = this.priceUsdc;\n const bodySchema = this.bodySchema;\n\n const route = (async (req: Request): Promise<Response> => {\n if (req.method === 'OPTIONS') {\n return withCors(new Response(null, { status: 204 }));\n }\n\n // Read + parse the body once, up front. A missing/empty body on a\n // schema-less route is fine; JSON parse failures only matter when a\n // paid request must be validated (the unpaid 402 fires regardless).\n let parsedBody: unknown;\n let bodyParseError: string | undefined;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n const text = await req.text();\n if (text.trim().length > 0) {\n try {\n parsedBody = JSON.parse(text);\n } catch {\n bodyParseError = 'request body is not valid JSON';\n }\n }\n }\n\n const resource = (runtime.baseUrl ?? new URL(req.url).origin).replace(/\\/$/, '') + `/${path}`;\n\n const runHandler = async (payer?: string): Promise<Response> => {\n let validated: unknown = parsedBody;\n if (bodySchema) {\n // `paid: false` is machine-readable charge honesty — a 422 fires\n // BEFORE settlement, so the buyer always keeps their money.\n if (bodyParseError) {\n return json(422, { error: bodyParseError, paid: false });\n }\n const result = await validateBody(bodySchema, parsedBody ?? {});\n if (!result.ok) {\n return json(422, { error: result.message, paid: false });\n }\n validated = result.data;\n }\n const out = await fn({ body: validated as TBody, req, payer });\n if (out instanceof Response) return withCors(out);\n return json(200, out);\n };\n\n // Free route — no payment machinery at all.\n if (!priceUsdc) {\n try {\n return await runHandler();\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed:`, err);\n return json(500, { error: 'internal error' });\n }\n }\n\n const paymentHeader = req.headers.get(X402_PAYMENT_HEADER);\n\n // Unpaid → 402 with the accepts[] envelope. This fires before body\n // validation on purpose: the catalog probe (and every discovery tool)\n // POSTs `{}` and must see the challenge, and an unpaid request can\n // never be charged, so there is nothing to protect yet.\n if (!paymentHeader) {\n return await respond402(runtime, { resource, priceUsdc });\n }\n\n if (isX402EscrowHeader(paymentHeader)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error:\n 'this endpoint sells instant per-call work (settle-then-serve), not escrow jobs — retry with a signed x402 payment',\n });\n }\n\n // 1. Parse + structural verify — right terms, right recipient, right\n // nonce. No RPC, no state. Wrong-terms payloads never reach the\n // handler.\n let payment: ReturnType<typeof parseX402Header>;\n try {\n payment = parseX402Header(paymentHeader);\n verifyX402Payment({\n payment,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `invalid payment: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 2. Challenge-once — a signed payload is single-use even before it\n // settles (the settled digest is separately consumed inside\n // settleX402Payment, digest-once).\n const challengeKey = `challenge:${payment.payload.challengeId}`;\n if (await runtime.store.has(challengeKey)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: 'payment challenge already used — sign a fresh payment',\n });\n }\n\n // 3 + 4. Validate, then compute the result. Any failure here returns\n // WITHOUT settling — the buyer-signed bytes are never submitted.\n let served: Response;\n try {\n served = await runHandler(payment.payload.senderAddress);\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed (payment NOT settled):`, err);\n return json(500, { error: 'internal error — you were not charged' });\n }\n if (served.status >= 400) return served; // 422 etc. — not charged\n\n // 5. Settle — submit the buyer-signed gasless bytes, confirm the\n // on-chain balance change, record the digest (digest-once).\n let settle: X402SettleResponse;\n try {\n settle = await settleX402Payment({\n payment,\n client: getGrpcClient(runtime.network, runtime.rpcUrl),\n store: runtime.store,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `settlement failed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 6. Consume the challenge + attach the receipt.\n try {\n await runtime.store.set(challengeKey);\n } catch {\n // Digest-once already holds; challenge-once is defense in depth.\n }\n\n // B2: attributed activity report — AFTER a successful settle only,\n // strictly fire-and-forget (a dead report can never change the\n // buyer's 200 or the settle; SPEC_T2_ACTIVITY_X402 §7 lock 6).\n reportActivity(runtime, {\n digest: settle.transaction,\n payer: settle.payer,\n priceUsdc,\n resource,\n });\n\n const headers = new Headers(served.headers);\n headers.set(X402_PAYMENT_RESPONSE_HEADER, encodeX402Response(settle));\n return new Response(served.body, { status: served.status, headers });\n }) as BuiltRoute;\n\n route.meta = {\n path,\n priceUsdc,\n description,\n bodySchema,\n inputSchema: this.inputSchema,\n outputSchema: this.outputSchema,\n };\n this.register(route);\n return route;\n }\n}\n\n/** Fire-and-forget x402.paid report (B2). Never awaited into the response\n * path; short timeout; every failure swallowed. The report endpoint\n * chain-verifies the digest, so this carries claims, not trust. */\nfunction reportActivity(\n runtime: RouteRuntime,\n args: { digest: string; payer: string; priceUsdc: string; resource: string },\n): void {\n const url = runtime.activityReportUrl;\n if (!url) return;\n try {\n void fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n digest: args.digest,\n payTo: runtime.payTo,\n payer: args.payer,\n amountMicroUsdc: Math.round(Number(args.priceUsdc) * 1_000_000),\n network: `sui:${runtime.network}`,\n route: args.resource,\n source: 'serve',\n }),\n signal: AbortSignal.timeout(1500),\n }).catch(() => undefined);\n } catch {\n // even a sync throw (bad URL) must not touch the buyer's response\n }\n}\n\nasync function respond402(\n runtime: RouteRuntime,\n args: { resource: string; priceUsdc: string; error?: string },\n): Promise<Response> {\n try {\n const { chain, epoch } = await getChainInfo(runtime.network, runtime.rpcUrl);\n const requirements = createX402Requirements({\n challengeId: crypto.randomUUID(),\n amount: args.priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n resource: args.resource,\n network: runtime.network,\n chain,\n currentEpoch: epoch,\n });\n // Belt-and-suspenders for pre-0.2.2 discovery clients and dual-dialect\n // consumers: mirror the challenge into the MPP WWW-Authenticate shape.\n // The accepts[] body stays the authoritative envelope — the header carries\n // the same recipient/currency and the DECIMAL amount that dialect uses.\n const host = (() => {\n try {\n return new URL(args.resource).hostname;\n } catch {\n return undefined;\n }\n })();\n const wwwAuth = `Payment realm=\"${host ?? 'x402'}\", recipient=\"${runtime.payTo}\", currency=\"${runtime.currency}\", amount=\"${args.priceUsdc}\"`;\n return json(\n 402,\n {\n x402Version: X402_VERSION,\n error: args.error ?? 'Payment required',\n accepts: [requirements],\n },\n { 'WWW-Authenticate': wwwAuth },\n );\n } catch (err) {\n // Chain info unreachable — a 402 without the envelope is unpayable, so\n // be honest about the outage instead of serving a dead challenge.\n console.error('[serve] failed to build 402 challenge:', err);\n return json(503, { error: 'payment challenge temporarily unavailable' });\n }\n}\n\n","import type { DigestStore } from '@t2000/sui-x402';\n\nexport { InMemoryDigestStore } from '@t2000/sui-x402';\nexport type { DigestStore } from '@t2000/sui-x402';\n\n// ---------------------------------------------------------------------------\n// Upstash-REST digest store — the production replay store for serverless\n// hosts. Mirrors the gateway's upstash-digest-store.ts but speaks the\n// Upstash REST API over plain fetch (no @upstash/redis dependency).\n//\n// TTL: 72h. x402 payments are chain-valid for the whole ValidDuring window\n// ([minEpoch, minEpoch+1] ≈ up to ~48h on mainnet). Sui resubmission of an\n// executed tx is idempotent, so if the digest/challenge keys expired BEFORE\n// the window closed, a replayed X-PAYMENT would re-settle \"successfully\"\n// and serve again on a single payment. 72h > max window + drift.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 72 * 60 * 60;\nconst PREFIX = 'serve:digest:';\n\nexport interface UpstashDigestStoreOptions {\n url: string;\n token: string;\n /** Key TTL in seconds. Default 72h — do not lower below ~50h (see above). */\n ttlSeconds?: number;\n}\n\nexport class UpstashDigestStore implements DigestStore {\n private readonly url: string;\n private readonly token: string;\n private readonly ttlSeconds: number;\n\n constructor(options: UpstashDigestStoreOptions) {\n this.url = options.url.replace(/\\/$/, '');\n this.token = options.token;\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n }\n\n private async command(segments: string[]): Promise<unknown> {\n const res = await fetch(`${this.url}/${segments.map(encodeURIComponent).join('/')}`, {\n headers: { authorization: `Bearer ${this.token}` },\n });\n if (!res.ok) {\n throw new Error(`Upstash command failed: ${res.status} ${await res.text()}`);\n }\n const body = (await res.json()) as { result?: unknown; error?: string };\n if (body.error) throw new Error(`Upstash error: ${body.error}`);\n return body.result;\n }\n\n async has(digest: string): Promise<boolean> {\n const result = await this.command(['GET', PREFIX + digest]);\n return result !== null && result !== undefined;\n }\n\n async set(digest: string): Promise<void> {\n // SET key 1 EX <ttl> NX — atomic set-if-absent. A null result means the\n // key already existed: the digest (or challenge) was already consumed.\n const result = await this.command([\n 'SET',\n PREFIX + digest,\n '1',\n 'EX',\n String(this.ttlSeconds),\n 'NX',\n ]);\n if (result === null || result === undefined) {\n throw new Error(`Digest already used: ${digest}`);\n }\n }\n}\n","import { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { InMemoryDigestStore, USDC, USDC_TESTNET, type Currency } from '@t2000/sui-x402';\nimport { buildLlmsTxt, buildOpenApiDocument } from './discovery.js';\nimport { RouteBuilder, type RouteOptions, type RouteRuntime } from './route.js';\nimport { UpstashDigestStore } from './store.js';\nimport type { BuiltRoute, ServeConfig, ServeNetwork } from './types.js';\n\n/** The t2000.ai attributed-activity report endpoint — ONE canonical string\n * (matches the sdk's DEFAULT_ACTIVITY_REPORT_URL; tests assert equality). */\nexport const DEFAULT_ACTIVITY_REPORT_URL = 'https://t2000.ai/api/activity/x402';\n\n/** Explicit opt-out tokens for T2000_ACTIVITY_REPORT_URL (case-insensitive). */\nconst REPORT_OPT_OUT = new Set(['false', '0', 'off', 'none']);\n\nexport class Serve {\n private readonly runtime: RouteRuntime;\n /** Every route built through this instance, keyed by path (discovery). */\n readonly routes = new Map<string, BuiltRoute>();\n\n readonly payTo: string;\n readonly network: ServeNetwork;\n readonly name?: string;\n readonly description?: string;\n readonly baseUrl?: string;\n /** Where settled payments are reported (B2) — undefined = no report. */\n readonly activityReportUrl?: string;\n\n constructor(config: ServeConfig) {\n if (!config.payTo || !isValidSuiAddress(config.payTo)) {\n throw new Error(\n `[serve] payTo must be a valid Sui address (the wallet your payments settle to), got \"${config.payTo}\"`,\n );\n }\n this.payTo = normalizeSuiAddress(config.payTo);\n this.network = config.network ?? 'mainnet';\n this.name = config.name;\n this.description = config.description;\n this.baseUrl = config.baseUrl?.replace(/\\/$/, '');\n this.activityReportUrl = config.activityReportUrl;\n\n const currency: Currency = this.network === 'testnet' ? USDC_TESTNET : USDC;\n this.runtime = {\n payTo: this.payTo,\n network: this.network,\n currency,\n store: config.store ?? new InMemoryDigestStore(),\n baseUrl: this.baseUrl,\n rpcUrl: config.rpcUrl,\n activityReportUrl: this.activityReportUrl,\n };\n }\n\n /** Start building a route. Chain `.paid()` / `.body()` / `.handler()`. */\n route(options: RouteOptions): RouteBuilder {\n const path = options.path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!path) throw new Error('[serve] route path must be non-empty');\n return new RouteBuilder({ ...this.runtime }, { ...options, path }, (route) => {\n this.routes.set(path, route);\n });\n }\n\n /**\n * Discovery: GET handler for /openapi.json. OpenAPI 3.1 with the\n * `x-payment-info` pricing extension on every paid operation — the shape\n * x402 tooling (and any catalog built on it) indexes.\n *\n * export const GET = serve.openapi(); // app/openapi.json/route.ts\n */\n openapi(): (req: Request) => Response {\n return (req: Request) =>\n new Response(JSON.stringify(buildOpenApiDocument(this, new URL(req.url).origin), null, 2), {\n headers: { 'content-type': 'application/json', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * Discovery: GET handler for /llms.txt — plain-text guidance agents read\n * to understand what the API sells, what it costs, and how to pay.\n *\n * export const GET = serve.llms(); // app/llms.txt/route.ts\n */\n llms(): (req: Request) => Response {\n return (req: Request) =>\n new Response(buildLlmsTxt(this, new URL(req.url).origin), {\n headers: { 'content-type': 'text/plain; charset=utf-8', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * One fetch handler for the whole app — routes + discovery docs. For\n * fetch-native runtimes (Bun.serve, Deno.serve, Hono, Cloudflare Workers):\n *\n * Bun.serve({ fetch: serve.fetch });\n * app.all('*', (c) => serve.fetch(c.req.raw)); // Hono\n *\n * Next.js apps can skip this and export route handlers directly.\n */\n readonly fetch = async (req: Request): Promise<Response> => {\n const pathname = new URL(req.url).pathname.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (pathname === 'openapi.json') return this.openapi()(req);\n if (pathname === 'llms.txt') return this.llms()(req);\n const route = this.routes.get(pathname);\n if (route) return route(req);\n return new Response(\n JSON.stringify({ error: 'not found', discovery: ['/openapi.json', '/llms.txt'] }),\n { status: 404, headers: { 'content-type': 'application/json' } },\n );\n };\n\n /**\n * The command that sells this API as an x402 Service on your Agent ID,\n * once it is deployed. Listing is a separate, explicit step: the endpoint\n * is live-probed (it must answer 402 with a Sui challenge that pays YOUR\n * wallet) and then recorded on-chain, sponsored and gasless.\n *\n * This used to emit curls against the hosted mpp.t2000.ai catalog. That\n * proxy mall was purged 2026-08-01 (SPEC_T2_CLEANUP_USDC_ONLY) — there is\n * no central catalog to submit to. Your Agent ID IS the listing, and\n * buyers find it with `t2 services`.\n */\n catalogSubmitCommand(deployedUrl?: string): string {\n const base = (deployedUrl ?? this.baseUrl ?? 'https://<your-deployed-app>').replace(/\\/$/, '');\n const paidPaths = [...this.routes.values()].filter((r) => r.meta.priceUsdc);\n const example = paidPaths[0]?.meta.path ?? '<route>';\n return [\n '# Sell it as an x402 Service on your Agent ID (live-probed, gasless):',\n `npx @t2000/cli agent sell ${base}/${example}`,\n '# Buyers then find it with `t2 services` and pay per call with `t2 pay`.',\n ].join('\\n');\n }\n}\n\nexport function createServe(config: ServeConfig): Serve {\n return new Serve(config);\n}\n\n/**\n * Build a Serve from environment variables — the template-app path where\n * config lives in the host's env UI, not code.\n *\n * T2000_PAY_TO required — the seller's Sui address\n * T2000_NETWORK optional — 'mainnet' (default) | 'testnet'\n * T2000_BASE_URL optional — public URL of the deployed app\n * T2000_NAME optional — service name for discovery docs\n * T2000_DESCRIPTION optional — one-liner for discovery docs\n * T2000_ACTIVITY_REPORT_URL\n * optional — where settled payments are reported\n * (fire-and-forget x402.paid after each successful settle;\n * chain-verified server-side, never affects buyer\n * responses). DEFAULT-ON for FromEnv: unset →\n * https://t2000.ai/api/activity/x402 so new sellers appear\n * on the t2000.ai activity tape. Opt out with\n * `false` | `0` | `off` | `none` (case-insensitive), or\n * set a custom URL. (`new Serve({...})` without\n * activityReportUrl stays silent — only FromEnv defaults.)\n * KV_REST_API_URL / KV_REST_API_TOKEN\n * optional — enables the durable Upstash replay store\n * (REQUIRED in serverless production; without it replay\n * state is per-instance memory)\n *\n * Empty strings are treated as unset (the Vercel empty-env bug class).\n */\nexport function createServeFromEnv(env: Record<string, string | undefined> = process.env): Serve {\n const read = (key: string): string | undefined => {\n const v = env[key]?.trim();\n return v && v.length > 0 ? v : undefined;\n };\n\n const payTo = read('T2000_PAY_TO');\n if (!payTo) {\n throw new Error(\n '[serve] T2000_PAY_TO is not set (or is empty). Set it to the Sui address your payments should settle to — `t2 address` prints yours.',\n );\n }\n\n const network = read('T2000_NETWORK');\n if (network && network !== 'mainnet' && network !== 'testnet') {\n throw new Error(`[serve] T2000_NETWORK must be 'mainnet' or 'testnet', got \"${network}\"`);\n }\n\n const kvUrl = read('KV_REST_API_URL');\n const kvToken = read('KV_REST_API_TOKEN');\n const store =\n kvUrl && kvToken ? new UpstashDigestStore({ url: kvUrl, token: kvToken }) : undefined;\n\n if (!store) {\n console.warn(\n '[serve] No KV_REST_API_URL/KV_REST_API_TOKEN — using the in-memory replay store. ' +\n 'Fine for a single long-lived process; on serverless hosts set both so replay protection is durable.',\n );\n }\n\n return new Serve({\n payTo,\n network: (network as ServeNetwork | undefined) ?? 'mainnet',\n baseUrl: read('T2000_BASE_URL'),\n name: read('T2000_NAME'),\n description: read('T2000_DESCRIPTION'),\n activityReportUrl: resolveReportUrlFromEnv(read('T2000_ACTIVITY_REPORT_URL')),\n store,\n });\n}\n\n/** FromEnv activity-report resolution (B2 default-on): unset/empty →\n * the t2000.ai default; an explicit opt-out token → undefined (silent);\n * anything else is the seller's custom report URL. */\nfunction resolveReportUrlFromEnv(raw: string | undefined): string | undefined {\n if (raw === undefined) return DEFAULT_ACTIVITY_REPORT_URL;\n if (REPORT_OPT_OUT.has(raw.toLowerCase())) return undefined;\n return raw;\n}\n","import type { BuiltRoute } from './types.js';\n\n/**\n * Export a built route the way Next.js App Router needs it.\n *\n * Next dispatches ONLY the methods a route.ts exports — serve's own CORS\n * handling (OPTIONS → 204 with the ACAO headers) never runs if the file\n * exports just `POST`: the browser preflight gets Next's bare 204 with no\n * CORS headers, and every browser buyer (Passport, the store's Try it)\n * fails while CLI/server buyers — who never preflight — work fine. Fetch\n * runtimes mounted via a single handler (`serve.fetch`-style) don't have\n * this hole; it is a Next export contract, not a serve one.\n *\n * export const { POST, OPTIONS } = asNextRoute(\n * serve.route({ path: 'haiku' }).paid('0.01').handler(fn),\n * );\n */\nexport function asNextRoute(route: BuiltRoute): {\n POST: BuiltRoute;\n OPTIONS: BuiltRoute;\n} {\n return { POST: route, OPTIONS: route };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/discovery.ts","../src/chain.ts","../src/route.ts","../src/store.ts","../src/serve.ts","../src/next.ts"],"names":["result","USDC_TESTNET","USDC","InMemoryDigestStore"],"mappings":";;;;;;AAgBO,SAAS,oBAAA,CAAqB,OAAc,MAAA,EAA0C;AAC3F,EAAA,MAAM,IAAA,GAAO,MAAM,OAAA,IAAW,MAAA;AAC9B,EAAA,MAAM,QAAiC,EAAC;AAExC,EAAA,KAAA,MAAW,KAAA,IAAS,KAAA,CAAM,MAAA,CAAO,MAAA,EAAO,EAAG;AACzC,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAW,aAAa,WAAA,EAAa,YAAA,KAAiB,KAAA,CAAM,IAAA;AAC1E,IAAA,MAAM,SAAA,GAAqC;AAAA,MACzC,WAAA,EAAa,IAAA,CAAK,OAAA,CAAQ,gBAAA,EAAkB,GAAG,CAAA;AAAA,MAC/C,SAAS,WAAA,IAAe,IAAA;AAAA,MACxB,SAAA,EAAW;AAAA,QACT,OAAO,YAAA,GACH;AAAA,UACE,WAAA,EAAa,SAAA;AAAA,UACb,SAAS,EAAE,kBAAA,EAAoB,EAAE,MAAA,EAAQ,cAAa;AAAE,SAC1D,GACA,EAAE,WAAA,EAAa,SAAA,EAAU;AAAA,QAC7B,GAAI,SAAA,GACA;AAAA,UACE,KAAA,EAAO;AAAA,YACL,WAAA,EACE;AAAA;AACJ,YAEF,EAAC;AAAA,QACL,KAAA,EAAO,EAAE,WAAA,EAAa,2CAAA;AAAuC;AAC/D,KACF;AACA,IAAA,IAAI,SAAA,EAAW;AAIb,MAAA,SAAA,CAAU,gBAAgB,CAAA,GAAI;AAAA,QAC5B,WAAA,EAAa,OAAA;AAAA,QACb,KAAA,EAAO,SAAA;AAAA,QACP,QAAA,EAAU,MAAA;AAAA,QACV,SAAA,EAAW,CAAC,KAAA,EAAO,MAAM,CAAA;AAAA,QACzB,IAAA,EAAM;AAAA,UACJ,MAAA,EAAQ,OAAA;AAAA,UACR,OAAA,EAAS,CAAA,IAAA,EAAO,KAAA,CAAM,OAAO,CAAA,CAAA;AAAA,UAC7B,KAAA,EAAA,CAAQ,KAAA,CAAM,OAAA,KAAY,SAAA,GAAY,eAAe,IAAA,EAAM,IAAA;AAAA,UAC3D,OAAO,KAAA,CAAM;AAAA;AACf,OACF;AAAA,IACF;AACA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,SAAA,CAAU,WAAA,GAAc;AAAA,QACtB,QAAA,EAAU,IAAA;AAAA,QACV,SAAS,EAAE,kBAAA,EAAoB,EAAE,MAAA,EAAQ,aAAY;AAAE,OACzD;AAAA,IACF;AACA,IAAA,KAAA,CAAM,IAAI,IAAI,CAAA,CAAE,CAAA,GAAI,EAAE,MAAM,SAAA,EAAU;AAAA,EACxC;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,OAAA;AAAA,IACT,IAAA,EAAM;AAAA,MACJ,KAAA,EAAO,MAAM,IAAA,IAAQ,UAAA;AAAA,MACrB,OAAA,EAAS,OAAA;AAAA,MACT,WAAA,EACE,MAAM,WAAA,IACN;AAAA,KACJ;AAAA,IACA,GAAI,IAAA,GAAO,EAAE,OAAA,EAAS,CAAC,EAAE,GAAA,EAAK,IAAA,EAAM,CAAA,EAAE,GAAI,EAAC;AAAA,IAC3C;AAAA,GACF;AACF;AAEO,SAAS,YAAA,CAAa,OAAc,MAAA,EAAyB;AAClE,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,IAAW,MAAA,IAAU,EAAA;AACxC,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAA,EAAK,KAAA,CAAM,IAAA,IAAQ,UAAU,CAAA,CAAE,CAAA;AAC1C,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,IAAI,MAAM,WAAA,EAAa;AACrB,IAAA,KAAA,CAAM,IAAA,CAAK,MAAM,WAAW,CAAA;AAC5B,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACf;AACA,EAAA,KAAA,CAAM,KAAK,eAAe,CAAA;AAC1B,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,oFAAA;AAAA,IACA,uFAAA;AAAA,IACA,wFAAA;AAAA,IACA,EAAA;AAAA,IACA,2EAAA;AAAA,IACA,iEAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,KAAA,CAAM,KAAK,cAAc,CAAA;AACzB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,MAAW,KAAA,IAAS,KAAA,CAAM,MAAA,CAAO,MAAA,EAAO,EAAG;AACzC,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAW,aAAa,WAAA,EAAa,YAAA,KAAiB,KAAA,CAAM,IAAA;AAC1E,IAAA,MAAM,KAAA,GAAQ,SAAA,GAAY,CAAA,EAAG,SAAS,CAAA,cAAA,CAAA,GAAmB,MAAA;AACzD,IAAA,KAAA,CAAM,KAAK,CAAA,SAAA,EAAY,IAAI,IAAI,IAAI,CAAA,QAAA,EAAM,KAAK,CAAA,CAAE,CAAA;AAChD,IAAA,IAAI,WAAA,EAAa,KAAA,CAAM,IAAA,CAAK,WAAW,CAAA;AACvC,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,KAAA,CAAM,KAAK,6BAA6B,CAAA;AACxC,MAAA,KAAA,CAAM,KAAK,SAAS,CAAA;AACpB,MAAA,KAAA,CAAM,KAAK,IAAA,CAAK,SAAA,CAAU,WAAA,EAAa,IAAA,EAAM,CAAC,CAAC,CAAA;AAC/C,MAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,IAClB;AACA,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,KAAA,CAAM,KAAK,+FAA0F,CAAA;AACrG,MAAA,KAAA,CAAM,KAAK,SAAS,CAAA;AACpB,MAAA,KAAA,CAAM,KAAK,IAAA,CAAK,SAAA,CAAU,YAAA,EAAc,IAAA,EAAM,CAAC,CAAC,CAAA;AAChD,MAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,IAClB;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACf;AACA,EAAA,KAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,IAAI,CAAA,aAAA,CAAe,CAAA;AAC5C,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AClHA,IAAM,aAAA,GAA8C;AAAA,EAClD,OAAA,EAAS,qCAAA;AAAA,EACT,OAAA,EAAS;AACX,CAAA;AAEA,IAAM,YAAA,GAAe,KAAK,EAAA,GAAK,GAAA;AAa/B,IAAM,QAAmD,EAAC;AAEnD,SAAS,aAAA,CAAc,SAAuB,MAAA,EAAgC;AACnF,EAAA,MAAM,CAAA,GAAK,KAAA,CAAM,OAAO,CAAA,KAAM,EAAC;AAC/B,EAAA,IAAI,CAAC,EAAE,MAAA,EAAQ;AACb,IAAA,CAAA,CAAE,MAAA,GAAS,IAAI,aAAA,CAAc;AAAA,MAC3B,OAAA,EAAS,MAAA,IAAU,aAAA,CAAc,OAAO,CAAA;AAAA,MACxC;AAAA,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,CAAA,CAAE,MAAA;AACX;AAEA,eAAsB,YAAA,CAAa,SAAuB,MAAA,EAAqC;AAC7F,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,OAAA,EAAS,MAAM,CAAA;AAC5C,EAAA,MAAM,CAAA,GAAK,KAAA,CAAM,OAAO,CAAA,KAAM,EAAC;AAC/B,EAAA,IAAI,CAAC,EAAE,OAAA,EAAS;AACd,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,IAAA,CAAK,kBAAA,EAAmB;AACjD,IAAA,CAAA,CAAE,UAAU,GAAA,CAAI,eAAA;AAAA,EAClB;AACA,EAAA,IAAI,CAAC,EAAE,KAAA,IAAS,IAAA,CAAK,KAAI,GAAI,CAAA,CAAE,KAAA,CAAM,SAAA,GAAY,YAAA,EAAc;AAC7D,IAAA,MAAM,GAAA,GAAM,MAAM,MAAA,CAAO,IAAA,CAAK,qBAAA,EAAsB;AACpD,IAAA,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,WAAA,CAAY,KAAK,CAAA,EAAG,SAAA,EAAW,IAAA,CAAK,GAAA,EAAI,EAAE;AAAA,EAC1E;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,CAAA,CAAE,SAAS,KAAA,EAAO,CAAA,CAAE,MAAM,KAAA,EAAM;AAClD;AAGO,SAAS,kBAAA,GAA2B;AACzC,EAAA,OAAO,KAAA,CAAM,OAAA;AACb,EAAA,OAAO,KAAA,CAAM,OAAA;AACf;AAGO,SAAS,eAAA,CAAgB,OAAA,EAAuB,KAAA,EAAe,KAAA,EAAqB;AACzF,EAAA,MAAM,CAAA,GAAK,KAAA,CAAM,OAAO,CAAA,KAAM,EAAC;AAC/B,EAAA,CAAA,CAAE,OAAA,GAAU,KAAA;AACZ,EAAA,CAAA,CAAE,QAAQ,EAAE,KAAA,EAAO,OAAO,SAAA,EAAW,IAAA,CAAK,KAAI,EAAE;AAClD;;;ACNA,IAAM,sBAAA,GAAyB,CAAA;AAE/B,IAAM,YAAA,GAAuC;AAAA,EAC3C,6BAAA,EAA+B,GAAA;AAAA,EAC/B,8BAAA,EAAgC,iCAAA;AAAA,EAChC,8BAAA,EAAgC,iBAAiB,mBAAmB,CAAA,CAAA;AAAA,EACpE,+BAAA,EAAiC,GAAG,4BAA4B,CAAA,kBAAA;AAClE,CAAA;AAEA,SAAS,SAAS,QAAA,EAA8B;AAC9C,EAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,QAAA,CAAS,OAAO,CAAA;AAC5C,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,MAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,EAAG,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA;AACnE,EAAA,OAAO,IAAI,SAAS,QAAA,CAAS,IAAA,EAAM,EAAE,MAAA,EAAQ,QAAA,CAAS,MAAA,EAAQ,OAAA,EAAS,CAAA;AACzE;AAEA,SAAS,IAAA,CAAK,MAAA,EAAgB,IAAA,EAAe,OAAA,EAA4C;AACvF,EAAA,OAAO,QAAA;AAAA,IACL,IAAI,QAAA,CAAS,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA,EAAG;AAAA,MACjC,MAAA;AAAA,MACA,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,GAAG,OAAA;AAAQ,KAC3D;AAAA,GACH;AACF;AAEA,SAAS,iBAAiB,MAAA,EAAmD;AAC3E,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,QAAQ,WAAA,IAAe,MAAA;AACzE;AAEA,eAAe,YAAA,CACb,QACA,KAAA,EACuE;AACvE,EAAA,IAAI,gBAAA,CAAiB,MAAM,CAAA,EAAG;AAC5B,IAAA,MAAMA,UAAS,MAAM,MAAA,CAAO,WAAW,CAAA,CAAE,SAAS,KAAK,CAAA;AACvD,IAAA,IAAIA,QAAO,MAAA,EAAQ;AAGjB,MAAA,MAAM,OAAA,GAAUA,OAAAA,CAAO,MAAA,CACpB,GAAA,CAAI,CAAC,CAAA,KAAM;AACV,QAAA,MAAM,IAAA,GAAA,CAAQ,EAAE,IAAA,IAAQ,IACrB,GAAA,CAAI,CAAC,QAAS,OAAO,GAAA,KAAQ,WAAW,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,GAAI,MAAA,CAAO,GAAG,CAAE,CAAA,CACtE,KAAK,GAAG,CAAA;AACX,QAAA,OAAO,OAAO,CAAA,EAAG,IAAI,KAAK,CAAA,CAAE,OAAO,KAAK,CAAA,CAAE,OAAA;AAAA,MAC5C,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AACZ,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAQ;AAAA,IAC9B;AACA,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAMA,QAAO,KAAA,EAAM;AAAA,EACxC;AACA,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,KAAK,CAAA;AACrC,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,SAAS,MAAA,CAAO,KAAA,CAAM,WAAW,cAAA,EAAe;AAAA,EACtE;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,OAAO,IAAA,EAAK;AACvC;AAGA,SAAS,gBAAA,CAAiB,OAAe,IAAA,EAAoB;AAC3D,EAAA,IAAI,CAAC,oBAAoB,IAAA,CAAK,KAAK,KAAK,MAAA,CAAO,KAAK,KAAK,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,eAAA,EAAkB,IAAI,CAAA,4EAAA,EAA+E,KAAK,CAAA,CAAA;AAAA,KAC5G;AAAA,EACF;AACA,EAAA,IAAI,MAAA,CAAO,KAAK,CAAA,GAAI,sBAAA,EAAwB;AAC1C,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN,CAAA,eAAA,EAAkB,IAAI,CAAA,SAAA,EAAY,KAAK,sBAAsB,sBAAsB,CAAA,gJAAA;AAAA,KAErF;AAAA,EACF;AACF;AAEO,IAAM,eAAN,MAAsC;AAAA,EAO3C,WAAA,CACmB,OAAA,EACA,OAAA,EACA,QAAA,EACjB;AAHiB,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA;AACA,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAAA,EAChB;AAAA,EAVK,SAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA,GAAS,KAAA;AAAA;AAAA,EASjB,KAAK,SAAA,EAAyB;AAC5B,IAAA,gBAAA,CAAiB,SAAA,EAAW,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA,EAGA,WAAA,GAAoB;AAClB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA;AACd,IAAA,IAAA,CAAK,SAAA,GAAY,MAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,IAAA,CAAQ,QAAwB,UAAA,EAAuD;AACrF,IAAA,IAAA,CAAK,UAAA,GAAa,MAAA;AAClB,IAAA,IAAA,CAAK,WAAA,GAAc,UAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,SAAS,UAAA,EAA2C;AAClD,IAAA,IAAA,CAAK,YAAA,GAAe,UAAA;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,QAAQ,EAAA,EAAwF;AAC9F,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,IAAU,CAAC,KAAK,SAAA,EAAW;AACnC,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,eAAA,EAAkB,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAA,2DAAA;AAAA,OACrC;AAAA,IACF;AACA,IAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AACrB,IAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAY,GAAI,IAAA,CAAK,OAAA;AACnC,IAAA,MAAM,YAAY,IAAA,CAAK,SAAA;AACvB,IAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AAExB,IAAA,MAAM,KAAA,IAAS,OAAO,GAAA,KAAoC;AACxD,MAAA,IAAI,GAAA,CAAI,WAAW,SAAA,EAAW;AAC5B,QAAA,OAAO,QAAA,CAAS,IAAI,QAAA,CAAS,IAAA,EAAM,EAAE,MAAA,EAAQ,GAAA,EAAK,CAAC,CAAA;AAAA,MACrD;AAKA,MAAA,IAAI,UAAA;AACJ,MAAA,IAAI,cAAA;AACJ,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,KAAA,IAAS,GAAA,CAAI,WAAW,MAAA,EAAQ;AACjD,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,QAAA,IAAI,IAAA,CAAK,IAAA,EAAK,CAAE,MAAA,GAAS,CAAA,EAAG;AAC1B,UAAA,IAAI;AACF,YAAA,UAAA,GAAa,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,UAC9B,CAAA,CAAA,MAAQ;AACN,YAAA,cAAA,GAAiB,gCAAA;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,QAAA,GAAA,CAAY,OAAA,CAAQ,OAAA,IAAW,IAAI,IAAI,GAAA,CAAI,GAAG,CAAA,CAAE,MAAA,EAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GAAI,IAAI,IAAI,CAAA,CAAA;AAE3F,MAAA,MAAM,UAAA,GAAa,OAAO,KAAA,KAAsC;AAC9D,QAAA,IAAI,SAAA,GAAqB,UAAA;AACzB,QAAA,IAAI,UAAA,EAAY;AAGd,UAAA,IAAI,cAAA,EAAgB;AAClB,YAAA,OAAO,KAAK,GAAA,EAAK,EAAE,OAAO,cAAA,EAAgB,IAAA,EAAM,OAAO,CAAA;AAAA,UACzD;AACA,UAAA,MAAM,SAAS,MAAM,YAAA,CAAa,UAAA,EAAY,UAAA,IAAc,EAAE,CAAA;AAC9D,UAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AACd,YAAA,OAAO,IAAA,CAAK,KAAK,EAAE,KAAA,EAAO,OAAO,OAAA,EAAS,IAAA,EAAM,OAAO,CAAA;AAAA,UACzD;AACA,UAAA,SAAA,GAAY,MAAA,CAAO,IAAA;AAAA,QACrB;AACA,QAAA,MAAM,GAAA,GAAM,MAAM,EAAA,CAAG,EAAE,MAAM,SAAA,EAAoB,GAAA,EAAK,OAAO,CAAA;AAC7D,QAAA,IAAI,GAAA,YAAe,QAAA,EAAU,OAAO,QAAA,CAAS,GAAG,CAAA;AAChD,QAAA,OAAO,IAAA,CAAK,KAAK,GAAG,CAAA;AAAA,MACtB,CAAA;AAGA,MAAA,IAAI,CAAC,SAAA,EAAW;AACd,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,UAAA,EAAW;AAAA,QAC1B,SAAS,GAAA,EAAK;AACZ,UAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,iBAAA,CAAA,EAAqB,GAAG,CAAA;AAC5D,UAAA,OAAO,IAAA,CAAK,GAAA,EAAK,EAAE,KAAA,EAAO,kBAAkB,CAAA;AAAA,QAC9C;AAAA,MACF;AAEA,MAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,mBAAmB,CAAA;AAMzD,MAAA,IAAI,CAAC,aAAA,EAAe;AAClB,QAAA,OAAO,MAAM,UAAA,CAAW,OAAA,EAAS,EAAE,QAAA,EAAU,WAAW,CAAA;AAAA,MAC1D;AAEA,MAAA,IAAI,kBAAA,CAAmB,aAAa,CAAA,EAAG;AACrC,QAAA,OAAO,MAAM,WAAW,OAAA,EAAS;AAAA,UAC/B,QAAA;AAAA,UACA,SAAA;AAAA,UACA,KAAA,EACE;AAAA,SACH,CAAA;AAAA,MACH;AAKA,MAAA,IAAI,OAAA;AACJ,MAAA,IAAI;AACF,QAAA,OAAA,GAAU,gBAAgB,aAAa,CAAA;AACvC,QAAA,iBAAA,CAAkB;AAAA,UAChB,OAAA;AAAA,UACA,QAAA,EAAU;AAAA,YACR,WAAA,EAAa,QAAQ,OAAA,CAAQ,WAAA;AAAA,YAC7B,MAAA,EAAQ,SAAA;AAAA,YACR,UAAU,OAAA,CAAQ,QAAA;AAAA,YAClB,WAAW,OAAA,CAAQ,KAAA;AAAA,YACnB,SAAS,OAAA,CAAQ;AAAA;AACnB,SACD,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,OAAO,MAAM,WAAW,OAAA,EAAS;AAAA,UAC/B,QAAA;AAAA,UACA,SAAA;AAAA,UACA,KAAA,EAAO,oBAAoB,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,SAC5E,CAAA;AAAA,MACH;AAKA,MAAA,MAAM,YAAA,GAAe,CAAA,UAAA,EAAa,OAAA,CAAQ,OAAA,CAAQ,WAAW,CAAA,CAAA;AAC7D,MAAA,IAAI,MAAM,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,YAAY,CAAA,EAAG;AACzC,QAAA,OAAO,MAAM,WAAW,OAAA,EAAS;AAAA,UAC/B,QAAA;AAAA,UACA,SAAA;AAAA,UACA,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAIA,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,OAAA,CAAQ,aAAa,CAAA;AAAA,MACzD,SAAS,GAAA,EAAK;AACZ,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,eAAA,EAAkB,IAAI,CAAA,uCAAA,CAAA,EAA2C,GAAG,CAAA;AAClF,QAAA,OAAO,IAAA,CAAK,GAAA,EAAK,EAAE,KAAA,EAAO,8CAAyC,CAAA;AAAA,MACrE;AACA,MAAA,IAAI,MAAA,CAAO,MAAA,IAAU,GAAA,EAAK,OAAO,MAAA;AAIjC,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AACF,QAAA,MAAA,GAAS,MAAM,iBAAA,CAAkB;AAAA,UAC/B,OAAA;AAAA,UACA,MAAA,EAAQ,aAAA,CAAc,OAAA,CAAQ,OAAA,EAAS,QAAQ,MAAM,CAAA;AAAA,UACrD,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,QAAA,EAAU;AAAA,YACR,WAAA,EAAa,QAAQ,OAAA,CAAQ,WAAA;AAAA,YAC7B,MAAA,EAAQ,SAAA;AAAA,YACR,UAAU,OAAA,CAAQ,QAAA;AAAA,YAClB,WAAW,OAAA,CAAQ,KAAA;AAAA,YACnB,SAAS,OAAA,CAAQ;AAAA;AACnB,SACD,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,OAAO,MAAM,WAAW,OAAA,EAAS;AAAA,UAC/B,QAAA;AAAA,UACA,SAAA;AAAA,UACA,KAAA,EAAO,sBAAsB,GAAA,YAAe,KAAA,GAAQ,IAAI,OAAA,GAAU,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,SAC9E,CAAA;AAAA,MACH;AAGA,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,CAAQ,KAAA,CAAM,GAAA,CAAI,YAAY,CAAA;AAAA,MACtC,CAAA,CAAA,MAAQ;AAAA,MAER;AAKA,MAAA,cAAA,CAAe,OAAA,EAAS;AAAA,QACtB,QAAQ,MAAA,CAAO,WAAA;AAAA,QACf,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,SAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,MAAA,CAAO,OAAO,CAAA;AAC1C,MAAA,OAAA,CAAQ,GAAA,CAAI,4BAAA,EAA8B,kBAAA,CAAmB,MAAM,CAAC,CAAA;AACpE,MAAA,OAAO,IAAI,SAAS,MAAA,CAAO,IAAA,EAAM,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAA,IACrE,CAAA,CAAA;AAEA,IAAA,KAAA,CAAM,IAAA,GAAO;AAAA,MACX,IAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,UAAA;AAAA,MACA,aAAa,IAAA,CAAK,WAAA;AAAA,MAClB,cAAc,IAAA,CAAK;AAAA,KACrB;AACA,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AACnB,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAKA,SAAS,cAAA,CACP,SACA,IAAA,EACM;AACN,EAAA,MAAM,MAAM,OAAA,CAAQ,iBAAA;AACpB,EAAA,IAAI,CAAC,GAAA,EAAK;AACV,EAAA,IAAI;AACF,IAAA,KAAK,MAAM,GAAA,EAAK;AAAA,MACd,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,MAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,OAAO,IAAA,CAAK,KAAA;AAAA,QACZ,iBAAiB,IAAA,CAAK,KAAA,CAAM,OAAO,IAAA,CAAK,SAAS,IAAI,GAAS,CAAA;AAAA,QAC9D,OAAA,EAAS,CAAA,IAAA,EAAO,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,QAC/B,OAAO,IAAA,CAAK,QAAA;AAAA,QACZ,MAAA,EAAQ;AAAA,OACT,CAAA;AAAA,MACD,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,IAAI;AAAA,KACjC,CAAA,CAAE,KAAA,CAAM,MAAM,KAAA,CAAS,CAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEA,eAAe,UAAA,CACb,SACA,IAAA,EACmB;AACnB,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,OAAO,KAAA,EAAM,GAAI,MAAM,YAAA,CAAa,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,MAAM,CAAA;AAC3E,IAAA,MAAM,eAAe,sBAAA,CAAuB;AAAA,MAC1C,WAAA,EAAa,OAAO,UAAA,EAAW;AAAA,MAC/B,QAAQ,IAAA,CAAK,SAAA;AAAA,MACb,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,WAAW,OAAA,CAAQ,KAAA;AAAA,MACnB,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,KAAA;AAAA,MACA,YAAA,EAAc;AAAA,KACf,CAAA;AAQD,IAAA,MAAM,QAAQ,MAAM;AAClB,MAAA,IAAI;AACF,QAAA,OAAO,IAAI,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA,CAAE,QAAA;AAAA,MAChC,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,KAAA,CAAA;AAAA,MACT;AAAA,IACF,CAAA,GAAG;AACH,IAAA,MAAM,OAAA,GAAU,CAAA,eAAA,EAAkB,IAAA,IAAQ,MAAM,CAAA,cAAA,EAAiB,OAAA,CAAQ,KAAK,CAAA,aAAA,EAAgB,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,WAAA,EAAc,KAAK,SAAS,CAAA,CAAA,CAAA;AAC/I,IAAA,OAAO,IAAA;AAAA,MACL,GAAA;AAAA,MACA;AAAA,QACE,WAAA,EAAa,YAAA;AAAA,QACb,KAAA,EAAO,KAAK,KAAA,IAAS,kBAAA;AAAA,QACrB,OAAA,EAAS,CAAC,YAAY;AAAA,OACxB;AAAA,MACA,EAAE,oBAAoB,OAAA;AAAQ,KAChC;AAAA,EACF,SAAS,GAAA,EAAK;AAGZ,IAAA,OAAA,CAAQ,KAAA,CAAM,0CAA0C,GAAG,CAAA;AAC3D,IAAA,OAAO,IAAA,CAAK,GAAA,EAAK,EAAE,KAAA,EAAO,6CAA6C,CAAA;AAAA,EACzE;AACF;ACnbA,IAAM,mBAAA,GAAsB,KAAK,EAAA,GAAK,EAAA;AACtC,IAAM,MAAA,GAAS,eAAA;AASR,IAAM,qBAAN,MAAgD;AAAA,EACpC,GAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EAEjB,YAAY,OAAA,EAAoC;AAC9C,IAAA,IAAA,CAAK,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,OAAA,CAAQ,OAAO,EAAE,CAAA;AACxC,IAAA,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,QAAQ,UAAA,IAAc,mBAAA;AAAA,EAC1C;AAAA,EAEA,MAAc,QAAQ,QAAA,EAAsC;AAC1D,IAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,KAAK,GAAG,CAAA,CAAA,EAAI,QAAA,CAAS,GAAA,CAAI,kBAAkB,CAAA,CAAE,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,EAAI;AAAA,MACnF,SAAS,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA;AAAG,KAClD,CAAA;AACD,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,GAAA,CAAI,MAAM,IAAI,MAAM,GAAA,CAAI,IAAA,EAAM,CAAA,CAAE,CAAA;AAAA,IAC7E;AACA,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7B,IAAA,IAAI,IAAA,CAAK,OAAO,MAAM,IAAI,MAAM,CAAA,eAAA,EAAkB,IAAA,CAAK,KAAK,CAAA,CAAE,CAAA;AAC9D,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEA,MAAM,IAAI,MAAA,EAAkC;AAC1C,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,CAAC,KAAA,EAAO,MAAA,GAAS,MAAM,CAAC,CAAA;AAC1D,IAAA,OAAO,MAAA,KAAW,QAAQ,MAAA,KAAW,MAAA;AAAA,EACvC;AAAA,EAEA,MAAM,IAAI,MAAA,EAA+B;AAGvC,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,OAAA,CAAQ;AAAA,MAChC,KAAA;AAAA,MACA,MAAA,GAAS,MAAA;AAAA,MACT,GAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA,CAAO,KAAK,UAAU,CAAA;AAAA,MACtB;AAAA,KACD,CAAA;AACD,IAAA,IAAI,MAAA,KAAW,IAAA,IAAQ,MAAA,KAAW,MAAA,EAAW;AAC3C,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,qBAAA,EAAwB,MAAM,CAAA,CAAE,CAAA;AAAA,IAClD;AAAA,EACF;AACF;;;AC7DO,IAAM,2BAAA,GAA8B;AAG3C,IAAM,cAAA,uBAAqB,GAAA,CAAI,CAAC,SAAS,GAAA,EAAK,KAAA,EAAO,MAAM,CAAC,CAAA;AAErD,IAAM,QAAN,MAAY;AAAA,EACA,OAAA;AAAA;AAAA,EAER,MAAA,uBAAa,GAAA,EAAwB;AAAA,EAErC,KAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA;AAAA,EACA,OAAA;AAAA;AAAA,EAEA,iBAAA;AAAA,EAET,YAAY,MAAA,EAAqB;AAC/B,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,CAAC,iBAAA,CAAkB,MAAA,CAAO,KAAK,CAAA,EAAG;AACrD,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,qFAAA,EAAwF,OAAO,KAAK,CAAA,CAAA;AAAA,OACtG;AAAA,IACF;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,mBAAA,CAAoB,MAAA,CAAO,KAAK,CAAA;AAC7C,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,SAAA;AACjC,IAAA,IAAA,CAAK,OAAO,MAAA,CAAO,IAAA;AACnB,IAAA,IAAA,CAAK,cAAc,MAAA,CAAO,WAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,CAAO,OAAA,EAAS,OAAA,CAAQ,OAAO,EAAE,CAAA;AAChD,IAAA,IAAA,CAAK,oBAAoB,MAAA,CAAO,iBAAA;AAEhC,IAAA,MAAM,QAAA,GAAqB,IAAA,CAAK,OAAA,KAAY,SAAA,GAAYC,YAAAA,GAAeC,IAAAA;AACvE,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAA;AAAA,MACA,KAAA,EAAO,MAAA,CAAO,KAAA,IAAS,IAAIC,mBAAAA,EAAoB;AAAA,MAC/C,SAAS,IAAA,CAAK,OAAA;AAAA,MACd,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,mBAAmB,IAAA,CAAK;AAAA,KAC1B;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,OAAA,EAAqC;AACzC,IAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,CAAK,OAAA,CAAQ,QAAQ,EAAE,CAAA,CAAE,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAChE,IAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,sCAAsC,CAAA;AACjE,IAAA,OAAO,IAAI,YAAA,CAAa,EAAE,GAAG,IAAA,CAAK,OAAA,EAAQ,EAAG,EAAE,GAAG,OAAA,EAAS,IAAA,EAAK,EAAG,CAAC,KAAA,KAAU;AAC5E,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,IAAA,EAAM,KAAK,CAAA;AAAA,IAC7B,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAA,GAAsC;AACpC,IAAA,OAAO,CAAC,GAAA,KACN,IAAI,QAAA,CAAS,IAAA,CAAK,UAAU,oBAAA,CAAqB,IAAA,EAAM,IAAI,GAAA,CAAI,IAAI,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG,IAAA,EAAM,CAAC,CAAA,EAAG;AAAA,MACzF,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAoB,+BAA+B,GAAA;AAAI,KACnF,CAAA;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAA,GAAmC;AACjC,IAAA,OAAO,CAAC,GAAA,KACN,IAAI,QAAA,CAAS,YAAA,CAAa,IAAA,EAAM,IAAI,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,MAAM,CAAA,EAAG;AAAA,MACxD,OAAA,EAAS,EAAE,cAAA,EAAgB,2BAAA,EAA6B,+BAA+B,GAAA;AAAI,KAC5F,CAAA;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWS,KAAA,GAAQ,OAAO,GAAA,KAAoC;AAC1D,IAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,CAAE,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,CAAE,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACjF,IAAA,IAAI,aAAa,cAAA,EAAgB,OAAO,IAAA,CAAK,OAAA,GAAU,GAAG,CAAA;AAC1D,IAAA,IAAI,aAAa,UAAA,EAAY,OAAO,IAAA,CAAK,IAAA,GAAO,GAAG,CAAA;AACnD,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,QAAQ,CAAA;AACtC,IAAA,IAAI,KAAA,EAAO,OAAO,KAAA,CAAM,GAAG,CAAA;AAC3B,IAAA,OAAO,IAAI,QAAA;AAAA,MACT,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,WAAA,EAAa,WAAW,CAAC,eAAA,EAAiB,WAAW,CAAA,EAAG,CAAA;AAAA,MAChF,EAAE,MAAA,EAAQ,GAAA,EAAK,SAAS,EAAE,cAAA,EAAgB,oBAAmB;AAAE,KACjE;AAAA,EACF,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,qBAAqB,WAAA,EAA8B;AACjD,IAAA,MAAM,QAAQ,WAAA,IAAe,IAAA,CAAK,WAAW,6BAAA,EAA+B,OAAA,CAAQ,OAAO,EAAE,CAAA;AAC7F,IAAA,MAAM,SAAA,GAAY,CAAC,GAAG,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,SAAS,CAAA;AAC1E,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,CAAC,CAAA,EAAG,KAAK,IAAA,IAAQ,SAAA;AAC3C,IAAA,OAAO;AAAA,MACL,uEAAA;AAAA,MACA,CAAA,0BAAA,EAA6B,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAAA,MAC5C;AAAA,KACF,CAAE,KAAK,IAAI,CAAA;AAAA,EACb;AACF;AAEO,SAAS,YAAY,MAAA,EAA4B;AACtD,EAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACzB;AA4BO,SAAS,kBAAA,CAAmB,GAAA,GAA0C,OAAA,CAAQ,GAAA,EAAY;AAC/F,EAAA,MAAM,IAAA,GAAO,CAAC,GAAA,KAAoC;AAChD,IAAA,MAAM,CAAA,GAAI,GAAA,CAAI,GAAG,CAAA,EAAG,IAAA,EAAK;AACzB,IAAA,OAAO,CAAA,IAAK,CAAA,CAAE,MAAA,GAAS,CAAA,GAAI,CAAA,GAAI,MAAA;AAAA,EACjC,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,KAAK,cAAc,CAAA;AACjC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,KAAK,eAAe,CAAA;AACpC,EAAA,IAAI,OAAA,IAAW,OAAA,KAAY,SAAA,IAAa,OAAA,KAAY,SAAA,EAAW;AAC7D,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2DAAA,EAA8D,OAAO,CAAA,CAAA,CAAG,CAAA;AAAA,EAC1F;AAEA,EAAA,MAAM,KAAA,GAAQ,KAAK,iBAAiB,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,KAAK,mBAAmB,CAAA;AACxC,EAAA,MAAM,KAAA,GACJ,KAAA,IAAS,OAAA,GAAU,IAAI,kBAAA,CAAmB,EAAE,GAAA,EAAK,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,CAAA,GAAI,MAAA;AAE9E,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAA,CAAQ,IAAA;AAAA,MACN;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,OAAO,IAAI,KAAA,CAAM;AAAA,IACf,KAAA;AAAA,IACA,SAAU,OAAA,IAAwC,SAAA;AAAA,IAClD,OAAA,EAAS,KAAK,gBAAgB,CAAA;AAAA,IAC9B,IAAA,EAAM,KAAK,YAAY,CAAA;AAAA,IACvB,WAAA,EAAa,KAAK,mBAAmB,CAAA;AAAA,IACrC,iBAAA,EAAmB,uBAAA,CAAwB,IAAA,CAAK,2BAA2B,CAAC,CAAA;AAAA,IAC5E;AAAA,GACD,CAAA;AACH;AAKA,SAAS,wBAAwB,GAAA,EAA6C;AAC5E,EAAA,IAAI,GAAA,KAAQ,QAAW,OAAO,2BAAA;AAC9B,EAAA,IAAI,eAAe,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,GAAG,OAAO,MAAA;AAClD,EAAA,OAAO,GAAA;AACT;;;ACjMO,SAAS,YAAY,KAAA,EAG1B;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,KAAA,EAAM;AACvC","file":"index.js","sourcesContent":["import { USDC, USDC_TESTNET } from '@t2000/sui-x402';\nimport type { Serve } from './serve.js';\n\n// ---------------------------------------------------------------------------\n// Discovery docs — /openapi.json + /llms.txt.\n//\n// The shapes here are what the on-chain listing probe grades (the check\n// behind `t2 agent sell`) (was: apps/gateway/lib/\n// catalog-ingest.ts `gradeListing`): a warning-free listing needs info.title,\n// a one-paragraph info.description, a flat string `x-payment-info.price` per\n// paid operation, and an application/json requestBody schema with typed\n// properties. Everything serve can derive is emitted automatically; the JSON\n// request schema comes from the route's `inputSchema` (zod v4 users:\n// `z.toJSONSchema(schema)`).\n// ---------------------------------------------------------------------------\n\nexport function buildOpenApiDocument(serve: Serve, origin?: string): Record<string, unknown> {\n const base = serve.baseUrl ?? origin;\n const paths: Record<string, unknown> = {};\n\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const operation: Record<string, unknown> = {\n operationId: path.replace(/[^a-zA-Z0-9]+/g, '_'),\n summary: description ?? path,\n responses: {\n '200': outputSchema\n ? {\n description: 'Success',\n content: { 'application/json': { schema: outputSchema } },\n }\n : { description: 'Success' },\n ...(priceUsdc\n ? {\n '402': {\n description:\n 'Payment required — the body carries an x402 accepts[] envelope (scheme \"exact\", network sui). Sign it and retry with the X-PAYMENT header.',\n },\n }\n : {}),\n '422': { description: 'Invalid request body — never charged' },\n },\n };\n if (priceUsdc) {\n // Same shape the gateway's own /openapi.json emits: 'mpp' is the\n // protocol family, 'x402' the dialect; the x402 block mirrors the\n // static half of the live accepts[] entry (dynamic fields ride the 402).\n operation['x-payment-info'] = {\n pricingMode: 'fixed',\n price: priceUsdc,\n currency: 'USDC',\n protocols: ['mpp', 'x402'],\n x402: {\n scheme: 'exact',\n network: `sui:${serve.network}`,\n asset: (serve.network === 'testnet' ? USDC_TESTNET : USDC).type,\n payTo: serve.payTo,\n },\n };\n }\n if (inputSchema) {\n operation.requestBody = {\n required: true,\n content: { 'application/json': { schema: inputSchema } },\n };\n }\n paths[`/${path}`] = { post: operation };\n }\n\n return {\n openapi: '3.1.0',\n info: {\n title: serve.name ?? 'Paid API',\n version: '1.0.0',\n description:\n serve.description ??\n 'Agent-payable API. Every paid endpoint answers 402 with an x402 accepts[] envelope; payment settles in USDC on Sui.',\n },\n ...(base ? { servers: [{ url: base }] } : {}),\n paths,\n };\n}\n\nexport function buildLlmsTxt(serve: Serve, origin?: string): string {\n const base = serve.baseUrl ?? origin ?? '';\n const lines: string[] = [];\n lines.push(`# ${serve.name ?? 'Paid API'}`);\n lines.push('');\n if (serve.description) {\n lines.push(serve.description);\n lines.push('');\n }\n lines.push('## How to pay');\n lines.push('');\n lines.push(\n 'Endpoints below are paid per call in USDC on Sui (x402). An unpaid request returns',\n 'HTTP 402 with an `accepts[]` envelope; sign it and retry with the `X-PAYMENT` header.',\n 'Invalid input returns 422 before any payment is taken. A failed call is never charged.',\n '',\n 'Easiest client: `npm i -g @t2000/cli` then `t2 pay <url> --data \\'{...}\\'`,',\n 'or the t2000 MCP server (`t2000_pay`), or `@t2000/sdk` `pay()`.',\n '',\n );\n lines.push('## Endpoints');\n lines.push('');\n for (const route of serve.routes.values()) {\n const { path, priceUsdc, description, inputSchema, outputSchema } = route.meta;\n const price = priceUsdc ? `${priceUsdc} USDC per call` : 'free';\n lines.push(`### POST ${base}/${path} — ${price}`);\n if (description) lines.push(description);\n if (inputSchema) {\n lines.push('Request body (JSON Schema):');\n lines.push('```json');\n lines.push(JSON.stringify(inputSchema, null, 2));\n lines.push('```');\n }\n if (outputSchema) {\n lines.push('Response (JSON Schema — contentMediaType/format annotations name the deliverable types):');\n lines.push('```json');\n lines.push(JSON.stringify(outputSchema, null, 2));\n lines.push('```');\n }\n lines.push('');\n }\n lines.push(`Discovery: ${base}/openapi.json`);\n return lines.join('\\n');\n}\n","import { SuiGrpcClient } from '@mysten/sui/grpc';\nimport type { ServeNetwork } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Chain plumbing — same shape as the gateway's x402-dialect.ts (the reference\n// composition). All reads are gRPC; this package never touches JSON-RPC.\n//\n// Cache policy: the chain identifier (genesis digest) is immutable per\n// network — cached forever. The epoch advances ~daily and x402 requirements\n// are valid for [epoch, epoch+1], so a 10-minute TTL is conservatively fresh.\n// ---------------------------------------------------------------------------\n\nconst FULLNODE_URLS: Record<ServeNetwork, string> = {\n mainnet: 'https://fullnode.mainnet.sui.io:443',\n testnet: 'https://fullnode.testnet.sui.io:443',\n};\n\nconst EPOCH_TTL_MS = 10 * 60 * 1000;\n\nexport interface ChainInfo {\n chain: string;\n epoch: string;\n}\n\ninterface ChainState {\n client?: SuiGrpcClient;\n chainId?: string;\n epoch?: { value: string; fetchedAt: number };\n}\n\nconst state: Partial<Record<ServeNetwork, ChainState>> = {};\n\nexport function getGrpcClient(network: ServeNetwork, rpcUrl?: string): SuiGrpcClient {\n const s = (state[network] ??= {});\n if (!s.client) {\n s.client = new SuiGrpcClient({\n baseUrl: rpcUrl ?? FULLNODE_URLS[network],\n network,\n });\n }\n return s.client;\n}\n\nexport async function getChainInfo(network: ServeNetwork, rpcUrl?: string): Promise<ChainInfo> {\n const client = getGrpcClient(network, rpcUrl);\n const s = (state[network] ??= {});\n if (!s.chainId) {\n const res = await client.core.getChainIdentifier();\n s.chainId = res.chainIdentifier;\n }\n if (!s.epoch || Date.now() - s.epoch.fetchedAt > EPOCH_TTL_MS) {\n const res = await client.core.getCurrentSystemState();\n s.epoch = { value: String(res.systemState.epoch), fetchedAt: Date.now() };\n }\n return { chain: s.chainId, epoch: s.epoch.value };\n}\n\n/** Test seam — reset module caches between cases. */\nexport function __resetChainCaches(): void {\n delete state.mainnet;\n delete state.testnet;\n}\n\n/** Test seam — pre-seed chain info so tests never hit the network. */\nexport function __seedChainInfo(network: ServeNetwork, chain: string, epoch: string): void {\n const s = (state[network] ??= {});\n s.chainId = chain;\n s.epoch = { value: epoch, fetchedAt: Date.now() };\n}\n","import type { Currency, DigestStore } from '@t2000/sui-x402';\nimport {\n createX402Requirements,\n encodeX402Response,\n isX402EscrowHeader,\n parseX402Header,\n settleX402Payment,\n verifyX402Payment,\n X402_PAYMENT_HEADER,\n X402_PAYMENT_RESPONSE_HEADER,\n X402_VERSION,\n type X402SettleResponse,\n} from '@t2000/sui-x402';\nimport { getChainInfo, getGrpcClient } from './chain.js';\nimport type {\n BuiltRoute,\n HandlerContext,\n HandlerResult,\n ServeNetwork,\n ServeSchema,\n StandardSchemaLike,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// The paid-request lifecycle (SPEC_T2000_SERVE §3 — sign-then-settle,\n// handler-then-settle):\n//\n// no X-PAYMENT → 402 with the accepts[] envelope (never a charge;\n// the catalog probe and every discovery tool read\n// this, so it fires BEFORE body validation)\n// X-PAYMENT present:\n// 1. parse + STRUCTURAL verify (right amount/recipient/nonce — no RPC)\n// 2. challenge-once check (a signed payload is single-use)\n// 3. validate the body — invalid → 422, payment NEVER submitted\n// (the JMPR paid-422 class is impossible: the buyer keeps their money)\n// 4. run the handler — throws → 500, payment NEVER submitted\n// 5. settle (submit the buyer-signed gasless bytes; digest-once inside)\n// 6. consume the challenge, attach the X-PAYMENT-RESPONSE receipt\n//\n// Money only moves at step 5, after the seller has already produced the\n// result. A forged payload can waste seller compute (signature authority is\n// the chain at settle time), never buyer money.\n// ---------------------------------------------------------------------------\n\nexport interface RouteRuntime {\n payTo: string;\n network: ServeNetwork;\n currency: Currency;\n store: DigestStore;\n baseUrl?: string;\n rpcUrl?: string;\n /** B2 attributed reporting — unset = no report (see ServeConfig). */\n activityReportUrl?: string;\n}\n\nexport interface RouteOptions {\n path: string;\n description?: string;\n}\n\n/** Sanity cap on a per-call price — above this, the work is job-shaped\n * (escrow) rather than a per-call x402 Service. */\nconst CATALOG_PRICE_CAP_USDC = 5;\n\nconst CORS_HEADERS: Record<string, string> = {\n 'access-control-allow-origin': '*',\n 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'access-control-allow-headers': `content-type, ${X402_PAYMENT_HEADER}`,\n 'access-control-expose-headers': `${X402_PAYMENT_RESPONSE_HEADER}, WWW-Authenticate`,\n};\n\nfunction withCors(response: Response): Response {\n const headers = new Headers(response.headers);\n for (const [k, v] of Object.entries(CORS_HEADERS)) headers.set(k, v);\n return new Response(response.body, { status: response.status, headers });\n}\n\nfunction json(status: number, body: unknown, headers?: Record<string, string>): Response {\n return withCors(\n new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json', ...headers },\n }),\n );\n}\n\nfunction isStandardSchema(schema: ServeSchema): schema is StandardSchemaLike {\n return typeof schema === 'object' && schema !== null && '~standard' in schema;\n}\n\nasync function validateBody(\n schema: ServeSchema,\n value: unknown,\n): Promise<{ ok: true; data: unknown } | { ok: false; message: string }> {\n if (isStandardSchema(schema)) {\n const result = await schema['~standard'].validate(value);\n if (result.issues) {\n // Name the failing field — bare \"Invalid input\" ×N gives a paying\n // buyer's agent nothing to self-correct with.\n const message = result.issues\n .map((i) => {\n const path = (i.path ?? [])\n .map((seg) => (typeof seg === 'object' ? String(seg.key) : String(seg)))\n .join('.');\n return path ? `${path}: ${i.message}` : i.message;\n })\n .join('; ');\n return { ok: false, message };\n }\n return { ok: true, data: result.value };\n }\n const result = schema.safeParse(value);\n if (!result.success) {\n return { ok: false, message: result.error.message ?? 'invalid body' };\n }\n return { ok: true, data: result.data };\n}\n\n/** Positive decimal USDC string, max 6dp (atomic precision). */\nfunction assertValidPrice(price: string, path: string): void {\n if (!/^\\d+(\\.\\d{1,6})?$/.test(price) || Number(price) <= 0) {\n throw new Error(\n `[serve] Route \"${path}\": price must be a positive decimal USDC string with up to 6 decimals, got \"${price}\"`,\n );\n }\n if (Number(price) > CATALOG_PRICE_CAP_USDC) {\n console.warn(\n `[serve] Route \"${path}\": price ${price} USDC is above the ${CATALOG_PRICE_CAP_USDC} USDC listing cap — ` +\n 'the route works, but per-call x402 is the wrong shape for it. Job-class work belongs in `t2 service create` (escrow).',\n );\n }\n}\n\nexport class RouteBuilder<TBody = undefined> {\n private priceUsdc?: string;\n private bodySchema?: ServeSchema;\n private inputSchema?: Record<string, unknown>;\n private outputSchema?: Record<string, unknown>;\n private isFree = false;\n\n constructor(\n private readonly runtime: RouteRuntime,\n private readonly options: RouteOptions,\n private readonly register: (route: BuiltRoute) => void,\n ) {}\n\n /** Charge this many USDC per call (human units, e.g. \"0.01\"). */\n paid(priceUsdc: string): this {\n assertValidPrice(priceUsdc, this.options.path);\n this.priceUsdc = priceUsdc;\n this.isFree = false;\n return this;\n }\n\n /** Serve without payment (health checks, previews, docs). */\n unprotected(): this {\n this.isFree = true;\n this.priceUsdc = undefined;\n return this;\n }\n\n /**\n * Validate the JSON request body. zod v4 / valibot / arktype / anything\n * Standard-Schema, or anything with a zod-style safeParse.\n *\n * Pass the JSON Schema as the second argument to publish it in\n * /openapi.json + /llms.txt (zod v4: `z.toJSONSchema(schema)`) — buyers'\n * agents build request bodies from it, and the catalog grades listings\n * without one.\n */\n body<T>(schema: ServeSchema<T>, jsonSchema?: Record<string, unknown>): RouteBuilder<T> {\n this.bodySchema = schema;\n this.inputSchema = jsonSchema;\n return this as unknown as RouteBuilder<T>;\n }\n\n /**\n * Declare the 200 response's JSON Schema (zod v4: `z.toJSONSchema(schema)`).\n * Published in /openapi.json + /llms.txt so buyer agents know what they're\n * buying and buyer UIs can render the deliverable by TYPE instead of\n * sniffing it — annotate with `contentMediaType` (e.g. \"image/svg+xml\",\n * \"text/markdown\") and `format: \"color\"` where they apply. Declaration\n * only; responses are never validated at runtime.\n */\n response(jsonSchema: Record<string, unknown>): this {\n this.outputSchema = jsonSchema;\n return this;\n }\n\n handler(fn: (ctx: HandlerContext<TBody>) => HandlerResult | Promise<HandlerResult>): BuiltRoute {\n if (!this.isFree && !this.priceUsdc) {\n throw new Error(\n `[serve] Route \"${this.options.path}\": call .paid('<usdc>') or .unprotected() before .handler()`,\n );\n }\n const runtime = this.runtime;\n const { path, description } = this.options;\n const priceUsdc = this.priceUsdc;\n const bodySchema = this.bodySchema;\n\n const route = (async (req: Request): Promise<Response> => {\n if (req.method === 'OPTIONS') {\n return withCors(new Response(null, { status: 204 }));\n }\n\n // Read + parse the body once, up front. A missing/empty body on a\n // schema-less route is fine; JSON parse failures only matter when a\n // paid request must be validated (the unpaid 402 fires regardless).\n let parsedBody: unknown;\n let bodyParseError: string | undefined;\n if (req.method !== 'GET' && req.method !== 'HEAD') {\n const text = await req.text();\n if (text.trim().length > 0) {\n try {\n parsedBody = JSON.parse(text);\n } catch {\n bodyParseError = 'request body is not valid JSON';\n }\n }\n }\n\n const resource = (runtime.baseUrl ?? new URL(req.url).origin).replace(/\\/$/, '') + `/${path}`;\n\n const runHandler = async (payer?: string): Promise<Response> => {\n let validated: unknown = parsedBody;\n if (bodySchema) {\n // `paid: false` is machine-readable charge honesty — a 422 fires\n // BEFORE settlement, so the buyer always keeps their money.\n if (bodyParseError) {\n return json(422, { error: bodyParseError, paid: false });\n }\n const result = await validateBody(bodySchema, parsedBody ?? {});\n if (!result.ok) {\n return json(422, { error: result.message, paid: false });\n }\n validated = result.data;\n }\n const out = await fn({ body: validated as TBody, req, payer });\n if (out instanceof Response) return withCors(out);\n return json(200, out);\n };\n\n // Free route — no payment machinery at all.\n if (!priceUsdc) {\n try {\n return await runHandler();\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed:`, err);\n return json(500, { error: 'internal error' });\n }\n }\n\n const paymentHeader = req.headers.get(X402_PAYMENT_HEADER);\n\n // Unpaid → 402 with the accepts[] envelope. This fires before body\n // validation on purpose: the catalog probe (and every discovery tool)\n // POSTs `{}` and must see the challenge, and an unpaid request can\n // never be charged, so there is nothing to protect yet.\n if (!paymentHeader) {\n return await respond402(runtime, { resource, priceUsdc });\n }\n\n if (isX402EscrowHeader(paymentHeader)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error:\n 'this endpoint sells instant per-call work (settle-then-serve), not escrow jobs — retry with a signed x402 payment',\n });\n }\n\n // 1. Parse + structural verify — right terms, right recipient, right\n // nonce. No RPC, no state. Wrong-terms payloads never reach the\n // handler.\n let payment: ReturnType<typeof parseX402Header>;\n try {\n payment = parseX402Header(paymentHeader);\n verifyX402Payment({\n payment,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `invalid payment: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 2. Challenge-once — a signed payload is single-use even before it\n // settles (the settled digest is separately consumed inside\n // settleX402Payment, digest-once).\n const challengeKey = `challenge:${payment.payload.challengeId}`;\n if (await runtime.store.has(challengeKey)) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: 'payment challenge already used — sign a fresh payment',\n });\n }\n\n // 3 + 4. Validate, then compute the result. Any failure here returns\n // WITHOUT settling — the buyer-signed bytes are never submitted.\n let served: Response;\n try {\n served = await runHandler(payment.payload.senderAddress);\n } catch (err) {\n console.error(`[serve] Route \"${path}\" handler failed (payment NOT settled):`, err);\n return json(500, { error: 'internal error — you were not charged' });\n }\n if (served.status >= 400) return served; // 422 etc. — not charged\n\n // 5. Settle — submit the buyer-signed gasless bytes, confirm the\n // on-chain balance change, record the digest (digest-once).\n let settle: X402SettleResponse;\n try {\n settle = await settleX402Payment({\n payment,\n client: getGrpcClient(runtime.network, runtime.rpcUrl),\n store: runtime.store,\n expected: {\n challengeId: payment.payload.challengeId,\n amount: priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n network: runtime.network,\n },\n });\n } catch (err) {\n return await respond402(runtime, {\n resource,\n priceUsdc,\n error: `settlement failed: ${err instanceof Error ? err.message : String(err)}`,\n });\n }\n\n // 6. Consume the challenge + attach the receipt.\n try {\n await runtime.store.set(challengeKey);\n } catch {\n // Digest-once already holds; challenge-once is defense in depth.\n }\n\n // B2: attributed activity report — AFTER a successful settle only,\n // strictly fire-and-forget (a dead report can never change the\n // buyer's 200 or the settle; SPEC_T2_ACTIVITY_X402 §7 lock 6).\n reportActivity(runtime, {\n digest: settle.transaction,\n payer: settle.payer,\n priceUsdc,\n resource,\n });\n\n const headers = new Headers(served.headers);\n headers.set(X402_PAYMENT_RESPONSE_HEADER, encodeX402Response(settle));\n return new Response(served.body, { status: served.status, headers });\n }) as BuiltRoute;\n\n route.meta = {\n path,\n priceUsdc,\n description,\n bodySchema,\n inputSchema: this.inputSchema,\n outputSchema: this.outputSchema,\n };\n this.register(route);\n return route;\n }\n}\n\n/** Fire-and-forget x402.paid report (B2). Never awaited into the response\n * path; short timeout; every failure swallowed. The report endpoint\n * chain-verifies the digest, so this carries claims, not trust. */\nfunction reportActivity(\n runtime: RouteRuntime,\n args: { digest: string; payer: string; priceUsdc: string; resource: string },\n): void {\n const url = runtime.activityReportUrl;\n if (!url) return;\n try {\n void fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n digest: args.digest,\n payTo: runtime.payTo,\n payer: args.payer,\n amountMicroUsdc: Math.round(Number(args.priceUsdc) * 1_000_000),\n network: `sui:${runtime.network}`,\n route: args.resource,\n source: 'serve',\n }),\n signal: AbortSignal.timeout(1500),\n }).catch(() => undefined);\n } catch {\n // even a sync throw (bad URL) must not touch the buyer's response\n }\n}\n\nasync function respond402(\n runtime: RouteRuntime,\n args: { resource: string; priceUsdc: string; error?: string },\n): Promise<Response> {\n try {\n const { chain, epoch } = await getChainInfo(runtime.network, runtime.rpcUrl);\n const requirements = createX402Requirements({\n challengeId: crypto.randomUUID(),\n amount: args.priceUsdc,\n currency: runtime.currency,\n recipient: runtime.payTo,\n resource: args.resource,\n network: runtime.network,\n chain,\n currentEpoch: epoch,\n });\n // Belt-and-suspenders for pre-0.2.2 discovery clients and dual-dialect\n // consumers: mirror the challenge into the MPP WWW-Authenticate shape.\n // The accepts[] body stays the authoritative envelope — the header carries\n // the same recipient/currency and the DECIMAL amount that dialect uses.\n // currency must be the coin TYPE STRING (the same identity the x402\n // asset field uses) — `Currency` is { type, decimals }, and object\n // interpolation shipped currency=\"[object Object]\" (beta #93, S.1002).\n const host = (() => {\n try {\n return new URL(args.resource).hostname;\n } catch {\n return undefined;\n }\n })();\n const wwwAuth = `Payment realm=\"${host ?? 'x402'}\", recipient=\"${runtime.payTo}\", currency=\"${runtime.currency.type}\", amount=\"${args.priceUsdc}\"`;\n return json(\n 402,\n {\n x402Version: X402_VERSION,\n error: args.error ?? 'Payment required',\n accepts: [requirements],\n },\n { 'WWW-Authenticate': wwwAuth },\n );\n } catch (err) {\n // Chain info unreachable — a 402 without the envelope is unpayable, so\n // be honest about the outage instead of serving a dead challenge.\n console.error('[serve] failed to build 402 challenge:', err);\n return json(503, { error: 'payment challenge temporarily unavailable' });\n }\n}\n\n","import type { DigestStore } from '@t2000/sui-x402';\n\nexport { InMemoryDigestStore } from '@t2000/sui-x402';\nexport type { DigestStore } from '@t2000/sui-x402';\n\n// ---------------------------------------------------------------------------\n// Upstash-REST digest store — the production replay store for serverless\n// hosts. Mirrors the gateway's upstash-digest-store.ts but speaks the\n// Upstash REST API over plain fetch (no @upstash/redis dependency).\n//\n// TTL: 72h. x402 payments are chain-valid for the whole ValidDuring window\n// ([minEpoch, minEpoch+1] ≈ up to ~48h on mainnet). Sui resubmission of an\n// executed tx is idempotent, so if the digest/challenge keys expired BEFORE\n// the window closed, a replayed X-PAYMENT would re-settle \"successfully\"\n// and serve again on a single payment. 72h > max window + drift.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_SECONDS = 72 * 60 * 60;\nconst PREFIX = 'serve:digest:';\n\nexport interface UpstashDigestStoreOptions {\n url: string;\n token: string;\n /** Key TTL in seconds. Default 72h — do not lower below ~50h (see above). */\n ttlSeconds?: number;\n}\n\nexport class UpstashDigestStore implements DigestStore {\n private readonly url: string;\n private readonly token: string;\n private readonly ttlSeconds: number;\n\n constructor(options: UpstashDigestStoreOptions) {\n this.url = options.url.replace(/\\/$/, '');\n this.token = options.token;\n this.ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;\n }\n\n private async command(segments: string[]): Promise<unknown> {\n const res = await fetch(`${this.url}/${segments.map(encodeURIComponent).join('/')}`, {\n headers: { authorization: `Bearer ${this.token}` },\n });\n if (!res.ok) {\n throw new Error(`Upstash command failed: ${res.status} ${await res.text()}`);\n }\n const body = (await res.json()) as { result?: unknown; error?: string };\n if (body.error) throw new Error(`Upstash error: ${body.error}`);\n return body.result;\n }\n\n async has(digest: string): Promise<boolean> {\n const result = await this.command(['GET', PREFIX + digest]);\n return result !== null && result !== undefined;\n }\n\n async set(digest: string): Promise<void> {\n // SET key 1 EX <ttl> NX — atomic set-if-absent. A null result means the\n // key already existed: the digest (or challenge) was already consumed.\n const result = await this.command([\n 'SET',\n PREFIX + digest,\n '1',\n 'EX',\n String(this.ttlSeconds),\n 'NX',\n ]);\n if (result === null || result === undefined) {\n throw new Error(`Digest already used: ${digest}`);\n }\n }\n}\n","import { isValidSuiAddress, normalizeSuiAddress } from '@mysten/sui/utils';\nimport { InMemoryDigestStore, USDC, USDC_TESTNET, type Currency } from '@t2000/sui-x402';\nimport { buildLlmsTxt, buildOpenApiDocument } from './discovery.js';\nimport { RouteBuilder, type RouteOptions, type RouteRuntime } from './route.js';\nimport { UpstashDigestStore } from './store.js';\nimport type { BuiltRoute, ServeConfig, ServeNetwork } from './types.js';\n\n/** The t2000.ai attributed-activity report endpoint — ONE canonical string\n * (matches the sdk's DEFAULT_ACTIVITY_REPORT_URL; tests assert equality). */\nexport const DEFAULT_ACTIVITY_REPORT_URL = 'https://t2000.ai/api/activity/x402';\n\n/** Explicit opt-out tokens for T2000_ACTIVITY_REPORT_URL (case-insensitive). */\nconst REPORT_OPT_OUT = new Set(['false', '0', 'off', 'none']);\n\nexport class Serve {\n private readonly runtime: RouteRuntime;\n /** Every route built through this instance, keyed by path (discovery). */\n readonly routes = new Map<string, BuiltRoute>();\n\n readonly payTo: string;\n readonly network: ServeNetwork;\n readonly name?: string;\n readonly description?: string;\n readonly baseUrl?: string;\n /** Where settled payments are reported (B2) — undefined = no report. */\n readonly activityReportUrl?: string;\n\n constructor(config: ServeConfig) {\n if (!config.payTo || !isValidSuiAddress(config.payTo)) {\n throw new Error(\n `[serve] payTo must be a valid Sui address (the wallet your payments settle to), got \"${config.payTo}\"`,\n );\n }\n this.payTo = normalizeSuiAddress(config.payTo);\n this.network = config.network ?? 'mainnet';\n this.name = config.name;\n this.description = config.description;\n this.baseUrl = config.baseUrl?.replace(/\\/$/, '');\n this.activityReportUrl = config.activityReportUrl;\n\n const currency: Currency = this.network === 'testnet' ? USDC_TESTNET : USDC;\n this.runtime = {\n payTo: this.payTo,\n network: this.network,\n currency,\n store: config.store ?? new InMemoryDigestStore(),\n baseUrl: this.baseUrl,\n rpcUrl: config.rpcUrl,\n activityReportUrl: this.activityReportUrl,\n };\n }\n\n /** Start building a route. Chain `.paid()` / `.body()` / `.handler()`. */\n route(options: RouteOptions): RouteBuilder {\n const path = options.path.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (!path) throw new Error('[serve] route path must be non-empty');\n return new RouteBuilder({ ...this.runtime }, { ...options, path }, (route) => {\n this.routes.set(path, route);\n });\n }\n\n /**\n * Discovery: GET handler for /openapi.json. OpenAPI 3.1 with the\n * `x-payment-info` pricing extension on every paid operation — the shape\n * x402 tooling (and any catalog built on it) indexes.\n *\n * export const GET = serve.openapi(); // app/openapi.json/route.ts\n */\n openapi(): (req: Request) => Response {\n return (req: Request) =>\n new Response(JSON.stringify(buildOpenApiDocument(this, new URL(req.url).origin), null, 2), {\n headers: { 'content-type': 'application/json', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * Discovery: GET handler for /llms.txt — plain-text guidance agents read\n * to understand what the API sells, what it costs, and how to pay.\n *\n * export const GET = serve.llms(); // app/llms.txt/route.ts\n */\n llms(): (req: Request) => Response {\n return (req: Request) =>\n new Response(buildLlmsTxt(this, new URL(req.url).origin), {\n headers: { 'content-type': 'text/plain; charset=utf-8', 'access-control-allow-origin': '*' },\n });\n }\n\n /**\n * One fetch handler for the whole app — routes + discovery docs. For\n * fetch-native runtimes (Bun.serve, Deno.serve, Hono, Cloudflare Workers):\n *\n * Bun.serve({ fetch: serve.fetch });\n * app.all('*', (c) => serve.fetch(c.req.raw)); // Hono\n *\n * Next.js apps can skip this and export route handlers directly.\n */\n readonly fetch = async (req: Request): Promise<Response> => {\n const pathname = new URL(req.url).pathname.replace(/^\\/+/, '').replace(/\\/+$/, '');\n if (pathname === 'openapi.json') return this.openapi()(req);\n if (pathname === 'llms.txt') return this.llms()(req);\n const route = this.routes.get(pathname);\n if (route) return route(req);\n return new Response(\n JSON.stringify({ error: 'not found', discovery: ['/openapi.json', '/llms.txt'] }),\n { status: 404, headers: { 'content-type': 'application/json' } },\n );\n };\n\n /**\n * The command that sells this API as an x402 Service on your Agent ID,\n * once it is deployed. Listing is a separate, explicit step: the endpoint\n * is live-probed (it must answer 402 with a Sui challenge that pays YOUR\n * wallet) and then recorded on-chain, sponsored and gasless.\n *\n * This used to emit curls against the hosted mpp.t2000.ai catalog. That\n * proxy mall was purged 2026-08-01 (SPEC_T2_CLEANUP_USDC_ONLY) — there is\n * no central catalog to submit to. Your Agent ID IS the listing, and\n * buyers find it with `t2 services`.\n */\n catalogSubmitCommand(deployedUrl?: string): string {\n const base = (deployedUrl ?? this.baseUrl ?? 'https://<your-deployed-app>').replace(/\\/$/, '');\n const paidPaths = [...this.routes.values()].filter((r) => r.meta.priceUsdc);\n const example = paidPaths[0]?.meta.path ?? '<route>';\n return [\n '# Sell it as an x402 Service on your Agent ID (live-probed, gasless):',\n `npx @t2000/cli agent sell ${base}/${example}`,\n '# Buyers then find it with `t2 services` and pay per call with `t2 pay`.',\n ].join('\\n');\n }\n}\n\nexport function createServe(config: ServeConfig): Serve {\n return new Serve(config);\n}\n\n/**\n * Build a Serve from environment variables — the template-app path where\n * config lives in the host's env UI, not code.\n *\n * T2000_PAY_TO required — the seller's Sui address\n * T2000_NETWORK optional — 'mainnet' (default) | 'testnet'\n * T2000_BASE_URL optional — public URL of the deployed app\n * T2000_NAME optional — service name for discovery docs\n * T2000_DESCRIPTION optional — one-liner for discovery docs\n * T2000_ACTIVITY_REPORT_URL\n * optional — where settled payments are reported\n * (fire-and-forget x402.paid after each successful settle;\n * chain-verified server-side, never affects buyer\n * responses). DEFAULT-ON for FromEnv: unset →\n * https://t2000.ai/api/activity/x402 so new sellers appear\n * on the t2000.ai activity tape. Opt out with\n * `false` | `0` | `off` | `none` (case-insensitive), or\n * set a custom URL. (`new Serve({...})` without\n * activityReportUrl stays silent — only FromEnv defaults.)\n * KV_REST_API_URL / KV_REST_API_TOKEN\n * optional — enables the durable Upstash replay store\n * (REQUIRED in serverless production; without it replay\n * state is per-instance memory)\n *\n * Empty strings are treated as unset (the Vercel empty-env bug class).\n */\nexport function createServeFromEnv(env: Record<string, string | undefined> = process.env): Serve {\n const read = (key: string): string | undefined => {\n const v = env[key]?.trim();\n return v && v.length > 0 ? v : undefined;\n };\n\n const payTo = read('T2000_PAY_TO');\n if (!payTo) {\n throw new Error(\n '[serve] T2000_PAY_TO is not set (or is empty). Set it to the Sui address your payments should settle to — `t2 address` prints yours.',\n );\n }\n\n const network = read('T2000_NETWORK');\n if (network && network !== 'mainnet' && network !== 'testnet') {\n throw new Error(`[serve] T2000_NETWORK must be 'mainnet' or 'testnet', got \"${network}\"`);\n }\n\n const kvUrl = read('KV_REST_API_URL');\n const kvToken = read('KV_REST_API_TOKEN');\n const store =\n kvUrl && kvToken ? new UpstashDigestStore({ url: kvUrl, token: kvToken }) : undefined;\n\n if (!store) {\n console.warn(\n '[serve] No KV_REST_API_URL/KV_REST_API_TOKEN — using the in-memory replay store. ' +\n 'Fine for a single long-lived process; on serverless hosts set both so replay protection is durable.',\n );\n }\n\n return new Serve({\n payTo,\n network: (network as ServeNetwork | undefined) ?? 'mainnet',\n baseUrl: read('T2000_BASE_URL'),\n name: read('T2000_NAME'),\n description: read('T2000_DESCRIPTION'),\n activityReportUrl: resolveReportUrlFromEnv(read('T2000_ACTIVITY_REPORT_URL')),\n store,\n });\n}\n\n/** FromEnv activity-report resolution (B2 default-on): unset/empty →\n * the t2000.ai default; an explicit opt-out token → undefined (silent);\n * anything else is the seller's custom report URL. */\nfunction resolveReportUrlFromEnv(raw: string | undefined): string | undefined {\n if (raw === undefined) return DEFAULT_ACTIVITY_REPORT_URL;\n if (REPORT_OPT_OUT.has(raw.toLowerCase())) return undefined;\n return raw;\n}\n","import type { BuiltRoute } from './types.js';\n\n/**\n * Export a built route the way Next.js App Router needs it.\n *\n * Next dispatches ONLY the methods a route.ts exports — serve's own CORS\n * handling (OPTIONS → 204 with the ACAO headers) never runs if the file\n * exports just `POST`: the browser preflight gets Next's bare 204 with no\n * CORS headers, and every browser buyer (Passport, the store's Try it)\n * fails while CLI/server buyers — who never preflight — work fine. Fetch\n * runtimes mounted via a single handler (`serve.fetch`-style) don't have\n * this hole; it is a Next export contract, not a serve one.\n *\n * export const { POST, OPTIONS } = asNextRoute(\n * serve.route({ path: 'haiku' }).paid('0.01').handler(fn),\n * );\n */\nexport function asNextRoute(route: BuiltRoute): {\n POST: BuiltRoute;\n OPTIONS: BuiltRoute;\n} {\n return { POST: route, OPTIONS: route };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t2000/serve",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.30.1",
|
|
4
4
|
"description": "Merchant-side x402 router for Sui — wrap any API so agents can discover it and pay per call in USDC. One builder: .paid().body().handler(). Sign-then-settle, no seller key, no seller gas.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"homepage": "https://docs.t2000.ai/sell-to-agents/overview",
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@mysten/sui": "^2.17.0",
|
|
39
|
-
"@t2000/sui-x402": "10.
|
|
39
|
+
"@t2000/sui-x402": "10.30.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^20",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"typescript": "^5",
|
|
46
46
|
"typescript-eslint": "^8.58.0",
|
|
47
47
|
"vitest": "^3",
|
|
48
|
-
"@t2000/discovery": "10.
|
|
48
|
+
"@t2000/discovery": "10.30.1"
|
|
49
49
|
},
|
|
50
50
|
"license": "MIT",
|
|
51
51
|
"scripts": {
|