@devlab.group/agent-commerce 0.1.0-alpha.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/filename.ts","../../src/core/domain/resource.ts","../../src/core/errors/codes.ts","../../src/core/errors/commerce-error.ts","../../src/core/errors/index.ts","../../src/core/interfaces/logger.ts","../../src/core/execution/backend-http.ts","../../src/core/execution/event-bus.ts","../../src/core/domain/wire.ts","../../src/core/execution/validation.ts","../../src/core/execution/pipeline.ts","../../src/core/execution/registry.ts","../../src/core/execution/index.ts","../../src/core/domain/event.ts","../../src/core/interfaces/protocol-adapter.ts","../../src/core/interfaces/runtime.ts","../../src/core/public-types.ts","../../src/core/index.ts","../../src/config/env.ts","../../src/config/schema.ts","../../src/config/load.ts","../../src/config/index.ts","../../src/cli/program.ts","../../src/cli/commands/demo.ts","../../src/cli/commands/doctor.ts","../../src/storage/receipts/store.ts","../../src/version.ts","../../src/storage/receipts/redact.ts","../../src/storage/receipts/rows.ts","../../src/storage/receipts/schema.ts","../../src/cli/lib/config-client.ts","../../src/cli/lib/http.ts","../../src/payments/x402/local-chain/accounts.ts","../../src/cli/lib/init-config.ts","../../src/payments/x402/local-chain/manifest.ts","../../src/cli/lib/manifest-env.ts","../../src/cli/lib/mask.ts","../../src/cli/lib/versions.ts","../../src/cli/commands/init.ts","../../src/cli/commands/validate.ts","../../src/cli/commands/version.ts","../../src/cli/lib/io.ts","../../src/cli/index.ts"],"names":["path","isPlainObject","text","fs","parseYaml","fsConstants","existsSync","createRequire","loadConfig","resolve","dirname","mkdirSync"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The default configuration filename, in one place.\n *\n * Deliberately its own module with **no imports**: `src/cli` reaches the rest\n * of `src/config` only through a dynamic import (see\n * `src/cli/lib/config-client.ts`), so that a broken config module cannot take\n * down commands that never read configuration. A leaf file holding a single\n * string has no module graph to break, so the CLI can import it directly\n * without reopening that seam — and `init`'s default output path, `--config`'s\n * help text and the loader's own lookup cannot drift apart, which is what\n * three separate copies of this string invited.\n */\nexport const DEFAULT_CONFIG_FILENAME = 'config.yaml';\n","/**\n * Canonical resource model.\n *\n * FROZEN CONTRACT.\n */\nimport type { DecimalAmount, JsonSchema, PaymentMethodName, ProtocolName } from './common.js';\n\n/** HTTP methods a backend handler may use. */\nexport type BackendMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n/**\n * Describes how the gateway calls the merchant's existing backend.\n *\n * Backend URLs are administrator-controlled configuration only. User- or\n * agent-controlled backend URLs are forbidden (see docs/security.md, SSRF).\n * Secret header values must come from `${ENV_VAR}` placeholders resolved by\n * the config loader, never from plaintext configuration.\n */\nexport interface BackendHandler {\n readonly type: 'http';\n readonly method: BackendMethod;\n readonly url: string;\n readonly headers?: Readonly<Record<string, string>>;\n /** Hard upper bound on the backend call. Defaults to DEFAULT_BACKEND_TIMEOUT_MS. */\n readonly timeoutMs?: number;\n}\n\n/** Default backend timeout when a resource does not specify one. */\nexport const DEFAULT_BACKEND_TIMEOUT_MS = 10_000;\n\n/**\n * Canonical pricing.\n *\n * `dynamic` exists in the type system for forward compatibility but is\n * REJECTED by config validation in v0.1.0-alpha.\n */\nexport type Pricing =\n | { readonly type: 'free' }\n | {\n readonly type: 'fixed';\n readonly amount: DecimalAmount;\n readonly currency: string;\n }\n | {\n readonly type: 'dynamic';\n readonly resolver: string;\n };\n\n/**\n * A merchant capability exposed to agents.\n *\n * The canonical resource is the single source of truth: protocol adapters map\n * it outward, they never define their own parallel notion of a resource.\n */\nexport interface CommerceResource {\n readonly id: string;\n readonly name: string;\n readonly description?: string;\n readonly inputSchema?: JsonSchema;\n readonly outputSchema?: JsonSchema;\n readonly handler: BackendHandler;\n readonly pricing: Pricing;\n readonly exposedVia: readonly ProtocolName[];\n readonly paymentMethods: readonly PaymentMethodName[];\n}\n\n/** Read-only view of every configured resource. */\nexport interface ResourceRegistry {\n get(id: string): CommerceResource | undefined;\n list(): readonly CommerceResource[];\n /** Resources exposed through a given protocol surface. */\n listExposedVia(protocol: ProtocolName): readonly CommerceResource[];\n has(id: string): boolean;\n}\n","/**\n * Typed domain error codes.\n *\n * FROZEN CONTRACT. Protocol adapters map these codes into their own response\n * format. Never throw a bare string or untyped Error across a package boundary.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'CONFIG_INVALID',\n 'RESOURCE_NOT_FOUND',\n 'INPUT_INVALID',\n 'PAYMENT_REQUIRED',\n 'PAYMENT_INVALID',\n 'PAYMENT_REPLAYED',\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'PAYMENT_SETTLEMENT_FAILED',\n 'BACKEND_TIMEOUT',\n 'BACKEND_ERROR',\n 'PROTOCOL_UNSUPPORTED',\n 'GATEWAY_BUSY',\n 'STORAGE_ERROR',\n 'INTERNAL_ERROR',\n] as const;\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number];\n\n/**\n * Canonical HTTP status for each error code.\n *\n * Paid resources fail closed: every payment failure maps to a 4xx/5xx status\n * and never to a successful delivery.\n */\nexport const COMMERCE_ERROR_HTTP_STATUS: Readonly<Record<CommerceErrorCode, number>> = {\n CONFIG_INVALID: 500,\n RESOURCE_NOT_FOUND: 404,\n INPUT_INVALID: 400,\n PAYMENT_REQUIRED: 402,\n PAYMENT_INVALID: 402,\n PAYMENT_REPLAYED: 409,\n PAYMENT_PROVIDER_UNAVAILABLE: 503,\n PAYMENT_SETTLEMENT_FAILED: 502,\n BACKEND_TIMEOUT: 504,\n BACKEND_ERROR: 502,\n PROTOCOL_UNSUPPORTED: 501,\n GATEWAY_BUSY: 503,\n STORAGE_ERROR: 500,\n INTERNAL_ERROR: 500,\n};\n\n/** Codes for which a client may reasonably retry the same request. */\nexport const RETRYABLE_ERROR_CODES: ReadonlySet<CommerceErrorCode> = new Set([\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'BACKEND_TIMEOUT',\n // Load shedding is transient by definition: the caller should back off and\n // try again. Before this code existed the MCP adapter's queue-full path threw\n // PROTOCOL_UNSUPPORTED — HTTP 501, retryable:false — so an agent framework\n // keyed on the machine-readable flag (which exists precisely so clients need\n // not parse prose) would read a momentary throttle as a permanent capability\n // gap and stop calling the tool.\n 'GATEWAY_BUSY',\n]);\n","/**\n * The single error type crossing package boundaries.\n *\n * FROZEN CONTRACT.\n */\nimport {\n COMMERCE_ERROR_HTTP_STATUS,\n type CommerceErrorCode,\n RETRYABLE_ERROR_CODES,\n} from './codes.js';\n\nexport interface CommerceErrorOptions {\n /** Structured, non-secret detail safe to return to a client. */\n readonly details?: Readonly<Record<string, unknown>>;\n readonly cause?: unknown;\n readonly requestId?: string;\n readonly resourceId?: string;\n /** Override the default HTTP status for this code. */\n readonly httpStatus?: number;\n}\n\n/** Serialisable wire form of a CommerceError. */\nexport interface CommerceErrorInfo {\n readonly code: CommerceErrorCode;\n readonly message: string;\n readonly httpStatus: number;\n readonly retryable: boolean;\n readonly requestId?: string;\n readonly resourceId?: string;\n readonly details?: Readonly<Record<string, unknown>>;\n}\n\nexport class CommerceError extends Error {\n readonly code: CommerceErrorCode;\n readonly httpStatus: number;\n readonly retryable: boolean;\n readonly details?: Readonly<Record<string, unknown>>;\n readonly requestId?: string;\n readonly resourceId?: string;\n\n constructor(code: CommerceErrorCode, message: string, options: CommerceErrorOptions = {}) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'CommerceError';\n this.code = code;\n this.httpStatus = options.httpStatus ?? COMMERCE_ERROR_HTTP_STATUS[code];\n this.retryable = RETRYABLE_ERROR_CODES.has(code);\n if (options.details !== undefined) this.details = options.details;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.resourceId !== undefined) this.resourceId = options.resourceId;\n Error.captureStackTrace?.(this, CommerceError);\n }\n\n /** Non-secret, client-safe representation. */\n toInfo(): CommerceErrorInfo {\n return {\n code: this.code,\n message: this.message,\n httpStatus: this.httpStatus,\n retryable: this.retryable,\n ...(this.requestId !== undefined ? { requestId: this.requestId } : {}),\n ...(this.resourceId !== undefined ? { resourceId: this.resourceId } : {}),\n ...(this.details !== undefined ? { details: this.details } : {}),\n };\n }\n}\n\nexport function isCommerceError(value: unknown): value is CommerceError {\n return value instanceof CommerceError;\n}\n\n/**\n * Normalise any thrown value into a CommerceError.\n *\n * Used at package boundaries so an unexpected failure never escapes untyped.\n *\n * SECURITY — do not \"improve\" this by propagating `value.message`.\n * `CommerceError.message` is client-visible: it is serialised by `toInfo()`\n * and `toErrorEnvelope()` and returned over HTTP and MCP. An arbitrary thrown\n * Error's message routinely carries internal detail — database connection\n * strings, internal hostnames, filesystem paths, backend URLs. Copying it into\n * a client-facing field turns every unexpected exception into an information\n * disclosure.\n *\n * The original value is preserved on `cause`, which is never serialised, so\n * logs and diagnostics keep the full detail while clients get only the\n * caller's deliberate, reviewed `fallbackMessage`.\n *\n * A caller that *wants* a specific client-facing message passes one:\n * toCommerceError(err, 'BACKEND_ERROR', 'Backend call failed')\n */\nexport function toCommerceError(\n value: unknown,\n fallbackCode: CommerceErrorCode = 'INTERNAL_ERROR',\n fallbackMessage = 'Unexpected internal error',\n): CommerceError {\n if (isCommerceError(value)) return value;\n return new CommerceError(fallbackCode, fallbackMessage, { cause: value });\n}\n","export * from './codes.js';\nexport * from './commerce-error.js';\n","/**\n * Minimal structural logger interface.\n *\n * Core must not depend on pino directly; the gateway injects a pino instance\n * that satisfies this shape. Never log secrets: private keys, seed phrases,\n * Authorization headers or payment authorisation payloads.\n */\nexport interface Logger {\n debug(obj: Record<string, unknown>, msg?: string): void;\n info(obj: Record<string, unknown>, msg?: string): void;\n warn(obj: Record<string, unknown>, msg?: string): void;\n error(obj: Record<string, unknown>, msg?: string): void;\n child(bindings: Record<string, unknown>): Logger;\n}\n\n/** A logger that discards everything. Useful in unit tests. */\nexport const NOOP_LOGGER: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n child: () => NOOP_LOGGER,\n};\n","/**\n * The only outbound HTTP path to a merchant backend.\n *\n * - Uses global `fetch` and always applies a bound timeout via `AbortSignal.timeout`.\n * - `redirect: 'manual'` — a 3xx response is treated as a `BACKEND_ERROR`, never\n * followed (SSRF hardening).\n * - `{param}` segments in `handler.url` are filled from validated input and\n * URL-encoded; whatever remains goes to the query string (GET/DELETE) or a\n * JSON body (POST/PUT/PATCH).\n */\nimport { type BackendHandler, DEFAULT_BACKEND_TIMEOUT_MS } from '../domain/resource.js';\nimport { CommerceError } from '../errors/index.js';\nimport type { BackendExecutor, BackendRequest, BackendResponse } from '../interfaces/backend.js';\nimport { type Logger, NOOP_LOGGER } from '../interfaces/logger.js';\n\nconst MAX_BODY_SNIPPET_LENGTH = 512;\n/**\n * The one canonical `{param}` grammar. Extraction, substitution, the config\n * gate and `doctor`'s probe all go through it.\n *\n * `-` and `.` are admitted: `/report/{report-id}` is ordinary\n * REST, and under the previous `[a-zA-Z0-9_]+` class it matched *nothing*. It\n * was therefore invisible to the config gate, survived substitution as a\n * literal, and a paid resource settled the buyer's payment before sending\n * `/report/%7Breport-id%7D` to a backend that 404s — the earlier money bug,\n * reachable again through the character class rather than through the check.\n */\nconst PATH_PARAM_PATTERN = /\\{([a-zA-Z0-9_.-]+)\\}/g;\n/** A hostile or broken backend can otherwise materialise an arbitrarily\n * large response in memory — AbortSignal.timeout bounds it by *time*, not\n * bytes. 1 MB is generous for a JSON API response. */\nconst MAX_RESPONSE_BODY_BYTES = 1024 * 1024;\n\nexport interface HttpBackendExecutorOptions {\n /** Override for `fetch`, used in tests. Defaults to the global implementation. */\n readonly fetchImpl?: typeof fetch;\n /** A non-2xx backend body is logged here (debug), never shipped to the client. */\n readonly logger?: Logger;\n}\n\nexport class HttpBackendExecutor implements BackendExecutor {\n private readonly fetchImpl: typeof fetch;\n private readonly logger: Logger;\n\n constructor(options: HttpBackendExecutorOptions = {}) {\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.logger = options.logger ?? NOOP_LOGGER;\n }\n\n async call(handler: BackendHandler, request: BackendRequest): Promise<BackendResponse> {\n const timeoutMs = handler.timeoutMs ?? DEFAULT_BACKEND_TIMEOUT_MS;\n const inputRecord = isPlainObject(request.input) ? request.input : {};\n\n let target: URL;\n let remaining: Record<string, unknown>;\n try {\n const templated = applyPathTemplate(handler.url, inputRecord);\n target = new URL(templated.url);\n remaining = templated.remaining;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith('invalid-path-parameter:')) {\n const field = error.message.slice('invalid-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" is not a valid value`, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { field },\n });\n }\n // Mirrors validateBackendRequestShape()'s own copy\n // — the pipeline calls that one first, so this branch is defence in\n // depth for a caller that bypasses it, not the normal path.\n if (error instanceof Error && error.message.startsWith('missing-path-parameter:')) {\n const field = error.message.slice('missing-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" was not supplied`, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { field },\n });\n }\n throw new CommerceError('BACKEND_ERROR', 'Backend URL could not be constructed from input', {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { reason: describeConstructionError(error) },\n cause: error,\n });\n }\n\n // Belt-and-braces beyond the per-parameter check above: whatever the\n // templated path resolved to must still live under the template's own\n // literal (pre-`{param}`) prefix. Templating something other than a path\n // segment (e.g. the host) is not a documented usage; if the literal\n // prefix does not even parse as a URL, skip this extra check rather than\n // fail a request the per-parameter check already covers.\n const literalPrefix = handler.url.split('{')[0] ?? handler.url;\n try {\n const literalPrefixPathname = new URL(literalPrefix).pathname;\n if (!target.pathname.startsWith(literalPrefixPathname)) {\n throw new CommerceError(\n 'INPUT_INVALID',\n 'Path parameters resolved outside the configured backend path',\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n },\n );\n }\n } catch (error) {\n if (error instanceof CommerceError) throw error;\n }\n\n const headers: Record<string, string> = { ...(handler.headers ?? {}) };\n let body: string | undefined;\n\n if (handler.method === 'GET' || handler.method === 'DELETE') {\n //.set() REPLACES an existing param, so without this check a caller\n // input key with the same name as an operator-baked-in query param\n // (?apikey=SECRET in handler.url) silently overwrites it.\n // Shared with validateBackendRequestShape() — that copy runs\n // *before* payment, this one is defence in depth.\n checkQueryCollision(target, remaining, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n });\n for (const [key, value] of Object.entries(remaining)) {\n target.searchParams.set(key, stringifyPrimitive(value));\n }\n } else {\n body = JSON.stringify(remaining);\n if (!hasHeader(headers, 'content-type')) {\n headers['content-type'] = 'application/json';\n }\n }\n\n const started = performance.now();\n let response: Response;\n try {\n response = await this.fetchImpl(target, {\n method: handler.method,\n headers,\n ...(body !== undefined ? { body } : {}),\n redirect: 'manual',\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n const durationMs = Math.round(performance.now() - started);\n if (isAbortError(error)) {\n throw new CommerceError(\n 'BACKEND_TIMEOUT',\n `Backend request timed out after ${timeoutMs}ms`,\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { timeoutMs, durationMs },\n cause: error,\n },\n );\n }\n throw new CommerceError('BACKEND_ERROR', 'Backend request failed (transport error)', {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { durationMs },\n cause: error,\n });\n }\n const durationMs = Math.round(performance.now() - started);\n\n const isRedirect =\n response.type === 'opaqueredirect' || (response.status >= 300 && response.status < 400);\n if (isRedirect) {\n throw new CommerceError(\n 'BACKEND_ERROR',\n 'Backend responded with a redirect, which is not followed',\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { status: response.status, reason: 'redirect-not-followed' },\n },\n );\n }\n\n const responseHeaders = headersToRecord(response.headers);\n const contentType = response.headers.get('content-type') ?? '';\n let parsedBody: unknown;\n try {\n parsedBody = await parseBody(response, contentType);\n } catch (error) {\n const tooLarge =\n error instanceof Error && error.message.startsWith('response-body-too-large');\n throw new CommerceError(\n 'BACKEND_ERROR',\n tooLarge\n ? 'Backend response exceeded the maximum allowed size'\n : 'Backend response could not be read',\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: tooLarge\n ? { reason: 'response-too-large', maxBytes: MAX_RESPONSE_BODY_BYTES }\n : { reason: 'read-error' },\n cause: error,\n },\n );\n }\n\n if (response.status < 200 || response.status >= 300) {\n // The backend status is ours to state; the backend's own response body\n // is not — a merchant backend in verbose/dev-error mode routinely\n // emits stack traces, hostnames or SQL fragments, and this gateway is\n // not the one who gets to decide those are safe to forward to whoever\n // called the (possibly free, possibly unauthenticated) resource. Log\n // it for the operator; never put it in a client-visible field.\n this.logger.debug(\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n status: response.status,\n bodySnippet: truncateSnippet(parsedBody),\n },\n 'Backend responded with a non-2xx status',\n );\n throw new CommerceError('BACKEND_ERROR', `Backend responded with status ${response.status}`, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { status: response.status },\n });\n }\n\n return {\n status: response.status,\n headers: responseHeaders,\n body: parsedBody,\n durationMs,\n };\n }\n}\n\n/**\n * The traversal and query-collision checks below must run before payment,\n * not only inside `call()` — pipeline step 6, which is *after*\n * verify -> reserve -> settle.\n * Both throw INPUT_INVALID, which schema validation (step 2) cannot catch\n * (it validates against `resource.inputSchema`, which knows nothing about\n * the URL template a bad value would collide with). Concretely: a paid,\n * path-templated resource called with `{ city: \"\" }` would settle the buyer's\n * payment on-chain and then never call the backend — payment without\n * delivery, no refund, no release of the reserved authorisation. Both\n * checks are pure functions of `(handler.url, input)` with no I/O, so the\n * pipeline calls this immediately after schema validation, *before* price\n * resolution — before any payment provider is even selected. `call()` keeps\n * its own copy as defence in depth (it is a public class; the pipeline is\n * not the only possible caller).\n */\n/**\n * `{param}` names in a `backend.url` template, in declaration order.\n * Exported so `src/config`'s `normaliseResource` can\n * cross-check every template parameter against the resource's input schema\n * at config load — the same regex, not a second copy that could silently\n * drift out of sync with what this file actually treats as a path\n * parameter.\n */\nexport function extractPathParameterNames(url: string): string[] {\n return [...url.matchAll(PATH_PARAM_PATTERN)].map((match) => match[1] as string);\n}\n\n/**\n * A brace left over after every legal `{param}` is removed, or `undefined`.\n *\n * Widening the grammar fixes the *common* spelling; it cannot fix every one.\n * `{report id}`, `{a/b}`, `{}` and an unbalanced `{` still match nothing, and\n * \"matches nothing\" is precisely the silent-literal shape that costs a buyer\n * money on a paid resource. So the rule is inverted: rather than enumerating\n * what is illegal, anything brace-shaped that is *not* a recognised parameter\n * is refused at config load. Exported so `src/config` applies it — the\n * grammar and its residue must never live in two files.\n */\nexport function findUnparsedBraceToken(url: string): string | undefined {\n const residue = url.replace(PATH_PARAM_PATTERN, '');\n const index = residue.search(/[{}]/);\n if (index === -1) return undefined;\n // Report the offending run, not just the character, so the error is fixable.\n const token = /\\{[^{}]*\\}?|\\}/.exec(residue.slice(index));\n return token?.[0] ?? residue[index];\n}\n\nexport function validateBackendRequestShape(\n handler: BackendHandler,\n input: unknown,\n context: { readonly requestId: string; readonly resourceId: string },\n): void {\n const inputRecord = isPlainObject(input) ? input : {};\n\n let templated: { url: string; remaining: Record<string, unknown> };\n try {\n templated = applyPathTemplate(handler.url, inputRecord);\n } catch (error) {\n if (error instanceof Error && error.message.startsWith('invalid-path-parameter:')) {\n const field = error.message.slice('invalid-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" is not a valid value`, {\n requestId: context.requestId,\n resourceId: context.resourceId,\n details: { field },\n });\n }\n if (error instanceof Error && error.message.startsWith('missing-path-parameter:')) {\n // Returning here is tempting: a missing path parameter is a\n // config/schema mismatch, not caller input, and so arguably not this\n // function's job. But that lets a paid, `{param}`-templated resource\n // whose schema can never supply it reach settle() on every call — the buyer pays, the backend is never\n // called, and there is no refund. The request genuinely cannot be\n // served, so it throws here, before payment, the same as an invalid\n // value does two lines up. `normaliseResource` (src/config) is\n // the root-cause fix — it rejects this shape at config load — but a\n // hand-built `CommerceResource` or a future adapter must not be able\n // to reintroduce the money bug just by skipping config validation.\n const field = error.message.slice('missing-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" was not supplied`, {\n requestId: context.requestId,\n resourceId: context.resourceId,\n details: { field },\n });\n }\n return;\n }\n\n if (handler.method === 'GET' || handler.method === 'DELETE') {\n let target: URL;\n try {\n target = new URL(templated.url);\n } catch {\n return; // call() surfaces the real BACKEND_ERROR for an unparseable URL.\n }\n checkQueryCollision(target, templated.remaining, context);\n }\n}\n\nfunction checkQueryCollision(\n target: URL,\n remaining: Record<string, unknown>,\n context: { readonly requestId: string; readonly resourceId: string },\n): void {\n const templateKeys = new Set(target.searchParams.keys());\n for (const key of Object.keys(remaining)) {\n if (templateKeys.has(key)) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `Input key \"${key}\" collides with a query parameter already set on backend.url`,\n { requestId: context.requestId, resourceId: context.resourceId, details: { field: key } },\n );\n }\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n// encodeURIComponent does not escape \".\" — a raw \"..\"/\".\" path-parameter\n// value survives it and new URL() then normalises the segment away, letting\n// a caller step outside the template's own directory (bounded traversal:\n// slashes ARE escaped, so only removing segments, never adding them). Reject\n// these exact values at substitution time instead of shipping them.\nconst TRAVERSAL_PATH_VALUES = new Set(['', '.', '..']);\n\nfunction applyPathTemplate(\n template: string,\n input: Record<string, unknown>,\n): { url: string; remaining: Record<string, unknown> } {\n const remaining: Record<string, unknown> = { ...input };\n let missing: string | undefined;\n let invalid: string | undefined;\n const url = template.replace(PATH_PARAM_PATTERN, (_match, key: string) => {\n // Object.hasOwn, not `key in remaining`: `in` also matches inherited\n // Object.prototype names (\"constructor\", \"toString\", …), which a\n // config-authored template naming a path param after one of them would\n // otherwise silently resolve to the wrong (inherited) value.\n if (!Object.hasOwn(remaining, key)) {\n missing = key;\n return '';\n }\n const value = remaining[key];\n delete remaining[key];\n const raw = stringifyPrimitive(value);\n if (TRAVERSAL_PATH_VALUES.has(raw)) {\n invalid = key;\n return '';\n }\n return encodeURIComponent(raw);\n });\n if (missing !== undefined) {\n throw new Error(`missing-path-parameter:${missing}`);\n }\n if (invalid !== undefined) {\n throw new Error(`invalid-path-parameter:${invalid}`);\n }\n return { url, remaining };\n}\n\nfunction describeConstructionError(error: unknown): string {\n if (error instanceof Error && error.message.startsWith('missing-path-parameter:')) {\n return error.message;\n }\n return 'invalid-url';\n}\n\nfunction stringifyPrimitive(value: unknown): string {\n if (value === undefined || value === null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n const target = name.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === target);\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n headers.forEach((value, key) => {\n record[key] = value;\n });\n return record;\n}\n\nasync function readBodyCapped(response: Response, maxBytes: number): Promise<string> {\n if (!response.body) return '';\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new Error(`response-body-too-large:${maxBytes}`);\n }\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return Buffer.concat(chunks).toString('utf8');\n}\n\nasync function parseBody(response: Response, contentType: string): Promise<unknown> {\n const text = await readBodyCapped(response, MAX_RESPONSE_BODY_BYTES);\n if (text.length === 0) return text;\n if (contentType.includes('json')) {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }\n return text;\n}\n\nfunction truncateSnippet(body: unknown): string {\n const text = typeof body === 'string' ? body : safeStringify(body);\n return text.length > MAX_BODY_SNIPPET_LENGTH\n ? `${text.slice(0, MAX_BODY_SNIPPET_LENGTH)}…`\n : text;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && (error.name === 'TimeoutError' || error.name === 'AbortError');\n}\n","/**\n * Fan-out `EventSink`: persists every event to the receipt store and notifies\n * in-process subscribers (the gateway's SSE feed). Never throws to the caller —\n * a store or subscriber failure is caught and logged.\n */\nimport type { CommerceEvent, EventSink } from '../domain/event.js';\nimport type { Logger } from '../interfaces/logger.js';\nimport type { Clock, IdGenerator } from '../interfaces/runtime.js';\nimport type { ReceiptStore } from '../interfaces/store.js';\n\nexport interface CreateEventBusOptions {\n readonly store: ReceiptStore;\n readonly logger: Logger;\n /** Reserved for callers that want the bus to mint ids/timestamps itself. */\n readonly ids?: IdGenerator;\n readonly clock?: Clock;\n}\n\nexport interface EventBus extends EventSink {\n /** Subscribe to every emitted event. Returns an unsubscribe function. */\n subscribe(fn: (event: CommerceEvent) => void): () => void;\n}\n\nexport function createEventBus(options: CreateEventBusOptions): EventBus {\n const subscribers = new Set<(event: CommerceEvent) => void>();\n\n return {\n async emit(event: CommerceEvent): Promise<void> {\n try {\n await options.store.appendEvent(event);\n } catch (error) {\n options.logger.error(\n { err: describeError(error), eventType: event.type, requestId: event.requestId },\n 'Failed to persist commerce event',\n );\n }\n\n for (const subscriber of subscribers) {\n try {\n subscriber(event);\n } catch (error) {\n options.logger.error(\n { err: describeError(error), eventType: event.type, requestId: event.requestId },\n 'Event subscriber threw',\n );\n }\n }\n },\n\n subscribe(fn: (event: CommerceEvent) => void): () => void {\n subscribers.add(fn);\n return () => {\n subscribers.delete(fn);\n };\n },\n };\n}\n\nfunction describeError(error: unknown): { message: string; name?: string } {\n if (error instanceof Error) {\n return { message: error.message, name: error.name };\n }\n return { message: String(error) };\n}\n","/**\n * Gateway-defined wire envelopes.\n *\n * FROZEN CONTRACT. These are the *only* representations of \"payment required\"\n * and \"error\" that leave the gateway, whichever protocol carries them. The HTTP\n * routes, the MCP adapter and the demo buyer agent all use these helpers so the\n * three can never drift apart.\n */\n\nimport type { CommerceError, CommerceErrorCode } from '../errors/index.js';\nimport type { DecimalAmount, IsoTimestamp, PaymentMethodName } from './common.js';\nimport type { DeliveredOutcome, PaymentRequiredOutcome } from './request.js';\n\n/**\n * Reserved input property carrying a payment proof on protocols that have no\n * header channel (MCP tool calls). Over HTTP the `X-PAYMENT` header is used.\n */\nexport const PAYMENT_INPUT_FIELD = '_payment';\n\n/** HTTP header carrying the payment proof. */\nexport const PAYMENT_HEADER = 'x-payment';\n\n/** HTTP response header carrying the settlement reference. */\nexport const PAYMENT_RESPONSE_HEADER = 'x-payment-response';\n\n/**\n * Key under which a protocol adapter attaches a {@link DeliverySummary} to its\n * result metadata — MCP's `CallToolResult._meta`, and anywhere else a protocol\n * offers an out-of-band metadata channel.\n *\n * Frozen deliberately. The bug this whole mechanism exists to fix was two\n * surfaces disagreeing about what a payer gets back; a key name enforced only\n * by one side's tests would reintroduce exactly that drift. Producer and\n * consumer both import this constant.\n *\n * Follows MCP's `<namespace>/<name>` convention for `_meta` keys.\n */\nexport const DELIVERY_SUMMARY_META_KEY = 'agent-commerce/delivery';\n\nexport interface PaymentRequiredEnvelope {\n readonly status: 'payment-required';\n readonly code: 'PAYMENT_REQUIRED';\n readonly requestId: string;\n readonly resourceId: string;\n readonly message: string;\n readonly payment: {\n readonly provider: PaymentMethodName;\n readonly version: string;\n readonly amount: DecimalAmount;\n readonly currency: string;\n readonly destination: string;\n readonly network?: string;\n readonly asset?: string;\n readonly expiresAt?: IsoTimestamp;\n /** Provider-native requirement objects, passed through verbatim. */\n readonly accepts: readonly Readonly<Record<string, unknown>>[];\n };\n}\n\nexport interface ErrorEnvelope {\n readonly status: 'error';\n readonly code: CommerceErrorCode;\n readonly message: string;\n readonly retryable: boolean;\n readonly requestId?: string;\n readonly resourceId?: string;\n readonly details?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * What a buyer learns about their own completed purchase.\n *\n * A payer is entitled to the record of their own transaction — the request it\n * belonged to, whether it settled, and the settlement reference they can check\n * on-chain. They are NOT entitled to the merchant's ledger, which is why\n * `/api/receipts` is an operator route behind `server.adminToken`.\n *\n * Before this existed the two surfaces disagreed: HTTP callers received a\n * settlement summary in `X-PAYMENT-RESPONSE` while MCP callers received\n * nothing, so an MCP buyer's only route to their own receipt was the merchant's\n * ledger. Both surfaces now emit this same shape.\n */\nexport interface DeliverySummary {\n readonly requestId: string;\n readonly resourceId: string;\n readonly receiptId: string;\n readonly deliveredAt: IsoTimestamp;\n readonly payment?: {\n readonly status: 'verified' | 'settled' | 'rejected';\n readonly amount: DecimalAmount;\n readonly currency: string;\n /** Settlement reference, e.g. an on-chain transaction hash. */\n readonly externalReference?: string;\n readonly network?: string;\n };\n}\n\n/** Build the payer-facing summary of a delivered outcome. */\nexport function toDeliverySummary(outcome: DeliveredOutcome): DeliverySummary {\n const p = outcome.payment;\n return {\n requestId: outcome.requestId,\n resourceId: outcome.resourceId,\n receiptId: outcome.receipt.id,\n deliveredAt: outcome.receipt.deliveredAt,\n ...(p !== undefined\n ? {\n payment: {\n status: p.status,\n amount: p.amount,\n currency: p.currency,\n ...(p.externalReference !== undefined\n ? { externalReference: p.externalReference }\n : {}),\n ...(p.network !== undefined ? { network: p.network } : {}),\n },\n }\n : {}),\n };\n}\n\nexport function toPaymentRequiredEnvelope(\n outcome: PaymentRequiredOutcome,\n): PaymentRequiredEnvelope {\n const r = outcome.requirement;\n return {\n status: 'payment-required',\n code: 'PAYMENT_REQUIRED',\n requestId: outcome.requestId,\n resourceId: outcome.resourceId,\n message: `Payment of ${r.amount} ${r.currency} is required for resource \"${outcome.resourceId}\". Retry with a ${r.provider} payment proof.`,\n payment: {\n provider: r.provider,\n version: r.challenge.version,\n amount: r.amount,\n currency: r.currency,\n destination: r.destination,\n ...(r.network !== undefined ? { network: r.network } : {}),\n ...(r.asset !== undefined ? { asset: r.asset } : {}),\n ...(r.expiresAt !== undefined ? { expiresAt: r.expiresAt } : {}),\n accepts: r.challenge.accepts,\n },\n };\n}\n\nexport function toErrorEnvelope(error: CommerceError): ErrorEnvelope {\n const info = error.toInfo();\n return {\n status: 'error',\n code: info.code,\n message: info.message,\n retryable: info.retryable,\n ...(info.requestId !== undefined ? { requestId: info.requestId } : {}),\n ...(info.resourceId !== undefined ? { resourceId: info.resourceId } : {}),\n ...(info.details !== undefined ? { details: info.details } : {}),\n };\n}\n\nexport function isPaymentRequiredEnvelope(value: unknown): value is PaymentRequiredEnvelope {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as PaymentRequiredEnvelope).status === 'payment-required' &&\n typeof (value as PaymentRequiredEnvelope).payment === 'object'\n );\n}\n","/**\n * A small, honest JSON Schema validator for resource input.\n *\n * Supported subset (draft-2020-12 vocabulary, structural only):\n * - `type`: \"object\" | \"string\" | \"number\" | \"integer\" | \"boolean\" | \"array\" | \"null\",\n * or an array of any of those (draft-2020-12 union form, e.g. `[\"object\",\"null\"]`)\n * - `properties` (object schemas, validated recursively)\n * - `required` (string[])\n * - `additionalProperties` (boolean, or a schema applied to extra properties)\n * - `enum` (array of allowed literal values, deep-equality compared)\n * - `items` (single schema applied to every array element — no tuple form)\n *\n * Explicitly NOT supported and silently ignored (never enforced):\n * `minLength`, `maxLength`, `pattern`, `format`, `minimum`, `maximum`,\n * `exclusiveMinimum/Maximum`, `multipleOf`, `oneOf`, `anyOf`, `allOf`, `not`,\n * `$ref`, `const`, `patternProperties`, `minItems`, `maxItems`, `uniqueItems`,\n * tuple-style `items` arrays. An unrecognised `type` value is not enforced\n * either. This is a deliberate, documented limitation for v0.1.0-alpha — do\n * not assume any of the above is validated.\n */\nimport type { JsonSchema } from '../domain/common.js';\n\nexport interface FieldError {\n readonly path: string;\n readonly message: string;\n}\n\nexport type ValidationResult =\n | { readonly valid: true; readonly value: unknown }\n | { readonly valid: false; readonly errors: readonly FieldError[] };\n\nexport type Validator = (input: unknown) => ValidationResult;\n\nconst SUPPORTED_TYPES = new Set([\n 'object',\n 'string',\n 'number',\n 'integer',\n 'boolean',\n 'array',\n 'null',\n]);\n\n/** Compile a resource `inputSchema` into a reusable validator function. */\nexport function compileJsonSchema(schema: JsonSchema | undefined): Validator {\n return (input: unknown): ValidationResult => {\n if (schema === undefined) return { valid: true, value: input };\n const errors = validateNode(schema, input, '$');\n return errors.length === 0 ? { valid: true, value: input } : { valid: false, errors };\n };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction matchesType(type: string, value: unknown): boolean {\n switch (type) {\n case 'object':\n return isPlainObject(value);\n case 'array':\n return Array.isArray(value);\n case 'string':\n return typeof value === 'string';\n case 'boolean':\n return typeof value === 'boolean';\n case 'number':\n return typeof value === 'number' && Number.isFinite(value);\n case 'integer':\n return typeof value === 'number' && Number.isInteger(value);\n case 'null':\n return value === null;\n default:\n return true;\n }\n}\n\nfunction describeType(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null) return false;\n if (typeof a !== 'object') return false;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n}\n\nfunction own(obj: Record<string, unknown>, key: string): unknown {\n return Object.hasOwn(obj, key) ? obj[key] : undefined;\n}\n\n/**\n * `type` may be a single string or (draft-2020-12) an array of strings,\n * e.g. `[\"object\", \"null\"]`. Only recognised when every entry is a string —\n * same conservative \"skip rather than guess\" rule the single-string form\n * already followed for an unrecognised type name.\n */\nfunction typeList(raw: unknown): string[] | undefined {\n if (typeof raw === 'string') return [raw];\n if (Array.isArray(raw) && raw.every((entry): entry is string => typeof entry === 'string')) {\n return raw;\n }\n return undefined;\n}\n\n/**\n * A bare `type === 'object'` string comparison is not enough: `type:\n * [\"object\", \"null\"]` — valid JSON Schema — would never route into\n * `validateObject`, so neither `required` nor `additionalProperties` would be\n * enforced on it, while `defaultClosedObjectSchema` (src/config) stamps\n * `additionalProperties: false` on it believing it closed. Also treats a node\n * with `properties`/`required` and no `type`\n * at all as an object schema, the same shape config's own stamping already\n * recognises via a bare `properties` check — a schema author relying on\n * `type` being implied by `properties` should not be silently unenforced.\n *\n * **exported**, and now the only definition of \"this node is\n * an object schema\" in the codebase. `src/config`'s `defaultClosedObjectSchema`\n * carried its own — `declaresObjectType || properties` — one keyword short of\n * this one, so a schema declaring only `required` was stamped by neither:\n * config left it open and this validator then enforced nothing on it, quietly\n * forwarding every unknown caller key to the merchant's backend while\n * docs/security.md promised \"closed by default at every level\". These two\n * definitions have been aligned once already; keeping them as two definitions\n * is what let them drift again.\n */\nexport function isObjectSchemaNode(schema: Record<string, unknown>): boolean {\n const types = typeList(schema['type']);\n if (types !== undefined) return types.includes('object');\n return Object.hasOwn(schema, 'properties') || Object.hasOwn(schema, 'required');\n}\n\nfunction validateNode(schema: JsonSchema, value: unknown, path: string): FieldError[] {\n const errors: FieldError[] = [];\n const types = typeList(own(schema, 'type'));\n const recognisedTypes = types?.filter((entry) => SUPPORTED_TYPES.has(entry));\n\n if (\n types !== undefined &&\n recognisedTypes !== undefined &&\n recognisedTypes.length === types.length &&\n types.length > 0\n ) {\n if (!types.some((entry) => matchesType(entry, value))) {\n errors.push({\n path,\n message: `expected type \"${types.join(' | ')}\" but got ${describeType(value)}`,\n });\n return errors;\n }\n }\n\n const enumRaw = own(schema, 'enum');\n if (Array.isArray(enumRaw)) {\n const allowed = enumRaw as unknown[];\n if (!allowed.some((candidate) => deepEqual(candidate, value))) {\n errors.push({ path, message: `must be one of ${JSON.stringify(allowed)}` });\n }\n }\n\n if (isObjectSchemaNode(schema) && isPlainObject(value)) {\n errors.push(...validateObject(schema, value, path));\n } else if ((types?.includes('array') ?? false) && Array.isArray(value)) {\n errors.push(...validateArray(schema, value, path));\n }\n\n return errors;\n}\n\nfunction validateObject(\n schema: JsonSchema,\n value: Record<string, unknown>,\n path: string,\n): FieldError[] {\n const errors: FieldError[] = [];\n const propsRaw = own(schema, 'properties');\n const properties = isPlainObject(propsRaw) ? propsRaw : {};\n const requiredRaw = own(schema, 'required');\n const required = Array.isArray(requiredRaw)\n ? requiredRaw.filter((entry): entry is string => typeof entry === 'string')\n : [];\n\n for (const key of required) {\n // Object.hasOwn, not `in`: `in` walks the prototype chain, so a schema\n // requiring \"toString\"/\"constructor\"/\"valueOf\"/\"hasOwnProperty\"/\n // \"__proto__\" could never actually enforce it — those names are always\n // present via inheritance, so `!(key in value)` is always false. This is\n // the same bug class every other lookup in this file already\n // guards against by using own().\n if (!Object.hasOwn(value, key)) {\n errors.push({ path: `${path}.${key}`, message: 'is required' });\n }\n }\n\n const additional = own(schema, 'additionalProperties');\n\n for (const key of Object.keys(value)) {\n // Object.hasOwn, not `properties[key]`: a plain-object lookup for\n // \"__proto__\"/\"constructor\"/\"toString\"/\"valueOf\"/\"hasOwnProperty\" resolves\n // to an inherited Object.prototype member instead of undefined, so those\n // keys would otherwise silently skip the additionalProperties check below\n //.\n const propSchemaRaw = own(properties, key);\n if (propSchemaRaw !== undefined) {\n if (isPlainObject(propSchemaRaw)) {\n errors.push(...validateNode(propSchemaRaw, value[key], `${path}.${key}`));\n }\n continue;\n }\n if (additional === false) {\n errors.push({ path: `${path}.${key}`, message: 'additional property not allowed' });\n } else if (isPlainObject(additional)) {\n errors.push(...validateNode(additional, value[key], `${path}.${key}`));\n }\n }\n\n return errors;\n}\n\nfunction validateArray(schema: JsonSchema, value: unknown[], path: string): FieldError[] {\n const errors: FieldError[] = [];\n const itemsRaw = own(schema, 'items');\n if (isPlainObject(itemsRaw)) {\n value.forEach((item, index) => {\n errors.push(...validateNode(itemsRaw, item, `${path}[${index}]`));\n });\n }\n return errors;\n}\n","/**\n * The single execution path every protocol adapter converges on.\n *\n * Order is a security boundary — do not reorder:\n * 1. resolve resource RESOURCE_NOT_FOUND\n * 2. strip `_payment`, validate input INPUT_INVALID\n * 3. resolve price\n * 4. free -> straight to backend\n * 5. paid -> pick provider -> createRequirement -> (challenge | verify ->\n * reserve replay key -> settle), fail closed at every step\n * 6. call backend BACKEND_TIMEOUT / BACKEND_ERROR\n * 7. persist receipt, emit events, return outcome\n */\n\nimport type { PaymentMethodName } from '../domain/common.js';\nimport type { CommerceEvent, EventSink } from '../domain/event.js';\nimport type { PaymentProvider, PaymentRequirement, PaymentResult } from '../domain/payment.js';\nimport type { CommerceReceipt } from '../domain/receipt.js';\nimport type { CanonicalRequest, ExecutionOutcome, ExecutionPipeline } from '../domain/request.js';\nimport type { CommerceResource, ResourceRegistry } from '../domain/resource.js';\nimport { PAYMENT_INPUT_FIELD } from '../domain/wire.js';\nimport { CommerceError, isCommerceError, toCommerceError } from '../errors/index.js';\nimport type { BackendExecutor, BackendResponse } from '../interfaces/backend.js';\nimport type { Logger } from '../interfaces/logger.js';\nimport type { Clock, IdGenerator } from '../interfaces/runtime.js';\nimport type { ReceiptStore } from '../interfaces/store.js';\nimport { validateBackendRequestShape } from './backend-http.js';\nimport { compileJsonSchema, type Validator } from './validation.js';\n\nexport interface CreateExecutionPipelineOptions {\n readonly resources: ResourceRegistry;\n readonly paymentProviders: readonly PaymentProvider[];\n readonly store: ReceiptStore;\n readonly backend: BackendExecutor;\n readonly events: EventSink;\n readonly logger: Logger;\n readonly clock: Clock;\n readonly ids: IdGenerator;\n}\n\nexport function createExecutionPipeline(\n options: CreateExecutionPipelineOptions,\n): ExecutionPipeline {\n const validators = new Map<string, Validator>();\n\n function getValidator(resource: CommerceResource): Validator {\n const cached = validators.get(resource.id);\n if (cached) return cached;\n const compiled = compileJsonSchema(resource.inputSchema);\n validators.set(resource.id, compiled);\n return compiled;\n }\n\n async function safeEmit(event: CommerceEvent): Promise<void> {\n try {\n await options.events.emit(event);\n } catch (error) {\n options.logger.error(\n { err: describeError(error), eventType: event.type, requestId: event.requestId },\n 'Event sink failed; commerce flow continues',\n );\n }\n }\n\n async function safePersist(\n op: () => Promise<void>,\n label: string,\n requestId: string,\n ): Promise<void> {\n try {\n await op();\n } catch (error) {\n options.logger.error(\n { err: describeError(error), requestId },\n `Persistence failed: ${label}`,\n );\n }\n }\n\n function buildEvent(partial: Omit<CommerceEvent, 'id' | 'at'>): CommerceEvent {\n return { id: options.ids.next('evt'), at: options.clock.nowIso(), ...partial };\n }\n\n async function execute(request: CanonicalRequest): Promise<ExecutionOutcome> {\n const pipelineStart = options.clock.monotonicMs();\n\n // 1. resolve resource\n const resource = options.resources.get(request.resourceId);\n // Same code, same message as a genuine miss: `expose` is an admin scoping\n // decision enforced on the one execution path every adapter shares — a\n // caller on a protocol the resource isn't exposed via must not be able to\n // distinguish \"doesn't exist\" from \"exists but not for you\".\n if (!resource || !resource.exposedVia.includes(request.protocol)) {\n throw new CommerceError(\n 'RESOURCE_NOT_FOUND',\n `Resource \"${request.resourceId}\" was not found`,\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n },\n );\n }\n\n await safeEmit(\n buildEvent({\n type: 'resource.requested',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n }),\n );\n\n // 2. strip reserved payment field, then validate input\n const strippedInput = stripPaymentField(request.input);\n const validation = getValidator(resource)(strippedInput);\n if (!validation.valid) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `Input for resource \"${resource.id}\" failed validation`,\n {\n requestId: request.requestId,\n resourceId: resource.id,\n details: { errors: validation.errors },\n },\n );\n }\n const validInput = validation.value;\n\n // validate the backend request shape (path-traversal, query-param\n // collision) here — before price resolution, so a resource that fails\n // this check never reaches payment. Both checks are pure functions of\n // (handler.url, input); doing them at pipeline step 6 (inside the actual\n // backend call) meant a bad value like `{ city: \"\" }` against a paid,\n // path-templated resource settled the buyer's payment and then never\n // called the backend at all — payment without delivery. call() keeps its\n // own copy of these checks as defence in depth.\n validateBackendRequestShape(resource.handler, validInput, {\n requestId: request.requestId,\n resourceId: resource.id,\n });\n\n // 3. resolve price\n if (resource.pricing.type === 'dynamic') {\n // Config validation rejects this before the gateway starts; this is defence-in-depth.\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${resource.id}\" uses unsupported dynamic pricing`,\n {\n requestId: request.requestId,\n resourceId: resource.id,\n },\n );\n }\n\n let paymentResult: PaymentResult | undefined;\n\n if (resource.pricing.type === 'fixed') {\n const pricing = resource.pricing;\n const provider = pickProvider(options.paymentProviders, resource.paymentMethods);\n if (!provider) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `No enabled payment provider for resource \"${resource.id}\"`,\n {\n requestId: request.requestId,\n resourceId: resource.id,\n details: { paymentMethods: resource.paymentMethods },\n },\n );\n }\n\n let requirement: PaymentRequirement;\n try {\n requirement = await provider.createRequirement({\n requestId: request.requestId,\n resource,\n amount: pricing.amount,\n currency: pricing.currency,\n requestedAt: options.clock.nowIso(),\n });\n } catch (error) {\n throw isCommerceError(error)\n ? error\n : new CommerceError('PAYMENT_PROVIDER_UNAVAILABLE', 'Payment provider is unavailable', {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: error,\n });\n }\n\n if (!request.payment) {\n await safeEmit(\n buildEvent({\n type: 'payment.required',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n }),\n );\n return {\n kind: 'payment-required',\n requestId: request.requestId,\n resourceId: resource.id,\n requirement,\n };\n }\n\n const payment = request.payment;\n\n let verification: PaymentResult;\n try {\n verification = await provider.verify({\n requestId: request.requestId,\n resource,\n requirement,\n submission: payment,\n });\n } catch (error) {\n // Any typed CommerceError the provider throws is rethrown as-is (a\n // provider can legitimately fail with STORAGE_ERROR, etc. — flattening\n // every code to PAYMENT_INVALID would hide the real cause and the\n // real, possibly-retryable HTTP status). Only a genuinely untyped\n // throw is mapped, with a fixed client-facing message — never the\n // raw error's own message.\n const mapped = isCommerceError(error)\n ? error\n : new CommerceError('PAYMENT_INVALID', 'Payment verification failed', {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: error,\n });\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: { reason: mapped.code },\n }),\n );\n throw mapped;\n }\n\n if (verification.status !== 'verified') {\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: verification.rejectionReason ? { reason: verification.rejectionReason } : {},\n }),\n );\n throw new CommerceError(\n 'PAYMENT_INVALID',\n verification.rejectionReason ?? 'Payment was rejected',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n },\n );\n }\n\n if (!verification.replayKey) {\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: { reason: 'missing-replay-key' },\n }),\n );\n throw new CommerceError('PAYMENT_INVALID', 'Payment provider did not return a replay key', {\n requestId: request.requestId,\n resourceId: resource.id,\n });\n }\n const replayKey = verification.replayKey;\n\n try {\n await options.store.reservePaymentAttempt({\n requestId: request.requestId,\n resourceId: resource.id,\n provider: provider.name,\n replayKey,\n amount: verification.amount,\n currency: verification.currency,\n ...(verification.payer !== undefined ? { payer: verification.payer } : {}),\n ...(verification.payee !== undefined ? { payee: verification.payee } : {}),\n });\n } catch (error) {\n // The store contract only promises PAYMENT_REPLAYED for an actual\n // duplicate replayKey (already a CommerceError with that code, so\n // isCommerceError below preserves it as-is). Anything else — a disk-\n // full error, a dropped connection — is a storage failure, not a\n // replay, and must not be mislabelled as one: telling a buyer\n // \"duplicate payment\" for a transient outage is actively false, and\n // poisons any alerting keyed on replay counts.\n const mapped = toCommerceError(\n error,\n 'STORAGE_ERROR',\n 'Payment attempt could not be recorded',\n );\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: { reason: mapped.code },\n }),\n );\n throw mapped;\n }\n\n await safeEmit(\n buildEvent({\n type: 'payment.verified',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'ok',\n }),\n );\n\n let settlement: PaymentResult;\n try {\n settlement = await provider.settle({\n requestId: request.requestId,\n resource,\n requirement,\n submission: payment,\n verification,\n });\n } catch (error) {\n // / \"the RPC did not answer\" and \"the transfer did not\n // happen\" are different facts. A provider that broadcast a settlement\n // transaction and then failed to confirm it throws\n // PAYMENT_PROVIDER_UNAVAILABLE with details.transactionHash attached\n // (the hash is known before confirmation). Recording that as plain\n // `failed` would tell the merchant's reconciliation artefact a\n // falsehood — the buyer's funds may already have moved. The resource\n // is still not delivered either way: only what gets *recorded*\n // changes, never the fail-closed outcome.\n const uncertainTxHash = uncertainSettlementTxHash(error);\n await safePersist(\n () =>\n options.store.updatePaymentAttempt(\n uncertainTxHash !== undefined\n ? { replayKey, status: 'settlement-uncertain', externalReference: uncertainTxHash }\n : {\n replayKey,\n status: 'failed',\n ...(error instanceof Error ? { rejectionReason: error.message } : {}),\n },\n ),\n uncertainTxHash !== undefined\n ? 'updatePaymentAttempt(settlement-uncertain)'\n : 'updatePaymentAttempt(failed)',\n request.requestId,\n );\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data:\n uncertainTxHash !== undefined\n ? { reason: 'settlement-uncertain', transactionHash: uncertainTxHash }\n : { reason: 'settlement-threw' },\n }),\n );\n // The merchant's record now tells the truth (above); the buyer must\n // too — they are the party whose funds may have moved, and the\n // client-visible error is their only way to find out. Code stays\n // PAYMENT_SETTLEMENT_FAILED (not PAYMENT_PROVIDER_UNAVAILABLE, which\n // is retryable) — a retry would reuse the already-reserved replay\n // key. The transaction hash is safe to disclose: it's the buyer's\n // own payment, public on-chain the moment it lands. Nothing else\n // from the underlying error travels — only this flag and the hash.\n throw new CommerceError(\n 'PAYMENT_SETTLEMENT_FAILED',\n uncertainTxHash !== undefined\n ? 'Settlement could not be confirmed'\n : 'Payment settlement failed',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: error,\n ...(uncertainTxHash !== undefined\n ? { details: { settlementUncertain: true, transactionHash: uncertainTxHash } }\n : {}),\n },\n );\n }\n\n if (settlement.status !== 'settled') {\n await safePersist(\n () =>\n options.store.updatePaymentAttempt({\n replayKey,\n status: 'rejected',\n ...(settlement.rejectionReason !== undefined\n ? { rejectionReason: settlement.rejectionReason }\n : {}),\n }),\n 'updatePaymentAttempt(rejected)',\n request.requestId,\n );\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: settlement.rejectionReason ? { reason: settlement.rejectionReason } : {},\n }),\n );\n throw new CommerceError(\n 'PAYMENT_SETTLEMENT_FAILED',\n settlement.rejectionReason ?? 'Settlement was rejected',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n },\n );\n }\n\n await safePersist(\n () =>\n options.store.updatePaymentAttempt({\n replayKey,\n status: 'settled',\n ...(settlement.externalReference !== undefined\n ? { externalReference: settlement.externalReference }\n : {}),\n }),\n 'updatePaymentAttempt(settled)',\n request.requestId,\n );\n await safeEmit(\n buildEvent({\n type: 'payment.settled',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'ok',\n }),\n );\n\n paymentResult = settlement;\n }\n\n // 6. call backend\n const backendStart = options.clock.monotonicMs();\n let backendResponse: BackendResponse;\n try {\n backendResponse = await options.backend.call(resource.handler, {\n requestId: request.requestId,\n resourceId: resource.id,\n input: validInput,\n });\n } catch (error) {\n const commerceError = toCommerceError(error, 'BACKEND_ERROR', 'Backend call failed');\n await safeEmit(\n buildEvent({\n type: 'backend.failed',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n status: 'error',\n durationMs: Math.round(options.clock.monotonicMs() - backendStart),\n data: { code: commerceError.code },\n }),\n );\n\n if (paymentResult !== undefined) {\n // Settlement already succeeded (verify -> reserve -> settle all\n // completed) before the backend call failed, so the\n // uncertain-settlement rule (\"the merchant's record now tells the\n // truth; the buyer must too\") applies to this far more common\n // *certain*-loss branch as well, not only to the uncertain-RPC-timeout\n // one 100 lines above. A backend 500 is more likely than an RPC\n // confirmation timeout, so disclosing strictly *less* here than there\n // would be backwards. The tx hash is\n // safe to disclose: it is the buyer's own payment, public\n // on-chain the moment it lands.\n const failedReceipt: CommerceReceipt = {\n id: options.ids.next('receipt'),\n requestId: request.requestId,\n resourceId: resource.id,\n deliveredAt: options.clock.nowIso(),\n backendStatus: backendErrorStatus(commerceError),\n protocol: request.protocol,\n payment: paymentResult,\n metadata: { delivered: false, backendErrorCode: commerceError.code },\n };\n await safePersist(\n () => options.store.saveReceipt(failedReceipt),\n 'saveReceipt(backend-failed-after-settlement)',\n request.requestId,\n );\n\n throw new CommerceError(\n 'BACKEND_ERROR',\n 'Payment settled but the backend call failed; the payment was not refunded automatically',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: commerceError,\n details: {\n payment: {\n status: paymentResult.status,\n provider: paymentResult.provider,\n amount: paymentResult.amount,\n currency: paymentResult.currency,\n ...(paymentResult.externalReference !== undefined\n ? { externalReference: paymentResult.externalReference }\n : {}),\n },\n },\n },\n );\n }\n\n throw commerceError;\n }\n\n await safeEmit(\n buildEvent({\n type: 'backend.called',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n status: 'ok',\n durationMs: backendResponse.durationMs,\n data: { status: backendResponse.status },\n }),\n );\n\n // 7. persist receipt, emit final event, return outcome\n const receipt: CommerceReceipt = {\n id: options.ids.next('receipt'),\n requestId: request.requestId,\n resourceId: resource.id,\n deliveredAt: options.clock.nowIso(),\n backendStatus: backendResponse.status,\n durationMs: backendResponse.durationMs,\n protocol: request.protocol,\n ...(paymentResult !== undefined ? { payment: paymentResult } : {}),\n };\n\n await safePersist(() => options.store.saveReceipt(receipt), 'saveReceipt', request.requestId);\n\n const totalDurationMs = Math.round(options.clock.monotonicMs() - pipelineStart);\n\n await safeEmit(\n buildEvent({\n type: 'resource.delivered',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n status: 'ok',\n durationMs: totalDurationMs,\n }),\n );\n\n return {\n kind: 'delivered',\n requestId: request.requestId,\n resourceId: resource.id,\n backendStatus: backendResponse.status,\n body: backendResponse.body,\n headers: backendResponse.headers,\n ...(paymentResult !== undefined ? { payment: paymentResult } : {}),\n receipt,\n durationMs: totalDurationMs,\n };\n }\n\n return { execute };\n}\n\n/** The HTTP status the backend actually returned, when known (backend-http.ts\n * attaches it as `details.status` for a non-2xx response). 0 means \"no\n * response was received at all\" (timeout/transport failure) — distinct from\n * any real HTTP status. */\nfunction backendErrorStatus(error: CommerceError): number {\n const status = error.details?.['status'];\n return typeof status === 'number' ? status : 0;\n}\n\nfunction uncertainSettlementTxHash(error: unknown): string | undefined {\n if (!isCommerceError(error) || error.code !== 'PAYMENT_PROVIDER_UNAVAILABLE') return undefined;\n const hash = error.details?.['transactionHash'];\n return typeof hash === 'string' ? hash : undefined;\n}\n\nfunction pickProvider(\n providers: readonly PaymentProvider[],\n methods: readonly PaymentMethodName[],\n): PaymentProvider | undefined {\n for (const method of methods) {\n const found = providers.find((provider) => provider.name === method);\n if (found) return found;\n }\n return undefined;\n}\n\nconst RESERVED_INPUT_KEYS = new Set([PAYMENT_INPUT_FIELD, '__proto__']);\n\nfunction stripPaymentField(input: unknown): unknown {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return input;\n const record = input as Record<string, unknown>;\n // Object.hasOwn: `in` would also match inherited names and strip things\n // that were never actually present on this input.\n const hasReserved = [...RESERVED_INPUT_KEYS].some((key) => Object.hasOwn(record, key));\n if (!hasReserved) return input;\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n // \"__proto__\" is dropped, not just excluded from the reserved-field\n // check: `rest[key] = record[key]` for key === \"__proto__\" would invoke\n // the inherited setter and reassign rest's own prototype instead of\n // creating a data property (belt-and-braces — validation.ts's\n // Object.hasOwn fix is the primary control).\n if (!RESERVED_INPUT_KEYS.has(key)) rest[key] = record[key];\n }\n return rest;\n}\n\nfunction describeError(error: unknown): { message: string; name?: string } {\n if (error instanceof Error) return { message: error.message, name: error.name };\n return { message: String(error) };\n}\n","/**\n * In-memory implementation of the frozen `ResourceRegistry` interface.\n */\nimport type { ProtocolName } from '../domain/common.js';\nimport type { CommerceResource, ResourceRegistry } from '../domain/resource.js';\nimport { CommerceError } from '../errors/index.js';\n\nexport class ResourceRegistryImpl implements ResourceRegistry {\n private readonly byId = new Map<string, CommerceResource>();\n private readonly ordered: readonly CommerceResource[];\n\n constructor(resources: readonly CommerceResource[]) {\n for (const resource of resources) {\n if (this.byId.has(resource.id)) {\n throw new CommerceError('CONFIG_INVALID', `Duplicate resource id \"${resource.id}\"`, {\n details: { resourceId: resource.id },\n });\n }\n this.byId.set(resource.id, resource);\n }\n this.ordered = [...resources];\n }\n\n get(id: string): CommerceResource | undefined {\n return this.byId.get(id);\n }\n\n list(): readonly CommerceResource[] {\n return this.ordered;\n }\n\n listExposedVia(protocol: ProtocolName): readonly CommerceResource[] {\n return this.ordered.filter((resource) => resource.exposedVia.includes(protocol));\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n}\n\n/** Build a `ResourceRegistry` from a validated list of canonical resources. */\nexport function createResourceRegistry(resources: readonly CommerceResource[]): ResourceRegistry {\n return new ResourceRegistryImpl(resources);\n}\n","/**\n * src/core/execution\n *\n * The execution pipeline implementation: resource registry, backend executor,\n * event bus and the pipeline itself. Not part of the frozen `public-types.ts`\n * barrel — this is implementation, not contract — but exported as a stable\n * subpath so `src/gateway` (and tests) can wire it up.\n */\n\nexport type { HttpBackendExecutorOptions } from './backend-http.js';\nexport {\n extractPathParameterNames,\n findUnparsedBraceToken,\n HttpBackendExecutor,\n validateBackendRequestShape,\n} from './backend-http.js';\nexport type { CreateEventBusOptions, EventBus } from './event-bus.js';\nexport { createEventBus } from './event-bus.js';\nexport type { CreateExecutionPipelineOptions } from './pipeline.js';\nexport { createExecutionPipeline } from './pipeline.js';\nexport { createResourceRegistry, ResourceRegistryImpl } from './registry.js';\nexport type { FieldError, ValidationResult, Validator } from './validation.js';\nexport { compileJsonSchema, isObjectSchemaNode } from './validation.js';\n","/**\n * Canonical commerce events.\n *\n * FROZEN CONTRACT. Every event in a single flow shares one `requestId` so that\n * logs, payment attempts, backend calls and receipts are correlatable\n *.\n */\nimport type { IsoTimestamp } from './common.js';\n\nexport const COMMERCE_EVENT_TYPES = [\n 'resource.discovered',\n 'resource.requested',\n 'payment.required',\n 'payment.rejected',\n 'payment.verified',\n 'payment.settled',\n 'backend.called',\n 'backend.failed',\n 'resource.delivered',\n] as const;\n\nexport type CommerceEventType = (typeof COMMERCE_EVENT_TYPES)[number];\n\nexport interface CommerceEvent {\n readonly id: string;\n readonly type: CommerceEventType;\n readonly requestId: string;\n readonly resourceId?: string;\n readonly at: IsoTimestamp;\n /** Protocol adapter that originated the request, e.g. 'mcp' or 'http'. */\n readonly adapter?: string;\n readonly paymentProvider?: string;\n readonly durationMs?: number;\n readonly status?: 'ok' | 'error';\n /** Non-secret, structured detail. Must never contain keys, headers or proofs. */\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Sink for canonical events.\n *\n * Implementations must be non-throwing from the caller's perspective: an event\n * sink failure must never fail an otherwise successful commerce flow.\n */\nexport interface EventSink {\n emit(event: CommerceEvent): Promise<void>;\n}\n","/**\n * Protocol adapter boundary.\n *\n * FROZEN CONTRACT. An adapter translates a protocol's wire format into a\n * `CanonicalRequest`, hands it to the execution pipeline and maps the outcome\n * back. It must not call merchant backends, implement payment logic, or hold\n * its own copy of the canonical model.\n *\n * Adapter isolation: a failure while starting or serving one adapter must not\n * prevent the others from operating.\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { AdapterDescriptor, AdapterHealth, ProtocolName } from '../domain/common.js';\nimport type { EventSink } from '../domain/event.js';\nimport type { ExecutionPipeline } from '../domain/request.js';\nimport type { ResourceRegistry } from '../domain/resource.js';\nimport type { Logger } from './logger.js';\nimport type { Clock, IdGenerator } from './runtime.js';\n\n/** Everything an adapter is given. Nothing else is available to it. */\nexport interface ProtocolAdapterContext {\n readonly pipeline: ExecutionPipeline;\n readonly resources: ResourceRegistry;\n readonly events: EventSink;\n readonly logger: Logger;\n readonly clock: Clock;\n readonly ids: IdGenerator;\n /** Externally reachable base URL of the gateway, from config. */\n readonly publicBaseUrl: string;\n}\n\nexport interface ProtocolAdapter {\n readonly name: ProtocolName;\n readonly descriptor: AdapterDescriptor;\n\n start(context: ProtocolAdapterContext): Promise<void>;\n health(): Promise<AdapterHealth>;\n stop(): Promise<void>;\n}\n\n/**\n * A protocol adapter served over HTTP.\n *\n * The gateway mounts `handleHttp` at `mountPath` using raw Node request and\n * response objects, so adapters stay independent of the HTTP framework.\n *\n * GUARANTEE — the request body is **unconsumed**.\n *\n * `req` is handed over with its stream unread: the gateway suppresses every\n * body parser on this mount, so an adapter whose SDK reads the body itself\n * (MCP's Streamable HTTP transport does) can do so. The adapter owns reading,\n * size-limiting beyond the gateway's own cap, and parsing.\n *\n * This is load-bearing and easy to break silently. Fastify pre-registers\n * exact-match parsers for `application/json` and `text/plain` and prefers them\n * over a `'*'` wildcard, so registering only a wildcard no-op leaves the\n * built-in JSON parser draining the body first — the adapter then reads an\n * empty stream and every request fails to parse. That exact regression shipped\n * once and no unit test caught it, because adapter conformance suites drive\n * `handleHttp` over a bare `node:http` server and never traverse the gateway.\n *\n * Any change to how adapters are mounted must be covered by a test that POSTs\n * a real JSON body through the real gateway and asserts the adapter received\n * it intact.\n */\nexport interface HttpProtocolAdapter extends ProtocolAdapter {\n /** Path prefix the gateway mounts this adapter at, e.g. '/mcp'. */\n readonly mountPath: string;\n handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void>;\n}\n\nexport function isHttpProtocolAdapter(adapter: ProtocolAdapter): adapter is HttpProtocolAdapter {\n return typeof (adapter as HttpProtocolAdapter).handleHttp === 'function';\n}\n","/**\n * Injected runtime primitives.\n *\n * Everything non-deterministic (time, ids) is injected so tests can be exact.\n */\nimport type { IsoTimestamp } from '../domain/common.js';\n\nexport interface Clock {\n now(): Date;\n nowIso(): IsoTimestamp;\n /** Milliseconds since an arbitrary origin; use for durations only. */\n monotonicMs(): number;\n}\n\nexport interface IdGenerator {\n /** Opaque, collision-resistant identifier. */\n next(prefix?: string): string;\n}\n\nexport const systemClock: Clock = {\n now: () => new Date(),\n nowIso: () => new Date().toISOString(),\n monotonicMs: () => performance.now(),\n};\n","/**\n * ============================================================================\n * FROZEN PUBLIC CONTRACT — v0.1.0-alpha\n * ============================================================================\n *\n * Every cross-package type and interface in the project is re-exported here.\n * This barrel is frozen. Everything reachable from it is public API that\n * consumers code against, so a change to any of it is a breaking change and\n * needs the decision record updated to match.\n *\n * Do not redeclare these shapes locally. If something is missing, add it here\n * rather than creating a parallel type.\n *\n * See docs/contracts.md for the freeze record.\n */\n\n// --- canonical domain ------------------------------------------------------\nexport type {\n AdapterDescriptor,\n AdapterHealth,\n DecimalAmount,\n IsoTimestamp,\n JsonSchema,\n PaymentMethodName,\n ProtocolName,\n} from './domain/common.js';\nexport type { CommerceEvent, CommerceEventType, EventSink } from './domain/event.js';\nexport { COMMERCE_EVENT_TYPES } from './domain/event.js';\n\nexport type {\n PaymentChallenge,\n PaymentContext,\n PaymentProvider,\n PaymentRequirement,\n PaymentResult,\n PaymentSettlementContext,\n PaymentSubmission,\n PaymentVerificationContext,\n} from './domain/payment.js';\n\nexport type { CommerceReceipt, PaymentAttempt } from './domain/receipt.js';\nexport type {\n CanonicalRequest,\n DeliveredOutcome,\n ExecutionOutcome,\n ExecutionPipeline,\n PaymentRequiredOutcome,\n} from './domain/request.js';\nexport type {\n BackendHandler,\n BackendMethod,\n CommerceResource,\n Pricing,\n ResourceRegistry,\n} from './domain/resource.js';\nexport { DEFAULT_BACKEND_TIMEOUT_MS } from './domain/resource.js';\nexport type {\n DeliverySummary,\n ErrorEnvelope,\n PaymentRequiredEnvelope,\n} from './domain/wire.js';\nexport {\n DELIVERY_SUMMARY_META_KEY,\n isPaymentRequiredEnvelope,\n PAYMENT_HEADER,\n PAYMENT_INPUT_FIELD,\n PAYMENT_RESPONSE_HEADER,\n toDeliverySummary,\n toErrorEnvelope,\n toPaymentRequiredEnvelope,\n} from './domain/wire.js';\n\n// --- errors ----------------------------------------------------------------\nexport type { CommerceErrorCode, CommerceErrorInfo, CommerceErrorOptions } from './errors/index.js';\nexport {\n COMMERCE_ERROR_CODES,\n COMMERCE_ERROR_HTTP_STATUS,\n CommerceError,\n isCommerceError,\n RETRYABLE_ERROR_CODES,\n toCommerceError,\n} from './errors/index.js';\n\n// --- injection boundaries --------------------------------------------------\nexport type { BackendExecutor, BackendRequest, BackendResponse } from './interfaces/backend.js';\nexport type { Logger } from './interfaces/logger.js';\nexport { NOOP_LOGGER } from './interfaces/logger.js';\nexport type {\n HttpProtocolAdapter,\n ProtocolAdapter,\n ProtocolAdapterContext,\n} from './interfaces/protocol-adapter.js';\nexport { isHttpProtocolAdapter } from './interfaces/protocol-adapter.js';\nexport type { Clock, IdGenerator } from './interfaces/runtime.js';\nexport { systemClock } from './interfaces/runtime.js';\nexport type {\n ListOptions,\n PaymentAttemptReservation,\n PaymentAttemptUpdate,\n ReceiptStore,\n} from './interfaces/store.js';\n","/**\n * src/core\n *\n * Canonical commerce domain model, typed errors and the execution pipeline.\n * Contains no protocol- or payment-rail-specific code.\n */\nexport * from './public-types.js';\n","/**\n * `${VAR}` / `${VAR:-default}` substitution over an arbitrary parsed-YAML value.\n *\n * Only string leaves are touched; numbers/booleans/null pass through untouched\n * (the caller coerces the *resulting* string back into a number/boolean where\n * the schema expects one). An unresolved placeholder fails config loading\n * immediately — startup must never proceed with an unresolved secret. That\n * includes one left behind by a *nested* placeholder such as `${A:-${B}}`,\n * which is rejected rather than silently passed through. There is no\n * escape syntax for a literal `${NAME}`; nothing in this config format needs\n * one, and adding it would mean two ways to write every value.\n *\n * `${VAR}` (no default) requires `VAR` to be present in `env` (any value,\n * including an empty string, counts as present).\n * `${VAR:-default}` falls back to `default` when `VAR` is absent OR empty,\n * matching common shell semantics.\n *\n * The resolved *value* of a variable is never included in any error message —\n * only the variable *name* and the config path are.\n */\nimport { CommerceError } from '../core/index.js';\n\nconst PLACEHOLDER_PATTERN = /\\$\\{([A-Za-z_][A-Za-z0-9_]*)(:-([^}]*))?\\}/g;\n\nexport function substituteEnv(value: unknown, env: NodeJS.ProcessEnv, path = '$'): unknown {\n if (typeof value === 'string') {\n return substituteString(value, env, path);\n }\n if (Array.isArray(value)) {\n return value.map((entry, index) => substituteEnv(entry, env, `${path}[${index}]`));\n }\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = substituteEnv(entry, env, `${path}.${key}`);\n }\n return result;\n }\n return value;\n}\n\nfunction substituteString(value: string, env: NodeJS.ProcessEnv, path: string): string {\n const substituted = substituteOnce(value, env, path);\n\n // `${A:-${B}}` with A unset produced the literal string\n // `${B}` — an unresolved placeholder that survived into the config, directly\n // contradicting this module's promise that one fails loading immediately.\n // (`[^}]*` cannot span the inner `}`, so the default captured is `${B`, and\n // the trailing `}` is ordinary text.) Refusing is the fail-closed reading of\n // that promise; resolving recursively would mean deciding what `${A:-${B:-c}}`\n // and a self-reference should do, which no config here needs. A `${` with no\n // closing brace is left alone — it is not a placeholder.\n PLACEHOLDER_PATTERN.lastIndex = 0;\n if (PLACEHOLDER_PATTERN.test(substituted)) {\n PLACEHOLDER_PATTERN.lastIndex = 0;\n const residual = PLACEHOLDER_PATTERN.exec(substituted)?.[0] ?? '${…}';\n PLACEHOLDER_PATTERN.lastIndex = 0;\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" still contains the unresolved placeholder \"${residual}\" after substitution — nested placeholders (e.g. \"\\${A:-\\${B}}\") are not supported. Use a plain default, or set the variable.`,\n { details: { path, residual } },\n );\n }\n return substituted;\n}\n\nfunction substituteOnce(value: string, env: NodeJS.ProcessEnv, path: string): string {\n return value.replace(\n PLACEHOLDER_PATTERN,\n (_match, name: string, hasDefault: string | undefined, def: string | undefined) => {\n const envValue = env[name];\n\n if (hasDefault !== undefined) {\n if (envValue === undefined || envValue === '') return def ?? '';\n return envValue;\n }\n\n if (envValue === undefined) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Unresolved environment variable \"\\${${name}}\" referenced at config path \"${path}\"`,\n { details: { variable: name, path } },\n );\n }\n return envValue;\n },\n );\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * `config.yaml` schema, validation and normalisation into the\n * canonical `GatewayConfig` (docs/contracts.md).\n *\n * Two-phase validation:\n * 1. Zod validates *shape* (types, required fields, unknown-key rejection).\n * Numeric/boolean leaves accept either their native type or a string\n * (env substitution always produces a string), and are left as-is here —\n * Zod's typed transforms have surprising inference interactions with\n * `.strict()` objects, so numeric/boolean coercion is done explicitly,\n * in plain TypeScript, in the normalisation pass below.\n * 2. A manual business-rule pass validates cross-references that need a\n * specific, actionable message (duplicate ids, disabled protocols/payment\n * methods, dynamic pricing, destination-address plausibility) and\n * performs the numeric/boolean coercion.\n *\n * Env substitution (`${VAR}` / `${VAR:-default}`) runs over the raw parsed\n * value *before* either phase, so numeric/boolean fields can be templated too.\n * One exception, deliberate: `checkVersion` runs **before** substitution, so\n * `version:` cannot itself be templated. It is the compatibility gate that\n * decides whether this parser understands the document at all; resolving\n * environment variables to find out which schema version to expect would be\n * backwards. The order is intended; `version:` is the one exception to the\n * substitution rule, which this sentence exists to record.\n */\n\nimport { type ZodError, type ZodIssue, type ZodTypeAny, z } from 'zod';\nimport {\n extractPathParameterNames,\n findUnparsedBraceToken,\n isObjectSchemaNode,\n} from '../core/execution/index.js';\nimport {\n CommerceError,\n type CommerceResource,\n PAYMENT_INPUT_FIELD,\n type Pricing,\n} from '../core/index.js';\nimport { substituteEnv } from './env.js';\n\nconst SUPPORTED_CONFIG_VERSION = 1;\n\n/** `0x` + 40 hex chars. Checksum-insensitive: casing is not enforced. */\nconst ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;\nconst ZERO_ADDRESS_PATTERN = /^0x0{40}$/i;\n\n/**\n * A resource `id` doubles as its MCP tool name (protocol-mcp registers one\n * tool per resource, named by id). Value verified against the regex actually\n * shipped in the installed `@modelcontextprotocol/sdk@1.30.0`\n * (`shared/toolNameValidation.js`, SEP-986 \"Specify Format for Tool Names\") —\n * not duplicated as an SDK dependency, since config stays protocol-agnostic.\n */\nconst MCP_TOOL_NAME_PATTERN = /^[A-Za-z0-9._-]{1,128}$/;\n\n// ---------------------------------------------------------------------------\n// Zod schema for the *shape* of the raw (post-substitution) document.\n// ---------------------------------------------------------------------------\n\n/** Accepts a real number or a (post env-substitution) numeric string. */\nconst NumberOrString = z.union([z.number(), z.string()]);\n/** Accepts a real boolean or a (post env-substitution) \"true\"/\"false\" string. */\nconst BooleanOrString = z.union([z.boolean(), z.string()]);\n\nconst MerchantSchema = z\n .object({\n id: z.string().min(1),\n name: z.string().min(1),\n publicBaseUrl: z.string().min(1),\n })\n .strict();\n\nconst ServerSchema = z\n .object({\n port: NumberOrString,\n host: z.string().min(1),\n /** Shared secret gating /api/receipts, /api/events, /api/events/stream. No token -> those routes 404. */\n adminToken: z.string().min(1).optional(),\n /** Browser origins allowed to read the dashboard-facing routes. Empty by default: closed. */\n // Entries are matched literally against the browser's\n // `Origin` header, so `\"*\"` and a trailing slash match nothing at all —\n // fail-closed (a lockout, not a bypass), but silently, and a lockout with\n // no explanation is the kind of thing an operator \"fixes\" by disabling the\n // check. Reject those two shapes with a pointer instead.\n allowedOrigins: z\n .array(\n z\n .string()\n .min(1)\n .refine((origin) => origin !== '*', {\n message:\n 'wildcard \"*\" is not supported — allowedOrigins entries are matched literally against the browser\\'s Origin header, so \"*\" would match nothing. List each scheme://host[:port] explicitly.',\n })\n .refine((origin) => !origin.endsWith('/'), {\n message:\n 'must not end with \"/\" — a browser Origin header never has a trailing slash, so this entry would match nothing. Use e.g. \"http://localhost:5173\".',\n }),\n )\n .optional(),\n })\n .strict();\n\nconst StorageSchema = z\n .object({\n receipts: z\n .object({\n driver: z.literal('sqlite'),\n path: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nconst ProtocolsSchema = z\n .object({\n http: z.object({ enabled: BooleanOrString }).strict(),\n mcp: z\n .object({\n enabled: BooleanOrString,\n mountPath: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\nconst BackendMethodSchema = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);\n\nconst BackendHandlerSchema = z\n .object({\n type: z.literal('http'),\n method: BackendMethodSchema,\n url: z.string().min(1),\n headers: z.record(z.string(), z.string()).optional(),\n timeoutMs: NumberOrString.optional(),\n })\n .strict();\n\nconst PricingSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('free') }).strict(),\n z\n .object({\n type: z.literal('fixed'),\n amount: z.string().min(1),\n currency: z.string().min(1),\n })\n .strict(),\n z\n .object({\n type: z.literal('dynamic'),\n resolver: z.string().min(1),\n })\n .strict(),\n]);\n\nconst JsonSchemaValueSchema: ZodTypeAny = z.record(z.string(), z.unknown());\n\nconst ResourceEntrySchema = z\n .object({\n name: z.string().min(1),\n description: z.string().optional(),\n input: JsonSchemaValueSchema.optional(),\n output: JsonSchemaValueSchema.optional(),\n backend: BackendHandlerSchema,\n pricing: PricingSchema,\n expose: z.array(z.string().min(1)).min(1),\n payments: z.array(z.string().min(1)).optional(),\n })\n .strict();\n\nconst ResourcesMapSchema = z.record(z.string().min(1), ResourceEntrySchema);\n\nconst FacilitatorSchema = z.discriminatedUnion('mode', [\n z\n .object({\n mode: z.literal('local'),\n signerPrivateKey: z.string().min(1),\n })\n .strict(),\n z\n .object({\n mode: z.literal('remote'),\n url: z.string().min(1),\n })\n .strict(),\n]);\n\nconst X402Schema = z\n .object({\n enabled: BooleanOrString,\n network: z.string().min(1),\n rpcUrl: z.string().min(1),\n asset: z.string().min(1),\n assetName: z.string().min(1),\n assetVersion: z.string().min(1),\n assetDecimals: NumberOrString,\n payTo: z.string().min(1),\n maxTimeoutSeconds: NumberOrString,\n facilitator: FacilitatorSchema,\n })\n .strict();\n\nconst PaymentsSchema = z\n .object({\n x402: X402Schema.optional(),\n })\n .strict();\n\nconst RawConfigSchema = z\n .object({\n version: z.literal(SUPPORTED_CONFIG_VERSION),\n merchant: MerchantSchema,\n server: ServerSchema,\n storage: StorageSchema,\n protocols: ProtocolsSchema,\n resources: ResourcesMapSchema,\n payments: PaymentsSchema,\n })\n .strict();\n\ntype RawConfig = z.infer<typeof RawConfigSchema>;\ntype RawResourceEntry = z.infer<typeof ResourceEntrySchema>;\n\n// ---------------------------------------------------------------------------\n// Public shape (docs/contracts.md — exact).\n// ---------------------------------------------------------------------------\n\nexport interface GatewayConfig {\n readonly version: 1;\n readonly merchant: { readonly id: string; readonly name: string; readonly publicBaseUrl: string };\n readonly server: {\n readonly port: number;\n readonly host: string;\n readonly adminToken?: string;\n readonly allowedOrigins: readonly string[];\n };\n readonly storage: { readonly receipts: { readonly driver: 'sqlite'; readonly path: string } };\n readonly protocols: {\n readonly http: { readonly enabled: boolean };\n readonly mcp: { readonly enabled: boolean; readonly mountPath: string };\n };\n /** Canonical resources, already normalised. */\n readonly resources: readonly CommerceResource[];\n readonly payments: {\n readonly x402?: {\n readonly enabled: boolean;\n readonly network: string;\n readonly rpcUrl: string;\n readonly asset: string;\n readonly assetName: string;\n readonly assetVersion: string;\n readonly assetDecimals: number;\n readonly payTo: string;\n readonly maxTimeoutSeconds: number;\n readonly facilitator:\n | { readonly mode: 'local'; readonly signerPrivateKey: string }\n | { readonly mode: 'remote'; readonly url: string };\n };\n };\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nexport function parseConfig(raw: unknown, env: NodeJS.ProcessEnv): GatewayConfig {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'Configuration root must be a mapping (object) at \"$\"',\n {\n details: { path: '$' },\n },\n );\n }\n\n checkVersion(raw as Record<string, unknown>);\n\n const substituted = substituteEnv(raw, env);\n const parsed = parseWithZod(RawConfigSchema, substituted);\n return normalise(parsed);\n}\n\nfunction checkVersion(raw: Record<string, unknown>): void {\n if (!('version' in raw)) {\n throw new CommerceError('CONFIG_INVALID', 'Configuration is missing required field \"version\"', {\n details: { path: 'version' },\n });\n }\n const rawVersion = raw['version'];\n const version = typeof rawVersion === 'string' ? Number(rawVersion) : rawVersion;\n if (version !== SUPPORTED_CONFIG_VERSION) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Unsupported config version \"${String(rawVersion)}\": this gateway only supports version ${SUPPORTED_CONFIG_VERSION}`,\n { details: { path: 'version', supported: SUPPORTED_CONFIG_VERSION } },\n );\n }\n}\n\nfunction parseWithZod<T>(schema: z.ZodType<T>, value: unknown): T {\n const result = schema.safeParse(value);\n if (!result.success) {\n throw zodErrorToConfigError(result.error);\n }\n return result.data;\n}\n\nfunction zodErrorToConfigError(error: ZodError): CommerceError {\n const issues = error.issues.map(describeIssue);\n const first = issues[0];\n const message = first\n ? `Configuration invalid at \"${first.path}\": ${first.message}`\n : 'Configuration invalid';\n return new CommerceError('CONFIG_INVALID', message, { details: { issues } });\n}\n\nfunction describeIssue(issue: ZodIssue): { path: string; message: string; code: string } {\n const path = issue.path.length > 0 ? issue.path.join('.') : '$';\n return { path, message: issue.message, code: issue.code };\n}\n\n// ---------------------------------------------------------------------------\n// Numeric / boolean coercion (explicit, not via Zod — see file header).\n// ---------------------------------------------------------------------------\n\nfunction toNumber(\n value: number | string,\n path: string,\n bounds: { min?: number; max?: number } = {},\n): number {\n // `Number('')` is 0 — finite, integral, and inside\n // `server.port`'s deliberate `min: 0` (\"let the OS pick\"). So `port: ${PORT:-}`\n // or an exported-but-empty PORT validated PASS and the gateway bound a random\n // port, after which `doctor` derived `http://127.0.0.1:0`, failed to connect,\n // and reported the gateway unreachable while it was serving. `Number` also\n // accepts `\"0x50\"` (80) and `\"1e3\"` (1000) for fields that are decimal\n // integers everywhere they are documented. Require plain digits instead.\n if (typeof value === 'string' && !/^\\s*\\d+\\s*$/.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be an integer written in decimal digits (got ${value === '' ? 'an empty string' : `\"${value}\"`})`,\n { details: { path } },\n );\n }\n const n = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(n) || !Number.isInteger(n)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be an integer`,\n {\n details: { path },\n },\n );\n }\n if (bounds.min !== undefined && n < bounds.min) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be >= ${bounds.min}`,\n {\n details: { path },\n },\n );\n }\n if (bounds.max !== undefined && n > bounds.max) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be <= ${bounds.max}`,\n {\n details: { path },\n },\n );\n }\n return n;\n}\n\nfunction toBoolean(value: boolean | string, path: string): boolean {\n if (typeof value === 'boolean') return value;\n const normalized = value.trim().toLowerCase();\n if (normalized === 'true') return true;\n if (normalized === 'false') return false;\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be a boolean (\"true\" or \"false\")`,\n { details: { path } },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Business-rule validation + normalisation into the canonical shape.\n// ---------------------------------------------------------------------------\n\nconst SUPPORTED_PROTOCOLS = new Set(['http', 'mcp']);\nconst SUPPORTED_PAYMENT_METHODS = new Set(['x402']);\n\nfunction normalise(raw: RawConfig): GatewayConfig {\n const protocols = {\n http: { enabled: toBoolean(raw.protocols.http.enabled, 'protocols.http.enabled') },\n mcp: {\n enabled: toBoolean(raw.protocols.mcp.enabled, 'protocols.mcp.enabled'),\n mountPath: raw.protocols.mcp.mountPath,\n },\n };\n\n const x402Raw = raw.payments.x402;\n // facilitator.mode \"remote\" is documented as unimplemented (three\n // places), but was accepted at config load — the provider constructed and\n // health() returned only \"warn\" (not consulted by /ready), so the failure\n // landed inside settle(), after the buyer's payment authorisation was\n // already burned. Every buyer who hit it lost that authorisation\n // permanently and had to sign a fresh one that failed identically. Reject\n // it here, next to the dynamic-pricing and UCP rejections, so\n // `agent-commerce validate` catches it where an operator expects it.\n if (x402Raw?.facilitator.mode === 'remote') {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'payments.x402.facilitator.mode \"remote\" is not supported in v0.1.0-alpha; use \"local\" (the deterministic dev-chain facilitator)',\n { details: { path: 'payments.x402.facilitator.mode' } },\n );\n }\n const x402 = x402Raw\n ? {\n enabled: toBoolean(x402Raw.enabled, 'payments.x402.enabled'),\n network: x402Raw.network,\n rpcUrl: x402Raw.rpcUrl,\n asset: x402Raw.asset,\n assetName: x402Raw.assetName,\n assetVersion: x402Raw.assetVersion,\n assetDecimals: toNumber(x402Raw.assetDecimals, 'payments.x402.assetDecimals', {\n min: 0,\n max: 36,\n }),\n payTo: x402Raw.payTo,\n maxTimeoutSeconds: toNumber(x402Raw.maxTimeoutSeconds, 'payments.x402.maxTimeoutSeconds', {\n min: 1,\n }),\n // Only \"local\" can reach here — \"remote\" was rejected above.\n facilitator: {\n mode: 'local' as const,\n signerPrivateKey: x402Raw.facilitator.signerPrivateKey,\n },\n }\n : undefined;\n\n if (x402) {\n validateAddress('payments.x402.payTo', x402.payTo);\n validateAddress('payments.x402.asset', x402.asset);\n }\n\n const resources = Object.entries(raw.resources).map(([id, entry]) =>\n normaliseResource(id, entry, protocols, x402),\n );\n\n return {\n version: SUPPORTED_CONFIG_VERSION,\n merchant: {\n id: raw.merchant.id,\n name: raw.merchant.name,\n publicBaseUrl: raw.merchant.publicBaseUrl,\n },\n // min 0, not 1: port 0 is the standard \"let the OS pick a free port\"\n // convention, useful for tests and ephemeral dev/demo instances.\n server: {\n port: toNumber(raw.server.port, 'server.port', { min: 0, max: 65535 }),\n host: raw.server.host,\n ...(raw.server.adminToken !== undefined ? { adminToken: raw.server.adminToken } : {}),\n allowedOrigins: raw.server.allowedOrigins ?? [],\n },\n storage: { receipts: { driver: 'sqlite', path: raw.storage.receipts.path } },\n protocols,\n resources,\n payments: {\n ...(x402 !== undefined ? { x402 } : {}),\n },\n };\n}\n\ninterface NormalisedProtocols {\n readonly http: { readonly enabled: boolean };\n readonly mcp: { readonly enabled: boolean; readonly mountPath: string };\n}\n\ninterface NormalisedX402 {\n readonly enabled: boolean;\n readonly assetDecimals: number;\n}\n\nfunction normaliseResource(\n id: string,\n entry: RawResourceEntry,\n protocols: NormalisedProtocols,\n x402: NormalisedX402 | undefined,\n): CommerceResource {\n if (entry.input !== undefined) validateResourceSchemaKeywords(id, 'input', entry.input);\n\n const inputProperties = entry.input?.['properties'];\n if (\n inputProperties &&\n typeof inputProperties === 'object' &&\n PAYMENT_INPUT_FIELD in inputProperties\n ) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" declares an input property \"${PAYMENT_INPUT_FIELD}\", which is reserved for payment proofs`,\n {\n details: {\n path: `resources.${id}.input.properties.${PAYMENT_INPUT_FIELD}`,\n resourceId: id,\n },\n },\n );\n }\n\n for (const protocol of entry.expose) {\n if (!SUPPORTED_PROTOCOLS.has(protocol)) {\n const hint = protocol === 'ucp' ? ' (UCP is planned, not supported in v0.1.0-alpha)' : '';\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" exposes unsupported protocol \"${protocol}\"${hint}. Supported: http, mcp.`,\n { details: { path: `resources.${id}.expose`, resourceId: id, protocol } },\n );\n }\n }\n if (entry.expose.includes('mcp')) {\n if (!protocols.mcp.enabled) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" is exposed via \"mcp\" but protocols.mcp.enabled is false`,\n { details: { path: `resources.${id}.expose`, resourceId: id } },\n );\n }\n if (!MCP_TOOL_NAME_PATTERN.test(id)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" is exposed via \"mcp\" but its id is not a legal MCP tool name (allowed: A-Z, a-z, 0-9, \"_\", \"-\", \".\", 1-128 chars)`,\n { details: { path: `resources.${id}`, resourceId: id } },\n );\n }\n }\n if (entry.expose.includes('http') && !protocols.http.enabled) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" is exposed via \"http\" but protocols.http.enabled is false`,\n { details: { path: `resources.${id}.expose`, resourceId: id } },\n );\n }\n\n validateBackendUrl(id, entry.backend.url);\n validatePathParametersDeclared(id, entry.backend.url, entry.input);\n\n if (entry.pricing.type === 'dynamic') {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" uses pricing.type \"dynamic\", which is not supported in v0.1.0-alpha`,\n { details: { path: `resources.${id}.pricing.type`, resourceId: id } },\n );\n }\n\n if (entry.pricing.type === 'fixed') {\n validatePricingAmount(id, entry.pricing.amount, x402);\n }\n\n const paymentMethods = entry.payments ?? [];\n\n if (entry.pricing.type === 'fixed') {\n if (paymentMethods.length === 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has fixed pricing but declares no \"payments\" (a paid resource must name at least one payment method)`,\n { details: { path: `resources.${id}.payments`, resourceId: id } },\n );\n }\n for (const method of paymentMethods) {\n if (!SUPPORTED_PAYMENT_METHODS.has(method)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" names unsupported payment method \"${method}\". Supported: x402.`,\n { details: { path: `resources.${id}.payments`, resourceId: id, method } },\n );\n }\n if (method === 'x402' && (!x402 || !x402.enabled)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" names payment method \"x402\" which is not configured or not enabled under payments.x402`,\n { details: { path: `resources.${id}.payments`, resourceId: id, method } },\n );\n }\n }\n }\n\n const pricing: Pricing =\n entry.pricing.type === 'free'\n ? { type: 'free' }\n : { type: 'fixed', amount: entry.pricing.amount, currency: entry.pricing.currency };\n\n return {\n id,\n name: entry.name,\n ...(entry.description !== undefined ? { description: entry.description } : {}),\n inputSchema:\n entry.input !== undefined\n ? defaultClosedObjectSchema(entry.input)\n : EMPTY_CLOSED_OBJECT_SCHEMA,\n ...(entry.output !== undefined ? { outputSchema: entry.output } : {}),\n handler: {\n type: 'http',\n method: entry.backend.method,\n url: entry.backend.url,\n ...(entry.backend.headers !== undefined ? { headers: entry.backend.headers } : {}),\n ...(entry.backend.timeoutMs !== undefined\n ? {\n timeoutMs: toNumber(entry.backend.timeoutMs, `resources.${id}.backend.timeoutMs`, {\n min: 1,\n }),\n }\n : {}),\n },\n pricing,\n exposedVia: entry.expose as CommerceResource['exposedVia'],\n paymentMethods: paymentMethods as CommerceResource['paymentMethods'],\n };\n}\n\n/**\n * `{param}` templates (e.g. `.../weather/{city}`) parse fine as a URL — the\n * WHATWG parser just percent-encodes the braces — so this only rejects\n * genuinely malformed strings and non-http(s) schemes, not templating.\n */\n/**\n * Permissive-by-default is the wrong default for a value forwarded to\n * someone else's API: an object schema that\n * omits `additionalProperties` defaults, per JSON Schema itself, to\n * \"anything goes\" — so default it to `false` here instead, unless the\n * operator set it explicitly (including explicitly to `true`, which is\n * respected).\n *\n * An earlier fix only stamped the ROOT schema, so\n * `filter: { type: object }` *looked* closed (the top level really was)\n * while every key one level down under `properties.filter` still passed\n * verbatim — `core`'s validator (execution/validation.ts) only enforces\n * `additionalProperties` where the schema states it explicitly, at every\n * level independently. Recurse into `properties` and `items` the same way\n * `validateResourceSchemaKeywords` below already does, so \"closed\" actually\n * means closed at every depth, not just the one an operator happened to\n * write `additionalProperties: false` on.\n *\n * `type` can be an array (`[\"object\",\"null\"]`, valid JSON\n * Schema) — a bare `=== 'object'` string comparison missed it, so a schema\n * in that shape got stamped as open. `declaresObjectType` below is the same\n * check `core`'s validator now makes (`execution/validation.ts`'s\n * `isObjectSchemaNode`) so the two stay in agreement.\n */\nfunction defaultClosedObjectSchema(schema: Record<string, unknown>): Record<string, unknown> {\n // imported, never re-implemented. The local predicate this\n // replaces recognised `type`/`properties` but not `required`, while core's\n // validator recognised `properties`/`required` — so `input: { required: [q] }`\n // was an object to the validator and not to the stamper, and every unknown\n // key sailed through to the merchant backend. One definition, one drift.\n const isObjectSchema = isObjectSchemaNode(schema);\n const result: Record<string, unknown> = { ...schema };\n\n if (isObjectSchema) {\n const properties = schema['properties'];\n if (isPlainObject(properties)) {\n result['properties'] = Object.fromEntries(\n Object.entries(properties).map(([key, sub]) => [\n key,\n isPlainObject(sub) ? defaultClosedObjectSchema(sub) : sub,\n ]),\n );\n }\n if (!Object.hasOwn(schema, 'additionalProperties')) {\n result['additionalProperties'] = false;\n }\n }\n\n const items = schema['items'];\n if (isPlainObject(items)) {\n result['items'] = defaultClosedObjectSchema(items);\n }\n\n return result;\n}\n\n/**\n * A resource that declares no `input:` at all got\n * `inputSchema: undefined`, and `compileJsonSchema(undefined)` is an\n * always-valid validator — every caller key was forwarded to the merchant\n * backend verbatim. The decision: default \"declared nothing\" to \"accepts\n * nothing\" (an empty closed object) rather than rejecting the config at load\n * time — a no-argument resource that omits `input:` is a legitimate shape,\n * and rejecting it would break every existing config that uses it.\n */\nconst EMPTY_CLOSED_OBJECT_SCHEMA: Record<string, unknown> = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n};\n\n/**\n * `src/core`'s validator only enforces the subset documented in\n * `execution/validation.ts` (type/properties/required/additionalProperties/\n * enum/items) — everything else (`pattern`, `minLength`, `format`, `oneOf`,\n * …) is silently ignored at runtime. An operator who writes `pattern` and\n * never sees it enforced has no way to know that from the config alone, so\n * warn at load time instead of letting them find out the hard way.\n */\nconst UNSUPPORTED_SCHEMA_KEYWORDS = [\n 'pattern',\n 'minLength',\n 'maxLength',\n 'format',\n 'minimum',\n 'maximum',\n 'exclusiveMinimum',\n 'exclusiveMaximum',\n 'multipleOf',\n 'oneOf',\n 'anyOf',\n 'allOf',\n 'not',\n '$ref',\n 'const',\n 'patternProperties',\n 'minItems',\n 'maxItems',\n 'uniqueItems',\n];\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** `type` explicitly set to something that rules out \"object\" (a bare\n * value, or an array not containing \"object\"). `undefined` — no `type` at\n * all — is deliberately NOT treated as excluding: core's validator treats\n * `properties`/`required` with no `type` as an object schema, so that shape\n * is fine, not another instance of this bug. */\nfunction excludesObjectType(schema: Record<string, unknown>): boolean {\n const type = schema['type'];\n if (type === undefined || type === 'object') return false;\n if (Array.isArray(type)) return !type.includes('object');\n return true;\n}\n\n/**\n * Walks a resource's input schema once, both warning (existing, unenforced\n * keywords) and rejecting (a node whose declared `type`\n * cannot structurally be an object, yet which still carries `properties` or\n * `required`). The `properties`/`required`-with-no-`type` shape is not\n * this function's problem any more, since the\n * validator now treats that shape as an object; what's still a trap is a\n * `type` that actively rules \"object\" out while `properties`/`required`\n * imply it was meant to be one, e.g. a copy-pasted sibling schema whose\n * `type` was never updated. Rejecting (not just warning) here is the\n * decision — a warning is exactly what let this bug class ship silently in\n * the first place (`validate`/`doctor` both said PASS).\n */\nfunction validateResourceSchemaKeywords(\n id: string,\n path: string,\n schema: Record<string, unknown>,\n): void {\n for (const keyword of UNSUPPORTED_SCHEMA_KEYWORDS) {\n if (Object.hasOwn(schema, keyword)) {\n // eslint-disable-next-line no-console\n console.warn(\n `[agent-commerce] resource \"${id}\" ${path} uses JSON Schema keyword \"${keyword}\", which this gateway does not enforce (see src/core/execution/validation.ts for the supported subset). Remove it or treat it as documentation only.`,\n );\n }\n }\n if (\n (Object.hasOwn(schema, 'properties') || Object.hasOwn(schema, 'required')) &&\n excludesObjectType(schema)\n ) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" ${path} declares \"properties\" and/or \"required\" but its \"type\" (${JSON.stringify(schema['type'])}) does not include \"object\" — the validator will never route a value through either check under that type, so this schema claims to constrain input it does not actually enforce. Remove \"properties\"/\"required\", or include \"object\" in \"type\".`,\n { details: { path: `resources.${id}.${path}`, resourceId: id } },\n );\n }\n // the other half. Closing a `required`-only node is\n // correct JSON Schema and quietly unsatisfiable: `required: [\"q\"]` demands a\n // property that `properties` never declares, so the stamped\n // `additionalProperties: false` rejects `q` as an unknown key — the schema\n // can never be satisfied by any input at all. Fail-closed, so no money is at\n // risk, but every call would 400 with a config that loaded cleanly. Say so\n // at load instead. Only when the node really will be closed: an explicit\n // `additionalProperties` other than `false` leaves the name reachable.\n const requiredRaw = schema['required'];\n const closed = !Object.hasOwn(schema, 'additionalProperties')\n ? true\n : schema['additionalProperties'] === false;\n if (Array.isArray(requiredRaw) && closed && isObjectSchemaNode(schema)) {\n const declared = isPlainObject(schema['properties']) ? schema['properties'] : {};\n const undeclared = requiredRaw.filter(\n (name): name is string => typeof name === 'string' && !Object.hasOwn(declared, name),\n );\n if (undeclared.length > 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" ${path} lists ${undeclared.map((n) => `\"${n}\"`).join(', ')} in \"required\" but does not declare ${undeclared.length === 1 ? 'it' : 'them'} in \"properties\". The schema is closed (additionalProperties: false), so ${undeclared.length === 1 ? 'that name is' : 'those names are'} rejected as an unknown key and no input can ever satisfy this schema. Declare ${undeclared.length === 1 ? 'it' : 'them'} in \"properties\".`,\n { details: { path: `resources.${id}.${path}`, resourceId: id, undeclared } },\n );\n }\n }\n\n const properties = schema['properties'];\n if (isPlainObject(properties)) {\n for (const [key, sub] of Object.entries(properties)) {\n if (isPlainObject(sub)) validateResourceSchemaKeywords(id, `${path}.properties.${key}`, sub);\n }\n }\n const items = schema['items'];\n if (isPlainObject(items)) {\n validateResourceSchemaKeywords(id, `${path}.items`, items);\n } else if (Array.isArray(items)) {\n // tuple-form `items` (an array of per-position\n // schemas) is valid JSON Schema, but `core`'s validator only supports\n // the single-schema form applied to every element — a tuple silently\n // enforces nothing, invisibly rather than wrongly, so warn the same way\n // an unsupported keyword does.\n // eslint-disable-next-line no-console\n console.warn(\n `[agent-commerce] resource \"${id}\" ${path}.items is a tuple (an array of schemas), which this gateway does not enforce — only a single schema applied to every array element is supported (see src/core/execution/validation.ts). Each position's schema is unenforced; treat it as documentation only.`,\n );\n }\n}\n\n/**\n * `amount: z.string().min(1)` alone let \"0,01\", \"$0.01\", \"1e-2\", \"-1\" and an\n * over-precise \"0.0000001\" all pass config + `doctor`, then throw on every\n * purchase. A plain\n * positive decimal only — no currency symbol, no thousands separator, no\n * exponent notation.\n */\nconst PRICING_AMOUNT_PATTERN = /^\\d+(?:\\.\\d+)?$/;\nconst ZERO_AMOUNT_PATTERN = /^0(?:\\.0+)?$/;\n\nfunction validatePricingAmount(id: string, amount: string, x402: NormalisedX402 | undefined): void {\n const path = `resources.${id}.pricing.amount`;\n if (!PRICING_AMOUNT_PATTERN.test(amount)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has pricing.amount \"${amount}\", which is not a plain positive decimal (no currency symbol, no thousands separator, no exponent — e.g. \"0.01\")`,\n { details: { path, resourceId: id } },\n );\n }\n if (ZERO_AMOUNT_PATTERN.test(amount)) {\n // A zero-priced \"paid\" resource settles a zero-value transfer, which is\n // nonsense — if something is free, it should say so.\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has pricing.amount \"0\" — a paid resource cannot cost zero; use \"pricing: { type: free }\" instead`,\n { details: { path, resourceId: id } },\n );\n }\n if (x402 !== undefined) {\n const fractionalDigits = amount.includes('.') ? (amount.split('.')[1]?.length ?? 0) : 0;\n if (fractionalDigits > x402.assetDecimals) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has pricing.amount \"${amount}\" with more precision (${fractionalDigits} fractional digits) than the configured asset supports (${x402.assetDecimals} decimals)`,\n { details: { path, resourceId: id } },\n );\n }\n }\n}\n\n/**\n * The root-cause half. `validateBackendRequestShape`\n * (src/core) rejects a missing path parameter at request time — after\n * schema validation but, without this check, on every single call, because\n * a schema that never declares `{city}` can never satisfy it. A paid\n * resource in that shape settles the buyer's payment and then always fails\n * to reach the backend: no refund, replay key burned, on every call, not an\n * unlucky one. Every `{param}` in `backend.url` must be BOTH declared in\n * `properties` AND listed in `required` — an optional value hits the exact\n * same \"caller structurally cannot supply it on every call that omits it\"\n * problem as an undeclared one, just less often. This is the config-load\n * gate `agent-commerce validate`/`doctor` catch it at; the runtime\n * `INPUT_INVALID` in `validateBackendRequestShape` is defence in depth for\n * a hand-built `CommerceResource` this check never saw.\n */\nfunction validatePathParametersDeclared(\n id: string,\n url: string,\n input: Record<string, unknown> | undefined,\n): void {\n // Before anything else: a brace token the canonical grammar does not\n // recognise is neither extracted here nor substituted at request time, so it\n // would travel to the backend as a percent-encoded literal. On a paid\n // resource that is payment-without-delivery on every single call. Refuse it\n // at load rather than letting \"matches nothing\" mean \"nothing to check\".\n const stray = findUnparsedBraceToken(url);\n if (stray !== undefined) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has backend.url containing \"${stray}\", which is not a valid path parameter (allowed characters: A-Z a-z 0-9 _ . -). It would be sent to the backend literally, so a paid resource would settle payment and then never reach the backend`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id, token: stray } },\n );\n }\n\n const params = extractPathParameterNames(url);\n if (params.length === 0) return;\n\n const propertiesRaw = input?.['properties'];\n const properties = isPlainObject(propertiesRaw) ? propertiesRaw : {};\n const requiredRaw = input?.['required'];\n const required = new Set(\n Array.isArray(requiredRaw)\n ? requiredRaw.filter((entry): entry is string => typeof entry === 'string')\n : [],\n );\n\n for (const param of params) {\n const path = `resources.${id}.backend.url`;\n if (!Object.hasOwn(properties, param)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has backend.url path parameter \"{${param}}\" which is not declared in its input schema — the caller has no way to supply it, so every call would settle payment (if priced) and then fail to reach the backend`,\n { details: { path, resourceId: id, param } },\n );\n }\n if (!required.has(param)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has backend.url path parameter \"{${param}}\" declared in its input schema but not listed in \"required\" — a caller that omits it hits the same unservable-request problem as an undeclared parameter`,\n { details: { path, resourceId: id, param } },\n );\n }\n }\n}\n\nfunction validateBackendUrl(id: string, url: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has an invalid backend.url \"${url}\": must be an absolute http:// or https:// URL`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id } },\n );\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has a backend.url with scheme \"${parsed.protocol}\": must be http:// or https://`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id } },\n );\n }\n}\n\nfunction validateAddress(path: string, value: string): void {\n if (!ADDRESS_PATTERN.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" is not a plausible address (expected \"0x\" followed by 40 hex characters)`,\n { details: { path } },\n );\n }\n if (ZERO_ADDRESS_PATTERN.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must not be the zero address`,\n {\n details: { path },\n },\n );\n }\n}\n","/**\n * Locates and parses `config.yaml`, then hands the raw value to\n * `parseConfig`. Never trusts raw YAML before Zod validation.\n */\nimport { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { parse as parseYaml, YAMLError } from 'yaml';\nimport { CommerceError } from '../core/index.js';\nimport { DEFAULT_CONFIG_FILENAME } from './filename.js';\nimport { type GatewayConfig, parseConfig } from './schema.js';\n\nconst CONFIG_PATH_ENV_VAR = 'AGENT_COMMERCE_CONFIG';\n\nexport interface LoadConfigOptions {\n readonly path?: string;\n readonly env?: NodeJS.ProcessEnv;\n readonly cwd?: string;\n}\n\nexport async function loadConfig(options: LoadConfigOptions = {}): Promise<GatewayConfig> {\n const env = options.env ?? process.env;\n const cwd = options.cwd ?? process.cwd();\n const configPath = resolveConfigPath(options.path, env, cwd);\n\n let text: string;\n try {\n text = await fs.readFile(configPath, 'utf8');\n } catch (error) {\n throw new CommerceError('CONFIG_INVALID', `Could not read configuration file \"${configPath}\"`, {\n details: { path: configPath },\n cause: error,\n });\n }\n\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (error) {\n const { reason, details } = describeYamlError(error);\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration file \"${configPath}\" is not valid YAML: ${reason}`,\n {\n details: { path: configPath, ...details },\n // Retained for programmatic callers. Nothing in the CLI prints a\n // `cause`, and nothing should start: this is the object whose\n // `.message` carries the source excerpt (see below).\n cause: error,\n },\n );\n }\n\n return parseConfig(raw, env);\n}\n\n/**\n * A YAML failure described from the error's *structured* fields only.\n *\n * Deliberately not `error.message`: the `yaml` package builds that message\n * with a **code frame excerpt of the source line**, so a syntax error next to\n * an inline secret would reproduce it verbatim into `validate`/`doctor` output — including `doctor --json`, the output most\n * likely to be pasted into an issue or captured by CI:\n *\n * … is not valid YAML: Nested mappings are not allowed … at line 2, column 15:\n *\n * adminToken: super-secret-token-value\n * ^\n *\n * `server.adminToken` and `payments.x402.facilitator.signerPrivateKey` are\n * both legal as inline literals, so this was a real sink rather than a\n * hypothetical one — and it contradicted `validate`'s own promise never to\n * print a resolved value: it never printed a resolved `${ENV}`, only an\n * inlined one. `code` and `linePos` locate the fault exactly as well and\n * cannot contain file content.\n */\n/**\n * Plain-English phrasing for the codes an operator actually hits, so replacing\n * the excerpt does not also cost the diagnostic its readability. These are\n * fixed strings chosen here — they can never contain file content, which is\n * the entire property that matters. Anything unlisted degrades to the bare\n * code, which is still precise.\n */\nconst YAML_ERROR_EXPLANATIONS: Readonly<Record<string, string>> = {\n DUPLICATE_KEY: 'map keys must be unique',\n BAD_INDENT: 'bad indentation',\n TAB_AS_INDENT: 'tabs cannot be used for indentation',\n MISSING_CHAR: 'a required character is missing',\n BLOCK_AS_IMPLICIT_KEY: 'a block value cannot be used as a key (missing quotes, or a stray colon)',\n MULTILINE_IMPLICIT_KEY: 'a key spans multiple lines (missing quotes, or a stray colon)',\n UNEXPECTED_TOKEN: 'unexpected token',\n};\n\nfunction describeYamlError(error: unknown): {\n reason: string;\n details: Record<string, unknown>;\n} {\n if (!(error instanceof YAMLError)) {\n return { reason: 'unknown YAML parse error', details: {} };\n }\n const start = error.linePos?.[0];\n const where =\n start === undefined ? '' : ` at line ${String(start.line)}, column ${String(start.col)}`;\n const explanation = YAML_ERROR_EXPLANATIONS[error.code];\n const what = explanation === undefined ? error.code : `${error.code} (${explanation})`;\n return {\n reason: `${what}${where}`,\n details: {\n yamlErrorCode: error.code,\n ...(start === undefined ? {} : { line: start.line, column: start.col }),\n },\n };\n}\n\nfunction resolveConfigPath(\n explicitPath: string | undefined,\n env: NodeJS.ProcessEnv,\n cwd: string,\n): string {\n if (explicitPath) return path.resolve(cwd, explicitPath);\n const fromEnv = env[CONFIG_PATH_ENV_VAR];\n if (fromEnv) return path.resolve(cwd, fromEnv);\n return path.resolve(cwd, DEFAULT_CONFIG_FILENAME);\n}\n","/**\n * src/config\n *\n * `config.yaml` schema, loader and environment substitution.\n */\n\nexport { substituteEnv } from './env.js';\nexport type { LoadConfigOptions } from './load.js';\nexport { loadConfig } from './load.js';\nexport type { GatewayConfig } from './schema.js';\nexport { parseConfig } from './schema.js';\n","import { Command } from 'commander';\nimport { DEFAULT_CONFIG_FILENAME } from '../config/filename.js';\nimport { runDemo } from './commands/demo.js';\nimport { printDoctorReport, runDoctor } from './commands/doctor.js';\nimport { runInit } from './commands/init.js';\nimport { runValidate } from './commands/validate.js';\nimport { runVersion } from './commands/version.js';\nimport { type Io, processIo } from './lib/io.js';\nimport { readVersionReport } from './lib/versions.js';\n\n/**\n * Builds the `agent-commerce` Commander program.\n *\n * `io` is injectable so tests can capture output instead of writing to the\n * real process streams; `exitOverride()` + `configureOutput()` mean\n * `--help`/errors never call `process.exit()` directly, so a caller (index.ts\n * or a test) fully controls process lifecycle.\n */\nexport function buildProgram(io: Io = processIo): Command {\n const program = new Command();\n\n program\n .name('agent-commerce')\n .description('CLI for the Agent Commerce Gateway: init, validate, doctor, demo.')\n // `--version` is required of the published binary. The `version`\n // subcommand stays: it additionally prints the pinned protocol/SDK\n // versions, which is what `doctor` and the support matrix are checked\n // against. Both read the same source, so they cannot disagree.\n .version(readVersionReport().cliVersion, '-v, --version', 'Print the CLI version.')\n .exitOverride()\n .configureOutput({\n writeOut: (str) => io.stdout(str.replace(/\\n+$/, '')),\n writeErr: (str) => io.stderr(str.replace(/\\n+$/, '')),\n });\n\n program\n .command('version')\n .description('Print the CLI version and pinned protocol/SDK versions.')\n .action(() => {\n process.exitCode = runVersion(io);\n });\n\n program\n .command('validate')\n .description(`Validate ${DEFAULT_CONFIG_FILENAME} and exit non-zero if it is invalid.`)\n .option('--config <path>', `path to ${DEFAULT_CONFIG_FILENAME}`)\n .action(async (opts: { config?: string }) => {\n const code = await runValidate(\n opts.config !== undefined ? { configPath: opts.config } : {},\n io,\n );\n process.exitCode = code;\n });\n\n program\n .command('doctor')\n .description('Diagnose config, gateway, backend, protocol and payment health.')\n .option('--config <path>', `path to ${DEFAULT_CONFIG_FILENAME}`)\n .option(\n '--gateway <url>',\n 'gateway base URL (default: derived from config, else http://localhost:8080)',\n )\n .option('--json', 'emit machine-readable JSON instead of a formatted report', false)\n .action(async (opts: { config?: string; gateway?: string; json?: boolean }) => {\n const report = await runDoctor({\n ...(opts.config !== undefined ? { configPath: opts.config } : {}),\n ...(opts.gateway !== undefined ? { gatewayUrl: opts.gateway } : {}),\n });\n printDoctorReport(report, io, opts.json === true);\n process.exitCode = report.exitCode;\n });\n\n program\n .command('init')\n .description(`Interactively generate ${DEFAULT_CONFIG_FILENAME}.`)\n .option('--output <path>', 'output path', DEFAULT_CONFIG_FILENAME)\n .option('--force', 'overwrite an existing file', false)\n .option('--yes', 'use non-interactive defaults (required for scripting/tests)', false)\n .action(async (opts: { output: string; force: boolean; yes: boolean }) => {\n const code = await runInit({ outputPath: opts.output, force: opts.force, yes: opts.yes }, io);\n process.exitCode = code;\n });\n\n program\n .command('demo')\n .description(\n 'Run the documented docker compose + demo agent quickstart, verifying health between steps.',\n )\n .action(async () => {\n process.exitCode = await runDemo(io);\n });\n\n return program;\n}\n","/**\n * `agent-commerce demo` — a thin, honest wrapper around the documented\n * `docker compose up` + `npm run demo:agent` steps (README/ commands).\n *\n * No orchestration magic: each step's exit code is checked, and a failing\n * step is reported with exactly what failed and what to run to retry it, not\n * swallowed into a generic \"demo failed\" message.\n */\nimport type { Io } from '../lib/io.js';\n\nexport interface DemoStep {\n readonly name: string;\n readonly command: string;\n readonly args: readonly string[];\n /** Optional health check run after the step; returns true when healthy. */\n readonly healthCheck?: () => Promise<boolean>;\n}\n\nexport interface RunResult {\n readonly code: number;\n readonly stderrTail?: string;\n}\n\nexport type RunCommand = (command: string, args: readonly string[]) => Promise<RunResult>;\n\nexport interface DemoDeps {\n readonly run?: RunCommand;\n readonly steps?: readonly DemoStep[];\n}\n\nexport function defaultDemoSteps(): readonly DemoStep[] {\n return [\n {\n name: 'Start local chain + gateway + merchant (docker compose)',\n command: 'docker',\n args: ['compose', 'up', '--build', '-d'],\n },\n { name: 'Run the deterministic buyer agent', command: 'npm', args: ['run', 'demo:agent'] },\n ];\n}\n\n/** `agent-commerce demo`. Returns process exit code. */\nexport async function runDemo(io: Io, deps: DemoDeps = {}): Promise<number> {\n const steps = deps.steps ?? defaultDemoSteps();\n const run = deps.run ?? execCommand;\n\n io.stdout('agent-commerce demo — running the documented quickstart steps:');\n for (const step of steps) {\n io.stdout('');\n io.stdout(`==> ${step.name}`);\n io.stdout(` $ ${step.command} ${step.args.join(' ')}`);\n const result = await run(step.command, step.args);\n if (result.code !== 0) {\n io.stderr(`FAIL \"${step.name}\" exited with code ${result.code}.`);\n if (result.stderrTail !== undefined && result.stderrTail.length > 0) {\n io.stderr(result.stderrTail);\n }\n io.stderr('');\n io.stderr('Nothing further was run. To retry manually:');\n io.stderr(` ${step.command} ${step.args.join(' ')}`);\n return 1;\n }\n if (step.healthCheck !== undefined) {\n const healthy = await step.healthCheck();\n if (!healthy) {\n io.stderr(`FAIL \"${step.name}\" completed but its health check did not pass.`);\n return 1;\n }\n }\n io.stdout(`OK ${step.name}`);\n }\n io.stdout('');\n io.stdout('PASS Demo is up. Try: agent-commerce doctor --config config-demo.yaml');\n return 0;\n}\n\nasync function execCommand(command: string, args: readonly string[]): Promise<RunResult> {\n const { spawn } = await import('node:child_process');\n return new Promise((resolvePromise) => {\n let stderr = '';\n const child = spawn(command, args, { stdio: ['ignore', 'inherit', 'pipe'] });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (err) => {\n resolvePromise({ code: 1, stderrTail: err.message });\n });\n child.on('close', (code) => {\n const tail = stderr.trim().split('\\n').slice(-10).join('\\n');\n resolvePromise({ code: code ?? 1, ...(tail.length > 0 ? { stderrTail: tail } : {}) });\n });\n });\n}\n","import { existsSync } from 'node:fs';\nimport picocolors from 'picocolors';\nimport { extractPathParameterNames } from '../../core/execution/index.js';\nimport { type CommerceResource, isCommerceError, type ReceiptStore } from '../../core/index.js';\nimport { createSqliteReceiptStore } from '../../storage/receipts/index.js';\nimport { type ConfigLoader, type GatewayConfig, loadConfigDynamic } from '../lib/config-client.js';\nimport { type FetchLike, fetchJson } from '../lib/http.js';\nimport { PLACEHOLDER_ASSET_ADDRESS } from '../lib/init-config.js';\nimport type { Io } from '../lib/io.js';\nimport {\n fillEnvFromLocalChainManifest,\n LOCAL_CHAIN_MANIFEST_PATH,\n MANIFEST_FILLABLE_ENV_VAR_NAMES,\n type ManifestEnvFill,\n} from '../lib/manifest-env.js';\nimport { maskMiddle } from '../lib/mask.js';\nimport { readVersionReport } from '../lib/versions.js';\n\nexport type CheckStatus = 'PASS' | 'WARN' | 'FAIL' | 'INFO';\n\nexport interface DoctorCheck {\n readonly name: string;\n readonly status: CheckStatus;\n readonly detail: string;\n}\n\nexport interface DoctorReport {\n readonly checks: readonly DoctorCheck[];\n readonly score: { readonly passed: number; readonly total: number };\n readonly exitCode: number;\n}\n\nexport interface DoctorOptions {\n readonly configPath?: string;\n readonly gatewayUrl?: string;\n}\n\nexport interface DoctorDeps {\n readonly fetchImpl?: FetchLike;\n readonly loadConfig?: ConfigLoader;\n readonly createStore?: (path: string) => ReceiptStore;\n readonly fillEnvFromManifest?: (env: NodeJS.ProcessEnv) => ManifestEnvFill;\n}\n\nconst CHECK_TIMEOUT_MS = 1500;\n\nfunction deriveGatewayUrl(explicit: string | undefined, config: GatewayConfig | undefined): string {\n if (explicit !== undefined) return explicit.replace(/\\/$/, '');\n if (config !== undefined) {\n // `0.0.0.0` means \"all interfaces\"; probe the loopback one. `::` is its\n // IPv6 equivalent. A literal IPv6 host such as `::1`\n // must be bracketed or the derived URL is invalid (`http://::1:8080`) and\n // doctor reported every running gateway as unreachable.\n const raw = config.server.host;\n const host = raw === '0.0.0.0' ? '127.0.0.1' : raw === '::' ? '::1' : raw;\n const authority = host.includes(':') ? `[${host}]` : host;\n return `http://${authority}:${config.server.port}`;\n }\n return 'http://localhost:8080';\n}\n\n/**\n * Fill `{param}` slots with a probe value, using the *canonical* grammar.\n *\n * A local `/\\{[^}]+\\}/g` here would recognise more than the runtime does. A\n * kebab-case token like `{report-id}` would match here and not there, so\n * `doctor` would probe `/report/demo-check` — the URL the operator meant —\n * and report the backend reachable, while every real request went to\n * `/report/%7Breport-id%7D` and 404'd after settling payment. A diagnostic\n * that probes a URL the runtime would never build is\n * worse than no diagnostic: it certifies the broken thing as healthy. Anything\n * the shared extractor does not recognise is deliberately left as-is, so the\n * probe hits exactly what the gateway would send.\n */\nfunction substitutePathParams(url: string): string {\n let filled = url;\n for (const name of extractPathParameterNames(url)) {\n filled = filled.split(`{${name}}`).join('demo-check');\n }\n return filled;\n}\n\ninterface LiveX402 {\n readonly asset: string;\n readonly network: string;\n readonly payTo: string;\n}\n\n/**\n * Pulls the gateway's *effective* x402 settlement config out of\n * `/.well-known/agent-commerce` (src/gateway/well-known.ts). Returns\n * undefined for anything short of \"the gateway confirms x402 is enabled and\n * reports all three fields\" — a doctor cross-check must never itself become\n * an unchecked cast on network-supplied JSON.\n */\n/**\n * `undefined` must not be allowed to mean three different things — gateway\n * down, document malformed, and *the gateway positively reporting x402\n * disabled*. The third is not an absence of information, it is a\n * disagreement: local config enables x402, the running gateway says it does\n * not, which is exactly the deployment-mismatch this cross-check was built to\n * catch. Reporting it as \"could not be verified\" turned the finding into a\n * shrug. `'disabled'` separates it out.\n */\ntype LiveX402Result = LiveX402 | 'disabled' | undefined;\n\nfunction extractWellKnownX402(body: Record<string, unknown> | undefined): LiveX402Result {\n const payments = body?.['payments'];\n if (typeof payments !== 'object' || payments === null) return undefined;\n const x402 = (payments as Record<string, unknown>)['x402'];\n if (typeof x402 !== 'object' || x402 === null) return undefined;\n const rec = x402 as Record<string, unknown>;\n // Only an explicit `false` is a positive statement. Anything else (absent,\n // null, a non-boolean) is still \"cannot tell\".\n if (rec['enabled'] === false) return 'disabled';\n if (rec['enabled'] !== true) return undefined;\n const { asset, network, payTo } = rec;\n if (typeof asset !== 'string' || typeof network !== 'string' || typeof payTo !== 'string') {\n return undefined;\n }\n return { asset, network, payTo };\n}\n\n/** Addresses are checksum-insensitive throughout this project (src/config/schema.ts). */\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n\n/**\n * A doctor that reports healthy against a mismatched deployment is worse\n * than no diagnostic at all false-green finding). Compares\n * the gateway's live settlement config against what the local config\n * resolved to, and names both values so the operator knows exactly what to\n * check rather than just that something disagrees.\n */\nfunction findX402Mismatch(configured: LiveX402, live: LiveX402): string | undefined {\n const diffs: string[] = [];\n if (!sameAddress(configured.asset, live.asset)) {\n diffs.push(\n `asset: gateway is using ${live.asset} but local config resolves to ${configured.asset}`,\n );\n }\n if (configured.network !== live.network) {\n diffs.push(\n `network: gateway is using \"${live.network}\" but local config resolves to \"${configured.network}\"`,\n );\n }\n if (!sameAddress(configured.payTo, live.payTo)) {\n diffs.push(\n `payTo: gateway is using ${live.payTo} but local config resolves to ${configured.payTo}`,\n );\n }\n if (diffs.length === 0) return undefined;\n return `${diffs.join('; ')} — the gateway may be running against an older deployment; restart it or re-run chain:deploy`;\n}\n\n/** `agent-commerce doctor [--config] [--gateway] [--json]`. */\nexport async function runDoctor(\n options: DoctorOptions,\n deps: DoctorDeps = {},\n): Promise<DoctorReport> {\n const fetchImpl = deps.fetchImpl ?? globalThis.fetch;\n const loadConfig = deps.loadConfig ?? loadConfigDynamic;\n const createStore = deps.createStore ?? ((path: string) => createSqliteReceiptStore({ path }));\n const fillEnvFromManifest = deps.fillEnvFromManifest ?? fillEnvFromLocalChainManifest;\n\n const checks: DoctorCheck[] = [];\n let config: GatewayConfig | undefined;\n\n // 1. Config\n const { env, filled, manifestFound } = fillEnvFromManifest(process.env);\n const filledSuffix =\n filled.length > 0\n ? ` (using local chain manifest ${LOCAL_CHAIN_MANIFEST_PATH} for ${filled.join(', ')})`\n : '';\n try {\n config = await loadConfig({\n ...(options.configPath !== undefined ? { path: options.configPath } : {}),\n env,\n });\n checks.push({\n name: 'Config',\n status: 'PASS',\n detail: `valid — ${config.resources.length} resource(s), merchant \"${config.merchant.name}\"${filledSuffix}`,\n });\n } catch (err) {\n const variable = isCommerceError(err) ? err.details?.['variable'] : undefined;\n const hint =\n !manifestFound &&\n typeof variable === 'string' &&\n MANIFEST_FILLABLE_ENV_VAR_NAMES.has(variable)\n ? ` — run \"npm run chain:deploy\" (writes ${LOCAL_CHAIN_MANIFEST_PATH}, read automatically for local X402_*/MERCHANT_WALLET placeholders)`\n : '';\n checks.push({\n name: 'Config',\n status: 'FAIL',\n detail: `${err instanceof Error ? err.message : String(err)}${hint}`,\n });\n }\n\n const gatewayUrl = deriveGatewayUrl(options.gatewayUrl, config);\n\n // 2. Gateway\n const health = await fetchJson(fetchImpl, `${gatewayUrl}/health`, CHECK_TIMEOUT_MS);\n let gatewayUp = false;\n if (!health.ok) {\n checks.push({\n name: 'Gateway',\n status: 'FAIL',\n detail: `unreachable at ${gatewayUrl} (${health.error ?? `HTTP ${health.status}`})`,\n });\n } else {\n gatewayUp = true;\n const ready = await fetchJson(fetchImpl, `${gatewayUrl}/ready`, CHECK_TIMEOUT_MS);\n checks.push(\n ready.ok\n ? { name: 'Gateway', status: 'PASS', detail: `healthy and ready at ${gatewayUrl}` }\n : {\n name: 'Gateway',\n status: 'WARN',\n detail: `healthy but not ready at ${gatewayUrl} (${ready.error ?? `HTTP ${ready.status}`})`,\n },\n );\n }\n\n // 3. Backend(s)\n if (config === undefined) {\n checks.push({ name: 'Backend', status: 'WARN', detail: 'skipped — config invalid' });\n } else if (config.resources.length === 0) {\n checks.push({ name: 'Backend', status: 'INFO', detail: 'no resources configured' });\n } else {\n const resources = config.resources as readonly CommerceResource[];\n const urls: string[] = [...new Set(resources.map((r) => substitutePathParams(r.handler.url)))];\n const results = await Promise.all(\n urls.map((url) => fetchJson(fetchImpl, url, CHECK_TIMEOUT_MS)),\n );\n const reachable = results.filter((r) => r.status !== 0).length;\n const status: CheckStatus =\n reachable === urls.length ? 'PASS' : reachable === 0 ? 'FAIL' : 'WARN';\n checks.push({\n name: 'Backend',\n status,\n detail: `${reachable}/${urls.length} backend host(s) reachable`,\n });\n }\n\n // 4. Well-known document (feeds Protocols + Protocol versions)\n const wellKnown = gatewayUp\n ? await fetchJson<Record<string, unknown>>(\n fetchImpl,\n `${gatewayUrl}/.well-known/agent-commerce`,\n CHECK_TIMEOUT_MS,\n )\n : undefined;\n\n // 5. Protocols\n if (config === undefined) {\n checks.push({ name: 'Protocols', status: 'WARN', detail: 'skipped — config invalid' });\n } else if (wellKnown === undefined || !wellKnown.ok) {\n checks.push({ name: 'Protocols', status: 'FAIL', detail: 'well-known document unreachable' });\n } else {\n const mcpMountPath = config.protocols.mcp.enabled ? config.protocols.mcp.mountPath : undefined;\n checks.push({\n name: 'Protocols',\n status: 'PASS',\n detail: `http=${config.protocols.http.enabled ? 'on' : 'off'} mcp=${config.protocols.mcp.enabled ? `on (${mcpMountPath})` : 'off'}`,\n });\n }\n\n // 6. Payments\n const x402 = config?.payments.x402;\n if (x402 === undefined || !x402.enabled) {\n checks.push({ name: 'Payments', status: 'INFO', detail: 'x402 not configured' });\n } else {\n const summary = `x402 enabled — network=${x402.network}, destination=${maskMiddle(x402.payTo)}, facilitator=${x402.facilitator.mode}`;\n const live = wellKnown?.ok ? extractWellKnownX402(wellKnown.body) : undefined;\n if (sameAddress(x402.asset, PLACEHOLDER_ASSET_ADDRESS)) {\n // `init --yes` writes this placeholder, and the\n // live cross-check compares config against the gateway's echo of the\n // same config — so everything matched and the report said 7/7 PASS on a\n // deployment where no paid call can ever succeed, because no token\n // contract exists at that address. Fail-closed holds and no funds are at\n // risk; the overstatement is the defect.\n checks.push({\n name: 'Payments',\n status: 'WARN',\n detail: `${summary}, but the asset is still the init placeholder ${maskMiddle(PLACEHOLDER_ASSET_ADDRESS)} — no token contract exists there, so every paid call will fail. Set payments.x402.asset (\\${X402_ASSET} is filled from .deploy/local.json by \"npm run chain:deploy\")`,\n });\n } else if (live === 'disabled') {\n // Verified, and it disagrees. Every paid call against this gateway will\n // be served free or refused, depending on the resource — either way the\n // deployment is not what this config describes.\n checks.push({\n name: 'Payments',\n status: 'FAIL',\n detail: `${summary}, but the gateway at ${gatewayUrl} reports x402 disabled — it is running a different configuration`,\n });\n } else if (live === undefined) {\n // Gateway unreachable, x402 not (yet) reported live, or the document\n // didn't parse as expected — can't judge a match either way, so this\n // is not a FAIL: a doctor that fails on things it cannot check is as\n // untrustworthy as one that passes on things it never checked.\n checks.push({\n name: 'Payments',\n status: 'INFO',\n detail: `${summary} (gateway's live settlement config could not be verified)`,\n });\n } else {\n const mismatch = findX402Mismatch(x402, live);\n checks.push(\n mismatch === undefined\n ? { name: 'Payments', status: 'PASS', detail: summary }\n : { name: 'Payments', status: 'FAIL', detail: mismatch },\n );\n }\n }\n checks.push({\n name: 'Payments (MPP)',\n status: 'INFO',\n detail: 'planned — not implemented in v0.1',\n });\n\n // 7. Storage\n if (config === undefined) {\n checks.push({ name: 'Storage', status: 'WARN', detail: 'skipped — config invalid' });\n } else if (\n // Diagnose without creating: createSqliteReceiptStore mkdir+creates the\n // file, so calling it on a wrong path (a typo, or a container path read\n // from the host) silently produces a fresh empty database and a false\n // \"healthy, receipts=0\" PASS — a read-only command must not have this\n // side effect, and it shadows the real store's real receipts entirely.\n //. `:memory:` never exists on disk by\n // definition, so it always falls through to the real open/health/count\n // branch below, same as today.\n config.storage.receipts.path !== ':memory:' &&\n !existsSync(config.storage.receipts.path)\n ) {\n checks.push({\n name: 'Storage',\n status: 'WARN',\n detail:\n `no store exists yet at \"${config.storage.receipts.path}\" — it is created ` +\n 'automatically the first time the gateway starts. If the gateway is already ' +\n 'running, this path does not match the one it actually uses.',\n });\n } else {\n let store: ReceiptStore | undefined;\n try {\n store = createStore(config.storage.receipts.path);\n await store.init();\n const storeHealth = await store.health();\n let receiptCount: number | undefined;\n try {\n // Exact count, not a list length: listReceipts clamps to\n // MAX_LIST_LIMIT (500, a store-level invariant) so counting via the\n // list silently saturated at 500 forever.\n receiptCount = await store.countReceipts();\n } catch {\n receiptCount = undefined;\n }\n let undeliveredCount: number | undefined;\n try {\n // A paid-but-undelivered purchase looks identical to a successful\n // one everywhere else; this is what makes it visible to an operator\n // running doctor. Same signal the\n // dashboard's receipt table uses, so the two views cannot disagree.\n undeliveredCount = await store.countUndeliveredReceipts();\n } catch {\n undeliveredCount = undefined;\n }\n const status: CheckStatus =\n storeHealth.status === 'pass' ? 'PASS' : storeHealth.status === 'warn' ? 'WARN' : 'FAIL';\n const receiptsSuffix =\n receiptCount !== undefined\n ? `; receipts=${receiptCount}${undeliveredCount !== undefined && undeliveredCount > 0 ? ` (${undeliveredCount} undelivered)` : ''}`\n : '';\n checks.push({\n name: 'Storage',\n status,\n detail: `${storeHealth.detail ?? 'sqlite'}${receiptsSuffix}`,\n });\n } catch (err) {\n checks.push({\n name: 'Storage',\n status: 'FAIL',\n detail: err instanceof Error ? err.message : String(err),\n });\n } finally {\n await store?.close();\n }\n }\n\n // 8. Protocol versions\n if (wellKnown !== undefined && wellKnown.ok) {\n checks.push({\n name: 'Protocol versions',\n status: 'PASS',\n detail: 'reported by gateway /.well-known/agent-commerce',\n });\n } else {\n const local = readVersionReport();\n checks.push({\n name: 'Protocol versions',\n status: 'INFO',\n detail: `gateway unreachable — local pins: ${local.pinned.map((p) => `${p.name}@${p.version}`).join(', ')}`,\n });\n }\n\n const scored = checks.filter((c) => c.status !== 'INFO');\n const passed = scored.filter((c) => c.status === 'PASS').length;\n const exitCode = checks.some((c) => c.status === 'FAIL') ? 1 : 0;\n\n return { checks, score: { passed, total: scored.length }, exitCode };\n}\n\nfunction statusColor(status: CheckStatus, text: string): string {\n switch (status) {\n case 'PASS':\n return picocolors.green(text);\n case 'WARN':\n return picocolors.yellow(text);\n case 'FAIL':\n return picocolors.red(text);\n case 'INFO':\n return picocolors.cyan(text);\n }\n}\n\nexport function printDoctorReport(report: DoctorReport, io: Io, json: boolean): void {\n if (json) {\n io.stdout(JSON.stringify(report, null, 2));\n return;\n }\n for (const check of report.checks) {\n const label = statusColor(check.status, check.status.padEnd(5));\n io.stdout(`${label} ${check.name.padEnd(20)} ${check.detail}`);\n }\n io.stdout('');\n io.stdout(`Score: ${report.score.passed}/${report.score.total} checks passed`);\n}\n","/**\n * SQLite implementation of the frozen ReceiptStore interface.\n *\n * Thin repository layer — no ORM. Every write goes through a prepared\n * statement; the only thing that varies between calls is parameters.\n */\nimport { randomUUID } from 'node:crypto';\nimport { accessSync, chmodSync, existsSync, constants as fsConstants, mkdirSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport Database from 'better-sqlite3';\nimport {\n type AdapterDescriptor,\n type AdapterHealth,\n type Clock,\n CommerceError,\n type CommerceEvent,\n type CommerceReceipt,\n type IdGenerator,\n type ListOptions,\n type Logger,\n NOOP_LOGGER,\n type PaymentAttempt,\n type PaymentAttemptReservation,\n type PaymentAttemptUpdate,\n type ReceiptStore,\n systemClock,\n toCommerceError,\n} from '../../core/index.js';\nimport { PACKAGE_VERSION } from '../../version.js';\nimport {\n type EventRow,\n eventToRow,\n type PaymentAttemptRow,\n type ReceiptRow,\n receiptToRow,\n rowToEvent,\n rowToPaymentAttempt,\n rowToReceipt,\n} from './rows.js';\nimport { migrate, SCHEMA_VERSION } from './schema.js';\n\nconst DEFAULT_LIST_LIMIT = 50;\n/**\n * Hard ceiling on every list query, applied here rather than only at the\n * gateway route, so every caller (HTTP, CLI, a future adapter) is covered.\n * SQLite treats a negative `LIMIT` as \"no limit\" —\n * confirmed `{ limit: -1 }` returns the entire table.\n */\nconst MAX_LIST_LIMIT = 500;\n\n/**\n * Clamps to a whole number in [1, MAX_LIST_LIMIT], defaulting when absent OR\n * non-finite (NaN/Infinity) — a store-level invariant that must hold\n * regardless of whether the current caller already filters those out.\n */\nfunction clampListLimit(limit: number | undefined): number {\n const base = limit !== undefined && Number.isFinite(limit) ? limit : DEFAULT_LIST_LIMIT;\n return Math.min(Math.max(Math.trunc(base), 1), MAX_LIST_LIMIT);\n}\n\nexport interface SqliteReceiptStoreOptions {\n /** File path, or ':memory:' for tests. Parent directory is created if missing. */\n readonly path: string;\n readonly logger?: Logger;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\nconst defaultIds: IdGenerator = {\n next: (prefix) => (prefix !== undefined ? `${prefix}_${randomUUID()}` : randomUUID()),\n};\n\nfunction isUniqueConstraintOn(err: unknown, column: string): boolean {\n return (\n err instanceof Error &&\n 'code' in err &&\n (err as { code?: unknown }).code === 'SQLITE_CONSTRAINT_UNIQUE' &&\n err.message.includes(column)\n );\n}\n\n/**\n * Narrow the database and its WAL sidecars to owner-only.\n *\n * `new Database(path)` opens with `0666 & ~umask`, so on a\n * standard host the `.sqlite`, `-wal` and `-shm` files landed at 0644 — any\n * other local user could read the whole commerce ledger: payer and payee\n * addresses, amounts, settlement transaction hashes, replay keys and the\n * entire event stream. No key material (the gateway is non-custodial and\n * `redact.ts` is recursive), but business metadata all the same.\n *\n * Called *after* `journal_mode = WAL`, because the sidecars do not exist until\n * then. Best-effort by design: a filesystem without POSIX modes must not stop\n * the gateway from starting, so a failure warns rather than throws.\n */\nfunction restrictDatabasePermissions(path: string, logger: Logger): void {\n for (const file of [path, `${path}-wal`, `${path}-shm`]) {\n try {\n chmodSync(file, 0o600);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') continue;\n logger.warn(\n { file, error: code ?? 'unknown' },\n 'could not restrict receipt database permissions to owner-only',\n );\n }\n }\n}\n\nexport function createSqliteReceiptStore(options: SqliteReceiptStoreOptions): ReceiptStore {\n const logger = options.logger ?? NOOP_LOGGER;\n const clock = options.clock ?? systemClock;\n const ids = options.ids ?? defaultIds;\n const path = options.path;\n const isFileBacked = path !== ':memory:';\n\n if (isFileBacked) {\n const dir = dirname(path);\n if (dir !== '' && dir !== '.' && !existsSync(dir)) {\n // 0700 on directories we create ourselves. An existing directory is the\n // operator's to own and is deliberately left alone.\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n }\n\n // Fail at startup, not on the first payment. `new Database(path)`\n // happily opens a file the process cannot write, and SQLite only says\n // \"attempt to write a readonly database\" once a write is attempted — which\n // on a paid resource is *after* the payment attempt reservation, surfacing\n // as an opaque STORAGE_ERROR per request. Readiness does catch it (503), but\n // the operator is left guessing. This is not hypothetical: switching the\n // demo containers to a non-root user left an existing named volume\n // root-owned, and that is exactly how it presented.\n if (isFileBacked && existsSync(path)) {\n try {\n accessSync(path, fsConstants.W_OK);\n } catch {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `Receipt database \"${path}\" exists but is not writable by this process (uid ${typeof process.getuid === 'function' ? process.getuid() : 'unknown'}). If this is a container that recently changed user, an existing volume may still be owned by the previous one — recreate it (docker compose down -v) or fix its ownership.`,\n { details: { path } },\n );\n }\n }\n\n const db = new Database(path);\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n migrate(db);\n if (isFileBacked) restrictDatabasePermissions(path, logger);\n\n const insertReceiptStmt = db.prepare(\n `INSERT INTO receipts (id, request_id, resource_id, payment_json, delivered_at, backend_status, duration_ms, protocol, metadata_json)\n VALUES (@id, @request_id, @resource_id, @payment_json, @delivered_at, @backend_status, @duration_ms, @protocol, @metadata_json)`,\n );\n const getReceiptStmt = db.prepare<[string], ReceiptRow>('SELECT * FROM receipts WHERE id = ?');\n const listReceiptsStmt = db.prepare<[number], ReceiptRow>(\n 'SELECT * FROM receipts ORDER BY delivered_at DESC, seq DESC LIMIT ?',\n );\n const listReceiptsByRequestStmt = db.prepare<[string, number], ReceiptRow>(\n 'SELECT * FROM receipts WHERE request_id = ? ORDER BY delivered_at DESC, seq DESC LIMIT ?',\n );\n const countReceiptsStmt = db.prepare<[], { count: number }>(\n 'SELECT COUNT(*) AS count FROM receipts',\n );\n // backend_status is INTEGER NOT NULL (schema.ts) so NOT BETWEEN never has\n // a NULL row to silently miss; 0 (backend never responded at all) and\n // every non-2xx status both count as undelivered, matching the dashboard's\n // deliveryResult() (ReceiptList.tsx) — the two views must not disagree\n // about what \"delivered\" means, which is the confusion.\n const countUndeliveredReceiptsStmt = db.prepare<[], { count: number }>(\n 'SELECT COUNT(*) AS count FROM receipts WHERE backend_status NOT BETWEEN 200 AND 299',\n );\n\n const insertEventStmt = db.prepare(\n `INSERT INTO events (id, type, request_id, resource_id, at, adapter, payment_provider, duration_ms, status, data_json)\n VALUES (@id, @type, @request_id, @resource_id, @at, @adapter, @payment_provider, @duration_ms, @status, @data_json)`,\n );\n const listEventsStmt = db.prepare<[number], EventRow>(\n 'SELECT * FROM events ORDER BY at DESC, seq DESC LIMIT ?',\n );\n const listEventsByRequestStmt = db.prepare<[string, number], EventRow>(\n 'SELECT * FROM events WHERE request_id = ? ORDER BY at DESC, seq DESC LIMIT ?',\n );\n\n const insertPaymentAttemptStmt = db.prepare(\n `INSERT INTO payment_attempts (id, request_id, resource_id, provider, replay_key, status, amount, currency, payer, payee, external_reference, rejection_reason, created_at, updated_at)\n VALUES (@id, @request_id, @resource_id, @provider, @replay_key, @status, @amount, @currency, @payer, @payee, @external_reference, @rejection_reason, @created_at, @updated_at)`,\n );\n const getPaymentAttemptByIdStmt = db.prepare<[string], PaymentAttemptRow>(\n 'SELECT * FROM payment_attempts WHERE id = ?',\n );\n // COALESCE: an omitted field (bound as NULL — see updatePaymentAttempt)\n // means \"leave the existing value alone\", not \"clear it\". Without this, a\n // second update that doesn't re-supply external_reference/rejection_reason\n // erases it — exactly the field that carries the on-chain tx hash for a\n // settlement-uncertain attempt, the one record proving the buyer's funds\n // may have moved. There is no current caller that needs to clear an\n // already-set value; if one appears, it needs an explicit sentinel rather\n // than overloading `undefined` to mean two different things again.\n const updatePaymentAttemptStmt = db.prepare(\n `UPDATE payment_attempts SET status = @status,\n external_reference = COALESCE(@external_reference, external_reference),\n rejection_reason = COALESCE(@rejection_reason, rejection_reason),\n updated_at = @updated_at\n WHERE replay_key = @replay_key`,\n );\n const listPaymentAttemptsStmt = db.prepare<[number], PaymentAttemptRow>(\n 'SELECT * FROM payment_attempts ORDER BY created_at DESC, seq DESC LIMIT ?',\n );\n const listPaymentAttemptsByRequestStmt = db.prepare<[string, number], PaymentAttemptRow>(\n 'SELECT * FROM payment_attempts WHERE request_id = ? ORDER BY created_at DESC, seq DESC LIMIT ?',\n );\n\n let closed = false;\n\n const descriptor: AdapterDescriptor = {\n name: 'sqlite-receipt-store',\n kind: 'storage',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: `sqlite-schema-v${SCHEMA_VERSION}`,\n capabilities: ['receipts', 'events', 'payment-attempts'],\n status: 'stable',\n };\n\n const store: ReceiptStore = {\n async init(): Promise<void> {\n // Schema setup already happened synchronously above (better-sqlite3 is\n // sync). This re-check makes init() a meaningful, idempotent gate for\n // callers that treat it as the lifecycle hook that must succeed before\n // any other method is used.\n const version = db.pragma('user_version', { simple: true }) as number;\n if (version !== SCHEMA_VERSION) {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `Receipt store schema version mismatch (found ${version}, expected ${SCHEMA_VERSION})`,\n );\n }\n },\n\n async appendEvent(event: CommerceEvent): Promise<void> {\n try {\n insertEventStmt.run(eventToRow(event));\n } catch (err) {\n logger.warn(\n {\n err: err instanceof Error ? err.message : String(err),\n eventId: event.id,\n requestId: event.requestId,\n },\n 'receipt-store: failed to persist commerce event',\n );\n }\n },\n\n async reservePaymentAttempt(reservation: PaymentAttemptReservation): Promise<PaymentAttempt> {\n const now = clock.nowIso();\n const id = ids.next('attempt');\n try {\n insertPaymentAttemptStmt.run({\n id,\n request_id: reservation.requestId,\n resource_id: reservation.resourceId,\n provider: reservation.provider,\n replay_key: reservation.replayKey,\n status: 'reserved' satisfies PaymentAttempt['status'],\n amount: reservation.amount,\n currency: reservation.currency,\n payer: reservation.payer ?? null,\n payee: reservation.payee ?? null,\n external_reference: null,\n rejection_reason: null,\n created_at: now,\n updated_at: now,\n });\n } catch (err) {\n if (isUniqueConstraintOn(err, 'payment_attempts.replay_key')) {\n throw new CommerceError(\n 'PAYMENT_REPLAYED',\n `Payment authorisation has already been used (replayKey=${reservation.replayKey})`,\n { requestId: reservation.requestId, resourceId: reservation.resourceId },\n );\n }\n throw toCommerceError(err, 'STORAGE_ERROR', 'Failed to reserve payment attempt');\n }\n const row = getPaymentAttemptByIdStmt.get(id);\n if (row === undefined) {\n throw new CommerceError(\n 'STORAGE_ERROR',\n 'Payment attempt vanished immediately after insert',\n );\n }\n return rowToPaymentAttempt(row);\n },\n\n async updatePaymentAttempt(update: PaymentAttemptUpdate): Promise<void> {\n try {\n const result = updatePaymentAttemptStmt.run({\n replay_key: update.replayKey,\n status: update.status,\n external_reference: update.externalReference ?? null,\n rejection_reason: update.rejectionReason ?? null,\n updated_at: clock.nowIso(),\n });\n if (result.changes === 0) {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `No payment attempt found for replayKey=${update.replayKey}`,\n );\n }\n } catch (err) {\n throw toCommerceError(err, 'STORAGE_ERROR', 'Failed to update payment attempt');\n }\n },\n\n async saveReceipt(receipt: CommerceReceipt): Promise<void> {\n try {\n insertReceiptStmt.run(receiptToRow(receipt));\n } catch (err) {\n throw toCommerceError(err, 'STORAGE_ERROR', 'Failed to save receipt');\n }\n },\n\n async getReceipt(id: string): Promise<CommerceReceipt | undefined> {\n const row = getReceiptStmt.get(id);\n return row !== undefined ? rowToReceipt(row) : undefined;\n },\n\n async listReceipts(listOptions: ListOptions = {}): Promise<readonly CommerceReceipt[]> {\n const limit = clampListLimit(listOptions.limit);\n const rows =\n listOptions.requestId !== undefined\n ? listReceiptsByRequestStmt.all(listOptions.requestId, limit)\n : listReceiptsStmt.all(limit);\n return rows.map(rowToReceipt);\n },\n\n /** Exact total, ignoring the listReceipts clamp — see the interface doc for why this exists. */\n async countReceipts(): Promise<number> {\n return countReceiptsStmt.get()?.count ?? 0;\n },\n\n /** Exact count of non-2xx receipts — see the interface doc for why this exists. */\n async countUndeliveredReceipts(): Promise<number> {\n return countUndeliveredReceiptsStmt.get()?.count ?? 0;\n },\n\n async listEvents(listOptions: ListOptions = {}): Promise<readonly CommerceEvent[]> {\n const limit = clampListLimit(listOptions.limit);\n const rows =\n listOptions.requestId !== undefined\n ? listEventsByRequestStmt.all(listOptions.requestId, limit)\n : listEventsStmt.all(limit);\n return rows.map(rowToEvent);\n },\n\n async listPaymentAttempts(listOptions: ListOptions = {}): Promise<readonly PaymentAttempt[]> {\n const limit = clampListLimit(listOptions.limit);\n const rows =\n listOptions.requestId !== undefined\n ? listPaymentAttemptsByRequestStmt.all(listOptions.requestId, limit)\n : listPaymentAttemptsStmt.all(limit);\n return rows.map(rowToPaymentAttempt);\n },\n\n descriptor,\n\n async health(): Promise<AdapterHealth> {\n // Same discipline: a client-visible field is authored from a\n // fixed vocabulary, never inherited from a caught error's `.message`.\n // `accessSync` on a real deployment throws e.g.\n // \"EACCES: permission denied, access '/workspace/data/receipts.sqlite'\"\n // — an absolute host path that must never reach the unauthenticated\n // `/ready` response). The raw message still goes\n // to the injected logger, so nothing is lost for diagnosis.\n const startedAt = clock.monotonicMs();\n if (closed) {\n return { status: 'fail', detail: 'store-unavailable', checkedAt: clock.nowIso() };\n }\n if (isFileBacked) {\n try {\n accessSync(path, fsConstants.W_OK);\n } catch (err) {\n logger.warn(\n { err: err instanceof Error ? err.message : String(err) },\n 'receipt-store: health check failed (store not writable)',\n );\n return {\n status: 'fail',\n detail: 'store-unwritable',\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n }\n try {\n const version = db.pragma('user_version', { simple: true }) as number;\n if (version !== SCHEMA_VERSION) {\n logger.warn(\n { found: version, expected: SCHEMA_VERSION },\n 'receipt-store: health check failed (schema version mismatch)',\n );\n return {\n status: 'fail',\n detail: 'store-schema-mismatch',\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n return {\n status: 'pass',\n detail: `sqlite schema v${SCHEMA_VERSION} writable`,\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n } catch (err) {\n logger.warn(\n { err: err instanceof Error ? err.message : String(err) },\n 'receipt-store: health check failed (store unavailable)',\n );\n return {\n status: 'fail',\n detail: 'store-unavailable',\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n },\n\n async close(): Promise<void> {\n if (!closed) {\n closed = true;\n db.close();\n }\n },\n };\n\n return store;\n}\n","/**\n * The package version, resolved once for the whole package.\n *\n * Two paths, deliberately:\n *\n * - **Development** reads the root manifest, so the number is always live.\n * - **The published bundle cannot.** tsup collapses `src/**` into\n * `dist/index.js` and `dist/cli/index.js`, so any `require('../../package.json')`\n * written against a source path resolves from the wrong depth once bundled —\n * which is exactly how this broke during the single-package refactor, and how\n * it earlier produced a CLI reporting `v0.0.0-unknown`. The build injects\n * `__OAC_PACKAGE_VERSION__` instead (see tsup.config.ts).\n *\n * `typeof` on an undeclared identifier is safe in JS, so the dev path is\n * unaffected by the constant not existing.\n */\nimport { createRequire } from 'node:module';\n\ndeclare const __OAC_PACKAGE_VERSION__: string | undefined;\n\nfunction readFromManifest(): string {\n try {\n const require = createRequire(import.meta.url);\n // src/version.ts -> repository root\n return (require('../package.json') as { version?: string }).version ?? '0.0.0-unknown';\n } catch {\n return '0.0.0-unknown';\n }\n}\n\nexport const PACKAGE_VERSION: string =\n typeof __OAC_PACKAGE_VERSION__ === 'string' ? __OAC_PACKAGE_VERSION__ : readFromManifest();\n","/**\n * Defence-in-depth against accidentally persisting secrets.\n *\n * The gateway and payment providers are expected to never place secrets into\n * `CommerceReceipt.metadata`, `CommerceEvent.data` or `PaymentResult.metadata`\n * (see docs/contracts.md, \"Store NO secrets\"). This module is a second line\n * of defence at the persistence boundary: any key that *looks* like it holds\n * a private key, an auth header or a raw payment proof is stripped — never\n * persisted — rather than rejecting the whole write, so a logging bug never\n * takes down an otherwise-successful commerce flow (appendEvent especially\n * must never throw into the caller's flow).\n */\n/**\n * The bearer-token family was missing — `token`, `bearerToken`,\n * `adminToken`, `authToken`, `credential`, `cookie`, `sessionId`, `jwt` all\n * returned false. Nothing writes such a key today, which is exactly the state\n * a second line of defence is for; and this data also lands in a\n * file that is now owner-only precisely because it is worth protecting.\n */\nconst SECRET_KEY_PATTERN =\n /private[-_ ]?key|secret|password|mnemonic|seed[-_ ]?phrase|api[-_ ]?key|authoriz(e|ation)|^auth$|auth[-_]?header|payment[-_ ]?proof|^proof$|x-payment|signature|signed[-_ ]?message|token|bearer|credential|cookie|session|jwt/i;\n\nconst REDACTED = '[REDACTED]';\n\n/** True if `key` looks like it names a secret value. */\nexport function isSecretKey(key: string): boolean {\n return SECRET_KEY_PATTERN.test(key);\n}\n\n/**\n * Recursively strip values whose key looks secret-shaped, returning a new\n * object. Safe to call on already-clean data (no-op in that case).\n */\nexport function redact<T>(value: T): T {\n return redactValue(value) as T;\n}\n\nfunction redactValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(redactValue);\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, inner] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSecretKey(key) ? REDACTED : redactValue(inner);\n }\n return out;\n }\n return value;\n}\n\n/** True if `value` (recursively) contains any key that looks secret-shaped. */\nexport function containsSecretKey(value: unknown): boolean {\n if (Array.isArray(value)) {\n return value.some(containsSecretKey);\n }\n if (value !== null && typeof value === 'object') {\n return Object.entries(value as Record<string, unknown>).some(\n ([key, inner]) => isSecretKey(key) || containsSecretKey(inner),\n );\n }\n return false;\n}\n","/**\n * SQLite row shapes and mapping to/from the canonical domain model.\n *\n * `exactOptionalPropertyTypes` is on: optional fields are only assigned when\n * present (see docs/contracts.md, assumption 8).\n */\nimport type {\n CommerceEvent,\n CommerceEventType,\n CommerceReceipt,\n PaymentAttempt,\n PaymentResult,\n} from '../../core/index.js';\nimport { redact } from './redact.js';\n\nexport interface ReceiptRow {\n readonly id: string;\n readonly request_id: string;\n readonly resource_id: string;\n readonly payment_json: string | null;\n readonly delivered_at: string;\n readonly backend_status: number;\n readonly duration_ms: number | null;\n readonly protocol: string | null;\n readonly metadata_json: string | null;\n}\n\nexport interface EventRow {\n readonly id: string;\n readonly type: string;\n readonly request_id: string;\n readonly resource_id: string | null;\n readonly at: string;\n readonly adapter: string | null;\n readonly payment_provider: string | null;\n readonly duration_ms: number | null;\n readonly status: string | null;\n readonly data_json: string | null;\n}\n\nexport interface PaymentAttemptRow {\n readonly id: string;\n readonly request_id: string;\n readonly resource_id: string;\n readonly provider: string;\n readonly replay_key: string;\n readonly status: string;\n readonly amount: string;\n readonly currency: string;\n readonly payer: string | null;\n readonly payee: string | null;\n readonly external_reference: string | null;\n readonly rejection_reason: string | null;\n readonly created_at: string;\n readonly updated_at: string;\n}\n\nexport function receiptToRow(receipt: CommerceReceipt): {\n id: string;\n request_id: string;\n resource_id: string;\n payment_json: string | null;\n delivered_at: string;\n backend_status: number;\n duration_ms: number | null;\n protocol: string | null;\n metadata_json: string | null;\n} {\n return {\n id: receipt.id,\n request_id: receipt.requestId,\n resource_id: receipt.resourceId,\n payment_json: receipt.payment !== undefined ? JSON.stringify(redact(receipt.payment)) : null,\n delivered_at: receipt.deliveredAt,\n backend_status: receipt.backendStatus,\n duration_ms: receipt.durationMs !== undefined ? receipt.durationMs : null,\n protocol: receipt.protocol !== undefined ? receipt.protocol : null,\n metadata_json: receipt.metadata !== undefined ? JSON.stringify(redact(receipt.metadata)) : null,\n };\n}\n\nexport function rowToReceipt(row: ReceiptRow): CommerceReceipt {\n const payment =\n row.payment_json !== null ? (JSON.parse(row.payment_json) as PaymentResult) : undefined;\n const metadata =\n row.metadata_json !== null\n ? (JSON.parse(row.metadata_json) as Record<string, unknown>)\n : undefined;\n return {\n id: row.id,\n requestId: row.request_id,\n resourceId: row.resource_id,\n deliveredAt: row.delivered_at,\n backendStatus: row.backend_status,\n ...(payment !== undefined ? { payment } : {}),\n ...(row.duration_ms !== null ? { durationMs: row.duration_ms } : {}),\n ...(row.protocol !== null ? { protocol: row.protocol } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nexport function eventToRow(event: CommerceEvent): {\n id: string;\n type: string;\n request_id: string;\n resource_id: string | null;\n at: string;\n adapter: string | null;\n payment_provider: string | null;\n duration_ms: number | null;\n status: string | null;\n data_json: string | null;\n} {\n return {\n id: event.id,\n type: event.type,\n request_id: event.requestId,\n resource_id: event.resourceId !== undefined ? event.resourceId : null,\n at: event.at,\n adapter: event.adapter !== undefined ? event.adapter : null,\n payment_provider: event.paymentProvider !== undefined ? event.paymentProvider : null,\n duration_ms: event.durationMs !== undefined ? event.durationMs : null,\n status: event.status !== undefined ? event.status : null,\n data_json: event.data !== undefined ? JSON.stringify(redact(event.data)) : null,\n };\n}\n\nexport function rowToEvent(row: EventRow): CommerceEvent {\n const data =\n row.data_json !== null ? (JSON.parse(row.data_json) as Record<string, unknown>) : undefined;\n return {\n id: row.id,\n type: row.type as CommerceEventType,\n requestId: row.request_id,\n at: row.at,\n ...(row.resource_id !== null ? { resourceId: row.resource_id } : {}),\n ...(row.adapter !== null ? { adapter: row.adapter } : {}),\n ...(row.payment_provider !== null ? { paymentProvider: row.payment_provider } : {}),\n ...(row.duration_ms !== null ? { durationMs: row.duration_ms } : {}),\n ...(row.status !== null ? { status: row.status as 'ok' | 'error' } : {}),\n ...(data !== undefined ? { data } : {}),\n };\n}\n\nexport function rowToPaymentAttempt(row: PaymentAttemptRow): PaymentAttempt {\n return {\n id: row.id,\n requestId: row.request_id,\n resourceId: row.resource_id,\n provider: row.provider,\n replayKey: row.replay_key,\n status: row.status as PaymentAttempt['status'],\n amount: row.amount,\n currency: row.currency,\n ...(row.payer !== null ? { payer: row.payer } : {}),\n ...(row.payee !== null ? { payee: row.payee } : {}),\n ...(row.external_reference !== null ? { externalReference: row.external_reference } : {}),\n ...(row.rejection_reason !== null ? { rejectionReason: row.rejection_reason } : {}),\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n","/**\n * Explicit migration scheme for the receipt-store SQLite schema.\n *\n * Uses SQLite's built-in `PRAGMA user_version` as the migration marker so a\n * restart against an existing database file re-opens without re-creating or\n * losing data (required negative test: \"gateway restart with receipt storage\n * preserved\").\n */\nimport type Database from 'better-sqlite3';\n\ninterface Migration {\n readonly version: number;\n up(db: Database.Database): void;\n}\n\nconst MIGRATIONS: readonly Migration[] = [\n {\n version: 1,\n up(db) {\n db.exec(`\n CREATE TABLE IF NOT EXISTS receipts (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n request_id TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n payment_json TEXT,\n delivered_at TEXT NOT NULL,\n backend_status INTEGER NOT NULL,\n duration_ms INTEGER,\n protocol TEXT,\n metadata_json TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_receipts_request_id ON receipts(request_id);\n CREATE INDEX IF NOT EXISTS idx_receipts_delivered_at ON receipts(delivered_at);\n\n CREATE TABLE IF NOT EXISTS events (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n type TEXT NOT NULL,\n request_id TEXT NOT NULL,\n resource_id TEXT,\n at TEXT NOT NULL,\n adapter TEXT,\n payment_provider TEXT,\n duration_ms INTEGER,\n status TEXT,\n data_json TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_events_request_id ON events(request_id);\n CREATE INDEX IF NOT EXISTS idx_events_at ON events(at);\n\n CREATE TABLE IF NOT EXISTS payment_attempts (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n request_id TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n provider TEXT NOT NULL,\n replay_key TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL,\n amount TEXT NOT NULL,\n currency TEXT NOT NULL,\n payer TEXT,\n payee TEXT,\n external_reference TEXT,\n rejection_reason TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_payment_attempts_request_id ON payment_attempts(request_id);\n CREATE INDEX IF NOT EXISTS idx_payment_attempts_created_at ON payment_attempts(created_at);\n `);\n },\n },\n];\n\n/** Current target schema version — the version of the last migration. */\nexport const SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;\n\n/**\n * Bring `db` up to {@link SCHEMA_VERSION}. Idempotent: re-opening an existing,\n * already-migrated file is a fast no-op check against `PRAGMA user_version`.\n */\nexport function migrate(db: Database.Database): void {\n const current = db.pragma('user_version', { simple: true }) as number;\n for (const migration of MIGRATIONS) {\n if (migration.version <= current) continue;\n const apply = db.transaction(() => {\n migration.up(db);\n db.pragma(`user_version = ${migration.version}`);\n });\n apply();\n }\n}\n","/**\n * Single seam for the CLI's dependency on `src/config`.\n *\n * The import is dynamic, not static, on purpose: a static\n * `import … from '../../config/index.js'` would fail the whole module\n * graph the instant the package became unavailable for any reason (mid-flight\n * refactor, a broken build), taking down every CLI command — even `version`,\n * which never touches config — the moment this file is loaded. A dynamic\n * import only fails, catchably, when a command actually needs configuration.\n *\n * `runValidate` / `runDoctor` / `runInit` also accept the loader as an\n * injected dependency (defaulting to {@link loadConfigDynamic}), which keeps\n * their logic unit-testable without touching the filesystem or the real\n * package.\n */\nimport type { GatewayConfig as GatewayConfigType } from '../../config/index.js';\n\nexport type GatewayConfig = GatewayConfigType;\n\nexport interface LoadConfigOptions {\n readonly path?: string;\n readonly env?: NodeJS.ProcessEnv;\n readonly cwd?: string;\n}\n\nexport type ConfigLoader = (options?: LoadConfigOptions) => Promise<GatewayConfig>;\n\n/** Validates an already-built raw config object, without touching the disk. */\nexport type ConfigParser = (raw: unknown, env?: NodeJS.ProcessEnv) => Promise<GatewayConfig>;\n\nexport async function loadConfigDynamic(options: LoadConfigOptions = {}): Promise<GatewayConfig> {\n let mod: typeof import('../../config/index.js');\n try {\n mod = await import('../../config/index.js');\n } catch (err) {\n throw new Error(\n `the configuration module could not be loaded: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return mod.loadConfig(options);\n}\n\n/**\n * In-memory validation, same module and same seam as {@link loadConfigDynamic}.\n *\n * Validating the object before writing means nothing lands unless it is\n * valid. Writing the file and *then* loading it back would leave an answer\n * that legitimately fails validation — no protocol selected, a typo'd\n * settlement address, a scheme-less backend URL — on disk under a printed\n * \"PASS Wrote …\", and tell the user to report their own input as a bug.\n */\nexport async function parseConfigDynamic(\n raw: unknown,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<GatewayConfig> {\n let mod: typeof import('../../config/index.js');\n try {\n mod = await import('../../config/index.js');\n } catch (err) {\n throw new Error(\n `the configuration module could not be loaded: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return mod.parseConfig(raw, env);\n}\n","/**\n * Small fetch-with-timeout helper for `doctor`. Injectable so tests never hit\n * a real network — they point it at a local stub HTTP server instead.\n */\nexport type FetchLike = typeof fetch;\n\nexport interface FetchJsonResult<T> {\n readonly ok: boolean;\n readonly status: number;\n readonly body?: T;\n readonly error?: string;\n}\n\nexport async function fetchJson<T = unknown>(\n fetchImpl: FetchLike,\n url: string,\n timeoutMs = 1500,\n): Promise<FetchJsonResult<T>> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetchImpl(url, { signal: controller.signal });\n let body: T | undefined;\n try {\n body = (await res.json()) as T;\n } catch {\n body = undefined;\n }\n return { ok: res.ok, status: res.status, ...(body !== undefined ? { body } : {}) };\n } catch (err) {\n return {\n ok: false,\n status: 0,\n error: err instanceof Error ? err.message : 'unknown fetch error',\n };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Anvil's well-known development accounts.\n *\n * LOCAL DEVELOPMENT ONLY — DO NOT FUND. These addresses and private keys are\n * derived from Foundry's public, well-documented default test mnemonic\n * (\"test test test test test test test test test test test junk\") and are\n * known to everyone who has ever run `anvil`. Anyone who sends real value to\n * one of these addresses on a real network will lose it.\n *\n * Index layout used by the local demo chain (see docs/contracts.md):\n * 0 — deployer / local facilitator signer (pays gas, broadcasts settlement)\n * 1 — merchant settlement destination (`payTo`)\n * 2 — buyer (signs EIP-3009 authorisations; never held by the gateway)\n */\nexport interface AnvilWellKnownAccount {\n readonly address: `0x${string}`;\n readonly privateKey: `0x${string}`;\n}\n\n/** Fixed-length tuple (not a bare array) so indexing by the documented layout above is fully typed. */\nexport const ANVIL_WELL_KNOWN_ACCOUNTS: readonly [\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n] = [\n {\n address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',\n },\n {\n address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',\n privateKey: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',\n },\n {\n address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',\n privateKey: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',\n },\n];\n\nexport const LOCAL_FACILITATOR_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[0];\nexport const LOCAL_MERCHANT_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[1];\nexport const LOCAL_BUYER_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[2];\n\n/** Safe label used everywhere a dev key appears in output, logs or manifests. */\nexport const DEV_KEY_LABEL = 'LOCAL DEVELOPMENT ONLY - DO NOT FUND';\n","/**\n * Pure YAML-rendering logic for `agent-commerce init`, kept separate from\n * prompt/IO concerns so it is trivially unit-testable.\n *\n * The on-disk shape here is the *raw* `config.yaml` document consumed\n * by `src/config`'s `parseConfig` (src/config/schema.ts):\n * `resources` is a map keyed by resource id, with `backend` / `expose` /\n * `payments` / `input` / `output` field names — distinct from the normalised\n * `CommerceResource` shape (`handler` / `exposedVia` / `paymentMethods` /\n * `inputSchema` / `outputSchema`) that `loadConfig()` returns.\n *\n * Addresses below are Anvil's well-known local dev accounts #0 (facilitator\n * signer) and #1 (merchant `payTo`) — public, fixed, printed by every\n * `anvil` startup banner. Never fund them.\n * Imported from `src/payments/x402/testing.ts` — the\n * canonical source (docs/contracts.md) — rather than duplicated as literals,\n * so `init` can never drift from `scripts/chain/deploy.ts`'s account layout.\n * A hand-copied or truncated literal here breaks every paid request and\n * silently defeats the dev-key guard. The MockUSDC `asset` address is a clearly labelled placeholder: it\n * cannot be known before `npm run chain:deploy` writes `.deploy/local.json`, so\n * it must not be the zero address (rejected by config validation) and must\n * be replaced by the real deployed address.\n */\n\nimport { stringify } from 'yaml';\n// Narrow module, not the `testing.js` barrel — see manifest-env.ts for why.\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from '../../payments/x402/local-chain/accounts.js';\n\n/** Anvil account #1 — merchant settlement destination, never the gateway/facilitator. */\nexport const LOCAL_DEV_MERCHANT_ADDRESS = ANVIL_WELL_KNOWN_ACCOUNTS[1].address;\n/** Anvil account #0 — local facilitator signer (broadcasts settlement on the dev chain only). */\nexport const LOCAL_DEV_FACILITATOR_PRIVATE_KEY = ANVIL_WELL_KNOWN_ACCOUNTS[0].privateKey;\n/** Placeholder only — replace with the MockUSDC address from `.deploy/local.json`. */\nexport const PLACEHOLDER_ASSET_ADDRESS = '0x000000000000000000000000000000000000dEaD';\n\nexport type InitResourceChoice = 'weather' | 'report';\nexport type InitProtocolChoice = 'http' | 'mcp';\n\nexport interface InitAnswers {\n readonly backendBaseUrl: string;\n readonly resources: readonly InitResourceChoice[];\n readonly protocols: readonly InitProtocolChoice[];\n readonly x402Enabled: boolean;\n readonly merchantPayTo: string;\n}\n\nexport function defaultInitAnswers(): InitAnswers {\n return {\n backendBaseUrl: 'http://localhost:3000',\n resources: ['weather', 'report'],\n protocols: ['http', 'mcp'],\n x402Enabled: true,\n merchantPayTo: LOCAL_DEV_MERCHANT_ADDRESS,\n };\n}\n\nfunction buildResourcesMap(answers: InitAnswers): Record<string, unknown> {\n const resources: Record<string, unknown> = {};\n const expose = [...answers.protocols];\n\n if (answers.resources.includes('weather')) {\n resources.weather = {\n name: 'Get weather',\n description: 'Deterministic demo weather lookup (free resource).',\n input: {\n type: 'object',\n properties: { city: { type: 'string' } },\n required: ['city'],\n additionalProperties: false,\n },\n backend: {\n type: 'http',\n method: 'GET',\n url: `${answers.backendBaseUrl}/api/weather/{city}`,\n },\n pricing: { type: 'free' },\n expose,\n };\n }\n\n if (answers.resources.includes('report')) {\n const paid = answers.x402Enabled;\n resources.report = {\n name: 'Get market report',\n description: 'Deterministic demo premium market report.',\n // No caller-supplied fields for this resource: an explicit empty,\n // closed schema (rather than omitting `input`) so a missing schema can\n // never be read as \"anything goes\".\n input: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n backend: {\n type: 'http',\n method: 'GET',\n url: `${answers.backendBaseUrl}/api/report`,\n },\n pricing: paid ? { type: 'fixed', amount: '0.01', currency: 'USDC' } : { type: 'free' },\n expose,\n ...(paid ? { payments: ['x402'] } : {}),\n };\n }\n\n return resources;\n}\n\n/** Builds the raw config object accepted by `parseConfig` (src/config). */\nexport function buildInitConfigObject(answers: InitAnswers): Record<string, unknown> {\n return {\n version: 1,\n merchant: {\n id: 'demo-merchant',\n name: 'Demo Merchant',\n publicBaseUrl: 'http://localhost:8080',\n },\n server: { port: 8080, host: '127.0.0.1' },\n storage: { receipts: { driver: 'sqlite', path: './data/receipts.db' } },\n protocols: {\n http: { enabled: answers.protocols.includes('http') },\n mcp: { enabled: answers.protocols.includes('mcp'), mountPath: '/mcp' },\n },\n resources: buildResourcesMap(answers),\n payments: answers.x402Enabled\n ? {\n x402: {\n enabled: true,\n network: 'base-sepolia',\n rpcUrl: 'http://127.0.0.1:8545',\n asset: PLACEHOLDER_ASSET_ADDRESS,\n assetName: 'MockUSDC',\n assetVersion: '2',\n assetDecimals: 6,\n payTo: answers.merchantPayTo,\n maxTimeoutSeconds: 60,\n facilitator: { mode: 'local', signerPrivateKey: LOCAL_DEV_FACILITATOR_PRIVATE_KEY },\n },\n }\n : {},\n };\n}\n\nconst HEADER = `# Generated by \\`agent-commerce init\\`.\n#\n# Any address/key below labelled \"LOCAL DEVELOPMENT ONLY\" or \"placeholder\" is\n# either one of Anvil's well-known, public dev accounts (never fund them,\n# never use them outside a local chain) or a\n# not-yet-real address. Before running against the local chain, run\n# \\`npm run chain:deploy\\` and replace \\`payments.x402.asset\\` with the deployed\n# MockUSDC address from \\`.deploy/local.json\\`. Replace \\`payments.x402.payTo\\`\n# with your real merchant-controlled settlement address before ever pointing\n# this at a funded network.\n#\n# server.host is loopback (127.0.0.1) on purpose: binding every interface\n# should be a deliberate edit, not something you inherit from a generator.\n#\n# server.adminToken / server.allowedOrigins are left unset here — a generated\n# secret in a file you might commit is its own problem, so this is left as a\n# placeholder for you to fill in rather than a real token. Without a token,\n# the operator routes (/api/receipts, /api/events, /api/events/stream) —\n# the merchant's commerce ledger: payer addresses, amounts, settlement\n# hashes — return 404 rather than serving openly. To enable them, uncomment\n# and set:\n# server:\n# adminToken: \\${ADMIN_TOKEN}\n# allowedOrigins:\n# - http://localhost:5173\n# See SECURITY.md before exposing this gateway beyond localhost.\n`;\n\nexport function renderInitConfigYaml(answers: InitAnswers): string {\n const body = stringify(buildInitConfigObject(answers), { indent: 2 });\n return `${HEADER}\\n${body}`;\n}\n","/**\n * Local chain deployment manifest — read/write contract for `.deploy/local.json`.\n *\n * Exact shape frozen in docs/contracts.md. Everything else in the repo reads\n * chain addresses through `readLocalChainManifest()` — no hard-coded\n * addresses anywhere else.\n *\n * Lives inside `src/payments/x402` (not `scripts/chain`, which is\n * outside `src/` and is run directly by npm scripts —\n * see `deploy-engine.ts`'s header comment for the same reasoning) so any\n * workspace package can import it via `src/payments/x402/testing.ts`\n * (see `docs/contracts.md`, \"Local chain deployment manifest\"). It has no\n * dependency on viem/zod/x402 regardless — plain Node built-ins only —\n * `scripts/chain/manifest.ts` re-exports this module unchanged so\n * `npm run chain:deploy` keeps working as a thin CLI wrapper.\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport const LOCAL_CHAIN_MANIFEST_PATH = '.deploy/local.json';\n\nexport interface LocalChainManifestMerchant {\n readonly address: string;\n readonly privateKeyLabel: string;\n}\n\nexport interface LocalChainManifestKeyedAccount {\n readonly address: string;\n readonly privateKey: string;\n readonly note: string;\n}\n\nexport interface LocalChainManifest {\n readonly chainId: number;\n readonly rpcUrl: string;\n /**\n * The same chain, reachable from the *host* — distinct from `rpcUrl` only\n * when the deployer ran inside a Docker network (there `rpcUrl` is the\n * container-internal address, e.g. \"http://anvil:8545\", unresolvable from\n * the host). A host deploy records the same value in both fields, since on\n * the host they genuinely are the same endpoint. Host-side consumers\n * (demo agent, CLI) should prefer `hostRpcUrl ?? rpcUrl`. Optional so a\n * manifest written before this field existed still parses.\n */\n readonly hostRpcUrl?: string;\n readonly asset: string;\n readonly assetName: string;\n readonly assetVersion: string;\n readonly assetDecimals: number;\n readonly merchant: LocalChainManifestMerchant;\n readonly buyer: LocalChainManifestKeyedAccount;\n readonly facilitator: LocalChainManifestKeyedAccount;\n readonly buyerInitialBalance: string;\n}\n\nconst REQUIRED_TOP_LEVEL_STRING_FIELDS = [\n 'rpcUrl',\n 'asset',\n 'assetName',\n 'assetVersion',\n 'buyerInitialBalance',\n] as const;\n\n/**\n * Reads and structurally validates `.deploy/local.json`.\n *\n * Throws a clear, actionable error if the manifest is missing or malformed —\n * every consumer of this function is expected to let that error propagate\n * rather than silently falling back to a hard-coded address.\n */\nexport function readLocalChainManifest(cwd: string = process.cwd()): LocalChainManifest {\n const path = join(cwd, LOCAL_CHAIN_MANIFEST_PATH);\n\n if (!existsSync(path)) {\n throw new Error(\n `Local chain manifest not found at \"${path}\". Run \"npm run chain:start\" then \"npm run chain:deploy\" first.`,\n );\n }\n\n let raw: string;\n try {\n raw = readFileSync(path, 'utf8');\n } catch (cause) {\n throw new Error(`Could not read local chain manifest at \"${path}\".`, { cause });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n throw new Error(\n `Local chain manifest at \"${path}\" is not valid JSON. Re-run \"npm run chain:deploy\" to regenerate it.`,\n { cause },\n );\n }\n\n return validateManifestShape(parsed, path);\n}\n\nfunction validateManifestShape(value: unknown, path: string): LocalChainManifest {\n const fail = (detail: string): never => {\n throw new Error(\n `Local chain manifest at \"${path}\" is invalid: ${detail}. Re-run \"npm run chain:deploy\".`,\n );\n };\n\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return fail('expected a JSON object');\n }\n const record = value as Record<string, unknown>;\n\n if (typeof record.chainId !== 'number') {\n return fail('\"chainId\" must be a number');\n }\n if (typeof record.assetDecimals !== 'number') {\n return fail('\"assetDecimals\" must be a number');\n }\n for (const field of REQUIRED_TOP_LEVEL_STRING_FIELDS) {\n if (typeof record[field] !== 'string' || record[field] === '') {\n return fail(`\"${field}\" must be a non-empty string`);\n }\n }\n // Optional: absent entirely on a manifest written before this field\n // existed, but if present it must be well-formed — never silently ignore a\n // malformed value on a trust-boundary read.\n if ('hostRpcUrl' in record && record.hostRpcUrl !== undefined) {\n if (typeof record.hostRpcUrl !== 'string' || record.hostRpcUrl === '') {\n return fail('\"hostRpcUrl\" must be a non-empty string when present');\n }\n }\n\n const merchant = record.merchant;\n if (\n typeof merchant !== 'object' ||\n merchant === null ||\n typeof (merchant as Record<string, unknown>).address !== 'string' ||\n typeof (merchant as Record<string, unknown>).privateKeyLabel !== 'string'\n ) {\n return fail('\"merchant\" must be { address: string, privateKeyLabel: string }');\n }\n\n for (const key of ['buyer', 'facilitator'] as const) {\n const account = record[key];\n if (\n typeof account !== 'object' ||\n account === null ||\n typeof (account as Record<string, unknown>).address !== 'string' ||\n typeof (account as Record<string, unknown>).privateKey !== 'string' ||\n typeof (account as Record<string, unknown>).note !== 'string'\n ) {\n return fail(`\"${key}\" must be { address: string, privateKey: string, note: string }`);\n }\n }\n\n return record as unknown as LocalChainManifest;\n}\n","/**\n * Local-development convenience: fills `X402_*`/`MERCHANT_WALLET`\n * placeholders in `config.yaml` from `.deploy/local.json` (written\n * by `npm run chain:deploy`) when the host shell hasn't set them itself.\n *\n * Why this exists: inside `docker compose`, `docker/gateway-entrypoint.sh`\n * exports these from the manifest before the gateway process starts. Running\n * `agent-commerce validate`/`doctor` on the host has no equivalent step, so\n * the exact same config that starts the (containerised) gateway fine fails\n * host-side with \"Unresolved environment variable\" — reporting a healthy\n * stack as broken. See docs/contracts.md \"Local chain deployment manifest\".\n *\n * Deliberately narrow: only fills a variable that is completely unset (a\n * real environment always wins — this can never override a deployment), only\n * from the exact fields the manifest declares, and only for `validate`/\n * `doctor` — never inside the config loader itself, so gateway startup is\n * unaffected either way.\n */\n// Imported from the narrow module, not the `testing.js` barrel: that barrel\n// also re-exports the Anvil bootstrap and the deploy engine, which import\n// `viem`. Tree-shaking drops the unused bindings but esbuild still emits a\n// bare `import 'viem'` for side effects, and viem is an optional peer — the\n// CLI would refuse to start on a default install. Caught by a bare\n// clean-consumer install, not by any in-repo test.\nimport {\n LOCAL_CHAIN_MANIFEST_PATH,\n type LocalChainManifest,\n readLocalChainManifest,\n} from '../../payments/x402/local-chain/manifest.js';\n\nexport { LOCAL_CHAIN_MANIFEST_PATH };\n\n/** `config.yaml` placeholder name -> the manifest field it maps to. */\nconst MANIFEST_ENV_VARS: readonly (readonly [string, (m: LocalChainManifest) => string])[] = [\n ['X402_ASSET', (m) => m.asset],\n ['X402_ASSET_NAME', (m) => m.assetName],\n ['X402_ASSET_VERSION', (m) => m.assetVersion],\n ['X402_ASSET_DECIMALS', (m) => String(m.assetDecimals)],\n ['MERCHANT_WALLET', (m) => m.merchant.address],\n ['X402_FACILITATOR_PRIVATE_KEY', (m) => m.facilitator.privateKey],\n];\n\n/** The subset of {@link MANIFEST_ENV_VARS} names, for checking a failed variable against. */\nexport const MANIFEST_FILLABLE_ENV_VAR_NAMES: ReadonlySet<string> = new Set(\n MANIFEST_ENV_VARS.map(([name]) => name),\n);\n\nexport interface ManifestEnvFill {\n /** `baseEnv`, plus any variables filled. Never mutates `baseEnv` itself. */\n readonly env: NodeJS.ProcessEnv;\n /** Names actually filled — empty when the manifest was absent or nothing needed filling. */\n readonly filled: readonly string[];\n /** True once a manifest was found at all, whether or not anything needed filling. */\n readonly manifestFound: boolean;\n}\n\n/**\n * Reads `.deploy/local.json` (relative to `cwd`) and fills only the\n * currently-unset variables in {@link MANIFEST_ENV_VARS}. Never throws — a\n * missing or invalid manifest just means nothing gets filled, and the\n * existing \"unresolved environment variable\" error from `src/config`\n * surfaces exactly as it does today.\n */\nexport function fillEnvFromLocalChainManifest(\n baseEnv: NodeJS.ProcessEnv,\n cwd: string = process.cwd(),\n): ManifestEnvFill {\n let manifest: LocalChainManifest;\n try {\n manifest = readLocalChainManifest(cwd);\n } catch {\n return { env: baseEnv, filled: [], manifestFound: false };\n }\n\n const filled: string[] = [];\n const env: NodeJS.ProcessEnv = { ...baseEnv };\n for (const [name, read] of MANIFEST_ENV_VARS) {\n if (env[name] === undefined) {\n env[name] = read(manifest);\n filled.push(name);\n }\n }\n return { env, filled, manifestFound: true };\n}\n","/**\n * Safe, visible-but-non-secret display of an address/destination for\n * `doctor`. Shows enough to eyeball correctness without ever printing a full\n * value that could be sensitive-adjacent (e.g. an RPC URL with an embedded\n * API key).\n *\n * Returning the value whole when it is short enough (`length <= keep * 2`)\n * would contradict the promise above — harmless for the 42-character\n * addresses this is used on today, and a trap for the next caller who reaches\n * for it with a short secret. A short value is masked entirely instead.\n */\nexport function maskMiddle(value: string, keep = 6): string {\n if (value.length <= keep * 2) return value.length === 0 ? value : '…';\n return `${value.slice(0, keep)}…${value.slice(-4)}`;\n}\n","/**\n * The CLI's own version and every pinned protocol/SDK version — never\n * hard-coded, so a pin bump (see docs/contracts.md) is reflected automatically.\n *\n * Two resolution paths, deliberately:\n *\n * - **Development** reads the root manifest directly, so the numbers are\n * always live.\n * - **The published npm package** cannot: the build collapses `src/**` into\n * two bundled files, so a relative manifest path written against a source\n * location resolves from the wrong depth once bundled. That has now failed\n * twice — it silently produced `v0.0.0-unknown` before packaging, and it\n * crashed both entry points during the single-package refactor. So the\n * build injects the resolved report as `__OAC_VERSION_REPORT__` (see\n * tsup.config.ts) and it is preferred when present.\n *\n * `typeof` on an undeclared identifier is safe in JS, so the dev path is\n * unaffected by the constant not existing.\n */\nimport { createRequire } from 'node:module';\n\ndeclare const __OAC_VERSION_REPORT__: string | undefined;\n\nconst require = createRequire(import.meta.url);\n\ninterface PackageManifest {\n readonly version: string;\n readonly dependencies?: Readonly<Record<string, string>>;\n readonly peerDependencies?: Readonly<Record<string, string>>;\n}\n\nfunction readManifest(relativePath: string): PackageManifest | undefined {\n try {\n return require(relativePath) as PackageManifest;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Peers count as pins. The three heaviest pins — the MCP SDK, x402 and viem —\n * are *optional peer* dependencies so a default install stays small, and\n * reading only `dependencies` silently emptied this report of exactly the\n * protocol/SDK versions it exists to show.\n */\nfunction depVersion(manifest: PackageManifest | undefined, name: string): string | undefined {\n return manifest?.dependencies?.[name] ?? manifest?.peerDependencies?.[name];\n}\n\nexport interface PinnedVersion {\n readonly name: string;\n readonly version: string;\n readonly via: string;\n}\n\nexport interface VersionReport {\n readonly cliVersion: string;\n readonly pinned: readonly PinnedVersion[];\n}\n\n/** Missing entries are omitted (rather than shown as \"unknown\") so nothing is ever fabricated. */\nexport function readVersionReport(): VersionReport {\n const injected = typeof __OAC_VERSION_REPORT__ === 'string' ? __OAC_VERSION_REPORT__ : undefined;\n if (injected !== undefined) {\n return JSON.parse(injected) as VersionReport;\n }\n\n // One package, one manifest. `via` names the module that owns each pin,\n // which is what a reader of `agent-commerce version` actually wants to know;\n // the names are src/ directories, not package manifests.\n const manifest = readManifest('../../../package.json');\n\n const candidates: readonly [string, string][] = [\n ['@modelcontextprotocol/sdk', 'protocols/mcp'],\n ['x402', 'payments/x402'],\n ['viem', 'payments/x402'],\n ['better-sqlite3', 'storage/receipts'],\n ['fastify', 'gateway'],\n ['pino', 'gateway'],\n ['zod', 'config'],\n ];\n\n const pinned: PinnedVersion[] = [];\n for (const [name, via] of candidates) {\n const version = depVersion(manifest, name);\n if (version !== undefined) {\n pinned.push({ name, version, via });\n }\n }\n\n return {\n cliVersion: manifest?.version ?? '0.0.0-unknown',\n pinned,\n };\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { writeFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport * as clack from '@clack/prompts';\nimport { DEFAULT_CONFIG_FILENAME } from '../../config/filename.js';\nimport {\n type ConfigLoader,\n type ConfigParser,\n type GatewayConfig,\n loadConfigDynamic,\n parseConfigDynamic,\n} from '../lib/config-client.js';\nimport {\n buildInitConfigObject,\n defaultInitAnswers,\n type InitAnswers,\n type InitProtocolChoice,\n type InitResourceChoice,\n renderInitConfigYaml,\n} from '../lib/init-config.js';\nimport type { Io } from '../lib/io.js';\nimport { formatConfigError } from './validate.js';\n\nexport interface InitOptions {\n readonly outputPath?: string;\n readonly force?: boolean;\n readonly yes?: boolean;\n}\n\nexport interface InitDeps {\n readonly loadConfig?: ConfigLoader;\n readonly parseConfig?: ConfigParser;\n readonly collectAnswers?: () => Promise<InitAnswers | undefined>;\n readonly fileExists?: (path: string) => boolean;\n readonly writeFile?: (path: string, content: string) => Promise<void>;\n}\n\n/** Exported for testing: the real interactive prompt flow (mocks `@clack/prompts`). */\nexport async function collectAnswersInteractive(): Promise<InitAnswers | undefined> {\n clack.intro('agent-commerce init');\n\n const backendBaseUrl = await clack.text({\n message: 'Backend base URL (your existing merchant API)',\n initialValue: 'http://localhost:3000',\n // shape-checked here, where the user can retype it,\n // rather than surfacing as a config error after the fact.\n validate: (value) => {\n const trimmed = (value ?? '').trim();\n if (trimmed.length === 0) return 'Required';\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n return 'Must be an absolute URL, e.g. http://localhost:3000';\n }\n return parsed.protocol === 'http:' || parsed.protocol === 'https:'\n ? undefined\n : 'Must use http:// or https://';\n },\n });\n if (clack.isCancel(backendBaseUrl)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n const resources = await clack.multiselect<InitResourceChoice>({\n message: 'Which example resource(s) do you want to expose?',\n options: [\n { value: 'weather', label: 'Weather (free)' },\n { value: 'report', label: 'Market report (paid)' },\n ],\n initialValues: ['weather', 'report'],\n required: false,\n });\n if (clack.isCancel(resources)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n const protocols = await clack.multiselect<InitProtocolChoice>({\n message: 'Which protocols should be enabled?',\n options: [\n { value: 'http', label: 'HTTP' },\n { value: 'mcp', label: 'MCP' },\n ],\n initialValues: ['http', 'mcp'],\n // `required: false` permits an empty selection, which renders\n // `expose: []` on every resource and fails the schema's min(1). clack's\n // multiselect has no `validate` hook, so this is caught by the in-memory\n // validation in `runInit` — which now reports the real schema error and\n // writes nothing, instead of leaving an invalid file behind.\n required: false,\n });\n if (clack.isCancel(protocols)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n const x402Enabled = await clack.confirm({ message: 'Enable x402 payments?', initialValue: true });\n if (clack.isCancel(x402Enabled)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n let merchantPayTo = defaultInitAnswers().merchantPayTo;\n if (x402Enabled) {\n const answer = await clack.text({\n message:\n 'Merchant settlement destination address (merchant-controlled — never a gateway-owned wallet)',\n initialValue: merchantPayTo,\n validate: (value) => {\n const trimmed = (value ?? '').trim();\n if (trimmed.length === 0) return 'Required';\n // Same shape the config schema enforces; catching it here means a\n // typo'd address never reaches the \"generated config is invalid\" path.\n return /^0x[0-9a-fA-F]{40}$/.test(trimmed)\n ? undefined\n : 'Must be a 0x-prefixed 20-byte EVM address (42 characters)';\n },\n });\n if (clack.isCancel(answer)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n merchantPayTo = answer;\n }\n\n clack.outro('Configuration answers collected.');\n\n return { backendBaseUrl, resources, protocols, x402Enabled, merchantPayTo };\n}\n\n/** `agent-commerce init [--yes] [--force] [--output <path>]`. */\nexport async function runInit(options: InitOptions, io: Io, deps: InitDeps = {}): Promise<number> {\n const outputPath = options.outputPath ?? DEFAULT_CONFIG_FILENAME;\n const loadConfig = deps.loadConfig ?? loadConfigDynamic;\n const parseConfigInMemory = deps.parseConfig ?? parseConfigDynamic;\n const fileExists = deps.fileExists ?? existsSync;\n const writeFileImpl =\n deps.writeFile ??\n (async (path: string, content: string) => {\n await writeFile(path, content, 'utf8');\n });\n\n if (fileExists(outputPath) && options.force !== true) {\n io.stderr(`FAIL ${outputPath} already exists. Re-run with --force to overwrite.`);\n return 1;\n }\n\n const answers =\n options.yes === true\n ? defaultInitAnswers()\n : await (deps.collectAnswers ?? collectAnswersInteractive)();\n\n if (answers === undefined) {\n io.stderr('FAIL init aborted, nothing was written.');\n return 1;\n }\n\n // Validate BEFORE writing. Interactive answers can legitimately fail\n // validation — an empty protocol multiselect, a typo'd settlement address,\n // a scheme-less backend URL — and writing first would print \"PASS Wrote …\"\n // and then blame the tool: \"please report this as a bug\". Nothing is\n // written unless it is valid, and the message is the real configuration\n // error, which names the field the user can fix.\n let config: GatewayConfig;\n try {\n config = await parseConfigInMemory(buildInitConfigObject(answers));\n } catch (err) {\n io.stderr(formatConfigError(err));\n io.stderr(`FAIL Nothing was written to ${outputPath}.`);\n return 1;\n }\n\n const yamlContent = renderInitConfigYaml(answers);\n const resolvedPath = resolve(outputPath);\n const dir = dirname(resolvedPath);\n if (dir !== '' && !existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n await writeFileImpl(outputPath, yamlContent);\n io.stdout(`PASS Wrote ${outputPath}`);\n io.stdout(`PASS ${outputPath} is valid — ${config.resources.length} resource(s)`);\n\n // The YAML is rendered from the very object just validated, but it is\n // rendered, not serialised from it — so read it back and confirm the two\n // agree. A renderer bug is the one failure the in-memory check cannot see,\n // and it IS a bug worth reporting.\n try {\n await loadConfig({ path: outputPath });\n } catch (err) {\n io.stderr(formatConfigError(err));\n io.stderr(\n `FAIL ${outputPath} was written but does not parse, although the same answers validated in memory — this is a bug in the config renderer, please report it.`,\n );\n return 1;\n }\n\n io.stdout('');\n io.stdout('Next steps:');\n io.stdout(` agent-commerce validate --config ${outputPath}`);\n // Only commands the reader can actually run. `npm run dev:merchant` and\n // `npm run dev:gateway` exist solely inside the development repo, and this\n // CLI ships to npm — telling an installed user to run them is a dead end.\n io.stdout(' docker compose up # start the local demo stack (from a repo clone)');\n io.stdout(` agent-commerce doctor --config ${outputPath}`);\n\n return 0;\n}\n","import { ZodError } from 'zod';\nimport { isCommerceError } from '../../core/index.js';\nimport { type ConfigLoader, loadConfigDynamic } from '../lib/config-client.js';\nimport type { Io } from '../lib/io.js';\nimport {\n fillEnvFromLocalChainManifest,\n LOCAL_CHAIN_MANIFEST_PATH,\n MANIFEST_FILLABLE_ENV_VAR_NAMES,\n type ManifestEnvFill,\n} from '../lib/manifest-env.js';\n\nexport interface ValidateOptions {\n readonly configPath?: string;\n}\n\nexport interface ValidateDeps {\n readonly loadConfig?: ConfigLoader;\n readonly fillEnvFromManifest?: (env: NodeJS.ProcessEnv) => ManifestEnvFill;\n}\n\n/**\n * Formats a config-loading failure into an actionable report.\n *\n * Handles the three error shapes `src/config` can produce:\n * a `CommerceError('CONFIG_INVALID', …)` with structured details, a raw\n * `ZodError` (schema errors, one line per failing path), or a plain Error\n * (e.g. a YAML syntax error, or the \"config package not available yet\"\n * integration-gap error). Never prints a resolved `${ENV}` value — only ever\n * the variable name, which the underlying error message is expected to carry.\n *\n * `manifestFound` adds one more hint line when the failure is specifically an\n * unresolved variable that `.deploy/local.json` would have supplied, had\n * `npm run chain:deploy` been run — see `../lib/manifest-env.js`.\n */\nexport function formatConfigError(err: unknown, manifestFound = false): string {\n if (isCommerceError(err)) {\n const lines = [`FAIL ${err.code}: ${err.message}`];\n if (err.details !== undefined) {\n lines.push(` details: ${JSON.stringify(err.details)}`);\n }\n const variable = err.details?.['variable'];\n if (\n !manifestFound &&\n typeof variable === 'string' &&\n MANIFEST_FILLABLE_ENV_VAR_NAMES.has(variable)\n ) {\n lines.push(\n ` hint: \"npm run chain:deploy\" writes ${LOCAL_CHAIN_MANIFEST_PATH}, which validate/doctor read automatically to fill local X402_*/MERCHANT_WALLET placeholders.`,\n );\n }\n return lines.join('\\n');\n }\n if (err instanceof ZodError) {\n const lines = ['FAIL Configuration schema errors:'];\n for (const issue of err.issues) {\n const path = issue.path.length > 0 ? issue.path.join('.') : '(root)';\n lines.push(` - ${path}: ${issue.message}`);\n }\n return lines.join('\\n');\n }\n if (err instanceof Error) {\n return `FAIL ${err.message}`;\n }\n return `FAIL ${String(err)}`;\n}\n\n/** `agent-commerce validate [--config <path>]`. Exit code is non-zero on invalid configuration. */\nexport async function runValidate(\n options: ValidateOptions,\n io: Io,\n deps: ValidateDeps = {},\n): Promise<number> {\n const loadConfig = deps.loadConfig ?? loadConfigDynamic;\n const fillEnvFromManifest = deps.fillEnvFromManifest ?? fillEnvFromLocalChainManifest;\n const { env, filled, manifestFound } = fillEnvFromManifest(process.env);\n if (filled.length > 0) {\n io.stdout(`using local chain manifest ${LOCAL_CHAIN_MANIFEST_PATH} for ${filled.join(', ')}`);\n }\n try {\n const config = await loadConfig({\n ...(options.configPath !== undefined ? { path: options.configPath } : {}),\n env,\n });\n io.stdout('PASS Configuration is valid');\n io.stdout(` merchant: ${config.merchant.name} (${config.merchant.id})`);\n io.stdout(` resources: ${config.resources.length}`);\n io.stdout(\n ` protocols: http=${config.protocols.http.enabled ? 'on' : 'off'} mcp=${config.protocols.mcp.enabled ? 'on' : 'off'}`,\n );\n io.stdout(` payments: x402=${config.payments.x402?.enabled === true ? 'on' : 'off'}`);\n return 0;\n } catch (err) {\n io.stderr(formatConfigError(err, manifestFound));\n return 1;\n }\n}\n","import type { Io } from '../lib/io.js';\nimport { readVersionReport, type VersionReport } from '../lib/versions.js';\n\nexport interface VersionDeps {\n readonly readVersionReport?: () => VersionReport;\n}\n\n/** `agent-commerce version` — CLI version + pinned protocol/SDK versions. */\nexport function runVersion(io: Io, deps: VersionDeps = {}): number {\n const report = (deps.readVersionReport ?? readVersionReport)();\n io.stdout(`agent-commerce v${report.cliVersion}`);\n if (report.pinned.length > 0) {\n io.stdout('');\n io.stdout('Pinned protocol / SDK versions:');\n for (const pin of report.pinned) {\n io.stdout(` ${pin.name.padEnd(24)} ${pin.version.padEnd(12)} (via ${pin.via})`);\n }\n }\n return 0;\n}\n","/**\n * Minimal, injectable stdout/stderr so command logic is testable without\n * capturing real process streams.\n */\nexport interface Io {\n stdout(line: string): void;\n stderr(line: string): void;\n}\n\nexport const processIo: Io = {\n stdout: (line) => {\n process.stdout.write(`${line}\\n`);\n },\n stderr: (line) => {\n process.stderr.write(`${line}\\n`);\n },\n};\n\n/** Collects lines instead of writing anywhere. Useful for tests. */\nexport function createCapturingIo(): Io & { out: string[]; err: string[] } {\n const out: string[] = [];\n const err: string[] = [];\n return {\n out,\n err,\n stdout: (line) => out.push(line),\n stderr: (line) => err.push(line),\n };\n}\n","#!/usr/bin/env node\nimport { CommanderError } from 'commander';\nimport { buildProgram } from './program.js';\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n if (err instanceof CommanderError) {\n process.exitCode = err.exitCode;\n return;\n }\n throw err;\n }\n}\n\nvoid main();\n"]}
1
+ {"version":3,"sources":["../../src/config/filename.ts","../../src/core/domain/resource.ts","../../src/core/errors/codes.ts","../../src/core/errors/commerce-error.ts","../../src/core/errors/index.ts","../../src/core/interfaces/logger.ts","../../src/core/execution/backend-http.ts","../../src/core/execution/event-bus.ts","../../src/core/domain/wire.ts","../../src/core/execution/validation.ts","../../src/core/execution/pipeline.ts","../../src/core/execution/registry.ts","../../src/core/execution/index.ts","../../src/core/domain/event.ts","../../src/core/interfaces/protocol-adapter.ts","../../src/core/interfaces/runtime.ts","../../src/core/public-types.ts","../../src/core/index.ts","../../src/payments/x402/networks.ts","../../src/config/env.ts","../../src/payments/x402/local-chain/accounts.ts","../../src/payments/x402/dev-key-guard.ts","../../src/payments/x402/guardrails.ts","../../src/config/schema.ts","../../src/config/load.ts","../../src/config/index.ts","../../src/cli/program.ts","../../src/cli/commands/demo.ts","../../src/cli/commands/doctor.ts","../../src/storage/receipts/store.ts","../../src/version.ts","../../src/storage/receipts/redact.ts","../../src/storage/receipts/rows.ts","../../src/storage/receipts/schema.ts","../../src/cli/lib/config-client.ts","../../src/cli/lib/http.ts","../../src/cli/lib/init-config.ts","../../src/payments/x402/local-chain/manifest.ts","../../src/cli/lib/manifest-env.ts","../../src/cli/lib/mask.ts","../../src/cli/lib/versions.ts","../../src/cli/commands/init.ts","../../src/cli/commands/validate.ts","../../src/cli/commands/version.ts","../../src/cli/lib/io.ts","../../src/cli/index.ts"],"names":["path","isPlainObject","text","fs","parseYaml","fsConstants","existsSync","createRequire","sameAddress","loadConfig","resolve","dirname","mkdirSync"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The default configuration filename, in one place.\n *\n * Deliberately its own module with **no imports**: `src/cli` reaches the rest\n * of `src/config` only through a dynamic import (see\n * `src/cli/lib/config-client.ts`), so that a broken config module cannot take\n * down commands that never read configuration. A leaf file holding a single\n * string has no module graph to break, so the CLI can import it directly\n * without reopening that seam — and `init`'s default output path, `--config`'s\n * help text and the loader's own lookup cannot drift apart, which is what\n * three separate copies of this string invited.\n */\nexport const DEFAULT_CONFIG_FILENAME = 'config.yaml';\n","/**\n * Canonical resource model.\n *\n * FROZEN CONTRACT.\n */\nimport type { DecimalAmount, JsonSchema, PaymentMethodName, ProtocolName } from './common.js';\n\n/** HTTP methods a backend handler may use. */\nexport type BackendMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n\n/**\n * Describes how the gateway calls the merchant's existing backend.\n *\n * Backend URLs are administrator-controlled configuration only. User- or\n * agent-controlled backend URLs are forbidden (see docs/security.md, SSRF).\n * Secret header values must come from `${ENV_VAR}` placeholders resolved by\n * the config loader, never from plaintext configuration.\n */\nexport interface BackendHandler {\n readonly type: 'http';\n readonly method: BackendMethod;\n readonly url: string;\n readonly headers?: Readonly<Record<string, string>>;\n /** Hard upper bound on the backend call. Defaults to DEFAULT_BACKEND_TIMEOUT_MS. */\n readonly timeoutMs?: number;\n}\n\n/** Default backend timeout when a resource does not specify one. */\nexport const DEFAULT_BACKEND_TIMEOUT_MS = 10_000;\n\n/**\n * Canonical pricing.\n *\n * `dynamic` exists in the type system for forward compatibility but is\n * REJECTED by config validation in this release.\n */\nexport type Pricing =\n | { readonly type: 'free' }\n | {\n readonly type: 'fixed';\n readonly amount: DecimalAmount;\n readonly currency: string;\n }\n | {\n readonly type: 'dynamic';\n readonly resolver: string;\n };\n\n/**\n * A merchant capability exposed to agents.\n *\n * The canonical resource is the single source of truth: protocol adapters map\n * it outward, they never define their own parallel notion of a resource.\n */\nexport interface CommerceResource {\n readonly id: string;\n readonly name: string;\n readonly description?: string;\n readonly inputSchema?: JsonSchema;\n readonly outputSchema?: JsonSchema;\n readonly handler: BackendHandler;\n readonly pricing: Pricing;\n readonly exposedVia: readonly ProtocolName[];\n readonly paymentMethods: readonly PaymentMethodName[];\n}\n\n/** Read-only view of every configured resource. */\nexport interface ResourceRegistry {\n get(id: string): CommerceResource | undefined;\n list(): readonly CommerceResource[];\n /** Resources exposed through a given protocol surface. */\n listExposedVia(protocol: ProtocolName): readonly CommerceResource[];\n has(id: string): boolean;\n}\n","/**\n * Typed domain error codes.\n *\n * FROZEN CONTRACT. Protocol adapters map these codes into their own response\n * format. Never throw a bare string or untyped Error across a package boundary.\n */\nexport const COMMERCE_ERROR_CODES = [\n 'CONFIG_INVALID',\n 'RESOURCE_NOT_FOUND',\n 'INPUT_INVALID',\n 'PAYMENT_REQUIRED',\n 'PAYMENT_INVALID',\n 'PAYMENT_REPLAYED',\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'PAYMENT_SETTLEMENT_FAILED',\n 'BACKEND_TIMEOUT',\n 'BACKEND_ERROR',\n 'PROTOCOL_UNSUPPORTED',\n 'GATEWAY_BUSY',\n 'STORAGE_ERROR',\n 'INTERNAL_ERROR',\n] as const;\n\nexport type CommerceErrorCode = (typeof COMMERCE_ERROR_CODES)[number];\n\n/**\n * Canonical HTTP status for each error code.\n *\n * Paid resources fail closed: every payment failure maps to a 4xx/5xx status\n * and never to a successful delivery.\n */\nexport const COMMERCE_ERROR_HTTP_STATUS: Readonly<Record<CommerceErrorCode, number>> = {\n CONFIG_INVALID: 500,\n RESOURCE_NOT_FOUND: 404,\n INPUT_INVALID: 400,\n PAYMENT_REQUIRED: 402,\n PAYMENT_INVALID: 402,\n PAYMENT_REPLAYED: 409,\n PAYMENT_PROVIDER_UNAVAILABLE: 503,\n PAYMENT_SETTLEMENT_FAILED: 502,\n BACKEND_TIMEOUT: 504,\n BACKEND_ERROR: 502,\n PROTOCOL_UNSUPPORTED: 501,\n GATEWAY_BUSY: 503,\n STORAGE_ERROR: 500,\n INTERNAL_ERROR: 500,\n};\n\n/** Codes for which a client may reasonably retry the same request. */\nexport const RETRYABLE_ERROR_CODES: ReadonlySet<CommerceErrorCode> = new Set([\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'BACKEND_TIMEOUT',\n // Load shedding is transient by definition: the caller should back off and\n // try again. Before this code existed the MCP adapter's queue-full path threw\n // PROTOCOL_UNSUPPORTED — HTTP 501, retryable:false — so an agent framework\n // keyed on the machine-readable flag (which exists precisely so clients need\n // not parse prose) would read a momentary throttle as a permanent capability\n // gap and stop calling the tool.\n 'GATEWAY_BUSY',\n]);\n","/**\n * The single error type crossing package boundaries.\n *\n * FROZEN CONTRACT.\n */\nimport {\n COMMERCE_ERROR_HTTP_STATUS,\n type CommerceErrorCode,\n RETRYABLE_ERROR_CODES,\n} from './codes.js';\n\nexport interface CommerceErrorOptions {\n /** Structured, non-secret detail safe to return to a client. */\n readonly details?: Readonly<Record<string, unknown>>;\n readonly cause?: unknown;\n readonly requestId?: string;\n readonly resourceId?: string;\n /** Override the default HTTP status for this code. */\n readonly httpStatus?: number;\n}\n\n/** Serialisable wire form of a CommerceError. */\nexport interface CommerceErrorInfo {\n readonly code: CommerceErrorCode;\n readonly message: string;\n readonly httpStatus: number;\n readonly retryable: boolean;\n readonly requestId?: string;\n readonly resourceId?: string;\n readonly details?: Readonly<Record<string, unknown>>;\n}\n\nexport class CommerceError extends Error {\n readonly code: CommerceErrorCode;\n readonly httpStatus: number;\n readonly retryable: boolean;\n readonly details?: Readonly<Record<string, unknown>>;\n readonly requestId?: string;\n readonly resourceId?: string;\n\n constructor(code: CommerceErrorCode, message: string, options: CommerceErrorOptions = {}) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'CommerceError';\n this.code = code;\n this.httpStatus = options.httpStatus ?? COMMERCE_ERROR_HTTP_STATUS[code];\n this.retryable = RETRYABLE_ERROR_CODES.has(code);\n if (options.details !== undefined) this.details = options.details;\n if (options.requestId !== undefined) this.requestId = options.requestId;\n if (options.resourceId !== undefined) this.resourceId = options.resourceId;\n Error.captureStackTrace?.(this, CommerceError);\n }\n\n /** Non-secret, client-safe representation. */\n toInfo(): CommerceErrorInfo {\n return {\n code: this.code,\n message: this.message,\n httpStatus: this.httpStatus,\n retryable: this.retryable,\n ...(this.requestId !== undefined ? { requestId: this.requestId } : {}),\n ...(this.resourceId !== undefined ? { resourceId: this.resourceId } : {}),\n ...(this.details !== undefined ? { details: this.details } : {}),\n };\n }\n}\n\nexport function isCommerceError(value: unknown): value is CommerceError {\n return value instanceof CommerceError;\n}\n\n/**\n * Normalise any thrown value into a CommerceError.\n *\n * Used at package boundaries so an unexpected failure never escapes untyped.\n *\n * SECURITY — do not \"improve\" this by propagating `value.message`.\n * `CommerceError.message` is client-visible: it is serialised by `toInfo()`\n * and `toErrorEnvelope()` and returned over HTTP and MCP. An arbitrary thrown\n * Error's message routinely carries internal detail — database connection\n * strings, internal hostnames, filesystem paths, backend URLs. Copying it into\n * a client-facing field turns every unexpected exception into an information\n * disclosure.\n *\n * The original value is preserved on `cause`, which is never serialised, so\n * logs and diagnostics keep the full detail while clients get only the\n * caller's deliberate, reviewed `fallbackMessage`.\n *\n * A caller that *wants* a specific client-facing message passes one:\n * toCommerceError(err, 'BACKEND_ERROR', 'Backend call failed')\n */\nexport function toCommerceError(\n value: unknown,\n fallbackCode: CommerceErrorCode = 'INTERNAL_ERROR',\n fallbackMessage = 'Unexpected internal error',\n): CommerceError {\n if (isCommerceError(value)) return value;\n return new CommerceError(fallbackCode, fallbackMessage, { cause: value });\n}\n","export * from './codes.js';\nexport * from './commerce-error.js';\n","/**\n * Minimal structural logger interface.\n *\n * Core must not depend on pino directly; the gateway injects a pino instance\n * that satisfies this shape. Never log secrets: private keys, seed phrases,\n * Authorization headers or payment authorisation payloads.\n */\nexport interface Logger {\n debug(obj: Record<string, unknown>, msg?: string): void;\n info(obj: Record<string, unknown>, msg?: string): void;\n warn(obj: Record<string, unknown>, msg?: string): void;\n error(obj: Record<string, unknown>, msg?: string): void;\n child(bindings: Record<string, unknown>): Logger;\n}\n\n/** A logger that discards everything. Useful in unit tests. */\nexport const NOOP_LOGGER: Logger = {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n child: () => NOOP_LOGGER,\n};\n","/**\n * The only outbound HTTP path to a merchant backend.\n *\n * - Uses global `fetch` and always applies a bound timeout via `AbortSignal.timeout`.\n * - `redirect: 'manual'` — a 3xx response is treated as a `BACKEND_ERROR`, never\n * followed (SSRF hardening).\n * - `{param}` segments in `handler.url` are filled from validated input and\n * URL-encoded; whatever remains goes to the query string (GET/DELETE) or a\n * JSON body (POST/PUT/PATCH).\n */\nimport { type BackendHandler, DEFAULT_BACKEND_TIMEOUT_MS } from '../domain/resource.js';\nimport { CommerceError } from '../errors/index.js';\nimport type { BackendExecutor, BackendRequest, BackendResponse } from '../interfaces/backend.js';\nimport { type Logger, NOOP_LOGGER } from '../interfaces/logger.js';\n\nconst MAX_BODY_SNIPPET_LENGTH = 512;\n/**\n * The one canonical `{param}` grammar. Extraction, substitution, the config\n * gate and `doctor`'s probe all go through it.\n *\n * `-` and `.` are admitted: `/report/{report-id}` is ordinary\n * REST, and under the previous `[a-zA-Z0-9_]+` class it matched *nothing*. It\n * was therefore invisible to the config gate, survived substitution as a\n * literal, and a paid resource settled the buyer's payment before sending\n * `/report/%7Breport-id%7D` to a backend that 404s — the earlier money bug,\n * reachable again through the character class rather than through the check.\n */\nconst PATH_PARAM_PATTERN = /\\{([a-zA-Z0-9_.-]+)\\}/g;\n/** A hostile or broken backend can otherwise materialise an arbitrarily\n * large response in memory — AbortSignal.timeout bounds it by *time*, not\n * bytes. 1 MB is generous for a JSON API response. */\nconst MAX_RESPONSE_BODY_BYTES = 1024 * 1024;\n\nexport interface HttpBackendExecutorOptions {\n /** Override for `fetch`, used in tests. Defaults to the global implementation. */\n readonly fetchImpl?: typeof fetch;\n /** A non-2xx backend body is logged here (debug), never shipped to the client. */\n readonly logger?: Logger;\n}\n\nexport class HttpBackendExecutor implements BackendExecutor {\n private readonly fetchImpl: typeof fetch;\n private readonly logger: Logger;\n\n constructor(options: HttpBackendExecutorOptions = {}) {\n this.fetchImpl = options.fetchImpl ?? fetch;\n this.logger = options.logger ?? NOOP_LOGGER;\n }\n\n async call(handler: BackendHandler, request: BackendRequest): Promise<BackendResponse> {\n const timeoutMs = handler.timeoutMs ?? DEFAULT_BACKEND_TIMEOUT_MS;\n const inputRecord = isPlainObject(request.input) ? request.input : {};\n\n let target: URL;\n let remaining: Record<string, unknown>;\n try {\n const templated = applyPathTemplate(handler.url, inputRecord);\n target = new URL(templated.url);\n remaining = templated.remaining;\n } catch (error) {\n if (error instanceof Error && error.message.startsWith('invalid-path-parameter:')) {\n const field = error.message.slice('invalid-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" is not a valid value`, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { field },\n });\n }\n // Mirrors validateBackendRequestShape()'s own copy\n // — the pipeline calls that one first, so this branch is defence in\n // depth for a caller that bypasses it, not the normal path.\n if (error instanceof Error && error.message.startsWith('missing-path-parameter:')) {\n const field = error.message.slice('missing-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" was not supplied`, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { field },\n });\n }\n throw new CommerceError('BACKEND_ERROR', 'Backend URL could not be constructed from input', {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { reason: describeConstructionError(error) },\n cause: error,\n });\n }\n\n // Belt-and-braces beyond the per-parameter check above: whatever the\n // templated path resolved to must still live under the template's own\n // literal (pre-`{param}`) prefix. Templating something other than a path\n // segment (e.g. the host) is not a documented usage; if the literal\n // prefix does not even parse as a URL, skip this extra check rather than\n // fail a request the per-parameter check already covers.\n const literalPrefix = handler.url.split('{')[0] ?? handler.url;\n try {\n const literalPrefixPathname = new URL(literalPrefix).pathname;\n if (!target.pathname.startsWith(literalPrefixPathname)) {\n throw new CommerceError(\n 'INPUT_INVALID',\n 'Path parameters resolved outside the configured backend path',\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n },\n );\n }\n } catch (error) {\n if (error instanceof CommerceError) throw error;\n }\n\n const headers: Record<string, string> = { ...(handler.headers ?? {}) };\n let body: string | undefined;\n\n if (handler.method === 'GET' || handler.method === 'DELETE') {\n //.set() REPLACES an existing param, so without this check a caller\n // input key with the same name as an operator-baked-in query param\n // (?apikey=SECRET in handler.url) silently overwrites it.\n // Shared with validateBackendRequestShape() — that copy runs\n // *before* payment, this one is defence in depth.\n checkQueryCollision(target, remaining, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n });\n for (const [key, value] of Object.entries(remaining)) {\n target.searchParams.set(key, stringifyPrimitive(value));\n }\n } else {\n body = JSON.stringify(remaining);\n if (!hasHeader(headers, 'content-type')) {\n headers['content-type'] = 'application/json';\n }\n }\n\n const started = performance.now();\n let response: Response;\n try {\n response = await this.fetchImpl(target, {\n method: handler.method,\n headers,\n ...(body !== undefined ? { body } : {}),\n redirect: 'manual',\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n const durationMs = Math.round(performance.now() - started);\n if (isAbortError(error)) {\n throw new CommerceError(\n 'BACKEND_TIMEOUT',\n `Backend request timed out after ${timeoutMs}ms`,\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { timeoutMs, durationMs },\n cause: error,\n },\n );\n }\n throw new CommerceError('BACKEND_ERROR', 'Backend request failed (transport error)', {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { durationMs },\n cause: error,\n });\n }\n const durationMs = Math.round(performance.now() - started);\n\n const isRedirect =\n response.type === 'opaqueredirect' || (response.status >= 300 && response.status < 400);\n if (isRedirect) {\n throw new CommerceError(\n 'BACKEND_ERROR',\n 'Backend responded with a redirect, which is not followed',\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { status: response.status, reason: 'redirect-not-followed' },\n },\n );\n }\n\n const responseHeaders = headersToRecord(response.headers);\n const contentType = response.headers.get('content-type') ?? '';\n let parsedBody: unknown;\n try {\n parsedBody = await parseBody(response, contentType);\n } catch (error) {\n const tooLarge =\n error instanceof Error && error.message.startsWith('response-body-too-large');\n throw new CommerceError(\n 'BACKEND_ERROR',\n tooLarge\n ? 'Backend response exceeded the maximum allowed size'\n : 'Backend response could not be read',\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: tooLarge\n ? { reason: 'response-too-large', maxBytes: MAX_RESPONSE_BODY_BYTES }\n : { reason: 'read-error' },\n cause: error,\n },\n );\n }\n\n if (response.status < 200 || response.status >= 300) {\n // The backend status is ours to state; the backend's own response body\n // is not — a merchant backend in verbose/dev-error mode routinely\n // emits stack traces, hostnames or SQL fragments, and this gateway is\n // not the one who gets to decide those are safe to forward to whoever\n // called the (possibly free, possibly unauthenticated) resource. Log\n // it for the operator; never put it in a client-visible field.\n this.logger.debug(\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n status: response.status,\n bodySnippet: truncateSnippet(parsedBody),\n },\n 'Backend responded with a non-2xx status',\n );\n throw new CommerceError('BACKEND_ERROR', `Backend responded with status ${response.status}`, {\n requestId: request.requestId,\n resourceId: request.resourceId,\n details: { status: response.status },\n });\n }\n\n return {\n status: response.status,\n headers: responseHeaders,\n body: parsedBody,\n durationMs,\n };\n }\n}\n\n/**\n * The traversal and query-collision checks below must run before payment,\n * not only inside `call()` — pipeline step 6, which is *after*\n * verify -> reserve -> settle.\n * Both throw INPUT_INVALID, which schema validation (step 2) cannot catch\n * (it validates against `resource.inputSchema`, which knows nothing about\n * the URL template a bad value would collide with). Concretely: a paid,\n * path-templated resource called with `{ city: \"\" }` would settle the buyer's\n * payment on-chain and then never call the backend — payment without\n * delivery, no refund, no release of the reserved authorisation. Both\n * checks are pure functions of `(handler.url, input)` with no I/O, so the\n * pipeline calls this immediately after schema validation, *before* price\n * resolution — before any payment provider is even selected. `call()` keeps\n * its own copy as defence in depth (it is a public class; the pipeline is\n * not the only possible caller).\n */\n/**\n * `{param}` names in a `backend.url` template, in declaration order.\n * Exported so `src/config`'s `normaliseResource` can\n * cross-check every template parameter against the resource's input schema\n * at config load — the same regex, not a second copy that could silently\n * drift out of sync with what this file actually treats as a path\n * parameter.\n */\nexport function extractPathParameterNames(url: string): string[] {\n return [...url.matchAll(PATH_PARAM_PATTERN)].map((match) => match[1] as string);\n}\n\n/**\n * A brace left over after every legal `{param}` is removed, or `undefined`.\n *\n * Widening the grammar fixes the *common* spelling; it cannot fix every one.\n * `{report id}`, `{a/b}`, `{}` and an unbalanced `{` still match nothing, and\n * \"matches nothing\" is precisely the silent-literal shape that costs a buyer\n * money on a paid resource. So the rule is inverted: rather than enumerating\n * what is illegal, anything brace-shaped that is *not* a recognised parameter\n * is refused at config load. Exported so `src/config` applies it — the\n * grammar and its residue must never live in two files.\n */\nexport function findUnparsedBraceToken(url: string): string | undefined {\n const residue = url.replace(PATH_PARAM_PATTERN, '');\n const index = residue.search(/[{}]/);\n if (index === -1) return undefined;\n // Report the offending run, not just the character, so the error is fixable.\n const token = /\\{[^{}]*\\}?|\\}/.exec(residue.slice(index));\n return token?.[0] ?? residue[index];\n}\n\nexport function validateBackendRequestShape(\n handler: BackendHandler,\n input: unknown,\n context: { readonly requestId: string; readonly resourceId: string },\n): void {\n const inputRecord = isPlainObject(input) ? input : {};\n\n let templated: { url: string; remaining: Record<string, unknown> };\n try {\n templated = applyPathTemplate(handler.url, inputRecord);\n } catch (error) {\n if (error instanceof Error && error.message.startsWith('invalid-path-parameter:')) {\n const field = error.message.slice('invalid-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" is not a valid value`, {\n requestId: context.requestId,\n resourceId: context.resourceId,\n details: { field },\n });\n }\n if (error instanceof Error && error.message.startsWith('missing-path-parameter:')) {\n // Returning here is tempting: a missing path parameter is a\n // config/schema mismatch, not caller input, and so arguably not this\n // function's job. But that lets a paid, `{param}`-templated resource\n // whose schema can never supply it reach settle() on every call — the buyer pays, the backend is never\n // called, and there is no refund. The request genuinely cannot be\n // served, so it throws here, before payment, the same as an invalid\n // value does two lines up. `normaliseResource` (src/config) is\n // the root-cause fix — it rejects this shape at config load — but a\n // hand-built `CommerceResource` or a future adapter must not be able\n // to reintroduce the money bug just by skipping config validation.\n const field = error.message.slice('missing-path-parameter:'.length);\n throw new CommerceError('INPUT_INVALID', `Path parameter \"${field}\" was not supplied`, {\n requestId: context.requestId,\n resourceId: context.resourceId,\n details: { field },\n });\n }\n return;\n }\n\n if (handler.method === 'GET' || handler.method === 'DELETE') {\n let target: URL;\n try {\n target = new URL(templated.url);\n } catch {\n return; // call() surfaces the real BACKEND_ERROR for an unparseable URL.\n }\n checkQueryCollision(target, templated.remaining, context);\n }\n}\n\nfunction checkQueryCollision(\n target: URL,\n remaining: Record<string, unknown>,\n context: { readonly requestId: string; readonly resourceId: string },\n): void {\n const templateKeys = new Set(target.searchParams.keys());\n for (const key of Object.keys(remaining)) {\n if (templateKeys.has(key)) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `Input key \"${key}\" collides with a query parameter already set on backend.url`,\n { requestId: context.requestId, resourceId: context.resourceId, details: { field: key } },\n );\n }\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n// encodeURIComponent does not escape \".\" — a raw \"..\"/\".\" path-parameter\n// value survives it and new URL() then normalises the segment away, letting\n// a caller step outside the template's own directory (bounded traversal:\n// slashes ARE escaped, so only removing segments, never adding them). Reject\n// these exact values at substitution time instead of shipping them.\nconst TRAVERSAL_PATH_VALUES = new Set(['', '.', '..']);\n\nfunction applyPathTemplate(\n template: string,\n input: Record<string, unknown>,\n): { url: string; remaining: Record<string, unknown> } {\n const remaining: Record<string, unknown> = { ...input };\n let missing: string | undefined;\n let invalid: string | undefined;\n const url = template.replace(PATH_PARAM_PATTERN, (_match, key: string) => {\n // Object.hasOwn, not `key in remaining`: `in` also matches inherited\n // Object.prototype names (\"constructor\", \"toString\", …), which a\n // config-authored template naming a path param after one of them would\n // otherwise silently resolve to the wrong (inherited) value.\n if (!Object.hasOwn(remaining, key)) {\n missing = key;\n return '';\n }\n const value = remaining[key];\n delete remaining[key];\n const raw = stringifyPrimitive(value);\n if (TRAVERSAL_PATH_VALUES.has(raw)) {\n invalid = key;\n return '';\n }\n return encodeURIComponent(raw);\n });\n if (missing !== undefined) {\n throw new Error(`missing-path-parameter:${missing}`);\n }\n if (invalid !== undefined) {\n throw new Error(`invalid-path-parameter:${invalid}`);\n }\n return { url, remaining };\n}\n\nfunction describeConstructionError(error: unknown): string {\n if (error instanceof Error && error.message.startsWith('missing-path-parameter:')) {\n return error.message;\n }\n return 'invalid-url';\n}\n\nfunction stringifyPrimitive(value: unknown): string {\n if (value === undefined || value === null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction hasHeader(headers: Record<string, string>, name: string): boolean {\n const target = name.toLowerCase();\n return Object.keys(headers).some((key) => key.toLowerCase() === target);\n}\n\nfunction headersToRecord(headers: Headers): Record<string, string> {\n const record: Record<string, string> = {};\n headers.forEach((value, key) => {\n record[key] = value;\n });\n return record;\n}\n\nasync function readBodyCapped(response: Response, maxBytes: number): Promise<string> {\n if (!response.body) return '';\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n total += value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new Error(`response-body-too-large:${maxBytes}`);\n }\n chunks.push(value);\n }\n } finally {\n reader.releaseLock();\n }\n return Buffer.concat(chunks).toString('utf8');\n}\n\nasync function parseBody(response: Response, contentType: string): Promise<unknown> {\n const text = await readBodyCapped(response, MAX_RESPONSE_BODY_BYTES);\n if (text.length === 0) return text;\n if (contentType.includes('json')) {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n }\n return text;\n}\n\nfunction truncateSnippet(body: unknown): string {\n const text = typeof body === 'string' ? body : safeStringify(body);\n return text.length > MAX_BODY_SNIPPET_LENGTH\n ? `${text.slice(0, MAX_BODY_SNIPPET_LENGTH)}…`\n : text;\n}\n\nfunction safeStringify(value: unknown): string {\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && (error.name === 'TimeoutError' || error.name === 'AbortError');\n}\n","/**\n * Fan-out `EventSink`: persists every event to the receipt store and notifies\n * in-process subscribers (the gateway's SSE feed). Never throws to the caller —\n * a store or subscriber failure is caught and logged.\n */\nimport type { CommerceEvent, EventSink } from '../domain/event.js';\nimport type { Logger } from '../interfaces/logger.js';\nimport type { Clock, IdGenerator } from '../interfaces/runtime.js';\nimport type { ReceiptStore } from '../interfaces/store.js';\n\nexport interface CreateEventBusOptions {\n readonly store: ReceiptStore;\n readonly logger: Logger;\n /** Reserved for callers that want the bus to mint ids/timestamps itself. */\n readonly ids?: IdGenerator;\n readonly clock?: Clock;\n}\n\nexport interface EventBus extends EventSink {\n /** Subscribe to every emitted event. Returns an unsubscribe function. */\n subscribe(fn: (event: CommerceEvent) => void): () => void;\n}\n\nexport function createEventBus(options: CreateEventBusOptions): EventBus {\n const subscribers = new Set<(event: CommerceEvent) => void>();\n\n return {\n async emit(event: CommerceEvent): Promise<void> {\n try {\n await options.store.appendEvent(event);\n } catch (error) {\n options.logger.error(\n { err: describeError(error), eventType: event.type, requestId: event.requestId },\n 'Failed to persist commerce event',\n );\n }\n\n for (const subscriber of subscribers) {\n try {\n subscriber(event);\n } catch (error) {\n options.logger.error(\n { err: describeError(error), eventType: event.type, requestId: event.requestId },\n 'Event subscriber threw',\n );\n }\n }\n },\n\n subscribe(fn: (event: CommerceEvent) => void): () => void {\n subscribers.add(fn);\n return () => {\n subscribers.delete(fn);\n };\n },\n };\n}\n\nfunction describeError(error: unknown): { message: string; name?: string } {\n if (error instanceof Error) {\n return { message: error.message, name: error.name };\n }\n return { message: String(error) };\n}\n","/**\n * Gateway-defined wire envelopes.\n *\n * FROZEN CONTRACT. These are the *only* representations of \"payment required\"\n * and \"error\" that leave the gateway, whichever protocol carries them. The HTTP\n * routes, the MCP adapter and the demo buyer agent all use these helpers so the\n * three can never drift apart.\n */\n\nimport type { CommerceError, CommerceErrorCode } from '../errors/index.js';\nimport type { DecimalAmount, IsoTimestamp, PaymentMethodName } from './common.js';\nimport type { DeliveredOutcome, PaymentRequiredOutcome } from './request.js';\n\n/**\n * Reserved input property carrying a payment proof on protocols that have no\n * header channel (MCP tool calls). Over HTTP the `PAYMENT-SIGNATURE` header is\n * used.\n */\nexport const PAYMENT_INPUT_FIELD = '_payment';\n\n/**\n * HTTP request header carrying the payment proof.\n *\n * x402 v2 header names, lowercased because that is how Node presents incoming\n * headers. v1's `X-PAYMENT` / `X-PAYMENT-RESPONSE` pair is not accepted: this\n * gateway speaks one protocol version, and quietly honouring both would mean\n * two verification paths for the same money.\n */\nexport const PAYMENT_HEADER = 'payment-signature';\n\n/** HTTP response header carrying the settlement result. */\nexport const PAYMENT_RESPONSE_HEADER = 'payment-response';\n\n/**\n * HTTP response header carrying the base64 payment challenge on a 402.\n *\n * The 402 body still carries {@link PaymentRequiredEnvelope} — richer, and the\n * only channel MCP has — but an x402 v2 client reads the challenge from this\n * header and ignores the body, so both are sent.\n */\nexport const PAYMENT_REQUIRED_HEADER = 'payment-required';\n\n/**\n * Key under which a protocol adapter attaches a {@link DeliverySummary} to its\n * result metadata — MCP's `CallToolResult._meta`, and anywhere else a protocol\n * offers an out-of-band metadata channel.\n *\n * Frozen deliberately. The bug this whole mechanism exists to fix was two\n * surfaces disagreeing about what a payer gets back; a key name enforced only\n * by one side's tests would reintroduce exactly that drift. Producer and\n * consumer both import this constant.\n *\n * Follows MCP's `<namespace>/<name>` convention for `_meta` keys.\n */\nexport const DELIVERY_SUMMARY_META_KEY = 'agent-commerce/delivery';\n\nexport interface PaymentRequiredEnvelope {\n readonly status: 'payment-required';\n readonly code: 'PAYMENT_REQUIRED';\n readonly requestId: string;\n readonly resourceId: string;\n readonly message: string;\n readonly payment: {\n readonly provider: PaymentMethodName;\n readonly version: string;\n readonly amount: DecimalAmount;\n readonly currency: string;\n readonly destination: string;\n readonly network?: string;\n readonly asset?: string;\n readonly expiresAt?: IsoTimestamp;\n /** Provider-native requirement objects, passed through verbatim. */\n readonly accepts: readonly Readonly<Record<string, unknown>>[];\n /**\n * The provider's own challenge document, verbatim — see\n * {@link PaymentChallenge.envelope}. Present for providers that have one;\n * a buyer's protocol client can hand this straight to its SDK.\n */\n readonly envelope?: Readonly<Record<string, unknown>>;\n };\n}\n\nexport interface ErrorEnvelope {\n readonly status: 'error';\n readonly code: CommerceErrorCode;\n readonly message: string;\n readonly retryable: boolean;\n readonly requestId?: string;\n readonly resourceId?: string;\n readonly details?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * What a buyer learns about their own completed purchase.\n *\n * A payer is entitled to the record of their own transaction — the request it\n * belonged to, whether it settled, and the settlement reference they can check\n * on-chain. They are NOT entitled to the merchant's ledger, which is why\n * `/api/receipts` is an operator route behind `server.adminToken`.\n *\n * Before this existed the two surfaces disagreed: HTTP callers received a\n * settlement summary in the payment-response header while MCP callers received\n * nothing, so an MCP buyer's only route to their own receipt was the merchant's\n * ledger. Both surfaces now emit this same shape.\n */\nexport interface DeliverySummary {\n readonly requestId: string;\n readonly resourceId: string;\n readonly receiptId: string;\n readonly deliveredAt: IsoTimestamp;\n readonly payment?: {\n readonly status: 'verified' | 'settled' | 'rejected';\n readonly amount: DecimalAmount;\n readonly currency: string;\n /** Settlement reference, e.g. an on-chain transaction hash. */\n readonly externalReference?: string;\n readonly network?: string;\n };\n}\n\n/** Build the payer-facing summary of a delivered outcome. */\nexport function toDeliverySummary(outcome: DeliveredOutcome): DeliverySummary {\n const p = outcome.payment;\n return {\n requestId: outcome.requestId,\n resourceId: outcome.resourceId,\n receiptId: outcome.receipt.id,\n deliveredAt: outcome.receipt.deliveredAt,\n ...(p !== undefined\n ? {\n payment: {\n status: p.status,\n amount: p.amount,\n currency: p.currency,\n ...(p.externalReference !== undefined\n ? { externalReference: p.externalReference }\n : {}),\n ...(p.network !== undefined ? { network: p.network } : {}),\n },\n }\n : {}),\n };\n}\n\nexport function toPaymentRequiredEnvelope(\n outcome: PaymentRequiredOutcome,\n): PaymentRequiredEnvelope {\n const r = outcome.requirement;\n return {\n status: 'payment-required',\n code: 'PAYMENT_REQUIRED',\n requestId: outcome.requestId,\n resourceId: outcome.resourceId,\n message: `Payment of ${r.amount} ${r.currency} is required for resource \"${outcome.resourceId}\". Retry with a ${r.provider} payment proof.`,\n payment: {\n provider: r.provider,\n version: r.challenge.version,\n amount: r.amount,\n currency: r.currency,\n destination: r.destination,\n ...(r.network !== undefined ? { network: r.network } : {}),\n ...(r.asset !== undefined ? { asset: r.asset } : {}),\n ...(r.expiresAt !== undefined ? { expiresAt: r.expiresAt } : {}),\n accepts: r.challenge.accepts,\n ...(r.challenge.envelope !== undefined ? { envelope: r.challenge.envelope } : {}),\n },\n };\n}\n\nexport function toErrorEnvelope(error: CommerceError): ErrorEnvelope {\n const info = error.toInfo();\n return {\n status: 'error',\n code: info.code,\n message: info.message,\n retryable: info.retryable,\n ...(info.requestId !== undefined ? { requestId: info.requestId } : {}),\n ...(info.resourceId !== undefined ? { resourceId: info.resourceId } : {}),\n ...(info.details !== undefined ? { details: info.details } : {}),\n };\n}\n\nexport function isPaymentRequiredEnvelope(value: unknown): value is PaymentRequiredEnvelope {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as PaymentRequiredEnvelope).status === 'payment-required' &&\n typeof (value as PaymentRequiredEnvelope).payment === 'object'\n );\n}\n","/**\n * A small, honest JSON Schema validator for resource input.\n *\n * Supported subset (draft-2020-12 vocabulary, structural only):\n * - `type`: \"object\" | \"string\" | \"number\" | \"integer\" | \"boolean\" | \"array\" | \"null\",\n * or an array of any of those (draft-2020-12 union form, e.g. `[\"object\",\"null\"]`)\n * - `properties` (object schemas, validated recursively)\n * - `required` (string[])\n * - `additionalProperties` (boolean, or a schema applied to extra properties)\n * - `enum` (array of allowed literal values, deep-equality compared)\n * - `items` (single schema applied to every array element — no tuple form)\n *\n * Explicitly NOT supported and silently ignored (never enforced):\n * `minLength`, `maxLength`, `pattern`, `format`, `minimum`, `maximum`,\n * `exclusiveMinimum/Maximum`, `multipleOf`, `oneOf`, `anyOf`, `allOf`, `not`,\n * `$ref`, `const`, `patternProperties`, `minItems`, `maxItems`, `uniqueItems`,\n * tuple-style `items` arrays. An unrecognised `type` value is not enforced\n * either. This is a deliberate, documented limitation of this release — do\n * not assume any of the above is validated.\n */\nimport type { JsonSchema } from '../domain/common.js';\n\nexport interface FieldError {\n readonly path: string;\n readonly message: string;\n}\n\nexport type ValidationResult =\n | { readonly valid: true; readonly value: unknown }\n | { readonly valid: false; readonly errors: readonly FieldError[] };\n\nexport type Validator = (input: unknown) => ValidationResult;\n\nconst SUPPORTED_TYPES = new Set([\n 'object',\n 'string',\n 'number',\n 'integer',\n 'boolean',\n 'array',\n 'null',\n]);\n\n/** Compile a resource `inputSchema` into a reusable validator function. */\nexport function compileJsonSchema(schema: JsonSchema | undefined): Validator {\n return (input: unknown): ValidationResult => {\n if (schema === undefined) return { valid: true, value: input };\n const errors = validateNode(schema, input, '$');\n return errors.length === 0 ? { valid: true, value: input } : { valid: false, errors };\n };\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction matchesType(type: string, value: unknown): boolean {\n switch (type) {\n case 'object':\n return isPlainObject(value);\n case 'array':\n return Array.isArray(value);\n case 'string':\n return typeof value === 'string';\n case 'boolean':\n return typeof value === 'boolean';\n case 'number':\n return typeof value === 'number' && Number.isFinite(value);\n case 'integer':\n return typeof value === 'number' && Number.isInteger(value);\n case 'null':\n return value === null;\n default:\n return true;\n }\n}\n\nfunction describeType(value: unknown): string {\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (a === null || b === null) return false;\n if (typeof a !== 'object') return false;\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch {\n return false;\n }\n}\n\nfunction own(obj: Record<string, unknown>, key: string): unknown {\n return Object.hasOwn(obj, key) ? obj[key] : undefined;\n}\n\n/**\n * `type` may be a single string or (draft-2020-12) an array of strings,\n * e.g. `[\"object\", \"null\"]`. Only recognised when every entry is a string —\n * same conservative \"skip rather than guess\" rule the single-string form\n * already followed for an unrecognised type name.\n */\nfunction typeList(raw: unknown): string[] | undefined {\n if (typeof raw === 'string') return [raw];\n if (Array.isArray(raw) && raw.every((entry): entry is string => typeof entry === 'string')) {\n return raw;\n }\n return undefined;\n}\n\n/**\n * A bare `type === 'object'` string comparison is not enough: `type:\n * [\"object\", \"null\"]` — valid JSON Schema — would never route into\n * `validateObject`, so neither `required` nor `additionalProperties` would be\n * enforced on it, while `defaultClosedObjectSchema` (src/config) stamps\n * `additionalProperties: false` on it believing it closed. Also treats a node\n * with `properties`/`required` and no `type`\n * at all as an object schema, the same shape config's own stamping already\n * recognises via a bare `properties` check — a schema author relying on\n * `type` being implied by `properties` should not be silently unenforced.\n *\n * **exported**, and now the only definition of \"this node is\n * an object schema\" in the codebase. `src/config`'s `defaultClosedObjectSchema`\n * carried its own — `declaresObjectType || properties` — one keyword short of\n * this one, so a schema declaring only `required` was stamped by neither:\n * config left it open and this validator then enforced nothing on it, quietly\n * forwarding every unknown caller key to the merchant's backend while\n * docs/security.md promised \"closed by default at every level\". These two\n * definitions have been aligned once already; keeping them as two definitions\n * is what let them drift again.\n */\nexport function isObjectSchemaNode(schema: Record<string, unknown>): boolean {\n const types = typeList(schema['type']);\n if (types !== undefined) return types.includes('object');\n return Object.hasOwn(schema, 'properties') || Object.hasOwn(schema, 'required');\n}\n\nfunction validateNode(schema: JsonSchema, value: unknown, path: string): FieldError[] {\n const errors: FieldError[] = [];\n const types = typeList(own(schema, 'type'));\n const recognisedTypes = types?.filter((entry) => SUPPORTED_TYPES.has(entry));\n\n if (\n types !== undefined &&\n recognisedTypes !== undefined &&\n recognisedTypes.length === types.length &&\n types.length > 0\n ) {\n if (!types.some((entry) => matchesType(entry, value))) {\n errors.push({\n path,\n message: `expected type \"${types.join(' | ')}\" but got ${describeType(value)}`,\n });\n return errors;\n }\n }\n\n const enumRaw = own(schema, 'enum');\n if (Array.isArray(enumRaw)) {\n const allowed = enumRaw as unknown[];\n if (!allowed.some((candidate) => deepEqual(candidate, value))) {\n errors.push({ path, message: `must be one of ${JSON.stringify(allowed)}` });\n }\n }\n\n if (isObjectSchemaNode(schema) && isPlainObject(value)) {\n errors.push(...validateObject(schema, value, path));\n } else if ((types?.includes('array') ?? false) && Array.isArray(value)) {\n errors.push(...validateArray(schema, value, path));\n }\n\n return errors;\n}\n\nfunction validateObject(\n schema: JsonSchema,\n value: Record<string, unknown>,\n path: string,\n): FieldError[] {\n const errors: FieldError[] = [];\n const propsRaw = own(schema, 'properties');\n const properties = isPlainObject(propsRaw) ? propsRaw : {};\n const requiredRaw = own(schema, 'required');\n const required = Array.isArray(requiredRaw)\n ? requiredRaw.filter((entry): entry is string => typeof entry === 'string')\n : [];\n\n for (const key of required) {\n // Object.hasOwn, not `in`: `in` walks the prototype chain, so a schema\n // requiring \"toString\"/\"constructor\"/\"valueOf\"/\"hasOwnProperty\"/\n // \"__proto__\" could never actually enforce it — those names are always\n // present via inheritance, so `!(key in value)` is always false. This is\n // the same bug class every other lookup in this file already\n // guards against by using own().\n if (!Object.hasOwn(value, key)) {\n errors.push({ path: `${path}.${key}`, message: 'is required' });\n }\n }\n\n const additional = own(schema, 'additionalProperties');\n\n for (const key of Object.keys(value)) {\n // Object.hasOwn, not `properties[key]`: a plain-object lookup for\n // \"__proto__\"/\"constructor\"/\"toString\"/\"valueOf\"/\"hasOwnProperty\" resolves\n // to an inherited Object.prototype member instead of undefined, so those\n // keys would otherwise silently skip the additionalProperties check below.\n const propSchemaRaw = own(properties, key);\n if (propSchemaRaw !== undefined) {\n if (isPlainObject(propSchemaRaw)) {\n errors.push(...validateNode(propSchemaRaw, value[key], `${path}.${key}`));\n }\n continue;\n }\n if (additional === false) {\n errors.push({ path: `${path}.${key}`, message: 'additional property not allowed' });\n } else if (isPlainObject(additional)) {\n errors.push(...validateNode(additional, value[key], `${path}.${key}`));\n }\n }\n\n return errors;\n}\n\nfunction validateArray(schema: JsonSchema, value: unknown[], path: string): FieldError[] {\n const errors: FieldError[] = [];\n const itemsRaw = own(schema, 'items');\n if (isPlainObject(itemsRaw)) {\n value.forEach((item, index) => {\n errors.push(...validateNode(itemsRaw, item, `${path}[${index}]`));\n });\n }\n return errors;\n}\n","/**\n * The single execution path every protocol adapter converges on.\n *\n * Order is a security boundary — do not reorder:\n * 1. resolve resource RESOURCE_NOT_FOUND\n * 2. strip `_payment`, validate input INPUT_INVALID\n * 3. resolve price\n * 4. free -> straight to backend\n * 5. paid -> pick provider -> createRequirement -> (challenge | verify ->\n * reserve replay key -> settle), fail closed at every step\n * 6. call backend BACKEND_TIMEOUT / BACKEND_ERROR\n * 7. persist receipt, emit events, return outcome\n */\n\nimport type { PaymentMethodName } from '../domain/common.js';\nimport type { CommerceEvent, EventSink } from '../domain/event.js';\nimport type { PaymentProvider, PaymentRequirement, PaymentResult } from '../domain/payment.js';\nimport type { CommerceReceipt } from '../domain/receipt.js';\nimport type { CanonicalRequest, ExecutionOutcome, ExecutionPipeline } from '../domain/request.js';\nimport type { CommerceResource, ResourceRegistry } from '../domain/resource.js';\nimport { PAYMENT_INPUT_FIELD } from '../domain/wire.js';\nimport { CommerceError, isCommerceError, toCommerceError } from '../errors/index.js';\nimport type { BackendExecutor, BackendResponse } from '../interfaces/backend.js';\nimport type { Logger } from '../interfaces/logger.js';\nimport type { Clock, IdGenerator } from '../interfaces/runtime.js';\nimport type { ReceiptStore } from '../interfaces/store.js';\nimport { validateBackendRequestShape } from './backend-http.js';\nimport { compileJsonSchema, type Validator } from './validation.js';\n\nexport interface CreateExecutionPipelineOptions {\n readonly resources: ResourceRegistry;\n readonly paymentProviders: readonly PaymentProvider[];\n readonly store: ReceiptStore;\n readonly backend: BackendExecutor;\n readonly events: EventSink;\n readonly logger: Logger;\n readonly clock: Clock;\n readonly ids: IdGenerator;\n}\n\nexport function createExecutionPipeline(\n options: CreateExecutionPipelineOptions,\n): ExecutionPipeline {\n const validators = new Map<string, Validator>();\n\n function getValidator(resource: CommerceResource): Validator {\n const cached = validators.get(resource.id);\n if (cached) return cached;\n const compiled = compileJsonSchema(resource.inputSchema);\n validators.set(resource.id, compiled);\n return compiled;\n }\n\n async function safeEmit(event: CommerceEvent): Promise<void> {\n try {\n await options.events.emit(event);\n } catch (error) {\n options.logger.error(\n { err: describeError(error), eventType: event.type, requestId: event.requestId },\n 'Event sink failed; commerce flow continues',\n );\n }\n }\n\n async function safePersist(\n op: () => Promise<void>,\n label: string,\n requestId: string,\n ): Promise<void> {\n try {\n await op();\n } catch (error) {\n options.logger.error(\n { err: describeError(error), requestId },\n `Persistence failed: ${label}`,\n );\n }\n }\n\n function buildEvent(partial: Omit<CommerceEvent, 'id' | 'at'>): CommerceEvent {\n return { id: options.ids.next('evt'), at: options.clock.nowIso(), ...partial };\n }\n\n async function execute(request: CanonicalRequest): Promise<ExecutionOutcome> {\n const pipelineStart = options.clock.monotonicMs();\n\n // 1. resolve resource\n const resource = options.resources.get(request.resourceId);\n // Same code, same message as a genuine miss: `expose` is an admin scoping\n // decision enforced on the one execution path every adapter shares — a\n // caller on a protocol the resource isn't exposed via must not be able to\n // distinguish \"doesn't exist\" from \"exists but not for you\".\n if (!resource || !resource.exposedVia.includes(request.protocol)) {\n throw new CommerceError(\n 'RESOURCE_NOT_FOUND',\n `Resource \"${request.resourceId}\" was not found`,\n {\n requestId: request.requestId,\n resourceId: request.resourceId,\n },\n );\n }\n\n await safeEmit(\n buildEvent({\n type: 'resource.requested',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n }),\n );\n\n // 2. strip reserved payment field, then validate input\n const strippedInput = stripPaymentField(request.input);\n const validation = getValidator(resource)(strippedInput);\n if (!validation.valid) {\n throw new CommerceError(\n 'INPUT_INVALID',\n `Input for resource \"${resource.id}\" failed validation`,\n {\n requestId: request.requestId,\n resourceId: resource.id,\n details: { errors: validation.errors },\n },\n );\n }\n const validInput = validation.value;\n\n // validate the backend request shape (path-traversal, query-param\n // collision) here — before price resolution, so a resource that fails\n // this check never reaches payment. Both checks are pure functions of\n // (handler.url, input); doing them at pipeline step 6 (inside the actual\n // backend call) meant a bad value like `{ city: \"\" }` against a paid,\n // path-templated resource settled the buyer's payment and then never\n // called the backend at all — payment without delivery. call() keeps its\n // own copy of these checks as defence in depth.\n validateBackendRequestShape(resource.handler, validInput, {\n requestId: request.requestId,\n resourceId: resource.id,\n });\n\n // 3. resolve price\n if (resource.pricing.type === 'dynamic') {\n // Config validation rejects this before the gateway starts; this is defence-in-depth.\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${resource.id}\" uses unsupported dynamic pricing`,\n {\n requestId: request.requestId,\n resourceId: resource.id,\n },\n );\n }\n\n let paymentResult: PaymentResult | undefined;\n\n if (resource.pricing.type === 'fixed') {\n const pricing = resource.pricing;\n const provider = pickProvider(options.paymentProviders, resource.paymentMethods);\n if (!provider) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `No enabled payment provider for resource \"${resource.id}\"`,\n {\n requestId: request.requestId,\n resourceId: resource.id,\n details: { paymentMethods: resource.paymentMethods },\n },\n );\n }\n\n let requirement: PaymentRequirement;\n try {\n requirement = await provider.createRequirement({\n requestId: request.requestId,\n resource,\n amount: pricing.amount,\n currency: pricing.currency,\n requestedAt: options.clock.nowIso(),\n });\n } catch (error) {\n throw isCommerceError(error)\n ? error\n : new CommerceError('PAYMENT_PROVIDER_UNAVAILABLE', 'Payment provider is unavailable', {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: error,\n });\n }\n\n if (!request.payment) {\n await safeEmit(\n buildEvent({\n type: 'payment.required',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n }),\n );\n return {\n kind: 'payment-required',\n requestId: request.requestId,\n resourceId: resource.id,\n requirement,\n };\n }\n\n const payment = request.payment;\n\n let verification: PaymentResult;\n try {\n verification = await provider.verify({\n requestId: request.requestId,\n resource,\n requirement,\n submission: payment,\n });\n } catch (error) {\n // Any typed CommerceError the provider throws is rethrown as-is (a\n // provider can legitimately fail with STORAGE_ERROR, etc. — flattening\n // every code to PAYMENT_INVALID would hide the real cause and the\n // real, possibly-retryable HTTP status). Only a genuinely untyped\n // throw is mapped, with a fixed client-facing message — never the\n // raw error's own message.\n const mapped = isCommerceError(error)\n ? error\n : new CommerceError('PAYMENT_INVALID', 'Payment verification failed', {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: error,\n });\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: { reason: mapped.code },\n }),\n );\n throw mapped;\n }\n\n if (verification.status !== 'verified') {\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: verification.rejectionReason ? { reason: verification.rejectionReason } : {},\n }),\n );\n throw new CommerceError(\n 'PAYMENT_INVALID',\n verification.rejectionReason ?? 'Payment was rejected',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n },\n );\n }\n\n if (!verification.replayKey) {\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: { reason: 'missing-replay-key' },\n }),\n );\n throw new CommerceError('PAYMENT_INVALID', 'Payment provider did not return a replay key', {\n requestId: request.requestId,\n resourceId: resource.id,\n });\n }\n const replayKey = verification.replayKey;\n\n try {\n await options.store.reservePaymentAttempt({\n requestId: request.requestId,\n resourceId: resource.id,\n provider: provider.name,\n replayKey,\n amount: verification.amount,\n currency: verification.currency,\n ...(verification.payer !== undefined ? { payer: verification.payer } : {}),\n ...(verification.payee !== undefined ? { payee: verification.payee } : {}),\n });\n } catch (error) {\n // The store contract only promises PAYMENT_REPLAYED for an actual\n // duplicate replayKey (already a CommerceError with that code, so\n // isCommerceError below preserves it as-is). Anything else — a disk-\n // full error, a dropped connection — is a storage failure, not a\n // replay, and must not be mislabelled as one: telling a buyer\n // \"duplicate payment\" for a transient outage is actively false, and\n // poisons any alerting keyed on replay counts.\n const mapped = toCommerceError(\n error,\n 'STORAGE_ERROR',\n 'Payment attempt could not be recorded',\n );\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: { reason: mapped.code },\n }),\n );\n throw mapped;\n }\n\n await safeEmit(\n buildEvent({\n type: 'payment.verified',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'ok',\n }),\n );\n\n let settlement: PaymentResult;\n try {\n settlement = await provider.settle({\n requestId: request.requestId,\n resource,\n requirement,\n submission: payment,\n verification,\n });\n } catch (error) {\n // / \"the RPC did not answer\" and \"the transfer did not\n // happen\" are different facts. A provider that broadcast a settlement\n // transaction and then failed to confirm it throws\n // PAYMENT_PROVIDER_UNAVAILABLE with details.transactionHash attached\n // (the hash is known before confirmation). Recording that as plain\n // `failed` would tell the merchant's reconciliation artefact a\n // falsehood — the buyer's funds may already have moved. The resource\n // is still not delivered either way: only what gets *recorded*\n // changes, never the fail-closed outcome.\n const uncertainTxHash = uncertainSettlementTxHash(error);\n await safePersist(\n () =>\n options.store.updatePaymentAttempt(\n uncertainTxHash !== undefined\n ? { replayKey, status: 'settlement-uncertain', externalReference: uncertainTxHash }\n : {\n replayKey,\n status: 'failed',\n ...(error instanceof Error ? { rejectionReason: error.message } : {}),\n },\n ),\n uncertainTxHash !== undefined\n ? 'updatePaymentAttempt(settlement-uncertain)'\n : 'updatePaymentAttempt(failed)',\n request.requestId,\n );\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data:\n uncertainTxHash !== undefined\n ? { reason: 'settlement-uncertain', transactionHash: uncertainTxHash }\n : { reason: 'settlement-threw' },\n }),\n );\n // The merchant's record now tells the truth (above); the buyer must\n // too — they are the party whose funds may have moved, and the\n // client-visible error is their only way to find out. Code stays\n // PAYMENT_SETTLEMENT_FAILED (not PAYMENT_PROVIDER_UNAVAILABLE, which\n // is retryable) — a retry would reuse the already-reserved replay\n // key. The transaction hash is safe to disclose: it's the buyer's\n // own payment, public on-chain the moment it lands. Nothing else\n // from the underlying error travels — only this flag and the hash.\n throw new CommerceError(\n 'PAYMENT_SETTLEMENT_FAILED',\n uncertainTxHash !== undefined\n ? 'Settlement could not be confirmed'\n : 'Payment settlement failed',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: error,\n ...(uncertainTxHash !== undefined\n ? { details: { settlementUncertain: true, transactionHash: uncertainTxHash } }\n : {}),\n },\n );\n }\n\n if (settlement.status !== 'settled') {\n await safePersist(\n () =>\n options.store.updatePaymentAttempt({\n replayKey,\n status: 'rejected',\n ...(settlement.rejectionReason !== undefined\n ? { rejectionReason: settlement.rejectionReason }\n : {}),\n }),\n 'updatePaymentAttempt(rejected)',\n request.requestId,\n );\n await safeEmit(\n buildEvent({\n type: 'payment.rejected',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'error',\n data: settlement.rejectionReason ? { reason: settlement.rejectionReason } : {},\n }),\n );\n throw new CommerceError(\n 'PAYMENT_SETTLEMENT_FAILED',\n settlement.rejectionReason ?? 'Settlement was rejected',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n },\n );\n }\n\n await safePersist(\n () =>\n options.store.updatePaymentAttempt({\n replayKey,\n status: 'settled',\n ...(settlement.externalReference !== undefined\n ? { externalReference: settlement.externalReference }\n : {}),\n }),\n 'updatePaymentAttempt(settled)',\n request.requestId,\n );\n await safeEmit(\n buildEvent({\n type: 'payment.settled',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n paymentProvider: provider.name,\n status: 'ok',\n }),\n );\n\n paymentResult = settlement;\n }\n\n // 6. call backend\n const backendStart = options.clock.monotonicMs();\n let backendResponse: BackendResponse;\n try {\n backendResponse = await options.backend.call(resource.handler, {\n requestId: request.requestId,\n resourceId: resource.id,\n input: validInput,\n });\n } catch (error) {\n const commerceError = toCommerceError(error, 'BACKEND_ERROR', 'Backend call failed');\n await safeEmit(\n buildEvent({\n type: 'backend.failed',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n status: 'error',\n durationMs: Math.round(options.clock.monotonicMs() - backendStart),\n data: { code: commerceError.code },\n }),\n );\n\n if (paymentResult !== undefined) {\n // Settlement already succeeded (verify -> reserve -> settle all\n // completed) before the backend call failed, so the\n // uncertain-settlement rule (\"the merchant's record now tells the\n // truth; the buyer must too\") applies to this far more common\n // *certain*-loss branch as well, not only to the uncertain-RPC-timeout\n // one 100 lines above. A backend 500 is more likely than an RPC\n // confirmation timeout, so disclosing strictly *less* here than there\n // would be backwards. The tx hash is\n // safe to disclose: it is the buyer's own payment, public\n // on-chain the moment it lands.\n const failedReceipt: CommerceReceipt = {\n id: options.ids.next('receipt'),\n requestId: request.requestId,\n resourceId: resource.id,\n deliveredAt: options.clock.nowIso(),\n backendStatus: backendErrorStatus(commerceError),\n protocol: request.protocol,\n payment: paymentResult,\n metadata: { delivered: false, backendErrorCode: commerceError.code },\n };\n await safePersist(\n () => options.store.saveReceipt(failedReceipt),\n 'saveReceipt(backend-failed-after-settlement)',\n request.requestId,\n );\n\n throw new CommerceError(\n 'BACKEND_ERROR',\n 'Payment settled but the backend call failed; the payment was not refunded automatically',\n {\n requestId: request.requestId,\n resourceId: resource.id,\n cause: commerceError,\n details: {\n payment: {\n status: paymentResult.status,\n provider: paymentResult.provider,\n amount: paymentResult.amount,\n currency: paymentResult.currency,\n ...(paymentResult.network !== undefined ? { network: paymentResult.network } : {}),\n ...(paymentResult.externalReference !== undefined\n ? { externalReference: paymentResult.externalReference }\n : {}),\n },\n },\n },\n );\n }\n\n throw commerceError;\n }\n\n await safeEmit(\n buildEvent({\n type: 'backend.called',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n status: 'ok',\n durationMs: backendResponse.durationMs,\n data: { status: backendResponse.status },\n }),\n );\n\n // 7. persist receipt, emit final event, return outcome\n const receipt: CommerceReceipt = {\n id: options.ids.next('receipt'),\n requestId: request.requestId,\n resourceId: resource.id,\n deliveredAt: options.clock.nowIso(),\n backendStatus: backendResponse.status,\n durationMs: backendResponse.durationMs,\n protocol: request.protocol,\n ...(paymentResult !== undefined ? { payment: paymentResult } : {}),\n };\n\n await safePersist(() => options.store.saveReceipt(receipt), 'saveReceipt', request.requestId);\n\n const totalDurationMs = Math.round(options.clock.monotonicMs() - pipelineStart);\n\n await safeEmit(\n buildEvent({\n type: 'resource.delivered',\n requestId: request.requestId,\n resourceId: resource.id,\n adapter: request.protocol,\n status: 'ok',\n durationMs: totalDurationMs,\n }),\n );\n\n return {\n kind: 'delivered',\n requestId: request.requestId,\n resourceId: resource.id,\n backendStatus: backendResponse.status,\n body: backendResponse.body,\n headers: backendResponse.headers,\n ...(paymentResult !== undefined ? { payment: paymentResult } : {}),\n receipt,\n durationMs: totalDurationMs,\n };\n }\n\n return { execute };\n}\n\n/** The HTTP status the backend actually returned, when known (backend-http.ts\n * attaches it as `details.status` for a non-2xx response). 0 means \"no\n * response was received at all\" (timeout/transport failure) — distinct from\n * any real HTTP status. */\nfunction backendErrorStatus(error: CommerceError): number {\n const status = error.details?.['status'];\n return typeof status === 'number' ? status : 0;\n}\n\nfunction uncertainSettlementTxHash(error: unknown): string | undefined {\n if (!isCommerceError(error) || error.code !== 'PAYMENT_PROVIDER_UNAVAILABLE') return undefined;\n const hash = error.details?.['transactionHash'];\n return typeof hash === 'string' ? hash : undefined;\n}\n\nfunction pickProvider(\n providers: readonly PaymentProvider[],\n methods: readonly PaymentMethodName[],\n): PaymentProvider | undefined {\n for (const method of methods) {\n const found = providers.find((provider) => provider.name === method);\n if (found) return found;\n }\n return undefined;\n}\n\nconst RESERVED_INPUT_KEYS = new Set([PAYMENT_INPUT_FIELD, '__proto__']);\n\nfunction stripPaymentField(input: unknown): unknown {\n if (typeof input !== 'object' || input === null || Array.isArray(input)) return input;\n const record = input as Record<string, unknown>;\n // Object.hasOwn: `in` would also match inherited names and strip things\n // that were never actually present on this input.\n const hasReserved = [...RESERVED_INPUT_KEYS].some((key) => Object.hasOwn(record, key));\n if (!hasReserved) return input;\n const rest: Record<string, unknown> = {};\n for (const key of Object.keys(record)) {\n // \"__proto__\" is dropped, not just excluded from the reserved-field\n // check: `rest[key] = record[key]` for key === \"__proto__\" would invoke\n // the inherited setter and reassign rest's own prototype instead of\n // creating a data property (belt-and-braces — validation.ts's\n // Object.hasOwn fix is the primary control).\n if (!RESERVED_INPUT_KEYS.has(key)) rest[key] = record[key];\n }\n return rest;\n}\n\nfunction describeError(error: unknown): { message: string; name?: string } {\n if (error instanceof Error) return { message: error.message, name: error.name };\n return { message: String(error) };\n}\n","/**\n * In-memory implementation of the frozen `ResourceRegistry` interface.\n */\nimport type { ProtocolName } from '../domain/common.js';\nimport type { CommerceResource, ResourceRegistry } from '../domain/resource.js';\nimport { CommerceError } from '../errors/index.js';\n\nexport class ResourceRegistryImpl implements ResourceRegistry {\n private readonly byId = new Map<string, CommerceResource>();\n private readonly ordered: readonly CommerceResource[];\n\n constructor(resources: readonly CommerceResource[]) {\n for (const resource of resources) {\n if (this.byId.has(resource.id)) {\n throw new CommerceError('CONFIG_INVALID', `Duplicate resource id \"${resource.id}\"`, {\n details: { resourceId: resource.id },\n });\n }\n this.byId.set(resource.id, resource);\n }\n this.ordered = [...resources];\n }\n\n get(id: string): CommerceResource | undefined {\n return this.byId.get(id);\n }\n\n list(): readonly CommerceResource[] {\n return this.ordered;\n }\n\n listExposedVia(protocol: ProtocolName): readonly CommerceResource[] {\n return this.ordered.filter((resource) => resource.exposedVia.includes(protocol));\n }\n\n has(id: string): boolean {\n return this.byId.has(id);\n }\n}\n\n/** Build a `ResourceRegistry` from a validated list of canonical resources. */\nexport function createResourceRegistry(resources: readonly CommerceResource[]): ResourceRegistry {\n return new ResourceRegistryImpl(resources);\n}\n","/**\n * src/core/execution\n *\n * The execution pipeline implementation: resource registry, backend executor,\n * event bus and the pipeline itself. Not part of the frozen `public-types.ts`\n * barrel — this is implementation, not contract — but exported as a stable\n * subpath so `src/gateway` (and tests) can wire it up.\n */\n\nexport type { HttpBackendExecutorOptions } from './backend-http.js';\nexport {\n extractPathParameterNames,\n findUnparsedBraceToken,\n HttpBackendExecutor,\n validateBackendRequestShape,\n} from './backend-http.js';\nexport type { CreateEventBusOptions, EventBus } from './event-bus.js';\nexport { createEventBus } from './event-bus.js';\nexport type { CreateExecutionPipelineOptions } from './pipeline.js';\nexport { createExecutionPipeline } from './pipeline.js';\nexport { createResourceRegistry, ResourceRegistryImpl } from './registry.js';\nexport type { FieldError, ValidationResult, Validator } from './validation.js';\nexport { compileJsonSchema, isObjectSchemaNode } from './validation.js';\n","/**\n * Canonical commerce events.\n *\n * FROZEN CONTRACT. Every event in a single flow shares one `requestId` so that\n * logs, payment attempts, backend calls and receipts are correlatable.\n */\nimport type { IsoTimestamp } from './common.js';\n\nexport const COMMERCE_EVENT_TYPES = [\n 'resource.discovered',\n 'resource.requested',\n 'payment.required',\n 'payment.rejected',\n 'payment.verified',\n 'payment.settled',\n 'backend.called',\n 'backend.failed',\n 'resource.delivered',\n] as const;\n\nexport type CommerceEventType = (typeof COMMERCE_EVENT_TYPES)[number];\n\nexport interface CommerceEvent {\n readonly id: string;\n readonly type: CommerceEventType;\n readonly requestId: string;\n readonly resourceId?: string;\n readonly at: IsoTimestamp;\n /** Protocol adapter that originated the request, e.g. 'mcp' or 'http'. */\n readonly adapter?: string;\n readonly paymentProvider?: string;\n readonly durationMs?: number;\n readonly status?: 'ok' | 'error';\n /** Non-secret, structured detail. Must never contain keys, headers or proofs. */\n readonly data?: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Sink for canonical events.\n *\n * Implementations must be non-throwing from the caller's perspective: an event\n * sink failure must never fail an otherwise successful commerce flow.\n */\nexport interface EventSink {\n emit(event: CommerceEvent): Promise<void>;\n}\n","/**\n * Protocol adapter boundary.\n *\n * FROZEN CONTRACT. An adapter translates a protocol's wire format into a\n * `CanonicalRequest`, hands it to the execution pipeline and maps the outcome\n * back. It must not call merchant backends, implement payment logic, or hold\n * its own copy of the canonical model.\n *\n * Adapter isolation: a failure while starting or serving one adapter must not\n * prevent the others from operating.\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { AdapterDescriptor, AdapterHealth, ProtocolName } from '../domain/common.js';\nimport type { EventSink } from '../domain/event.js';\nimport type { ExecutionPipeline } from '../domain/request.js';\nimport type { ResourceRegistry } from '../domain/resource.js';\nimport type { Logger } from './logger.js';\nimport type { Clock, IdGenerator } from './runtime.js';\n\n/** Everything an adapter is given. Nothing else is available to it. */\nexport interface ProtocolAdapterContext {\n readonly pipeline: ExecutionPipeline;\n readonly resources: ResourceRegistry;\n readonly events: EventSink;\n readonly logger: Logger;\n readonly clock: Clock;\n readonly ids: IdGenerator;\n /** Externally reachable base URL of the gateway, from config. */\n readonly publicBaseUrl: string;\n}\n\nexport interface ProtocolAdapter {\n readonly name: ProtocolName;\n readonly descriptor: AdapterDescriptor;\n\n start(context: ProtocolAdapterContext): Promise<void>;\n health(): Promise<AdapterHealth>;\n stop(): Promise<void>;\n}\n\n/**\n * A protocol adapter served over HTTP.\n *\n * The gateway mounts `handleHttp` at `mountPath` using raw Node request and\n * response objects, so adapters stay independent of the HTTP framework.\n *\n * GUARANTEE — the request body is **unconsumed**.\n *\n * `req` is handed over with its stream unread: the gateway suppresses every\n * body parser on this mount, so an adapter whose SDK reads the body itself\n * (MCP's Streamable HTTP transport does) can do so. The adapter owns reading,\n * size-limiting beyond the gateway's own cap, and parsing.\n *\n * This is load-bearing and easy to break silently. Fastify pre-registers\n * exact-match parsers for `application/json` and `text/plain` and prefers them\n * over a `'*'` wildcard, so registering only a wildcard no-op leaves the\n * built-in JSON parser draining the body first — the adapter then reads an\n * empty stream and every request fails to parse. That exact regression shipped\n * once and no unit test caught it, because adapter conformance suites drive\n * `handleHttp` over a bare `node:http` server and never traverse the gateway.\n *\n * Any change to how adapters are mounted must be covered by a test that POSTs\n * a real JSON body through the real gateway and asserts the adapter received\n * it intact.\n */\nexport interface HttpProtocolAdapter extends ProtocolAdapter {\n /** Path prefix the gateway mounts this adapter at, e.g. '/mcp'. */\n readonly mountPath: string;\n handleHttp(req: IncomingMessage, res: ServerResponse): Promise<void>;\n}\n\nexport function isHttpProtocolAdapter(adapter: ProtocolAdapter): adapter is HttpProtocolAdapter {\n return typeof (adapter as HttpProtocolAdapter).handleHttp === 'function';\n}\n","/**\n * Injected runtime primitives.\n *\n * Everything non-deterministic (time, ids) is injected so tests can be exact.\n */\nimport type { IsoTimestamp } from '../domain/common.js';\n\nexport interface Clock {\n now(): Date;\n nowIso(): IsoTimestamp;\n /** Milliseconds since an arbitrary origin; use for durations only. */\n monotonicMs(): number;\n}\n\nexport interface IdGenerator {\n /** Opaque, collision-resistant identifier. */\n next(prefix?: string): string;\n}\n\nexport const systemClock: Clock = {\n now: () => new Date(),\n nowIso: () => new Date().toISOString(),\n monotonicMs: () => performance.now(),\n};\n","/**\n * ============================================================================\n * FROZEN PUBLIC CONTRACT — frozen at v0.1.0-alpha\n * ============================================================================\n *\n * Every cross-package type and interface in the project is re-exported here.\n * This barrel is frozen. Everything reachable from it is public API that\n * consumers code against, so a change to any of it is a breaking change and\n * needs the decision record updated to match.\n *\n * Do not redeclare these shapes locally. If something is missing, add it here\n * rather than creating a parallel type.\n *\n * See docs/contracts.md for the freeze record.\n */\n\n// --- canonical domain ------------------------------------------------------\nexport type {\n AdapterDescriptor,\n AdapterHealth,\n DecimalAmount,\n IsoTimestamp,\n JsonSchema,\n PaymentMethodName,\n ProtocolName,\n} from './domain/common.js';\nexport type { CommerceEvent, CommerceEventType, EventSink } from './domain/event.js';\nexport { COMMERCE_EVENT_TYPES } from './domain/event.js';\n\nexport type {\n PaymentChallenge,\n PaymentContext,\n PaymentProvider,\n PaymentRequirement,\n PaymentResult,\n PaymentSettlementContext,\n PaymentSubmission,\n PaymentVerificationContext,\n} from './domain/payment.js';\n\nexport type { CommerceReceipt, PaymentAttempt } from './domain/receipt.js';\nexport type {\n CanonicalRequest,\n DeliveredOutcome,\n ExecutionOutcome,\n ExecutionPipeline,\n PaymentRequiredOutcome,\n} from './domain/request.js';\nexport type {\n BackendHandler,\n BackendMethod,\n CommerceResource,\n Pricing,\n ResourceRegistry,\n} from './domain/resource.js';\nexport { DEFAULT_BACKEND_TIMEOUT_MS } from './domain/resource.js';\nexport type {\n DeliverySummary,\n ErrorEnvelope,\n PaymentRequiredEnvelope,\n} from './domain/wire.js';\nexport {\n DELIVERY_SUMMARY_META_KEY,\n isPaymentRequiredEnvelope,\n PAYMENT_HEADER,\n PAYMENT_INPUT_FIELD,\n PAYMENT_REQUIRED_HEADER,\n PAYMENT_RESPONSE_HEADER,\n toDeliverySummary,\n toErrorEnvelope,\n toPaymentRequiredEnvelope,\n} from './domain/wire.js';\n\n// --- errors ----------------------------------------------------------------\nexport type { CommerceErrorCode, CommerceErrorInfo, CommerceErrorOptions } from './errors/index.js';\nexport {\n COMMERCE_ERROR_CODES,\n COMMERCE_ERROR_HTTP_STATUS,\n CommerceError,\n isCommerceError,\n RETRYABLE_ERROR_CODES,\n toCommerceError,\n} from './errors/index.js';\n\n// --- injection boundaries --------------------------------------------------\nexport type { BackendExecutor, BackendRequest, BackendResponse } from './interfaces/backend.js';\nexport type { Logger } from './interfaces/logger.js';\nexport { NOOP_LOGGER } from './interfaces/logger.js';\nexport type {\n HttpProtocolAdapter,\n ProtocolAdapter,\n ProtocolAdapterContext,\n} from './interfaces/protocol-adapter.js';\nexport { isHttpProtocolAdapter } from './interfaces/protocol-adapter.js';\nexport type { Clock, IdGenerator } from './interfaces/runtime.js';\nexport { systemClock } from './interfaces/runtime.js';\nexport type {\n ListOptions,\n PaymentAttemptReservation,\n PaymentAttemptUpdate,\n ReceiptStore,\n} from './interfaces/store.js';\n","/**\n * src/core\n *\n * Canonical commerce domain model, typed errors and the execution pipeline.\n * Contains no protocol- or payment-rail-specific code.\n */\nexport * from './public-types.js';\n","/**\n * The networks this gateway will settle on, as data.\n *\n * x402 v2 identifies a network by its CAIP-2 id, so the only thing an\n * operator has to change to move between environments is that string. What\n * the code needs on top of it — the chain id to sign against, a name a human\n * recognises, and whether real money is involved — lives here rather than\n * being derived at each call site.\n *\n * A registry rather than \"parse any `eip155:*`\" on purpose. The chain id is\n * parseable from any such string, but `mainnet` is not, and every guardrail in\n * `guardrails.ts` keys off it. An unknown id is refused at startup instead of\n * being quietly treated as a testnet.\n *\n * Base Sepolia and the local dev chain share the id `eip155:84532`: the local\n * chain deliberately reuses Base Sepolia's chain id so the unmodified x402 SDK\n * can talk to it. Nothing may infer \"public network\" from the network id alone\n * — that is what `resolveDeploymentMode` and the Anvil probe in `provider.ts`\n * are for.\n */\nimport { CommerceError } from '../../core/index.js';\n\nexport interface NetworkProfile {\n /** CAIP-2 identifier, e.g. `eip155:84532`. */\n readonly id: string;\n /** Signed into the buyer's EIP-712 domain. */\n readonly chainId: number;\n readonly displayName: string;\n readonly kind: 'testnet' | 'mainnet';\n /**\n * The USDC deployment this network is expected to settle in, with the EIP-712\n * domain the token actually reports. Enforced only on mainnet (see\n * `guardrails.ts`) — a testnet is where a mock token is a legitimate thing to\n * point at.\n *\n * `name` is not decorative and is not the symbol: it is signed into every\n * buyer's EIP-712 domain, and the two USDC deployments disagree. Base Sepolia\n * reports `\"USDC\"`; Base mainnet reports `\"USD Coin\"`. Configure the wrong\n * one and every payment is refused `invalid_exact_evm_token_name_mismatch`\n * after the buyer has signed. Read back from the contracts, not assumed.\n */\n readonly canonicalAsset?: {\n readonly symbol: string;\n readonly address: string;\n readonly name: string;\n readonly version: string;\n };\n}\n\nconst PROFILES: readonly NetworkProfile[] = [\n {\n id: 'eip155:84532',\n chainId: 84532,\n displayName: 'Base Sepolia',\n kind: 'testnet',\n canonicalAsset: {\n symbol: 'USDC',\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n name: 'USDC',\n version: '2',\n },\n },\n {\n id: 'eip155:8453',\n chainId: 8453,\n displayName: 'Base',\n kind: 'mainnet',\n canonicalAsset: {\n symbol: 'USDC',\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n name: 'USD Coin',\n version: '2',\n },\n },\n];\n\nconst BY_ID = new Map(PROFILES.map((profile) => [profile.id, profile]));\n\nexport const SUPPORTED_NETWORK_IDS: readonly string[] = PROFILES.map((p) => p.id);\n\nexport function findNetworkProfile(id: string): NetworkProfile | undefined {\n return BY_ID.get(id);\n}\n\nexport function requireNetworkProfile(id: string, path: string): NetworkProfile {\n const profile = BY_ID.get(id);\n if (!profile) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `${path}: \"${id}\" is not a supported network. Supported CAIP-2 identifiers: ${SUPPORTED_NETWORK_IDS.join(', ')}`,\n { details: { path, network: id } },\n );\n }\n return profile;\n}\n\n/**\n * What this deployment actually is, as opposed to what it is called.\n *\n * `local` is a property of the *facilitator*, not the network: settling\n * through the in-process facilitator against a dev node is local regardless of\n * the CAIP-2 id that node answers to. This distinction is the whole reason\n * diagnostics can say `eip155:84532` without claiming to be on public Base\n * Sepolia.\n */\nexport type DeploymentMode = 'local' | 'testnet' | 'mainnet';\n\nexport function resolveDeploymentMode(\n profile: NetworkProfile,\n facilitatorMode: 'local' | 'remote',\n): DeploymentMode {\n if (facilitatorMode === 'local') return 'local';\n return profile.kind;\n}\n\n/** The banner an operator must not be able to miss. Never printed for anything else. */\nexport const LIVE_MAINNET_BANNER = 'LIVE MAINNET MODE — REAL FUNDS';\n\nexport function describeDeploymentMode(mode: DeploymentMode): string {\n return mode === 'mainnet' ? LIVE_MAINNET_BANNER : mode.toUpperCase();\n}\n","/**\n * `${VAR}` / `${VAR:-default}` substitution over an arbitrary parsed-YAML value.\n *\n * Only string leaves are touched; numbers/booleans/null pass through untouched\n * (the caller coerces the *resulting* string back into a number/boolean where\n * the schema expects one). An unresolved placeholder fails config loading\n * immediately — startup must never proceed with an unresolved secret. That\n * includes one left behind by a *nested* placeholder such as `${A:-${B}}`,\n * which is rejected rather than silently passed through. There is no\n * escape syntax for a literal `${NAME}`; nothing in this config format needs\n * one, and adding it would mean two ways to write every value.\n *\n * `${VAR}` (no default) requires `VAR` to be present in `env` (any value,\n * including an empty string, counts as present).\n * `${VAR:-default}` falls back to `default` when `VAR` is absent OR empty,\n * matching common shell semantics.\n *\n * Anything else brace-shaped is refused: `${VAR-x}`, `${VAR:=x}`, `${VAR:?x}`\n * are valid *shell* and would otherwise load as literal strings. That is\n * harmless where a downstream check rejects the literal, and quietly wrong for\n * a free-string field — `adminToken: ${ADMIN_TOKEN-fallback}` would run the\n * gateway with that literal as the ledger credential while the operator\n * believed an env secret gated it. A bare `$VAR` is deliberately left alone: it\n * is not brace-shaped, and refusing it would reject values that legitimately\n * contain a dollar sign.\n *\n * Every rule above is decided from the **template**, before substitution.\n * Deciding afterwards is how `${A:-${B}}` used to corrupt a value on the one\n * branch its guard did not cover, and how a resolved secret containing a\n * `${…}`-shaped fragment used to get quoted back in the error text.\n *\n * The resolved *value* of a variable is never included in any error message —\n * only the variable *name* and the config path are.\n */\nimport { CommerceError } from '../core/index.js';\n\nconst PLACEHOLDER_PATTERN = /\\$\\{([A-Za-z_][A-Za-z0-9_]*)(:-([^}]*))?\\}/g;\n\n/** An innermost brace token: `${` … `}` with no braces between. */\nconst BRACE_TOKEN = /\\$\\{[^{}]*\\}/g;\n\n/** The same grammar as PLACEHOLDER_PATTERN, anchored, for validating one token. */\nconst SUPPORTED_TOKEN = /^\\$\\{[A-Za-z_][A-Za-z0-9_]*(:-[^}]*)?\\}$/;\n\n/** A placeholder whose default segment opens another placeholder. */\nconst NESTED_PLACEHOLDER = /\\$\\{[^{}]*\\$\\{/;\n\nexport function substituteEnv(value: unknown, env: NodeJS.ProcessEnv, path = '$'): unknown {\n if (typeof value === 'string') {\n return substituteString(value, env, path);\n }\n if (Array.isArray(value)) {\n return value.map((entry, index) => substituteEnv(entry, env, `${path}[${index}]`));\n }\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = substituteEnv(entry, env, `${path}.${key}`);\n }\n return result;\n }\n return value;\n}\n\nfunction substituteString(value: string, env: NodeJS.ProcessEnv, path: string): string {\n assertTemplateIsSupported(value, path);\n return substituteOnce(value, env, path);\n}\n\n/**\n * Refuses a template this module cannot honour, before any substitution runs.\n *\n * `${A:-${B}}` is the case that motivated this. `[^}]*` cannot span the inner\n * `}`, so the match consumes `${A:-${B` and leaves a stray `}` behind. When `A`\n * is unset the leftover `${B}` was visible afterwards and got caught; when `A`\n * is *set* — the normal case, and the whole reason someone writes a default —\n * substitution succeeded and the stray `}` was appended to the resolved value\n * with nothing to notice it. For `adminToken` that means the gateway compares\n * against a credential the operator does not hold, with no diagnostic.\n *\n * Deciding from the template covers both branches with one rule, and means no\n * error message is ever derived from a resolved value.\n */\nfunction assertTemplateIsSupported(value: string, path: string): void {\n if (NESTED_PLACEHOLDER.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" nests placeholders (e.g. \"\\${A:-\\${B}}\"), which is not supported — the inner one is not resolved and its closing brace ends up in the value. Use a plain default, or set the variable.`,\n { details: { path } },\n );\n }\n\n BRACE_TOKEN.lastIndex = 0;\n for (const [token] of value.matchAll(BRACE_TOKEN)) {\n if (SUPPORTED_TOKEN.test(token)) continue;\n // The token itself, never the surrounding value: this runs pre-substitution,\n // so it cannot contain a resolved secret.\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" contains \"${token}\", which is not a supported placeholder. Only \"\\${VAR}\" and \"\\${VAR:-default}\" are recognised; shell forms such as \"\\${VAR-default}\", \"\\${VAR:=default}\" and \"\\${VAR:?message}\" would load as literal text.`,\n { details: { path, token } },\n );\n }\n}\n\nfunction substituteOnce(value: string, env: NodeJS.ProcessEnv, path: string): string {\n return value.replace(\n PLACEHOLDER_PATTERN,\n (_match, name: string, hasDefault: string | undefined, def: string | undefined) => {\n const envValue = env[name];\n\n if (hasDefault !== undefined) {\n if (envValue === undefined || envValue === '') return def ?? '';\n return envValue;\n }\n\n if (envValue === undefined) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Unresolved environment variable \"\\${${name}}\" referenced at config path \"${path}\"`,\n { details: { variable: name, path } },\n );\n }\n return envValue;\n },\n );\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Anvil's well-known development accounts.\n *\n * LOCAL DEVELOPMENT ONLY — DO NOT FUND. These addresses and private keys are\n * derived from Foundry's public, well-documented default test mnemonic\n * (\"test test test test test test test test test test test junk\") and are\n * known to everyone who has ever run `anvil`. Anyone who sends real value to\n * one of these addresses on a real network will lose it.\n *\n * Index layout used by the local demo chain (see docs/contracts.md):\n * 0 — deployer / local facilitator signer (pays gas, broadcasts settlement)\n * 1 — merchant settlement destination (`payTo`)\n * 2 — buyer (signs EIP-3009 authorisations; never held by the gateway)\n */\nexport interface AnvilWellKnownAccount {\n readonly address: `0x${string}`;\n readonly privateKey: `0x${string}`;\n}\n\n/** Fixed-length tuple (not a bare array) so indexing by the documented layout above is fully typed. */\nexport const ANVIL_WELL_KNOWN_ACCOUNTS: readonly [\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n] = [\n {\n address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',\n },\n {\n address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',\n privateKey: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',\n },\n {\n address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',\n privateKey: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',\n },\n];\n\nexport const LOCAL_FACILITATOR_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[0];\nexport const LOCAL_MERCHANT_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[1];\nexport const LOCAL_BUYER_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[2];\n\n/** Safe label used everywhere a dev key appears in output, logs or manifests. */\nexport const DEV_KEY_LABEL = 'LOCAL DEVELOPMENT ONLY - DO NOT FUND';\n","/**\n * Prevents a well-known Anvil development private key — or a well-known\n * Anvil development *address* — from ever being used against anything other\n * than a loopback/private/dev RPC. Two symmetric mistakes, both covered:\n * signing settlement with a dev key (`assertDevKeyIsLocalOnly`), and routing\n * settlement revenue to a dev address (`assertPayToIsNotDevAddress`). The\n * second is the more consequential of the two — a wrong key merely fails to\n * sign, a wrong payTo silently succeeds and gives the money away, since the\n * private key behind every well-known Anvil address is public knowledge.\n *\n * Chain id alone cannot tell a real network from this project's local dev\n * chain: Base Sepolia's own chain id is 84532, the same id this project\n * deliberately reuses for the local chain so the unmodified x402 SDK can talk\n * to it. A dev key or dev payTo pointed at a real RPC by a config mistake is\n * instantly drainable — this is checked once at provider construction, not per\n * payment.\n */\nimport { CommerceError } from '../../core/index.js';\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from './local-chain/accounts.js';\n\nconst WELL_KNOWN_DEV_KEYS: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.privateKey.toLowerCase()),\n);\n\nconst WELL_KNOWN_DEV_ADDRESSES: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.address.toLowerCase()),\n);\n\n/** `0x` + 64 hex chars — the only shape `privateKeyToAccount` accepts. */\nconst PRIVATE_KEY_SHAPE = /^0x[0-9a-fA-F]{64}$/;\n\nexport function isWellKnownDevKey(privateKey: string): boolean {\n return WELL_KNOWN_DEV_KEYS.has(privateKey.toLowerCase());\n}\n\nexport function isWellKnownDevAddress(address: string): boolean {\n return WELL_KNOWN_DEV_ADDRESSES.has(address.toLowerCase());\n}\n\n/**\n * True for loopback addresses, RFC1918 private ranges, and bare (dot-free)\n * hostnames — the shape of a docker-compose/k8s service name (e.g.\n * \"anvil\"), which a real public DNS name essentially never has.\n *\n * ASSUMPTION, and the loosest edge of this guard: every dot-free, colon-free\n * hostname is treated as private, with no exceptions. A single-label *public* hostname (no dots) is\n * essentially nonexistent in practice — ICANN does not delegate bare\n * gTLDs/TLDs as public A/AAAA records — but this function cannot tell \"no\n * dots because it's a compose service name\" from \"no dots because it's an\n * unusual real host\" if one somehow existed. If that assumption ever stops\n * holding, this is the line to revisit.\n */\nexport function isLikelyLocalOrPrivateHost(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '');\n if (h === 'localhost' || h === '127.0.0.1' || h === '::1') return true;\n if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (!h.includes('.') && !h.includes(':')) return true; // bare hostname\n return false;\n}\n\nfunction parseHostnameOrThrow(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).hostname;\n } catch (cause) {\n // Not the URL itself: every commercial EVM RPC provider embeds an API key\n // in the path, and these messages reach `validate`, `doctor`, startup\n // output and CI logs.\n throw new CommerceError('CONFIG_INVALID', 'x402 provider: rpcUrl is not a valid URL', {\n cause,\n });\n }\n}\n\n/** Host only, for diagnostics. An RPC URL's path routinely carries a key. */\nfunction describeRpc(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).origin;\n } catch {\n return '[unparseable rpcUrl]';\n }\n}\n\n/**\n * Throws CONFIG_INVALID if a well-known dev key would sign against a non-local\n * RPC — or if `signerPrivateKey` isn't shaped like a private key at all.\n *\n * The shape check runs first and unconditionally. \"Not a key I recognise\"\n * (falls through `isWellKnownDevKey`, silently treated as someone's own real\n * facilitator key) and \"not a key at all\" (e.g. a truncated 63-char string)\n * must never share a code path: a malformed key that slips past this guard\n * only fails later, inside `settle()`, after the buyer's replayKey is already\n * reserved.\n */\nexport function assertDevKeyIsLocalOnly(rpcUrl: string, signerPrivateKey: string): void {\n if (!PRIVATE_KEY_SHAPE.test(signerPrivateKey)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is not a well-formed private key ' +\n '(expected \"0x\" followed by exactly 64 hex characters).',\n );\n }\n\n if (!isWellKnownDevKey(signerPrivateKey)) return; // a real facilitator key: not our business\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ' +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. A public dev key must never sign against ` +\n 'a public network — it is instantly drainable and can grief real settlements via nonce exhaustion. ' +\n 'Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.',\n );\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `payTo` (the settlement destination) is a\n * well-known Anvil development address and `rpcUrl` doesn't look\n * local/private.\n *\n * Mirrors `assertDevKeyIsLocalOnly`, but guards the *receiving* side of the\n * payment instead of the signing side, and — unlike the key guard — applies\n * regardless of facilitator mode: which account signs the settlement\n * transaction has no bearing on whether the destination address is one whose\n * private key is public knowledge. `agent-commerce init` defaults `payTo` to\n * a well-known Anvil address as a local-demo convenience; on a real network\n * that default routes every payment to an address anyone on earth can sweep.\n */\nexport function assertPayToIsNotDevAddress(rpcUrl: string, payTo: string): void {\n if (!isWellKnownDevAddress(payTo)) return; // not a dev address: not our business\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" (${payTo}) is a well-known Anvil development address, but rpcUrl ` +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. The private key behind that address ` +\n 'is public knowledge, so any revenue settled to it is immediately spendable by anyone. Set ' +\n '\"payTo\" to your own merchant wallet for any non-local RPC, or point rpcUrl at your ' +\n 'local/dev chain.',\n );\n }\n}\n","/**\n * Everything that must be true before this gateway is allowed to settle a\n * payment on the configured network.\n *\n * One definition, two callers: the provider runs it at construction so a\n * library consumer who never touches our config loader still gets the checks,\n * and `doctor` runs it against the parsed config so an operator sees the same\n * verdict without starting the gateway. Sharing a *call* is not sharing a\n * definition — the checks live here, and nothing re-implements them.\n *\n * Every failure is a startup failure. None of these are request-time\n * decisions: a deployment that is unsafe is unsafe before the first buyer\n * arrives, and finding out during `settle()` means the buyer's authorisation\n * is already burned.\n *\n * Peer-free by construction (no viem, no `@x402/*`) so the CLI can import it.\n */\nimport { CommerceError } from '../../core/index.js';\nimport { isLikelyLocalOrPrivateHost, isWellKnownDevAddress } from './dev-key-guard.js';\nimport {\n type DeploymentMode,\n type NetworkProfile,\n requireNetworkProfile,\n resolveDeploymentMode,\n} from './networks.js';\n\n/**\n * How the gateway authenticates to a remote facilitator.\n *\n * Deliberately a list, not a vendor: x402 facilitators are not a Coinbase-only\n * category, and a scheme that only fitted one vendor's credentials would make\n * the abstraction a fiction.\n *\n * - `none` — the facilitator takes no credential (the public testnet one).\n * - `bearer` — a static token. Covers most self-hosted and third-party\n * facilitators, and needs nothing installed.\n * - `cdp` — Coinbase Developer Platform, which signs a fresh JWT per request\n * over method + host + path, so a static header cannot express it. Handled by\n * the optional peer `@coinbase/x402`, imported only when this type is\n * configured. Anyone not using CDP never installs it.\n *\n * A facilitator whose scheme is none of these is refused at config load rather\n * than sent nothing.\n */\nexport type FacilitatorAuth =\n | { readonly type: 'none' }\n | { readonly type: 'bearer'; readonly token: string }\n | { readonly type: 'cdp'; readonly apiKeyId: string; readonly apiKeySecret: string };\n\nexport type X402FacilitatorConfig =\n | { readonly mode: 'local'; readonly signerPrivateKey: string }\n | { readonly mode: 'remote'; readonly url: string; readonly auth: FacilitatorAuth };\n\nexport interface X402DeploymentInput {\n readonly network: string;\n readonly payTo: string;\n readonly asset: string;\n /** EIP-712 domain of the asset, as the token itself reports it. */\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly facilitator: X402FacilitatorConfig;\n /** Required, and required to be `true`, before anything settles on a mainnet. */\n readonly allowMainnet?: boolean;\n /**\n * Required, and required to be `true`, to settle on a mainnet through a\n * facilitator that takes no credential.\n *\n * Separate from `allowMainnet` because it names a different decision: not\n * \"I meant to use real money\" but \"I accept this particular counterparty\n * without an account, terms, or anyone to call\".\n */\n readonly allowUnauthenticatedFacilitator?: boolean;\n}\n\nexport interface X402Deployment {\n readonly profile: NetworkProfile;\n readonly mode: DeploymentMode;\n}\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\n/**\n * Resolves the deployment and refuses every combination that could move real\n * money by accident. Order matters only in that the network must resolve\n * first; the rest are independent.\n */\nexport function resolveX402Deployment(input: X402DeploymentInput): X402Deployment {\n const profile = requireNetworkProfile(input.network, 'payments.x402.network');\n const mode = resolveDeploymentMode(profile, input.facilitator.mode);\n\n // The in-process facilitator signs with a key this process holds. Not a\n // custody problem — that signer never holds buyer or merchant funds, it pays\n // gas and broadcasts `transferWithAuthorization`, and the money moves buyer\n // to merchant directly on-chain. What it *is*, on a mainnet, is a funded key\n // inside the resource server: compromise that process and an attacker drains\n // the gas wallet and broadcasts from it. Separate processes, separate blast\n // radius — so it is refused, not warned about.\n if (profile.kind === 'mainnet' && input.facilitator.mode === 'local') {\n throw invalid(\n `payments.x402: network \"${profile.id}\" (${profile.displayName}) is a mainnet and cannot be served by facilitator.mode \"local\". A mainnet deployment must settle through a remote facilitator.`,\n 'payments.x402.facilitator.mode',\n );\n }\n\n if (mode === 'mainnet' && input.allowMainnet !== true) {\n throw invalid(\n `payments.x402: network \"${profile.id}\" (${profile.displayName}) settles real funds. Set payments.x402.allowMainnet: true to acknowledge this explicitly — it is never the default.`,\n 'payments.x402.allowMainnet',\n );\n }\n\n if (input.facilitator.mode === 'remote') {\n assertFacilitatorUrlIsSafe(input.facilitator.url, mode);\n // Not a funds check. An EIP-3009 authorisation names its recipient, its\n // amount and its chain, so a facilitator can broadcast exactly that\n // transfer or nothing — it cannot redirect the money. What a credential\n // buys is a *relationship*: rate limits, terms, someone to call when\n // settlement stops. Running production payments through a counterparty you\n // have none of that with is a real choice, and this is where it gets made\n // explicitly rather than by omission.\n if (\n mode === 'mainnet' &&\n input.facilitator.auth.type === 'none' &&\n input.allowUnauthenticatedFacilitator !== true\n ) {\n throw invalid(\n `payments.x402: facilitator ${describeOrigin(input.facilitator.url)} takes no credential, and this is a mainnet deployment. It will see every payment authorisation you handle, with no account, terms or support behind it. Set payments.x402.allowUnauthenticatedFacilitator: true to accept that, or configure facilitator.auth.`,\n 'payments.x402.allowUnauthenticatedFacilitator',\n );\n }\n // An empty credential is refused rather than sent: a blank token or key\n // reaches the facilitator as \"unauthenticated\" and fails every payment\n // after the buyer has already signed. `${VAR:- }` resolving to whitespace\n // is the realistic way this happens.\n for (const [field, value] of credentialFields(input.facilitator.auth)) {\n if (value.trim() === '') {\n throw invalid(\n `payments.x402: facilitator.auth.type is \"${input.facilitator.auth.type}\" but ${field} is empty. An empty credential is refused rather than sent.`,\n `payments.x402.facilitator.auth.${field}`,\n );\n }\n }\n }\n\n // The private key behind every well-known Anvil address is public knowledge.\n // `dev-key-guard` already refuses one against a public *RPC*; this refuses\n // one on any non-local *deployment*, which is the case a remote facilitator\n // creates — there the RPC host says nothing about where settlement lands.\n // The zero address lived only in the config loader, so a library consumer\n // calling `createX402PaymentProvider` directly — the path this shared\n // definition exists to cover — could boot a mainnet provider whose every\n // payment burns — sharing a *call* is not sharing a definition, and this\n // check had drifted out of the shared one.\n if (/^0x0{40}$/i.test(input.payTo)) {\n throw invalid(\n 'payments.x402: \"payTo\" is the zero address. Every payment settled there is destroyed.',\n 'payments.x402.payTo',\n );\n }\n\n if (mode !== 'local' && isWellKnownDevAddress(input.payTo)) {\n throw invalid(\n `payments.x402: \"payTo\" (${input.payTo}) is a well-known Anvil development address and this is a ${mode} deployment. Anyone can spend what settles there. Set payTo to your own merchant wallet.`,\n 'payments.x402.payTo',\n );\n }\n\n // Mainnet only. A testnet is exactly where pointing at a mock token is the\n // right thing to do, so the same check there would block the normal case.\n const canonical = profile.canonicalAsset;\n if (mode === 'mainnet' && canonical) {\n if (!sameAddress(input.asset, canonical.address)) {\n throw invalid(\n `payments.x402: asset ${input.asset} is not ${canonical.symbol} on ${profile.displayName} (expected ${canonical.address}). Settling a mainnet payment in an unintended token is refused.`,\n 'payments.x402.asset',\n );\n }\n // The EIP-712 domain is signed by the buyer and checked by the scheme. Get\n // it wrong and every payment is refused `invalid_exact_evm_token_name_mismatch`\n // *after* the buyer signed — a config error charged to the buyer's patience.\n // Caught here instead, before the gateway starts.\n if (input.assetName !== undefined && input.assetName !== canonical.name) {\n throw invalid(\n `payments.x402: assetName \"${input.assetName}\" is not the EIP-712 domain name ${canonical.symbol} reports on ${profile.displayName} (expected \"${canonical.name}\"). Every payment would be refused after the buyer signed.`,\n 'payments.x402.assetName',\n );\n }\n if (input.assetVersion !== undefined && input.assetVersion !== canonical.version) {\n throw invalid(\n `payments.x402: assetVersion \"${input.assetVersion}\" is not the EIP-712 domain version ${canonical.symbol} reports on ${profile.displayName} (expected \"${canonical.version}\").`,\n 'payments.x402.assetVersion',\n );\n }\n }\n\n return { profile, mode };\n}\n\n/**\n * A facilitator sees every payment authorisation this gateway handles. Plain\n * HTTP to one on a public network puts those on the wire in the clear and\n * lets anyone in the path rewrite a settlement result, so it is allowed only\n * where the endpoint cannot leave the host — a local or private address.\n */\nfunction assertFacilitatorUrlIsSafe(url: string, mode: DeploymentMode): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch (cause) {\n throw new CommerceError('CONFIG_INVALID', `payments.x402: facilitator.url is not a valid URL`, {\n cause,\n details: { path: 'payments.x402.facilitator.url' },\n });\n }\n\n if (parsed.protocol === 'https:') return;\n if (parsed.protocol !== 'http:') {\n throw invalid(\n `payments.x402: facilitator ${describeOrigin(url)} must be reached over https (or http on a local/private host); got \"${parsed.protocol}//\"`,\n 'payments.x402.facilitator.url',\n );\n }\n if (mode !== 'mainnet' && isLikelyLocalOrPrivateHost(parsed.hostname)) return;\n\n // The origin, never the whole URL: the path can carry a tenant or an API\n // key, which is why `/.well-known` withholds this field entirely. A refusal\n // message goes to `validate`, `doctor`, startup output and CI logs.\n throw invalid(\n `payments.x402: facilitator ${describeOrigin(url)} is reached over plain HTTP. Payment authorisations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,\n 'payments.x402.facilitator.url',\n );\n}\n\n/** Host only — a facilitator URL can carry a tenant path or an API key. */\nfunction describeOrigin(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return '[unparseable facilitator.url]';\n }\n}\n\n/** The secret-bearing fields of an auth block, for emptiness checks only. Never logged. */\nfunction credentialFields(auth: FacilitatorAuth): readonly (readonly [string, string])[] {\n switch (auth.type) {\n case 'bearer':\n return [['token', auth.token]];\n case 'cdp':\n return [\n ['apiKeyId', auth.apiKeyId],\n ['apiKeySecret', auth.apiKeySecret],\n ];\n default:\n return [];\n }\n}\n\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n","/**\n * `config.yaml` schema, validation and normalisation into the\n * canonical `GatewayConfig` (docs/contracts.md).\n *\n * Two-phase validation:\n * 1. Zod validates *shape* (types, required fields, unknown-key rejection).\n * Numeric/boolean leaves accept either their native type or a string\n * (env substitution always produces a string), and are left as-is here —\n * Zod's typed transforms have surprising inference interactions with\n * `.strict()` objects, so numeric/boolean coercion is done explicitly,\n * in plain TypeScript, in the normalisation pass below.\n * 2. A manual business-rule pass validates cross-references that need a\n * specific, actionable message (duplicate ids, disabled protocols/payment\n * methods, dynamic pricing, destination-address plausibility) and\n * performs the numeric/boolean coercion.\n *\n * Env substitution (`${VAR}` / `${VAR:-default}`) runs over the raw parsed\n * value *before* either phase, so numeric/boolean fields can be templated too.\n * One exception, deliberate: `checkVersion` runs **before** substitution, so\n * `version:` cannot itself be templated. It is the compatibility gate that\n * decides whether this parser understands the document at all; resolving\n * environment variables to find out which schema version to expect would be\n * backwards. The order is intended; `version:` is the one exception to the\n * substitution rule, which this sentence exists to record.\n */\n\nimport { type ZodError, type ZodIssue, type ZodTypeAny, z } from 'zod';\nimport {\n extractPathParameterNames,\n findUnparsedBraceToken,\n isObjectSchemaNode,\n} from '../core/execution/index.js';\nimport {\n CommerceError,\n type CommerceResource,\n PAYMENT_INPUT_FIELD,\n type Pricing,\n} from '../core/index.js';\nimport { resolveX402Deployment, type X402FacilitatorConfig } from '../payments/x402/guardrails.js';\nimport { substituteEnv } from './env.js';\n\nconst SUPPORTED_CONFIG_VERSION = 1;\n\n/** `0x` + 40 hex chars. Checksum-insensitive: casing is not enforced. */\nconst ADDRESS_PATTERN = /^0x[0-9a-fA-F]{40}$/;\nconst ZERO_ADDRESS_PATTERN = /^0x0{40}$/i;\n\n/**\n * A resource `id` doubles as its MCP tool name (protocol-mcp registers one\n * tool per resource, named by id). Value verified against the regex actually\n * shipped in the installed `@modelcontextprotocol/sdk@1.30.0`\n * (`shared/toolNameValidation.js`, SEP-986 \"Specify Format for Tool Names\") —\n * not duplicated as an SDK dependency, since config stays protocol-agnostic.\n */\nconst MCP_TOOL_NAME_PATTERN = /^[A-Za-z0-9._-]{1,128}$/;\n\n// ---------------------------------------------------------------------------\n// Zod schema for the *shape* of the raw (post-substitution) document.\n// ---------------------------------------------------------------------------\n\n/** Accepts a real number or a (post env-substitution) numeric string. */\nconst NumberOrString = z.union([z.number(), z.string()]);\n/** Accepts a real boolean or a (post env-substitution) \"true\"/\"false\" string. */\nconst BooleanOrString = z.union([z.boolean(), z.string()]);\n\nconst MerchantSchema = z\n .object({\n id: z.string().min(1),\n name: z.string().min(1),\n publicBaseUrl: z.string().min(1),\n })\n .strict();\n\nconst ServerSchema = z\n .object({\n port: NumberOrString,\n host: z.string().min(1),\n /** Shared secret gating /api/receipts, /api/events, /api/events/stream. No token -> those routes 404. */\n adminToken: z.string().min(1).optional(),\n /** Browser origins allowed to read the dashboard-facing routes. Empty by default: closed. */\n // Entries are matched literally against the browser's\n // `Origin` header, so `\"*\"` and a trailing slash match nothing at all —\n // fail-closed (a lockout, not a bypass), but silently, and a lockout with\n // no explanation is the kind of thing an operator \"fixes\" by disabling the\n // check. Reject those two shapes with a pointer instead.\n allowedOrigins: z\n .array(\n z\n .string()\n .min(1)\n .refine((origin) => origin !== '*', {\n message:\n 'wildcard \"*\" is not supported — allowedOrigins entries are matched literally against the browser\\'s Origin header, so \"*\" would match nothing. List each scheme://host[:port] explicitly.',\n })\n .refine((origin) => !origin.endsWith('/'), {\n message:\n 'must not end with \"/\" — a browser Origin header never has a trailing slash, so this entry would match nothing. Use e.g. \"http://localhost:5173\".',\n }),\n )\n .optional(),\n })\n .strict();\n\nconst StorageSchema = z\n .object({\n receipts: z\n .object({\n driver: z.literal('sqlite'),\n path: z.string().min(1),\n })\n .strict(),\n })\n .strict();\n\n/**\n * Every path the gateway registers itself (`src/gateway/routes.ts`). An MCP\n * mount that equals one of these makes Fastify's `.all()` a duplicate of the\n * registered route; one that is a path-prefix of them swallows their 404s\n * through the mount's `${mountPath}/*` wildcard.\n */\nconst RESERVED_GATEWAY_PATHS = [\n '/health',\n '/ready',\n '/.well-known/agent-commerce',\n '/api/resources',\n '/api/resources/:id/invoke',\n '/api/receipts',\n '/api/events',\n '/api/events/stream',\n] as const;\n\n/**\n * `mountPath` reaches Fastify as a route pattern, and a bad one throws inside\n * route registration — deferred to `server.ready()`, so `createGateway` fails\n * wholesale with an opaque `FST_ERR_*` instead of the adapter alone degrading.\n * Catching the shape here turns that into a CONFIG_INVALID naming the value.\n * Fastify pattern syntax (`:param`, `*`) is rejected rather than supported:\n * the mount registers its own wildcard, so a pattern here has no meaning.\n */\nconst McpMountPathSchema = z\n .string()\n .min(1)\n .refine((value) => value.startsWith('/'), {\n message: 'must start with \"/\" — it is an absolute gateway path, e.g. \"/mcp\".',\n })\n .refine((value) => !/[:*?\\s]/.test(value), {\n message:\n 'must not contain \":\", \"*\", \"?\" or whitespace — the mount is a literal path prefix, not a Fastify route pattern, and registers its own wildcard.',\n })\n .refine(\n (value) => {\n const base = value.replace(/\\/+$/, '');\n return !RESERVED_GATEWAY_PATHS.some(\n (reserved) => reserved === base || reserved.startsWith(`${base}/`),\n );\n },\n {\n message: `must not collide with a route the gateway already serves (${RESERVED_GATEWAY_PATHS.join(', ')}); pick a dedicated prefix such as \"/mcp\".`,\n },\n );\n\nconst ProtocolsSchema = z\n .object({\n http: z.object({ enabled: BooleanOrString }).strict(),\n mcp: z\n .object({\n enabled: BooleanOrString,\n mountPath: McpMountPathSchema,\n })\n .strict(),\n })\n .strict();\n\nconst BackendMethodSchema = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);\n\nconst BackendHandlerSchema = z\n .object({\n type: z.literal('http'),\n method: BackendMethodSchema,\n url: z.string().min(1),\n headers: z.record(z.string(), z.string()).optional(),\n timeoutMs: NumberOrString.optional(),\n })\n .strict();\n\nconst PricingSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('free') }).strict(),\n z\n .object({\n type: z.literal('fixed'),\n amount: z.string().min(1),\n currency: z.string().min(1),\n })\n .strict(),\n z\n .object({\n type: z.literal('dynamic'),\n resolver: z.string().min(1),\n })\n .strict(),\n]);\n\nconst JsonSchemaValueSchema: ZodTypeAny = z.record(z.string(), z.unknown());\n\nconst ResourceEntrySchema = z\n .object({\n name: z.string().min(1),\n description: z.string().optional(),\n input: JsonSchemaValueSchema.optional(),\n output: JsonSchemaValueSchema.optional(),\n backend: BackendHandlerSchema,\n pricing: PricingSchema,\n expose: z.array(z.string().min(1)).min(1),\n payments: z.array(z.string().min(1)).optional(),\n })\n .strict();\n\nconst ResourcesMapSchema = z.record(z.string().min(1), ResourceEntrySchema);\n\n/**\n * Facilitator credentials, kept generic on purpose: x402 facilitators are not\n * a single-vendor category, and an auth block shaped around one provider's\n * credentials would make the abstraction a fiction. A facilitator needing\n * per-request signed credentials is refused rather than sent nothing.\n */\nconst FacilitatorAuthSchema = z.discriminatedUnion('type', [\n z.object({ type: z.literal('none') }).strict(),\n z.object({ type: z.literal('bearer'), token: z.string().min(1) }).strict(),\n // Coinbase Developer Platform. Needs the optional peer `@coinbase/x402`,\n // which signs a fresh JWT per request; a static header cannot express it.\n z\n .object({\n type: z.literal('cdp'),\n apiKeyId: z.string().min(1),\n apiKeySecret: z.string().min(1),\n })\n .strict(),\n]);\n\nconst FacilitatorSchema = z.discriminatedUnion('mode', [\n z\n .object({\n mode: z.literal('local'),\n signerPrivateKey: z.string().min(1),\n })\n .strict(),\n z\n .object({\n mode: z.literal('remote'),\n url: z.string().min(1),\n // Absent means \"this facilitator takes no credential\" — an explicit\n // statement, normalised to `{ type: 'none' }` below. On a mainnet that\n // combination is refused outright, so the default can never quietly\n // become an unauthenticated production facilitator.\n auth: FacilitatorAuthSchema.optional(),\n })\n .strict(),\n]);\n\nconst X402Schema = z\n .object({\n enabled: BooleanOrString,\n network: z.string().min(1),\n rpcUrl: z.string().min(1),\n asset: z.string().min(1),\n assetName: z.string().min(1),\n assetVersion: z.string().min(1),\n assetDecimals: NumberOrString,\n payTo: z.string().min(1),\n maxTimeoutSeconds: NumberOrString,\n facilitator: FacilitatorSchema,\n /** Real funds. Never defaulted — see src/payments/x402/guardrails.ts. */\n allowMainnet: BooleanOrString.optional(),\n /** Accepts a mainnet facilitator that takes no credential. Never defaulted. */\n allowUnauthenticatedFacilitator: BooleanOrString.optional(),\n })\n .strict();\n\nconst PaymentsSchema = z\n .object({\n x402: X402Schema.optional(),\n })\n .strict();\n\nconst RawConfigSchema = z\n .object({\n version: z.literal(SUPPORTED_CONFIG_VERSION),\n merchant: MerchantSchema,\n server: ServerSchema,\n storage: StorageSchema,\n protocols: ProtocolsSchema,\n resources: ResourcesMapSchema,\n payments: PaymentsSchema,\n })\n .strict();\n\ntype RawConfig = z.infer<typeof RawConfigSchema>;\ntype RawResourceEntry = z.infer<typeof ResourceEntrySchema>;\n\n// ---------------------------------------------------------------------------\n// Public shape (docs/contracts.md — exact).\n// ---------------------------------------------------------------------------\n\nexport interface GatewayConfig {\n readonly version: 1;\n readonly merchant: { readonly id: string; readonly name: string; readonly publicBaseUrl: string };\n readonly server: {\n readonly port: number;\n readonly host: string;\n readonly adminToken?: string;\n readonly allowedOrigins: readonly string[];\n };\n readonly storage: { readonly receipts: { readonly driver: 'sqlite'; readonly path: string } };\n readonly protocols: {\n readonly http: { readonly enabled: boolean };\n readonly mcp: { readonly enabled: boolean; readonly mountPath: string };\n };\n /** Canonical resources, already normalised. */\n readonly resources: readonly CommerceResource[];\n readonly payments: {\n readonly x402?: {\n readonly enabled: boolean;\n readonly network: string;\n readonly rpcUrl: string;\n readonly asset: string;\n readonly assetName: string;\n readonly assetVersion: string;\n readonly assetDecimals: number;\n readonly payTo: string;\n readonly maxTimeoutSeconds: number;\n readonly facilitator: X402FacilitatorConfig;\n readonly allowMainnet?: boolean;\n readonly allowUnauthenticatedFacilitator?: boolean;\n };\n };\n}\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nexport function parseConfig(raw: unknown, env: NodeJS.ProcessEnv): GatewayConfig {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'Configuration root must be a mapping (object) at \"$\"',\n {\n details: { path: '$' },\n },\n );\n }\n\n checkVersion(raw as Record<string, unknown>);\n\n const substituted = substituteEnv(raw, env);\n const parsed = parseWithZod(RawConfigSchema, substituted);\n return normalise(parsed);\n}\n\nfunction checkVersion(raw: Record<string, unknown>): void {\n if (!('version' in raw)) {\n throw new CommerceError('CONFIG_INVALID', 'Configuration is missing required field \"version\"', {\n details: { path: 'version' },\n });\n }\n const rawVersion = raw['version'];\n const version = typeof rawVersion === 'string' ? Number(rawVersion) : rawVersion;\n if (version !== SUPPORTED_CONFIG_VERSION) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Unsupported config version \"${String(rawVersion)}\": this gateway only supports version ${SUPPORTED_CONFIG_VERSION}`,\n { details: { path: 'version', supported: SUPPORTED_CONFIG_VERSION } },\n );\n }\n}\n\nfunction parseWithZod<T>(schema: z.ZodType<T>, value: unknown): T {\n const result = schema.safeParse(value);\n if (!result.success) {\n throw zodErrorToConfigError(result.error);\n }\n return result.data;\n}\n\nfunction zodErrorToConfigError(error: ZodError): CommerceError {\n const issues = error.issues.map(describeIssue);\n const first = issues[0];\n const message = first\n ? `Configuration invalid at \"${first.path}\": ${first.message}`\n : 'Configuration invalid';\n return new CommerceError('CONFIG_INVALID', message, { details: { issues } });\n}\n\nfunction describeIssue(issue: ZodIssue): { path: string; message: string; code: string } {\n const path = issue.path.length > 0 ? issue.path.join('.') : '$';\n return { path, message: issue.message, code: issue.code };\n}\n\n// ---------------------------------------------------------------------------\n// Numeric / boolean coercion (explicit, not via Zod — see file header).\n// ---------------------------------------------------------------------------\n\nfunction toNumber(\n value: number | string,\n path: string,\n bounds: { min?: number; max?: number } = {},\n): number {\n // `Number('')` is 0 — finite, integral, and inside\n // `server.port`'s deliberate `min: 0` (\"let the OS pick\"). So `port: ${PORT:-}`\n // or an exported-but-empty PORT validated PASS and the gateway bound a random\n // port, after which `doctor` derived `http://127.0.0.1:0`, failed to connect,\n // and reported the gateway unreachable while it was serving. `Number` also\n // accepts `\"0x50\"` (80) and `\"1e3\"` (1000) for fields that are decimal\n // integers everywhere they are documented. Require plain digits instead.\n if (typeof value === 'string' && !/^\\s*\\d+\\s*$/.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be an integer written in decimal digits (got ${value === '' ? 'an empty string' : `\"${value}\"`})`,\n { details: { path } },\n );\n }\n const n = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(n) || !Number.isInteger(n)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be an integer`,\n {\n details: { path },\n },\n );\n }\n if (bounds.min !== undefined && n < bounds.min) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be >= ${bounds.min}`,\n {\n details: { path },\n },\n );\n }\n if (bounds.max !== undefined && n > bounds.max) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be <= ${bounds.max}`,\n {\n details: { path },\n },\n );\n }\n return n;\n}\n\nfunction toBoolean(value: boolean | string, path: string): boolean {\n if (typeof value === 'boolean') return value;\n const normalized = value.trim().toLowerCase();\n if (normalized === 'true') return true;\n if (normalized === 'false') return false;\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must be a boolean (\"true\" or \"false\")`,\n { details: { path } },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Business-rule validation + normalisation into the canonical shape.\n// ---------------------------------------------------------------------------\n\nconst SUPPORTED_PROTOCOLS = new Set(['http', 'mcp']);\nconst SUPPORTED_PAYMENT_METHODS = new Set(['x402']);\n\nfunction normalise(raw: RawConfig): GatewayConfig {\n const protocols = {\n http: { enabled: toBoolean(raw.protocols.http.enabled, 'protocols.http.enabled') },\n mcp: {\n enabled: toBoolean(raw.protocols.mcp.enabled, 'protocols.mcp.enabled'),\n mountPath: raw.protocols.mcp.mountPath,\n },\n };\n\n const x402Raw = raw.payments.x402;\n const facilitator: X402FacilitatorConfig | undefined =\n x402Raw === undefined\n ? undefined\n : x402Raw.facilitator.mode === 'local'\n ? { mode: 'local', signerPrivateKey: x402Raw.facilitator.signerPrivateKey }\n : {\n mode: 'remote',\n url: x402Raw.facilitator.url,\n auth: x402Raw.facilitator.auth ?? { type: 'none' },\n };\n const x402 =\n x402Raw && facilitator\n ? {\n enabled: toBoolean(x402Raw.enabled, 'payments.x402.enabled'),\n network: x402Raw.network,\n rpcUrl: x402Raw.rpcUrl,\n asset: x402Raw.asset,\n assetName: x402Raw.assetName,\n assetVersion: x402Raw.assetVersion,\n assetDecimals: toNumber(x402Raw.assetDecimals, 'payments.x402.assetDecimals', {\n min: 0,\n max: 36,\n }),\n payTo: x402Raw.payTo,\n maxTimeoutSeconds: toNumber(\n x402Raw.maxTimeoutSeconds,\n 'payments.x402.maxTimeoutSeconds',\n {\n min: 1,\n },\n ),\n facilitator,\n ...(x402Raw.allowMainnet !== undefined\n ? { allowMainnet: toBoolean(x402Raw.allowMainnet, 'payments.x402.allowMainnet') }\n : {}),\n ...(x402Raw.allowUnauthenticatedFacilitator !== undefined\n ? {\n allowUnauthenticatedFacilitator: toBoolean(\n x402Raw.allowUnauthenticatedFacilitator,\n 'payments.x402.allowUnauthenticatedFacilitator',\n ),\n }\n : {}),\n }\n : undefined;\n\n if (x402) {\n validateAddress('payments.x402.payTo', x402.payTo);\n validateAddress('payments.x402.asset', x402.asset);\n // The same call the provider makes at construction, run here so\n // `agent-commerce validate` reports an unsafe deployment where an operator\n // expects to hear about it, rather than at first boot.\n resolveX402Deployment({\n network: x402.network,\n payTo: x402.payTo,\n asset: x402.asset,\n assetName: x402.assetName,\n assetVersion: x402.assetVersion,\n facilitator: x402.facilitator,\n ...(x402.allowMainnet !== undefined ? { allowMainnet: x402.allowMainnet } : {}),\n ...(x402.allowUnauthenticatedFacilitator !== undefined\n ? { allowUnauthenticatedFacilitator: x402.allowUnauthenticatedFacilitator }\n : {}),\n });\n }\n\n const resources = Object.entries(raw.resources).map(([id, entry]) =>\n normaliseResource(id, entry, protocols, x402),\n );\n\n return {\n version: SUPPORTED_CONFIG_VERSION,\n merchant: {\n id: raw.merchant.id,\n name: raw.merchant.name,\n publicBaseUrl: raw.merchant.publicBaseUrl,\n },\n // min 0, not 1: port 0 is the standard \"let the OS pick a free port\"\n // convention, useful for tests and ephemeral dev/demo instances.\n server: {\n port: toNumber(raw.server.port, 'server.port', { min: 0, max: 65535 }),\n host: raw.server.host,\n ...(raw.server.adminToken !== undefined ? { adminToken: raw.server.adminToken } : {}),\n allowedOrigins: raw.server.allowedOrigins ?? [],\n },\n storage: { receipts: { driver: 'sqlite', path: raw.storage.receipts.path } },\n protocols,\n resources,\n payments: {\n ...(x402 !== undefined ? { x402 } : {}),\n },\n };\n}\n\ninterface NormalisedProtocols {\n readonly http: { readonly enabled: boolean };\n readonly mcp: { readonly enabled: boolean; readonly mountPath: string };\n}\n\ninterface NormalisedX402 {\n readonly enabled: boolean;\n readonly assetDecimals: number;\n}\n\nfunction normaliseResource(\n id: string,\n entry: RawResourceEntry,\n protocols: NormalisedProtocols,\n x402: NormalisedX402 | undefined,\n): CommerceResource {\n if (entry.input !== undefined) validateResourceSchemaKeywords(id, 'input', entry.input);\n\n const inputProperties = entry.input?.['properties'];\n if (\n inputProperties &&\n typeof inputProperties === 'object' &&\n PAYMENT_INPUT_FIELD in inputProperties\n ) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" declares an input property \"${PAYMENT_INPUT_FIELD}\", which is reserved for payment proofs`,\n {\n details: {\n path: `resources.${id}.input.properties.${PAYMENT_INPUT_FIELD}`,\n resourceId: id,\n },\n },\n );\n }\n\n for (const protocol of entry.expose) {\n if (!SUPPORTED_PROTOCOLS.has(protocol)) {\n const hint = protocol === 'ucp' ? ' (UCP is planned, not supported in this release)' : '';\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" exposes unsupported protocol \"${protocol}\"${hint}. Supported: http, mcp.`,\n { details: { path: `resources.${id}.expose`, resourceId: id, protocol } },\n );\n }\n }\n if (entry.expose.includes('mcp')) {\n if (!protocols.mcp.enabled) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" is exposed via \"mcp\" but protocols.mcp.enabled is false`,\n { details: { path: `resources.${id}.expose`, resourceId: id } },\n );\n }\n if (!MCP_TOOL_NAME_PATTERN.test(id)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" is exposed via \"mcp\" but its id is not a legal MCP tool name (allowed: A-Z, a-z, 0-9, \"_\", \"-\", \".\", 1-128 chars)`,\n { details: { path: `resources.${id}`, resourceId: id } },\n );\n }\n }\n if (entry.expose.includes('http') && !protocols.http.enabled) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" is exposed via \"http\" but protocols.http.enabled is false`,\n { details: { path: `resources.${id}.expose`, resourceId: id } },\n );\n }\n\n validateBackendUrl(id, entry.backend.url);\n validatePathParametersDeclared(id, entry.backend.url, entry.input);\n\n if (entry.pricing.type === 'dynamic') {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" uses pricing.type \"dynamic\", which is not supported in this release`,\n { details: { path: `resources.${id}.pricing.type`, resourceId: id } },\n );\n }\n\n if (entry.pricing.type === 'fixed') {\n validatePricingAmount(id, entry.pricing.amount, x402);\n }\n\n const paymentMethods = entry.payments ?? [];\n\n if (entry.pricing.type === 'fixed') {\n if (paymentMethods.length === 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has fixed pricing but declares no \"payments\" (a paid resource must name at least one payment method)`,\n { details: { path: `resources.${id}.payments`, resourceId: id } },\n );\n }\n for (const method of paymentMethods) {\n if (!SUPPORTED_PAYMENT_METHODS.has(method)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" names unsupported payment method \"${method}\". Supported: x402.`,\n { details: { path: `resources.${id}.payments`, resourceId: id, method } },\n );\n }\n if (method === 'x402' && (!x402 || !x402.enabled)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" names payment method \"x402\" which is not configured or not enabled under payments.x402`,\n { details: { path: `resources.${id}.payments`, resourceId: id, method } },\n );\n }\n }\n }\n\n const pricing: Pricing =\n entry.pricing.type === 'free'\n ? { type: 'free' }\n : { type: 'fixed', amount: entry.pricing.amount, currency: entry.pricing.currency };\n\n return {\n id,\n name: entry.name,\n ...(entry.description !== undefined ? { description: entry.description } : {}),\n inputSchema:\n entry.input !== undefined\n ? defaultClosedObjectSchema(entry.input)\n : EMPTY_CLOSED_OBJECT_SCHEMA,\n ...(entry.output !== undefined ? { outputSchema: entry.output } : {}),\n handler: {\n type: 'http',\n method: entry.backend.method,\n url: entry.backend.url,\n ...(entry.backend.headers !== undefined ? { headers: entry.backend.headers } : {}),\n ...(entry.backend.timeoutMs !== undefined\n ? {\n timeoutMs: toNumber(entry.backend.timeoutMs, `resources.${id}.backend.timeoutMs`, {\n min: 1,\n }),\n }\n : {}),\n },\n pricing,\n exposedVia: entry.expose as CommerceResource['exposedVia'],\n paymentMethods: paymentMethods as CommerceResource['paymentMethods'],\n };\n}\n\n/**\n * `{param}` templates (e.g. `.../weather/{city}`) parse fine as a URL — the\n * WHATWG parser just percent-encodes the braces — so this only rejects\n * genuinely malformed strings and non-http(s) schemes, not templating.\n */\n/**\n * Permissive-by-default is the wrong default for a value forwarded to\n * someone else's API: an object schema that\n * omits `additionalProperties` defaults, per JSON Schema itself, to\n * \"anything goes\" — so default it to `false` here instead, unless the\n * operator set it explicitly (including explicitly to `true`, which is\n * respected).\n *\n * An earlier fix only stamped the ROOT schema, so\n * `filter: { type: object }` *looked* closed (the top level really was)\n * while every key one level down under `properties.filter` still passed\n * verbatim — `core`'s validator (execution/validation.ts) only enforces\n * `additionalProperties` where the schema states it explicitly, at every\n * level independently. Recurse into `properties` and `items` the same way\n * `validateResourceSchemaKeywords` below already does, so \"closed\" actually\n * means closed at every depth, not just the one an operator happened to\n * write `additionalProperties: false` on.\n *\n * `type` can be an array (`[\"object\",\"null\"]`, valid JSON\n * Schema) — a bare `=== 'object'` string comparison missed it, so a schema\n * in that shape got stamped as open. `declaresObjectType` below is the same\n * check `core`'s validator now makes (`execution/validation.ts`'s\n * `isObjectSchemaNode`) so the two stay in agreement.\n */\nfunction defaultClosedObjectSchema(schema: Record<string, unknown>): Record<string, unknown> {\n // imported, never re-implemented. The local predicate this\n // replaces recognised `type`/`properties` but not `required`, while core's\n // validator recognised `properties`/`required` — so `input: { required: [q] }`\n // was an object to the validator and not to the stamper, and every unknown\n // key sailed through to the merchant backend. One definition, one drift.\n const isObjectSchema = isObjectSchemaNode(schema);\n const result: Record<string, unknown> = { ...schema };\n\n if (isObjectSchema) {\n const properties = schema['properties'];\n if (isPlainObject(properties)) {\n result['properties'] = Object.fromEntries(\n Object.entries(properties).map(([key, sub]) => [\n key,\n isPlainObject(sub) ? defaultClosedObjectSchema(sub) : sub,\n ]),\n );\n }\n if (!Object.hasOwn(schema, 'additionalProperties')) {\n result['additionalProperties'] = false;\n }\n }\n\n const items = schema['items'];\n if (isPlainObject(items)) {\n result['items'] = defaultClosedObjectSchema(items);\n }\n\n // The third place this stamper drifted from the validator, after `required`\n // and tuple `items`. `additionalProperties: {schema}` is the idiomatic\n // \"map of typed objects\" shape, and core's validator applies that subschema\n // recursively at unbounded depth — so without this branch, every node under\n // it stayed open and unknown keys reached the merchant backend. Recursion\n // here is not conditional on `isObjectSchema`: the validator applies the\n // subschema wherever it finds one.\n const additional = schema['additionalProperties'];\n if (isPlainObject(additional)) {\n result['additionalProperties'] = defaultClosedObjectSchema(additional);\n }\n\n return result;\n}\n\n/**\n * A resource that declares no `input:` at all got\n * `inputSchema: undefined`, and `compileJsonSchema(undefined)` is an\n * always-valid validator — every caller key was forwarded to the merchant\n * backend verbatim. The decision: default \"declared nothing\" to \"accepts\n * nothing\" (an empty closed object) rather than rejecting the config at load\n * time — a no-argument resource that omits `input:` is a legitimate shape,\n * and rejecting it would break every existing config that uses it.\n */\nconst EMPTY_CLOSED_OBJECT_SCHEMA: Record<string, unknown> = {\n type: 'object',\n properties: {},\n additionalProperties: false,\n};\n\n/**\n * `src/core`'s validator only enforces the subset documented in\n * `execution/validation.ts` (type/properties/required/additionalProperties/\n * enum/items) — everything else (`pattern`, `minLength`, `format`, `oneOf`,\n * …) is silently ignored at runtime. An operator who writes `pattern` and\n * never sees it enforced has no way to know that from the config alone, so\n * warn at load time instead of letting them find out the hard way.\n */\nconst UNSUPPORTED_SCHEMA_KEYWORDS = [\n 'pattern',\n 'minLength',\n 'maxLength',\n 'format',\n 'minimum',\n 'maximum',\n 'exclusiveMinimum',\n 'exclusiveMaximum',\n 'multipleOf',\n 'oneOf',\n 'anyOf',\n 'allOf',\n 'not',\n '$ref',\n 'const',\n 'patternProperties',\n 'minItems',\n 'maxItems',\n 'uniqueItems',\n];\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** `type` explicitly set to something that rules out \"object\" (a bare\n * value, or an array not containing \"object\"). `undefined` — no `type` at\n * all — is deliberately NOT treated as excluding: core's validator treats\n * `properties`/`required` with no `type` as an object schema, so that shape\n * is fine, not another instance of this bug. */\nfunction excludesObjectType(schema: Record<string, unknown>): boolean {\n const type = schema['type'];\n if (type === undefined || type === 'object') return false;\n if (Array.isArray(type)) return !type.includes('object');\n return true;\n}\n\n/**\n * Walks a resource's input schema once, both warning (existing, unenforced\n * keywords) and rejecting (a node whose declared `type`\n * cannot structurally be an object, yet which still carries `properties` or\n * `required`). The `properties`/`required`-with-no-`type` shape is not\n * this function's problem any more, since the\n * validator now treats that shape as an object; what's still a trap is a\n * `type` that actively rules \"object\" out while `properties`/`required`\n * imply it was meant to be one, e.g. a copy-pasted sibling schema whose\n * `type` was never updated. Rejecting (not just warning) here is the\n * decision — a warning is exactly what let this bug class ship silently in\n * the first place (`validate`/`doctor` both said PASS).\n */\nfunction validateResourceSchemaKeywords(\n id: string,\n path: string,\n schema: Record<string, unknown>,\n): void {\n for (const keyword of UNSUPPORTED_SCHEMA_KEYWORDS) {\n if (Object.hasOwn(schema, keyword)) {\n // eslint-disable-next-line no-console\n console.warn(\n `[agent-commerce] resource \"${id}\" ${path} uses JSON Schema keyword \"${keyword}\", which this gateway does not enforce (see src/core/execution/validation.ts for the supported subset). Remove it or treat it as documentation only.`,\n );\n }\n }\n if (\n (Object.hasOwn(schema, 'properties') || Object.hasOwn(schema, 'required')) &&\n excludesObjectType(schema)\n ) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" ${path} declares \"properties\" and/or \"required\" but its \"type\" (${JSON.stringify(schema['type'])}) does not include \"object\" — the validator will never route a value through either check under that type, so this schema claims to constrain input it does not actually enforce. Remove \"properties\"/\"required\", or include \"object\" in \"type\".`,\n { details: { path: `resources.${id}.${path}`, resourceId: id } },\n );\n }\n // the other half. Closing a `required`-only node is\n // correct JSON Schema and quietly unsatisfiable: `required: [\"q\"]` demands a\n // property that `properties` never declares, so the stamped\n // `additionalProperties: false` rejects `q` as an unknown key — the schema\n // can never be satisfied by any input at all. Fail-closed, so no money is at\n // risk, but every call would 400 with a config that loaded cleanly. Say so\n // at load instead. Only when the node really will be closed: an explicit\n // `additionalProperties` other than `false` leaves the name reachable.\n const requiredRaw = schema['required'];\n const closed = !Object.hasOwn(schema, 'additionalProperties')\n ? true\n : schema['additionalProperties'] === false;\n if (Array.isArray(requiredRaw) && closed && isObjectSchemaNode(schema)) {\n const declared = isPlainObject(schema['properties']) ? schema['properties'] : {};\n const undeclared = requiredRaw.filter(\n (name): name is string => typeof name === 'string' && !Object.hasOwn(declared, name),\n );\n if (undeclared.length > 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" ${path} lists ${undeclared.map((n) => `\"${n}\"`).join(', ')} in \"required\" but does not declare ${undeclared.length === 1 ? 'it' : 'them'} in \"properties\". The schema is closed (additionalProperties: false), so ${undeclared.length === 1 ? 'that name is' : 'those names are'} rejected as an unknown key and no input can ever satisfy this schema. Declare ${undeclared.length === 1 ? 'it' : 'them'} in \"properties\".`,\n { details: { path: `resources.${id}.${path}`, resourceId: id, undeclared } },\n );\n }\n }\n\n const properties = schema['properties'];\n if (isPlainObject(properties)) {\n for (const [key, sub] of Object.entries(properties)) {\n if (isPlainObject(sub)) validateResourceSchemaKeywords(id, `${path}.properties.${key}`, sub);\n }\n }\n const additional = schema['additionalProperties'];\n if (isPlainObject(additional)) {\n validateResourceSchemaKeywords(id, `${path}.additionalProperties`, additional);\n }\n const items = schema['items'];\n if (isPlainObject(items)) {\n validateResourceSchemaKeywords(id, `${path}.items`, items);\n } else if (Array.isArray(items)) {\n // tuple-form `items` (an array of per-position\n // schemas) is valid JSON Schema, but `core`'s validator only supports\n // the single-schema form applied to every element — a tuple silently\n // enforces nothing, invisibly rather than wrongly, so warn the same way\n // an unsupported keyword does.\n // eslint-disable-next-line no-console\n console.warn(\n `[agent-commerce] resource \"${id}\" ${path}.items is a tuple (an array of schemas), which this gateway does not enforce — only a single schema applied to every array element is supported (see src/core/execution/validation.ts). Each position's schema is unenforced; treat it as documentation only.`,\n );\n }\n}\n\n/**\n * `amount: z.string().min(1)` alone let \"0,01\", \"$0.01\", \"1e-2\", \"-1\" and an\n * over-precise \"0.0000001\" all pass config + `doctor`, then throw on every\n * purchase. A plain\n * positive decimal only — no currency symbol, no thousands separator, no\n * exponent notation.\n */\nconst PRICING_AMOUNT_PATTERN = /^\\d+(?:\\.\\d+)?$/;\nconst ZERO_AMOUNT_PATTERN = /^0(?:\\.0+)?$/;\n\nfunction validatePricingAmount(id: string, amount: string, x402: NormalisedX402 | undefined): void {\n const path = `resources.${id}.pricing.amount`;\n if (!PRICING_AMOUNT_PATTERN.test(amount)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has pricing.amount \"${amount}\", which is not a plain positive decimal (no currency symbol, no thousands separator, no exponent — e.g. \"0.01\")`,\n { details: { path, resourceId: id } },\n );\n }\n if (ZERO_AMOUNT_PATTERN.test(amount)) {\n // A zero-priced \"paid\" resource settles a zero-value transfer, which is\n // nonsense — if something is free, it should say so.\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has pricing.amount \"0\" — a paid resource cannot cost zero; use \"pricing: { type: free }\" instead`,\n { details: { path, resourceId: id } },\n );\n }\n if (x402 !== undefined) {\n const fractionalDigits = amount.includes('.') ? (amount.split('.')[1]?.length ?? 0) : 0;\n if (fractionalDigits > x402.assetDecimals) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has pricing.amount \"${amount}\" with more precision (${fractionalDigits} fractional digits) than the configured asset supports (${x402.assetDecimals} decimals)`,\n { details: { path, resourceId: id } },\n );\n }\n }\n}\n\n/**\n * The root-cause half. `validateBackendRequestShape`\n * (src/core) rejects a missing path parameter at request time — after\n * schema validation but, without this check, on every single call, because\n * a schema that never declares `{city}` can never satisfy it. A paid\n * resource in that shape settles the buyer's payment and then always fails\n * to reach the backend: no refund, replay key burned, on every call, not an\n * unlucky one. Every `{param}` in `backend.url` must be BOTH declared in\n * `properties` AND listed in `required` — an optional value hits the exact\n * same \"caller structurally cannot supply it on every call that omits it\"\n * problem as an undeclared one, just less often. This is the config-load\n * gate `agent-commerce validate`/`doctor` catch it at; the runtime\n * `INPUT_INVALID` in `validateBackendRequestShape` is defence in depth for\n * a hand-built `CommerceResource` this check never saw.\n */\nfunction validatePathParametersDeclared(\n id: string,\n url: string,\n input: Record<string, unknown> | undefined,\n): void {\n // Before anything else: a brace token the canonical grammar does not\n // recognise is neither extracted here nor substituted at request time, so it\n // would travel to the backend as a percent-encoded literal. On a paid\n // resource that is payment-without-delivery on every single call. Refuse it\n // at load rather than letting \"matches nothing\" mean \"nothing to check\".\n const stray = findUnparsedBraceToken(url);\n if (stray !== undefined) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has backend.url containing \"${stray}\", which is not a valid path parameter (allowed characters: A-Z a-z 0-9 _ . -). It would be sent to the backend literally, so a paid resource would settle payment and then never reach the backend`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id, token: stray } },\n );\n }\n\n const params = extractPathParameterNames(url);\n if (params.length === 0) return;\n\n // Every defence around `{param}` guards the *path* position, and in the host\n // position all of them fail open at once: `new URL('http://{host}/api')`\n // parses (the hostname is literally `{host}`) so the URL check passes; the\n // runtime containment check is skipped because its literal prefix\n // (`http://`) does not itself parse as a URL; and `encodeURIComponent` does\n // not escape dots, so a hostname survives it whole. Caller input then chooses\n // which host the gateway calls — the metadata service, an internal address,\n // anything. `http://{region}.api.internal/...` is an ordinary-looking\n // multi-tenant template, so this is refused here rather than warned about.\n //\n // The rule: everything before the first `{` must already be a complete\n // authority — a parseable origin followed by the path's leading `/`.\n const firstBrace = url.indexOf('{');\n if (firstBrace !== -1) {\n const prefix = url.slice(0, firstBrace);\n let origin: string | undefined;\n try {\n const parsedPrefix = new URL(prefix);\n origin = parsedPrefix.hostname === '' ? undefined : parsedPrefix.origin;\n } catch {\n // Not a URL at all — the parameter starts before the authority is done.\n }\n if (origin === undefined || !prefix.startsWith(`${origin}/`)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has a backend.url parameter before the end of the host (\"${url}\"). A caller-supplied value would choose which host the gateway calls, which is request forgery with the gateway's own network position. Parameters are supported inside the path and query only`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id } },\n );\n }\n }\n\n const propertiesRaw = input?.['properties'];\n const properties = isPlainObject(propertiesRaw) ? propertiesRaw : {};\n const requiredRaw = input?.['required'];\n const required = new Set(\n Array.isArray(requiredRaw)\n ? requiredRaw.filter((entry): entry is string => typeof entry === 'string')\n : [],\n );\n\n for (const param of params) {\n const path = `resources.${id}.backend.url`;\n if (!Object.hasOwn(properties, param)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has backend.url path parameter \"{${param}}\" which is not declared in its input schema — the caller has no way to supply it, so every call would settle payment (if priced) and then fail to reach the backend`,\n { details: { path, resourceId: id, param } },\n );\n }\n if (!required.has(param)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has backend.url path parameter \"{${param}}\" declared in its input schema but not listed in \"required\" — a caller that omits it hits the same unservable-request problem as an undeclared parameter`,\n { details: { path, resourceId: id, param } },\n );\n }\n }\n}\n\nfunction validateBackendUrl(id: string, url: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has an invalid backend.url \"${url}\": must be an absolute http:// or https:// URL`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id } },\n );\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Resource \"${id}\" has a backend.url with scheme \"${parsed.protocol}\": must be http:// or https://`,\n { details: { path: `resources.${id}.backend.url`, resourceId: id } },\n );\n }\n}\n\nfunction validateAddress(path: string, value: string): void {\n if (!ADDRESS_PATTERN.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" is not a plausible address (expected \"0x\" followed by 40 hex characters)`,\n { details: { path } },\n );\n }\n if (ZERO_ADDRESS_PATTERN.test(value)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration value at \"${path}\" must not be the zero address`,\n {\n details: { path },\n },\n );\n }\n}\n","/**\n * Locates and parses `config.yaml`, then hands the raw value to\n * `parseConfig`. Never trusts raw YAML before Zod validation.\n */\nimport { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport { parse as parseYaml, YAMLError } from 'yaml';\nimport { CommerceError } from '../core/index.js';\nimport { DEFAULT_CONFIG_FILENAME } from './filename.js';\nimport { type GatewayConfig, parseConfig } from './schema.js';\n\nconst CONFIG_PATH_ENV_VAR = 'AGENT_COMMERCE_CONFIG';\n\nexport interface LoadConfigOptions {\n readonly path?: string;\n readonly env?: NodeJS.ProcessEnv;\n readonly cwd?: string;\n}\n\nexport async function loadConfig(options: LoadConfigOptions = {}): Promise<GatewayConfig> {\n const env = options.env ?? process.env;\n const cwd = options.cwd ?? process.cwd();\n const configPath = resolveConfigPath(options.path, env, cwd);\n\n let text: string;\n try {\n text = await fs.readFile(configPath, 'utf8');\n } catch (error) {\n throw new CommerceError('CONFIG_INVALID', `Could not read configuration file \"${configPath}\"`, {\n details: { path: configPath },\n cause: error,\n });\n }\n\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (error) {\n const { reason, details } = describeYamlError(error);\n throw new CommerceError(\n 'CONFIG_INVALID',\n `Configuration file \"${configPath}\" is not valid YAML: ${reason}`,\n {\n details: { path: configPath, ...details },\n // Retained for programmatic callers. Nothing in the CLI prints a\n // `cause`, and nothing should start: this is the object whose\n // `.message` carries the source excerpt (see below).\n cause: error,\n },\n );\n }\n\n return parseConfig(raw, env);\n}\n\n/**\n * A YAML failure described from the error's *structured* fields only.\n *\n * Deliberately not `error.message`: the `yaml` package builds that message\n * with a **code frame excerpt of the source line**, so a syntax error next to\n * an inline secret would reproduce it verbatim into `validate`/`doctor` output — including `doctor --json`, the output most\n * likely to be pasted into an issue or captured by CI:\n *\n * … is not valid YAML: Nested mappings are not allowed … at line 2, column 15:\n *\n * adminToken: super-secret-token-value\n * ^\n *\n * `server.adminToken` and `payments.x402.facilitator.signerPrivateKey` are\n * both legal as inline literals, so this was a real sink rather than a\n * hypothetical one — and it contradicted `validate`'s own promise never to\n * print a resolved value: it never printed a resolved `${ENV}`, only an\n * inlined one. `code` and `linePos` locate the fault exactly as well and\n * cannot contain file content.\n */\n/**\n * Plain-English phrasing for the codes an operator actually hits, so replacing\n * the excerpt does not also cost the diagnostic its readability. These are\n * fixed strings chosen here — they can never contain file content, which is\n * the entire property that matters. Anything unlisted degrades to the bare\n * code, which is still precise.\n */\nconst YAML_ERROR_EXPLANATIONS: Readonly<Record<string, string>> = {\n DUPLICATE_KEY: 'map keys must be unique',\n BAD_INDENT: 'bad indentation',\n TAB_AS_INDENT: 'tabs cannot be used for indentation',\n MISSING_CHAR: 'a required character is missing',\n BLOCK_AS_IMPLICIT_KEY: 'a block value cannot be used as a key (missing quotes, or a stray colon)',\n MULTILINE_IMPLICIT_KEY: 'a key spans multiple lines (missing quotes, or a stray colon)',\n UNEXPECTED_TOKEN: 'unexpected token',\n};\n\nfunction describeYamlError(error: unknown): {\n reason: string;\n details: Record<string, unknown>;\n} {\n if (!(error instanceof YAMLError)) {\n return { reason: 'unknown YAML parse error', details: {} };\n }\n const start = error.linePos?.[0];\n const where =\n start === undefined ? '' : ` at line ${String(start.line)}, column ${String(start.col)}`;\n const explanation = YAML_ERROR_EXPLANATIONS[error.code];\n const what = explanation === undefined ? error.code : `${error.code} (${explanation})`;\n return {\n reason: `${what}${where}`,\n details: {\n yamlErrorCode: error.code,\n ...(start === undefined ? {} : { line: start.line, column: start.col }),\n },\n };\n}\n\nfunction resolveConfigPath(\n explicitPath: string | undefined,\n env: NodeJS.ProcessEnv,\n cwd: string,\n): string {\n if (explicitPath) return path.resolve(cwd, explicitPath);\n const fromEnv = env[CONFIG_PATH_ENV_VAR];\n if (fromEnv) return path.resolve(cwd, fromEnv);\n return path.resolve(cwd, DEFAULT_CONFIG_FILENAME);\n}\n","/**\n * src/config\n *\n * `config.yaml` schema, loader and environment substitution.\n */\n\nexport { substituteEnv } from './env.js';\nexport type { LoadConfigOptions } from './load.js';\nexport { loadConfig } from './load.js';\nexport type { GatewayConfig } from './schema.js';\nexport { parseConfig } from './schema.js';\n","import { Command } from 'commander';\nimport { DEFAULT_CONFIG_FILENAME } from '../config/filename.js';\nimport { runDemo } from './commands/demo.js';\nimport { printDoctorReport, runDoctor } from './commands/doctor.js';\nimport { runInit } from './commands/init.js';\nimport { runValidate } from './commands/validate.js';\nimport { runVersion } from './commands/version.js';\nimport { type Io, processIo } from './lib/io.js';\nimport { readVersionReport } from './lib/versions.js';\n\n/**\n * Builds the `agent-commerce` Commander program.\n *\n * `io` is injectable so tests can capture output instead of writing to the\n * real process streams; `exitOverride()` + `configureOutput()` mean\n * `--help`/errors never call `process.exit()` directly, so a caller (index.ts\n * or a test) fully controls process lifecycle.\n */\nexport function buildProgram(io: Io = processIo): Command {\n const program = new Command();\n\n program\n .name('agent-commerce')\n .description('CLI for the Agent Commerce Gateway: init, validate, doctor, demo.')\n // `--version` is required of the published binary. The `version`\n // subcommand stays: it additionally prints the pinned protocol/SDK\n // versions, which is what `doctor` and the support matrix are checked\n // against. Both read the same source, so they cannot disagree.\n .version(readVersionReport().cliVersion, '-v, --version', 'Print the CLI version.')\n .exitOverride()\n .configureOutput({\n writeOut: (str) => io.stdout(str.replace(/\\n+$/, '')),\n writeErr: (str) => io.stderr(str.replace(/\\n+$/, '')),\n });\n\n program\n .command('version')\n .description('Print the CLI version and pinned protocol/SDK versions.')\n .action(() => {\n process.exitCode = runVersion(io);\n });\n\n program\n .command('validate')\n .description(`Validate ${DEFAULT_CONFIG_FILENAME} and exit non-zero if it is invalid.`)\n .option('--config <path>', `path to ${DEFAULT_CONFIG_FILENAME}`)\n .action(async (opts: { config?: string }) => {\n const code = await runValidate(\n opts.config !== undefined ? { configPath: opts.config } : {},\n io,\n );\n process.exitCode = code;\n });\n\n program\n .command('doctor')\n .description('Diagnose config, gateway, backend, protocol and payment health.')\n .option('--config <path>', `path to ${DEFAULT_CONFIG_FILENAME}`)\n .option(\n '--gateway <url>',\n 'gateway base URL (default: derived from config, else http://localhost:8080)',\n )\n .option('--json', 'emit machine-readable JSON instead of a formatted report', false)\n .action(async (opts: { config?: string; gateway?: string; json?: boolean }) => {\n const report = await runDoctor({\n ...(opts.config !== undefined ? { configPath: opts.config } : {}),\n ...(opts.gateway !== undefined ? { gatewayUrl: opts.gateway } : {}),\n });\n printDoctorReport(report, io, opts.json === true);\n process.exitCode = report.exitCode;\n });\n\n program\n .command('init')\n .description(`Interactively generate ${DEFAULT_CONFIG_FILENAME}.`)\n .option('--output <path>', 'output path', DEFAULT_CONFIG_FILENAME)\n .option('--force', 'overwrite an existing file', false)\n .option('--yes', 'use non-interactive defaults (required for scripting/tests)', false)\n .action(async (opts: { output: string; force: boolean; yes: boolean }) => {\n const code = await runInit({ outputPath: opts.output, force: opts.force, yes: opts.yes }, io);\n process.exitCode = code;\n });\n\n program\n .command('demo')\n .description(\n 'Run the documented docker compose + demo agent quickstart, verifying health between steps.',\n )\n .action(async () => {\n process.exitCode = await runDemo(io);\n });\n\n return program;\n}\n","/**\n * `agent-commerce demo` — a thin, honest wrapper around the documented\n * `docker compose up` + `npm run demo:agent` steps (README/ commands).\n *\n * No orchestration magic: each step's exit code is checked, and a failing\n * step is reported with exactly what failed and what to run to retry it, not\n * swallowed into a generic \"demo failed\" message.\n */\nimport type { Io } from '../lib/io.js';\n\nexport interface DemoStep {\n readonly name: string;\n readonly command: string;\n readonly args: readonly string[];\n /** Optional health check run after the step; returns true when healthy. */\n readonly healthCheck?: () => Promise<boolean>;\n}\n\nexport interface RunResult {\n readonly code: number;\n readonly stderrTail?: string;\n}\n\nexport type RunCommand = (command: string, args: readonly string[]) => Promise<RunResult>;\n\nexport interface DemoDeps {\n readonly run?: RunCommand;\n readonly steps?: readonly DemoStep[];\n}\n\nexport function defaultDemoSteps(): readonly DemoStep[] {\n return [\n {\n name: 'Start local chain + gateway + merchant (docker compose)',\n command: 'docker',\n args: ['compose', 'up', '--build', '-d'],\n },\n { name: 'Run the deterministic buyer agent', command: 'npm', args: ['run', 'demo:agent'] },\n ];\n}\n\n/** `agent-commerce demo`. Returns process exit code. */\nexport async function runDemo(io: Io, deps: DemoDeps = {}): Promise<number> {\n const steps = deps.steps ?? defaultDemoSteps();\n const run = deps.run ?? execCommand;\n\n io.stdout('agent-commerce demo — running the documented quickstart steps:');\n for (const step of steps) {\n io.stdout('');\n io.stdout(`==> ${step.name}`);\n io.stdout(` $ ${step.command} ${step.args.join(' ')}`);\n const result = await run(step.command, step.args);\n if (result.code !== 0) {\n io.stderr(`FAIL \"${step.name}\" exited with code ${result.code}.`);\n if (result.stderrTail !== undefined && result.stderrTail.length > 0) {\n io.stderr(result.stderrTail);\n }\n io.stderr('');\n io.stderr('Nothing further was run. To retry manually:');\n io.stderr(` ${step.command} ${step.args.join(' ')}`);\n return 1;\n }\n if (step.healthCheck !== undefined) {\n const healthy = await step.healthCheck();\n if (!healthy) {\n io.stderr(`FAIL \"${step.name}\" completed but its health check did not pass.`);\n return 1;\n }\n }\n io.stdout(`OK ${step.name}`);\n }\n io.stdout('');\n io.stdout('PASS Demo is up. Try: agent-commerce doctor --config config-demo.yaml');\n return 0;\n}\n\nasync function execCommand(command: string, args: readonly string[]): Promise<RunResult> {\n const { spawn } = await import('node:child_process');\n return new Promise((resolvePromise) => {\n let stderr = '';\n const child = spawn(command, args, { stdio: ['ignore', 'inherit', 'pipe'] });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (err) => {\n resolvePromise({ code: 1, stderrTail: err.message });\n });\n child.on('close', (code) => {\n const tail = stderr.trim().split('\\n').slice(-10).join('\\n');\n resolvePromise({ code: code ?? 1, ...(tail.length > 0 ? { stderrTail: tail } : {}) });\n });\n });\n}\n","import { existsSync } from 'node:fs';\nimport picocolors from 'picocolors';\nimport { extractPathParameterNames } from '../../core/execution/index.js';\nimport { type CommerceResource, isCommerceError, type ReceiptStore } from '../../core/index.js';\nimport {\n describeDeploymentMode,\n findNetworkProfile,\n resolveDeploymentMode,\n} from '../../payments/x402/networks.js';\nimport { createSqliteReceiptStore } from '../../storage/receipts/index.js';\nimport { type ConfigLoader, type GatewayConfig, loadConfigDynamic } from '../lib/config-client.js';\nimport { type FetchLike, fetchJson } from '../lib/http.js';\nimport { PLACEHOLDER_ASSET_ADDRESS } from '../lib/init-config.js';\nimport type { Io } from '../lib/io.js';\nimport {\n fillEnvFromLocalChainManifest,\n LOCAL_CHAIN_MANIFEST_PATH,\n MANIFEST_FILLABLE_ENV_VAR_NAMES,\n type ManifestEnvFill,\n} from '../lib/manifest-env.js';\nimport { maskMiddle } from '../lib/mask.js';\nimport { readVersionReport } from '../lib/versions.js';\n\nexport type CheckStatus = 'PASS' | 'WARN' | 'FAIL' | 'INFO';\n\nexport interface DoctorCheck {\n readonly name: string;\n readonly status: CheckStatus;\n readonly detail: string;\n}\n\nexport interface DoctorReport {\n readonly checks: readonly DoctorCheck[];\n readonly score: { readonly passed: number; readonly total: number };\n readonly exitCode: number;\n}\n\nexport interface DoctorOptions {\n readonly configPath?: string;\n readonly gatewayUrl?: string;\n}\n\nexport interface DoctorDeps {\n readonly fetchImpl?: FetchLike;\n readonly loadConfig?: ConfigLoader;\n readonly createStore?: (path: string) => ReceiptStore;\n readonly fillEnvFromManifest?: (env: NodeJS.ProcessEnv) => ManifestEnvFill;\n}\n\nconst CHECK_TIMEOUT_MS = 1500;\n\nfunction deriveGatewayUrl(explicit: string | undefined, config: GatewayConfig | undefined): string {\n if (explicit !== undefined) return explicit.replace(/\\/$/, '');\n if (config !== undefined) {\n // `0.0.0.0` means \"all interfaces\"; probe the loopback one. `::` is its\n // IPv6 equivalent. A literal IPv6 host such as `::1`\n // must be bracketed or the derived URL is invalid (`http://::1:8080`) and\n // doctor reported every running gateway as unreachable.\n const raw = config.server.host;\n const host = raw === '0.0.0.0' ? '127.0.0.1' : raw === '::' ? '::1' : raw;\n const authority = host.includes(':') ? `[${host}]` : host;\n return `http://${authority}:${config.server.port}`;\n }\n return 'http://localhost:8080';\n}\n\n/**\n * Fill `{param}` slots with a probe value, using the *canonical* grammar.\n *\n * A local `/\\{[^}]+\\}/g` here would recognise more than the runtime does. A\n * kebab-case token like `{report-id}` would match here and not there, so\n * `doctor` would probe `/report/demo-check` — the URL the operator meant —\n * and report the backend reachable, while every real request went to\n * `/report/%7Breport-id%7D` and 404'd after settling payment. A diagnostic\n * that probes a URL the runtime would never build is\n * worse than no diagnostic: it certifies the broken thing as healthy. Anything\n * the shared extractor does not recognise is deliberately left as-is, so the\n * probe hits exactly what the gateway would send.\n */\nfunction substitutePathParams(url: string): string {\n let filled = url;\n for (const name of extractPathParameterNames(url)) {\n filled = filled.split(`{${name}}`).join('demo-check');\n }\n return filled;\n}\n\ninterface LiveX402 {\n readonly asset: string;\n readonly network: string;\n readonly payTo: string;\n}\n\n/**\n * Pulls the gateway's *effective* x402 settlement config out of\n * `/.well-known/agent-commerce` (src/gateway/well-known.ts). Returns\n * undefined for anything short of \"the gateway confirms x402 is enabled and\n * reports all three fields\" — a doctor cross-check must never itself become\n * an unchecked cast on network-supplied JSON.\n */\n/**\n * `undefined` must not be allowed to mean three different things — gateway\n * down, document malformed, and *the gateway positively reporting x402\n * disabled*. The third is not an absence of information, it is a\n * disagreement: local config enables x402, the running gateway says it does\n * not, which is exactly the deployment-mismatch this cross-check was built to\n * catch. Reporting it as \"could not be verified\" turned the finding into a\n * shrug. `'disabled'` separates it out.\n */\ntype LiveX402Result = LiveX402 | 'disabled' | undefined;\n\nfunction extractWellKnownX402(body: Record<string, unknown> | undefined): LiveX402Result {\n const payments = body?.['payments'];\n if (typeof payments !== 'object' || payments === null) return undefined;\n const x402 = (payments as Record<string, unknown>)['x402'];\n if (typeof x402 !== 'object' || x402 === null) return undefined;\n const rec = x402 as Record<string, unknown>;\n // Only an explicit `false` is a positive statement. Anything else (absent,\n // null, a non-boolean) is still \"cannot tell\".\n if (rec['enabled'] === false) return 'disabled';\n if (rec['enabled'] !== true) return undefined;\n const { asset, network, payTo } = rec;\n if (typeof asset !== 'string' || typeof network !== 'string' || typeof payTo !== 'string') {\n return undefined;\n }\n return { asset, network, payTo };\n}\n\n/** Addresses are checksum-insensitive throughout this project (src/config/schema.ts). */\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n\n/**\n * A doctor that reports healthy against a mismatched deployment is worse\n * than no diagnostic at all false-green finding). Compares\n * the gateway's live settlement config against what the local config\n * resolved to, and names both values so the operator knows exactly what to\n * check rather than just that something disagrees.\n */\nfunction findX402Mismatch(configured: LiveX402, live: LiveX402): string | undefined {\n const diffs: string[] = [];\n if (!sameAddress(configured.asset, live.asset)) {\n diffs.push(\n `asset: gateway is using ${live.asset} but local config resolves to ${configured.asset}`,\n );\n }\n if (configured.network !== live.network) {\n diffs.push(\n `network: gateway is using \"${live.network}\" but local config resolves to \"${configured.network}\"`,\n );\n }\n if (!sameAddress(configured.payTo, live.payTo)) {\n diffs.push(\n `payTo: gateway is using ${live.payTo} but local config resolves to ${configured.payTo}`,\n );\n }\n if (diffs.length === 0) return undefined;\n return `${diffs.join('; ')} — the gateway may be running against an older deployment; restart it or re-run chain:deploy`;\n}\n\n/** `agent-commerce doctor [--config] [--gateway] [--json]`. */\nexport async function runDoctor(\n options: DoctorOptions,\n deps: DoctorDeps = {},\n): Promise<DoctorReport> {\n const fetchImpl = deps.fetchImpl ?? globalThis.fetch;\n const loadConfig = deps.loadConfig ?? loadConfigDynamic;\n const createStore = deps.createStore ?? ((path: string) => createSqliteReceiptStore({ path }));\n const fillEnvFromManifest = deps.fillEnvFromManifest ?? fillEnvFromLocalChainManifest;\n\n const checks: DoctorCheck[] = [];\n let config: GatewayConfig | undefined;\n\n // 1. Config\n const { env, filled, manifestFound } = fillEnvFromManifest(process.env);\n const filledSuffix =\n filled.length > 0\n ? ` (using local chain manifest ${LOCAL_CHAIN_MANIFEST_PATH} for ${filled.join(', ')})`\n : '';\n try {\n config = await loadConfig({\n ...(options.configPath !== undefined ? { path: options.configPath } : {}),\n env,\n });\n checks.push({\n name: 'Config',\n status: 'PASS',\n detail: `valid — ${config.resources.length} resource(s), merchant \"${config.merchant.name}\"${filledSuffix}`,\n });\n } catch (err) {\n const variable = isCommerceError(err) ? err.details?.['variable'] : undefined;\n const hint =\n !manifestFound &&\n typeof variable === 'string' &&\n MANIFEST_FILLABLE_ENV_VAR_NAMES.has(variable)\n ? ` — run \"npm run chain:deploy\" (writes ${LOCAL_CHAIN_MANIFEST_PATH}, read automatically for local X402_*/MERCHANT_WALLET placeholders)`\n : '';\n checks.push({\n name: 'Config',\n status: 'FAIL',\n detail: `${err instanceof Error ? err.message : String(err)}${hint}`,\n });\n }\n\n const gatewayUrl = deriveGatewayUrl(options.gatewayUrl, config);\n\n // 2. Gateway\n const health = await fetchJson(fetchImpl, `${gatewayUrl}/health`, CHECK_TIMEOUT_MS);\n let gatewayUp = false;\n if (!health.ok) {\n checks.push({\n name: 'Gateway',\n status: 'FAIL',\n detail: `unreachable at ${gatewayUrl} (${health.error ?? `HTTP ${health.status}`})`,\n });\n } else {\n gatewayUp = true;\n const ready = await fetchJson(fetchImpl, `${gatewayUrl}/ready`, CHECK_TIMEOUT_MS);\n checks.push(\n ready.ok\n ? { name: 'Gateway', status: 'PASS', detail: `healthy and ready at ${gatewayUrl}` }\n : {\n name: 'Gateway',\n status: 'WARN',\n detail: `healthy but not ready at ${gatewayUrl} (${ready.error ?? `HTTP ${ready.status}`})`,\n },\n );\n }\n\n // 3. Backend(s)\n if (config === undefined) {\n checks.push({ name: 'Backend', status: 'WARN', detail: 'skipped — config invalid' });\n } else if (config.resources.length === 0) {\n checks.push({ name: 'Backend', status: 'INFO', detail: 'no resources configured' });\n } else {\n const resources = config.resources as readonly CommerceResource[];\n const urls: string[] = [...new Set(resources.map((r) => substitutePathParams(r.handler.url)))];\n const results = await Promise.all(\n urls.map((url) => fetchJson(fetchImpl, url, CHECK_TIMEOUT_MS)),\n );\n const reachable = results.filter((r) => r.status !== 0).length;\n const status: CheckStatus =\n reachable === urls.length ? 'PASS' : reachable === 0 ? 'FAIL' : 'WARN';\n checks.push({\n name: 'Backend',\n status,\n detail: `${reachable}/${urls.length} backend host(s) reachable`,\n });\n }\n\n // 4. Well-known document (feeds Protocols + Protocol versions)\n const wellKnown = gatewayUp\n ? await fetchJson<Record<string, unknown>>(\n fetchImpl,\n `${gatewayUrl}/.well-known/agent-commerce`,\n CHECK_TIMEOUT_MS,\n )\n : undefined;\n\n // 5. Protocols\n if (config === undefined) {\n checks.push({ name: 'Protocols', status: 'WARN', detail: 'skipped — config invalid' });\n } else if (wellKnown === undefined || !wellKnown.ok) {\n checks.push({ name: 'Protocols', status: 'FAIL', detail: 'well-known document unreachable' });\n } else {\n const mcpMountPath = config.protocols.mcp.enabled ? config.protocols.mcp.mountPath : undefined;\n checks.push({\n name: 'Protocols',\n status: 'PASS',\n detail: `http=${config.protocols.http.enabled ? 'on' : 'off'} mcp=${config.protocols.mcp.enabled ? `on (${mcpMountPath})` : 'off'}`,\n });\n }\n\n // 6. Payments\n const x402 = config?.payments.x402;\n if (x402 === undefined || !x402.enabled) {\n checks.push({ name: 'Payments', status: 'INFO', detail: 'x402 not configured' });\n } else {\n // The protocol version is named because chain id 84532 is shared with the\n // public Base Sepolia testnet: the *mode* is what says whether this\n // deployment settles on a local dev node or a public network, and nothing\n // here may be read as a claim about a public network on its own.\n //\n // A config whose network is unknown cannot reach here in normal operation\n // — `parseConfig` refuses it — so an absent profile means doctor is\n // reading a config some other loader produced. Say so rather than guess.\n const profile = findNetworkProfile(x402.network);\n const mode = profile ? resolveDeploymentMode(profile, x402.facilitator.mode) : undefined;\n // Naming the public network while in local mode would read as a claim to\n // be on it — the exact confusion the shared chain id creates. Local says\n // \"dev chain\"; only a remote facilitator earns the network's name.\n const where =\n profile === undefined || mode === undefined\n ? `unknown network ${x402.network}`\n : mode === 'local'\n ? `LOCAL dev chain (${x402.network}, chain id shared with ${profile.displayName})`\n : `${describeDeploymentMode(mode)} on ${profile.displayName} (${x402.network})`;\n const facilitatorDetail =\n x402.facilitator.mode === 'local' ? 'local' : `remote (auth=${x402.facilitator.auth.type})`;\n const summary = `x402 v2 (scheme=exact) enabled — ${where}, destination=${maskMiddle(x402.payTo)}, facilitator=${facilitatorDetail}`;\n const live = wellKnown?.ok ? extractWellKnownX402(wellKnown.body) : undefined;\n if (sameAddress(x402.asset, PLACEHOLDER_ASSET_ADDRESS)) {\n // `init --yes` writes this placeholder, and the\n // live cross-check compares config against the gateway's echo of the\n // same config — so everything matched and the report said 7/7 PASS on a\n // deployment where no paid call can ever succeed, because no token\n // contract exists at that address. Fail-closed holds and no funds are at\n // risk; the overstatement is the defect.\n checks.push({\n name: 'Payments',\n status: 'WARN',\n detail: `${summary}, but the asset is still the init placeholder ${maskMiddle(PLACEHOLDER_ASSET_ADDRESS)} — no token contract exists there, so every paid call will fail. Set payments.x402.asset (\\${X402_ASSET} is filled from .deploy/local.json by \"npm run chain:deploy\")`,\n });\n } else if (live === 'disabled') {\n // Verified, and it disagrees. Every paid call against this gateway will\n // be served free or refused, depending on the resource — either way the\n // deployment is not what this config describes.\n checks.push({\n name: 'Payments',\n status: 'FAIL',\n detail: `${summary}, but the gateway at ${gatewayUrl} reports x402 disabled — it is running a different configuration`,\n });\n } else if (live === undefined) {\n // Gateway unreachable, x402 not (yet) reported live, or the document\n // didn't parse as expected — can't judge a match either way, so this\n // is not a FAIL: a doctor that fails on things it cannot check is as\n // untrustworthy as one that passes on things it never checked.\n checks.push({\n name: 'Payments',\n status: 'INFO',\n detail: `${summary} (gateway's live settlement config could not be verified)`,\n });\n } else {\n const mismatch = findX402Mismatch(x402, live);\n checks.push(\n mismatch === undefined\n ? { name: 'Payments', status: 'PASS', detail: summary }\n : { name: 'Payments', status: 'FAIL', detail: mismatch },\n );\n }\n if (mode === 'mainnet') {\n // Reporting, not re-checking. Every one of these is refused at config\n // load (src/payments/x402/guardrails.ts), so a config that got this far\n // has already passed them — but an operator about to move real money\n // should be told which guarantees they are relying on, and see the\n // banner without having to read a log.\n // An unauthenticated mainnet facilitator is allowed, but only by name.\n // Saying so here is the point: the acknowledgement lives in a config\n // file someone wrote weeks ago, and this is where they look today.\n const unauthenticated =\n x402.facilitator.mode === 'remote' && x402.facilitator.auth.type === 'none';\n checks.push({\n name: 'Mainnet safety',\n status: unauthenticated ? 'WARN' : 'INFO',\n detail: unauthenticated\n ? `${describeDeploymentMode('mainnet')} — settling through a facilitator that takes no ` +\n 'credential, accepted via allowUnauthenticatedFacilitator. It sees every payment ' +\n 'authorisation you handle, with no account or terms behind it. Everything else is ' +\n 'enforced at config load: explicit allowMainnet opt-in, HTTPS, non-development ' +\n 'payTo, canonical asset. Payments are fail-closed.'\n : `${describeDeploymentMode('mainnet')} — enforced at config load: explicit allowMainnet ` +\n 'opt-in, remote facilitator over HTTPS with a credential, non-development payTo, ' +\n 'and the canonical asset for this network. Payments are fail-closed.',\n });\n }\n }\n checks.push({\n name: 'Payments (MPP)',\n status: 'INFO',\n detail: 'planned — not implemented in this release',\n });\n\n // 7. Storage\n if (config === undefined) {\n checks.push({ name: 'Storage', status: 'WARN', detail: 'skipped — config invalid' });\n } else if (\n // Diagnose without creating: createSqliteReceiptStore mkdir+creates the\n // file, so calling it on a wrong path (a typo, or a container path read\n // from the host) silently produces a fresh empty database and a false\n // \"healthy, receipts=0\" PASS — a read-only command must not have this\n // side effect, and it shadows the real store's real receipts entirely.\n // `:memory:` never exists on disk by definition, so it always falls\n // through to the real open/health/count branch below, same as today.\n config.storage.receipts.path !== ':memory:' &&\n !existsSync(config.storage.receipts.path)\n ) {\n checks.push({\n name: 'Storage',\n status: 'WARN',\n detail:\n `no store exists yet at \"${config.storage.receipts.path}\" — it is created ` +\n 'automatically the first time the gateway starts. If the gateway is already ' +\n 'running, this path does not match the one it actually uses.',\n });\n } else {\n let store: ReceiptStore | undefined;\n try {\n store = createStore(config.storage.receipts.path);\n await store.init();\n const storeHealth = await store.health();\n let receiptCount: number | undefined;\n try {\n // Exact count, not a list length: listReceipts clamps to\n // MAX_LIST_LIMIT (500, a store-level invariant) so counting via the\n // list silently saturated at 500 forever.\n receiptCount = await store.countReceipts();\n } catch {\n receiptCount = undefined;\n }\n let undeliveredCount: number | undefined;\n try {\n // A paid-but-undelivered purchase looks identical to a successful\n // one everywhere else; this is what makes it visible to an operator\n // running doctor. Same signal the\n // dashboard's receipt table uses, so the two views cannot disagree.\n undeliveredCount = await store.countUndeliveredReceipts();\n } catch {\n undeliveredCount = undefined;\n }\n const status: CheckStatus =\n storeHealth.status === 'pass' ? 'PASS' : storeHealth.status === 'warn' ? 'WARN' : 'FAIL';\n const receiptsSuffix =\n receiptCount !== undefined\n ? `; receipts=${receiptCount}${undeliveredCount !== undefined && undeliveredCount > 0 ? ` (${undeliveredCount} undelivered)` : ''}`\n : '';\n checks.push({\n name: 'Storage',\n status,\n detail: `${storeHealth.detail ?? 'sqlite'}${receiptsSuffix}`,\n });\n } catch (err) {\n checks.push({\n name: 'Storage',\n status: 'FAIL',\n detail: err instanceof Error ? err.message : String(err),\n });\n } finally {\n await store?.close();\n }\n }\n\n // 8. Protocol versions\n if (wellKnown !== undefined && wellKnown.ok) {\n checks.push({\n name: 'Protocol versions',\n status: 'PASS',\n detail: 'reported by gateway /.well-known/agent-commerce',\n });\n } else {\n const local = readVersionReport();\n checks.push({\n name: 'Protocol versions',\n status: 'INFO',\n detail: `gateway unreachable — local pins: ${local.pinned.map((p) => `${p.name}@${p.version}`).join(', ')}`,\n });\n }\n\n const scored = checks.filter((c) => c.status !== 'INFO');\n const passed = scored.filter((c) => c.status === 'PASS').length;\n const exitCode = checks.some((c) => c.status === 'FAIL') ? 1 : 0;\n\n return { checks, score: { passed, total: scored.length }, exitCode };\n}\n\nfunction statusColor(status: CheckStatus, text: string): string {\n switch (status) {\n case 'PASS':\n return picocolors.green(text);\n case 'WARN':\n return picocolors.yellow(text);\n case 'FAIL':\n return picocolors.red(text);\n case 'INFO':\n return picocolors.cyan(text);\n }\n}\n\nexport function printDoctorReport(report: DoctorReport, io: Io, json: boolean): void {\n if (json) {\n io.stdout(JSON.stringify(report, null, 2));\n return;\n }\n for (const check of report.checks) {\n const label = statusColor(check.status, check.status.padEnd(5));\n io.stdout(`${label} ${check.name.padEnd(20)} ${check.detail}`);\n }\n io.stdout('');\n io.stdout(`Score: ${report.score.passed}/${report.score.total} checks passed`);\n}\n","/**\n * SQLite implementation of the frozen ReceiptStore interface.\n *\n * Thin repository layer — no ORM. Every write goes through a prepared\n * statement; the only thing that varies between calls is parameters.\n */\nimport { randomUUID } from 'node:crypto';\nimport {\n accessSync,\n chmodSync,\n closeSync,\n existsSync,\n constants as fsConstants,\n mkdirSync,\n openSync,\n} from 'node:fs';\nimport { dirname } from 'node:path';\nimport Database from 'better-sqlite3';\nimport {\n type AdapterDescriptor,\n type AdapterHealth,\n type Clock,\n CommerceError,\n type CommerceEvent,\n type CommerceReceipt,\n type IdGenerator,\n type ListOptions,\n type Logger,\n NOOP_LOGGER,\n type PaymentAttempt,\n type PaymentAttemptReservation,\n type PaymentAttemptUpdate,\n type ReceiptStore,\n systemClock,\n toCommerceError,\n} from '../../core/index.js';\nimport { PACKAGE_VERSION } from '../../version.js';\nimport {\n type EventRow,\n eventToRow,\n type PaymentAttemptRow,\n type ReceiptRow,\n receiptToRow,\n rowToEvent,\n rowToPaymentAttempt,\n rowToReceipt,\n} from './rows.js';\nimport { migrate, SCHEMA_VERSION } from './schema.js';\n\nconst DEFAULT_LIST_LIMIT = 50;\n/**\n * Hard ceiling on every list query, applied here rather than only at the\n * gateway route, so every caller (HTTP, CLI, a future adapter) is covered.\n * SQLite treats a negative `LIMIT` as \"no limit\" —\n * confirmed `{ limit: -1 }` returns the entire table.\n */\nconst MAX_LIST_LIMIT = 500;\n\n/**\n * Clamps to a whole number in [1, MAX_LIST_LIMIT], defaulting when absent OR\n * non-finite (NaN/Infinity) — a store-level invariant that must hold\n * regardless of whether the current caller already filters those out.\n */\nfunction clampListLimit(limit: number | undefined): number {\n const base = limit !== undefined && Number.isFinite(limit) ? limit : DEFAULT_LIST_LIMIT;\n return Math.min(Math.max(Math.trunc(base), 1), MAX_LIST_LIMIT);\n}\n\nexport interface SqliteReceiptStoreOptions {\n /** File path, or ':memory:' for tests. Parent directory is created if missing. */\n readonly path: string;\n readonly logger?: Logger;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\nconst defaultIds: IdGenerator = {\n next: (prefix) => (prefix !== undefined ? `${prefix}_${randomUUID()}` : randomUUID()),\n};\n\nfunction isUniqueConstraintOn(err: unknown, column: string): boolean {\n return (\n err instanceof Error &&\n 'code' in err &&\n (err as { code?: unknown }).code === 'SQLITE_CONSTRAINT_UNIQUE' &&\n err.message.includes(column)\n );\n}\n\n/**\n * Narrow the database and its WAL sidecars to owner-only.\n *\n * `new Database(path)` opens with `0666 & ~umask`, so on a\n * standard host the `.sqlite`, `-wal` and `-shm` files landed at 0644 — any\n * other local user could read the whole commerce ledger: payer and payee\n * addresses, amounts, settlement transaction hashes, replay keys and the\n * entire event stream. No key material (the gateway is non-custodial and\n * `redact.ts` is recursive), but business metadata all the same.\n *\n * Called *after* `journal_mode = WAL`, because the sidecars do not exist until\n * then. Belt-and-braces since the main file is now pre-created at 0600 (see\n * `createSqliteReceiptStore`): this still tightens a database that already\n * existed with a looser mode. Best-effort by design: a filesystem without\n * POSIX modes must not stop the gateway from starting, so a failure warns\n * rather than throws.\n */\nfunction restrictDatabasePermissions(path: string, logger: Logger): void {\n for (const file of [path, `${path}-wal`, `${path}-shm`]) {\n try {\n chmodSync(file, 0o600);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') continue;\n logger.warn(\n { file, error: code ?? 'unknown' },\n 'could not restrict receipt database permissions to owner-only',\n );\n }\n }\n}\n\nexport function createSqliteReceiptStore(options: SqliteReceiptStoreOptions): ReceiptStore {\n const logger = options.logger ?? NOOP_LOGGER;\n const clock = options.clock ?? systemClock;\n const ids = options.ids ?? defaultIds;\n const path = options.path;\n const isFileBacked = path !== ':memory:';\n\n if (isFileBacked) {\n const dir = dirname(path);\n if (dir !== '' && dir !== '.' && !existsSync(dir)) {\n // 0700 on directories we create ourselves. An existing directory is the\n // operator's to own and is deliberately left alone.\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n }\n\n // Fail at startup, not on the first payment. `new Database(path)`\n // happily opens a file the process cannot write, and SQLite only says\n // \"attempt to write a readonly database\" once a write is attempted — which\n // on a paid resource is *after* the payment attempt reservation, surfacing\n // as an opaque STORAGE_ERROR per request. Readiness does catch it (503), but\n // the operator is left guessing. This is not hypothetical: switching the\n // demo containers to a non-root user left an existing named volume\n // root-owned, and that is exactly how it presented.\n if (isFileBacked && existsSync(path)) {\n try {\n accessSync(path, fsConstants.W_OK);\n } catch {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `Receipt database \"${path}\" exists but is not writable by this process (uid ${typeof process.getuid === 'function' ? process.getuid() : 'unknown'}). If this is a container that recently changed user, an existing volume may still be owned by the previous one — recreate it (docker compose down -v) or fix its ownership.`,\n { details: { path } },\n );\n }\n }\n\n // Create the file ourselves, at 0600, *before* SQLite can create it at\n // `0666 & ~umask`. The chmod below only narrows the mode after the fact: a\n // local co-tenant who opens the file inside that window keeps a readable\n // descriptor across the chmod and reads every receipt written afterwards.\n // SQLite copies the main file's mode onto the -wal/-shm sidecars, so this\n // one call covers all three. `mode` applies on creation only, so an\n // existing file is untouched here and left to the chmod.\n if (isFileBacked) {\n try {\n closeSync(openSync(path, 'a', 0o600));\n } catch {\n // Deliberately silent: whatever stopped us (unwritable directory,\n // exotic filesystem) is about to be reported by `new Database` with a\n // better message, or is harmless and covered by the chmod below.\n }\n }\n\n const db = new Database(path);\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n migrate(db);\n if (isFileBacked) restrictDatabasePermissions(path, logger);\n\n const insertReceiptStmt = db.prepare(\n `INSERT INTO receipts (id, request_id, resource_id, payment_json, delivered_at, backend_status, duration_ms, protocol, metadata_json)\n VALUES (@id, @request_id, @resource_id, @payment_json, @delivered_at, @backend_status, @duration_ms, @protocol, @metadata_json)`,\n );\n const getReceiptStmt = db.prepare<[string], ReceiptRow>('SELECT * FROM receipts WHERE id = ?');\n const listReceiptsStmt = db.prepare<[number], ReceiptRow>(\n 'SELECT * FROM receipts ORDER BY delivered_at DESC, seq DESC LIMIT ?',\n );\n const listReceiptsByRequestStmt = db.prepare<[string, number], ReceiptRow>(\n 'SELECT * FROM receipts WHERE request_id = ? ORDER BY delivered_at DESC, seq DESC LIMIT ?',\n );\n const countReceiptsStmt = db.prepare<[], { count: number }>(\n 'SELECT COUNT(*) AS count FROM receipts',\n );\n // backend_status is INTEGER NOT NULL (schema.ts) so NOT BETWEEN never has\n // a NULL row to silently miss; 0 (backend never responded at all) and\n // every non-2xx status both count as undelivered, matching the dashboard's\n // deliveryResult() (ReceiptList.tsx) — the two views must not disagree\n // about what \"delivered\" means, which is the confusion.\n const countUndeliveredReceiptsStmt = db.prepare<[], { count: number }>(\n 'SELECT COUNT(*) AS count FROM receipts WHERE backend_status NOT BETWEEN 200 AND 299',\n );\n\n const insertEventStmt = db.prepare(\n `INSERT INTO events (id, type, request_id, resource_id, at, adapter, payment_provider, duration_ms, status, data_json)\n VALUES (@id, @type, @request_id, @resource_id, @at, @adapter, @payment_provider, @duration_ms, @status, @data_json)`,\n );\n const listEventsStmt = db.prepare<[number], EventRow>(\n 'SELECT * FROM events ORDER BY at DESC, seq DESC LIMIT ?',\n );\n const listEventsByRequestStmt = db.prepare<[string, number], EventRow>(\n 'SELECT * FROM events WHERE request_id = ? ORDER BY at DESC, seq DESC LIMIT ?',\n );\n\n const insertPaymentAttemptStmt = db.prepare(\n `INSERT INTO payment_attempts (id, request_id, resource_id, provider, replay_key, status, amount, currency, payer, payee, external_reference, rejection_reason, created_at, updated_at)\n VALUES (@id, @request_id, @resource_id, @provider, @replay_key, @status, @amount, @currency, @payer, @payee, @external_reference, @rejection_reason, @created_at, @updated_at)`,\n );\n const getPaymentAttemptByIdStmt = db.prepare<[string], PaymentAttemptRow>(\n 'SELECT * FROM payment_attempts WHERE id = ?',\n );\n // COALESCE: an omitted field (bound as NULL — see updatePaymentAttempt)\n // means \"leave the existing value alone\", not \"clear it\". Without this, a\n // second update that doesn't re-supply external_reference/rejection_reason\n // erases it — exactly the field that carries the on-chain tx hash for a\n // settlement-uncertain attempt, the one record proving the buyer's funds\n // may have moved. There is no current caller that needs to clear an\n // already-set value; if one appears, it needs an explicit sentinel rather\n // than overloading `undefined` to mean two different things again.\n const updatePaymentAttemptStmt = db.prepare(\n `UPDATE payment_attempts SET status = @status,\n external_reference = COALESCE(@external_reference, external_reference),\n rejection_reason = COALESCE(@rejection_reason, rejection_reason),\n updated_at = @updated_at\n WHERE replay_key = @replay_key`,\n );\n const listPaymentAttemptsStmt = db.prepare<[number], PaymentAttemptRow>(\n 'SELECT * FROM payment_attempts ORDER BY created_at DESC, seq DESC LIMIT ?',\n );\n const listPaymentAttemptsByRequestStmt = db.prepare<[string, number], PaymentAttemptRow>(\n 'SELECT * FROM payment_attempts WHERE request_id = ? ORDER BY created_at DESC, seq DESC LIMIT ?',\n );\n\n let closed = false;\n\n const descriptor: AdapterDescriptor = {\n name: 'sqlite-receipt-store',\n kind: 'storage',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: `sqlite-schema-v${SCHEMA_VERSION}`,\n capabilities: ['receipts', 'events', 'payment-attempts'],\n status: 'stable',\n };\n\n const store: ReceiptStore = {\n async init(): Promise<void> {\n // Schema setup already happened synchronously above (better-sqlite3 is\n // sync). This re-check makes init() a meaningful, idempotent gate for\n // callers that treat it as the lifecycle hook that must succeed before\n // any other method is used.\n const version = db.pragma('user_version', { simple: true }) as number;\n if (version !== SCHEMA_VERSION) {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `Receipt store schema version mismatch (found ${version}, expected ${SCHEMA_VERSION})`,\n );\n }\n },\n\n async appendEvent(event: CommerceEvent): Promise<void> {\n try {\n insertEventStmt.run(eventToRow(event));\n } catch (err) {\n logger.warn(\n {\n err: err instanceof Error ? err.message : String(err),\n eventId: event.id,\n requestId: event.requestId,\n },\n 'receipt-store: failed to persist commerce event',\n );\n }\n },\n\n async reservePaymentAttempt(reservation: PaymentAttemptReservation): Promise<PaymentAttempt> {\n const now = clock.nowIso();\n const id = ids.next('attempt');\n try {\n insertPaymentAttemptStmt.run({\n id,\n request_id: reservation.requestId,\n resource_id: reservation.resourceId,\n provider: reservation.provider,\n replay_key: reservation.replayKey,\n status: 'reserved' satisfies PaymentAttempt['status'],\n amount: reservation.amount,\n currency: reservation.currency,\n payer: reservation.payer ?? null,\n payee: reservation.payee ?? null,\n external_reference: null,\n rejection_reason: null,\n created_at: now,\n updated_at: now,\n });\n } catch (err) {\n if (isUniqueConstraintOn(err, 'payment_attempts.replay_key')) {\n throw new CommerceError(\n 'PAYMENT_REPLAYED',\n `Payment authorisation has already been used (replayKey=${reservation.replayKey})`,\n { requestId: reservation.requestId, resourceId: reservation.resourceId },\n );\n }\n throw toCommerceError(err, 'STORAGE_ERROR', 'Failed to reserve payment attempt');\n }\n const row = getPaymentAttemptByIdStmt.get(id);\n if (row === undefined) {\n throw new CommerceError(\n 'STORAGE_ERROR',\n 'Payment attempt vanished immediately after insert',\n );\n }\n return rowToPaymentAttempt(row);\n },\n\n async updatePaymentAttempt(update: PaymentAttemptUpdate): Promise<void> {\n try {\n const result = updatePaymentAttemptStmt.run({\n replay_key: update.replayKey,\n status: update.status,\n external_reference: update.externalReference ?? null,\n rejection_reason: update.rejectionReason ?? null,\n updated_at: clock.nowIso(),\n });\n if (result.changes === 0) {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `No payment attempt found for replayKey=${update.replayKey}`,\n );\n }\n } catch (err) {\n throw toCommerceError(err, 'STORAGE_ERROR', 'Failed to update payment attempt');\n }\n },\n\n async saveReceipt(receipt: CommerceReceipt): Promise<void> {\n try {\n insertReceiptStmt.run(receiptToRow(receipt));\n } catch (err) {\n throw toCommerceError(err, 'STORAGE_ERROR', 'Failed to save receipt');\n }\n },\n\n async getReceipt(id: string): Promise<CommerceReceipt | undefined> {\n const row = getReceiptStmt.get(id);\n return row !== undefined ? rowToReceipt(row) : undefined;\n },\n\n async listReceipts(listOptions: ListOptions = {}): Promise<readonly CommerceReceipt[]> {\n const limit = clampListLimit(listOptions.limit);\n const rows =\n listOptions.requestId !== undefined\n ? listReceiptsByRequestStmt.all(listOptions.requestId, limit)\n : listReceiptsStmt.all(limit);\n return rows.map(rowToReceipt);\n },\n\n /** Exact total, ignoring the listReceipts clamp — see the interface doc for why this exists. */\n async countReceipts(): Promise<number> {\n return countReceiptsStmt.get()?.count ?? 0;\n },\n\n /** Exact count of non-2xx receipts — see the interface doc for why this exists. */\n async countUndeliveredReceipts(): Promise<number> {\n return countUndeliveredReceiptsStmt.get()?.count ?? 0;\n },\n\n async listEvents(listOptions: ListOptions = {}): Promise<readonly CommerceEvent[]> {\n const limit = clampListLimit(listOptions.limit);\n const rows =\n listOptions.requestId !== undefined\n ? listEventsByRequestStmt.all(listOptions.requestId, limit)\n : listEventsStmt.all(limit);\n return rows.map(rowToEvent);\n },\n\n async listPaymentAttempts(listOptions: ListOptions = {}): Promise<readonly PaymentAttempt[]> {\n const limit = clampListLimit(listOptions.limit);\n const rows =\n listOptions.requestId !== undefined\n ? listPaymentAttemptsByRequestStmt.all(listOptions.requestId, limit)\n : listPaymentAttemptsStmt.all(limit);\n return rows.map(rowToPaymentAttempt);\n },\n\n descriptor,\n\n async health(): Promise<AdapterHealth> {\n // Same discipline: a client-visible field is authored from a\n // fixed vocabulary, never inherited from a caught error's `.message`.\n // `accessSync` on a real deployment throws e.g.\n // \"EACCES: permission denied, access '/workspace/data/receipts.sqlite'\"\n // — an absolute host path that must never reach the unauthenticated\n // `/ready` response). The raw message still goes\n // to the injected logger, so nothing is lost for diagnosis.\n const startedAt = clock.monotonicMs();\n if (closed) {\n return { status: 'fail', detail: 'store-unavailable', checkedAt: clock.nowIso() };\n }\n if (isFileBacked) {\n try {\n accessSync(path, fsConstants.W_OK);\n } catch (err) {\n logger.warn(\n { err: err instanceof Error ? err.message : String(err) },\n 'receipt-store: health check failed (store not writable)',\n );\n return {\n status: 'fail',\n detail: 'store-unwritable',\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n }\n try {\n const version = db.pragma('user_version', { simple: true }) as number;\n if (version !== SCHEMA_VERSION) {\n logger.warn(\n { found: version, expected: SCHEMA_VERSION },\n 'receipt-store: health check failed (schema version mismatch)',\n );\n return {\n status: 'fail',\n detail: 'store-schema-mismatch',\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n return {\n status: 'pass',\n detail: `sqlite schema v${SCHEMA_VERSION} writable`,\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n } catch (err) {\n logger.warn(\n { err: err instanceof Error ? err.message : String(err) },\n 'receipt-store: health check failed (store unavailable)',\n );\n return {\n status: 'fail',\n detail: 'store-unavailable',\n checkedAt: clock.nowIso(),\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n },\n\n async close(): Promise<void> {\n if (!closed) {\n closed = true;\n db.close();\n }\n },\n };\n\n return store;\n}\n","/**\n * The package version, resolved once for the whole package.\n *\n * Two paths, deliberately:\n *\n * - **Development** reads the root manifest, so the number is always live.\n * - **The published bundle cannot.** tsup collapses `src/**` into\n * `dist/index.js` and `dist/cli/index.js`, so any `require('../../package.json')`\n * written against a source path resolves from the wrong depth once bundled —\n * which is exactly how this broke during the single-package refactor, and how\n * it earlier produced a CLI reporting `v0.0.0-unknown`. The build injects\n * `__OAC_PACKAGE_VERSION__` instead (see tsup.config.ts).\n *\n * `typeof` on an undeclared identifier is safe in JS, so the dev path is\n * unaffected by the constant not existing.\n */\nimport { createRequire } from 'node:module';\n\ndeclare const __OAC_PACKAGE_VERSION__: string | undefined;\n\nfunction readFromManifest(): string {\n try {\n const require = createRequire(import.meta.url);\n // src/version.ts -> repository root\n return (require('../package.json') as { version?: string }).version ?? '0.0.0-unknown';\n } catch {\n return '0.0.0-unknown';\n }\n}\n\nexport const PACKAGE_VERSION: string =\n typeof __OAC_PACKAGE_VERSION__ === 'string' ? __OAC_PACKAGE_VERSION__ : readFromManifest();\n","/**\n * Defence-in-depth against accidentally persisting secrets.\n *\n * The gateway and payment providers are expected to never place secrets into\n * `CommerceReceipt.metadata`, `CommerceEvent.data` or `PaymentResult.metadata`\n * (see docs/contracts.md, \"Store NO secrets\"). This module is a second line\n * of defence at the persistence boundary: any key that *looks* like it holds\n * a private key, an auth header or a raw payment proof is stripped — never\n * persisted — rather than rejecting the whole write, so a logging bug never\n * takes down an otherwise-successful commerce flow (appendEvent especially\n * must never throw into the caller's flow).\n */\n/**\n * The bearer-token family was missing — `token`, `bearerToken`,\n * `adminToken`, `authToken`, `credential`, `cookie`, `sessionId`, `jwt` all\n * returned false. Nothing writes such a key today, which is exactly the state\n * a second line of defence is for; and this data also lands in a\n * file that is now owner-only precisely because it is worth protecting.\n */\nconst SECRET_KEY_PATTERN =\n /private[-_ ]?key|secret|password|mnemonic|seed[-_ ]?phrase|api[-_ ]?key|authoriz(e|ation)|^auth$|auth[-_]?header|payment[-_ ]?proof|^proof$|x-payment|signature|signed[-_ ]?message|token|bearer|credential|cookie|session|jwt/i;\n\nconst REDACTED = '[REDACTED]';\n\n/** True if `key` looks like it names a secret value. */\nexport function isSecretKey(key: string): boolean {\n return SECRET_KEY_PATTERN.test(key);\n}\n\n/**\n * Recursively strip values whose key looks secret-shaped, returning a new\n * object. Safe to call on already-clean data (no-op in that case).\n */\nexport function redact<T>(value: T): T {\n return redactValue(value) as T;\n}\n\nfunction redactValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(redactValue);\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [key, inner] of Object.entries(value as Record<string, unknown>)) {\n out[key] = isSecretKey(key) ? REDACTED : redactValue(inner);\n }\n return out;\n }\n return value;\n}\n\n/** True if `value` (recursively) contains any key that looks secret-shaped. */\nexport function containsSecretKey(value: unknown): boolean {\n if (Array.isArray(value)) {\n return value.some(containsSecretKey);\n }\n if (value !== null && typeof value === 'object') {\n return Object.entries(value as Record<string, unknown>).some(\n ([key, inner]) => isSecretKey(key) || containsSecretKey(inner),\n );\n }\n return false;\n}\n","/**\n * SQLite row shapes and mapping to/from the canonical domain model.\n *\n * `exactOptionalPropertyTypes` is on: optional fields are only assigned when\n * present (see docs/contracts.md, assumption 8).\n */\nimport type {\n CommerceEvent,\n CommerceEventType,\n CommerceReceipt,\n PaymentAttempt,\n PaymentResult,\n} from '../../core/index.js';\nimport { redact } from './redact.js';\n\nexport interface ReceiptRow {\n readonly id: string;\n readonly request_id: string;\n readonly resource_id: string;\n readonly payment_json: string | null;\n readonly delivered_at: string;\n readonly backend_status: number;\n readonly duration_ms: number | null;\n readonly protocol: string | null;\n readonly metadata_json: string | null;\n}\n\nexport interface EventRow {\n readonly id: string;\n readonly type: string;\n readonly request_id: string;\n readonly resource_id: string | null;\n readonly at: string;\n readonly adapter: string | null;\n readonly payment_provider: string | null;\n readonly duration_ms: number | null;\n readonly status: string | null;\n readonly data_json: string | null;\n}\n\nexport interface PaymentAttemptRow {\n readonly id: string;\n readonly request_id: string;\n readonly resource_id: string;\n readonly provider: string;\n readonly replay_key: string;\n readonly status: string;\n readonly amount: string;\n readonly currency: string;\n readonly payer: string | null;\n readonly payee: string | null;\n readonly external_reference: string | null;\n readonly rejection_reason: string | null;\n readonly created_at: string;\n readonly updated_at: string;\n}\n\nexport function receiptToRow(receipt: CommerceReceipt): {\n id: string;\n request_id: string;\n resource_id: string;\n payment_json: string | null;\n delivered_at: string;\n backend_status: number;\n duration_ms: number | null;\n protocol: string | null;\n metadata_json: string | null;\n} {\n return {\n id: receipt.id,\n request_id: receipt.requestId,\n resource_id: receipt.resourceId,\n payment_json: receipt.payment !== undefined ? JSON.stringify(redact(receipt.payment)) : null,\n delivered_at: receipt.deliveredAt,\n backend_status: receipt.backendStatus,\n duration_ms: receipt.durationMs !== undefined ? receipt.durationMs : null,\n protocol: receipt.protocol !== undefined ? receipt.protocol : null,\n metadata_json: receipt.metadata !== undefined ? JSON.stringify(redact(receipt.metadata)) : null,\n };\n}\n\nexport function rowToReceipt(row: ReceiptRow): CommerceReceipt {\n const payment =\n row.payment_json !== null ? (JSON.parse(row.payment_json) as PaymentResult) : undefined;\n const metadata =\n row.metadata_json !== null\n ? (JSON.parse(row.metadata_json) as Record<string, unknown>)\n : undefined;\n return {\n id: row.id,\n requestId: row.request_id,\n resourceId: row.resource_id,\n deliveredAt: row.delivered_at,\n backendStatus: row.backend_status,\n ...(payment !== undefined ? { payment } : {}),\n ...(row.duration_ms !== null ? { durationMs: row.duration_ms } : {}),\n ...(row.protocol !== null ? { protocol: row.protocol } : {}),\n ...(metadata !== undefined ? { metadata } : {}),\n };\n}\n\nexport function eventToRow(event: CommerceEvent): {\n id: string;\n type: string;\n request_id: string;\n resource_id: string | null;\n at: string;\n adapter: string | null;\n payment_provider: string | null;\n duration_ms: number | null;\n status: string | null;\n data_json: string | null;\n} {\n return {\n id: event.id,\n type: event.type,\n request_id: event.requestId,\n resource_id: event.resourceId !== undefined ? event.resourceId : null,\n at: event.at,\n adapter: event.adapter !== undefined ? event.adapter : null,\n payment_provider: event.paymentProvider !== undefined ? event.paymentProvider : null,\n duration_ms: event.durationMs !== undefined ? event.durationMs : null,\n status: event.status !== undefined ? event.status : null,\n data_json: event.data !== undefined ? JSON.stringify(redact(event.data)) : null,\n };\n}\n\nexport function rowToEvent(row: EventRow): CommerceEvent {\n const data =\n row.data_json !== null ? (JSON.parse(row.data_json) as Record<string, unknown>) : undefined;\n return {\n id: row.id,\n type: row.type as CommerceEventType,\n requestId: row.request_id,\n at: row.at,\n ...(row.resource_id !== null ? { resourceId: row.resource_id } : {}),\n ...(row.adapter !== null ? { adapter: row.adapter } : {}),\n ...(row.payment_provider !== null ? { paymentProvider: row.payment_provider } : {}),\n ...(row.duration_ms !== null ? { durationMs: row.duration_ms } : {}),\n ...(row.status !== null ? { status: row.status as 'ok' | 'error' } : {}),\n ...(data !== undefined ? { data } : {}),\n };\n}\n\nexport function rowToPaymentAttempt(row: PaymentAttemptRow): PaymentAttempt {\n return {\n id: row.id,\n requestId: row.request_id,\n resourceId: row.resource_id,\n provider: row.provider,\n replayKey: row.replay_key,\n status: row.status as PaymentAttempt['status'],\n amount: row.amount,\n currency: row.currency,\n ...(row.payer !== null ? { payer: row.payer } : {}),\n ...(row.payee !== null ? { payee: row.payee } : {}),\n ...(row.external_reference !== null ? { externalReference: row.external_reference } : {}),\n ...(row.rejection_reason !== null ? { rejectionReason: row.rejection_reason } : {}),\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n","/**\n * Explicit migration scheme for the receipt-store SQLite schema.\n *\n * Uses SQLite's built-in `PRAGMA user_version` as the migration marker so a\n * restart against an existing database file re-opens without re-creating or\n * losing data (required negative test: \"gateway restart with receipt storage\n * preserved\").\n */\nimport type Database from 'better-sqlite3';\n\ninterface Migration {\n readonly version: number;\n up(db: Database.Database): void;\n}\n\nconst MIGRATIONS: readonly Migration[] = [\n {\n version: 1,\n up(db) {\n db.exec(`\n CREATE TABLE IF NOT EXISTS receipts (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n request_id TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n payment_json TEXT,\n delivered_at TEXT NOT NULL,\n backend_status INTEGER NOT NULL,\n duration_ms INTEGER,\n protocol TEXT,\n metadata_json TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_receipts_request_id ON receipts(request_id);\n CREATE INDEX IF NOT EXISTS idx_receipts_delivered_at ON receipts(delivered_at);\n\n CREATE TABLE IF NOT EXISTS events (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n type TEXT NOT NULL,\n request_id TEXT NOT NULL,\n resource_id TEXT,\n at TEXT NOT NULL,\n adapter TEXT,\n payment_provider TEXT,\n duration_ms INTEGER,\n status TEXT,\n data_json TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_events_request_id ON events(request_id);\n CREATE INDEX IF NOT EXISTS idx_events_at ON events(at);\n\n CREATE TABLE IF NOT EXISTS payment_attempts (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n request_id TEXT NOT NULL,\n resource_id TEXT NOT NULL,\n provider TEXT NOT NULL,\n replay_key TEXT NOT NULL UNIQUE,\n status TEXT NOT NULL,\n amount TEXT NOT NULL,\n currency TEXT NOT NULL,\n payer TEXT,\n payee TEXT,\n external_reference TEXT,\n rejection_reason TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_payment_attempts_request_id ON payment_attempts(request_id);\n CREATE INDEX IF NOT EXISTS idx_payment_attempts_created_at ON payment_attempts(created_at);\n `);\n },\n },\n];\n\n/** Current target schema version — the version of the last migration. */\nexport const SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;\n\n/**\n * Bring `db` up to {@link SCHEMA_VERSION}. Idempotent: re-opening an existing,\n * already-migrated file is a fast no-op check against `PRAGMA user_version`.\n */\nexport function migrate(db: Database.Database): void {\n const current = db.pragma('user_version', { simple: true }) as number;\n for (const migration of MIGRATIONS) {\n if (migration.version <= current) continue;\n const apply = db.transaction(() => {\n migration.up(db);\n db.pragma(`user_version = ${migration.version}`);\n });\n apply();\n }\n}\n","/**\n * Single seam for the CLI's dependency on `src/config`.\n *\n * The import is dynamic, not static, on purpose: a static\n * `import … from '../../config/index.js'` would fail the whole module\n * graph the instant the package became unavailable for any reason (mid-flight\n * refactor, a broken build), taking down every CLI command — even `version`,\n * which never touches config — the moment this file is loaded. A dynamic\n * import only fails, catchably, when a command actually needs configuration.\n *\n * `runValidate` / `runDoctor` / `runInit` also accept the loader as an\n * injected dependency (defaulting to {@link loadConfigDynamic}), which keeps\n * their logic unit-testable without touching the filesystem or the real\n * package.\n */\nimport type { GatewayConfig as GatewayConfigType } from '../../config/index.js';\n\nexport type GatewayConfig = GatewayConfigType;\n\nexport interface LoadConfigOptions {\n readonly path?: string;\n readonly env?: NodeJS.ProcessEnv;\n readonly cwd?: string;\n}\n\nexport type ConfigLoader = (options?: LoadConfigOptions) => Promise<GatewayConfig>;\n\n/** Validates an already-built raw config object, without touching the disk. */\nexport type ConfigParser = (raw: unknown, env?: NodeJS.ProcessEnv) => Promise<GatewayConfig>;\n\nexport async function loadConfigDynamic(options: LoadConfigOptions = {}): Promise<GatewayConfig> {\n let mod: typeof import('../../config/index.js');\n try {\n mod = await import('../../config/index.js');\n } catch (err) {\n throw new Error(\n `the configuration module could not be loaded: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return mod.loadConfig(options);\n}\n\n/**\n * In-memory validation, same module and same seam as {@link loadConfigDynamic}.\n *\n * Validating the object before writing means nothing lands unless it is\n * valid. Writing the file and *then* loading it back would leave an answer\n * that legitimately fails validation — no protocol selected, a typo'd\n * settlement address, a scheme-less backend URL — on disk under a printed\n * \"PASS Wrote …\", and tell the user to report their own input as a bug.\n */\nexport async function parseConfigDynamic(\n raw: unknown,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<GatewayConfig> {\n let mod: typeof import('../../config/index.js');\n try {\n mod = await import('../../config/index.js');\n } catch (err) {\n throw new Error(\n `the configuration module could not be loaded: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return mod.parseConfig(raw, env);\n}\n","/**\n * Small fetch-with-timeout helper for `doctor`. Injectable so tests never hit\n * a real network — they point it at a local stub HTTP server instead.\n */\nexport type FetchLike = typeof fetch;\n\nexport interface FetchJsonResult<T> {\n readonly ok: boolean;\n readonly status: number;\n readonly body?: T;\n readonly error?: string;\n}\n\nexport async function fetchJson<T = unknown>(\n fetchImpl: FetchLike,\n url: string,\n timeoutMs = 1500,\n): Promise<FetchJsonResult<T>> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const res = await fetchImpl(url, { signal: controller.signal });\n let body: T | undefined;\n try {\n body = (await res.json()) as T;\n } catch {\n body = undefined;\n }\n return { ok: res.ok, status: res.status, ...(body !== undefined ? { body } : {}) };\n } catch (err) {\n return {\n ok: false,\n status: 0,\n error: err instanceof Error ? err.message : 'unknown fetch error',\n };\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Pure YAML-rendering logic for `agent-commerce init`, kept separate from\n * prompt/IO concerns so it is trivially unit-testable.\n *\n * The on-disk shape here is the *raw* `config.yaml` document consumed\n * by `src/config`'s `parseConfig` (src/config/schema.ts):\n * `resources` is a map keyed by resource id, with `backend` / `expose` /\n * `payments` / `input` / `output` field names — distinct from the normalised\n * `CommerceResource` shape (`handler` / `exposedVia` / `paymentMethods` /\n * `inputSchema` / `outputSchema`) that `loadConfig()` returns.\n *\n * Addresses below are Anvil's well-known local dev accounts #0 (facilitator\n * signer) and #1 (merchant `payTo`) — public, fixed, printed by every\n * `anvil` startup banner. Never fund them.\n * Imported from `src/payments/x402/testing.ts` — the\n * canonical source (docs/contracts.md) — rather than duplicated as literals,\n * so `init` can never drift from `scripts/chain/deploy.ts`'s account layout.\n * A hand-copied or truncated literal here breaks every paid request and\n * silently defeats the dev-key guard. The MockUSDC `asset` address is a clearly labelled placeholder: it\n * cannot be known before `npm run chain:deploy` writes `.deploy/local.json`, so\n * it must not be the zero address (rejected by config validation) and must\n * be replaced by the real deployed address.\n */\n\nimport { stringify } from 'yaml';\n// Narrow module, not the `testing.js` barrel — see manifest-env.ts for why.\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from '../../payments/x402/local-chain/accounts.js';\n\n/** Anvil account #1 — merchant settlement destination, never the gateway/facilitator. */\nexport const LOCAL_DEV_MERCHANT_ADDRESS = ANVIL_WELL_KNOWN_ACCOUNTS[1].address;\n/** Anvil account #0 — local facilitator signer (broadcasts settlement on the dev chain only). */\nexport const LOCAL_DEV_FACILITATOR_PRIVATE_KEY = ANVIL_WELL_KNOWN_ACCOUNTS[0].privateKey;\n/** Placeholder only — replace with the MockUSDC address from `.deploy/local.json`. */\nexport const PLACEHOLDER_ASSET_ADDRESS = '0x000000000000000000000000000000000000dEaD';\n\nexport type InitResourceChoice = 'weather' | 'report';\nexport type InitProtocolChoice = 'http' | 'mcp';\n\nexport interface InitAnswers {\n readonly backendBaseUrl: string;\n readonly resources: readonly InitResourceChoice[];\n readonly protocols: readonly InitProtocolChoice[];\n readonly x402Enabled: boolean;\n readonly merchantPayTo: string;\n}\n\nexport function defaultInitAnswers(): InitAnswers {\n return {\n backendBaseUrl: 'http://localhost:3000',\n resources: ['weather', 'report'],\n protocols: ['http', 'mcp'],\n x402Enabled: true,\n merchantPayTo: LOCAL_DEV_MERCHANT_ADDRESS,\n };\n}\n\nfunction buildResourcesMap(answers: InitAnswers): Record<string, unknown> {\n const resources: Record<string, unknown> = {};\n const expose = [...answers.protocols];\n\n if (answers.resources.includes('weather')) {\n resources.weather = {\n name: 'Get weather',\n description: 'Deterministic demo weather lookup (free resource).',\n input: {\n type: 'object',\n properties: { city: { type: 'string' } },\n required: ['city'],\n additionalProperties: false,\n },\n backend: {\n type: 'http',\n method: 'GET',\n url: `${answers.backendBaseUrl}/api/weather/{city}`,\n },\n pricing: { type: 'free' },\n expose,\n };\n }\n\n if (answers.resources.includes('report')) {\n const paid = answers.x402Enabled;\n resources.report = {\n name: 'Get market report',\n description: 'Deterministic demo premium market report.',\n // No caller-supplied fields for this resource: an explicit empty,\n // closed schema (rather than omitting `input`) so a missing schema can\n // never be read as \"anything goes\".\n input: {\n type: 'object',\n properties: {},\n additionalProperties: false,\n },\n backend: {\n type: 'http',\n method: 'GET',\n url: `${answers.backendBaseUrl}/api/report`,\n },\n pricing: paid ? { type: 'fixed', amount: '0.01', currency: 'USDC' } : { type: 'free' },\n expose,\n ...(paid ? { payments: ['x402'] } : {}),\n };\n }\n\n return resources;\n}\n\n/** Builds the raw config object accepted by `parseConfig` (src/config). */\nexport function buildInitConfigObject(answers: InitAnswers): Record<string, unknown> {\n return {\n version: 1,\n merchant: {\n id: 'demo-merchant',\n name: 'Demo Merchant',\n publicBaseUrl: 'http://localhost:8080',\n },\n server: { port: 8080, host: '127.0.0.1' },\n storage: { receipts: { driver: 'sqlite', path: './data/receipts.db' } },\n protocols: {\n http: { enabled: answers.protocols.includes('http') },\n mcp: { enabled: answers.protocols.includes('mcp'), mountPath: '/mcp' },\n },\n resources: buildResourcesMap(answers),\n payments: answers.x402Enabled\n ? {\n x402: {\n enabled: true,\n network: 'eip155:84532',\n rpcUrl: 'http://127.0.0.1:8545',\n asset: PLACEHOLDER_ASSET_ADDRESS,\n assetName: 'MockUSDC',\n assetVersion: '2',\n assetDecimals: 6,\n payTo: answers.merchantPayTo,\n maxTimeoutSeconds: 60,\n facilitator: { mode: 'local', signerPrivateKey: LOCAL_DEV_FACILITATOR_PRIVATE_KEY },\n },\n }\n : {},\n };\n}\n\nconst HEADER = `# Generated by \\`agent-commerce init\\`.\n#\n# Any address/key below labelled \"LOCAL DEVELOPMENT ONLY\" or \"placeholder\" is\n# either one of Anvil's well-known, public dev accounts (never fund them,\n# never use them outside a local chain) or a\n# not-yet-real address. Before running against the local chain, run\n# \\`npm run chain:deploy\\` and replace \\`payments.x402.asset\\` with the deployed\n# MockUSDC address from \\`.deploy/local.json\\`. Replace \\`payments.x402.payTo\\`\n# with your real merchant-controlled settlement address before ever pointing\n# this at a funded network.\n#\n# server.host is loopback (127.0.0.1) on purpose: binding every interface\n# should be a deliberate edit, not something you inherit from a generator.\n#\n# server.adminToken / server.allowedOrigins are left unset here — a generated\n# secret in a file you might commit is its own problem, so this is left as a\n# placeholder for you to fill in rather than a real token. Without a token,\n# the operator routes (/api/receipts, /api/events, /api/events/stream) —\n# the merchant's commerce ledger: payer addresses, amounts, settlement\n# hashes — return 404 rather than serving openly. To enable them, uncomment\n# and set:\n# server:\n# adminToken: \\${ADMIN_TOKEN}\n# allowedOrigins:\n# - http://localhost:5173\n# See SECURITY.md before exposing this gateway beyond localhost.\n`;\n\nexport function renderInitConfigYaml(answers: InitAnswers): string {\n const body = stringify(buildInitConfigObject(answers), { indent: 2 });\n return `${HEADER}\\n${body}`;\n}\n","/**\n * Local chain deployment manifest — read/write contract for `.deploy/local.json`.\n *\n * Exact shape frozen in docs/contracts.md. Everything else in the repo reads\n * chain addresses through `readLocalChainManifest()` — no hard-coded\n * addresses anywhere else.\n *\n * Lives inside `src/payments/x402` (not `scripts/chain`, which is\n * outside `src/` and is run directly by npm scripts —\n * see `deploy-engine.ts`'s header comment for the same reasoning) so any\n * workspace package can import it via `src/payments/x402/testing.ts`\n * (see `docs/contracts.md`, \"Local chain deployment manifest\"). It has no\n * dependency on viem/zod/x402 regardless — plain Node built-ins only —\n * `scripts/chain/manifest.ts` re-exports this module unchanged so\n * `npm run chain:deploy` keeps working as a thin CLI wrapper.\n */\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport const LOCAL_CHAIN_MANIFEST_PATH = '.deploy/local.json';\n\nexport interface LocalChainManifestMerchant {\n readonly address: string;\n readonly privateKeyLabel: string;\n}\n\nexport interface LocalChainManifestKeyedAccount {\n readonly address: string;\n readonly privateKey: string;\n readonly note: string;\n}\n\nexport interface LocalChainManifest {\n readonly chainId: number;\n readonly rpcUrl: string;\n /**\n * The same chain, reachable from the *host* — distinct from `rpcUrl` only\n * when the deployer ran inside a Docker network (there `rpcUrl` is the\n * container-internal address, e.g. \"http://anvil:8545\", unresolvable from\n * the host). A host deploy records the same value in both fields, since on\n * the host they genuinely are the same endpoint. Host-side consumers\n * (demo agent, CLI) should prefer `hostRpcUrl ?? rpcUrl`. Optional so a\n * manifest written before this field existed still parses.\n */\n readonly hostRpcUrl?: string;\n readonly asset: string;\n readonly assetName: string;\n readonly assetVersion: string;\n readonly assetDecimals: number;\n readonly merchant: LocalChainManifestMerchant;\n readonly buyer: LocalChainManifestKeyedAccount;\n readonly facilitator: LocalChainManifestKeyedAccount;\n readonly buyerInitialBalance: string;\n}\n\nconst REQUIRED_TOP_LEVEL_STRING_FIELDS = [\n 'rpcUrl',\n 'asset',\n 'assetName',\n 'assetVersion',\n 'buyerInitialBalance',\n] as const;\n\n/**\n * Reads and structurally validates `.deploy/local.json`.\n *\n * Throws a clear, actionable error if the manifest is missing or malformed —\n * every consumer of this function is expected to let that error propagate\n * rather than silently falling back to a hard-coded address.\n */\nexport function readLocalChainManifest(cwd: string = process.cwd()): LocalChainManifest {\n const path = join(cwd, LOCAL_CHAIN_MANIFEST_PATH);\n\n if (!existsSync(path)) {\n throw new Error(\n `Local chain manifest not found at \"${path}\". Run \"npm run chain:start\" then \"npm run chain:deploy\" first.`,\n );\n }\n\n let raw: string;\n try {\n raw = readFileSync(path, 'utf8');\n } catch (cause) {\n throw new Error(`Could not read local chain manifest at \"${path}\".`, { cause });\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n throw new Error(\n `Local chain manifest at \"${path}\" is not valid JSON. Re-run \"npm run chain:deploy\" to regenerate it.`,\n { cause },\n );\n }\n\n return validateManifestShape(parsed, path);\n}\n\nfunction validateManifestShape(value: unknown, path: string): LocalChainManifest {\n const fail = (detail: string): never => {\n throw new Error(\n `Local chain manifest at \"${path}\" is invalid: ${detail}. Re-run \"npm run chain:deploy\".`,\n );\n };\n\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return fail('expected a JSON object');\n }\n const record = value as Record<string, unknown>;\n\n if (typeof record.chainId !== 'number') {\n return fail('\"chainId\" must be a number');\n }\n if (typeof record.assetDecimals !== 'number') {\n return fail('\"assetDecimals\" must be a number');\n }\n for (const field of REQUIRED_TOP_LEVEL_STRING_FIELDS) {\n if (typeof record[field] !== 'string' || record[field] === '') {\n return fail(`\"${field}\" must be a non-empty string`);\n }\n }\n // Optional: absent entirely on a manifest written before this field\n // existed, but if present it must be well-formed — never silently ignore a\n // malformed value on a trust-boundary read.\n if ('hostRpcUrl' in record && record.hostRpcUrl !== undefined) {\n if (typeof record.hostRpcUrl !== 'string' || record.hostRpcUrl === '') {\n return fail('\"hostRpcUrl\" must be a non-empty string when present');\n }\n }\n\n const merchant = record.merchant;\n if (\n typeof merchant !== 'object' ||\n merchant === null ||\n typeof (merchant as Record<string, unknown>).address !== 'string' ||\n typeof (merchant as Record<string, unknown>).privateKeyLabel !== 'string'\n ) {\n return fail('\"merchant\" must be { address: string, privateKeyLabel: string }');\n }\n\n for (const key of ['buyer', 'facilitator'] as const) {\n const account = record[key];\n if (\n typeof account !== 'object' ||\n account === null ||\n typeof (account as Record<string, unknown>).address !== 'string' ||\n typeof (account as Record<string, unknown>).privateKey !== 'string' ||\n typeof (account as Record<string, unknown>).note !== 'string'\n ) {\n return fail(`\"${key}\" must be { address: string, privateKey: string, note: string }`);\n }\n }\n\n return record as unknown as LocalChainManifest;\n}\n","/**\n * Local-development convenience: fills `X402_*`/`MERCHANT_WALLET`\n * placeholders in `config.yaml` from `.deploy/local.json` (written\n * by `npm run chain:deploy`) when the host shell hasn't set them itself.\n *\n * Why this exists: inside `docker compose`, `docker/gateway-entrypoint.sh`\n * exports these from the manifest before the gateway process starts. Running\n * `agent-commerce validate`/`doctor` on the host has no equivalent step, so\n * the exact same config that starts the (containerised) gateway fine fails\n * host-side with \"Unresolved environment variable\" — reporting a healthy\n * stack as broken. See docs/contracts.md \"Local chain deployment manifest\".\n *\n * Deliberately narrow: only fills a variable that is completely unset (a\n * real environment always wins — this can never override a deployment), only\n * from the exact fields the manifest declares, and only for `validate`/\n * `doctor` — never inside the config loader itself, so gateway startup is\n * unaffected either way.\n */\n// Imported from the narrow module, not the `testing.js` barrel: that barrel\n// also re-exports the Anvil bootstrap and the deploy engine, which import\n// `viem`. Tree-shaking drops the unused bindings but esbuild still emits a\n// bare `import 'viem'` for side effects, and viem is an optional peer — the\n// CLI would refuse to start on a default install. Caught by a bare\n// clean-consumer install, not by any in-repo test.\nimport {\n LOCAL_CHAIN_MANIFEST_PATH,\n type LocalChainManifest,\n readLocalChainManifest,\n} from '../../payments/x402/local-chain/manifest.js';\n\nexport { LOCAL_CHAIN_MANIFEST_PATH };\n\n/** `config.yaml` placeholder name -> the manifest field it maps to. */\nconst MANIFEST_ENV_VARS: readonly (readonly [string, (m: LocalChainManifest) => string])[] = [\n ['X402_ASSET', (m) => m.asset],\n ['X402_ASSET_NAME', (m) => m.assetName],\n ['X402_ASSET_VERSION', (m) => m.assetVersion],\n ['X402_ASSET_DECIMALS', (m) => String(m.assetDecimals)],\n ['MERCHANT_WALLET', (m) => m.merchant.address],\n ['X402_FACILITATOR_PRIVATE_KEY', (m) => m.facilitator.privateKey],\n];\n\n/** The subset of {@link MANIFEST_ENV_VARS} names, for checking a failed variable against. */\nexport const MANIFEST_FILLABLE_ENV_VAR_NAMES: ReadonlySet<string> = new Set(\n MANIFEST_ENV_VARS.map(([name]) => name),\n);\n\nexport interface ManifestEnvFill {\n /** `baseEnv`, plus any variables filled. Never mutates `baseEnv` itself. */\n readonly env: NodeJS.ProcessEnv;\n /** Names actually filled — empty when the manifest was absent or nothing needed filling. */\n readonly filled: readonly string[];\n /** True once a manifest was found at all, whether or not anything needed filling. */\n readonly manifestFound: boolean;\n}\n\n/**\n * Reads `.deploy/local.json` (relative to `cwd`) and fills only the\n * currently-unset variables in {@link MANIFEST_ENV_VARS}. Never throws — a\n * missing or invalid manifest just means nothing gets filled, and the\n * existing \"unresolved environment variable\" error from `src/config`\n * surfaces exactly as it does today.\n */\nexport function fillEnvFromLocalChainManifest(\n baseEnv: NodeJS.ProcessEnv,\n cwd: string = process.cwd(),\n): ManifestEnvFill {\n let manifest: LocalChainManifest;\n try {\n manifest = readLocalChainManifest(cwd);\n } catch {\n return { env: baseEnv, filled: [], manifestFound: false };\n }\n\n const filled: string[] = [];\n const env: NodeJS.ProcessEnv = { ...baseEnv };\n for (const [name, read] of MANIFEST_ENV_VARS) {\n if (env[name] === undefined) {\n env[name] = read(manifest);\n filled.push(name);\n }\n }\n return { env, filled, manifestFound: true };\n}\n","/**\n * Safe, visible-but-non-secret display of an address/destination for\n * `doctor`. Shows enough to eyeball correctness without ever printing a full\n * value that could be sensitive-adjacent (e.g. an RPC URL with an embedded\n * API key).\n *\n * Returning the value whole when it is short enough (`length <= keep * 2`)\n * would contradict the promise above — harmless for the 42-character\n * addresses this is used on today, and a trap for the next caller who reaches\n * for it with a short secret. A short value is masked entirely instead.\n */\nexport function maskMiddle(value: string, keep = 6): string {\n if (value.length <= keep * 2) return value.length === 0 ? value : '…';\n return `${value.slice(0, keep)}…${value.slice(-4)}`;\n}\n","/**\n * The CLI's own version and every pinned protocol/SDK version — never\n * hard-coded, so a pin bump (see docs/contracts.md) is reflected automatically.\n *\n * Two resolution paths, deliberately:\n *\n * - **Development** reads the root manifest directly, so the numbers are\n * always live.\n * - **The published npm package** cannot: the build collapses `src/**` into\n * two bundled files, so a relative manifest path written against a source\n * location resolves from the wrong depth once bundled. That has now failed\n * twice — it silently produced `v0.0.0-unknown` before packaging, and it\n * crashed both entry points during the single-package refactor. So the\n * build injects the resolved report as `__OAC_VERSION_REPORT__` (see\n * tsup.config.ts) and it is preferred when present.\n *\n * `typeof` on an undeclared identifier is safe in JS, so the dev path is\n * unaffected by the constant not existing.\n */\nimport { createRequire } from 'node:module';\n\ndeclare const __OAC_VERSION_REPORT__: string | undefined;\n\nconst require = createRequire(import.meta.url);\n\ninterface PackageManifest {\n readonly version: string;\n readonly dependencies?: Readonly<Record<string, string>>;\n readonly peerDependencies?: Readonly<Record<string, string>>;\n}\n\nfunction readManifest(relativePath: string): PackageManifest | undefined {\n try {\n return require(relativePath) as PackageManifest;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Peers count as pins. The three heaviest pins — the MCP SDK, x402 and viem —\n * are *optional peer* dependencies so a default install stays small, and\n * reading only `dependencies` silently emptied this report of exactly the\n * protocol/SDK versions it exists to show.\n */\nfunction depVersion(manifest: PackageManifest | undefined, name: string): string | undefined {\n return manifest?.dependencies?.[name] ?? manifest?.peerDependencies?.[name];\n}\n\nexport interface PinnedVersion {\n readonly name: string;\n readonly version: string;\n readonly via: string;\n}\n\nexport interface VersionReport {\n readonly cliVersion: string;\n readonly pinned: readonly PinnedVersion[];\n}\n\n/** Missing entries are omitted (rather than shown as \"unknown\") so nothing is ever fabricated. */\nexport function readVersionReport(): VersionReport {\n const injected = typeof __OAC_VERSION_REPORT__ === 'string' ? __OAC_VERSION_REPORT__ : undefined;\n if (injected !== undefined) {\n return JSON.parse(injected) as VersionReport;\n }\n\n // One package, one manifest. `via` names the module that owns each pin,\n // which is what a reader of `agent-commerce version` actually wants to know;\n // the names are src/ directories, not package manifests.\n const manifest = readManifest('../../../package.json');\n\n const candidates: readonly [string, string][] = [\n ['@modelcontextprotocol/sdk', 'protocols/mcp'],\n ['@coinbase/x402', 'payments/x402'],\n ['@x402/core', 'payments/x402'],\n ['@x402/evm', 'payments/x402'],\n ['viem', 'payments/x402'],\n ['better-sqlite3', 'storage/receipts'],\n ['fastify', 'gateway'],\n ['pino', 'gateway'],\n ['zod', 'config'],\n ];\n\n const pinned: PinnedVersion[] = [];\n for (const [name, via] of candidates) {\n const version = depVersion(manifest, name);\n if (version !== undefined) {\n pinned.push({ name, version, via });\n }\n }\n\n return {\n cliVersion: manifest?.version ?? '0.0.0-unknown',\n pinned,\n };\n}\n","import { existsSync, mkdirSync } from 'node:fs';\nimport { writeFile } from 'node:fs/promises';\nimport { dirname, resolve } from 'node:path';\nimport * as clack from '@clack/prompts';\nimport { DEFAULT_CONFIG_FILENAME } from '../../config/filename.js';\nimport {\n type ConfigLoader,\n type ConfigParser,\n type GatewayConfig,\n loadConfigDynamic,\n parseConfigDynamic,\n} from '../lib/config-client.js';\nimport {\n buildInitConfigObject,\n defaultInitAnswers,\n type InitAnswers,\n type InitProtocolChoice,\n type InitResourceChoice,\n renderInitConfigYaml,\n} from '../lib/init-config.js';\nimport type { Io } from '../lib/io.js';\nimport { formatConfigError } from './validate.js';\n\nexport interface InitOptions {\n readonly outputPath?: string;\n readonly force?: boolean;\n readonly yes?: boolean;\n}\n\nexport interface InitDeps {\n readonly loadConfig?: ConfigLoader;\n readonly parseConfig?: ConfigParser;\n readonly collectAnswers?: () => Promise<InitAnswers | undefined>;\n readonly fileExists?: (path: string) => boolean;\n readonly writeFile?: (path: string, content: string) => Promise<void>;\n}\n\n/** Exported for testing: the real interactive prompt flow (mocks `@clack/prompts`). */\nexport async function collectAnswersInteractive(): Promise<InitAnswers | undefined> {\n clack.intro('agent-commerce init');\n\n const backendBaseUrl = await clack.text({\n message: 'Backend base URL (your existing merchant API)',\n initialValue: 'http://localhost:3000',\n // shape-checked here, where the user can retype it,\n // rather than surfacing as a config error after the fact.\n validate: (value) => {\n const trimmed = (value ?? '').trim();\n if (trimmed.length === 0) return 'Required';\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n return 'Must be an absolute URL, e.g. http://localhost:3000';\n }\n return parsed.protocol === 'http:' || parsed.protocol === 'https:'\n ? undefined\n : 'Must use http:// or https://';\n },\n });\n if (clack.isCancel(backendBaseUrl)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n const resources = await clack.multiselect<InitResourceChoice>({\n message: 'Which example resource(s) do you want to expose?',\n options: [\n { value: 'weather', label: 'Weather (free)' },\n { value: 'report', label: 'Market report (paid)' },\n ],\n initialValues: ['weather', 'report'],\n required: false,\n });\n if (clack.isCancel(resources)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n const protocols = await clack.multiselect<InitProtocolChoice>({\n message: 'Which protocols should be enabled?',\n options: [\n { value: 'http', label: 'HTTP' },\n { value: 'mcp', label: 'MCP' },\n ],\n initialValues: ['http', 'mcp'],\n // `required: false` permits an empty selection, which renders\n // `expose: []` on every resource and fails the schema's min(1). clack's\n // multiselect has no `validate` hook, so this is caught by the in-memory\n // validation in `runInit` — which now reports the real schema error and\n // writes nothing, instead of leaving an invalid file behind.\n required: false,\n });\n if (clack.isCancel(protocols)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n const x402Enabled = await clack.confirm({ message: 'Enable x402 payments?', initialValue: true });\n if (clack.isCancel(x402Enabled)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n\n let merchantPayTo = defaultInitAnswers().merchantPayTo;\n if (x402Enabled) {\n const answer = await clack.text({\n message:\n 'Merchant settlement destination address (merchant-controlled — never a gateway-owned wallet)',\n initialValue: merchantPayTo,\n validate: (value) => {\n const trimmed = (value ?? '').trim();\n if (trimmed.length === 0) return 'Required';\n // Same shape the config schema enforces; catching it here means a\n // typo'd address never reaches the \"generated config is invalid\" path.\n return /^0x[0-9a-fA-F]{40}$/.test(trimmed)\n ? undefined\n : 'Must be a 0x-prefixed 20-byte EVM address (42 characters)';\n },\n });\n if (clack.isCancel(answer)) {\n clack.cancel('Aborted.');\n return undefined;\n }\n merchantPayTo = answer;\n }\n\n clack.outro('Configuration answers collected.');\n\n return { backendBaseUrl, resources, protocols, x402Enabled, merchantPayTo };\n}\n\n/** `agent-commerce init [--yes] [--force] [--output <path>]`. */\nexport async function runInit(options: InitOptions, io: Io, deps: InitDeps = {}): Promise<number> {\n const outputPath = options.outputPath ?? DEFAULT_CONFIG_FILENAME;\n const loadConfig = deps.loadConfig ?? loadConfigDynamic;\n const parseConfigInMemory = deps.parseConfig ?? parseConfigDynamic;\n const fileExists = deps.fileExists ?? existsSync;\n const writeFileImpl =\n deps.writeFile ??\n (async (path: string, content: string) => {\n await writeFile(path, content, 'utf8');\n });\n\n if (fileExists(outputPath) && options.force !== true) {\n io.stderr(`FAIL ${outputPath} already exists. Re-run with --force to overwrite.`);\n return 1;\n }\n\n const answers =\n options.yes === true\n ? defaultInitAnswers()\n : await (deps.collectAnswers ?? collectAnswersInteractive)();\n\n if (answers === undefined) {\n io.stderr('FAIL init aborted, nothing was written.');\n return 1;\n }\n\n // Validate BEFORE writing. Interactive answers can legitimately fail\n // validation — an empty protocol multiselect, a typo'd settlement address,\n // a scheme-less backend URL — and writing first would print \"PASS Wrote …\"\n // and then blame the tool: \"please report this as a bug\". Nothing is\n // written unless it is valid, and the message is the real configuration\n // error, which names the field the user can fix.\n let config: GatewayConfig;\n try {\n config = await parseConfigInMemory(buildInitConfigObject(answers));\n } catch (err) {\n io.stderr(formatConfigError(err));\n io.stderr(`FAIL Nothing was written to ${outputPath}.`);\n return 1;\n }\n\n const yamlContent = renderInitConfigYaml(answers);\n const resolvedPath = resolve(outputPath);\n const dir = dirname(resolvedPath);\n if (dir !== '' && !existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n await writeFileImpl(outputPath, yamlContent);\n io.stdout(`PASS Wrote ${outputPath}`);\n io.stdout(`PASS ${outputPath} is valid — ${config.resources.length} resource(s)`);\n\n // The YAML is rendered from the very object just validated, but it is\n // rendered, not serialised from it — so read it back and confirm the two\n // agree. A renderer bug is the one failure the in-memory check cannot see,\n // and it IS a bug worth reporting.\n try {\n await loadConfig({ path: outputPath });\n } catch (err) {\n io.stderr(formatConfigError(err));\n io.stderr(\n `FAIL ${outputPath} was written but does not parse, although the same answers validated in memory — this is a bug in the config renderer, please report it.`,\n );\n return 1;\n }\n\n io.stdout('');\n io.stdout('Next steps:');\n io.stdout(` agent-commerce validate --config ${outputPath}`);\n // Only commands the reader can actually run. `npm run dev:merchant` and\n // `npm run dev:gateway` exist solely inside the development repo, and this\n // CLI ships to npm — telling an installed user to run them is a dead end.\n io.stdout(' docker compose up # start the local demo stack (from a repo clone)');\n io.stdout(` agent-commerce doctor --config ${outputPath}`);\n\n return 0;\n}\n","import { ZodError } from 'zod';\nimport { isCommerceError } from '../../core/index.js';\nimport { type ConfigLoader, loadConfigDynamic } from '../lib/config-client.js';\nimport type { Io } from '../lib/io.js';\nimport {\n fillEnvFromLocalChainManifest,\n LOCAL_CHAIN_MANIFEST_PATH,\n MANIFEST_FILLABLE_ENV_VAR_NAMES,\n type ManifestEnvFill,\n} from '../lib/manifest-env.js';\n\nexport interface ValidateOptions {\n readonly configPath?: string;\n}\n\nexport interface ValidateDeps {\n readonly loadConfig?: ConfigLoader;\n readonly fillEnvFromManifest?: (env: NodeJS.ProcessEnv) => ManifestEnvFill;\n}\n\n/**\n * Formats a config-loading failure into an actionable report.\n *\n * Handles the three error shapes `src/config` can produce:\n * a `CommerceError('CONFIG_INVALID', …)` with structured details, a raw\n * `ZodError` (schema errors, one line per failing path), or a plain Error\n * (e.g. a YAML syntax error, or the \"config package not available yet\"\n * integration-gap error). Never prints a resolved `${ENV}` value — only ever\n * the variable name, which the underlying error message is expected to carry.\n *\n * `manifestFound` adds one more hint line when the failure is specifically an\n * unresolved variable that `.deploy/local.json` would have supplied, had\n * `npm run chain:deploy` been run — see `../lib/manifest-env.js`.\n */\nexport function formatConfigError(err: unknown, manifestFound = false): string {\n if (isCommerceError(err)) {\n const lines = [`FAIL ${err.code}: ${err.message}`];\n if (err.details !== undefined) {\n lines.push(` details: ${JSON.stringify(err.details)}`);\n }\n const variable = err.details?.['variable'];\n if (\n !manifestFound &&\n typeof variable === 'string' &&\n MANIFEST_FILLABLE_ENV_VAR_NAMES.has(variable)\n ) {\n lines.push(\n ` hint: \"npm run chain:deploy\" writes ${LOCAL_CHAIN_MANIFEST_PATH}, which validate/doctor read automatically to fill local X402_*/MERCHANT_WALLET placeholders.`,\n );\n }\n return lines.join('\\n');\n }\n if (err instanceof ZodError) {\n const lines = ['FAIL Configuration schema errors:'];\n for (const issue of err.issues) {\n const path = issue.path.length > 0 ? issue.path.join('.') : '(root)';\n lines.push(` - ${path}: ${issue.message}`);\n }\n return lines.join('\\n');\n }\n if (err instanceof Error) {\n return `FAIL ${err.message}`;\n }\n return `FAIL ${String(err)}`;\n}\n\n/** `agent-commerce validate [--config <path>]`. Exit code is non-zero on invalid configuration. */\nexport async function runValidate(\n options: ValidateOptions,\n io: Io,\n deps: ValidateDeps = {},\n): Promise<number> {\n const loadConfig = deps.loadConfig ?? loadConfigDynamic;\n const fillEnvFromManifest = deps.fillEnvFromManifest ?? fillEnvFromLocalChainManifest;\n const { env, filled, manifestFound } = fillEnvFromManifest(process.env);\n if (filled.length > 0) {\n io.stdout(`using local chain manifest ${LOCAL_CHAIN_MANIFEST_PATH} for ${filled.join(', ')}`);\n }\n try {\n const config = await loadConfig({\n ...(options.configPath !== undefined ? { path: options.configPath } : {}),\n env,\n });\n io.stdout('PASS Configuration is valid');\n io.stdout(` merchant: ${config.merchant.name} (${config.merchant.id})`);\n io.stdout(` resources: ${config.resources.length}`);\n io.stdout(\n ` protocols: http=${config.protocols.http.enabled ? 'on' : 'off'} mcp=${config.protocols.mcp.enabled ? 'on' : 'off'}`,\n );\n io.stdout(` payments: x402=${config.payments.x402?.enabled === true ? 'on' : 'off'}`);\n return 0;\n } catch (err) {\n io.stderr(formatConfigError(err, manifestFound));\n return 1;\n }\n}\n","import type { Io } from '../lib/io.js';\nimport { readVersionReport, type VersionReport } from '../lib/versions.js';\n\nexport interface VersionDeps {\n readonly readVersionReport?: () => VersionReport;\n}\n\n/** `agent-commerce version` — CLI version + pinned protocol/SDK versions. */\nexport function runVersion(io: Io, deps: VersionDeps = {}): number {\n const report = (deps.readVersionReport ?? readVersionReport)();\n io.stdout(`agent-commerce v${report.cliVersion}`);\n if (report.pinned.length > 0) {\n io.stdout('');\n io.stdout('Pinned protocol / SDK versions:');\n for (const pin of report.pinned) {\n io.stdout(` ${pin.name.padEnd(24)} ${pin.version.padEnd(12)} (via ${pin.via})`);\n }\n }\n return 0;\n}\n","/**\n * Minimal, injectable stdout/stderr so command logic is testable without\n * capturing real process streams.\n */\nexport interface Io {\n stdout(line: string): void;\n stderr(line: string): void;\n}\n\nexport const processIo: Io = {\n stdout: (line) => {\n process.stdout.write(`${line}\\n`);\n },\n stderr: (line) => {\n process.stderr.write(`${line}\\n`);\n },\n};\n\n/** Collects lines instead of writing anywhere. Useful for tests. */\nexport function createCapturingIo(): Io & { out: string[]; err: string[] } {\n const out: string[] = [];\n const err: string[] = [];\n return {\n out,\n err,\n stdout: (line) => out.push(line),\n stderr: (line) => err.push(line),\n };\n}\n","#!/usr/bin/env node\nimport { CommanderError } from 'commander';\nimport { buildProgram } from './program.js';\n\n/**\n * `agent-commerce version | grep -q x402` is an ordinary thing to type, and\n * `grep -q` exits on its first match — closing the pipe while the CLI is still\n * writing. Node's default for that is an unhandled `EPIPE` error event on the\n * socket, which aborts the process with a stack trace: a command that did\n * exactly what was asked, reported as a crash, and a red CI step.\n *\n * Exit quietly instead. Every other stream error still throws.\n */\nfor (const stream of [process.stdout, process.stderr]) {\n stream.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EPIPE') process.exit(0);\n throw err;\n });\n}\n\nasync function main(): Promise<void> {\n const program = buildProgram();\n try {\n await program.parseAsync(process.argv);\n } catch (err) {\n if (err instanceof CommanderError) {\n process.exitCode = err.exitCode;\n return;\n }\n throw err;\n }\n}\n\nvoid main();\n"]}