@agent-score/commerce 1.8.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +73 -9
  2. package/dist/{_response-9yp6Fit2.d.mts → _response-BFYN3b6i.d.mts} +17 -19
  3. package/dist/{_response-CC6jNb8q.d.ts → _response-_iPD5AIj.d.ts} +17 -19
  4. package/dist/challenge/index.d.mts +106 -198
  5. package/dist/challenge/index.d.ts +106 -198
  6. package/dist/challenge/index.js +238 -111
  7. package/dist/challenge/index.js.map +1 -1
  8. package/dist/challenge/index.mjs +238 -111
  9. package/dist/challenge/index.mjs.map +1 -1
  10. package/dist/checkout-B1JuEcbx.d.ts +939 -0
  11. package/dist/checkout-BN5i1Fi7.d.mts +939 -0
  12. package/dist/core.d.mts +2 -2
  13. package/dist/core.d.ts +2 -2
  14. package/dist/core.js +1 -1
  15. package/dist/core.js.map +1 -1
  16. package/dist/core.mjs +1 -1
  17. package/dist/core.mjs.map +1 -1
  18. package/dist/discovery/index.d.mts +453 -51
  19. package/dist/discovery/index.d.ts +453 -51
  20. package/dist/discovery/index.js +1092 -58
  21. package/dist/discovery/index.js.map +1 -1
  22. package/dist/discovery/index.mjs +1060 -57
  23. package/dist/discovery/index.mjs.map +1 -1
  24. package/dist/identity/express.d.mts +3 -3
  25. package/dist/identity/express.d.ts +3 -3
  26. package/dist/identity/express.js +30 -19
  27. package/dist/identity/express.js.map +1 -1
  28. package/dist/identity/express.mjs +30 -19
  29. package/dist/identity/express.mjs.map +1 -1
  30. package/dist/identity/fastify.d.mts +4 -4
  31. package/dist/identity/fastify.d.ts +4 -4
  32. package/dist/identity/fastify.js +30 -19
  33. package/dist/identity/fastify.js.map +1 -1
  34. package/dist/identity/fastify.mjs +30 -19
  35. package/dist/identity/fastify.mjs.map +1 -1
  36. package/dist/identity/hono.d.mts +3 -3
  37. package/dist/identity/hono.d.ts +3 -3
  38. package/dist/identity/hono.js +30 -19
  39. package/dist/identity/hono.js.map +1 -1
  40. package/dist/identity/hono.mjs +30 -19
  41. package/dist/identity/hono.mjs.map +1 -1
  42. package/dist/identity/nextjs.d.mts +6 -7
  43. package/dist/identity/nextjs.d.ts +6 -7
  44. package/dist/identity/nextjs.js +30 -19
  45. package/dist/identity/nextjs.js.map +1 -1
  46. package/dist/identity/nextjs.mjs +30 -19
  47. package/dist/identity/nextjs.mjs.map +1 -1
  48. package/dist/identity/policy.d.mts +41 -4
  49. package/dist/identity/policy.d.ts +41 -4
  50. package/dist/identity/policy.js +23307 -18
  51. package/dist/identity/policy.js.map +1 -1
  52. package/dist/identity/policy.mjs +23313 -3
  53. package/dist/identity/policy.mjs.map +1 -1
  54. package/dist/identity/web.d.mts +3 -3
  55. package/dist/identity/web.d.ts +3 -3
  56. package/dist/identity/web.js +30 -19
  57. package/dist/identity/web.js.map +1 -1
  58. package/dist/identity/web.mjs +30 -19
  59. package/dist/identity/web.mjs.map +1 -1
  60. package/dist/index.d.mts +72 -329
  61. package/dist/index.d.ts +72 -329
  62. package/dist/index.js +23301 -378
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +23294 -362
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/payment/index.d.mts +297 -265
  67. package/dist/payment/index.d.ts +297 -265
  68. package/dist/payment/index.js +605 -149
  69. package/dist/payment/index.js.map +1 -1
  70. package/dist/payment/index.mjs +590 -148
  71. package/dist/payment/index.mjs.map +1 -1
  72. package/dist/{agent_instructions-DiMSGkdm.d.mts → pricing-CQ9DIFaw.d.ts} +109 -56
  73. package/dist/{agent_instructions-DiMSGkdm.d.ts → pricing-CxzwyiO6.d.mts} +109 -56
  74. package/dist/rail_spec-XP0wKgJV.d.mts +132 -0
  75. package/dist/rail_spec-XP0wKgJV.d.ts +132 -0
  76. package/dist/{signer-CFVQsWjL.d.mts → signer-3FAit11j.d.mts} +27 -1
  77. package/dist/{signer-CFVQsWjL.d.ts → signer-3FAit11j.d.ts} +27 -1
  78. package/dist/solana-Cds87OTu.d.mts +67 -0
  79. package/dist/solana-Cds87OTu.d.ts +67 -0
  80. package/dist/stripe-multichain/index.d.mts +55 -66
  81. package/dist/stripe-multichain/index.d.ts +55 -66
  82. package/dist/stripe-multichain/index.js +68 -42
  83. package/dist/stripe-multichain/index.js.map +1 -1
  84. package/dist/stripe-multichain/index.mjs +68 -41
  85. package/dist/stripe-multichain/index.mjs.map +1 -1
  86. package/dist/{wwwauthenticate-CU1eNvMQ.d.mts → wwwauthenticate-D_FMnPgU.d.mts} +9 -10
  87. package/dist/{wwwauthenticate-CU1eNvMQ.d.ts → wwwauthenticate-D_FMnPgU.d.ts} +9 -10
  88. package/dist/x402_server-hgQzWQwB.d.mts +81 -0
  89. package/dist/x402_server-hgQzWQwB.d.ts +81 -0
  90. package/package.json +9 -7
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/payment/networks.ts","../../src/payment/usdc.ts","../../src/payment/rails.ts","../../src/payment/directive.ts","../../src/payment/wwwauthenticate.ts","../../src/discovery/probe.ts","../../src/discovery/bazaar.ts","../../src/discovery/well_known_mpp.ts","../../src/discovery/well_known_x402.ts","../../src/discovery/llms_txt.ts","../../src/discovery/openapi.ts","../../src/discovery/robots_tag.ts","../../src/challenge/agent_instructions.ts","../../src/discovery/skill_md.ts"],"sourcesContent":["/**\n * Named network registry. Vendors reference symbolic names (`networks.base.mainnet.caip2`)\n * instead of magic strings. Lifted from agentscore-pay's constants.\n */\nexport const networks = {\n base: {\n mainnet: { caip2: 'eip155:8453' as const, chainId: 8453 },\n sepolia: { caip2: 'eip155:84532' as const, chainId: 84532 },\n },\n solana: {\n mainnet: { caip2: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' as const },\n devnet: { caip2: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1' as const },\n },\n tempo: {\n mainnet: { caip2: 'eip155:4217' as const, chainId: 4217 },\n testnet: { caip2: 'eip155:42431' as const, chainId: 42431 },\n },\n} as const;\n\nexport type NetworkFamily = keyof typeof networks;\n\n/**\n * Returns the family name (base/solana/tempo) for a given CAIP-2 network string,\n * or null if the network isn't in the registry. Useful for routing settlement\n * by network.\n */\nexport function networkFamily(caip2: string): NetworkFamily | null {\n if (caip2 === networks.base.mainnet.caip2 || caip2 === networks.base.sepolia.caip2) return 'base';\n if (caip2 === networks.solana.mainnet.caip2 || caip2 === networks.solana.devnet.caip2) return 'solana';\n if (caip2 === networks.tempo.mainnet.caip2 || caip2 === networks.tempo.testnet.caip2) return 'tempo';\n if (caip2.startsWith('solana:')) return 'solana';\n return null;\n}\n","/**\n * USDC token registry per network. Used by paymentDirective and rail definitions.\n * Lifted from agentscore-pay's constants.\n */\nexport const USDC = {\n base: {\n mainnet: { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const, decimals: 6 },\n sepolia: { address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as const, decimals: 6 },\n },\n solana: {\n mainnet: { mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6 },\n devnet: { mint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', decimals: 6 },\n },\n tempo: {\n mainnet: { address: '0x20C000000000000000000000b9537d11c60E8b50' as const, decimals: 6 },\n testnet: { address: '0x20c0000000000000000000000000000000000000' as const, decimals: 6 },\n },\n} as const;\n","import { networks } from './networks';\nimport { USDC } from './usdc';\n\n/**\n * Symbolic rail names mapped to their protocol details. Vendors pass `rail: 'tempo-mainnet'`\n * to the directive builder and the SDK fills in method/network/decimals/currency from this\n * registry. Custom rails not in this registry can be passed by setting the lower-level\n * fields directly on the directive builder.\n */\nexport const rails = {\n 'tempo-mainnet': {\n method: 'tempo',\n network: networks.tempo.mainnet.caip2,\n chainId: networks.tempo.mainnet.chainId,\n currency: USDC.tempo.mainnet.address,\n decimals: USDC.tempo.mainnet.decimals,\n asset: USDC.tempo.mainnet.address,\n },\n 'tempo-testnet': {\n method: 'tempo',\n network: networks.tempo.testnet.caip2,\n chainId: networks.tempo.testnet.chainId,\n currency: USDC.tempo.testnet.address,\n decimals: USDC.tempo.testnet.decimals,\n asset: USDC.tempo.testnet.address,\n },\n 'x402-base-mainnet': {\n method: 'x402',\n network: networks.base.mainnet.caip2,\n chainId: networks.base.mainnet.chainId,\n currency: USDC.base.mainnet.address,\n decimals: USDC.base.mainnet.decimals,\n asset: USDC.base.mainnet.address,\n },\n 'x402-base-sepolia': {\n method: 'x402',\n network: networks.base.sepolia.caip2,\n chainId: networks.base.sepolia.chainId,\n currency: USDC.base.sepolia.address,\n decimals: USDC.base.sepolia.decimals,\n asset: USDC.base.sepolia.address,\n },\n // Upto rails — pay UP TO a max amount (Permit2-based, vs EIP-3009 for exact). Use for\n // variable-cost APIs where the actual cost depends on output (LLM tokens, bandwidth, etc.).\n // Only available on EVM networks; Solana svm doesn't ship an upto scheme yet.\n 'x402-base-mainnet-upto': {\n method: 'x402-upto',\n network: networks.base.mainnet.caip2,\n chainId: networks.base.mainnet.chainId,\n currency: USDC.base.mainnet.address,\n decimals: USDC.base.mainnet.decimals,\n asset: USDC.base.mainnet.address,\n },\n 'x402-base-sepolia-upto': {\n method: 'x402-upto',\n network: networks.base.sepolia.caip2,\n chainId: networks.base.sepolia.chainId,\n currency: USDC.base.sepolia.address,\n decimals: USDC.base.sepolia.decimals,\n asset: USDC.base.sepolia.address,\n },\n 'mpp-solana-mainnet': {\n method: 'solana',\n network: networks.solana.mainnet.caip2,\n currency: USDC.solana.mainnet.mint,\n decimals: USDC.solana.mainnet.decimals,\n asset: USDC.solana.mainnet.mint,\n },\n 'mpp-solana-devnet': {\n method: 'solana',\n network: networks.solana.devnet.caip2,\n currency: USDC.solana.devnet.mint,\n decimals: USDC.solana.devnet.decimals,\n asset: USDC.solana.devnet.mint,\n },\n 'stripe-spt': {\n method: 'stripe',\n currency: 'usd',\n decimals: 2,\n },\n} as const;\n\nexport type RailName = keyof typeof rails;\n\nexport interface RailDefinition {\n method: string;\n network?: string;\n chainId?: number;\n currency: string;\n decimals: number;\n asset?: string;\n}\n\n/**\n * Lookup a rail definition by symbolic name. Returns undefined if the rail isn't in\n * the registry — vendors with custom rails should pass the low-level fields directly.\n */\nexport function lookupRail(name: string): RailDefinition | undefined {\n return rails[name as RailName] as RailDefinition | undefined;\n}\n","import { lookupRail } from './rails';\n\nexport interface PaymentRequestInput {\n /** Symbolic rail name (e.g., 'tempo-mainnet', 'x402-base-mainnet') — fills in defaults */\n rail?: string;\n /** Amount in USD as a number or string. Converted to raw integer using `decimals`. */\n amountUsd: string | number;\n /** Token contract address or currency code. Defaults from rail. */\n currency?: string;\n /** Decimal precision for the amount. Defaults from rail (6 for USDC, 2 for USD). */\n decimals?: number;\n /** Recipient address (on-chain). Optional for stripe-style rails. */\n recipient?: string;\n /** EVM chain ID (goes into methodDetails.chainId). Defaults from rail. */\n chainId?: number;\n /** Stripe profile_id or similar (goes into methodDetails.networkId — note camelCase per link-cli's mpp decode validator). */\n networkId?: string;\n}\n\n/**\n * Build the base64-encoded `request` blob for an MPP Payment directive (per the\n * paymentauth.org spec). Output shape matches what link-cli `mpp decode` expects:\n *\n * { amount: \"<raw_integer>\", currency: \"<token>\", recipient?: \"<addr>\",\n * methodDetails?: { chainId?: number, networkId?: string } }\n */\nexport function buildPaymentRequestBlob(input: PaymentRequestInput): string {\n const railDef = input.rail ? lookupRail(input.rail) : undefined;\n const decimals = input.decimals ?? railDef?.decimals ?? 6;\n const currency = input.currency ?? railDef?.currency ?? 'usd';\n const chainId = input.chainId ?? railDef?.chainId;\n\n const amountNum = typeof input.amountUsd === 'string' ? Number(input.amountUsd) : input.amountUsd;\n const amountRaw = BigInt(Math.round(amountNum * 10 ** decimals)).toString();\n const blob: Record<string, unknown> = { amount: amountRaw, currency, decimals };\n if (input.recipient) blob.recipient = input.recipient;\n const methodDetails: Record<string, unknown> = {};\n if (chainId !== undefined) methodDetails.chainId = chainId;\n if (input.networkId) methodDetails.networkId = input.networkId;\n if (Object.keys(methodDetails).length > 0) blob.methodDetails = methodDetails;\n return Buffer.from(JSON.stringify(blob)).toString('base64url');\n}\n\nexport interface PaymentDirectiveInput {\n /** Symbolic rail name — sets `method` automatically */\n rail?: string;\n /** Challenge id (unique per request, used to correlate retries) */\n id: string;\n /** Realm — the host of the merchant URL (e.g., \"agents.merchant.example\") */\n realm: string;\n /** MPP method name. Defaults from rail (e.g., 'tempo', 'stripe'). */\n method?: string;\n /** MPP intent. Defaults to 'charge'. */\n intent?: string;\n /** ISO-8601 expiry timestamp. Defaults to now + 5 minutes. */\n expires?: string;\n /** Base64-encoded request blob. Pass the result of buildPaymentRequestBlob. */\n request: string;\n}\n\n/**\n * Format an MPP Payment directive string for the WWW-Authenticate header.\n * Output shape: `Payment id=\"...\", realm=\"...\", method=\"...\", intent=\"charge\",\n * expires=\"...\", request=\"<base64>\"`\n */\nexport function paymentDirective(input: PaymentDirectiveInput): string {\n const railDef = input.rail ? lookupRail(input.rail) : undefined;\n const method = input.method ?? railDef?.method ?? 'unknown';\n const intent = input.intent ?? 'charge';\n const expires = input.expires ?? new Date(Date.now() + 5 * 60 * 1000).toISOString();\n return `Payment id=\"${input.id}\", realm=\"${input.realm}\", method=\"${method}\", intent=\"${intent}\", expires=\"${expires}\", request=\"${input.request}\"`;\n}\n\nexport interface BuildPaymentDirectiveInput\n extends Omit<PaymentRequestInput, 'rail'>,\n Omit<PaymentDirectiveInput, 'request'> {\n rail: string;\n}\n\n/**\n * Convenience: build the request blob and the directive in one call. Most vendors\n * want this rather than the two-step form.\n */\nexport function buildPaymentDirective(input: BuildPaymentDirectiveInput): string {\n const request = buildPaymentRequestBlob({\n rail: input.rail,\n amountUsd: input.amountUsd,\n currency: input.currency,\n decimals: input.decimals,\n recipient: input.recipient,\n chainId: input.chainId,\n networkId: input.networkId,\n });\n return paymentDirective({\n rail: input.rail,\n id: input.id,\n realm: input.realm,\n method: input.method,\n intent: input.intent,\n expires: input.expires,\n request,\n });\n}\n","/**\n * Joins multiple Payment directives into a single WWW-Authenticate header value.\n * Per RFC 7235, multiple challenges are comma-separated.\n */\nexport function wwwAuthenticateHeader(directives: string[]): string {\n return directives.join(', ');\n}\n\nexport interface PaymentRequiredHeaderInput {\n x402Version: 1 | 2;\n accepts: unknown[];\n resource?: { url: string; mimeType?: string };\n}\n\n/**\n * Add the v1↔v2 amount-field alias to each accepts entry. Idempotent. Used by both\n * `paymentRequiredHeader` (header emit) and `build402Body` (body emit) so every\n * x402 entry on the wire carries BOTH `amount` (v2 spec) AND `maxAmountRequired`\n * (v1 spec) — strict v1-only parsers (e.g. Coinbase awal at `payments-mcp.coinbase.com`,\n * which is hardcoded to read `maxAmountRequired`) work alongside strict v2 parsers,\n * which ignore the alias.\n */\nexport function aliasAmountFields(accepts: unknown[]): unknown[] {\n return accepts.map((entry) => {\n if (entry === null || typeof entry !== 'object') return entry;\n const e = entry as Record<string, unknown>;\n const hasAmount = e.amount !== undefined;\n const hasMaxAmount = e.maxAmountRequired !== undefined;\n if (hasAmount && !hasMaxAmount) return { ...e, maxAmountRequired: e.amount };\n if (hasMaxAmount && !hasAmount) return { ...e, amount: e.maxAmountRequired };\n return e;\n });\n}\n\n/**\n * Encode the standard x402 PAYMENT-REQUIRED header (base64-encoded JSON of the\n * PaymentRequired object). Clients that recognize the header (`@x402/fetch`,\n * `@x402/core` HTTPClient, `agentscore-pay`) prefer it over body fields.\n *\n * Note: do NOT add a v1↔v2 amount-field alias here. `@x402/core`'s\n * `findMatchingRequirements` uses `deepEqual` against the agent's signed\n * `accepted` payload — any field present on one side and missing on the other\n * (e.g. `maxAmountRequired` on the wire body but not in `buildPaymentRequirements`'s\n * output) makes the match silently fail at settle time. Keep `accepts` shape\n * identical to whatever `buildPaymentRequirements` produces server-side.\n */\nexport function paymentRequiredHeader(input: PaymentRequiredHeaderInput): string {\n return Buffer.from(JSON.stringify(input)).toString('base64');\n}\n","import { buildPaymentRequestBlob, paymentDirective } from '../payment/directive';\nimport { networks } from '../payment/networks';\nimport { USDC } from '../payment/usdc';\nimport { paymentRequiredHeader } from '../payment/wwwauthenticate';\n\n/** Placeholder payTo for x402 sample accepts in the discovery probe — the probe\n * exists for crawlers to find that we support x402, not for actual payment. The\n * real 402 (returned on a fully-formed request body) carries real deposit\n * addresses minted from a Stripe PaymentIntent. */\nconst ZERO_EVM_PAYTO = '0x0000000000000000000000000000000000000000';\nconst ZERO_SOLANA_PAYTO = '11111111111111111111111111111111';\n\n/**\n * Build a sample x402 accepts entry for a CAIP-2 network. Looks up the USDC asset\n * for the network from the `USDC` registry and uses a placeholder payTo. Used by\n * the discovery probe to advertise x402 support without exposing real deposit\n * addresses.\n *\n * Returns null when the network isn't in the registry — vendors with custom\n * networks should construct accepts entries by hand and pass them via\n * `x402Sample.accepts` directly.\n */\nexport function sampleX402AcceptForNetwork(\n caip2: string,\n amountAtomic: string = '1000000',\n): Record<string, unknown> | null {\n if (caip2 === networks.base.mainnet.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.base.mainnet.address,\n payTo: ZERO_EVM_PAYTO,\n maxTimeoutSeconds: 300,\n // ``extra.name`` mirrors the on-chain USDC contract's ``name()`` because\n // EIP-712 domain hashes include this string. Wrong name → every signed\n // payload fails facilitator verify with ``invalid_exact_evm_payload_signature``.\n // Base mainnet USDC returns \"USD Coin\"; base sepolia USDC returns \"USDC\".\n extra: { name: 'USD Coin', version: '2' },\n };\n }\n if (caip2 === networks.base.sepolia.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.base.sepolia.address,\n payTo: ZERO_EVM_PAYTO,\n maxTimeoutSeconds: 300,\n extra: { name: 'USDC', version: '2' },\n };\n }\n if (caip2 === networks.solana.mainnet.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.solana.mainnet.mint,\n payTo: ZERO_SOLANA_PAYTO,\n maxTimeoutSeconds: 300,\n };\n }\n if (caip2 === networks.solana.devnet.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.solana.devnet.mint,\n payTo: ZERO_SOLANA_PAYTO,\n maxTimeoutSeconds: 300,\n };\n }\n return null;\n}\n\nexport interface DiscoveryProbeOptions {\n /** Realm — typically the host of your merchant URL (e.g., \"agents.merchant.example\"). */\n realm: string;\n /** Symbolic rail name to advertise in the sample challenge (e.g., 'tempo-mainnet'). */\n sampleRail: string;\n /** Sample amount in USD for the probe (e.g., 1.00). Crawlers use this as an example. */\n sampleAmountUsd: number;\n /** A recipient address to use in the sample directive (your real or zero address is fine). */\n sampleRecipient: string;\n /** MPP intent. Defaults to 'charge'. */\n intent?: string;\n /** TTL for the probe challenge in seconds. Defaults to 300 (5 minutes). */\n ttlSeconds?: number;\n /** Optional URL to include in the body for further docs (e.g., your llms.txt). */\n docsUrl?: string;\n /** Optional human-readable message in the body. */\n message?: string;\n /** Optional sample x402 accepts entries. When provided, the probe response also\n * carries the standard x402 `payment-required` header (base64 PaymentRequired) AND\n * an `accepts` array in the body — so x402 crawlers (e.g. Coinbase awal's\n * `x402 details`/`x402 pay`) can discover the endpoint's x402 support without\n * needing to send a fully-formed business request. Each entry is run through\n * `aliasAmountFields` so v1-only parsers can read `maxAmountRequired` too.\n *\n * Pass `networks` (shorthand) for the common case — the helper looks up USDC\n * per network from the registry and uses placeholder payTo addresses. Or pass\n * `accepts` directly for full control over the sample shape. */\n x402Sample?: {\n /** Spec version to declare. Defaults to 2. */\n version?: 1 | 2;\n /** Shorthand: array of CAIP-2 network strings. Each is mapped to a sample\n * USDC accepts entry via `sampleX402AcceptForNetwork`. Networks not in the\n * USDC registry are silently skipped. Use `accepts` for custom shapes. */\n networks?: string[];\n /** Sample accepts entries. Used when `networks` shorthand isn't enough.\n * Supplied entries are NOT merged with `networks`-derived entries — pick\n * one or the other. */\n accepts?: unknown[];\n /** Sample atomic amount used by the `networks` shorthand. Defaults to\n * `'1000000'` ($1.00 USDC at 6 decimals). Ignored when `accepts` is set. */\n amountAtomic?: string;\n /** Resource URL the probe is responding for. Used in the PAYMENT-REQUIRED header. */\n resourceUrl?: string;\n };\n}\n\nexport interface DiscoveryProbeResponse {\n status: 402;\n headers: Record<string, string>;\n body: string;\n}\n\n/**\n * Build a 402 response advertising a sample Payment challenge. MPP crawlers\n * (mppscan, link-cli mpp decode) probe with empty bodies; merchants need to answer\n * with a properly-formatted Payment directive so the realm can be indexed.\n *\n * Returns a framework-agnostic response shape. Wrap in your framework's response:\n *\n * const probe = buildDiscoveryProbeResponse({...});\n * return new Response(probe.body, { status: probe.status, headers: probe.headers });\n */\nexport function buildDiscoveryProbeResponse(opts: DiscoveryProbeOptions): DiscoveryProbeResponse {\n const probeId = `probe_${Date.now()}`;\n const expires = new Date(Date.now() + (opts.ttlSeconds ?? 300) * 1000).toISOString();\n const request = buildPaymentRequestBlob({\n rail: opts.sampleRail,\n amountUsd: opts.sampleAmountUsd,\n recipient: opts.sampleRecipient,\n });\n const directive = paymentDirective({\n rail: opts.sampleRail,\n id: probeId,\n realm: opts.realm,\n intent: opts.intent,\n expires,\n request,\n });\n\n const bodyObj: Record<string, unknown> = {\n error: {\n code: 'payment_required',\n message: opts.message ?? 'This endpoint requires payment. Send a valid request body to receive a full challenge.',\n },\n discovery: true,\n ...(opts.docsUrl ? { docs: opts.docsUrl } : {}),\n };\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'www-authenticate': directive,\n };\n\n if (opts.x402Sample) {\n const x402Version = opts.x402Sample.version ?? 2;\n const sampleAccepts = opts.x402Sample.accepts\n ?? (opts.x402Sample.networks ?? [])\n .map((n) => sampleX402AcceptForNetwork(n, opts.x402Sample!.amountAtomic ?? '1000000'))\n .filter((e): e is Record<string, unknown> => e !== null);\n // paymentRequiredHeader applies aliasAmountFields internally; do the same for\n // the body's `accepts` so v1-only parsers (Coinbase awal at payments-mcp.coinbase.com)\n // and v2-strict parsers can both read either field name.\n headers['payment-required'] = paymentRequiredHeader({\n x402Version,\n accepts: sampleAccepts,\n ...(opts.x402Sample.resourceUrl\n ? { resource: { url: opts.x402Sample.resourceUrl, mimeType: 'application/json' } }\n : {}),\n });\n // Also embed in body for clients that read body-level accepts (e.g. awal x402 details\n // falls back from header → body when the header isn't present).\n bodyObj.x402Version = x402Version;\n // Reuse the header's already-aliased accepts so the body matches.\n const headerJson = JSON.parse(Buffer.from(headers['payment-required'], 'base64').toString('utf-8'));\n bodyObj.accepts = headerJson.accepts;\n }\n\n return {\n status: 402,\n headers,\n body: JSON.stringify(bodyObj),\n };\n}\n\nexport interface RequestLike {\n method: string;\n headers: { get(name: string): string | null };\n clone(): { text(): Promise<string> };\n}\n\n/**\n * Returns true when the request is an empty-body POST without a payment credential —\n * the canonical MPP discovery probe pattern. Vendors compose this with\n * buildDiscoveryProbeResponse to short-circuit crawler requests before any business\n * logic runs.\n */\nexport async function isDiscoveryProbeRequest(req: RequestLike): Promise<boolean> {\n if (req.method !== 'POST') return false;\n const auth = req.headers.get('authorization');\n if (auth?.startsWith('Payment ')) return false;\n const body = await req.clone().text();\n return !body || body === '{}';\n}\n","/**\n * Bazaar discovery extension wrapper. Vendors pass their merchant config and we wrap\n * `declareDiscoveryExtension` from `@x402/extensions/bazaar`. The returned value is\n * registered on the x402 server (e.g., via `createX402Server({bazaar: true})` or\n * `server.registerExtension(...)`).\n *\n * `@x402/extensions` is an optional peer dependency.\n */\nexport interface BazaarDiscoveryConfig {\n bodyType?: 'json' | 'form';\n input?: Record<string, unknown>;\n output?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface BazaarModule {\n declareDiscoveryExtension?: (config: BazaarDiscoveryConfig) => unknown;\n}\n\nexport async function createBazaarDiscovery(config: BazaarDiscoveryConfig): Promise<unknown> {\n const bazaar = await dynamicImport<BazaarModule>('@x402/extensions/bazaar');\n /* v8 ignore start -- peer-dep-absence guard; @x402/extensions is installed in test env */\n if (!bazaar?.declareDiscoveryExtension) {\n throw new Error(\n '@x402/extensions not installed — `npm install @x402/extensions` for createBazaarDiscovery.',\n );\n }\n /* v8 ignore stop */\n return bazaar.declareDiscoveryExtension(config);\n}\n\nasync function dynamicImport<T>(moduleName: string): Promise<T | null> {\n try {\n return (await import(moduleName)) as T;\n } catch {\n /* v8 ignore next -- catch fires only when peer dep is missing; installed in test env */\n return null;\n }\n}\n","export interface PaymentMethodConfig {\n /** MPP payment methods accepted, e.g., ['tempo', 'x402', 'stripe']. */\n methods: string[];\n /** x402-specific config (when 'x402' is in methods). */\n x402?: {\n networks: string[];\n scheme?: string;\n asset?: string;\n facilitator?: string;\n client_tooling?: string;\n };\n /** Identity headers accepted (e.g., ['X-Operator-Token', 'X-Wallet-Address']). */\n identity?: string[];\n /** Per-identity-path metadata for agents. */\n identity_paths?: {\n wallet?: { header: string; applies_to_rails: string[]; note?: string };\n operator_token?: { header: string; applies_to_rails: string[]; note?: string };\n };\n /** Compliance policy summary for agents to know what they need before purchasing. */\n compliance?: {\n require_kyc?: boolean;\n min_age?: number;\n allowed_jurisdictions?: string[];\n require_sanctions_clear?: boolean;\n };\n /** Required fields in the request body. */\n required_fields?: string[];\n /** Optional fields in the request body. */\n optional_fields?: string[];\n /** Vendor-specific extras merged into the purchase block (e.g., gift_note metadata). */\n extra?: Record<string, unknown>;\n}\n\nexport interface WellKnownMppInput {\n /** Merchant display name. */\n name: string;\n /** Short description (1-2 sentences). */\n description?: string;\n /** Canonical merchant URL. */\n url: string;\n /** OpenAPI doc URL (typically `${url}/openapi.json`). */\n openapi?: string;\n /** Endpoints map: path → {method, url}. */\n endpoints: Record<string, { method: string; url: string }>;\n /** Catalog metadata (categories, etc). Optional. */\n catalog?: Record<string, unknown>;\n /** Purchase flow details (payment methods, identity, compliance). */\n purchase: PaymentMethodConfig;\n /** Shipping policy (countries, restrictions). */\n shipping?: Record<string, unknown>;\n /** Vendor-specific extra fields merged at the top level. */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Build the standard `.well-known/mpp.json` discovery document. Lift the boilerplate\n * (payment.methods, payment.identity_paths, payment.compliance) into a typed config so\n * vendors get spec-compliance \"for free\"; merchant-specific fields (catalog, shipping)\n * pass through.\n *\n * Wire it in your framework like:\n * app.get('/.well-known/mpp.json', (c) => c.json(buildWellKnownMpp({...})));\n */\nexport function buildWellKnownMpp(input: WellKnownMppInput): Record<string, unknown> {\n return {\n name: input.name,\n ...(input.description ? { description: input.description } : {}),\n url: input.url,\n ...(input.openapi ? { openapi: input.openapi } : {}),\n endpoints: input.endpoints,\n ...(input.catalog ? { catalog: input.catalog } : {}),\n purchase: {\n ...(input.purchase.required_fields ? { required_fields: input.purchase.required_fields } : {}),\n ...(input.purchase.optional_fields ? { optional_fields: input.purchase.optional_fields } : {}),\n ...(input.purchase.extra ?? {}),\n ...(input.purchase.identity ? { identity: input.purchase.identity } : {}),\n ...(input.purchase.identity_paths ? { identity_paths: input.purchase.identity_paths } : {}),\n payment_methods: input.purchase.methods,\n ...(input.purchase.x402 ? { x402: input.purchase.x402 } : {}),\n ...(input.purchase.compliance ? { compliance: input.purchase.compliance } : {}),\n },\n ...(input.shipping ? { shipping: input.shipping } : {}),\n ...(input.extra ?? {}),\n };\n}\n","/**\n * `buildWellKnownX402`: emits the x402scan v1 `/.well-known/x402` discovery shape.\n *\n * x402scan accepts three discovery strategies (OpenAPI > `/.well-known/x402` > endpoint\n * probe). Most AgentScore merchants already publish a richer `/.well-known/mpp.json`,\n * but x402scan's strict parser only reads the v1 shape, so we emit both. The two\n * coexist on different paths.\n *\n * Spec (verbatim, x402scan):\n *\n * {\n * \"version\": 1,\n * \"resources\": [\"POST /api/route\", ...]\n * }\n *\n * Resource entries are `\"METHOD /path\"` strings, not objects. Runtime 402 behavior\n * is authoritative over this static metadata.\n */\n\nexport interface WellKnownX402Resource {\n /** HTTP method, uppercase: `'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'`. */\n method: string;\n /** Path, leading slash: `'/purchase'`. */\n path: string;\n}\n\nexport interface BuildWellKnownX402Input {\n /** Invocable, payment-required routes. Each entry becomes `\"METHOD /path\"`. */\n resources: WellKnownX402Resource[];\n}\n\nexport interface WellKnownX402Document {\n version: 1;\n resources: string[];\n}\n\nexport function buildWellKnownX402(input: BuildWellKnownX402Input): WellKnownX402Document {\n return {\n version: 1,\n resources: input.resources.map((r) => `${r.method.toUpperCase()} ${r.path}`),\n };\n}\n","export interface LlmsTxtIdentitySectionInput {\n /** When true, include the AgentScore identity-paths explanation (wallet vs operator-token). */\n agentscore?: boolean;\n /** Compliance policy to mention (KYC, age, jurisdiction). */\n compliance?: {\n require_kyc?: boolean;\n min_age?: number;\n allowed_jurisdictions?: string[];\n require_sanctions_clear?: boolean;\n };\n}\n\n/**\n * Generate the standard \"Choose your identity header\" section for an AgentScore-gated\n * merchant's llms.txt. Explains wallet-auth vs operator-token paths + the cross-merchant\n * memory contract so agents know how to authenticate without reading the API docs.\n */\nexport function llmsTxtIdentitySection(input: LlmsTxtIdentitySectionInput = {}): string {\n if (!input.agentscore) {\n return '';\n }\n const compliance = input.compliance;\n const complianceNote = compliance\n ? `\\n\\nCompliance: ${[\n compliance.require_kyc ? 'KYC required' : null,\n compliance.min_age ? `age ${compliance.min_age}+` : null,\n compliance.allowed_jurisdictions?.length\n ? `${compliance.allowed_jurisdictions.join('/')} only`\n : null,\n compliance.require_sanctions_clear ? 'sanctions clear' : null,\n ]\n .filter(Boolean)\n .join(', ')}.`\n : '';\n return `## Identity\n\nAgentScore identity is reusable across every AgentScore-gated merchant — one KYC, no re-verification per site. Pick a header:\n\n- **\\`X-Wallet-Address: 0x...\\` or base58** — works on signing rails (Tempo, x402, Solana MPP). The wallet you claim must sign the payment.\n- **\\`X-Operator-Token: opc_...\\`** — works on every rail, including Stripe SPT. Reusable across AgentScore merchants until expiry.\n- **Neither** — you get a 403 with \\`verify_url\\`. Complete the session flow once and reuse the resulting \\`opc_...\\` everywhere.${complianceNote}`;\n}\n\nexport interface LlmsTxtPaymentSectionInput {\n /** Symbolic rail names supported. */\n rails: ('tempo-mainnet' | 'tempo-testnet' | 'x402-base-mainnet' | 'x402-base-sepolia' | 'mpp-solana-mainnet' | 'mpp-solana-devnet' | 'stripe-spt' | string)[];\n /** Merchant URL — used in the example commands. */\n appUrl: string;\n /**\n * When true, emit the verbose multi-step variant: setup commands per rail, full per-rail\n * payment-command examples, and warnings about footguns. Default false (one-line bullet per rail).\n * Use this when llms.txt is the primary integration doc the agent reads.\n */\n verbose?: boolean;\n /** When verbose, the Tempo network name to mention in the prerequisites. Default 'tempo-mainnet'. */\n tempoNetworkName?: string;\n /** When verbose, the Tempo chain id to mention in the prerequisites. Default 4217. */\n tempoChainId?: number;\n}\n\n/**\n * Generate the standard \"## Payment\" section for a merchant's llms.txt. Documents the\n * supported rails with concrete CLI examples (tempo request, agentscore-pay, link-cli)\n * per the configured rail set.\n *\n * Pass `verbose: true` for the rich variant — multi-step setup + multi-line command examples +\n * exact-amount warnings. Default is the compact one-bullet-per-rail form.\n */\nexport function llmsTxtPaymentSection(input: LlmsTxtPaymentSectionInput): string {\n return input.verbose ? llmsTxtPaymentSectionVerbose(input) : llmsTxtPaymentSectionCompact(input);\n}\n\nfunction hasRailFamily(rails: string[], prefix: string): boolean {\n return rails.some(r => r.startsWith(prefix));\n}\n\nfunction isTestnetRail(rails: string[], prefix: string): boolean {\n return rails.some(r => r.startsWith(prefix) && /(sepolia|devnet|moderato|testnet)/.test(r));\n}\n\nfunction llmsTxtPaymentSectionCompact(input: LlmsTxtPaymentSectionInput): string {\n const lines: string[] = ['## Payment', ''];\n const rails = input.rails;\n if (hasRailFamily(rails, 'tempo-')) {\n lines.push('- **Tempo USDC via MPP** — `tempo request -X POST -H \"X-Operator-Token: opc_...\" --json \\'{...}\\' --max-spend N ' + input.appUrl + '`');\n }\n if (hasRailFamily(rails, 'x402-base-')) {\n lines.push('- **x402 USDC on Base** (EIP-3009) — `agentscore-pay pay POST ' + input.appUrl + ' --chain base -H \"X-Operator-Token: opc_...\" -d \\'{...}\\'`');\n }\n if (hasRailFamily(rails, 'mpp-solana-')) {\n lines.push('- **USDC on Solana** — `agentscore-pay pay POST ' + input.appUrl + ' --chain solana -H \"X-Operator-Token: opc_...\" -d \\'{...}\\'`');\n }\n if (rails.includes('stripe-spt')) {\n lines.push('- **Stripe Shared Payment Token** — agent mints SPT (own Stripe account scoped to networkId, OR `link-cli spend-request create --credential-type shared_payment_token --network-id <profileId> ...`)');\n }\n lines.push('');\n lines.push('IMPORTANT: Do NOT use raw on-chain transfers. Use the CLI commands above so the payment credential is signed and submitted via the protocol handshake.');\n lines.push('');\n return lines.join('\\n');\n}\n\nfunction llmsTxtPaymentSectionVerbose(input: LlmsTxtPaymentSectionInput): string {\n const rails = input.rails;\n const tempoNetwork = input.tempoNetworkName ?? 'tempo-mainnet';\n const tempoChain = input.tempoChainId ?? 4217;\n const hasTempo = hasRailFamily(rails, 'tempo-');\n const hasBase = hasRailFamily(rails, 'x402-base-');\n const hasSolana = hasRailFamily(rails, 'mpp-solana-');\n const hasStripe = rails.includes('stripe-spt');\n const baseNetworkName = isTestnetRail(rails, 'x402-base-') ? 'Base Sepolia' : 'Base';\n const solanaNetworkName = isTestnetRail(rails, 'mpp-solana-') ? 'Solana devnet' : 'Solana';\n\n const lines: string[] = ['## Payment', ''];\n lines.push('Accepted rails:');\n lines.push('');\n if (hasTempo) lines.push('- **USDC on Tempo**');\n if (hasBase) lines.push(`- **USDC on ${baseNetworkName}**`);\n if (hasSolana) lines.push(`- **USDC on ${solanaNetworkName}**`);\n if (hasStripe) lines.push('- **Stripe Shared Payment Token**');\n lines.push('');\n\n if (hasTempo) {\n lines.push('### Pay with Tempo');\n lines.push('');\n lines.push('```bash');\n lines.push('curl -fsSL https://tempo.xyz/install | bash');\n lines.push('tempo wallet login');\n lines.push(`tempo wallet whoami # need USDC.e on ${tempoNetwork} (chain ${tempoChain})`);\n lines.push('tempo wallet fund # if zero');\n lines.push('');\n lines.push('tempo request -X POST \\\\');\n lines.push(' -H \"X-Operator-Token: opc_...\" \\\\');\n lines.push(\" --json '{...}' \\\\\");\n lines.push(' --max-spend N \\\\');\n lines.push(` ${input.appUrl}`);\n lines.push('```');\n lines.push('');\n }\n\n if (hasBase || hasSolana) {\n const chainsLabel = [hasBase && baseNetworkName, hasSolana && solanaNetworkName].filter(Boolean).join(' or ');\n const flags = [hasBase && '`--chain base`', hasSolana && '`--chain solana`'].filter(Boolean).join(' or ');\n lines.push(`### Pay with ${chainsLabel}`);\n lines.push('');\n lines.push('```bash');\n lines.push('npm install -g @agent-score/pay');\n lines.push(`agentscore-pay wallet create ${flags}`);\n lines.push(`agentscore-pay balance ${flags} # fund the printed address with USDC`);\n lines.push('');\n lines.push(`agentscore-pay pay POST ${input.appUrl} \\\\`);\n lines.push(` ${hasBase ? '--chain base' : '--chain solana'} \\\\`);\n lines.push(' -H \"X-Operator-Token: opc_...\" \\\\');\n lines.push(\" -d '{...}' \\\\\");\n lines.push(' --max-spend N');\n lines.push('```');\n lines.push('');\n }\n\n if (hasStripe) {\n lines.push('### Pay with Stripe SPT');\n lines.push('');\n lines.push('Mint a SharedPaymentToken scoped to the `profile_id` from the 402 body, then submit via `Authorization: Payment` with `method=stripe/charge`. Either your own Stripe account or `link-cli spend-request create --credential-type shared_payment_token --network-id <profileId> ...` for Stripe Link wallets.');\n lines.push('');\n }\n\n lines.push('IMPORTANT: Use the CLIs above. Raw on-chain transfers (e.g. `tempo wallet transfer`, sending USDC manually to deposit addresses) bypass the protocol handshake and the order will not complete.');\n if (hasBase || hasSolana) {\n lines.push('IMPORTANT: Pay the exact amount in the 402 challenge. Overpayments and underpayments cannot be matched.');\n }\n lines.push('');\n return lines.join('\\n');\n}\n\nexport interface BuildLlmsTxtInput {\n merchantName: string;\n /** Optional 1-line summary under the title. */\n tagline?: string;\n /** Custom merchant-written sections (intro, endpoints, terms, etc.). */\n sections: { heading: string; content: string }[];\n /** Append the AgentScore identity section. */\n agentscoreIdentity?: LlmsTxtIdentitySectionInput;\n /** Append the standard payment section. */\n payment?: LlmsTxtPaymentSectionInput;\n}\n\n/**\n * Assemble a complete llms.txt document. Vendor passes their merchant-specific sections\n * (intro, catalog, endpoints, gift orders, shipping, etc.); the helper adds the AgentScore\n * identity + payment boilerplate at the end. Returns the full markdown string.\n */\nexport function buildLlmsTxt(input: BuildLlmsTxtInput): string {\n const parts: string[] = [`# ${input.merchantName}`];\n if (input.tagline) {\n parts.push(`> ${input.tagline}`);\n }\n parts.push('');\n for (const s of input.sections) {\n parts.push(`## ${s.heading}`);\n parts.push('');\n parts.push(s.content);\n parts.push('');\n }\n if (input.agentscoreIdentity) {\n parts.push(llmsTxtIdentitySection(input.agentscoreIdentity));\n parts.push('');\n }\n if (input.payment) {\n parts.push(llmsTxtPaymentSection(input.payment));\n }\n return parts.join('\\n');\n}\n","/**\n * OpenAPI snippets for AgentScore-related concepts. Vendors plug these into their own\n * OpenAPI 3.1 document (typically /openapi.json) so MPPScan and similar agent registries\n * can validate the merchant's auth + denial schemas correctly.\n *\n * Each helper returns a piece of an OpenAPI document — vendors compose them into their\n * full spec.\n */\n\n/**\n * Standard AgentScore identity security schemes. Plug into `components.securitySchemes`.\n *\n * Includes `siwx` (Sign-In With X) per the x402scan discovery spec so identity-gated\n * operations can declare `security: [{ siwx: [] }]` and stay classified as identity-only,\n * not paid.\n */\nexport function agentscoreSecuritySchemes(): Record<string, unknown> {\n return {\n OperatorToken: {\n type: 'apiKey',\n in: 'header',\n name: 'X-Operator-Token',\n description:\n 'Operator-token-path identity (opc_...). Works on every payment rail; reusable across AgentScore merchants. If both X-Operator-Token and X-Wallet-Address are sent, this one wins.',\n },\n WalletAddress: {\n type: 'apiKey',\n in: 'header',\n name: 'X-Wallet-Address',\n description:\n 'Wallet-path identity (0x... or base58). Only works on rails that carry a wallet signature (Tempo MPP, x402 EIP-3009, x402 SPL Token). The wallet you claim MUST sign the payment.',\n },\n siwx: siwxSecurityScheme(),\n };\n}\n\n/**\n * Sign-In With X security scheme entry, per the x402scan discovery spec.\n *\n * Reference it on identity-gated (but free) operations as\n * `security: [{ siwx: [] }]`. Do NOT also attach `x-payment-info` to those routes,\n * x402scan will misclassify them as paid.\n */\nexport function siwxSecurityScheme(): Record<string, unknown> {\n return {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'SIWX',\n description:\n 'Sign-In With X wallet authentication. Agent signs a challenge with their wallet (any supported chain) and presents the proof in the Authorization header. Used for identity-gated free endpoints; payment-required endpoints declare x-payment-info instead.',\n };\n}\n\n/**\n * Standard AgentScore denial response schemas. Plug into `components.schemas` so OpenAPI\n * validators understand the 403 body shape across denial codes.\n */\nexport function agentscoreDenialSchemas(): Record<string, unknown> {\n return {\n AgentScoreDenialReason: {\n type: 'string',\n enum: [\n 'missing_identity',\n 'identity_verification_required',\n 'token_expired',\n 'invalid_credential',\n 'wallet_signer_mismatch',\n 'wallet_auth_requires_wallet_signing',\n 'wallet_not_trusted',\n 'api_error',\n 'payment_required',\n ],\n description:\n \"Denial code emitted by AgentScore's gate middleware in 403 responses. Every code carries a structured agent_instructions block describing recovery actions (per-code action: missing_identity → probe_identity_then_session, identity_verification_required / token_expired → deliver_verify_url_and_poll, invalid_credential → switch_token_or_restart_session, wallet_signer_mismatch → resign_or_switch_to_operator_token, wallet_auth_requires_wallet_signing → switch_to_operator_token, wallet_not_trusted → contact_support — UNFIXABLE compliance only (sanctions/age/jurisdiction_restricted); fixable reasons re-route to identity_verification_required, payment_required → contact_merchant).\",\n },\n AgentScoreDenialBody: {\n type: 'object',\n properties: {\n error: { $ref: '#/components/schemas/AgentScoreDenialReason' },\n agent_instructions: {\n type: 'string',\n description:\n 'JSON-encoded { action, steps, user_message } block. Always present on every denial; agents parse this to learn how to recover (e.g., poll verify_url, switch headers, re-sign).',\n },\n verify_url: { type: 'string', format: 'uri', description: \"Present for missing_identity / identity_verification_required / token_expired denials. Agent shares this with the user to complete KYC or claim a wallet. Not present on wallet_not_trusted (UNFIXABLE compliance — re-verification won't change the outcome).\" },\n session_id: { type: 'string' },\n poll_url: { type: 'string', format: 'uri' },\n poll_secret: { type: 'string' },\n agent_memory: { type: 'object', description: 'Cross-merchant pattern hint emitted on first-encounter denials.' },\n },\n required: ['error', 'agent_instructions'],\n },\n };\n}\n\n/**\n * Standard 402 PaymentRequired body schema (for AgentScore-extended 402 responses).\n * Includes the rails, identity metadata, agent_instructions, pricing, and x402-compliance\n * fields a typical merchant emits via build402Body.\n */\nexport function agentscorePaymentRequiredSchema(): Record<string, unknown> {\n return {\n AgentScorePaymentRequired: {\n type: 'object',\n properties: {\n payment_required: { type: 'boolean', enum: [true] },\n x402Version: { type: 'integer', enum: [1, 2] },\n accepts: { type: 'array', items: { type: 'object' }, description: 'x402 PaymentRequired.accepts entries.' },\n accepted_methods: {\n type: 'array',\n items: { type: 'object' },\n description: 'MPP method entries (tempo/charge, x402/exact, stripe/charge, ...).',\n },\n amount_usd: { type: 'string' },\n currency: { type: 'string' },\n pricing: {\n type: 'object',\n properties: {\n subtotal: { type: 'string' },\n tax: { type: 'string' },\n tax_rate: { type: 'number' },\n tax_state: { type: 'string' },\n total: { type: 'string' },\n },\n },\n identity_mode: { type: 'string', enum: ['wallet', 'operator_token'] },\n required_signer: { type: 'string' },\n linked_wallets: { type: 'array', items: { type: 'string' } },\n signer_constraint: { type: 'string' },\n agent_instructions: { type: 'object' },\n agent_memory: { type: 'object' },\n },\n },\n };\n}\n\n/**\n * Per-operation `x-payment-info` extension, per the x402scan discovery spec.\n *\n * Every payment-required OpenAPI operation should carry this block alongside a\n * 402 response. Tells discovery crawlers (x402scan, agent CLIs) the static price\n * and which protocols the route accepts. Runtime 402 behavior is authoritative\n * over this static metadata; the static side is for indexability.\n *\n * @example fixed price across x402 + MPP Tempo\n * ```ts\n * Object.assign(operation, {\n * ...xPaymentInfoExtension({\n * price: { mode: 'fixed', currency: 'USD', amount: '0.10' },\n * protocols: [\n * { x402: {} },\n * { mpp: { method: 'tempo/charge', intent: 'pay', currency: 'USD' } },\n * ],\n * }),\n * responses: {\n * '200': {...},\n * '402': { description: 'Payment Required' },\n * },\n * });\n * ```\n */\nexport interface XPaymentInfoFixedPrice {\n mode: 'fixed';\n currency: string;\n amount: string;\n}\n\nexport interface XPaymentInfoDynamicPrice {\n mode: 'dynamic';\n currency: string;\n min: string;\n max: string;\n}\n\nexport type XPaymentInfoPrice = XPaymentInfoFixedPrice | XPaymentInfoDynamicPrice;\n\nexport interface XPaymentInfoX402Protocol {\n x402: Record<string, unknown>;\n}\n\nexport interface XPaymentInfoMppProtocol {\n mpp: { method: string; intent: string; currency: string };\n}\n\nexport type XPaymentInfoProtocol = XPaymentInfoX402Protocol | XPaymentInfoMppProtocol;\n\nexport interface XPaymentInfoInput {\n price: XPaymentInfoPrice;\n protocols: XPaymentInfoProtocol[];\n}\n\nexport function xPaymentInfoExtension(\n input: XPaymentInfoInput,\n): { 'x-payment-info': { price: XPaymentInfoPrice; protocols: XPaymentInfoProtocol[] } } {\n return { 'x-payment-info': { price: input.price, protocols: input.protocols } };\n}\n\n/**\n * `info.x-guidance` extension, per the x402scan discovery spec. Spread into your\n * OpenAPI document's `info` block to give agents a high-level prose description\n * of how to use the API. Discovery crawlers surface this on the listing page.\n *\n * @example\n * ```ts\n * const spec = {\n * openapi: '3.1.0',\n * info: {\n * title: 'My Merchant API',\n * version: '1.0',\n * ...xGuidanceExtension('Wine merchant. POST /purchase with a verified operator token...'),\n * },\n * };\n * ```\n */\nexport function xGuidanceExtension(text: string): { 'x-guidance': string } {\n return { 'x-guidance': text };\n}\n\nexport interface BuildAgentScoreOpenApiSnippetsInput {\n /** Include security schemes in the snippet. Default true. */\n security?: boolean;\n /** Include denial schemas in the snippet. Default true. */\n denials?: boolean;\n /** Include the 402 PaymentRequired schema in the snippet. Default true. */\n paymentRequired?: boolean;\n}\n\n/**\n * Convenience: returns a `components` snippet ready to merge into an OpenAPI document.\n *\n * const spec = {\n * openapi: '3.1.0',\n * info: { title: 'My Merchant API', version: '1.0' },\n * paths: {...},\n * components: { ...agentscoreOpenApiSnippets(), schemas: { ...mySchemas, ...agentscoreOpenApiSnippets().schemas } },\n * };\n *\n * Or more idiomatically: `Object.assign(spec.components, agentscoreOpenApiSnippets())`.\n */\nexport function agentscoreOpenApiSnippets(\n opts: BuildAgentScoreOpenApiSnippetsInput = {},\n): { securitySchemes?: Record<string, unknown>; schemas?: Record<string, unknown> } {\n const out: { securitySchemes?: Record<string, unknown>; schemas?: Record<string, unknown> } = {};\n if (opts.security !== false) {\n out.securitySchemes = agentscoreSecuritySchemes();\n }\n if (opts.denials !== false || opts.paymentRequired !== false) {\n out.schemas = {\n ...(opts.denials !== false ? agentscoreDenialSchemas() : {}),\n ...(opts.paymentRequired !== false ? agentscorePaymentRequiredSchema() : {}),\n };\n }\n return out;\n}\n","/**\n * Default discovery paths emitted by `@agent-score/commerce` builders. These are\n * the public-by-design endpoints agents and crawlers fetch to learn the\n * merchant's shape: OpenAPI, llms.txt, MPP well-known, A2A agent card, UCP profile.\n * They should NOT carry `X-Robots-Tag: noindex` since the whole point is for\n * agents (and search/discovery crawlers) to find them.\n *\n * Everything else on an agent-only API should noindex by default — there's no\n * human-shaped HTML to surface to general search engines, and accidental\n * indexing leaks transactional endpoints into noisy SERPs.\n */\nexport const defaultDiscoveryPaths: ReadonlySet<string> = new Set([\n '/openapi.json',\n '/llms.txt',\n '/skill.md',\n '/SKILL.md',\n '/.well-known/mpp.json',\n '/.well-known/x402',\n '/.well-known/agent-card.json',\n '/.well-known/ucp',\n '/.well-known/jwks.json',\n '/favicon.png',\n '/favicon.ico',\n]);\n\n/**\n * Pure predicate for \"is this path a known discovery surface?\". Compose this\n * into your own framework's middleware when you don't want the bundled Hono\n * wrapper. Custom paths are the union with the defaults — pass `replace: true`\n * to skip the defaults.\n */\nexport function isDiscoveryPath(\n path: string,\n options?: { customPaths?: Iterable<string>; replace?: boolean },\n): boolean {\n if (options?.replace) {\n return new Set(options.customPaths ?? []).has(path);\n }\n if (defaultDiscoveryPaths.has(path)) return true;\n if (options?.customPaths) {\n for (const p of options.customPaths) if (p === path) return true;\n }\n return false;\n}\n\nexport interface NoindexNonDiscoveryOptions {\n /** Additional discovery paths beyond the defaults (e.g. `/sitemap.xml`,\n * `/.well-known/foo`). Merged with the defaults unless `replacePaths: true`. */\n customPaths?: Iterable<string>;\n /** When true, ignore the bundled defaults and only treat `customPaths` as\n * discovery surfaces. Use when the merchant deliberately chooses a different\n * set (e.g. omits `/openapi.json` from a closed API). */\n replacePaths?: boolean;\n /** Override the X-Robots-Tag value applied to non-discovery paths. Defaults to\n * the standard \"noindex, nofollow, noarchive, nosnippet\" tuple — change only\n * if you have a very specific crawl-shape requirement. */\n robotsTag?: string;\n}\n\nconst DEFAULT_ROBOTS_TAG = 'noindex, nofollow, noarchive, nosnippet';\n\n/** Predicate the per-framework wrappers share. Pulled out so non-listed frameworks\n * can compose it directly (`if (!shouldNoindex(path, opts)) ...`). */\nfunction shouldNoindex(path: string, customSet: Set<string> | undefined, replacePaths: boolean | undefined): boolean {\n const isDiscovery = replacePaths\n ? (customSet?.has(path) ?? false)\n : defaultDiscoveryPaths.has(path) || (customSet?.has(path) ?? false);\n return !isDiscovery;\n}\n\n/**\n * Hono middleware. Mount globally near the top of your middleware stack:\n *\n * app.use('*', noindexNonDiscoveryPaths());\n * app.use('*', noindexNonDiscoveryPaths({ customPaths: ['/sitemap.xml'] }));\n *\n * Per-framework variants (`noindexNonDiscoveryPathsExpress`,\n * `noindexNonDiscoveryPathsFastify`, `noindexNonDiscoveryPathsWeb`) ship below.\n * For Next.js Route Handlers, use `applyNoindexHeader(response, path, opts)`\n * inline since route handlers don't have a global mount point.\n */\nexport function noindexNonDiscoveryPaths(options?: NoindexNonDiscoveryOptions) {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n return async (c: { req: { path: string }; header: (k: string, v: string) => void }, next: () => Promise<void>) => {\n await next();\n if (shouldNoindex(c.req.path, customSet, options?.replacePaths)) {\n c.header('X-Robots-Tag', robotsTag);\n }\n };\n}\n\n/** Express middleware. Sets the header before `next()` so route handlers can\n * override per-response if they need to. */\nexport function noindexNonDiscoveryPathsExpress(options?: NoindexNonDiscoveryOptions) {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n return (\n req: { path: string },\n res: { setHeader: (name: string, value: string) => void },\n next: () => void,\n ) => {\n if (shouldNoindex(req.path, customSet, options?.replacePaths)) {\n res.setHeader('X-Robots-Tag', robotsTag);\n }\n next();\n };\n}\n\n/** Fastify plugin (use as `app.register(noindexNonDiscoveryPathsFastify, opts)`).\n * Registers an `onRequest` hook so the header lands on every response. */\ninterface FastifyReqLike { url?: string; routerPath?: string }\ninterface FastifyReplyLike { header: (name: string, value: string) => void }\ninterface FastifyAppLike {\n addHook(event: 'onRequest', handler: (req: FastifyReqLike, reply: FastifyReplyLike, done: () => void) => void): void;\n}\nexport function noindexNonDiscoveryPathsFastify(\n app: FastifyAppLike,\n options: NoindexNonDiscoveryOptions | undefined,\n done: () => void,\n): void {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n app.addHook('onRequest', (req, reply, hookDone) => {\n const path = (req.url ?? req.routerPath ?? '').split('?')[0];\n if (shouldNoindex(path, customSet, options?.replacePaths)) {\n reply.header('X-Robots-Tag', robotsTag);\n }\n hookDone();\n });\n done();\n}\n\n/** Web Fetch / Cloudflare Workers / Deno / Bun helper. Returns a wrapped\n * Response that carries `X-Robots-Tag` on non-discovery paths. Pair with the\n * request's URL pathname:\n *\n * return wrapNoindexResponse(new URL(req.url).pathname, response);\n */\nexport function wrapNoindexResponse(\n path: string,\n response: Response,\n options?: NoindexNonDiscoveryOptions,\n): Response {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n if (!shouldNoindex(path, customSet, options?.replacePaths)) return response;\n const headers = new Headers(response.headers);\n headers.set('X-Robots-Tag', robotsTag);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\n/** Next.js Route Handler helper. Call inline before returning the Response:\n *\n * export async function POST(req: Request) {\n * const path = new URL(req.url).pathname;\n * const res = Response.json({...});\n * return applyNoindexHeader(res, path);\n * }\n *\n * Same wrapper shape as the Web Fetch helper — exported separately for clarity\n * in Next.js docs/examples. */\nexport const applyNoindexHeader = wrapNoindexResponse;\n","import type { HowToPayBlock } from './how_to_pay';\n\n/** Map of rail key (e.g. 'x402_base', 'tempo_mpp', 'stripe') → list of client identifiers\n * that have been smoke-verified by the merchant against the protocol shape they emit.\n * Strings are display labels, not install commands — agents already get install commands\n * via `how_to_pay.<rail>.setup`. Use these as a \"what's known to work\" hint. */\nexport type CompatibleClients = Record<string, string[]>;\n\nexport interface BuildAgentInstructionsInput {\n /** Per-rail commands. Build with `buildHowToPay`. */\n howToPay: HowToPayBlock;\n /** Tool recommendations as human-readable strings. Defaults to a sensible set covering tempo + agentscore-pay. */\n recommendedTools?: string[];\n /** Wallet-stack compatibility note for the agent. Default: rail-neutral, no specific wallet stack required. */\n walletCompatibility?: string;\n /** How long the merchant will wait for payment after the 402. Default 300 (5 minutes). */\n timeoutSeconds?: number;\n /** Warnings about common footguns. Defaults include tempo wallet transfer + raw on-chain x402 deposits. */\n warnings?: string[];\n /** Additional warnings appended to the default protocol-footgun set. Use this when you want\n * to keep the SDK's protocol warnings AND add merchant-specific notes (e.g., a per-order\n * rail-availability message). Ignored when `warnings` is set explicitly. */\n extraWarnings?: string[];\n /** Recommended rail (e.g., 'tempo', 'x402_base'). Surfaced for agents to default to. */\n recommended?: string;\n /** Per-rail list of client names the merchant has verified work end-to-end. Vendors set\n * this from their own smoke matrix — defaults to none (avoids vouching for clients the\n * merchant has not tested). When omitted, the field is not emitted. */\n compatibleClients?: CompatibleClients;\n /** Arbitrary additional fields the vendor wants merged into the agent_instructions object. */\n extra?: Record<string, unknown>;\n}\n\nexport interface AgentInstructions {\n how_to_pay: HowToPayBlock;\n recommended_tools: string[];\n wallet_compatibility: string;\n timeout_seconds: number;\n warnings: string[];\n recommended?: string;\n compatible_clients?: CompatibleClients;\n [key: string]: unknown;\n}\n\nconst TEMPO_WARNING =\n 'Do NOT use `tempo wallet transfer`. That moves USDC on-chain without completing the protocol handshake, so the order will not complete. Use `tempo request` instead.';\n\nconst X402_WARNING =\n 'Do NOT send USDC manually to the deposit addresses. Use `agentscore-pay pay` so the credential is signed and submitted; otherwise the order will not complete even though the deposit lands.';\n\nconst TEMPO_TOOL = '`tempo request` for Tempo USDC';\nconst AGENTSCORE_PAY_TOOL = '`agentscore-pay` — Base + Solana + Tempo from one CLI';\n\nconst DEFAULT_WALLET_COMPATIBILITY =\n 'Any client that can produce a valid MPP credential (Authorization: Payment) or x402 X-Payment header. Use the CLI commands above; sign-it-yourself is also fine.';\n\nfunction defaultRecommendedTools(howToPay: HowToPayBlock): string[] {\n const tools: string[] = [];\n if (howToPay.tempo) tools.push(TEMPO_TOOL);\n if (howToPay.tempo || howToPay.x402_base || howToPay.solana_mpp) tools.push(AGENTSCORE_PAY_TOOL);\n return tools;\n}\n\nfunction defaultWarnings(howToPay: HowToPayBlock): string[] {\n const w: string[] = [];\n if (howToPay.tempo) w.push(TEMPO_WARNING);\n if (howToPay.x402_base) w.push(X402_WARNING);\n return w;\n}\n\n/**\n * Default `compatible_clients` derived from the rails declared in `howToPay`. Lists\n * clients the AgentScore team has smoke-verified end-to-end against an `@agent-score/commerce`\n * merchant; entries appear only for rails the vendor actually offers. Vendors override\n * this in `buildAgentInstructions({compatibleClients: {...}})` to add their own tested\n * clients or remove entries that don't fit their endpoint.\n *\n * Verified state as of the SDK release. The same data is also published as a docs page\n * for humans (rationale, per-rail commands, why some clients don't fully work, last\n * verified date) — this default keeps the merchant-side surface in sync.\n */\n/** Symbolic rail keys agent-facing surfaces use to talk about a rail without spelling out\n * network/scheme details. Same keys as `CompatibleClients` map keys. */\nexport type RailKey = 'tempo_mpp' | 'x402_base' | 'solana_mpp' | 'stripe';\n\nconst RAIL_CLIENTS: Record<RailKey, readonly string[]> = {\n tempo_mpp: ['agentscore-pay', 'tempo request', 'x402-proxy'],\n x402_base: ['agentscore-pay', 'x402-proxy', 'purl (omit --network flag)'],\n solana_mpp: ['agentscore-pay'],\n stripe: ['link-cli'],\n};\n\n/** Returns the smoke-verified client list for a set of rail keys. The single source of\n * truth for \"which CLIs we've verified end-to-end on each rail\" — consumed both by the\n * 402-body builder (`defaultCompatibleClients`) and by discovery surfaces (skill.md,\n * llms.txt, etc.). Update here, every surface inherits. */\nexport function compatibleClientsByRails(rails: readonly RailKey[]): CompatibleClients | undefined {\n const out: CompatibleClients = {};\n for (const r of rails) out[r] = [...RAIL_CLIENTS[r]];\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\nfunction defaultCompatibleClients(howToPay: HowToPayBlock): CompatibleClients | undefined {\n const rails: RailKey[] = [];\n if (howToPay.tempo) rails.push('tempo_mpp');\n if (howToPay.x402_base) rails.push('x402_base');\n if (howToPay.solana_mpp) rails.push('solana_mpp');\n if (howToPay.stripe) rails.push('stripe');\n return compatibleClientsByRails(rails);\n}\n\n/**\n * Build the agent_instructions object for the 402 body. Combines how_to_pay with\n * recommended tools, warnings, wallet-compatibility note, and timeout.\n *\n * Defaults adapt to the rails declared in `howToPay`: only tempo-relevant warnings/tools\n * appear if `howToPay.tempo` is set, only x402-relevant ones if `x402_base` is set.\n * Stripe-only merchants get neither rail-specific warning. Vendors override\n * `warnings`/`recommendedTools` for full control.\n */\nexport function buildAgentInstructions(input: BuildAgentInstructionsInput): AgentInstructions {\n const compatibleClients = input.compatibleClients ?? defaultCompatibleClients(input.howToPay);\n return {\n how_to_pay: input.howToPay,\n recommended_tools: input.recommendedTools ?? defaultRecommendedTools(input.howToPay),\n wallet_compatibility: input.walletCompatibility ?? DEFAULT_WALLET_COMPATIBILITY,\n timeout_seconds: input.timeoutSeconds ?? 300,\n warnings: input.warnings ?? [...defaultWarnings(input.howToPay), ...(input.extraWarnings ?? [])],\n ...(input.recommended ? { recommended: input.recommended } : {}),\n ...(compatibleClients ? { compatible_clients: compatibleClients } : {}),\n ...(input.extra ?? {}),\n };\n}\n","import { compatibleClientsByRails } from '../challenge/agent_instructions';\nimport type { CompatibleClients, RailKey } from '../challenge/agent_instructions';\n\nexport type { CompatibleClients, RailKey } from '../challenge/agent_instructions';\nexport { compatibleClientsByRails } from '../challenge/agent_instructions';\n\nexport interface SkillMdEndpoint {\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n path: string;\n authRequired: boolean;\n description: string;\n}\n\nexport interface SkillMdIdentityRequirements {\n /** Whether KYC is required for gated routes. */\n kycRequired?: boolean;\n /** Minimum age (e.g. 21 for alcohol). */\n minAge?: number;\n /** Allowed-jurisdictions list (ISO 3166-1 alpha-2 country codes). */\n allowedJurisdictions?: string[];\n /** Whether sanctions screening is enforced. */\n sanctionsClear?: boolean;\n}\n\nexport interface SkillMdShippingPolicy {\n /** Allowed shipping countries (ISO 3166-1 alpha-2). */\n allowedCountries?: string[];\n /** Blocked US states (2-letter codes). */\n blockedStates?: string[];\n}\n\nexport interface SkillMdLink {\n label: string;\n url: string;\n}\n\nexport interface BuildSkillMdInput {\n /** Skill manifest identifier — kebab-case per agentskills.io spec: 1-64 chars, lowercase\n * alphanumeric + hyphens, no leading/trailing/consecutive hyphens. Validated at build\n * time; invalid names throw. e.g. 'example-merchant-commerce'. */\n name: string;\n /** Skill description — agentskills.io spec: 1-1024 chars, non-empty. Should describe both\n * what the skill does AND when to use it; imperative phrasing recommended (\"Use when…\").\n * Validated at build time; over-length throws. */\n description: string;\n /** Merchant homepage (or domain root). Emitted as `metadata.homepage` per spec\n * (top-level non-spec fields go under metadata). */\n homepage: string;\n /** Skill schema version — increment when the skill body materially changes. Emitted as\n * a quoted string under `metadata.version` per agentskills.io spec (metadata values\n * must be strings). Accepts string or number; numbers are converted. Default \"1\". */\n version?: string | number;\n\n /** Optional license name or path to a bundled license file. Emitted as top-level\n * frontmatter `license:` per spec. */\n license?: string;\n /** Optional environment-requirements note (max 500 chars). e.g. \"Requires Node 20+\".\n * Emitted as top-level frontmatter `compatibility:` per spec. */\n compatibility?: string;\n /** Optional space-separated string of pre-approved tools (experimental per spec). */\n allowedTools?: string;\n /** Additional caller-defined metadata entries — flat key/value strings nested under\n * `metadata:`. Spec requires string values. */\n metadata?: Record<string, string | number>;\n\n /** Human display name (e.g. \"Example Merchant\"). */\n merchantName: string;\n /** Optional one-line tagline appearing under the title. */\n tagline?: string;\n /** Optional short prose intro describing what the merchant offers. Renders below the title. */\n intro?: string;\n\n /** Files / well-known URLs surfaced under the \"Important Files\" table. The skill.md URL\n * itself is added automatically — list other discovery surfaces (llms.txt, mpp.json,\n * openapi.json, agent-card.json). */\n files?: SkillMdLink[];\n\n /** Rails the merchant accepts. Drives the Payment + Compatible Clients sections. Order\n * is preserved in render. Default to the rails actually declared on the merchant's\n * `respond402` config — keep these in sync. */\n acceptedRails: RailKey[];\n /** Override the per-rail compatible-clients matrix. When omitted, derives from\n * `acceptedRails` via the SDK's smoke-verified default. Override keys not in\n * `acceptedRails` are dropped (the rail isn't accepted, so the row isn't rendered). */\n compatibleClients?: CompatibleClients;\n\n /** Identity requirements as agent-observable outcomes (kyc / age / jurisdiction /\n * sanctions). Internal posture (`failOpen`, mount strategy, KYC vendor) is intentionally\n * not part of this shape — agents act on outcomes, not implementation. */\n identity?: SkillMdIdentityRequirements;\n /** URL to the identity-bootstrap skill. Linked from the Identity Prerequisite section\n * so an agent without a Passport can follow the bootstrap before attempting purchase. */\n identityBootstrapUrl?: string;\n\n /** Shipping policy, for physical-goods merchants. Omit for digital merchants. */\n shipping?: SkillMdShippingPolicy;\n\n /** Agent-facing endpoints — path, method, whether auth is required, brief purpose. */\n endpoints: SkillMdEndpoint[];\n\n /** When this skill should fire (skill loader uses for trigger matching). */\n triggers: string[];\n\n /** Optional numbered onboarding steps. Each entry renders as a numbered list item;\n * may include shell snippets in markdown code fences. */\n onboardingSteps?: string[];\n\n /** Support / homepage / docs links rendered in the \"Support\" section. */\n supportLinks?: SkillMdLink[];\n\n /** When true (default), append a footer noting clients can refresh skill.md to pick\n * up new endpoints. Set to false to suppress. */\n refreshFooter?: boolean;\n}\n\nconst RAIL_LABELS: Record<RailKey, string> = {\n tempo_mpp: 'MPP on Tempo',\n x402_base: 'x402 on Base',\n solana_mpp: 'MPP on Solana',\n stripe: 'Stripe Shared Payment Token',\n};\n\nconst RAIL_NOTES: Record<RailKey, string> = {\n tempo_mpp: 'USDC. Use `agentscore-pay pay --chain tempo` (or `tempo request`); MPP credential goes in `Authorization: Payment`.',\n x402_base: 'USDC (EIP-3009). Use `agentscore-pay pay --chain base`; X-Payment header carries the signed credential.',\n solana_mpp: 'USDC (SPL). Use `agentscore-pay pay --chain solana`; MPP credential goes in `Authorization: Payment`.',\n stripe: 'Card via Link wallet. Use `@stripe/link-cli` — `agentscore-pay` emits the handoff hint when this rail is picked.',\n};\n\nconst NAME_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst NAME_MAX = 64;\nconst DESCRIPTION_MAX = 1024;\nconst COMPATIBILITY_MAX = 500;\n\nfunction validateInput(input: BuildSkillMdInput): void {\n if (!input.name || input.name.length === 0 || input.name.length > NAME_MAX) {\n throw new Error(`buildSkillMd: name must be 1-${NAME_MAX} characters (got ${input.name?.length ?? 0})`);\n }\n if (!NAME_RE.test(input.name)) {\n throw new Error(\n `buildSkillMd: name \"${input.name}\" is invalid — must be lowercase alphanumeric and hyphens, no leading/trailing/consecutive hyphens (agentskills.io spec)`,\n );\n }\n if (!input.description || input.description.length === 0) {\n throw new Error('buildSkillMd: description is required and must be non-empty (agentskills.io spec)');\n }\n if (input.description.length > DESCRIPTION_MAX) {\n throw new Error(\n `buildSkillMd: description must be ≤${DESCRIPTION_MAX} characters (got ${input.description.length})`,\n );\n }\n if (input.compatibility && input.compatibility.length > COMPATIBILITY_MAX) {\n throw new Error(\n `buildSkillMd: compatibility must be ≤${COMPATIBILITY_MAX} characters (got ${input.compatibility.length})`,\n );\n }\n}\n\n/** Quote a value as a YAML double-quoted scalar — escape `\\\\`, `\"`, and newlines. The\n * agentskills.io spec calls out unquoted colons in `description` as the most common\n * parse failure across clients; emit every user-supplied scalar quoted to be safe. */\nfunction quoteYaml(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')}\"`;\n}\n\n/** Sanitize a string for inclusion in a markdown table cell — escape backslashes first\n * (so existing `\\` aren't treated as escapes), then escape pipes (which would otherwise\n * terminate the cell). */\nfunction tableCell(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\\|/g, '\\\\|');\n}\n\nfunction frontmatter(input: BuildSkillMdInput): string {\n const lines: string[] = ['---'];\n lines.push(`name: ${input.name}`);\n lines.push(`description: ${quoteYaml(input.description)}`);\n if (input.license) lines.push(`license: ${quoteYaml(input.license)}`);\n if (input.compatibility) lines.push(`compatibility: ${quoteYaml(input.compatibility)}`);\n if (input.allowedTools) lines.push(`allowed-tools: ${quoteYaml(input.allowedTools)}`);\n\n const meta: Array<[string, string]> = [];\n meta.push(['version', String(input.version ?? '1')]);\n meta.push(['homepage', input.homepage]);\n for (const [k, v] of Object.entries(input.metadata ?? {})) {\n if (k === 'version' || k === 'homepage') continue;\n meta.push([k, String(v)]);\n }\n lines.push('metadata:');\n for (const [k, v] of meta) {\n lines.push(` ${k}: ${quoteYaml(v)}`);\n }\n lines.push('---');\n return lines.join('\\n');\n}\n\nfunction importantFiles(input: BuildSkillMdInput): string {\n const skillUrl = `${input.homepage.replace(/\\/$/, '')}/skill.md`;\n const rows: string[] = [\n '| File | URL |',\n '|------|-----|',\n `| **SKILL.md** (this file) | \\`${skillUrl}\\` |`,\n ];\n for (const f of input.files ?? []) {\n rows.push(`| ${tableCell(f.label)} | \\`${tableCell(f.url)}\\` |`);\n }\n return ['## Important Files', '', ...rows].join('\\n');\n}\n\nfunction paymentSection(input: BuildSkillMdInput): string {\n const override = input.compatibleClients;\n const defaults = compatibleClientsByRails(input.acceptedRails) ?? {};\n // Override entries only apply to rails actually accepted; ignore stragglers.\n const clients: CompatibleClients = {};\n for (const r of input.acceptedRails) {\n clients[r] = override?.[r] ?? defaults[r] ?? [];\n }\n const rows: string[] = ['| Rail | Notes | Compatible clients |', '|---|---|---|'];\n for (const r of input.acceptedRails) {\n const list = (clients[r] ?? []).join(', ') || '—';\n rows.push(`| **${RAIL_LABELS[r]}** | ${RAIL_NOTES[r]} | ${list} |`);\n }\n return [\n '## Payment',\n '',\n 'Each gated route returns a 402 with `WWW-Authenticate` + `PAYMENT-REQUIRED` body listing the rails below with current pricing. Pick whichever your wallet is funded for.',\n '',\n ...rows,\n ].join('\\n');\n}\n\nfunction identitySection(input: BuildSkillMdInput): string {\n const id = input.identity;\n if (!id) return '';\n const reqs: string[] = [];\n if (id.kycRequired) reqs.push('KYC verified Passport');\n if (id.minAge) reqs.push(`age ${id.minAge}+`);\n if (id.allowedJurisdictions?.length) reqs.push(`${id.allowedJurisdictions.join('/')} only`);\n if (id.sanctionsClear) reqs.push('sanctions clear');\n if (reqs.length === 0) return '';\n const bootstrap = input.identityBootstrapUrl\n ? `\\n\\nIf you don't have a Passport, fetch \\`${input.identityBootstrapUrl}\\` and follow the onboarding there first. Bring back the \\`opc_...\\` operator token in \\`X-Operator-Token\\` on every gated request.`\n : '';\n return [\n '## Identity Prerequisite',\n '',\n `This merchant uses AgentScore identity. Required: ${reqs.join(', ')}.${bootstrap}`,\n '',\n 'Denial bodies carry an `agent_instructions` block describing the recovery action — read the `action` field and follow it. See the identity-bootstrap skill for the canonical denial-code → action table.',\n ].join('\\n');\n}\n\nfunction shippingSection(input: BuildSkillMdInput): string {\n const s = input.shipping;\n if (!s || (!s.allowedCountries?.length && !s.blockedStates?.length)) return '';\n const lines: string[] = ['## Shipping', ''];\n if (s.allowedCountries?.length) {\n lines.push(`Ships to: ${s.allowedCountries.join(', ')}.`);\n }\n if (s.blockedStates?.length) {\n if (lines.length > 2) lines.push('');\n lines.push(`Blocked US states: ${s.blockedStates.join(', ')}.`);\n }\n return lines.join('\\n');\n}\n\nfunction endpointsSection(input: BuildSkillMdInput): string {\n if (input.endpoints.length === 0) return '';\n const rows = ['| Method | Path | Auth | Purpose |', '|---|---|---|---|'];\n for (const e of input.endpoints) {\n rows.push(\n `| ${e.method} | \\`${tableCell(e.path)}\\` | ${e.authRequired ? 'identity required' : 'anonymous'} | ${tableCell(e.description)} |`,\n );\n }\n return ['## Endpoints', '', ...rows].join('\\n');\n}\n\nfunction onboardingSection(input: BuildSkillMdInput): string {\n if (!input.onboardingSteps?.length) return '';\n const rows = input.onboardingSteps.map((step, i) => `${i + 1}. ${step}`);\n return ['## Onboarding Flow', '', ...rows].join('\\n');\n}\n\nfunction triggersSection(input: BuildSkillMdInput): string {\n if (input.triggers.length === 0) return '';\n const rows = input.triggers.map((t) => `- ${t}`);\n return ['## Triggers', '', 'Use this skill when the user wants to:', '', ...rows].join('\\n');\n}\n\nfunction supportSection(input: BuildSkillMdInput): string {\n if (!input.supportLinks?.length) return '';\n const rows = input.supportLinks.map((l) => `- **${l.label}**: ${l.url}`);\n return ['## Support', '', ...rows].join('\\n');\n}\n\nfunction refreshFooter(input: BuildSkillMdInput): string {\n if (input.refreshFooter === false) return '';\n return '_Re-fetch this file periodically to pick up new endpoints, rails, or policies._';\n}\n\nfunction titleBlock(input: BuildSkillMdInput): string {\n const parts: string[] = [`# ${input.merchantName}`];\n if (input.tagline) parts.push(`_${input.tagline}_`);\n if (input.intro) parts.push(input.intro);\n return parts.join('\\n\\n');\n}\n\n/**\n * Render an agentskills.io-compatible `skill.md` for an agent-commerce merchant.\n *\n * Output is YAML frontmatter (`name` / `description` / optional `license` /\n * `compatibility` / `allowed-tools` / `metadata`) followed by markdown sections\n * describing payment rails, identity requirements, endpoints, triggers, and support\n * links — strictly the agent-facing contract, with no internal posture (no `failOpen`,\n * no mount-strategy names, no KYC vendor, no defense parameters).\n *\n * Spec compliance:\n * - `name` validated against the agentskills.io regex (lowercase alphanumeric + hyphens,\n * no leading/trailing/consecutive hyphens, ≤64 chars).\n * - `description` length capped at 1024.\n * - `metadata` values always emitted as quoted strings.\n * - `description` (and other user scalars) double-quoted to defuse the colon /\n * newline / quote pitfall the spec explicitly warns about.\n *\n * The compatible-clients-per-rail table sources from the same SDK constant\n * (`compatibleClientsByRails`) that drives the live 402 body's `compatible_clients`\n * field, so updating a smoke-verified client in one place propagates to every surface.\n */\nexport function buildSkillMd(input: BuildSkillMdInput): string {\n validateInput(input);\n const sections = [\n frontmatter(input),\n titleBlock(input),\n importantFiles(input),\n identitySection(input),\n paymentSection(input),\n shippingSection(input),\n onboardingSection(input),\n endpointsSection(input),\n triggersSection(input),\n supportSection(input),\n refreshFooter(input),\n ].filter((s) => s !== '');\n return sections.join('\\n\\n').replace(/\\n{3,}/g, '\\n\\n').trim() + '\\n';\n}\n"],"mappings":";AAIO,IAAM,WAAW;AAAA,EACtB,MAAM;AAAA,IACJ,SAAS,EAAE,OAAO,eAAwB,SAAS,KAAK;AAAA,IACxD,SAAS,EAAE,OAAO,gBAAyB,SAAS,MAAM;AAAA,EAC5D;AAAA,EACA,QAAQ;AAAA,IACN,SAAS,EAAE,OAAO,0CAAmD;AAAA,IACrE,QAAQ,EAAE,OAAO,0CAAmD;AAAA,EACtE;AAAA,EACA,OAAO;AAAA,IACL,SAAS,EAAE,OAAO,eAAwB,SAAS,KAAK;AAAA,IACxD,SAAS,EAAE,OAAO,gBAAyB,SAAS,MAAM;AAAA,EAC5D;AACF;;;ACbO,IAAM,OAAO;AAAA,EAClB,MAAM;AAAA,IACJ,SAAS,EAAE,SAAS,8CAAuD,UAAU,EAAE;AAAA,IACvF,SAAS,EAAE,SAAS,8CAAuD,UAAU,EAAE;AAAA,EACzF;AAAA,EACA,QAAQ;AAAA,IACN,SAAS,EAAE,MAAM,gDAAgD,UAAU,EAAE;AAAA,IAC7E,QAAQ,EAAE,MAAM,gDAAgD,UAAU,EAAE;AAAA,EAC9E;AAAA,EACA,OAAO;AAAA,IACL,SAAS,EAAE,SAAS,8CAAuD,UAAU,EAAE;AAAA,IACvF,SAAS,EAAE,SAAS,8CAAuD,UAAU,EAAE;AAAA,EACzF;AACF;;;ACRO,IAAM,QAAQ;AAAA,EACnB,iBAAiB;AAAA,IACf,QAAQ;AAAA,IACR,SAAS,SAAS,MAAM,QAAQ;AAAA,IAChC,SAAS,SAAS,MAAM,QAAQ;AAAA,IAChC,UAAU,KAAK,MAAM,QAAQ;AAAA,IAC7B,UAAU,KAAK,MAAM,QAAQ;AAAA,IAC7B,OAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAAA,EACA,iBAAiB;AAAA,IACf,QAAQ;AAAA,IACR,SAAS,SAAS,MAAM,QAAQ;AAAA,IAChC,SAAS,SAAS,MAAM,QAAQ;AAAA,IAChC,UAAU,KAAK,MAAM,QAAQ;AAAA,IAC7B,UAAU,KAAK,MAAM,QAAQ;AAAA,IAC7B,OAAO,KAAK,MAAM,QAAQ;AAAA,EAC5B;AAAA,EACA,qBAAqB;AAAA,IACnB,QAAQ;AAAA,IACR,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,OAAO,KAAK,KAAK,QAAQ;AAAA,EAC3B;AAAA,EACA,qBAAqB;AAAA,IACnB,QAAQ;AAAA,IACR,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,OAAO,KAAK,KAAK,QAAQ;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAIA,0BAA0B;AAAA,IACxB,QAAQ;AAAA,IACR,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,OAAO,KAAK,KAAK,QAAQ;AAAA,EAC3B;AAAA,EACA,0BAA0B;AAAA,IACxB,QAAQ;AAAA,IACR,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,SAAS,SAAS,KAAK,QAAQ;AAAA,IAC/B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,UAAU,KAAK,KAAK,QAAQ;AAAA,IAC5B,OAAO,KAAK,KAAK,QAAQ;AAAA,EAC3B;AAAA,EACA,sBAAsB;AAAA,IACpB,QAAQ;AAAA,IACR,SAAS,SAAS,OAAO,QAAQ;AAAA,IACjC,UAAU,KAAK,OAAO,QAAQ;AAAA,IAC9B,UAAU,KAAK,OAAO,QAAQ;AAAA,IAC9B,OAAO,KAAK,OAAO,QAAQ;AAAA,EAC7B;AAAA,EACA,qBAAqB;AAAA,IACnB,QAAQ;AAAA,IACR,SAAS,SAAS,OAAO,OAAO;AAAA,IAChC,UAAU,KAAK,OAAO,OAAO;AAAA,IAC7B,UAAU,KAAK,OAAO,OAAO;AAAA,IAC7B,OAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EACA,cAAc;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACF;AAiBO,SAAS,WAAW,MAA0C;AACnE,SAAO,MAAM,IAAgB;AAC/B;;;ACzEO,SAAS,wBAAwB,OAAoC;AAC1E,QAAM,UAAU,MAAM,OAAO,WAAW,MAAM,IAAI,IAAI;AACtD,QAAM,WAAW,MAAM,YAAY,SAAS,YAAY;AACxD,QAAM,WAAW,MAAM,YAAY,SAAS,YAAY;AACxD,QAAM,UAAU,MAAM,WAAW,SAAS;AAE1C,QAAM,YAAY,OAAO,MAAM,cAAc,WAAW,OAAO,MAAM,SAAS,IAAI,MAAM;AACxF,QAAM,YAAY,OAAO,KAAK,MAAM,YAAY,MAAM,QAAQ,CAAC,EAAE,SAAS;AAC1E,QAAM,OAAgC,EAAE,QAAQ,WAAW,UAAU,SAAS;AAC9E,MAAI,MAAM,UAAW,MAAK,YAAY,MAAM;AAC5C,QAAM,gBAAyC,CAAC;AAChD,MAAI,YAAY,OAAW,eAAc,UAAU;AACnD,MAAI,MAAM,UAAW,eAAc,YAAY,MAAM;AACrD,MAAI,OAAO,KAAK,aAAa,EAAE,SAAS,EAAG,MAAK,gBAAgB;AAChE,SAAO,OAAO,KAAK,KAAK,UAAU,IAAI,CAAC,EAAE,SAAS,WAAW;AAC/D;AAwBO,SAAS,iBAAiB,OAAsC;AACrE,QAAM,UAAU,MAAM,OAAO,WAAW,MAAM,IAAI,IAAI;AACtD,QAAM,SAAS,MAAM,UAAU,SAAS,UAAU;AAClD,QAAM,SAAS,MAAM,UAAU;AAC/B,QAAM,UAAU,MAAM,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,KAAK,GAAI,EAAE,YAAY;AAClF,SAAO,eAAe,MAAM,EAAE,aAAa,MAAM,KAAK,cAAc,MAAM,cAAc,MAAM,eAAe,OAAO,eAAe,MAAM,OAAO;AAClJ;;;ACzBO,SAAS,sBAAsB,OAA2C;AAC/E,SAAO,OAAO,KAAK,KAAK,UAAU,KAAK,CAAC,EAAE,SAAS,QAAQ;AAC7D;;;ACvCA,IAAM,iBAAiB;AACvB,IAAM,oBAAoB;AAYnB,SAAS,2BACd,OACA,eAAuB,WACS;AAChC,MAAI,UAAU,SAAS,KAAK,QAAQ,OAAO;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO,KAAK,KAAK,QAAQ;AAAA,MACzB,OAAO;AAAA,MACP,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA,MAKnB,OAAO,EAAE,MAAM,YAAY,SAAS,IAAI;AAAA,IAC1C;AAAA,EACF;AACA,MAAI,UAAU,SAAS,KAAK,QAAQ,OAAO;AACzC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO,KAAK,KAAK,QAAQ;AAAA,MACzB,OAAO;AAAA,MACP,mBAAmB;AAAA,MACnB,OAAO,EAAE,MAAM,QAAQ,SAAS,IAAI;AAAA,IACtC;AAAA,EACF;AACA,MAAI,UAAU,SAAS,OAAO,QAAQ,OAAO;AAC3C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO,KAAK,OAAO,QAAQ;AAAA,MAC3B,OAAO;AAAA,MACP,mBAAmB;AAAA,IACrB;AAAA,EACF;AACA,MAAI,UAAU,SAAS,OAAO,OAAO,OAAO;AAC1C,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,OAAO,KAAK,OAAO,OAAO;AAAA,MAC1B,OAAO;AAAA,MACP,mBAAmB;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AACT;AAgEO,SAAS,4BAA4B,MAAqD;AAC/F,QAAM,UAAU,SAAS,KAAK,IAAI,CAAC;AACnC,QAAM,UAAU,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,cAAc,OAAO,GAAI,EAAE,YAAY;AACnF,QAAM,UAAU,wBAAwB;AAAA,IACtC,MAAM,KAAK;AAAA,IACX,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK;AAAA,EAClB,CAAC;AACD,QAAM,YAAY,iBAAiB;AAAA,IACjC,MAAM,KAAK;AAAA,IACX,IAAI;AAAA,IACJ,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,IACb;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,UAAmC;AAAA,IACvC,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,KAAK,WAAW;AAAA,IAC3B;AAAA,IACA,WAAW;AAAA,IACX,GAAI,KAAK,UAAU,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,EAC/C;AACA,QAAM,UAAkC;AAAA,IACtC,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,EACtB;AAEA,MAAI,KAAK,YAAY;AACnB,UAAM,cAAc,KAAK,WAAW,WAAW;AAC/C,UAAM,gBAAgB,KAAK,WAAW,YAChC,KAAK,WAAW,YAAY,CAAC,GAC9B,IAAI,CAAC,MAAM,2BAA2B,GAAG,KAAK,WAAY,gBAAgB,SAAS,CAAC,EACpF,OAAO,CAAC,MAAoC,MAAM,IAAI;AAI3D,YAAQ,kBAAkB,IAAI,sBAAsB;AAAA,MAClD;AAAA,MACA,SAAS;AAAA,MACT,GAAI,KAAK,WAAW,cAChB,EAAE,UAAU,EAAE,KAAK,KAAK,WAAW,aAAa,UAAU,mBAAmB,EAAE,IAC/E,CAAC;AAAA,IACP,CAAC;AAGD,YAAQ,cAAc;AAEtB,UAAM,aAAa,KAAK,MAAM,OAAO,KAAK,QAAQ,kBAAkB,GAAG,QAAQ,EAAE,SAAS,OAAO,CAAC;AAClG,YAAQ,UAAU,WAAW;AAAA,EAC/B;AAEA,SAAO;AAAA,IACL,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,KAAK,UAAU,OAAO;AAAA,EAC9B;AACF;AAcA,eAAsB,wBAAwB,KAAoC;AAChF,MAAI,IAAI,WAAW,OAAQ,QAAO;AAClC,QAAM,OAAO,IAAI,QAAQ,IAAI,eAAe;AAC5C,MAAI,MAAM,WAAW,UAAU,EAAG,QAAO;AACzC,QAAM,OAAO,MAAM,IAAI,MAAM,EAAE,KAAK;AACpC,SAAO,CAAC,QAAQ,SAAS;AAC3B;;;ACrMA,eAAsB,sBAAsB,QAAiD;AAC3F,QAAM,SAAS,MAAM,cAA4B,yBAAyB;AAE1E,MAAI,CAAC,QAAQ,2BAA2B;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,0BAA0B,MAAM;AAChD;AAEA,eAAe,cAAiB,YAAuC;AACrE,MAAI;AACF,WAAQ,MAAM,OAAO;AAAA,EACvB,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;;;ACyBO,SAAS,kBAAkB,OAAmD;AACnF,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC9D,KAAK,MAAM;AAAA,IACX,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IAClD,WAAW,MAAM;AAAA,IACjB,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IAClD,UAAU;AAAA,MACR,GAAI,MAAM,SAAS,kBAAkB,EAAE,iBAAiB,MAAM,SAAS,gBAAgB,IAAI,CAAC;AAAA,MAC5F,GAAI,MAAM,SAAS,kBAAkB,EAAE,iBAAiB,MAAM,SAAS,gBAAgB,IAAI,CAAC;AAAA,MAC5F,GAAI,MAAM,SAAS,SAAS,CAAC;AAAA,MAC7B,GAAI,MAAM,SAAS,WAAW,EAAE,UAAU,MAAM,SAAS,SAAS,IAAI,CAAC;AAAA,MACvE,GAAI,MAAM,SAAS,iBAAiB,EAAE,gBAAgB,MAAM,SAAS,eAAe,IAAI,CAAC;AAAA,MACzF,iBAAiB,MAAM,SAAS;AAAA,MAChC,GAAI,MAAM,SAAS,OAAO,EAAE,MAAM,MAAM,SAAS,KAAK,IAAI,CAAC;AAAA,MAC3D,GAAI,MAAM,SAAS,aAAa,EAAE,YAAY,MAAM,SAAS,WAAW,IAAI,CAAC;AAAA,IAC/E;AAAA,IACA,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,IACrD,GAAI,MAAM,SAAS,CAAC;AAAA,EACtB;AACF;;;AChDO,SAAS,mBAAmB,OAAuD;AACxF,SAAO;AAAA,IACL,SAAS;AAAA,IACT,WAAW,MAAM,UAAU,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE;AAAA,EAC7E;AACF;;;ACxBO,SAAS,uBAAuB,QAAqC,CAAC,GAAW;AACtF,MAAI,CAAC,MAAM,YAAY;AACrB,WAAO;AAAA,EACT;AACA,QAAM,aAAa,MAAM;AACzB,QAAM,iBAAiB,aACnB;AAAA;AAAA,cAAmB;AAAA,IACjB,WAAW,cAAc,iBAAiB;AAAA,IAC1C,WAAW,UAAU,OAAO,WAAW,OAAO,MAAM;AAAA,IACpD,WAAW,uBAAuB,SAC9B,GAAG,WAAW,sBAAsB,KAAK,GAAG,CAAC,UAC7C;AAAA,IACJ,WAAW,0BAA0B,oBAAoB;AAAA,EAC3D,EACG,OAAO,OAAO,EACd,KAAK,IAAI,CAAC,MACb;AACJ,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wIAM0H,cAAc;AACjJ;AA2BO,SAAS,sBAAsB,OAA2C;AAC/E,SAAO,MAAM,UAAU,6BAA6B,KAAK,IAAI,6BAA6B,KAAK;AACjG;AAEA,SAAS,cAAcA,QAAiB,QAAyB;AAC/D,SAAOA,OAAM,KAAK,OAAK,EAAE,WAAW,MAAM,CAAC;AAC7C;AAEA,SAAS,cAAcA,QAAiB,QAAyB;AAC/D,SAAOA,OAAM,KAAK,OAAK,EAAE,WAAW,MAAM,KAAK,oCAAoC,KAAK,CAAC,CAAC;AAC5F;AAEA,SAAS,6BAA6B,OAA2C;AAC/E,QAAM,QAAkB,CAAC,cAAc,EAAE;AACzC,QAAMA,SAAQ,MAAM;AACpB,MAAI,cAAcA,QAAO,QAAQ,GAAG;AAClC,UAAM,KAAK,yHAAqH,MAAM,SAAS,GAAG;AAAA,EACpJ;AACA,MAAI,cAAcA,QAAO,YAAY,GAAG;AACtC,UAAM,KAAK,wEAAmE,MAAM,SAAS,2DAA4D;AAAA,EAC3J;AACA,MAAI,cAAcA,QAAO,aAAa,GAAG;AACvC,UAAM,KAAK,0DAAqD,MAAM,SAAS,6DAA8D;AAAA,EAC/I;AACA,MAAIA,OAAM,SAAS,YAAY,GAAG;AAChC,UAAM,KAAK,2MAAsM;AAAA,EACnN;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,wJAAwJ;AACnK,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,6BAA6B,OAA2C;AAC/E,QAAMA,SAAQ,MAAM;AACpB,QAAM,eAAe,MAAM,oBAAoB;AAC/C,QAAM,aAAa,MAAM,gBAAgB;AACzC,QAAM,WAAW,cAAcA,QAAO,QAAQ;AAC9C,QAAM,UAAU,cAAcA,QAAO,YAAY;AACjD,QAAM,YAAY,cAAcA,QAAO,aAAa;AACpD,QAAM,YAAYA,OAAM,SAAS,YAAY;AAC7C,QAAM,kBAAkB,cAAcA,QAAO,YAAY,IAAI,iBAAiB;AAC9E,QAAM,oBAAoB,cAAcA,QAAO,aAAa,IAAI,kBAAkB;AAElF,QAAM,QAAkB,CAAC,cAAc,EAAE;AACzC,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,EAAE;AACb,MAAI,SAAU,OAAM,KAAK,qBAAqB;AAC9C,MAAI,QAAS,OAAM,KAAK,eAAe,eAAe,IAAI;AAC1D,MAAI,UAAW,OAAM,KAAK,eAAe,iBAAiB,IAAI;AAC9D,MAAI,UAAW,OAAM,KAAK,mCAAmC;AAC7D,QAAM,KAAK,EAAE;AAEb,MAAI,UAAU;AACZ,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,6CAA6C;AACxD,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,4CAA4C,YAAY,WAAW,UAAU,GAAG;AAC3F,UAAM,KAAK,mCAAmC;AAC9C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,0BAA0B;AACrC,UAAM,KAAK,qCAAqC;AAChD,UAAM,KAAK,qBAAqB;AAChC,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,KAAK,MAAM,MAAM,EAAE;AAC9B,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,WAAW,WAAW;AACxB,UAAM,cAAc,CAAC,WAAW,iBAAiB,aAAa,iBAAiB,EAAE,OAAO,OAAO,EAAE,KAAK,MAAM;AAC5G,UAAM,QAAQ,CAAC,WAAW,kBAAkB,aAAa,kBAAkB,EAAE,OAAO,OAAO,EAAE,KAAK,MAAM;AACxG,UAAM,KAAK,gBAAgB,WAAW,EAAE;AACxC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,SAAS;AACpB,UAAM,KAAK,iCAAiC;AAC5C,UAAM,KAAK,gCAAgC,KAAK,EAAE;AAClD,UAAM,KAAK,0BAA0B,KAAK,yCAAyC;AACnF,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,2BAA2B,MAAM,MAAM,KAAK;AACvD,UAAM,KAAK,KAAK,UAAU,iBAAiB,gBAAgB,KAAK;AAChE,UAAM,KAAK,qCAAqC;AAChD,UAAM,KAAK,iBAAiB;AAC5B,UAAM,KAAK,iBAAiB;AAC5B,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,WAAW;AACb,UAAM,KAAK,yBAAyB;AACpC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,8SAA8S;AACzT,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,iMAAiM;AAC5M,MAAI,WAAW,WAAW;AACxB,UAAM,KAAK,yGAAyG;AAAA,EACtH;AACA,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;AAmBO,SAAS,aAAa,OAAkC;AAC7D,QAAM,QAAkB,CAAC,KAAK,MAAM,YAAY,EAAE;AAClD,MAAI,MAAM,SAAS;AACjB,UAAM,KAAK,KAAK,MAAM,OAAO,EAAE;AAAA,EACjC;AACA,QAAM,KAAK,EAAE;AACb,aAAW,KAAK,MAAM,UAAU;AAC9B,UAAM,KAAK,MAAM,EAAE,OAAO,EAAE;AAC5B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,EAAE,OAAO;AACpB,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,MAAM,oBAAoB;AAC5B,UAAM,KAAK,uBAAuB,MAAM,kBAAkB,CAAC;AAC3D,UAAM,KAAK,EAAE;AAAA,EACf;AACA,MAAI,MAAM,SAAS;AACjB,UAAM,KAAK,sBAAsB,MAAM,OAAO,CAAC;AAAA,EACjD;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AClMO,SAAS,4BAAqD;AACnE,SAAO;AAAA,IACL,eAAe;AAAA,MACb,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,aACE;AAAA,IACJ;AAAA,IACA,eAAe;AAAA,MACb,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,aACE;AAAA,IACJ;AAAA,IACA,MAAM,mBAAmB;AAAA,EAC3B;AACF;AASO,SAAS,qBAA8C;AAC5D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,aACE;AAAA,EACJ;AACF;AAMO,SAAS,0BAAmD;AACjE,SAAO;AAAA,IACL,wBAAwB;AAAA,MACtB,MAAM;AAAA,MACN,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,aACE;AAAA,IACJ;AAAA,IACA,sBAAsB;AAAA,MACpB,MAAM;AAAA,MACN,YAAY;AAAA,QACV,OAAO,EAAE,MAAM,8CAA8C;AAAA,QAC7D,oBAAoB;AAAA,UAClB,MAAM;AAAA,UACN,aACE;AAAA,QACJ;AAAA,QACA,YAAY,EAAE,MAAM,UAAU,QAAQ,OAAO,aAAa,sQAAiQ;AAAA,QAC3T,YAAY,EAAE,MAAM,SAAS;AAAA,QAC7B,UAAU,EAAE,MAAM,UAAU,QAAQ,MAAM;AAAA,QAC1C,aAAa,EAAE,MAAM,SAAS;AAAA,QAC9B,cAAc,EAAE,MAAM,UAAU,aAAa,kEAAkE;AAAA,MACjH;AAAA,MACA,UAAU,CAAC,SAAS,oBAAoB;AAAA,IAC1C;AAAA,EACF;AACF;AAOO,SAAS,kCAA2D;AACzE,SAAO;AAAA,IACL,2BAA2B;AAAA,MACzB,MAAM;AAAA,MACN,YAAY;AAAA,QACV,kBAAkB,EAAE,MAAM,WAAW,MAAM,CAAC,IAAI,EAAE;AAAA,QAClD,aAAa,EAAE,MAAM,WAAW,MAAM,CAAC,GAAG,CAAC,EAAE;AAAA,QAC7C,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,aAAa,wCAAwC;AAAA,QAC1G,kBAAkB;AAAA,UAChB,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,aAAa;AAAA,QACf;AAAA,QACA,YAAY,EAAE,MAAM,SAAS;AAAA,QAC7B,UAAU,EAAE,MAAM,SAAS;AAAA,QAC3B,SAAS;AAAA,UACP,MAAM;AAAA,UACN,YAAY;AAAA,YACV,UAAU,EAAE,MAAM,SAAS;AAAA,YAC3B,KAAK,EAAE,MAAM,SAAS;AAAA,YACtB,UAAU,EAAE,MAAM,SAAS;AAAA,YAC3B,WAAW,EAAE,MAAM,SAAS;AAAA,YAC5B,OAAO,EAAE,MAAM,SAAS;AAAA,UAC1B;AAAA,QACF;AAAA,QACA,eAAe,EAAE,MAAM,UAAU,MAAM,CAAC,UAAU,gBAAgB,EAAE;AAAA,QACpE,iBAAiB,EAAE,MAAM,SAAS;AAAA,QAClC,gBAAgB,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,EAAE;AAAA,QAC3D,mBAAmB,EAAE,MAAM,SAAS;AAAA,QACpC,oBAAoB,EAAE,MAAM,SAAS;AAAA,QACrC,cAAc,EAAE,MAAM,SAAS;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AACF;AAyDO,SAAS,sBACd,OACuF;AACvF,SAAO,EAAE,kBAAkB,EAAE,OAAO,MAAM,OAAO,WAAW,MAAM,UAAU,EAAE;AAChF;AAmBO,SAAS,mBAAmB,MAAwC;AACzE,SAAO,EAAE,cAAc,KAAK;AAC9B;AAuBO,SAAS,0BACd,OAA4C,CAAC,GACqC;AAClF,QAAM,MAAwF,CAAC;AAC/F,MAAI,KAAK,aAAa,OAAO;AAC3B,QAAI,kBAAkB,0BAA0B;AAAA,EAClD;AACA,MAAI,KAAK,YAAY,SAAS,KAAK,oBAAoB,OAAO;AAC5D,QAAI,UAAU;AAAA,MACZ,GAAI,KAAK,YAAY,QAAQ,wBAAwB,IAAI,CAAC;AAAA,MAC1D,GAAI,KAAK,oBAAoB,QAAQ,gCAAgC,IAAI,CAAC;AAAA,IAC5E;AAAA,EACF;AACA,SAAO;AACT;;;AClPO,IAAM,wBAA6C,oBAAI,IAAI;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,SAAS,gBACd,MACA,SACS;AACT,MAAI,SAAS,SAAS;AACpB,WAAO,IAAI,IAAI,QAAQ,eAAe,CAAC,CAAC,EAAE,IAAI,IAAI;AAAA,EACpD;AACA,MAAI,sBAAsB,IAAI,IAAI,EAAG,QAAO;AAC5C,MAAI,SAAS,aAAa;AACxB,eAAW,KAAK,QAAQ,YAAa,KAAI,MAAM,KAAM,QAAO;AAAA,EAC9D;AACA,SAAO;AACT;AAgBA,IAAM,qBAAqB;AAI3B,SAAS,cAAc,MAAc,WAAoC,cAA4C;AACnH,QAAM,cAAc,eACf,WAAW,IAAI,IAAI,KAAK,QACzB,sBAAsB,IAAI,IAAI,MAAM,WAAW,IAAI,IAAI,KAAK;AAChE,SAAO,CAAC;AACV;AAaO,SAAS,yBAAyB,SAAsC;AAC7E,QAAM,YAAY,SAAS,cAAc,IAAI,IAAI,QAAQ,WAAW,IAAI;AACxE,QAAM,YAAY,SAAS,aAAa;AACxC,SAAO,OAAO,GAAsE,SAA8B;AAChH,UAAM,KAAK;AACX,QAAI,cAAc,EAAE,IAAI,MAAM,WAAW,SAAS,YAAY,GAAG;AAC/D,QAAE,OAAO,gBAAgB,SAAS;AAAA,IACpC;AAAA,EACF;AACF;AAIO,SAAS,gCAAgC,SAAsC;AACpF,QAAM,YAAY,SAAS,cAAc,IAAI,IAAI,QAAQ,WAAW,IAAI;AACxE,QAAM,YAAY,SAAS,aAAa;AACxC,SAAO,CACL,KACA,KACA,SACG;AACH,QAAI,cAAc,IAAI,MAAM,WAAW,SAAS,YAAY,GAAG;AAC7D,UAAI,UAAU,gBAAgB,SAAS;AAAA,IACzC;AACA,SAAK;AAAA,EACP;AACF;AASO,SAAS,gCACd,KACA,SACA,MACM;AACN,QAAM,YAAY,SAAS,cAAc,IAAI,IAAI,QAAQ,WAAW,IAAI;AACxE,QAAM,YAAY,SAAS,aAAa;AACxC,MAAI,QAAQ,aAAa,CAAC,KAAK,OAAO,aAAa;AACjD,UAAM,QAAQ,IAAI,OAAO,IAAI,cAAc,IAAI,MAAM,GAAG,EAAE,CAAC;AAC3D,QAAI,cAAc,MAAM,WAAW,SAAS,YAAY,GAAG;AACzD,YAAM,OAAO,gBAAgB,SAAS;AAAA,IACxC;AACA,aAAS;AAAA,EACX,CAAC;AACD,OAAK;AACP;AAQO,SAAS,oBACd,MACA,UACA,SACU;AACV,QAAM,YAAY,SAAS,cAAc,IAAI,IAAI,QAAQ,WAAW,IAAI;AACxE,QAAM,YAAY,SAAS,aAAa;AACxC,MAAI,CAAC,cAAc,MAAM,WAAW,SAAS,YAAY,EAAG,QAAO;AACnE,QAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,UAAQ,IAAI,gBAAgB,SAAS;AACrC,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,YAAY,SAAS;AAAA,IACrB;AAAA,EACF,CAAC;AACH;AAYO,IAAM,qBAAqB;;;ACjFlC,IAAM,eAAmD;AAAA,EACvD,WAAW,CAAC,kBAAkB,iBAAiB,YAAY;AAAA,EAC3D,WAAW,CAAC,kBAAkB,cAAc,4BAA4B;AAAA,EACxE,YAAY,CAAC,gBAAgB;AAAA,EAC7B,QAAQ,CAAC,UAAU;AACrB;AAMO,SAAS,yBAAyBC,QAA0D;AACjG,QAAM,MAAyB,CAAC;AAChC,aAAW,KAAKA,OAAO,KAAI,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;AACnD,SAAO,OAAO,KAAK,GAAG,EAAE,WAAW,IAAI,SAAY;AACrD;;;ACeA,IAAM,cAAuC;AAAA,EAC3C,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AACV;AAEA,IAAM,aAAsC;AAAA,EAC1C,WAAW;AAAA,EACX,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AACV;AAEA,IAAM,UAAU;AAChB,IAAM,WAAW;AACjB,IAAM,kBAAkB;AACxB,IAAM,oBAAoB;AAE1B,SAAS,cAAc,OAAgC;AACrD,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,MAAM,KAAK,SAAS,UAAU;AAC1E,UAAM,IAAI,MAAM,gCAAgC,QAAQ,oBAAoB,MAAM,MAAM,UAAU,CAAC,GAAG;AAAA,EACxG;AACA,MAAI,CAAC,QAAQ,KAAK,MAAM,IAAI,GAAG;AAC7B,UAAM,IAAI;AAAA,MACR,uBAAuB,MAAM,IAAI;AAAA,IACnC;AAAA,EACF;AACA,MAAI,CAAC,MAAM,eAAe,MAAM,YAAY,WAAW,GAAG;AACxD,UAAM,IAAI,MAAM,mFAAmF;AAAA,EACrG;AACA,MAAI,MAAM,YAAY,SAAS,iBAAiB;AAC9C,UAAM,IAAI;AAAA,MACR,2CAAsC,eAAe,oBAAoB,MAAM,YAAY,MAAM;AAAA,IACnG;AAAA,EACF;AACA,MAAI,MAAM,iBAAiB,MAAM,cAAc,SAAS,mBAAmB;AACzE,UAAM,IAAI;AAAA,MACR,6CAAwC,iBAAiB,oBAAoB,MAAM,cAAc,MAAM;AAAA,IACzG;AAAA,EACF;AACF;AAKA,SAAS,UAAU,OAAuB;AACxC,SAAO,IAAI,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,EAAE,QAAQ,OAAO,KAAK,CAAC;AACpF;AAKA,SAAS,UAAU,OAAuB;AACxC,SAAO,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,OAAO,KAAK;AAC1D;AAEA,SAAS,YAAY,OAAkC;AACrD,QAAM,QAAkB,CAAC,KAAK;AAC9B,QAAM,KAAK,SAAS,MAAM,IAAI,EAAE;AAChC,QAAM,KAAK,gBAAgB,UAAU,MAAM,WAAW,CAAC,EAAE;AACzD,MAAI,MAAM,QAAS,OAAM,KAAK,YAAY,UAAU,MAAM,OAAO,CAAC,EAAE;AACpE,MAAI,MAAM,cAAe,OAAM,KAAK,kBAAkB,UAAU,MAAM,aAAa,CAAC,EAAE;AACtF,MAAI,MAAM,aAAc,OAAM,KAAK,kBAAkB,UAAU,MAAM,YAAY,CAAC,EAAE;AAEpF,QAAM,OAAgC,CAAC;AACvC,OAAK,KAAK,CAAC,WAAW,OAAO,MAAM,WAAW,GAAG,CAAC,CAAC;AACnD,OAAK,KAAK,CAAC,YAAY,MAAM,QAAQ,CAAC;AACtC,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,YAAY,CAAC,CAAC,GAAG;AACzD,QAAI,MAAM,aAAa,MAAM,WAAY;AACzC,SAAK,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;AAAA,EAC1B;AACA,QAAM,KAAK,WAAW;AACtB,aAAW,CAAC,GAAG,CAAC,KAAK,MAAM;AACzB,UAAM,KAAK,KAAK,CAAC,KAAK,UAAU,CAAC,CAAC,EAAE;AAAA,EACtC;AACA,QAAM,KAAK,KAAK;AAChB,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,eAAe,OAAkC;AACxD,QAAM,WAAW,GAAG,MAAM,SAAS,QAAQ,OAAO,EAAE,CAAC;AACrD,QAAM,OAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA,kCAAkC,QAAQ;AAAA,EAC5C;AACA,aAAW,KAAK,MAAM,SAAS,CAAC,GAAG;AACjC,SAAK,KAAK,KAAK,UAAU,EAAE,KAAK,CAAC,QAAQ,UAAU,EAAE,GAAG,CAAC,MAAM;AAAA,EACjE;AACA,SAAO,CAAC,sBAAsB,IAAI,GAAG,IAAI,EAAE,KAAK,IAAI;AACtD;AAEA,SAAS,eAAe,OAAkC;AACxD,QAAM,WAAW,MAAM;AACvB,QAAM,WAAW,yBAAyB,MAAM,aAAa,KAAK,CAAC;AAEnE,QAAM,UAA6B,CAAC;AACpC,aAAW,KAAK,MAAM,eAAe;AACnC,YAAQ,CAAC,IAAI,WAAW,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC;AAAA,EAChD;AACA,QAAM,OAAiB,CAAC,yCAAyC,eAAe;AAChF,aAAW,KAAK,MAAM,eAAe;AACnC,UAAM,QAAQ,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,KAAK;AAC9C,SAAK,KAAK,OAAO,YAAY,CAAC,CAAC,QAAQ,WAAW,CAAC,CAAC,MAAM,IAAI,IAAI;AAAA,EACpE;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,gBAAgB,OAAkC;AACzD,QAAM,KAAK,MAAM;AACjB,MAAI,CAAC,GAAI,QAAO;AAChB,QAAM,OAAiB,CAAC;AACxB,MAAI,GAAG,YAAa,MAAK,KAAK,uBAAuB;AACrD,MAAI,GAAG,OAAQ,MAAK,KAAK,OAAO,GAAG,MAAM,GAAG;AAC5C,MAAI,GAAG,sBAAsB,OAAQ,MAAK,KAAK,GAAG,GAAG,qBAAqB,KAAK,GAAG,CAAC,OAAO;AAC1F,MAAI,GAAG,eAAgB,MAAK,KAAK,iBAAiB;AAClD,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,YAAY,MAAM,uBACpB;AAAA;AAAA,wCAA6C,MAAM,oBAAoB,wIACvE;AACJ,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,qDAAqD,KAAK,KAAK,IAAI,CAAC,IAAI,SAAS;AAAA,IACjF;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,gBAAgB,OAAkC;AACzD,QAAM,IAAI,MAAM;AAChB,MAAI,CAAC,KAAM,CAAC,EAAE,kBAAkB,UAAU,CAAC,EAAE,eAAe,OAAS,QAAO;AAC5E,QAAM,QAAkB,CAAC,eAAe,EAAE;AAC1C,MAAI,EAAE,kBAAkB,QAAQ;AAC9B,UAAM,KAAK,aAAa,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG;AAAA,EAC1D;AACA,MAAI,EAAE,eAAe,QAAQ;AAC3B,QAAI,MAAM,SAAS,EAAG,OAAM,KAAK,EAAE;AACnC,UAAM,KAAK,sBAAsB,EAAE,cAAc,KAAK,IAAI,CAAC,GAAG;AAAA,EAChE;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,iBAAiB,OAAkC;AAC1D,MAAI,MAAM,UAAU,WAAW,EAAG,QAAO;AACzC,QAAM,OAAO,CAAC,sCAAsC,mBAAmB;AACvE,aAAW,KAAK,MAAM,WAAW;AAC/B,SAAK;AAAA,MACH,KAAK,EAAE,MAAM,QAAQ,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,eAAe,sBAAsB,WAAW,MAAM,UAAU,EAAE,WAAW,CAAC;AAAA,IAChI;AAAA,EACF;AACA,SAAO,CAAC,gBAAgB,IAAI,GAAG,IAAI,EAAE,KAAK,IAAI;AAChD;AAEA,SAAS,kBAAkB,OAAkC;AAC3D,MAAI,CAAC,MAAM,iBAAiB,OAAQ,QAAO;AAC3C,QAAM,OAAO,MAAM,gBAAgB,IAAI,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE;AACvE,SAAO,CAAC,sBAAsB,IAAI,GAAG,IAAI,EAAE,KAAK,IAAI;AACtD;AAEA,SAAS,gBAAgB,OAAkC;AACzD,MAAI,MAAM,SAAS,WAAW,EAAG,QAAO;AACxC,QAAM,OAAO,MAAM,SAAS,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AAC/C,SAAO,CAAC,eAAe,IAAI,0CAA0C,IAAI,GAAG,IAAI,EAAE,KAAK,IAAI;AAC7F;AAEA,SAAS,eAAe,OAAkC;AACxD,MAAI,CAAC,MAAM,cAAc,OAAQ,QAAO;AACxC,QAAM,OAAO,MAAM,aAAa,IAAI,CAAC,MAAM,OAAO,EAAE,KAAK,OAAO,EAAE,GAAG,EAAE;AACvE,SAAO,CAAC,cAAc,IAAI,GAAG,IAAI,EAAE,KAAK,IAAI;AAC9C;AAEA,SAAS,cAAc,OAAkC;AACvD,MAAI,MAAM,kBAAkB,MAAO,QAAO;AAC1C,SAAO;AACT;AAEA,SAAS,WAAW,OAAkC;AACpD,QAAM,QAAkB,CAAC,KAAK,MAAM,YAAY,EAAE;AAClD,MAAI,MAAM,QAAS,OAAM,KAAK,IAAI,MAAM,OAAO,GAAG;AAClD,MAAI,MAAM,MAAO,OAAM,KAAK,MAAM,KAAK;AACvC,SAAO,MAAM,KAAK,MAAM;AAC1B;AAuBO,SAAS,aAAa,OAAkC;AAC7D,gBAAc,KAAK;AACnB,QAAM,WAAW;AAAA,IACf,YAAY,KAAK;AAAA,IACjB,WAAW,KAAK;AAAA,IAChB,eAAe,KAAK;AAAA,IACpB,gBAAgB,KAAK;AAAA,IACrB,eAAe,KAAK;AAAA,IACpB,gBAAgB,KAAK;AAAA,IACrB,kBAAkB,KAAK;AAAA,IACvB,iBAAiB,KAAK;AAAA,IACtB,gBAAgB,KAAK;AAAA,IACrB,eAAe,KAAK;AAAA,IACpB,cAAc,KAAK;AAAA,EACrB,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACxB,SAAO,SAAS,KAAK,MAAM,EAAE,QAAQ,WAAW,MAAM,EAAE,KAAK,IAAI;AACnE;","names":["rails","rails"]}
1
+ {"version":3,"sources":["../../src/payment/networks.ts","../../src/payment/usdc.ts","../../src/payment/rails.ts","../../src/payment/directive.ts","../../src/payment/wwwauthenticate.ts","../../src/discovery/probe.ts","../../src/discovery/bazaar.ts","../../src/discovery/well_known_mpp.ts","../../src/discovery/well_known_x402.ts","../../src/discovery/llms_txt.ts","../../src/discovery/openapi.ts","../../src/discovery/robots_tag.ts","../../src/challenge/agent_instructions.ts","../../src/discovery/skill_md.ts","../../src/discovery/agentscore_content.ts","../../src/discovery/redemption_md.ts","../../src/identity/ucp.ts","../../src/identity/ucp-jwks.ts","../../src/discovery/well_known.ts","../../src/discovery/request_id.ts"],"sourcesContent":["/**\n * Named network registry. Vendors reference symbolic names (`networks.base.mainnet.caip2`)\n * instead of magic strings. Lifted from agentscore-pay's constants.\n */\nexport const networks = {\n base: {\n mainnet: { caip2: 'eip155:8453' as const, chainId: 8453 },\n sepolia: { caip2: 'eip155:84532' as const, chainId: 84532 },\n },\n solana: {\n mainnet: { caip2: 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp' as const },\n devnet: { caip2: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1' as const },\n },\n tempo: {\n mainnet: { caip2: 'eip155:4217' as const, chainId: 4217 },\n testnet: { caip2: 'eip155:42431' as const, chainId: 42431 },\n },\n} as const;\n\nexport type NetworkFamily = keyof typeof networks;\n\n/**\n * Returns the family name (base/solana/tempo) for a given CAIP-2 network string,\n * or null if the network isn't in the registry. Useful for routing settlement\n * by network.\n */\nexport function networkFamily(caip2: string): NetworkFamily | null {\n if (caip2 === networks.base.mainnet.caip2 || caip2 === networks.base.sepolia.caip2) return 'base';\n if (caip2 === networks.solana.mainnet.caip2 || caip2 === networks.solana.devnet.caip2) return 'solana';\n if (caip2 === networks.tempo.mainnet.caip2 || caip2 === networks.tempo.testnet.caip2) return 'tempo';\n if (caip2.startsWith('solana:')) return 'solana';\n return null;\n}\n","/**\n * USDC token registry per network. Used by paymentDirective and rail definitions.\n * Lifted from agentscore-pay's constants.\n */\nexport const USDC = {\n base: {\n mainnet: { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' as const, decimals: 6 },\n sepolia: { address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e' as const, decimals: 6 },\n },\n solana: {\n mainnet: { mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6 },\n devnet: { mint: '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU', decimals: 6 },\n },\n tempo: {\n mainnet: { address: '0x20C000000000000000000000b9537d11c60E8b50' as const, decimals: 6 },\n testnet: { address: '0x20c0000000000000000000000000000000000000' as const, decimals: 6 },\n },\n} as const;\n","import { networks } from './networks';\nimport { USDC } from './usdc';\n\n/**\n * Symbolic rail names mapped to their protocol details. Vendors pass `rail: 'tempo-mainnet'`\n * to the directive builder and the SDK fills in method/network/decimals/currency from this\n * registry. Custom rails not in this registry can be passed by setting the lower-level\n * fields directly on the directive builder.\n */\nexport const rails = {\n 'tempo-mainnet': {\n method: 'tempo',\n network: networks.tempo.mainnet.caip2,\n chainId: networks.tempo.mainnet.chainId,\n currency: USDC.tempo.mainnet.address,\n decimals: USDC.tempo.mainnet.decimals,\n asset: USDC.tempo.mainnet.address,\n },\n 'tempo-testnet': {\n method: 'tempo',\n network: networks.tempo.testnet.caip2,\n chainId: networks.tempo.testnet.chainId,\n currency: USDC.tempo.testnet.address,\n decimals: USDC.tempo.testnet.decimals,\n asset: USDC.tempo.testnet.address,\n },\n 'x402-base-mainnet': {\n method: 'x402',\n network: networks.base.mainnet.caip2,\n chainId: networks.base.mainnet.chainId,\n currency: USDC.base.mainnet.address,\n decimals: USDC.base.mainnet.decimals,\n asset: USDC.base.mainnet.address,\n },\n 'x402-base-sepolia': {\n method: 'x402',\n network: networks.base.sepolia.caip2,\n chainId: networks.base.sepolia.chainId,\n currency: USDC.base.sepolia.address,\n decimals: USDC.base.sepolia.decimals,\n asset: USDC.base.sepolia.address,\n },\n // Upto rails — pay UP TO a max amount (Permit2-based, vs EIP-3009 for exact). Use for\n // variable-cost APIs where the actual cost depends on output (LLM tokens, bandwidth, etc.).\n // Only available on EVM networks; Solana svm doesn't ship an upto scheme yet.\n 'x402-base-mainnet-upto': {\n method: 'x402-upto',\n network: networks.base.mainnet.caip2,\n chainId: networks.base.mainnet.chainId,\n currency: USDC.base.mainnet.address,\n decimals: USDC.base.mainnet.decimals,\n asset: USDC.base.mainnet.address,\n },\n 'x402-base-sepolia-upto': {\n method: 'x402-upto',\n network: networks.base.sepolia.caip2,\n chainId: networks.base.sepolia.chainId,\n currency: USDC.base.sepolia.address,\n decimals: USDC.base.sepolia.decimals,\n asset: USDC.base.sepolia.address,\n },\n 'mpp-solana-mainnet': {\n method: 'solana',\n network: networks.solana.mainnet.caip2,\n currency: USDC.solana.mainnet.mint,\n decimals: USDC.solana.mainnet.decimals,\n asset: USDC.solana.mainnet.mint,\n },\n 'mpp-solana-devnet': {\n method: 'solana',\n network: networks.solana.devnet.caip2,\n currency: USDC.solana.devnet.mint,\n decimals: USDC.solana.devnet.decimals,\n asset: USDC.solana.devnet.mint,\n },\n 'stripe-spt': {\n method: 'stripe',\n currency: 'usd',\n decimals: 2,\n },\n} as const;\n\nexport type RailName = keyof typeof rails;\n\nexport interface RailDefinition {\n method: string;\n network?: string;\n chainId?: number;\n currency: string;\n decimals: number;\n asset?: string;\n}\n\n/**\n * Lookup a rail definition by symbolic name. Returns undefined if the rail isn't in\n * the registry — vendors with custom rails should pass the low-level fields directly.\n */\nexport function lookupRail(name: string): RailDefinition | undefined {\n return rails[name as RailName] as RailDefinition | undefined;\n}\n","import { lookupRail } from './rails';\n\n/**\n * Build the base64-encoded `request` blob for an MPP Payment directive (per the\n * paymentauth.org spec). Output shape matches what link-cli `mpp decode` expects:\n *\n * { amount: \"<raw_integer>\", currency: \"<token>\", recipient?: \"<addr>\",\n * methodDetails?: { chainId?: number, networkId?: string } }\n */\nexport function buildPaymentRequestBlob({\n rail,\n amountUsd,\n currency,\n decimals,\n recipient,\n chainId,\n networkId,\n}: {\n /** Symbolic rail name (e.g., 'tempo-mainnet', 'x402-base-mainnet') — fills in defaults */\n rail?: string;\n /** Amount in USD as a number or string. Converted to raw integer using `decimals`. */\n amountUsd: string | number;\n /** Token contract address or currency code. Defaults from rail. */\n currency?: string;\n /** Decimal precision for the amount. Defaults from rail (6 for USDC, 2 for USD). */\n decimals?: number;\n /** Recipient address (on-chain). Optional for stripe-style rails. */\n recipient?: string;\n /** EVM chain ID (goes into methodDetails.chainId). Defaults from rail. */\n chainId?: number;\n /** Stripe profile_id or similar (goes into methodDetails.networkId — note camelCase per link-cli's mpp decode validator). */\n networkId?: string;\n}): string {\n const railDef = rail ? lookupRail(rail) : undefined;\n const decimalsResolved = decimals ?? railDef?.decimals ?? 6;\n const currencyResolved = currency ?? railDef?.currency ?? 'usd';\n const chainIdResolved = chainId ?? railDef?.chainId;\n\n const amountNum = typeof amountUsd === 'string' ? Number(amountUsd) : amountUsd;\n const amountRaw = BigInt(Math.round(amountNum * 10 ** decimalsResolved)).toString();\n const blob: Record<string, unknown> = { amount: amountRaw, currency: currencyResolved, decimals: decimalsResolved };\n if (recipient) blob.recipient = recipient;\n const methodDetails: Record<string, unknown> = {};\n if (chainIdResolved !== undefined) methodDetails.chainId = chainIdResolved;\n if (networkId) methodDetails.networkId = networkId;\n if (Object.keys(methodDetails).length > 0) blob.methodDetails = methodDetails;\n return Buffer.from(JSON.stringify(blob)).toString('base64url');\n}\n\n/**\n * Format an MPP Payment directive string for the WWW-Authenticate header.\n * Output shape: `Payment id=\"...\", realm=\"...\", method=\"...\", intent=\"charge\",\n * expires=\"...\", request=\"<base64>\"`\n */\nexport function paymentDirective({\n rail,\n id,\n realm,\n method,\n intent,\n expires,\n request,\n}: {\n /** Symbolic rail name — sets `method` automatically */\n rail?: string;\n /** Challenge id (unique per request, used to correlate retries) */\n id: string;\n /** Realm — the host of the merchant URL (e.g., \"agents.merchant.example\") */\n realm: string;\n /** MPP method name. Defaults from rail (e.g., 'tempo', 'stripe'). */\n method?: string;\n /** MPP intent. Defaults to 'charge'. */\n intent?: string;\n /** ISO-8601 expiry timestamp. Defaults to now + 5 minutes. */\n expires?: string;\n /** Base64-encoded request blob. Pass the result of buildPaymentRequestBlob. */\n request: string;\n}): string {\n const railDef = rail ? lookupRail(rail) : undefined;\n const methodResolved = method ?? railDef?.method ?? 'unknown';\n const intentResolved = intent ?? 'charge';\n const expiresResolved = expires ?? new Date(Date.now() + 5 * 60 * 1000).toISOString();\n return `Payment id=\"${id}\", realm=\"${realm}\", method=\"${methodResolved}\", intent=\"${intentResolved}\", expires=\"${expiresResolved}\", request=\"${request}\"`;\n}\n\n/**\n * Convenience: build the request blob and the directive in one call. Most vendors\n * want this rather than the two-step form.\n */\nexport function buildPaymentDirective({\n rail,\n id,\n realm,\n amountUsd,\n currency,\n decimals,\n recipient,\n chainId,\n networkId,\n method,\n intent,\n expires,\n}: {\n rail: string;\n id: string;\n realm: string;\n amountUsd: string | number;\n currency?: string;\n decimals?: number;\n recipient?: string;\n chainId?: number;\n networkId?: string;\n method?: string;\n intent?: string;\n expires?: string;\n}): string {\n const request = buildPaymentRequestBlob({\n rail,\n amountUsd,\n currency,\n decimals,\n recipient,\n chainId,\n networkId,\n });\n return paymentDirective({\n rail,\n id,\n realm,\n method,\n intent,\n expires,\n request,\n });\n}\n","/**\n * Joins multiple Payment directives into a single WWW-Authenticate header value.\n * Per RFC 7235, multiple challenges are comma-separated.\n */\nexport function wwwAuthenticateHeader(directives: string[]): string {\n return directives.join(', ');\n}\n\n/**\n * Add the v1↔v2 amount-field alias to each accepts entry. Idempotent. Used by both\n * `paymentRequiredHeader` (header emit) and `build402Body` (body emit) so every\n * x402 entry on the wire carries BOTH `amount` (v2 spec) AND `maxAmountRequired`\n * (v1 spec) — strict v1-only parsers (e.g. Coinbase awal at `payments-mcp.coinbase.com`,\n * which is hardcoded to read `maxAmountRequired`) work alongside strict v2 parsers,\n * which ignore the alias.\n */\nexport function aliasAmountFields(accepts: unknown[]): unknown[] {\n return accepts.map((entry) => {\n if (entry === null || typeof entry !== 'object') return entry;\n const e = entry as Record<string, unknown>;\n const hasAmount = e.amount !== undefined;\n const hasMaxAmount = e.maxAmountRequired !== undefined;\n if (hasAmount && !hasMaxAmount) return { ...e, maxAmountRequired: e.amount };\n if (hasMaxAmount && !hasAmount) return { ...e, amount: e.maxAmountRequired };\n return e;\n });\n}\n\n/**\n * Encode the standard x402 PAYMENT-REQUIRED header (base64-encoded JSON of the\n * PaymentRequired object). Clients that recognize the header (`@x402/fetch`,\n * `@x402/core` HTTPClient, `agentscore-pay`) prefer it over body fields.\n *\n * Note: do NOT add a v1↔v2 amount-field alias here. `@x402/core`'s\n * `findMatchingRequirements` uses `deepEqual` against the agent's signed\n * `accepted` payload — any field present on one side and missing on the other\n * (e.g. `maxAmountRequired` on the wire body but not in `buildPaymentRequirements`'s\n * output) makes the match silently fail at settle time. Keep `accepts` shape\n * identical to whatever `buildPaymentRequirements` produces server-side.\n */\nexport function paymentRequiredHeader({\n x402Version,\n accepts,\n resource,\n}: {\n x402Version: 1 | 2;\n accepts: unknown[];\n resource?: { url: string; mimeType?: string };\n}): string {\n return Buffer.from(JSON.stringify({ x402Version, accepts, ...(resource ? { resource } : {}) })).toString('base64');\n}\n","import { buildPaymentRequestBlob, paymentDirective } from '../payment/directive';\nimport { networks } from '../payment/networks';\nimport { USDC } from '../payment/usdc';\nimport { paymentRequiredHeader } from '../payment/wwwauthenticate';\n\n/** Placeholder payTo for x402 sample accepts in the discovery probe — the probe\n * exists for crawlers to find that we support x402, not for actual payment. The\n * real 402 (returned on a fully-formed request body) carries real deposit\n * addresses minted from a Stripe PaymentIntent. */\nconst ZERO_EVM_PAYTO = '0x0000000000000000000000000000000000000000';\nconst ZERO_SOLANA_PAYTO = '11111111111111111111111111111111';\n\n/**\n * Build a sample x402 accepts entry for a CAIP-2 network. Looks up the USDC asset\n * for the network from the `USDC` registry and uses a placeholder payTo. Used by\n * the discovery probe to advertise x402 support without exposing real deposit\n * addresses.\n *\n * Returns null when the network isn't in the registry — vendors with custom\n * networks should construct accepts entries by hand and pass them via\n * `x402Sample.accepts` directly.\n */\nexport function sampleX402AcceptForNetwork(\n caip2: string,\n amountAtomic: string = '1000000',\n): Record<string, unknown> | null {\n if (caip2 === networks.base.mainnet.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.base.mainnet.address,\n payTo: ZERO_EVM_PAYTO,\n maxTimeoutSeconds: 300,\n // ``extra.name`` mirrors the on-chain USDC contract's ``name()`` because\n // EIP-712 domain hashes include this string. Wrong name → every signed\n // payload fails facilitator verify with ``invalid_exact_evm_payload_signature``.\n // Base mainnet USDC returns \"USD Coin\"; base sepolia USDC returns \"USDC\".\n extra: { name: 'USD Coin', version: '2' },\n };\n }\n if (caip2 === networks.base.sepolia.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.base.sepolia.address,\n payTo: ZERO_EVM_PAYTO,\n maxTimeoutSeconds: 300,\n extra: { name: 'USDC', version: '2' },\n };\n }\n if (caip2 === networks.solana.mainnet.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.solana.mainnet.mint,\n payTo: ZERO_SOLANA_PAYTO,\n maxTimeoutSeconds: 300,\n };\n }\n if (caip2 === networks.solana.devnet.caip2) {\n return {\n scheme: 'exact',\n network: caip2,\n amount: amountAtomic,\n asset: USDC.solana.devnet.mint,\n payTo: ZERO_SOLANA_PAYTO,\n maxTimeoutSeconds: 300,\n };\n }\n return null;\n}\n\ninterface DiscoveryProbeOptions {\n /** Realm — typically the host of your merchant URL (e.g., \"agents.merchant.example\"). */\n realm: string;\n /** Symbolic rail name to advertise in the sample challenge (e.g., 'tempo-mainnet'). */\n sampleRail: string;\n /** Sample amount in USD for the probe (e.g., 1.00). Crawlers use this as an example. */\n sampleAmountUsd: number;\n /** A recipient address to use in the sample directive (your real or zero address is fine). */\n sampleRecipient: string;\n /** MPP intent. Defaults to 'charge'. */\n intent?: string;\n /** TTL for the probe challenge in seconds. Defaults to 300 (5 minutes). */\n ttlSeconds?: number;\n /** Optional URL to include in the body for further docs (e.g., your llms.txt). */\n docsUrl?: string;\n /** Optional human-readable message in the body. */\n message?: string;\n /** Optional sample x402 accepts entries. When provided, the probe response also\n * carries the standard x402 `payment-required` header (base64 PaymentRequired) AND\n * an `accepts` array in the body — so x402 crawlers (e.g. Coinbase awal's\n * `x402 details`/`x402 pay`) can discover the endpoint's x402 support without\n * needing to send a fully-formed business request. Each entry is run through\n * `aliasAmountFields` so v1-only parsers can read `maxAmountRequired` too.\n *\n * Pass `networks` (shorthand) for the common case — the helper looks up USDC\n * per network from the registry and uses placeholder payTo addresses. Or pass\n * `accepts` directly for full control over the sample shape. */\n x402Sample?: {\n /** Spec version to declare. Defaults to 2. */\n version?: 1 | 2;\n /** Shorthand: array of CAIP-2 network strings. Each is mapped to a sample\n * USDC accepts entry via `sampleX402AcceptForNetwork`. Networks not in the\n * USDC registry are silently skipped. Use `accepts` for custom shapes. */\n networks?: string[];\n /** Sample accepts entries. Used when `networks` shorthand isn't enough.\n * Supplied entries are NOT merged with `networks`-derived entries — pick\n * one or the other. */\n accepts?: unknown[];\n /** Sample atomic amount used by the `networks` shorthand. Defaults to\n * `'1000000'` ($1.00 USDC at 6 decimals). Ignored when `accepts` is set. */\n amountAtomic?: string;\n /** Resource URL the probe is responding for. Used in the PAYMENT-REQUIRED header. */\n resourceUrl?: string;\n };\n}\n\nexport interface DiscoveryProbeResponse {\n status: 402;\n headers: Record<string, string>;\n body: string;\n}\n\n/**\n * Build a 402 response advertising a sample Payment challenge. MPP crawlers\n * (mppscan, link-cli mpp decode) probe with empty bodies; merchants need to answer\n * with a properly-formatted Payment directive so the realm can be indexed.\n *\n * Returns a framework-agnostic response shape. Wrap in your framework's response:\n *\n * const probe = buildDiscoveryProbeResponse({...});\n * return new Response(probe.body, { status: probe.status, headers: probe.headers });\n */\nexport function buildDiscoveryProbeResponse(opts: DiscoveryProbeOptions): DiscoveryProbeResponse {\n const probeId = `probe_${Date.now()}`;\n const expires = new Date(Date.now() + (opts.ttlSeconds ?? 300) * 1000).toISOString();\n const request = buildPaymentRequestBlob({\n rail: opts.sampleRail,\n amountUsd: opts.sampleAmountUsd,\n recipient: opts.sampleRecipient,\n });\n const directive = paymentDirective({\n rail: opts.sampleRail,\n id: probeId,\n realm: opts.realm,\n intent: opts.intent,\n expires,\n request,\n });\n\n const bodyObj: Record<string, unknown> = {\n error: {\n code: 'payment_required',\n message: opts.message ?? 'This endpoint requires payment. Send a valid request body to receive a full challenge.',\n },\n discovery: true,\n ...(opts.docsUrl ? { docs: opts.docsUrl } : {}),\n };\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n 'www-authenticate': directive,\n };\n\n if (opts.x402Sample) {\n const x402Version = opts.x402Sample.version ?? 2;\n const sampleAccepts = opts.x402Sample.accepts\n ?? (opts.x402Sample.networks ?? [])\n .map((n) => sampleX402AcceptForNetwork(n, opts.x402Sample!.amountAtomic ?? '1000000'))\n .filter((e): e is Record<string, unknown> => e !== null);\n // paymentRequiredHeader applies aliasAmountFields internally; do the same for\n // the body's `accepts` so v1-only parsers (Coinbase awal at payments-mcp.coinbase.com)\n // and v2-strict parsers can both read either field name.\n headers['payment-required'] = paymentRequiredHeader({\n x402Version,\n accepts: sampleAccepts,\n ...(opts.x402Sample.resourceUrl\n ? { resource: { url: opts.x402Sample.resourceUrl, mimeType: 'application/json' } }\n : {}),\n });\n // Also embed in body for clients that read body-level accepts (e.g. awal x402 details\n // falls back from header → body when the header isn't present).\n bodyObj.x402Version = x402Version;\n // Reuse the header's already-aliased accepts so the body matches.\n const headerJson = JSON.parse(Buffer.from(headers['payment-required'], 'base64').toString('utf-8'));\n bodyObj.accepts = headerJson.accepts;\n }\n\n return {\n status: 402,\n headers,\n body: JSON.stringify(bodyObj),\n };\n}\n\nexport interface RequestLike {\n method: string;\n headers: { get(name: string): string | null };\n clone(): { text(): Promise<string> };\n}\n\n/**\n * Returns true when the request is an empty-body POST without a payment credential —\n * the canonical MPP discovery probe pattern. Vendors compose this with\n * buildDiscoveryProbeResponse to short-circuit crawler requests before any business\n * logic runs.\n */\nexport async function isDiscoveryProbeRequest(req: RequestLike): Promise<boolean> {\n if (req.method !== 'POST') return false;\n const auth = req.headers.get('authorization');\n if (auth?.startsWith('Payment ')) return false;\n const body = await req.clone().text();\n return !body || body === '{}';\n}\n","/**\n * Bazaar discovery extension wrapper. Vendors pass their merchant config and we wrap\n * `declareDiscoveryExtension` from `@x402/extensions/bazaar`. The returned value is\n * registered on the x402 server (e.g., via `createX402Server({bazaar: true})` or\n * `server.registerExtension(...)`).\n *\n * `@x402/extensions` is an optional peer dependency.\n */\ninterface BazaarDiscoveryConfig {\n bodyType?: 'json' | 'form';\n input?: Record<string, unknown>;\n output?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\ninterface BazaarModule {\n declareDiscoveryExtension?: (config: BazaarDiscoveryConfig) => unknown;\n}\n\nexport async function createBazaarDiscovery(config: BazaarDiscoveryConfig): Promise<unknown> {\n const bazaar = await dynamicImport<BazaarModule>('@x402/extensions/bazaar');\n /* v8 ignore start -- peer-dep-absence guard; @x402/extensions is installed in test env */\n if (!bazaar?.declareDiscoveryExtension) {\n throw new Error(\n '@x402/extensions not installed — `npm install @x402/extensions` for createBazaarDiscovery.',\n );\n }\n /* v8 ignore stop */\n return bazaar.declareDiscoveryExtension(config);\n}\n\nasync function dynamicImport<T>(moduleName: string): Promise<T | null> {\n try {\n return (await import(moduleName)) as T;\n } catch {\n /* v8 ignore next -- catch fires only when peer dep is missing; installed in test env */\n return null;\n }\n}\n","export interface PaymentMethodConfig {\n /** MPP payment methods accepted, e.g., ['tempo', 'x402', 'stripe']. */\n methods: string[];\n /** x402-specific config (when 'x402' is in methods). */\n x402?: {\n networks: string[];\n scheme?: string;\n asset?: string;\n facilitator?: string;\n client_tooling?: string;\n };\n /** Identity headers accepted (e.g., ['X-Operator-Token', 'X-Wallet-Address']). */\n identity?: string[];\n /** Per-identity-path metadata for agents. */\n identity_paths?: {\n wallet?: { header: string; applies_to_rails: string[]; note?: string };\n operator_token?: { header: string; applies_to_rails: string[]; note?: string };\n };\n /** Compliance policy summary for agents to know what they need before purchasing. */\n compliance?: {\n require_kyc?: boolean;\n min_age?: number;\n allowed_jurisdictions?: string[];\n require_sanctions_clear?: boolean;\n };\n /** Required fields in the request body. */\n required_fields?: string[];\n /** Optional fields in the request body. */\n optional_fields?: string[];\n /** Vendor-specific extras merged into the purchase block (e.g., gift_note metadata). */\n extra?: Record<string, unknown>;\n}\n\n/**\n * Build the standard `.well-known/mpp.json` discovery document. Lift the boilerplate\n * (payment.methods, payment.identity_paths, payment.compliance) into a typed config so\n * vendors get spec-compliance \"for free\"; merchant-specific fields (catalog, shipping)\n * pass through.\n *\n * Wire it in your framework like:\n * app.get('/.well-known/mpp.json', (c) => c.json(buildWellKnownMpp({...})));\n */\nexport function buildWellKnownMpp({\n name,\n description,\n url,\n openapi,\n endpoints,\n catalog,\n purchase,\n shipping,\n extra,\n}: {\n /** Merchant display name. */\n name: string;\n /** Short description (1-2 sentences). */\n description?: string;\n /** Canonical merchant URL. */\n url: string;\n /** OpenAPI doc URL (typically `${url}/openapi.json`). */\n openapi?: string;\n /** Endpoints map: path → {method, url}. */\n endpoints: Record<string, { method: string; url: string }>;\n /** Catalog metadata (categories, etc). Optional. */\n catalog?: Record<string, unknown>;\n /** Purchase flow details (payment methods, identity, compliance). */\n purchase: PaymentMethodConfig;\n /** Shipping policy (countries, restrictions). */\n shipping?: Record<string, unknown>;\n /** Vendor-specific extra fields merged at the top level. */\n extra?: Record<string, unknown>;\n}): Record<string, unknown> {\n return {\n name,\n ...(description ? { description } : {}),\n url,\n ...(openapi ? { openapi } : {}),\n endpoints,\n ...(catalog ? { catalog } : {}),\n purchase: {\n ...(purchase.required_fields ? { required_fields: purchase.required_fields } : {}),\n ...(purchase.optional_fields ? { optional_fields: purchase.optional_fields } : {}),\n ...(purchase.extra ?? {}),\n ...(purchase.identity ? { identity: purchase.identity } : {}),\n ...(purchase.identity_paths ? { identity_paths: purchase.identity_paths } : {}),\n payment_methods: purchase.methods,\n ...(purchase.x402 ? { x402: purchase.x402 } : {}),\n ...(purchase.compliance ? { compliance: purchase.compliance } : {}),\n },\n ...(shipping ? { shipping } : {}),\n ...(extra ?? {}),\n };\n}\n","/**\n * `buildWellKnownX402`: emits the x402scan v1 `/.well-known/x402` discovery shape.\n *\n * x402scan accepts three discovery strategies (OpenAPI > `/.well-known/x402` > endpoint\n * probe). Most AgentScore merchants already publish a richer `/.well-known/mpp.json`,\n * but x402scan's strict parser only reads the v1 shape, so we emit both. The two\n * coexist on different paths.\n *\n * Spec (verbatim, x402scan):\n *\n * {\n * \"version\": 1,\n * \"resources\": [\"POST /api/route\", ...]\n * }\n *\n * Resource entries are `\"METHOD /path\"` strings, not objects. Runtime 402 behavior\n * is authoritative over this static metadata.\n */\n\nexport interface WellKnownX402Resource {\n /** HTTP method, uppercase: `'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'`. */\n method: string;\n /** Path, leading slash: `'/purchase'`. */\n path: string;\n}\n\nexport interface BuildWellKnownX402Input {\n /** Invocable, payment-required routes. Each entry becomes `\"METHOD /path\"`. */\n resources: WellKnownX402Resource[];\n}\n\nexport interface WellKnownX402Document {\n version: 1;\n resources: string[];\n}\n\nexport function buildWellKnownX402(input: BuildWellKnownX402Input): WellKnownX402Document {\n return {\n version: 1,\n resources: input.resources.map((r) => `${r.method.toUpperCase()} ${r.path}`),\n };\n}\n","/**\n * Generate the standard \"Choose your identity header\" section for an AgentScore-gated\n * merchant's llms.txt. Explains wallet-auth vs operator-token paths + the cross-merchant\n * memory contract so agents know how to authenticate without reading the API docs.\n */\nexport function llmsTxtIdentitySection({\n agentscore,\n compliance,\n}: {\n /** When true, include the AgentScore identity-paths explanation (wallet vs operator-token). */\n agentscore?: boolean;\n /** Compliance policy to mention (KYC, age, jurisdiction). */\n compliance?: {\n require_kyc?: boolean;\n min_age?: number;\n allowed_jurisdictions?: string[];\n require_sanctions_clear?: boolean;\n };\n} = {}): string {\n if (!agentscore) {\n return '';\n }\n const complianceNote = compliance\n ? `\\n\\nCompliance: ${[\n compliance.require_kyc ? 'KYC required' : null,\n compliance.min_age ? `age ${compliance.min_age}+` : null,\n compliance.allowed_jurisdictions?.length\n ? `${compliance.allowed_jurisdictions.join('/')} only`\n : null,\n compliance.require_sanctions_clear ? 'sanctions clear' : null,\n ]\n .filter(Boolean)\n .join(', ')}.`\n : '';\n return `## Identity\n\nAgentScore identity is reusable across every AgentScore-gated merchant — one KYC, no re-verification per site. Pick a header:\n\n- **\\`X-Wallet-Address: 0x...\\` or base58** — works on signing rails (Tempo, x402, Solana MPP). The wallet you claim must sign the payment.\n- **\\`X-Operator-Token: opc_...\\`** — works on every rail, including Stripe SPT. Reusable across AgentScore merchants until expiry.\n- **Neither** — you get a 403 with \\`verify_url\\`. Complete the session flow once and reuse the resulting \\`opc_...\\` everywhere.${complianceNote}`;\n}\n\ninterface LlmsTxtPaymentSectionConfig {\n /** Symbolic rail names supported. */\n rails: ('tempo-mainnet' | 'tempo-testnet' | 'x402-base-mainnet' | 'x402-base-sepolia' | 'mpp-solana-mainnet' | 'mpp-solana-devnet' | 'stripe-spt' | string)[];\n /** Merchant URL — used in the example commands. */\n appUrl: string;\n /**\n * When true, emit the verbose multi-step variant: setup commands per rail, full per-rail\n * payment-command examples, and warnings about footguns. Default false (one-line bullet per rail).\n * Use this when llms.txt is the primary integration doc the agent reads.\n */\n verbose?: boolean;\n /** When verbose, the Tempo network name to mention in the prerequisites. Default 'tempo-mainnet'. */\n tempoNetworkName?: string;\n /** When verbose, the Tempo chain id to mention in the prerequisites. Default 4217. */\n tempoChainId?: number;\n}\n\n/**\n * Generate the standard \"## Payment\" section for a merchant's llms.txt. Documents the\n * supported rails with concrete CLI examples (tempo request, agentscore-pay, link-cli)\n * per the configured rail set.\n *\n * Pass `verbose: true` for the rich variant — multi-step setup + multi-line command examples +\n * exact-amount warnings. Default is the compact one-bullet-per-rail form.\n */\nexport function llmsTxtPaymentSection(input: LlmsTxtPaymentSectionConfig): string {\n return input.verbose ? llmsTxtPaymentSectionVerbose(input) : llmsTxtPaymentSectionCompact(input);\n}\n\nfunction hasRailFamily(rails: string[], prefix: string): boolean {\n return rails.some(r => r.startsWith(prefix));\n}\n\nfunction isTestnetRail(rails: string[], prefix: string): boolean {\n return rails.some(r => r.startsWith(prefix) && /(sepolia|devnet|moderato|testnet)/.test(r));\n}\n\nfunction llmsTxtPaymentSectionCompact(input: LlmsTxtPaymentSectionConfig): string {\n const lines: string[] = ['## Payment', ''];\n const rails = input.rails;\n if (hasRailFamily(rails, 'tempo-')) {\n lines.push('- **Tempo USDC via MPP** — `tempo request -X POST -H \"X-Operator-Token: opc_...\" --json \\'{...}\\' --max-spend N ' + input.appUrl + '`');\n }\n if (hasRailFamily(rails, 'x402-base-')) {\n lines.push('- **x402 USDC on Base** (EIP-3009) — `agentscore-pay pay POST ' + input.appUrl + ' --chain base -H \"X-Operator-Token: opc_...\" -d \\'{...}\\'`');\n }\n if (hasRailFamily(rails, 'mpp-solana-')) {\n lines.push('- **USDC on Solana** — `agentscore-pay pay POST ' + input.appUrl + ' --chain solana -H \"X-Operator-Token: opc_...\" -d \\'{...}\\'`');\n }\n if (rails.includes('stripe-spt')) {\n lines.push('- **Stripe Shared Payment Token** — agent mints SPT (own Stripe account scoped to networkId, OR `link-cli spend-request create --credential-type shared_payment_token --network-id <profileId> ...`)');\n }\n lines.push('');\n lines.push('IMPORTANT: Do NOT use raw on-chain transfers. Use the CLI commands above so the payment credential is signed and submitted via the protocol handshake.');\n lines.push('');\n return lines.join('\\n');\n}\n\nfunction llmsTxtPaymentSectionVerbose(input: LlmsTxtPaymentSectionConfig): string {\n const rails = input.rails;\n const tempoNetwork = input.tempoNetworkName ?? 'tempo-mainnet';\n const tempoChain = input.tempoChainId ?? 4217;\n const hasTempo = hasRailFamily(rails, 'tempo-');\n const hasBase = hasRailFamily(rails, 'x402-base-');\n const hasSolana = hasRailFamily(rails, 'mpp-solana-');\n const hasStripe = rails.includes('stripe-spt');\n const baseNetworkName = isTestnetRail(rails, 'x402-base-') ? 'Base Sepolia' : 'Base';\n const solanaNetworkName = isTestnetRail(rails, 'mpp-solana-') ? 'Solana devnet' : 'Solana';\n\n const lines: string[] = ['## Payment', ''];\n lines.push('Accepted rails:');\n lines.push('');\n if (hasTempo) lines.push('- **USDC on Tempo**');\n if (hasBase) lines.push(`- **USDC on ${baseNetworkName}**`);\n if (hasSolana) lines.push(`- **USDC on ${solanaNetworkName}**`);\n if (hasStripe) lines.push('- **Stripe Shared Payment Token**');\n lines.push('');\n\n if (hasTempo) {\n lines.push('### Pay with Tempo');\n lines.push('');\n lines.push('```bash');\n lines.push('curl -fsSL https://tempo.xyz/install | bash');\n lines.push('tempo wallet login');\n lines.push(`tempo wallet whoami # need USDC.e on ${tempoNetwork} (chain ${tempoChain})`);\n lines.push('tempo wallet fund # if zero');\n lines.push('');\n lines.push('tempo request -X POST \\\\');\n lines.push(' -H \"X-Operator-Token: opc_...\" \\\\');\n lines.push(\" --json '{...}' \\\\\");\n lines.push(' --max-spend N \\\\');\n lines.push(` ${input.appUrl}`);\n lines.push('```');\n lines.push('');\n }\n\n if (hasBase || hasSolana) {\n const chainsLabel = [hasBase && baseNetworkName, hasSolana && solanaNetworkName].filter(Boolean).join(' or ');\n const flags = [hasBase && '`--chain base`', hasSolana && '`--chain solana`'].filter(Boolean).join(' or ');\n lines.push(`### Pay with ${chainsLabel}`);\n lines.push('');\n lines.push('```bash');\n lines.push('npm install -g @agent-score/pay');\n lines.push(`agentscore-pay wallet create ${flags}`);\n lines.push(`agentscore-pay balance ${flags} # fund the printed address with USDC`);\n lines.push('');\n lines.push(`agentscore-pay pay POST ${input.appUrl} \\\\`);\n lines.push(` ${hasBase ? '--chain base' : '--chain solana'} \\\\`);\n lines.push(' -H \"X-Operator-Token: opc_...\" \\\\');\n lines.push(\" -d '{...}' \\\\\");\n lines.push(' --max-spend N');\n lines.push('```');\n lines.push('');\n }\n\n if (hasStripe) {\n lines.push('### Pay with Stripe SPT');\n lines.push('');\n lines.push('Mint a SharedPaymentToken scoped to the `profile_id` from the 402 body, then submit via `Authorization: Payment` with `method=stripe/charge`. Either your own Stripe account or `link-cli spend-request create --credential-type shared_payment_token --network-id <profileId> ...` for Stripe Link wallets.');\n lines.push('');\n }\n\n lines.push('IMPORTANT: Use the CLIs above. Raw on-chain transfers (e.g. `tempo wallet transfer`, sending USDC manually to deposit addresses) bypass the protocol handshake and the request will not complete.');\n if (hasBase || hasSolana) {\n lines.push('IMPORTANT: Pay the exact amount in the 402 challenge. Overpayments and underpayments cannot be matched.');\n }\n lines.push('');\n return lines.join('\\n');\n}\n\n/**\n * Assemble a complete llms.txt document. Vendor passes their merchant-specific sections\n * (intro, catalog, endpoints, gift orders, shipping, etc.); the helper adds the AgentScore\n * identity + payment boilerplate at the end. Returns the full markdown string.\n */\nexport function buildLlmsTxt({\n merchantName,\n tagline,\n sections,\n agentscoreIdentity,\n payment,\n}: {\n merchantName: string;\n /** Optional 1-line summary under the title. */\n tagline?: string;\n /** Custom merchant-written sections (intro, endpoints, terms, etc.). */\n sections: { heading: string; content: string }[];\n /** Append the AgentScore identity section. */\n agentscoreIdentity?: Parameters<typeof llmsTxtIdentitySection>[0];\n /** Append the standard payment section. */\n payment?: Parameters<typeof llmsTxtPaymentSection>[0];\n}): string {\n const parts: string[] = [`# ${merchantName}`];\n if (tagline) {\n parts.push(`> ${tagline}`);\n }\n parts.push('');\n for (const s of sections) {\n parts.push(`## ${s.heading}`);\n parts.push('');\n parts.push(s.content);\n parts.push('');\n }\n if (agentscoreIdentity) {\n parts.push(llmsTxtIdentitySection(agentscoreIdentity));\n parts.push('');\n }\n if (payment) {\n parts.push(llmsTxtPaymentSection(payment));\n }\n return parts.join('\\n');\n}\n","/**\n * OpenAPI snippets for AgentScore-related concepts. Vendors plug these into their own\n * OpenAPI 3.1 document (typically /openapi.json) so MPPScan and similar agent registries\n * can validate the merchant's auth + denial schemas correctly.\n *\n * Each helper returns a piece of an OpenAPI document — vendors compose them into their\n * full spec.\n */\n\n/**\n * Standard AgentScore identity security schemes. Plug into `components.securitySchemes`.\n *\n * Includes `siwx` (Sign-In With X) per the x402scan discovery spec so identity-gated\n * operations can declare `security: [{ siwx: [] }]` and stay classified as identity-only,\n * not paid.\n */\nexport function agentscoreSecuritySchemes(): Record<string, unknown> {\n return {\n OperatorToken: {\n type: 'apiKey',\n in: 'header',\n name: 'X-Operator-Token',\n description:\n 'Operator-token-path identity (opc_...). Works on every payment rail; reusable across AgentScore merchants. If both X-Operator-Token and X-Wallet-Address are sent, this one wins.',\n },\n WalletAddress: {\n type: 'apiKey',\n in: 'header',\n name: 'X-Wallet-Address',\n description:\n 'Wallet-path identity (0x... or base58). Only works on rails that carry a wallet signature (Tempo MPP, x402 EIP-3009, x402 SPL Token). The wallet you claim MUST sign the payment.',\n },\n siwx: siwxSecurityScheme(),\n };\n}\n\n/**\n * Sign-In With X security scheme entry, per the x402scan discovery spec.\n *\n * Reference it on identity-gated (but free) operations as\n * `security: [{ siwx: [] }]`. Do NOT also attach `x-payment-info` to those routes,\n * x402scan will misclassify them as paid.\n */\nexport function siwxSecurityScheme(): Record<string, unknown> {\n return {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'SIWX',\n description:\n 'Sign-In With X wallet authentication. Agent signs a challenge with their wallet (any supported chain) and presents the proof in the Authorization header. Used for identity-gated free endpoints; payment-required endpoints declare x-payment-info instead.',\n };\n}\n\n/**\n * Standard AgentScore denial response schemas. Plug into `components.schemas` so OpenAPI\n * validators understand the 403 body shape across denial codes.\n */\nexport function agentscoreDenialSchemas(): Record<string, unknown> {\n return {\n AgentScoreDenialReason: {\n type: 'string',\n enum: [\n 'missing_identity',\n 'identity_verification_required',\n 'token_expired',\n 'invalid_credential',\n 'wallet_signer_mismatch',\n 'wallet_auth_requires_wallet_signing',\n 'wallet_not_trusted',\n 'api_error',\n 'payment_required',\n ],\n description:\n \"Denial code emitted by AgentScore's gate middleware in 403 responses. Every code carries a structured agent_instructions block describing recovery actions (per-code action: missing_identity → probe_identity_then_session, identity_verification_required / token_expired → deliver_verify_url_and_poll, invalid_credential → switch_token_or_restart_session, wallet_signer_mismatch → resign_or_switch_to_operator_token, wallet_auth_requires_wallet_signing → switch_to_operator_token, wallet_not_trusted → contact_support — UNFIXABLE compliance only (sanctions/age/jurisdiction_restricted); fixable reasons re-route to identity_verification_required, payment_required → contact_merchant).\",\n },\n AgentScoreDenialBody: {\n type: 'object',\n properties: {\n error: { $ref: '#/components/schemas/AgentScoreDenialReason' },\n agent_instructions: {\n type: 'string',\n description:\n 'JSON-encoded { action, steps, user_message } block. Always present on every denial; agents parse this to learn how to recover (e.g., poll verify_url, switch headers, re-sign).',\n },\n verify_url: { type: 'string', format: 'uri', description: \"Present for missing_identity / identity_verification_required / token_expired denials. Agent shares this with the user to complete KYC or claim a wallet. Not present on wallet_not_trusted (UNFIXABLE compliance — re-verification won't change the outcome).\" },\n session_id: { type: 'string' },\n poll_url: { type: 'string', format: 'uri' },\n poll_secret: { type: 'string' },\n agent_memory: { type: 'object', description: 'Cross-merchant pattern hint emitted on first-encounter denials.' },\n },\n required: ['error', 'agent_instructions'],\n },\n };\n}\n\n/**\n * Standard 402 PaymentRequired body schema (for AgentScore-extended 402 responses).\n * Includes the rails, identity metadata, agent_instructions, pricing, and x402-compliance\n * fields a typical merchant emits via build402Body.\n */\nexport function agentscorePaymentRequiredSchema(): Record<string, unknown> {\n return {\n AgentScorePaymentRequired: {\n type: 'object',\n properties: {\n payment_required: { type: 'boolean', enum: [true] },\n x402Version: { type: 'integer', enum: [1, 2] },\n accepts: { type: 'array', items: { type: 'object' }, description: 'x402 PaymentRequired.accepts entries.' },\n accepted_methods: {\n type: 'array',\n items: { type: 'object' },\n description: 'MPP method entries (tempo/charge, x402/exact, stripe/charge, ...).',\n },\n amount_usd: { type: 'string' },\n currency: { type: 'string' },\n pricing: {\n type: 'object',\n properties: {\n subtotal: { type: 'string' },\n tax: { type: 'string' },\n tax_rate: { type: 'number' },\n tax_state: { type: 'string' },\n total: { type: 'string' },\n },\n },\n identity_mode: { type: 'string', enum: ['wallet', 'operator_token'] },\n required_signer: { type: 'string' },\n linked_wallets: { type: 'array', items: { type: 'string' } },\n signer_constraint: { type: 'string' },\n agent_instructions: { type: 'object' },\n agent_memory: { type: 'object' },\n },\n },\n };\n}\n\n/**\n * Per-operation `x-payment-info` extension, per the x402scan discovery spec.\n *\n * Every payment-required OpenAPI operation should carry this block alongside a\n * 402 response. Tells discovery crawlers (x402scan, agent CLIs) the static price\n * and which protocols the route accepts. Runtime 402 behavior is authoritative\n * over this static metadata; the static side is for indexability.\n *\n * @example fixed price across x402 + MPP Tempo\n * ```ts\n * Object.assign(operation, {\n * ...xPaymentInfoExtension({\n * price: { mode: 'fixed', currency: 'USD', amount: '0.10' },\n * protocols: [\n * { x402: {} },\n * { mpp: { method: 'tempo/charge', intent: 'pay', currency: 'USD' } },\n * ],\n * }),\n * responses: {\n * '200': {...},\n * '402': { description: 'Payment Required' },\n * },\n * });\n * ```\n */\nexport interface XPaymentInfoFixedPrice {\n mode: 'fixed';\n currency: string;\n amount: string;\n}\n\nexport interface XPaymentInfoDynamicPrice {\n mode: 'dynamic';\n currency: string;\n min: string;\n max: string;\n}\n\nexport type XPaymentInfoPrice = XPaymentInfoFixedPrice | XPaymentInfoDynamicPrice;\n\nexport interface XPaymentInfoX402Protocol {\n x402: Record<string, unknown>;\n}\n\nexport interface XPaymentInfoMppProtocol {\n mpp: { method: string; intent: string; currency?: string; [key: string]: unknown };\n}\n\nexport type XPaymentInfoProtocol = XPaymentInfoX402Protocol | XPaymentInfoMppProtocol;\n\nexport interface XPaymentInfoBlock {\n authMode: 'payment';\n price: XPaymentInfoPrice;\n protocols: XPaymentInfoProtocol[];\n description?: string;\n}\n\nexport function xPaymentInfoExtension({\n price,\n protocols,\n description,\n}: {\n price: XPaymentInfoPrice;\n protocols: XPaymentInfoProtocol[];\n description?: string;\n}): { 'x-payment-info': XPaymentInfoBlock } {\n return {\n 'x-payment-info': {\n authMode: 'payment',\n price,\n protocols,\n ...(description !== undefined && { description }),\n },\n };\n}\n\n/**\n * `info.x-guidance` extension, per the x402scan discovery spec. Spread into your\n * OpenAPI document's `info` block to give agents a high-level prose description\n * of how to use the API. Discovery crawlers surface this on the listing page.\n *\n * @example\n * ```ts\n * const spec = {\n * openapi: '3.1.0',\n * info: {\n * title: 'My Merchant API',\n * version: '1.0',\n * ...xGuidanceExtension('Wine merchant. POST /purchase with a verified operator token...'),\n * },\n * };\n * ```\n */\nexport function xGuidanceExtension(text: string): { 'x-guidance': string } {\n return { 'x-guidance': text };\n}\n\n/**\n * `x-service-info` extension for the OpenAPI document's root. Discovery\n * crawlers (x402scan, agent CLIs) read this to categorize the service and\n * follow links to human-side docs. Spread into the OpenAPI doc's root\n * alongside `paths`, `info`, etc.\n *\n * @example\n * ```ts\n * const spec = {\n * openapi: '3.1.0',\n * info: {...},\n * ...xServiceInfoExtension({\n * categories: ['commerce', 'wine'],\n * docs: { homepage: 'https://www.martinestate.com', llms: 'https://agents.martinestate.com/llms.txt' },\n * }),\n * paths: {...},\n * };\n * ```\n */\nexport function xServiceInfoExtension(opts: {\n categories: string[];\n docs?: Record<string, string>;\n}): { 'x-service-info': { categories: string[]; docs?: Record<string, string> } } {\n return {\n 'x-service-info': {\n categories: opts.categories,\n ...(opts.docs !== undefined && { docs: opts.docs }),\n },\n };\n}\n\n/**\n * Derive an `x-payment-info` extension from a configured `Checkout` instance.\n *\n * Walks `checkout.rails` and emits one entry in `protocols[]` per rail —\n * Tempo MPP, x402 (Base), Solana MPP, Stripe SPT. Saves merchants from\n * enumerating protocols by hand and keeps the OpenAPI doc in sync with the\n * actual rails the Checkout serves.\n *\n * `price` is merchant-supplied (the rail registry doesn't carry per-merchant\n * pricing; rates live on each Checkout's `computePricing` hook). Per-rail\n * extras (client commands, asset names) can be merged via `protocolExtras`\n * keyed by rail slug (`tempo`, `base`, `solana`, `stripe`).\n */\nexport function xPaymentInfoFromCheckout(opts: {\n checkout: {\n rails: Record<\n string,\n { network?: string; recipient?: unknown; currency?: unknown; token?: unknown; profileId?: unknown }\n >;\n };\n price: XPaymentInfoPrice;\n description?: string;\n protocolExtras?: Partial<{\n tempo: Record<string, unknown>;\n base: Record<string, unknown>;\n solana: Record<string, unknown>;\n stripe: Record<string, unknown>;\n }>;\n}): { 'x-payment-info': XPaymentInfoBlock } {\n const protocols: XPaymentInfoProtocol[] = [];\n const extras = opts.protocolExtras ?? {};\n for (const spec of Object.values(opts.checkout.rails)) {\n const isStripe = !('recipient' in spec);\n const network = typeof spec.network === 'string' ? spec.network : '';\n // MPP protocols emit `currency` = on-chain token contract (Tempo USDC.e\n // address, Solana USDC mint). `spec.currency` wins when set explicitly;\n // `spec.token` is the RailSpec canonical name and is the typical source.\n const tokenCurrency =\n (typeof spec.currency === 'string' ? spec.currency : '') ||\n (typeof spec.token === 'string' ? spec.token : '');\n if (isStripe) {\n protocols.push({ mpp: { method: 'stripe', intent: 'charge', currency: 'usd', ...(extras.stripe ?? {}) } });\n } else if (network.startsWith('eip155:')) {\n protocols.push({\n x402: {\n scheme: 'exact',\n network: 'base',\n asset: 'USDC',\n ...(extras.base ?? {}),\n },\n });\n } else if (network.startsWith('solana:')) {\n // Per MPP solana/charge spec (paymentauth.org/draft-solana-charge-00):\n // `currency` = SPL mint address (base58) for tokens, `\"sol\"` for native.\n // No `asset` field in the spec — token symbols are not part of the\n // discovery contract.\n protocols.push({\n mpp: {\n method: 'solana',\n intent: 'charge',\n ...(tokenCurrency ? { currency: tokenCurrency } : {}),\n ...(extras.solana ?? {}),\n },\n });\n } else {\n protocols.push({\n mpp: {\n method: 'tempo',\n intent: 'charge',\n ...(tokenCurrency ? { currency: tokenCurrency } : {}),\n ...(extras.tempo ?? {}),\n },\n });\n }\n }\n return xPaymentInfoExtension({\n price: opts.price,\n protocols,\n ...(opts.description !== undefined && { description: opts.description }),\n });\n}\n\n/**\n * Convenience: returns a `components` snippet ready to merge into an OpenAPI document.\n *\n * const spec = {\n * openapi: '3.1.0',\n * info: { title: 'My Merchant API', version: '1.0' },\n * paths: {...},\n * components: { ...agentscoreOpenApiSnippets(), schemas: { ...mySchemas, ...agentscoreOpenApiSnippets().schemas } },\n * };\n *\n * Or more idiomatically: `Object.assign(spec.components, agentscoreOpenApiSnippets())`.\n */\nexport function agentscoreOpenApiSnippets({\n security = true,\n denials = true,\n paymentRequired = true,\n}: {\n /** Include security schemes in the snippet. Default true. */\n security?: boolean;\n /** Include denial schemas in the snippet. Default true. */\n denials?: boolean;\n /** Include the 402 PaymentRequired schema in the snippet. Default true. */\n paymentRequired?: boolean;\n} = {}): { securitySchemes?: Record<string, unknown>; schemas?: Record<string, unknown> } {\n const out: { securitySchemes?: Record<string, unknown>; schemas?: Record<string, unknown> } = {};\n if (security) {\n out.securitySchemes = agentscoreSecuritySchemes();\n }\n if (denials || paymentRequired) {\n out.schemas = {\n ...(denials ? agentscoreDenialSchemas() : {}),\n ...(paymentRequired ? agentscorePaymentRequiredSchema() : {}),\n };\n }\n return out;\n}\n","/**\n * Default discovery paths emitted by `@agent-score/commerce` builders. These are\n * the public-by-design endpoints agents and crawlers fetch to learn the\n * merchant's shape: OpenAPI, llms.txt, MPP well-known, A2A agent card, UCP profile.\n * They should NOT carry `X-Robots-Tag: noindex` since the whole point is for\n * agents (and search/discovery crawlers) to find them.\n *\n * Everything else on an agent-only API should noindex by default — there's no\n * human-shaped HTML to surface to general search engines, and accidental\n * indexing leaks transactional endpoints into noisy SERPs.\n */\nexport const defaultDiscoveryPaths: ReadonlySet<string> = new Set([\n '/openapi.json',\n '/llms.txt',\n '/skill.md',\n '/SKILL.md',\n '/.well-known/mpp.json',\n '/.well-known/x402',\n '/.well-known/agent-card.json',\n '/.well-known/ucp',\n '/.well-known/jwks.json',\n '/favicon.png',\n '/favicon.ico',\n]);\n\n/**\n * Pure predicate for \"is this path a known discovery surface?\". Compose this\n * into your own framework's middleware when you don't want the bundled Hono\n * wrapper. Custom paths are the union with the defaults — pass `replace: true`\n * to skip the defaults.\n */\nexport function isDiscoveryPath(\n path: string,\n options?: { customPaths?: Iterable<string>; replace?: boolean },\n): boolean {\n if (options?.replace) {\n return new Set(options.customPaths ?? []).has(path);\n }\n if (defaultDiscoveryPaths.has(path)) return true;\n if (options?.customPaths) {\n for (const p of options.customPaths) if (p === path) return true;\n }\n return false;\n}\n\ninterface NoindexNonDiscoveryOptions {\n /** Additional discovery paths beyond the defaults (e.g. `/sitemap.xml`,\n * `/.well-known/foo`). Merged with the defaults unless `replacePaths: true`. */\n customPaths?: Iterable<string>;\n /** When true, ignore the bundled defaults and only treat `customPaths` as\n * discovery surfaces. Use when the merchant deliberately chooses a different\n * set (e.g. omits `/openapi.json` from a closed API). */\n replacePaths?: boolean;\n /** Override the X-Robots-Tag value applied to non-discovery paths. Defaults to\n * the standard \"noindex, nofollow, noarchive, nosnippet\" tuple — change only\n * if you have a very specific crawl-shape requirement. */\n robotsTag?: string;\n}\n\nconst DEFAULT_ROBOTS_TAG = 'noindex, nofollow, noarchive, nosnippet';\n\n/** Predicate the per-framework wrappers share. Pulled out so non-listed frameworks\n * can compose it directly (`if (!shouldNoindex(path, opts)) ...`). */\nfunction shouldNoindex(path: string, customSet: Set<string> | undefined, replacePaths: boolean | undefined): boolean {\n const isDiscovery = replacePaths\n ? (customSet?.has(path) ?? false)\n : defaultDiscoveryPaths.has(path) || (customSet?.has(path) ?? false);\n return !isDiscovery;\n}\n\n/**\n * Hono middleware. Mount globally near the top of your middleware stack:\n *\n * app.use('*', noindexNonDiscoveryPaths());\n * app.use('*', noindexNonDiscoveryPaths({ customPaths: ['/sitemap.xml'] }));\n *\n * Per-framework variants (`noindexNonDiscoveryPathsExpress`,\n * `noindexNonDiscoveryPathsFastify`, `noindexNonDiscoveryPathsWeb`) ship below.\n * For Next.js Route Handlers, use `applyNoindexHeader(response, path, opts)`\n * inline since route handlers don't have a global mount point.\n */\nexport function noindexNonDiscoveryPaths(options?: NoindexNonDiscoveryOptions) {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n return async (c: { req: { path: string }; header: (k: string, v: string) => void }, next: () => Promise<void>) => {\n await next();\n if (shouldNoindex(c.req.path, customSet, options?.replacePaths)) {\n c.header('X-Robots-Tag', robotsTag);\n }\n };\n}\n\n/** Express middleware. Sets the header before `next()` so route handlers can\n * override per-response if they need to. */\nexport function noindexNonDiscoveryPathsExpress(options?: NoindexNonDiscoveryOptions) {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n return (\n req: { path: string },\n res: { setHeader: (name: string, value: string) => void },\n next: () => void,\n ) => {\n if (shouldNoindex(req.path, customSet, options?.replacePaths)) {\n res.setHeader('X-Robots-Tag', robotsTag);\n }\n next();\n };\n}\n\n/** Fastify plugin (use as `app.register(noindexNonDiscoveryPathsFastify, opts)`).\n * Registers an `onRequest` hook so the header lands on every response. */\ninterface FastifyReqLike { url?: string; routerPath?: string }\ninterface FastifyReplyLike { header: (name: string, value: string) => void }\ninterface FastifyAppLike {\n addHook(event: 'onRequest', handler: (req: FastifyReqLike, reply: FastifyReplyLike, done: () => void) => void): void;\n}\nexport function noindexNonDiscoveryPathsFastify(\n app: FastifyAppLike,\n options: NoindexNonDiscoveryOptions | undefined,\n done: () => void,\n): void {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n app.addHook('onRequest', (req, reply, hookDone) => {\n const path = (req.url ?? req.routerPath ?? '').split('?')[0];\n if (shouldNoindex(path, customSet, options?.replacePaths)) {\n reply.header('X-Robots-Tag', robotsTag);\n }\n hookDone();\n });\n done();\n}\n\n/** Web Fetch / Cloudflare Workers / Deno / Bun helper. Returns a wrapped\n * Response that carries `X-Robots-Tag` on non-discovery paths. Pair with the\n * request's URL pathname:\n *\n * return wrapNoindexResponse(new URL(req.url).pathname, response);\n */\nexport function wrapNoindexResponse(\n path: string,\n response: Response,\n options?: NoindexNonDiscoveryOptions,\n): Response {\n const customSet = options?.customPaths ? new Set(options.customPaths) : undefined;\n const robotsTag = options?.robotsTag ?? DEFAULT_ROBOTS_TAG;\n if (!shouldNoindex(path, customSet, options?.replacePaths)) return response;\n const headers = new Headers(response.headers);\n headers.set('X-Robots-Tag', robotsTag);\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n}\n\n/** Next.js Route Handler helper. Call inline before returning the Response:\n *\n * export async function POST(req: Request) {\n * const path = new URL(req.url).pathname;\n * const res = Response.json({...});\n * return applyNoindexHeader(res, path);\n * }\n *\n * Same wrapper shape as the Web Fetch helper — exported separately for clarity\n * in Next.js docs/examples. */\nexport const applyNoindexHeader = wrapNoindexResponse;\n","import type { HowToPayBlock } from './how_to_pay';\n\n/** Map of rail key (e.g. 'x402_base', 'tempo_mpp', 'stripe') → list of client identifiers\n * that have been smoke-verified by the merchant against the protocol shape they emit.\n * Strings are display labels, not install commands — agents already get install commands\n * via `how_to_pay.<rail>.setup`. Use these as a \"what's known to work\" hint. */\nexport type CompatibleClients = Record<string, string[]>;\n\n\nexport interface AgentInstructions {\n how_to_pay: HowToPayBlock;\n recommended_tools: string[];\n wallet_compatibility: string;\n timeout_seconds: number;\n warnings: string[];\n recommended?: string;\n compatible_clients?: CompatibleClients;\n [key: string]: unknown;\n}\n\nconst TEMPO_WARNING =\n 'Do NOT use `tempo wallet transfer`. That moves USDC on-chain without completing the protocol handshake, so the request will not complete. Use `tempo request` instead.';\n\nconst X402_WARNING =\n 'Do NOT send USDC manually to the deposit addresses. Use `agentscore-pay pay` so the credential is signed and submitted; otherwise the request will not complete even though the deposit lands.';\n\nconst TEMPO_TOOL = '`tempo request` for Tempo USDC';\nconst AGENTSCORE_PAY_TOOL = '`agentscore-pay` — Base + Solana + Tempo from one CLI';\n\nconst DEFAULT_WALLET_COMPATIBILITY =\n 'Any client that can produce a valid MPP credential (Authorization: Payment) or x402 X-Payment header. Use the CLI commands above; sign-it-yourself is also fine.';\n\nfunction defaultRecommendedTools(howToPay: HowToPayBlock): string[] {\n const tools: string[] = [];\n if (howToPay.tempo) tools.push(TEMPO_TOOL);\n if (howToPay.tempo || howToPay.x402_base || howToPay.solana_mpp) tools.push(AGENTSCORE_PAY_TOOL);\n return tools;\n}\n\nfunction defaultWarnings(howToPay: HowToPayBlock): string[] {\n const w: string[] = [];\n if (howToPay.tempo) w.push(TEMPO_WARNING);\n if (howToPay.x402_base) w.push(X402_WARNING);\n return w;\n}\n\n/**\n * Default `compatible_clients` derived from the rails declared in `howToPay`. Lists\n * clients the AgentScore team has smoke-verified end-to-end against an `@agent-score/commerce`\n * merchant; entries appear only for rails the vendor actually offers. Vendors override\n * this in `buildAgentInstructions({compatibleClients: {...}})` to add their own tested\n * clients or remove entries that don't fit their endpoint.\n *\n * Verified state as of the SDK release. The same data is also published as a docs page\n * for humans (rationale, per-rail commands, why some clients don't fully work, last\n * verified date) — this default keeps the merchant-side surface in sync.\n */\n/** Symbolic rail keys agent-facing surfaces use to talk about a rail without spelling out\n * network/scheme details. Same keys as `CompatibleClients` map keys. */\nexport type RailKey = 'tempo_mpp' | 'x402_base' | 'solana_mpp' | 'stripe';\n\nconst RAIL_CLIENTS: Record<RailKey, readonly string[]> = {\n tempo_mpp: ['agentscore-pay', 'tempo request', 'x402-proxy'],\n x402_base: ['agentscore-pay', 'x402-proxy', 'purl (omit --network flag)'],\n solana_mpp: ['agentscore-pay'],\n stripe: ['link-cli'],\n};\n\n/** Returns the smoke-verified client list for a set of rail keys. The single source of\n * truth for \"which CLIs we've verified end-to-end on each rail\" — consumed both by the\n * 402-body builder (`defaultCompatibleClients`) and by discovery surfaces (skill.md,\n * llms.txt, etc.). Update here, every surface inherits. */\nexport function compatibleClientsByRails(rails: readonly RailKey[]): CompatibleClients | undefined {\n const out: CompatibleClients = {};\n for (const r of rails) out[r] = [...RAIL_CLIENTS[r]];\n return Object.keys(out).length === 0 ? undefined : out;\n}\n\nfunction defaultCompatibleClients(howToPay: HowToPayBlock): CompatibleClients | undefined {\n const rails: RailKey[] = [];\n if (howToPay.tempo) rails.push('tempo_mpp');\n if (howToPay.x402_base) rails.push('x402_base');\n if (howToPay.solana_mpp) rails.push('solana_mpp');\n if (howToPay.stripe) rails.push('stripe');\n return compatibleClientsByRails(rails);\n}\n\n/**\n * Build the agent_instructions object for the 402 body. Combines how_to_pay with\n * recommended tools, warnings, wallet-compatibility note, and timeout.\n *\n * Defaults adapt to the rails declared in `howToPay`: only tempo-relevant warnings/tools\n * appear if `howToPay.tempo` is set, only x402-relevant ones if `x402_base` is set.\n * Stripe-only merchants get neither rail-specific warning. Vendors override\n * `warnings`/`recommendedTools` for full control.\n */\nexport function buildAgentInstructions({\n howToPay,\n recommendedTools,\n walletCompatibility,\n timeoutSeconds,\n warnings,\n extraWarnings,\n recommended,\n compatibleClients,\n extra,\n}: {\n /** Per-rail commands. Build with `buildHowToPay`. */\n howToPay: HowToPayBlock;\n /** Tool recommendations as human-readable strings. Defaults to a sensible set covering tempo + agentscore-pay. */\n recommendedTools?: string[];\n /** Wallet-stack compatibility note for the agent. Default: rail-neutral, no specific wallet stack required. */\n walletCompatibility?: string;\n /** How long the merchant will wait for payment after the 402. Default 300 (5 minutes). */\n timeoutSeconds?: number;\n /** Warnings about common footguns. Defaults include tempo wallet transfer + raw on-chain x402 deposits. */\n warnings?: string[];\n /** Additional warnings appended to the default protocol-footgun set. Use this when you want\n * to keep the SDK's protocol warnings AND add merchant-specific notes. Ignored when\n * `warnings` is set explicitly. */\n extraWarnings?: string[];\n /** Recommended rail (e.g., 'tempo', 'x402_base'). Surfaced for agents to default to. */\n recommended?: string;\n /** Per-rail list of client names the merchant has verified work end-to-end. Vendors set\n * this from their own smoke matrix — defaults to none. When omitted, the field is not emitted. */\n compatibleClients?: CompatibleClients;\n /** Arbitrary additional fields the vendor wants merged into the agent_instructions object. */\n extra?: Record<string, unknown>;\n}): AgentInstructions {\n const compatibleClientsOut = compatibleClients ?? defaultCompatibleClients(howToPay);\n return {\n how_to_pay: howToPay,\n recommended_tools: recommendedTools ?? defaultRecommendedTools(howToPay),\n wallet_compatibility: walletCompatibility ?? DEFAULT_WALLET_COMPATIBILITY,\n timeout_seconds: timeoutSeconds ?? 300,\n warnings: warnings ?? [...defaultWarnings(howToPay), ...(extraWarnings ?? [])],\n ...(recommended ? { recommended } : {}),\n ...(compatibleClientsOut ? { compatible_clients: compatibleClientsOut } : {}),\n ...(extra ?? {}),\n };\n}\n","import { compatibleClientsByRails } from '../challenge/agent_instructions';\nimport type { CompatibleClients, RailKey } from '../challenge/agent_instructions';\n\nexport type { CompatibleClients, RailKey } from '../challenge/agent_instructions';\nexport { compatibleClientsByRails } from '../challenge/agent_instructions';\n\nexport interface SkillMdEndpoint {\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n path: string;\n authRequired: boolean;\n description: string;\n}\n\nexport interface SkillMdIdentityRequirements {\n /** Whether KYC is required for gated routes. */\n kycRequired?: boolean;\n /** Minimum age (e.g. 21 for alcohol). */\n minAge?: number;\n /** Allowed-jurisdictions list (ISO 3166-1 alpha-2 country codes). */\n allowedJurisdictions?: string[];\n /** Whether sanctions screening is enforced. */\n sanctionsClear?: boolean;\n}\n\n/** PHYSICAL-GOODS-ONLY. Shipping-policy block for skill.md. Digital goods and\n * API merchants skip this (the `shipping?:` field on BuildSkillMdInput is\n * optional). */\nexport interface SkillMdShippingPolicy {\n /** Allowed shipping countries (ISO 3166-1 alpha-2). */\n allowedCountries?: string[];\n /** Blocked US states (2-letter codes). */\n blockedStates?: string[];\n}\n\nexport interface SkillMdLink {\n label: string;\n url: string;\n}\n\ninterface BuildSkillMdInput {\n /** Skill manifest identifier — kebab-case per agentskills.io spec: 1-64 chars, lowercase\n * alphanumeric + hyphens, no leading/trailing/consecutive hyphens. Validated at build\n * time; invalid names throw. e.g. 'example-merchant-commerce'. */\n name: string;\n /** Skill description — agentskills.io spec: 1-1024 chars, non-empty. Should describe both\n * what the skill does AND when to use it; imperative phrasing recommended (\"Use when…\").\n * Validated at build time; over-length throws. */\n description: string;\n /** Merchant homepage (or domain root). Emitted as `metadata.homepage` per spec\n * (top-level non-spec fields go under metadata). */\n homepage: string;\n /** Skill schema version — increment when the skill body materially changes. Emitted as\n * a quoted string under `metadata.version` per agentskills.io spec (metadata values\n * must be strings). Accepts string or number; numbers are converted. Default \"1\". */\n version?: string | number;\n\n /** Optional license name or path to a bundled license file. Emitted as top-level\n * frontmatter `license:` per spec. */\n license?: string;\n /** Optional environment-requirements note (max 500 chars). e.g. \"Requires Node 20+\".\n * Emitted as top-level frontmatter `compatibility:` per spec. */\n compatibility?: string;\n /** Optional space-separated string of pre-approved tools (experimental per spec). */\n allowedTools?: string;\n /** Additional caller-defined metadata entries — flat key/value strings nested under\n * `metadata:`. Spec requires string values. */\n metadata?: Record<string, string | number>;\n\n /** Human display name (e.g. \"Example Merchant\"). */\n merchantName: string;\n /** Optional one-line tagline appearing under the title. */\n tagline?: string;\n /** Optional short prose intro describing what the merchant offers. Renders below the title. */\n intro?: string;\n\n /** Files / well-known URLs surfaced under the \"Important Files\" table. The skill.md URL\n * itself is added automatically — list other discovery surfaces (llms.txt, mpp.json,\n * openapi.json, agent-card.json). */\n files?: SkillMdLink[];\n\n /** Rails the merchant accepts. Drives the Payment + Compatible Clients sections. Order\n * is preserved in render. Default to the rails actually declared on the merchant's\n * `respond402` config — keep these in sync. */\n acceptedRails: RailKey[];\n /** Override the per-rail compatible-clients matrix. When omitted, derives from\n * `acceptedRails` via the SDK's smoke-verified default. Override keys not in\n * `acceptedRails` are dropped (the rail isn't accepted, so the row isn't rendered). */\n compatibleClients?: CompatibleClients;\n\n /** Identity requirements as agent-observable outcomes (kyc / age / jurisdiction /\n * sanctions). Internal posture (`failOpen`, mount strategy, KYC vendor) is intentionally\n * not part of this shape — agents act on outcomes, not implementation. */\n identity?: SkillMdIdentityRequirements;\n /** URL to the identity-bootstrap skill. Linked from the Identity Prerequisite section\n * so an agent without a Passport can follow the bootstrap before attempting purchase. */\n identityBootstrapUrl?: string;\n\n /** Shipping policy, for physical-goods merchants. Omit for digital merchants. */\n shipping?: SkillMdShippingPolicy;\n\n /** Agent-facing endpoints — path, method, whether auth is required, brief purpose. */\n endpoints: SkillMdEndpoint[];\n\n /** When this skill should fire (skill loader uses for trigger matching). */\n triggers: string[];\n\n /** Optional numbered onboarding steps. Each entry renders as a numbered list item;\n * may include shell snippets in markdown code fences. */\n onboardingSteps?: string[];\n\n /** Support / homepage / docs links rendered in the \"Support\" section. */\n supportLinks?: SkillMdLink[];\n\n /** When true (default), append a footer noting clients can refresh skill.md to pick\n * up new endpoints. Set to false to suppress. */\n refreshFooter?: boolean;\n}\n\nconst RAIL_LABELS: Record<RailKey, string> = {\n tempo_mpp: 'MPP on Tempo',\n x402_base: 'x402 on Base',\n solana_mpp: 'MPP on Solana',\n stripe: 'Stripe Shared Payment Token',\n};\n\nconst RAIL_NOTES: Record<RailKey, string> = {\n tempo_mpp: 'USDC. Use `agentscore-pay pay --chain tempo` (or `tempo request`); MPP credential goes in `Authorization: Payment`.',\n x402_base: 'USDC (EIP-3009). Use `agentscore-pay pay --chain base`; X-Payment header carries the signed credential.',\n solana_mpp: 'USDC (SPL). Use `agentscore-pay pay --chain solana`; MPP credential goes in `Authorization: Payment`.',\n stripe: 'Card via Link wallet. Use `@stripe/link-cli` — `agentscore-pay` emits the handoff hint when this rail is picked.',\n};\n\nconst NAME_RE = /^[a-z0-9]+(-[a-z0-9]+)*$/;\nconst NAME_MAX = 64;\nconst DESCRIPTION_MAX = 1024;\nconst COMPATIBILITY_MAX = 500;\n\nfunction validateInput(input: BuildSkillMdInput): void {\n if (!input.name || input.name.length === 0 || input.name.length > NAME_MAX) {\n throw new Error(`buildSkillMd: name must be 1-${NAME_MAX} characters (got ${input.name?.length ?? 0})`);\n }\n if (!NAME_RE.test(input.name)) {\n throw new Error(\n `buildSkillMd: name \"${input.name}\" is invalid — must be lowercase alphanumeric and hyphens, no leading/trailing/consecutive hyphens (agentskills.io spec)`,\n );\n }\n if (!input.description || input.description.length === 0) {\n throw new Error('buildSkillMd: description is required and must be non-empty (agentskills.io spec)');\n }\n if (input.description.length > DESCRIPTION_MAX) {\n throw new Error(\n `buildSkillMd: description must be ≤${DESCRIPTION_MAX} characters (got ${input.description.length})`,\n );\n }\n if (input.compatibility && input.compatibility.length > COMPATIBILITY_MAX) {\n throw new Error(\n `buildSkillMd: compatibility must be ≤${COMPATIBILITY_MAX} characters (got ${input.compatibility.length})`,\n );\n }\n}\n\n/** Quote a value as a YAML double-quoted scalar — escape `\\\\`, `\"`, and newlines. The\n * agentskills.io spec calls out unquoted colons in `description` as the most common\n * parse failure across clients; emit every user-supplied scalar quoted to be safe. */\nfunction quoteYaml(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n')}\"`;\n}\n\n/** Sanitize a string for inclusion in a markdown table cell — escape backslashes first\n * (so existing `\\` aren't treated as escapes), then escape pipes (which would otherwise\n * terminate the cell). */\nfunction tableCell(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/\\|/g, '\\\\|');\n}\n\nfunction frontmatter(input: BuildSkillMdInput): string {\n const lines: string[] = ['---'];\n lines.push(`name: ${input.name}`);\n lines.push(`description: ${quoteYaml(input.description)}`);\n if (input.license) lines.push(`license: ${quoteYaml(input.license)}`);\n if (input.compatibility) lines.push(`compatibility: ${quoteYaml(input.compatibility)}`);\n if (input.allowedTools) lines.push(`allowed-tools: ${quoteYaml(input.allowedTools)}`);\n\n const meta: Array<[string, string]> = [];\n meta.push(['version', String(input.version ?? '1')]);\n meta.push(['homepage', input.homepage]);\n for (const [k, v] of Object.entries(input.metadata ?? {})) {\n if (k === 'version' || k === 'homepage') continue;\n meta.push([k, String(v)]);\n }\n lines.push('metadata:');\n for (const [k, v] of meta) {\n lines.push(` ${k}: ${quoteYaml(v)}`);\n }\n lines.push('---');\n return lines.join('\\n');\n}\n\nfunction importantFiles(input: BuildSkillMdInput): string {\n const skillUrl = `${input.homepage.replace(/\\/$/, '')}/skill.md`;\n const rows: string[] = [\n '| File | URL |',\n '|------|-----|',\n `| **SKILL.md** (this file) | \\`${skillUrl}\\` |`,\n ];\n for (const f of input.files ?? []) {\n rows.push(`| ${tableCell(f.label)} | \\`${tableCell(f.url)}\\` |`);\n }\n return ['## Important Files', '', ...rows].join('\\n');\n}\n\nfunction paymentSection(input: BuildSkillMdInput): string {\n const override = input.compatibleClients;\n const defaults = compatibleClientsByRails(input.acceptedRails) ?? {};\n // Override entries only apply to rails actually accepted; ignore stragglers.\n const clients: CompatibleClients = {};\n for (const r of input.acceptedRails) {\n clients[r] = override?.[r] ?? defaults[r] ?? [];\n }\n const rows: string[] = ['| Rail | Notes | Compatible clients |', '|---|---|---|'];\n for (const r of input.acceptedRails) {\n const list = (clients[r] ?? []).join(', ') || '—';\n rows.push(`| **${RAIL_LABELS[r]}** | ${RAIL_NOTES[r]} | ${list} |`);\n }\n return [\n '## Payment',\n '',\n 'Each gated route returns a 402 with `WWW-Authenticate` + `PAYMENT-REQUIRED` body listing the rails below with current pricing. Pick whichever your wallet is funded for.',\n '',\n ...rows,\n ].join('\\n');\n}\n\nfunction identitySection(input: BuildSkillMdInput): string {\n const id = input.identity;\n if (!id) return '';\n const reqs: string[] = [];\n if (id.kycRequired) reqs.push('KYC verified Passport');\n if (id.minAge) reqs.push(`age ${id.minAge}+`);\n if (id.allowedJurisdictions?.length) reqs.push(`${id.allowedJurisdictions.join('/')} only`);\n if (id.sanctionsClear) reqs.push('sanctions clear');\n if (reqs.length === 0) return '';\n const bootstrap = input.identityBootstrapUrl\n ? `\\n\\nIf you don't have a Passport, fetch \\`${input.identityBootstrapUrl}\\` and follow the onboarding there first. Bring back the \\`opc_...\\` operator token in \\`X-Operator-Token\\` on every gated request.`\n : '';\n return [\n '## Identity Prerequisite',\n '',\n `This merchant uses AgentScore identity. Required: ${reqs.join(', ')}.${bootstrap}`,\n '',\n 'Denial bodies carry an `agent_instructions` block describing the recovery action — read the `action` field and follow it. See the identity-bootstrap skill for the canonical denial-code → action table.',\n ].join('\\n');\n}\n\nfunction shippingSection(input: BuildSkillMdInput): string {\n const s = input.shipping;\n if (!s || (!s.allowedCountries?.length && !s.blockedStates?.length)) return '';\n const lines: string[] = ['## Shipping', ''];\n if (s.allowedCountries?.length) {\n lines.push(`Ships to: ${s.allowedCountries.join(', ')}.`);\n }\n if (s.blockedStates?.length) {\n if (lines.length > 2) lines.push('');\n lines.push(`Blocked US states: ${s.blockedStates.join(', ')}.`);\n }\n return lines.join('\\n');\n}\n\nfunction endpointsSection(input: BuildSkillMdInput): string {\n if (input.endpoints.length === 0) return '';\n const rows = ['| Method | Path | Auth | Purpose |', '|---|---|---|---|'];\n for (const e of input.endpoints) {\n rows.push(\n `| ${e.method} | \\`${tableCell(e.path)}\\` | ${e.authRequired ? 'identity required' : 'anonymous'} | ${tableCell(e.description)} |`,\n );\n }\n return ['## Endpoints', '', ...rows].join('\\n');\n}\n\nfunction onboardingSection(input: BuildSkillMdInput): string {\n if (!input.onboardingSteps?.length) return '';\n const rows = input.onboardingSteps.map((step, i) => `${i + 1}. ${step}`);\n return ['## Onboarding Flow', '', ...rows].join('\\n');\n}\n\nfunction triggersSection(input: BuildSkillMdInput): string {\n if (input.triggers.length === 0) return '';\n const rows = input.triggers.map((t) => `- ${t}`);\n return ['## Triggers', '', 'Use this skill when the user wants to:', '', ...rows].join('\\n');\n}\n\nfunction supportSection(input: BuildSkillMdInput): string {\n if (!input.supportLinks?.length) return '';\n const rows = input.supportLinks.map((l) => `- **${l.label}**: ${l.url}`);\n return ['## Support', '', ...rows].join('\\n');\n}\n\nfunction refreshFooter(input: BuildSkillMdInput): string {\n if (input.refreshFooter === false) return '';\n return '_Re-fetch this file periodically to pick up new endpoints, rails, or policies._';\n}\n\nfunction titleBlock(input: BuildSkillMdInput): string {\n const parts: string[] = [`# ${input.merchantName}`];\n if (input.tagline) parts.push(`_${input.tagline}_`);\n if (input.intro) parts.push(input.intro);\n return parts.join('\\n\\n');\n}\n\n/**\n * Render an agentskills.io-compatible `skill.md` for an agent-commerce merchant.\n *\n * Output is YAML frontmatter (`name` / `description` / optional `license` /\n * `compatibility` / `allowed-tools` / `metadata`) followed by markdown sections\n * describing payment rails, identity requirements, endpoints, triggers, and support\n * links — strictly the agent-facing contract, with no internal posture (no `failOpen`,\n * no mount-strategy names, no KYC vendor, no defense parameters).\n *\n * Spec compliance:\n * - `name` validated against the agentskills.io regex (lowercase alphanumeric + hyphens,\n * no leading/trailing/consecutive hyphens, ≤64 chars).\n * - `description` length capped at 1024.\n * - `metadata` values always emitted as quoted strings.\n * - `description` (and other user scalars) double-quoted to defuse the colon /\n * newline / quote pitfall the spec explicitly warns about.\n *\n * The compatible-clients-per-rail table sources from the same SDK constant\n * (`compatibleClientsByRails`) that drives the live 402 body's `compatible_clients`\n * field, so updating a smoke-verified client in one place propagates to every surface.\n */\nexport function buildSkillMd(input: BuildSkillMdInput): string {\n validateInput(input);\n // Helpers downstream receive the typed input object; the type is internal-only so the\n // public surface is destructured-kwargs from the caller's perspective (vendors pass object\n // literals, identical to the rest of the SDK's builders).\n const sections = [\n frontmatter(input),\n titleBlock(input),\n importantFiles(input),\n identitySection(input),\n paymentSection(input),\n shippingSection(input),\n onboardingSection(input),\n endpointsSection(input),\n triggersSection(input),\n supportSection(input),\n refreshFooter(input),\n ].filter((s) => s !== '');\n return sections.join('\\n\\n').replace(/\\n{3,}/g, '\\n\\n').trim() + '\\n';\n}\n","/**\n * Standard agent-facing prose for AgentScore-gated merchants.\n *\n * Every AgentScore merchant emits roughly the same skill.md onboarding steps,\n * catalog purchase-mode notes, and endpoint descriptions. These helpers ship\n * those canonical strings so merchants supply only the merchant-specific parts\n * (name, URL, accepted rails) and get consistent agent-facing content back.\n *\n * Rationale: agents that hit one AgentScore merchant should see the same\n * pattern hints at every other one. Custom prose per merchant adds noise\n * without adding information; the SDK owns the cross-merchant boilerplate so\n * it stays consistent.\n */\n\n/**\n * Whether a paid surface accepts redemption codes. Applies to any merchant\n * that bills per-purchase or per-call — goods (catalog rows) and API\n * (per-endpoint or per-tier billing) both use this enum.\n */\nexport type PurchaseMode = 'redemption_only' | 'coupon_applicable' | 'paid_only';\n\n/**\n * Canonical agent-facing notes for each `purchase_mode`. Surface this in\n * /catalog rows (goods) or in `x-service-info` / `/llms.txt` (API) so agents\n * know whether to expect a `redemption_code` field in the request body.\n */\nexport const PURCHASE_MODE_NOTES: Readonly<Record<string, string>> = Object.freeze({\n redemption_only:\n 'Requires a single-use redemption code (printed on a mailer or other ' +\n 'out-of-band delivery). Submit the code in the request body as ' +\n '`redemption_code`. Without a valid code the order is rejected.',\n coupon_applicable:\n 'Codes are optional. Without one, settle at list price. With a valid ' +\n 'code the discount is applied automatically (percent_off, fixed_off, ' +\n 'or fixed_settle).',\n paid_only:\n 'Codes are NOT accepted. Settle at the listed price. Submitting a ' +\n '`redemption_code` field returns 400 codes_not_accepted.',\n});\n\n/**\n * Canonical agent-facing note for a `purchase_mode`. Falls back to an empty\n * string for unknown modes so responses don't leak `undefined` when the\n * merchant introduces a non-standard mode.\n */\nexport function purchaseModeNote(mode: string): string {\n return PURCHASE_MODE_NOTES[mode] ?? '';\n}\n\n/**\n * Build the canonical skill.md `onboarding_steps` for an AgentScore merchant.\n *\n * Returns a list of imperative step strings the agent follows to bootstrap\n * wallet + Passport, then either browse + buy (goods) or make the paid call\n * (api). Generic across every AgentScore-gated merchant; only the\n * merchantName + appUrl + rails list are substituted in.\n *\n * Rails accepted today: `\"tempo\"`, `\"x402-base\"`, `\"solana-mpp\"`, `\"stripe-spt\"`.\n * Unknown rail names are passed through verbatim so future rails work without\n * an SDK bump.\n *\n * Pass `vendorType: 'api'` for per-call API providers — the catalog step is\n * dropped and the final step becomes \"Make the paid call\" instead of \"Place\n * the order\".\n */\nexport function buildAgentscoreOnboardingSteps(opts: {\n merchantName: string;\n appUrl: string;\n acceptedRails: string[];\n requiresKyc?: boolean;\n vendorType?: 'goods' | 'api';\n}): string[] {\n const { merchantName, appUrl, acceptedRails, requiresKyc = false, vendorType = 'goods' } = opts;\n const railWordMap: Record<string, string> = {\n tempo: 'Tempo USDC',\n 'x402-base': 'x402 USDC on Base',\n 'solana-mpp': 'Solana SPL USDC',\n 'stripe-spt': 'Stripe Shared Payment Token',\n };\n const railsHuman = acceptedRails.map((r) => railWordMap[r] ?? r).join(', ');\n\n const chainPairs: ReadonlyArray<readonly [string, string]> = [\n ['tempo', 'tempo'],\n ['x402-base', 'base'],\n ['solana-mpp', 'solana'],\n ];\n const flags = chainPairs.filter(([rail]) => acceptedRails.includes(rail)).map(([, flag]) => flag);\n const chainFlags = flags.length > 0 ? flags.join(' | ') : 'tempo|base';\n\n // Per-rail compatible-client hints; mirrors what `compatibleClientsByRails`\n // emits on the 402 body so the skill.md and the runtime challenge stay in sync.\n const compatibleHints: ReadonlyArray<readonly [string, string]> = [\n ['tempo', '`tempo request` works for tempo USDC.e'],\n ['x402-base', '`x402-proxy` / `purl` work for Base x402'],\n ['stripe-spt', '`@stripe/link-cli` works for Stripe SPT'],\n ];\n const compatibleFragment = compatibleHints\n .filter(([rail]) => acceptedRails.includes(rail))\n .map(([, hint]) => hint)\n .join(', ');\n\n const installStep =\n 'Install agentscore-pay if you don\\'t already have a compatible client for your funded chain: ' +\n '`npm i -g @agent-score/pay` (or `brew install agentscore/tap/agentscore-pay`). ' +\n `${merchantName} accepts: ${railsHuman}. agentscore-pay speaks every supported rail; ` +\n (compatibleFragment ? `the rails table also lists per-rail \\`compatible_clients\\` — ${compatibleFragment}. ` : '') +\n 'Any spec-compliant client for an individual rail works too.';\n const bootstrapStep =\n 'First-run only: bootstrap wallet + Passport. Run `agentscore-pay agent-guide --json` ' +\n 'for the canonical cold-start path — it walks `agentscore-pay init` ' +\n '(creates keystore + per-chain wallet), `agentscore-pay passport login` ' +\n `(one-time KYC${requiresKyc ? '; required for this merchant' : ''}; the human completes a verify URL once and pay caches the operator_token), ` +\n 'and `agentscore-pay balance` to see which chain has USDC. Skip if your wallet+Passport are already provisioned.';\n const stripeFallbackStep =\n 'If your only payment method is a Stripe / Link card (no crypto), install `@stripe/link-cli` ' +\n 'instead of agentscore-pay and use it on the SPT rail. Identity gating still applies — the ' +\n 'merchant\\'s 403 with `verify_url` lets you bootstrap a Passport even with no crypto wallet involved.';\n const returningUserStep =\n 'Returning user note: if you\\'ve paid an AgentScore-gated merchant before from this wallet, ' +\n 'the wallet is already in your Passport\\'s `linked_wallets[]` and identity flows through ' +\n 'automatically with no re-KYC prompt. Paying from a NEW wallet while you already hold an ' +\n '`opc_...` token returns 403 `wallet_signer_mismatch`; the body lists `linked_wallets[]` and ' +\n '`agent_instructions.action: resign_or_switch_to_operator_token` with three deterministic ' +\n 'recoveries (switch to a linked wallet, drop the operator_token to re-KYC the new wallet, ' +\n 'or pre-claim the new wallet via SIWE on agentscore.sh/verify).';\n const pickRailStep =\n `Pick the rail your wallet is funded for. The 402 advertises ${acceptedRails.length} rail${acceptedRails.length === 1 ? '' : 's'}. ` +\n '`agentscore-pay balance` (without `--chain`) lists every chain\\'s USDC; pay rejects with ' +\n '`multi_rail_ambiguity` if you don\\'t pass `--chain` on a multi-rail challenge.';\n const placeOrderStep =\n `Place the order: \\`agentscore-pay pay POST ${appUrl}/purchase --chain <${chainFlags}> ` +\n '-d \\'<body>\\' --max-spend <amount>` for crypto rails. For Stripe SPT, follow the handoff ' +\n 'hint pay emits and use `@stripe/link-cli` instead. Either way pay handles the 402 retry, ' +\n 'signing, and Passport attachment; branch on the structured CliError `code` on non-zero ' +\n 'exit (insufficient_balance, multi_rail_ambiguity, config_error for missing wallet/Passport, etc.).';\n const makeCallStep =\n `Make the paid call: \\`agentscore-pay pay POST ${appUrl}/<endpoint> --chain <${chainFlags}> ` +\n '--max-spend <amount>`; pay handles 402 retry, rail selection, signing, and Passport ' +\n 'attachment. Branch on the structured CliError `code` on non-zero exit (insufficient_balance, ' +\n 'multi_rail_ambiguity, config_error for missing wallet/Passport, etc.).';\n\n const acceptsStripe = acceptedRails.includes('stripe-spt');\n if (vendorType === 'api') {\n return [\n installStep,\n bootstrapStep,\n ...(acceptsStripe ? [stripeFallbackStep] : []),\n returningUserStep,\n pickRailStep,\n makeCallStep,\n ];\n }\n return [\n installStep,\n bootstrapStep,\n ...(acceptsStripe ? [stripeFallbackStep] : []),\n returningUserStep,\n `Browse the catalog: \\`curl ${appUrl}/catalog\\`.`,\n \"Read each product's `purchase_mode` and `purchase_note` to decide \" +\n 'whether a redemption code is required, optional, or rejected.',\n pickRailStep,\n placeOrderStep,\n ];\n}\n\n/**\n * Canonical descriptions for the standard AgentScore **goods-merchant**\n * endpoints (`/catalog`, `/catalog/{slug}`, `/purchase`, `/orders/{id}`).\n *\n * Use in `/` discovery JSON, OpenAPI summaries, or anywhere the merchant needs\n * to describe what each endpoint does in agent-readable language. Descriptions\n * are merchant-agnostic; they describe response semantics (402 on discovery,\n * 400 on validation, 403 on identity, 200 on success), not the body schema\n * (which varies per merchant; surface that in OpenAPI).\n *\n * Pass `kind: 'api'` for per-call API providers; the bundle drops catalog +\n * orders routes and surfaces `POST /<endpoint>` + `GET /usage` instead.\n *\n * `includeOrderStatusRoute: true` (goods only) adds the lightweight\n * `/orders/{id}/status` PII-free variant alongside `/orders/{id}`.\n */\nexport function standardEndpointDescriptions(opts?: {\n kind?: 'goods' | 'api';\n includeOrderStatusRoute?: boolean;\n}): Record<string, string> {\n if (opts?.kind === 'api') {\n return {\n 'POST /<endpoint>':\n 'Per-call paid endpoint. Returns 402 on the discovery leg with payment rails; 400 on body rejection; 403 + recovery payload when identity is required; 200 with the call result on success.',\n 'GET /usage': 'Per-credential usage / billing summary. Identity-scoped.',\n };\n }\n const out: Record<string, string> = {\n 'GET /catalog': 'List purchasable products.',\n 'GET /catalog/{slug}': 'Single product detail.',\n 'POST /purchase':\n 'Place an order. Returns 402 on the discovery leg with payment rails; 400 on body rejection; 403 + recovery payload when identity is required; 200 with order confirmation on success.',\n 'GET /orders/{id}': 'Order detail (PII). Identity-scoped.',\n };\n if (opts?.includeOrderStatusRoute) {\n out['GET /orders/{id}/status'] = 'Payment status only (no PII).';\n }\n return out;\n}\n\n/**\n * Build the canonical AgentScore commerce `/` root discovery body. Works for\n * both goods merchants (catalog + purchase + orders) and API merchants (per-\n * call paid endpoints) — `endpoints` and any merchant-specific fields are\n * passed through `extra`.\n *\n * Common fields surfaced: `name`, `description`, `docs`, `endpoints`,\n * `audience: 'agents'`, `supported_rails`. Pass `extra` for merchant-specific\n * additions: `compliance` for goods merchants, `pricing` for API merchants,\n * `website` for branded fronts.\n *\n * `docs` keys map to absolute URLs; pass whichever discovery surfaces this\n * merchant ships (`llms`, `openapi`, `skill_md`, `mpp`, `agent_card`, `ucp`,\n * `jwks`, `redemption`, ...).\n */\nexport function buildMerchantIndexJson(opts: {\n name: string;\n description: string;\n docs: Record<string, string>;\n endpoints: Record<string, string>;\n supportedRails: string[];\n extra?: Record<string, unknown>;\n}): Record<string, unknown> {\n return {\n name: opts.name,\n description: opts.description,\n docs: opts.docs,\n endpoints: opts.endpoints,\n audience: 'agents',\n supported_rails: opts.supportedRails,\n ...(opts.extra ?? {}),\n };\n}\n\n/**\n * Standard `next_steps` block emitted in a 200 success body. Works for both\n * goods-merchant order-success and API-merchant per-call-success — the\n * `user_message` reinforces the cross-merchant Passport pattern (universal),\n * with merchant-specific copy overridable via `userMessage`.\n *\n * `orderStatusUrl` is emitted as `order_status_url`. API merchants that don't\n * have an order-detail endpoint can either pass a usage/dashboard URL or omit\n * the field by passing an empty string (filtered out before emit).\n *\n * `fulfillmentEta` is goods-specific (shipping window) — omit for API or\n * digital-goods merchants.\n */\nexport function buildSuccessNextSteps(opts: {\n orderStatusUrl?: string;\n fulfillmentEta?: string;\n userMessage?: string;\n}): Record<string, string> {\n const out: Record<string, string> = {\n action: 'done',\n user_message:\n opts.userMessage ??\n 'Payment complete. Your AgentScore Passport is now active across ' +\n 'every AgentScore-gated merchant.',\n };\n if (opts.orderStatusUrl) out.order_status_url = opts.orderStatusUrl;\n if (opts.fulfillmentEta !== undefined) out.fulfillment_eta = opts.fulfillmentEta;\n return out;\n}\n","/**\n * Standard `/redemption.md` template for merchants offering redemption codes.\n *\n * Renders the canonical cold-start bootstrap + TL;DR + recovery table + body /\n * code rules for any merchant that accepts single-use codes against a paid\n * endpoint. The pattern is delivery-neutral: codes can be printed on a mailer,\n * emailed, surfaced in-app, or issued as API trial credits.\n *\n * Goods merchants get the default body-shape (product_slug + shipping + email).\n * API merchants or digital-credit issuers pass `bodyShape` to override the\n * JSON example, and `extraRecoveryRows` to add merchant-specific error rows.\n *\n * Mirrors the prose every AgentScore merchant otherwise hand-writes so agents\n * encounter the same shape of redemption flow at any merchant.\n */\n\nconst DEFAULT_BODY_SHAPE = `{\n \"product_slug\": \"<slug>\",\n \"redemption_code\": \"<code>\",\n \"email\": \"user@example.com\",\n \"shipping\": { \"name\": \"...\", \"address_1\": \"...\", \"city\": \"...\", \"state\": \"CA\", \"zip\": \"94573\" }\n }`;\n\nconst DEFAULT_BODY_RULES = `## Body rules\n\n- \\`quantity\\` is fixed at 1; one product per code.\n- \\`shipping.country\\` defaults to \\`\"US\"\\`; non-US shipping is rejected for\n redemption-eligible products.\n- \\`shipping.state\\` must be a 2-letter US state code; \\`unsupported_jurisdiction\\`\n 400 if the state isn't on the merchant's allowlist.\n- \\`email\\` must be valid; the merchant returns 422 on malformed input.`;\n\n/**\n * Render the canonical `redemption.md` for an AgentScore merchant.\n *\n * `endpointPath` is the redemption endpoint relative to `appUrl`. Defaults to\n * `\"/purchase\"` for goods merchants; API merchants typically pass\n * `\"/<endpoint>\"` (the per-call paid route that accepts a `redemption_code`).\n *\n * `deliveryIntro` overrides the cold-start paragraph describing how the code\n * was distributed. Default covers printed mailers, emails, and any other\n * out-of-band delivery channel. API merchants distributing trial credits\n * might override with vendor-specific language.\n *\n * `bodyShape` is the JSON example shown in the TL;DR. Defaults to the\n * goods-merchant shape; API merchants pass their endpoint's body shape (which\n * still includes `redemption_code`).\n *\n * `bodyRules` overrides the body-rules section. Default covers goods-shipping\n * rules; API merchants typically pass either `\"\"` (drop the section) or their\n * own constraints.\n *\n * `extraRecoveryRows` is appended verbatim to the recovery table after the\n * universal rows. Use it for merchant-specific error codes (e.g.\n * `unsupported_jurisdiction`, per-tier code rules).\n *\n * `skuIntro` describes what the code unlocks at this merchant. Defaults to a\n * generic placeholder.\n *\n * `peerMerchantPointer` is the optional \"Don't have a code?\" cross-link at the\n * bottom. Omit to drop the section.\n */\nexport function buildRedemptionSkillMd(opts: {\n merchantName: string;\n appUrl: string;\n endpointPath?: string;\n skuIntro?: string;\n deliveryIntro?: string;\n bodyShape?: string;\n bodyRules?: string;\n extraRecoveryRows?: string;\n peerMerchantPointer?: string;\n}): string {\n const {\n merchantName,\n appUrl,\n endpointPath = '/purchase',\n skuIntro,\n deliveryIntro,\n bodyShape,\n bodyRules,\n extraRecoveryRows,\n peerMerchantPointer,\n } = opts;\n const skuText =\n skuIntro ??\n \"The code redeems a product or paid call at this merchant which you'll find in \" +\n \"the merchant's catalog or per-endpoint documentation with `purchase_mode = redemption_only`.\";\n const deliveryText =\n deliveryIntro ??\n 'You\\'re reading this because the user you\\'re working for received a single-use ' +\n `redemption code from ${merchantName} (printed on a mailer, emailed, surfaced in-app, ` +\n 'or distributed out-of-band). This page tells you, the agent, exactly how to turn ' +\n 'that code into a settled call.';\n const renderedBodyShape = bodyShape ?? DEFAULT_BODY_SHAPE;\n const renderedBodyRules = bodyRules !== undefined ? bodyRules : DEFAULT_BODY_RULES;\n const bodyRulesSection = renderedBodyRules ? `\\n${renderedBodyRules}\\n` : '';\n const extraRows = extraRecoveryRows ? `\\n${extraRecoveryRows.trimEnd()}` : '';\n\n const peerSection = peerMerchantPointer\n ? '\\n## Don\\'t have a code?\\n\\nThis page is the redemption flow for single-use codes. ' +\n `If you're looking to buy or call without a code, see: ${peerMerchantPointer}\\n`\n : '';\n\n return `# Redeeming an AgentScore code at ${merchantName}\n\n${deliveryText}\n\n${skuText} The 402 challenge on ${endpointPath} tells you the actual settle amount\nafter the code is applied; discounts can range from a partial amount off list\ndown to free.\n\n## Cold-start bootstrap (skip if your wallet + Passport are already set up)\n\nIf \\`agentscore-pay\\` isn't installed yet, install it (\\`npm i -g @agent-score/pay\\`\nor \\`brew install agentscore/tap/agentscore-pay\\`), then run \\`agentscore-pay\nagent-guide --json\\` for the canonical cold-start path. That walks\n\\`agentscore-pay init\\` (creates keystore + per-chain wallet),\n\\`agentscore-pay passport login\\` (one-time KYC; opens a verify URL the human\ncompletes, after which pay caches the \\`operator_token\\`), and\n\\`agentscore-pay balance\\` to confirm funds. Fund enough to cover the\npost-discount settle amount the 402 advertises; for $0 codes the merchant\nskips the on-chain settle entirely so funds aren't required, but the wallet\nstill needs to exist so the credential can be signed.\n\nYou don't have to use \\`agentscore-pay\\` specifically; any spec-compliant client\nfor the merchant's accepted rails (Tempo MPP, x402 Base, Solana MPP, Stripe SPT)\nworks. The 402 challenge lists every accepted rail in \\`accepted_methods\\`.\n\n## TL;DR\n\n1. Ask the user for their redemption code, plus any merchant-specific fields the\n body requires (email, shipping address for goods merchants, identifiers for\n API merchants, etc.).\n2. Discover the redemption-eligible target. Goods merchants: \\`GET ${appUrl}/catalog\\`\n and find the product whose \\`purchase_mode\\` is \\`redemption_only\\`. API merchants:\n read the per-endpoint docs for the route that accepts \\`redemption_code\\`.\n Read any \\`purchase_note\\` for product-specific rules.\n3. \\`POST ${appUrl}${endpointPath}\\` with body:\n \\`\\`\\`json\n ${renderedBodyShape}\n \\`\\`\\`\n4. If you get **403 \\`operator_verification_required\\`**, surface the body's\n \\`verify_url\\` to the user for one-time KYC and poll \\`poll_url\\` with\n \\`poll_secret\\`. After verification, retry with \\`X-Operator-Token\\` attached.\n If you already have an \\`opc_...\\` from a prior AgentScore-gated merchant,\n attach it on the first call and skip this step.\n5. On **402**, the body carries \\`accepted_methods\\` and \\`agent_instructions.how_to_pay\\`.\n Settle with \\`agentscore-pay pay POST ${appUrl}${endpointPath} --chain <rail> -d '<body>'\n --max-spend <amount>\\`; pay handles 402 retry, rail selection, signing, and\n Passport attachment. Pass \\`--max-spend\\` >= the amount in the 402.\n6. **200**; the call settled. Response carries a receipt \\`id\\` (order id for goods,\n request id for API), \\`next_steps.order_status_url\\` (or usage dashboard URL),\n and an \\`agent_memory\\` block you should persist (the cross-merchant pattern\n hint, NOT the operator_token or poll_secret). For $0 redemptions \\`tx_hash\\`\n is \\`null\\`; the credential is still authenticated and the code is burned\n single-use.\n${bodyRulesSection}\n## Code rules\n\n- Codes are case-insensitive (server uppercases on receipt), single-use, and\n burned atomically against \\`(code, operator_token)\\` OR \\`(code, signer_address)\\`\n for token-less wallet flows. A second attempt returns 400 \\`redemption_already_used\\`.\n- Submit the code in the JSON body as \\`\"redemption_code\"\\`; never as a header.\n\n## Recovery on common errors\n\n| HTTP | error.code | What it means | What to do |\n|---|---|---|---|\n| 403 | \\`operator_verification_required\\` | User has no Passport / KYC pending | Surface \\`verify_url\\`; poll \\`poll_url\\` with \\`poll_secret\\`; retry with \\`X-Operator-Token\\` |\n| 403 | \\`wallet_signer_mismatch\\` | Operator token + signer wallet aren't linked to the same identity | Switch to a wallet in \\`linked_wallets[]\\`, or drop the operator_token to re-KYC the new wallet |\n| 400 | \\`invalid_body\\` | JSON parse failed | Fix the JSON and retry |\n| 400 | \\`missing_fields\\` | Required field absent | Add the field per \\`error.message\\` and retry |\n| 400 | \\`product_not_found\\` | Identifier doesn't match an active product / endpoint | Re-check the catalog or endpoint docs and use the exact slug / route |\n| 400 | \\`product_out_of_stock\\` | Goods-only: stock 0 | Tell the user; no retry possible |\n| 400 | \\`invalid_redemption_code\\` | Code unknown / expired | Ask the user for the code as printed; do not invent variants |\n| 400 | \\`redemption_already_used\\` | Code burned | Tell the user; codes are single-use |\n| 400 | \\`codes_not_accepted\\` | Target is \\`paid_only\\` and rejects codes | Drop \\`redemption_code\\` and retry, or pick a different target |\n| 402 | (challenge) | Identity OK; payment required | Run \\`agentscore-pay pay\\` against the same URL |${extraRows}\n${peerSection}`;\n}\n","/**\n * UCP (Universal Commerce Protocol) profile builder.\n *\n * Compose the JSON payload published at `/.well-known/ucp` per the UCP spec.\n * Output shape matches the spec example: top-level `{ ucp: {...}, signing_keys: [...] }`\n * envelope, with `services` / `capabilities` / `payment_handlers` as MAPs keyed by\n * reverse-DNS service / capability / handler name.\n *\n * AgentScore identity claims layer over UCP via the `sh.agentscore.identity` capability\n * (vendor-namespaced; UCP doesn't define KYC/sanctions/age/jurisdiction natively). The\n * capability extends `dev.ucp.shopping.checkout` AND `dev.ucp.shopping.cart` (multi-parent,\n * the standard pattern UCP allows for capabilities that compose multiple parents).\n *\n * The unsigned profile body returned here is what merchants publish; pass it through\n * `signUCPProfile` to attach the `agentscore-profile+jws` signature for trust-mode\n * verifiers (vendor extension; UCP itself doesn't mandate profile-body signing).\n *\n * Spec reference: https://ucp.dev/\n */\n\n\n/**\n * UCP per-element shape note: each binding interface (`UCPServiceBinding`,\n * `UCPCapabilityBinding`, `UCPPaymentHandlerBinding`) carries the canonical UCP fields\n * plus arbitrary vendor extras flat on the same object via `[k: string]: unknown`. The\n * python sibling models these as dataclasses with an explicit `extras: dict` field. Both\n * designs offer equivalent guarantees through different mechanisms.\n */\n// ─── Payment handler builders ─────────────────────────────────────────────\n// Vendors compose UCP `payment_handlers` blocks by spreading these helpers.\n// The helpers fill in id/version/spec/schema/config wrapper so vendors only\n// supply merchant-specific data (networks + recipients + profile_id).\n//\n// payment_handlers: {\n// ...mppPaymentHandler({ networks: [...] }),\n// ...x402PaymentHandler({ networks: [...] }),\n// ...stripeSptPaymentHandler({ profile_id: '...' }),\n// }\n//\n// Each helper returns `{ [reverse-DNS-key]: [binding] }` so spreading into\n// the parent map composes cleanly. The reverse-DNS keys + spec/schema URLs\n// + handler `version` are owned by these constants; bumping a handler spec\n// version is a one-line change here, not 20 lines across consumers.\n\nimport {\n type RecipientLike,\n type SolanaMppRailSpec,\n type StripeRailSpec,\n type TempoRailSpec,\n type TempoSessionRailSpec,\n type X402BaseRailSpec,\n} from '../payment/rail_spec';\n\nexport interface UCPSigningKey {\n /** JWK kid (key id). */\n kid: string;\n /** JWK kty (key type) — `EC`, `RSA`, or `OKP`. */\n kty: string;\n /** JWK alg (signing algorithm) — `ES256`, `RS256`, or `EdDSA`. */\n alg?: string;\n /** JWK use, typically `sig`. */\n use?: string;\n /** JWK crv (curve) for EC / OKP keys. */\n crv?: string;\n /** JWK x / y / n / e / etc. The full key material; passed through verbatim. */\n [k: string]: unknown;\n}\n\n/**\n * Construct a UCPSigningKey from a public JWK dict (e.g. the `publicJWK` returned by\n * `generateUCPSigningKey()`). Validates required fields and rejects symmetric keys that\n * can't publicly verify a JWS in trust-mode UCP. Mirrors python's\n * `UCPSigningKey.from_jwk(public_jwk)` classmethod via the `UCPSigningKey.fromJWK`\n * static-method-style namespace export below.\n */\nfunction ucpSigningKeyFromJWKImpl(jwk: Record<string, unknown>): UCPSigningKey {\n if (!jwk || typeof jwk !== 'object') {\n throw new Error(`UCPSigningKey.fromJWK expected a non-null object; got ${typeof jwk}.`);\n }\n if (typeof jwk.kid !== 'string' || !jwk.kid) {\n throw new Error('UCPSigningKey.fromJWK: JWK missing required field `kid` (or non-string).');\n }\n if (typeof jwk.kty !== 'string' || !jwk.kty) {\n throw new Error('UCPSigningKey.fromJWK: JWK missing required field `kty` (or non-string).');\n }\n if (jwk.kty !== 'OKP' && jwk.kty !== 'EC' && jwk.kty !== 'RSA') {\n throw new Error(\n `UCPSigningKey.fromJWK: kty=${JSON.stringify(jwk.kty)} is not a supported asymmetric key type (expected OKP, EC, or RSA). Symmetric \\`oct\\` keys are rejected because they cannot publicly verify a JWS in the trust-mode UCP flow.`,\n );\n }\n if ((jwk.kty === 'EC' || jwk.kty === 'OKP') && (typeof jwk.crv !== 'string' || !jwk.crv)) {\n throw new Error(`UCPSigningKey.fromJWK: kty=${jwk.kty} requires a non-empty \\`crv\\` field (e.g., \"P-256\" for EC, \"Ed25519\" for OKP).`);\n }\n return jwk as unknown as UCPSigningKey;\n}\n\n/** Static-method-style namespace on the `UCPSigningKey` interface — mirrors python's\n * `UCPSigningKey.from_jwk(jwk)` classmethod. Use as `UCPSigningKey.fromJWK(jwk)`. */\nexport const UCPSigningKey = {\n fromJWK: ucpSigningKeyFromJWKImpl,\n};\n\n/** Transport binding — keyed under a service name (e.g., `dev.ucp.shopping`). */\nexport interface UCPServiceBinding {\n /** Spec version, YYYY-MM-DD per UCP convention. REQUIRED. */\n version: string;\n /** URL to human-readable specification. REQUIRED. */\n spec: string;\n /** Transport — `rest` / `mcp` / `a2a` / `embedded`. REQUIRED. */\n transport: 'rest' | 'mcp' | 'a2a' | 'embedded';\n /** Endpoint URL — required for rest/mcp; A2A points at the agent-card.json URL. */\n endpoint?: string;\n /** URL to JSON Schema — required for rest/mcp/embedded per spec. */\n schema?: string;\n /** Optional id for entity-instance disambiguation. */\n id?: string;\n /** Entity-specific config. */\n config?: Record<string, unknown>;\n /** Vendor-specific extras. */\n [k: string]: unknown;\n}\n\n/** Capability binding — keyed under a capability name (e.g., `dev.ucp.shopping.checkout`). */\nexport interface UCPCapabilityBinding {\n /** Capability version, YYYY-MM-DD. REQUIRED. */\n version: string;\n /** URL to human-readable specification. REQUIRED. */\n spec: string;\n /** URL to JSON Schema. REQUIRED. */\n schema: string;\n /** Optional id for entity-instance disambiguation. */\n id?: string;\n /** Entity-specific config (feature flags, callback URLs, etc). */\n config?: Record<string, unknown>;\n /** Parent capability(ies) extended — single string or array for multi-parent. */\n extends?: string | string[];\n /** Optional version requirements per UCP §6.5. */\n requires?: {\n protocol?: { min: string; max?: string };\n capabilities?: Record<string, { min: string; max?: string }>;\n };\n /** Vendor-specific extras allowed per UCP convention (e.g., the AgentScore identity\n * capability adds a vendor-namespaced policy declaration here). */\n [k: string]: unknown;\n}\n\n/** Payment handler binding — keyed under a handler reverse-DNS name (e.g., `com.google.pay`). */\nexport interface UCPPaymentHandlerBinding {\n /** Handler instance id (short, human-readable, e.g., `gpay`, `tempo`, `x402`). REQUIRED. */\n id: string;\n /** Handler spec version, YYYY-MM-DD. REQUIRED. */\n version: string;\n /** URL to handler spec. REQUIRED. */\n spec: string;\n /** URL to handler config schema. REQUIRED. */\n schema: string;\n /** Available instruments — type + per-type constraints (cards, wallets, etc.). */\n available_instruments?: Array<{ type: string; constraints?: Record<string, unknown>; [k: string]: unknown }>;\n /** Handler config — gateway IDs, merchant IDs, public keys, etc. */\n config?: Record<string, unknown>;\n /** Vendor-specific extras. */\n [k: string]: unknown;\n}\n\n/** UCP body — nested under the `ucp` key of the published profile. */\nexport interface UCPProfileBody {\n /** UCP spec version (YYYY-MM-DD). */\n version: string;\n /** Display name for the merchant / agent surface. */\n name?: string;\n /** Services — keyed by service name (e.g., `dev.ucp.shopping`). Each value is an\n * array of transport bindings (one merchant typically advertises multiple transports\n * under one service name). */\n services: Record<string, UCPServiceBinding[]>;\n /** Capabilities — keyed by capability name (e.g., `dev.ucp.shopping.checkout`). */\n capabilities: Record<string, UCPCapabilityBinding[]>;\n /** Payment handlers — keyed by handler reverse-DNS name (e.g., `com.google.pay`). */\n payment_handlers: Record<string, UCPPaymentHandlerBinding[]>;\n /** Optional `supported_versions` map linking historical version-specific profile URLs.\n * Pattern: `{ \"2026-01-23\": \"https://merchant/.well-known/ucp/2026-01-23\", ... }`. */\n supported_versions?: Record<string, string>;\n /** Vendor-specific extras inside the `ucp` envelope. */\n [k: string]: unknown;\n}\n\n/** Full UCP profile body as published at `/.well-known/ucp`. Top-level shape:\n * `{ ucp: {...}, signing_keys: [...], signature?: \"...\" }`. */\nexport interface UCPProfile {\n /** UCP body. ALL UCP-spec fields nest here per spec. */\n ucp: UCPProfileBody;\n /** JWKS — public keys at the OUTER level per UCP spec. Verifiers fetch this profile,\n * match the kid from a JWS / RFC 9421 signature header against this list, and validate. */\n signing_keys: UCPSigningKey[];\n /** Set when JWS-signed via `signUCPProfile` — JWS Compact Serialization with detached\n * payload (header..signature; payload is the canonicalized body minus this field). */\n signature?: string;\n /** Top-level vendor-specific extras (outside the `ucp` envelope). */\n [k: string]: unknown;\n}\n\ninterface BuildUCPProfileInput {\n /** UCP spec version. Default `'2026-04-08'` (the latest published UCP spec date). MUST match a published UCP spec version, not a free-form date. */\n version?: string;\n /** Display name for the merchant / agent surface. */\n name?: string;\n /** Services map, keyed by service name. UCP-shopping merchants typically advertise\n * bindings under `'dev.ucp.shopping'`. */\n services?: Record<string, UCPServiceBinding[]>;\n /** Capabilities map, keyed by capability name. The `sh.agentscore.identity` capability\n * is auto-added when `agentscore_gate` is provided. */\n capabilities?: Record<string, UCPCapabilityBinding[]>;\n /** Payment handlers map, keyed by handler reverse-DNS name. */\n payment_handlers?: Record<string, UCPPaymentHandlerBinding[]>;\n /** JWKS — public keys the merchant signs with. REQUIRED by spec. */\n signing_keys: UCPSigningKey[];\n /** Merchant gate policy declaration. When provided, the SDK auto-injects an\n * `sh.agentscore.identity` capability binding into `capabilities`, with the\n * policy as the binding's `config`. Static merchant declaration only — no\n * per-operator data ever ends up on the public profile. Per-operator identity\n * attestation lives on the AP2 risk-signal endpoint, not here. */\n agentscore_gate?: AgentScoreGatePolicy;\n /** Optional override for the AgentScore capability schema URL. Field is snake_cased\n * for cross-language parity with the Python sibling. */\n agentscore_schema_url?: string;\n /** Optional override for the AgentScore capability spec URL. */\n agentscore_spec_url?: string;\n /** `supported_versions` map at the profile root for backwards-compat across\n * spec dates. Pattern: `{ \"<date>\": \"<base>/.well-known/ucp/<date>\" }`. */\n supported_versions?: Record<string, string>;\n /** Vendor-specific extras at the OUTER level (alongside `ucp` + `signing_keys`). */\n extras?: Record<string, unknown>;\n /** Vendor-specific extras INSIDE the `ucp` envelope (alongside `version`, `services`, etc.). */\n ucp_extras?: Record<string, unknown>;\n}\n\nconst DEFAULT_VERSION = '2026-04-08';\n// Reverse-DNS namespacing per UCP convention (`^[a-z][a-z0-9]*(?:\\.[a-z][a-z0-9_]*)+$`).\n// The bare `agentscore-identity` form fails the spec regex; vendor-namespacing under\n// `sh.agentscore` is honest about the capability being our extension, not UCP-canonical.\nconst AGENTSCORE_CAPABILITY_NAME = 'sh.agentscore.identity';\n// Date-format version per UCP convention (matches every other binding's version field).\nconst AGENTSCORE_CAPABILITY_VERSION = '2026-04-08';\n\n/** Merchant gate policy declared on the UCP profile via `sh.agentscore.identity` capability config.\n * All fields optional; merchant declares which AgentScore checks the gate enforces. Snake-case\n * field names match the AgentScore API's `/v1/assess` policy contract verbatim — no conversion\n * layer between this declaration and what the gate actually enforces at runtime. */\nexport interface AgentScoreGatePolicy {\n /** Gate denies if the operator/account behind the agent is not Stripe-Identity-verified. */\n require_kyc?: boolean;\n /** Gate denies if the operator/account is flagged by OpenSanctions screening. */\n require_sanctions_clear?: boolean;\n /** Gate denies if the verified age (from KYC) is below this threshold. Common values: 18, 21. */\n min_age?: number;\n /** ISO-3166-1 alpha-2 country codes the gate accepts. Empty/absent allows any. Mutually exclusive\n * with `blocked_jurisdictions` (set one or the other, not both). */\n allowed_jurisdictions?: string[];\n /** ISO-3166-1 alpha-2 country codes the gate denies. Empty/absent denies none. Mutually exclusive\n * with `allowed_jurisdictions`. */\n blocked_jurisdictions?: string[];\n}\nconst AGENTSCORE_DEFAULT_SPEC_URL = 'https://agentscore.sh/specification/identity';\nconst AGENTSCORE_DEFAULT_SCHEMA_URL = 'https://agentscore.sh/schemas/ucp/sh-agentscore-identity-v1.json';\n// Multi-parent extension — `sh.agentscore.identity` declares merchant policy relevant at\n// both checkout-build (compliance gate) and cart-build (price-gate eligibility, jurisdiction-\n// restricted items in cart) time, so an agent reading either parent capability picks up the\n// policy contract. Mirrors the multi-parent convention in the live ecosystem\n// (Shopify's `dev.shopify.catalog.storefront` extends both `catalog.search` and\n// `catalog.lookup`; UCP-canonical `dev.ucp.shopping.discount` extends both checkout and cart).\nconst AGENTSCORE_EXTENDS = ['dev.ucp.shopping.checkout', 'dev.ucp.shopping.cart'];\n\nconst RESERVED_TOP_LEVEL = new Set([\n 'ucp',\n 'signing_keys',\n 'signature',\n '__proto__',\n 'constructor',\n 'prototype',\n]);\nconst RESERVED_UCP_FIELDS = new Set([\n 'version',\n 'name',\n 'services',\n 'capabilities',\n 'payment_handlers',\n 'supported_versions',\n '__proto__',\n 'constructor',\n 'prototype',\n]);\n\n/**\n * Compose a UCP profile body for `/.well-known/ucp` publication. Returns the spec-\n * compliant shape: `{ ucp: { version, services, capabilities, payment_handlers, ... },\n * signing_keys: [...] }`. Pass through `signUCPProfile` to attach a JWS signature for\n * trust-mode verifiers.\n *\n * Auto-injects `sh.agentscore.identity` as a vendor capability extending both\n * `dev.ucp.shopping.checkout` and `dev.ucp.shopping.cart` when `agentscore_gate`\n * is provided. The capability's `config` carries the merchant's static gate\n * policy declaration (require_kyc / require_sanctions_clear / min_age /\n * allowed_jurisdictions / blocked_jurisdictions). NO per-operator data is ever\n * placed on the public profile — per-operator identity attestation flows through\n * the AP2 risk-signal endpoint, not here.\n *\n * Example:\n * ```ts\n * import { buildUCPProfile } from '@agent-score/commerce';\n *\n * const profile = buildUCPProfile({\n * name: 'Example Merchant',\n * services: {\n * 'dev.ucp.shopping': [\n * { version: '2026-04-08', spec: 'https://ucp.dev/2026-04-08/specification/overview',\n * transport: 'mcp', endpoint: 'https://merchant.example/api/ucp/mcp',\n * schema: 'https://ucp.dev/services/shopping/mcp.openrpc.json' },\n * ],\n * },\n * payment_handlers: {\n * ...mppPaymentHandler({ networks: [{ network: 'tempo-mainnet', chain_id: 4217, recipient: TEMPO_ADDR }] }),\n * },\n * signing_keys: [signingKey],\n * agentscore_gate: { require_kyc: true, min_age: 21, allowed_jurisdictions: ['US'] },\n * });\n * ```\n */\nexport function buildUCPProfile(input: BuildUCPProfileInput): UCPProfile {\n // Per UCP spec service.json: rest/mcp/a2a transports REQUIRE endpoint;\n // embedded does not. Validate caller-supplied services so a misconfigured\n // profile fails locally instead of being rejected by spec-strict platforms.\n for (const [name, bindings] of Object.entries(input.services ?? {})) {\n for (const binding of bindings) {\n if (\n (binding.transport === 'rest' || binding.transport === 'mcp' || binding.transport === 'a2a')\n && (binding.endpoint === undefined || binding.endpoint === null || binding.endpoint === '')\n ) {\n throw new Error(\n `buildUCPProfile: service \"${name}\" transport=${binding.transport} requires \\`endpoint\\`. Per UCP spec service.json business_schema, rest/mcp/a2a bindings MUST carry an endpoint URL.`,\n );\n }\n }\n }\n\n // Per UCP spec payment_handler.json: available_instruments has minItems:1.\n // Deep-copy each binding and drop available_instruments when empty so a caller\n // passing `[]` doesn't ship an invalid profile.\n const paymentHandlers: Record<string, UCPPaymentHandlerBinding[]> = {};\n for (const [name, bindings] of Object.entries(input.payment_handlers ?? {})) {\n paymentHandlers[name] = bindings.map((binding) => {\n if (Array.isArray(binding.available_instruments) && binding.available_instruments.length === 0) {\n const { available_instruments: _drop, ...rest } = binding;\n return rest as UCPPaymentHandlerBinding;\n }\n return binding;\n });\n }\n\n // Deep-clone the capabilities map so we can safely mutate (auto-add the AgentScore\n // identity capability) without altering the caller's input.\n const capabilities: Record<string, UCPCapabilityBinding[]> = {};\n for (const [name, bindings] of Object.entries(input.capabilities ?? {})) {\n capabilities[name] = [...bindings];\n }\n\n // Auto-inject `sh.agentscore.identity` capability when the merchant declares a gate\n // policy. Static merchant-policy declaration only — no per-operator data on the public\n // profile. Per-operator identity attestation flows through the AP2 risk-signal endpoint\n // or per-request 4xx response bodies, not here.\n if (input.agentscore_gate) {\n const gateConfig = { ...input.agentscore_gate };\n const agentscoreBinding: UCPCapabilityBinding = {\n version: AGENTSCORE_CAPABILITY_VERSION,\n spec: input.agentscore_spec_url ?? AGENTSCORE_DEFAULT_SPEC_URL,\n schema: input.agentscore_schema_url ?? AGENTSCORE_DEFAULT_SCHEMA_URL,\n extends: AGENTSCORE_EXTENDS,\n };\n // Omit `config` when empty so node + python emit byte-identical canonical output\n // (python's UCPCapabilityBinding.to_dict already drops empty config).\n if (Object.keys(gateConfig).length > 0) agentscoreBinding.config = gateConfig;\n const existing = capabilities[AGENTSCORE_CAPABILITY_NAME];\n if (existing) existing.push(agentscoreBinding);\n else capabilities[AGENTSCORE_CAPABILITY_NAME] = [agentscoreBinding];\n }\n\n const ucp: UCPProfileBody = {\n version: input.version ?? DEFAULT_VERSION,\n services: input.services ?? {},\n capabilities,\n payment_handlers: paymentHandlers,\n };\n if (input.name !== undefined) ucp.name = input.name;\n if (input.supported_versions !== undefined) ucp.supported_versions = input.supported_versions;\n if (input.ucp_extras) {\n for (const k of Object.keys(input.ucp_extras)) {\n if (RESERVED_UCP_FIELDS.has(k)) {\n throw new Error(`buildUCPProfile: ucp_extras key \"${k}\" collides with a reserved \\`ucp\\` field; rejected.`);\n }\n }\n Object.assign(ucp, input.ucp_extras);\n }\n\n const profile: UCPProfile = {\n ucp,\n signing_keys: input.signing_keys,\n };\n if (input.extras) {\n // `__proto__`, `constructor`, `prototype` reserved so vendor extras can't slip\n // prototype-pollution payloads into the canonical body.\n for (const k of Object.keys(input.extras)) {\n if (RESERVED_TOP_LEVEL.has(k)) {\n throw new Error(`buildUCPProfile: extras key \"${k}\" collides with a reserved profile field; rejected.`);\n }\n }\n Object.assign(profile, input.extras);\n }\n\n return profile;\n}\n\nexport const AGENTSCORE_UCP_CAPABILITY = AGENTSCORE_CAPABILITY_NAME;\n\nconst HANDLER_VERSION = '2026-04-08';\nconst SPEC_BASE = 'https://agentscore.sh/specification/payment-handlers';\nconst SCHEMA_BASE = 'https://agentscore.sh/schemas/payment-handlers';\n\n// CAIP-2 → UCP-namespace network-name mapping. UCP payment_handler bindings publish\n// network strings in the UCP namespace (`base-8453`, `solana-mainnet-beta`); RailSpecs\n// carry the CAIP-2 form (`eip155:8453`, `solana:5eykt4...`). Unknown values pass\n// through verbatim — vendors who pin a non-standard rail can override the spec's\n// network field directly.\nconst CAIP2_TO_UCP_NETWORK: Record<string, string> = {\n 'eip155:8453': 'base-8453',\n 'eip155:84532': 'base-84532',\n 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': 'solana-mainnet-beta',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'solana-devnet',\n};\n\nfunction ucpNetworkName(caip2OrUcp: string | undefined, fallback: string): string {\n if (caip2OrUcp === undefined) return fallback;\n return CAIP2_TO_UCP_NETWORK[caip2OrUcp] ?? caip2OrUcp;\n}\n\n/**\n * Return the recipient as a string when it's both a string AND non-empty;\n * `undefined` for factory callables OR empty-string sentinels (both signal\n * per-order minting; the authoritative recipient ships in the 402 body at\n * request time, not in the static UCP profile).\n */\nfunction staticRecipient(r: RecipientLike): string | undefined {\n return typeof r === 'string' && r.length > 0 ? r : undefined;\n}\n\nfunction tempoToNetworkEntry(spec: TempoRailSpec): Record<string, unknown> {\n const entry: Record<string, unknown> = {\n network: spec.testnet ? 'tempo-testnet' : (spec.network ?? 'tempo-mainnet'),\n chain_id: spec.chainId ?? 4217,\n };\n const recipient = staticRecipient(spec.recipient);\n if (recipient !== undefined) entry.recipient = recipient;\n return entry;\n}\n\nfunction solanaMppToNetworkEntry(spec: SolanaMppRailSpec): Record<string, unknown> {\n const entry: Record<string, unknown> = {\n network: ucpNetworkName(spec.network, 'solana-mainnet-beta'),\n };\n const recipient = staticRecipient(spec.recipient);\n if (recipient !== undefined) entry.recipient = recipient;\n return entry;\n}\n\nfunction tempoSessionToNetworkEntry(spec: TempoSessionRailSpec): Record<string, unknown> {\n const entry: Record<string, unknown> = {\n network: spec.testnet ? 'tempo-testnet' : 'tempo-mainnet',\n escrow_contract: spec.escrowContract,\n };\n const recipient = staticRecipient(spec.recipient);\n if (recipient !== undefined) entry.recipient = recipient;\n return entry;\n}\n\ntype MppRailSpec = TempoRailSpec | SolanaMppRailSpec | TempoSessionRailSpec;\n\nfunction isTempoRailSpec(s: MppRailSpec): s is TempoRailSpec {\n return !('escrowContract' in s) && !('rpcUrl' in s) && !('tokenProgram' in s);\n}\n\nfunction isTempoSessionRailSpec(s: MppRailSpec): s is TempoSessionRailSpec {\n return 'escrowContract' in s && 'store' in s;\n}\n\nfunction mppRailToNetworkEntry(spec: MppRailSpec): Record<string, unknown> {\n if (isTempoSessionRailSpec(spec)) return tempoSessionToNetworkEntry(spec);\n if ('rpcUrl' in spec || 'tokenProgram' in spec || (spec.network?.startsWith('solana:') ?? false)) {\n return solanaMppToNetworkEntry(spec as SolanaMppRailSpec);\n }\n if (isTempoRailSpec(spec)) return tempoToNetworkEntry(spec);\n // Default: treat as TempoRailSpec — covers the common case where the caller passes\n // a bare `{recipient}` with no network/chain_id override.\n return tempoToNetworkEntry(spec as TempoRailSpec);\n}\n\n/**\n * Build the `sh.agentscore.payment.mpp` payment handler block for a UCP profile.\n *\n * Pass any mix of `TempoRailSpec`, `SolanaMppRailSpec`, and `TempoSessionRailSpec`.\n *\n * @example\n * ```ts\n * buildUCPProfile({\n * ...,\n * payment_handlers: {\n * ...mppPaymentHandler({\n * networks: [\n * { recipient: '0xtempo' }, // TempoRailSpec\n * { recipient: 'solanaaddr', network: 'solana:5eykt4...' }, // SolanaMppRailSpec\n * ],\n * }),\n * },\n * });\n * ```\n */\nexport function mppPaymentHandler({\n networks,\n}: {\n networks: MppRailSpec[];\n}): Record<string, UCPPaymentHandlerBinding[]> {\n return {\n 'sh.agentscore.payment.mpp': [{\n id: 'mpp',\n version: HANDLER_VERSION,\n spec: `${SPEC_BASE}/mpp`,\n schema: `${SCHEMA_BASE}/mpp.json`,\n config: { networks: networks.map(mppRailToNetworkEntry) },\n }],\n };\n}\n\nfunction x402RailToNetworkEntry(spec: X402BaseRailSpec): Record<string, unknown> {\n const entry: Record<string, unknown> = {\n network: ucpNetworkName(spec.network, 'base-8453'),\n };\n const recipient = staticRecipient(spec.recipient);\n if (recipient !== undefined) entry.recipient = recipient;\n return entry;\n}\n\n/**\n * Build the `sh.agentscore.payment.x402` payment handler block for a UCP profile.\n *\n * @example\n * ```ts\n * buildUCPProfile({\n * ...,\n * payment_handlers: {\n * ...x402PaymentHandler({ networks: [{ recipient: '0xabc...' }] }),\n * },\n * });\n * ```\n */\nexport function x402PaymentHandler({\n networks,\n}: {\n networks: X402BaseRailSpec[];\n}): Record<string, UCPPaymentHandlerBinding[]> {\n return {\n 'sh.agentscore.payment.x402': [{\n id: 'x402',\n version: HANDLER_VERSION,\n spec: `${SPEC_BASE}/x402`,\n schema: `${SCHEMA_BASE}/x402.json`,\n config: { networks: networks.map(x402RailToNetworkEntry) },\n }],\n };\n}\n\n/**\n * Build the `sh.agentscore.payment.stripe_spt` payment handler block for a UCP profile.\n *\n * @example\n * ```ts\n * buildUCPProfile({\n * ...,\n * payment_handlers: {\n * ...stripeSptPaymentHandler({ spec: { profileId: 'profile_5xKvNqM9BaH' } }),\n * },\n * });\n * ```\n */\nexport function stripeSptPaymentHandler({\n spec,\n}: {\n spec: StripeRailSpec;\n}): Record<string, UCPPaymentHandlerBinding[]> {\n return {\n 'sh.agentscore.payment.stripe_spt': [{\n id: 'stripe-spt',\n version: HANDLER_VERSION,\n spec: `${SPEC_BASE}/stripe_spt`,\n schema: `${SCHEMA_BASE}/stripe_spt.json`,\n config: { rail: 'stripe-spt', profile_id: spec.profileId ?? null },\n }],\n };\n}\n","/**\n * UCP profile signing helpers (JWKS + JWS).\n *\n * UCP §6 (https://ucp.dev/latest/specification/signatures/) requires that profiles\n * published at `/.well-known/ucp` carry a JWKS-backed signature for trust-mode clients\n * (Google AI Mode, Gemini commerce, future ChatGPT app shells). Without a signature,\n * trust-mode clients reject the profile.\n *\n * This module provides:\n * - `generateUCPSigningKey()` — generate an Ed25519 keypair for signing\n * - `signUCPProfile()` — sign a UCP profile body, returning a JWS-attached envelope\n * - `verifyUCPProfile()` — verify a signed profile against a JWKS\n * - `buildJWKSResponse()` — assemble a JWKS document for `/.well-known/jwks.json`\n *\n * Implementation rides on `jose` (peer-dep, optional). Merchants who don't sign their\n * profile (development) skip this module entirely; the unsigned `buildUCPProfile()`\n * path still works.\n *\n * Why Ed25519: smaller signatures (64 bytes vs 256+ for RSA), faster verification, no\n * curve-parameter ceremony. UCP also accepts ES256 (P-256 ECDSA) — pass `alg: 'ES256'`\n * to `signUCPProfile()` if your existing payment signing key is P-256.\n */\n\nimport type { UCPProfile, UCPSigningKey } from './ucp';\n\n/** Output of `generateUCPSigningKey()`. The private key is what you sign with; the\n * public JWK is what you publish at `/.well-known/jwks.json` and reference in the\n * UCP profile's `signing_keys[]`.\n */\nexport interface GeneratedUCPKey {\n /** Private key (KeyLike, opaque) — pass to `signUCPProfile()`. Never publish. */\n privateKey: unknown;\n /** Public key as JWK — publish at `/.well-known/jwks.json` and inline in UCP `signing_keys[]`. */\n publicJWK: UCPSigningKey;\n}\n\n/** A JWKS document — `{ keys: [...] }` per RFC 7517. Serve at `/.well-known/jwks.json`. */\nexport interface JWKSResponse {\n keys: UCPSigningKey[];\n}\n\n\n/** A signed UCP profile envelope. Same shape as `UCPProfile` plus the `signature` field\n * carrying the JWS Compact Serialization over the canonicalized profile body. */\nexport interface SignedUCPProfile extends UCPProfile {\n /** JWS Compact Serialization (`<header>.<payload>.<signature>`) over the profile body\n * with `signature` removed and keys sorted. Verifiers reconstruct the canonical body\n * and validate against the JWK identified by `kid` in the JWS protected header. */\n signature: string;\n}\n\nconst JOSE_INSTALL_HINT = 'Install the optional peer dependency: `npm install jose@^6` (or `bun add jose`). Tested against jose v6.x.';\n\n/** UCP §6 + RFC 8725 §3.1 — restrict accepted JWS algorithms. Anything outside this\n * list (HS, RS, none, etc.) is rejected to prevent alg-confusion attacks where a\n * hostile JWK published in the profile's signing_keys[] is used with an unintended\n * algorithm. */\nconst ALLOWED_ALGS = ['EdDSA', 'ES256'] as const;\ntype AllowedAlg = (typeof ALLOWED_ALGS)[number];\n\n/** JWS protected header `typ` value. Vendor-namespaced because UCP §6 does not define\n * a profile-as-JWS typ; the value advertises that this signed envelope follows the\n * AgentScore extension semantics rather than a UCP-canonical signing convention.\n * Verifiers SHOULD enforce this to prevent cross-protocol token reuse (RFC 8725 §3.11). */\nconst PROFILE_TYP = 'agentscore-profile+jws';\n\n/** Discriminated error class so consumers can branch on failure mode without\n * parsing message strings or importing jose internals. */\nexport class UCPVerificationError extends Error {\n constructor(\n public readonly code:\n | 'no_signature'\n | 'missing_kid'\n | 'kid_not_found'\n | 'duplicate_kid'\n | 'unsupported_alg'\n | 'wrong_typ'\n | 'signature_invalid'\n | 'body_mismatch'\n | 'malformed_jws'\n | 'malformed_jwks'\n | 'unrecognized_critical_header'\n | 'unusable_key',\n message: string,\n ) {\n super(message);\n this.name = 'UCPVerificationError';\n }\n}\n\nasync function loadJose(): Promise<typeof import('jose')> {\n try {\n return await import('jose');\n } catch (err) {\n throw new Error(\n `UCP signing requires the \\`jose\\` library, which is an optional peer dependency. ${JOSE_INSTALL_HINT}\\nOriginal error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\n/**\n * Canonicalize a UCP profile for signing. Removes the `signature` field (if present),\n * sorts keys deterministically, and returns the JSON string. Both signer and verifier\n * compute the same bytes.\n *\n * Implementation note: UCP §6.2 specifies \"the JSON-serialized profile body, with\n * `signature` removed and keys ordered lexicographically at every nesting level.\" This\n * is JCS-style canonicalization without the full RFC 8785 numeric handling — UCP\n * profiles don't contain floats so the simpler key-sort is sufficient.\n */\nfunction canonicalizeProfile(profile: UCPProfile): string {\n const stripped = { ...profile } as Record<string, unknown>;\n delete stripped.signature;\n return stableStringify(stripped);\n}\n\n/** Deterministic JSON.stringify with lexicographic key ordering at every level.\n * Rejects ANY non-finite Number (NaN, Infinity, -Infinity) and any Number\n * whose value has a fractional part OR whose JSON representation may diverge\n * cross-language. Cross-language float canonicalization (RFC 8785 §3.2.2.3)\n * is not stable between Node's JSON.stringify and Python's json.dumps\n * (e.g. `1.0` → `1` vs `1.0`, `1e-7` → `1e-7` vs `1e-07`). UCP profiles\n * must use decimal strings for monetary or fractional fields to preserve\n * byte parity with the Python sibling. */\nfunction stableStringify(value: unknown): string {\n if (value === undefined) {\n throw new Error(\n 'stableStringify: undefined values are not allowed in canonicalized JSON. ' +\n 'Object fields with no value must be omitted.',\n );\n }\n if (typeof value === 'function' || typeof value === 'symbol') {\n throw new Error(`stableStringify: ${typeof value} values are not allowed in canonicalized JSON.`);\n }\n if (typeof value === 'bigint') {\n throw new Error('stableStringify: BigInt values are not allowed; use a decimal string.');\n }\n if (value instanceof Date) {\n throw new Error(\n 'stableStringify: Date instances are not allowed; serialize to an ISO string before passing.',\n );\n }\n if (value instanceof Map || value instanceof Set || value instanceof WeakMap || value instanceof WeakSet) {\n throw new Error(\n `stableStringify: ${value.constructor.name} values are not allowed; convert to a plain object/array first.`,\n );\n }\n if (ArrayBuffer.isView(value)) {\n throw new Error('stableStringify: typed arrays are not allowed; convert to a plain array first.');\n }\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n throw new Error(\n `UCP profile canonicalization rejects non-finite Number ${value}. Use a decimal string for any value that may be NaN/Infinity.`,\n );\n }\n if (!Number.isInteger(value)) {\n throw new Error(\n `UCP profile canonicalization rejects non-integer Number ${value}. Use a decimal string (e.g. \"9.99\") for monetary or fractional fields to preserve cross-language byte-parity.`,\n );\n }\n if (!Number.isSafeInteger(value)) {\n throw new Error(\n `stableStringify: integer ${value} exceeds Number.MAX_SAFE_INTEGER. ` +\n 'For values >2^53, use a decimal string to preserve cross-language byte parity.',\n );\n }\n }\n if (typeof value === 'string') {\n // Cross-language byte parity: pre-ES2019 V8 (and any environment whose\n // JSON.stringify still escapes U+2028 / U+2029) emits \\u2028 / \\u2029\n // for these codepoints, while Python's json.dumps with ensure_ascii=False\n // emits them raw. A string carrying either would canonicalize to different\n // bytes across the Node and Python siblings and break signature\n // verification at the language boundary. Mirror the rejection in\n // core/api/src/lib/canonicalize.ts so the contract stays symmetric.\n if (value.includes('\\u2028') || value.includes('\\u2029')) {\n throw new Error(\n 'stableStringify: strings containing U+2028 (LINE SEPARATOR) or U+2029 (PARAGRAPH SEPARATOR) are not allowed; cross-language byte parity requires neither be present (Node JSON.stringify on older V8 escapes them; Python json.dumps with ensure_ascii=False does not).',\n );\n }\n return JSON.stringify(value);\n }\n if (value === null || typeof value !== 'object') return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort((a, b) => {\n const aPoints = [...a].map((c) => c.codePointAt(0)!);\n const bPoints = [...b].map((c) => c.codePointAt(0)!);\n const len = Math.min(aPoints.length, bPoints.length);\n for (let i = 0; i < len; i += 1) {\n if (aPoints[i] !== bPoints[i]) return aPoints[i] - bPoints[i];\n }\n return aPoints.length - bPoints.length;\n });\n // Cross-language byte parity: same rejection rationale as the string-value\n // branch above. Object keys flow through JSON.stringify(k) at the pairs line\n // below, so without this check a key carrying U+2028 / U+2029 would pass on\n // modern V8 but Python's _reject_unsafe_numbers (which recurses into dict\n // keys) would throw at verify time.\n for (const k of keys) {\n if (k.includes('
') || k.includes('
')) {\n throw new Error(\n 'stableStringify: object keys containing U+2028 (LINE SEPARATOR) or U+2029 (PARAGRAPH SEPARATOR) are not allowed; cross-language byte parity (Node JSON.stringify on older V8 escapes them; Python json.dumps with ensure_ascii=False does not).',\n );\n }\n }\n const pairs = keys.map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`);\n return `{${pairs.join(',')}}`;\n}\n\n/**\n * Generate a fresh Ed25519 (default) or ES256 keypair for signing UCP profiles.\n *\n * The `privateKey` is an opaque KeyLike — store it server-side and pass to\n * `signUCPProfile()`. Never log or transmit the private key.\n *\n * The `publicJWK` is what you publish at `/.well-known/jwks.json` and inline in the\n * UCP profile's `signing_keys[]` array.\n *\n * Example:\n * ```ts\n * import { generateUCPSigningKey } from '@agent-score/commerce';\n *\n * const { privateKey, publicJWK } = await generateUCPSigningKey({ kid: 'merchant-2026-05' });\n * // Persist privateKey securely (env var, KMS, secret manager).\n * // Publish publicJWK at /.well-known/jwks.json and reference it in your UCP profile.\n * ```\n */\nexport async function generateUCPSigningKey(opts: {\n /** Key ID (kid). Must be unique per key; you'll reference this in the UCP profile's `signing_keys[]`. */\n kid: string;\n /** Signing algorithm. Default `EdDSA`. */\n alg?: 'EdDSA' | 'ES256';\n}): Promise<GeneratedUCPKey> {\n const jose = await loadJose();\n const alg = opts.alg ?? 'EdDSA';\n const { privateKey, publicKey } = await jose.generateKeyPair(alg, { extractable: true });\n const exportedJwk = await jose.exportJWK(publicKey);\n\n const publicJWK: UCPSigningKey = {\n kid: opts.kid,\n alg,\n use: 'sig',\n ...exportedJwk,\n } as UCPSigningKey;\n\n return { privateKey, publicJWK };\n}\n\n/**\n * Sign a UCP profile, returning a new envelope with the JWS attached as `signature`.\n *\n * The signature covers the canonicalized profile body (everything except `signature`\n * itself, with keys sorted at every level). Trust-mode UCP verifiers reconstruct the\n * canonical body, look up the key referenced by the JWS header's `kid`, and validate.\n *\n * The profile's `signing_keys[]` MUST already include a JWK with the matching `kid`\n * — otherwise verifiers can't find the public key. Add the `publicJWK` from\n * `generateUCPSigningKey()` to your `signing_keys[]` before calling this.\n *\n * Example:\n * ```ts\n * const profile = buildUCPProfile({ ..., signing_keys: [publicJWK] });\n * const signed = await signUCPProfile(profile, { signingKey: privateKey, kid: 'merchant-2026-05' });\n * c.json(signed);\n * ```\n */\nexport async function signUCPProfile(\n profile: UCPProfile,\n {\n signingKey,\n kid,\n alg = 'EdDSA',\n }: {\n /** Private signing key — opaque KeyLike from `generateUCPSigningKey()` or `importJWK()`. */\n signingKey: unknown;\n /** Key ID (must match a `kid` in the profile's `signing_keys[]`). */\n kid: string;\n /** Signing algorithm — `EdDSA` (default) or `ES256`. */\n alg?: 'EdDSA' | 'ES256';\n },\n): Promise<SignedUCPProfile> {\n const jose = await loadJose();\n\n if (!ALLOWED_ALGS.includes(alg as AllowedAlg)) {\n throw new Error(\n `signUCPProfile: alg ${JSON.stringify(alg)} is not in the supported set [${ALLOWED_ALGS.join(', ')}].`,\n );\n }\n\n // Sign-time kid sanity check: the profile's `signing_keys[]` MUST contain a\n // JWK with the matching kid; otherwise verifiers can't resolve the public\n // key and the profile is dead-on-arrival. Catch this at sign-time rather\n // than at verifier-time in production.\n if (typeof kid !== 'string' || !kid) {\n throw new Error('signUCPProfile: kid must be a non-empty string.');\n }\n const kids = (profile.signing_keys ?? []).map((k) => (k as Record<string, unknown>).kid);\n if (!kids.includes(kid)) {\n throw new Error(\n `signUCPProfile: kid ${JSON.stringify(kid)} is not present in profile.signing_keys[] (declared kids: ${JSON.stringify(kids)}). Verifiers will not find the key.`,\n );\n }\n\n const canonicalBody = canonicalizeProfile(profile);\n const payloadBytes = new TextEncoder().encode(canonicalBody);\n\n const signature = await new jose.CompactSign(payloadBytes)\n .setProtectedHeader({ alg, kid, typ: PROFILE_TYP })\n .sign(signingKey as Parameters<typeof jose.CompactSign.prototype.sign>[0]);\n\n return { ...profile, signature };\n}\n\n/**\n * Verify a signed UCP profile against a JWKS. Returns `true` when the JWS validates\n * against a matching key in `jwks`; throws on signature mismatch, missing key, or\n * canonicalization drift.\n *\n * Round-trip helper for tests and for cross-merchant verification flows. Trust-mode\n * UCP clients use the same algorithm.\n *\n * Example:\n * ```ts\n * const ok = await verifyUCPProfile(signedProfile, { keys: [publicJWK] });\n * ```\n */\nexport async function verifyUCPProfile(\n profile: SignedUCPProfile,\n jwks: JWKSResponse,\n): Promise<boolean> {\n if (profile === null || typeof profile !== 'object' || Array.isArray(profile)) {\n throw new UCPVerificationError(\n 'no_signature',\n `UCP profile must be a JSON object; got ${profile === null ? 'null' : Array.isArray(profile) ? 'array' : typeof profile}.`,\n );\n }\n\n const jose = await loadJose();\n\n // JWKS shape guard so a malformed argument emits a typed UCPVerificationError\n // rather than a raw TypeError on `.filter is not a function`.\n if (!jwks || typeof jwks !== 'object' || !Array.isArray((jwks as { keys?: unknown }).keys)) {\n throw new UCPVerificationError(\n 'malformed_jwks',\n `UCP verifier expected JWKS shape { keys: [...] }; got ${jwks === null ? 'null' : typeof jwks === 'object' ? 'object without keys[] array' : typeof jwks}.`,\n );\n }\n\n const stripped = { ...profile } as Partial<SignedUCPProfile>;\n const sig = stripped.signature;\n delete stripped.signature;\n if (typeof sig !== 'string' || !sig) {\n throw new UCPVerificationError(\n 'no_signature',\n `UCP profile signature must be a non-empty string; got ${sig === undefined ? 'undefined' : typeof sig}.`,\n );\n }\n\n // Pre-decode the protected header so typ → alg → kid → crit checks run BEFORE\n // jose's compactVerify. jose enforces `crit` internally ahead of the key-resolver\n // callback, which would surface `unrecognized_critical_header` on a JWS that\n // also has a wrong typ; the python-commerce sibling's `_peek_jws_header` decodes\n // the header manually and checks typ first. Mirroring that ordering here means\n // a JWS with multiple header faults emits the same `code` in both SDKs.\n let header: { alg?: unknown; kid?: unknown; typ?: unknown; crit?: unknown };\n try {\n const protectedB64 = sig.split('.')[0];\n if (!protectedB64) throw new Error('JWS protected header segment is empty.');\n const headerJson = new TextDecoder().decode(jose.base64url.decode(protectedB64));\n const parsed = JSON.parse(headerJson);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error('JWS protected header is not a JSON object.');\n }\n header = parsed as { alg?: unknown; kid?: unknown; typ?: unknown; crit?: unknown };\n } catch (err) {\n throw new UCPVerificationError(\n 'malformed_jws',\n `JWS protected header is not valid base64url-encoded JSON: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n // Header check order is typ → alg → kid → crit to match the Python sibling's\n // _peek_jws_header. RFC 8725 §3.11: enforce expected typ to prevent\n // cross-protocol token reuse.\n if (header.typ !== PROFILE_TYP) {\n throw new UCPVerificationError('wrong_typ', `UCP signature typ must be \"${PROFILE_TYP}\"; got ${String(header.typ)}.`);\n }\n // RFC 8725 §3.1: restrict to allow-listed algorithms before key resolution\n // so a hostile JWK can never be used with HS256/none/RS256/etc.\n if (!ALLOWED_ALGS.includes(header.alg as AllowedAlg)) {\n throw new UCPVerificationError('unsupported_alg', `UCP signing alg must be one of ${ALLOWED_ALGS.join(', ')}; got ${String(header.alg)}.`);\n }\n // Strict string check: a non-string kid (number/bool/null) could accidentally\n // match a JWK with an equal-typed kid and mask attacks.\n if (typeof header.kid !== 'string' || !header.kid) {\n throw new UCPVerificationError(\n 'missing_kid',\n `UCP signature header kid must be a non-empty string; got ${header.kid === undefined ? 'undefined' : typeof header.kid}.`,\n );\n }\n // RFC 7515 §4.1.11: `crit` MUST be a non-empty array of strings if present.\n // Shape-check first (matches python-commerce's malformed_jws split) so that\n // explicit `crit: null` / `crit: []` / `crit: \"foo\"` / `crit: [42]` aren't\n // silently accepted; only well-formed crit arrays fall through to the\n // unrecognized-extension check (RFC 8725 §3.10 — UCP defines no crit headers).\n if ('crit' in header) {\n const crit = (header as { crit?: unknown }).crit;\n if (!Array.isArray(crit) || crit.length === 0 || !crit.every((c) => typeof c === 'string')) {\n throw new UCPVerificationError(\n 'malformed_jws',\n `JWS protected header crit must be a non-empty array of strings; got ${JSON.stringify(crit)}.`,\n );\n }\n throw new UCPVerificationError(\n 'unrecognized_critical_header',\n `JWS protected header advertises unrecognized crit headers: ${JSON.stringify(crit)}.`,\n );\n }\n\n let signedPayload: Uint8Array;\n try {\n const verified = await jose.compactVerify(\n sig,\n async (h) => {\n // typ/alg/kid/crit were validated up-front against the pre-decoded header;\n // this resolver only handles JWK lookup. Re-checking kid here keeps the\n // jose API satisfied and provides defense-in-depth against any header\n // re-parse divergence between this code path and jose's internals.\n const kid = h.kid;\n if (typeof kid !== 'string' || !kid) {\n throw new UCPVerificationError(\n 'missing_kid',\n `UCP signature header kid must be a non-empty string; got ${kid === undefined ? 'undefined' : typeof kid}.`,\n );\n }\n const matches = jwks.keys.filter(\n (k) => k != null && typeof k === 'object' && (k as Record<string, unknown>).kid === kid,\n );\n if (matches.length === 0) throw new UCPVerificationError('kid_not_found', `No JWK in JWKS matching kid=${JSON.stringify(kid)}.`);\n if (matches.length > 1) throw new UCPVerificationError('duplicate_kid', `JWKS contains ${matches.length} keys with kid=${JSON.stringify(kid)}; expected exactly one.`);\n // RFC 7517 §4.2: reject keys not intended for signature verification.\n // `use` and `alg` are optional per RFC 7517; an explicit JSON null is\n // out-of-spec but treat it as absent (skip-on-null) so a JWK with\n // `\"use\": null` matches Python's `is not None` semantics in\n // ucp_jwks.py and the two languages stay symmetric.\n const matchedKey = matches[0] as Record<string, unknown>;\n if (matchedKey.use != null && matchedKey.use !== 'sig') {\n throw new UCPVerificationError('unusable_key', `JWK with kid=${kid} has use=${JSON.stringify(matchedKey.use)}; expected \"sig\".`);\n }\n // RFC 7517 §4.4: a JWK with a declared `alg` field constrains its use to that algorithm.\n if (matchedKey.alg != null && matchedKey.alg !== h.alg) {\n throw new UCPVerificationError(\n 'unusable_key',\n `JWK alg ${JSON.stringify(matchedKey.alg)} does not match JWS header alg ${JSON.stringify(h.alg)}.`,\n );\n }\n return jose.importJWK(matches[0] as Parameters<typeof jose.importJWK>[0], h.alg);\n },\n );\n signedPayload = verified.payload;\n } catch (err) {\n if (err instanceof UCPVerificationError) throw err;\n if (err instanceof Error && err.name === 'JOSEAlgNotAllowed') {\n throw new UCPVerificationError('unsupported_alg', `UCP signing alg not allowed: ${err.message}`);\n }\n if (err instanceof Error && err.name === 'JWSSignatureVerificationFailed') {\n throw new UCPVerificationError('signature_invalid', `UCP signature verification failed: ${err.message}`);\n }\n if (err instanceof Error && err.name === 'JWSInvalid') {\n throw new UCPVerificationError('malformed_jws', `Malformed JWS: ${err.message}`);\n }\n // RFC 7515 §4.1.11 / RFC 8725 §3.10: a verifier MUST reject any JWS whose\n // `crit` header carries an extension the implementation doesn't understand.\n // jose throws JOSENotSupported; wrap so callers see the typed error.\n if (err instanceof Error && err.name === 'JOSENotSupported') {\n throw new UCPVerificationError('unrecognized_critical_header', `UCP signing rejected unrecognized critical header: ${err.message}`);\n }\n throw err;\n }\n\n let canonicalBody: string;\n try {\n canonicalBody = canonicalizeProfile(stripped as UCPProfile);\n } catch (err) {\n throw new UCPVerificationError(\n 'body_mismatch',\n `Failed to canonicalize received profile for verification: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n const expectedPayload = new TextEncoder().encode(canonicalBody);\n\n // Compare the bytes that were actually signed against the canonical body of the\n // profile we received. `compactVerify` validates the JWS against the bytes embedded\n // in the JWS payload segment, but the profile body could have been swapped after\n // signing while the JWS stayed unchanged. Body-vs-payload comparison closes that\n // gap.\n if (!constantTimeEqual(signedPayload, expectedPayload)) {\n throw new UCPVerificationError('body_mismatch', 'UCP profile body does not match the signed payload (tampered or non-canonical).');\n }\n\n return true;\n}\n\n/** Constant-time byte comparison to avoid leaking length / position info on mismatch. */\nfunction constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i += 1) {\n diff |= a[i] ^ b[i];\n }\n return diff === 0;\n}\n\n/**\n * Build a JWKS document for `/.well-known/jwks.json`.\n *\n * Example:\n * ```ts\n * import { buildJWKSResponse } from '@agent-score/commerce';\n *\n * app.get('/.well-known/jwks.json', (c) =>\n * c.json(buildJWKSResponse([publicJWK]))\n * );\n * ```\n */\nexport function buildJWKSResponse(keys: UCPSigningKey[]): JWKSResponse {\n return { keys };\n}\n\n// ── env-driven loader (extracted from store + martin + signed_ucp_merchant) ──\n\ninterface ResolvedLoadUCPSigningKeyOpts {\n envJwkVar: string;\n envKidVar: string;\n envAlgVar: string;\n defaultKid: string;\n defaultAlg: 'EdDSA' | 'ES256';\n}\n\nconst DEFAULT_LOAD_OPTS: ResolvedLoadUCPSigningKeyOpts = {\n envJwkVar: 'UCP_SIGNING_KEY_JWK_PRIVATE',\n envKidVar: 'UCP_SIGNING_KEY_KID',\n envAlgVar: 'UCP_SIGNING_KEY_ALG',\n defaultKid: 'merchant-default',\n defaultAlg: 'EdDSA',\n};\n\nfunction readEnvTrimmed(name: string): string | undefined {\n const raw = process.env[name];\n if (raw === undefined) return undefined;\n const trimmed = raw.trim();\n return trimmed === '' ? undefined : trimmed;\n}\n\nfunction detectAlgFromJwk(jwk: Record<string, unknown>): 'EdDSA' | 'ES256' | null {\n if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') return 'EdDSA';\n if (jwk.kty === 'EC' && jwk.crv === 'P-256') return 'ES256';\n return null;\n}\n\n// Cache entries are keyed by the full resolved opts (so different opts get separate\n// entries) and store the IN-FLIGHT Promise — concurrent first-callers with the same\n// opts await the same key generation rather than racing to produce different ephemeral\n// keys (a losing keypair signing a JWS that the published JWKS then rejects).\nconst envLoaderCache = new Map<string, Promise<GeneratedUCPKey>>();\n\nfunction cacheKey(opts: ResolvedLoadUCPSigningKeyOpts): string {\n return `${opts.envJwkVar}|${opts.envKidVar}|${opts.envAlgVar}|${opts.defaultKid}|${opts.defaultAlg}`;\n}\n\nasync function buildEnvSigningKey(\n opts: ResolvedLoadUCPSigningKeyOpts,\n): Promise<GeneratedUCPKey> {\n const kidDefault = readEnvTrimmed(opts.envKidVar) ?? opts.defaultKid;\n // Case-insensitive env-alg comparison: secret configs commonly carry casing drift\n // (`\"es256\"`, `\" ES256 \"`, `\"eS256\"`). Strict exact-match would silently downgrade\n // to the default and operators would publish a JWKS with the wrong key family.\n const rawAlg = (readEnvTrimmed(opts.envAlgVar) ?? '').toUpperCase();\n const algFallback: 'EdDSA' | 'ES256' = rawAlg === 'ES256' ? 'ES256' : opts.defaultAlg;\n\n const envJwk = readEnvTrimmed(opts.envJwkVar);\n if (envJwk) {\n let jwkDict: Record<string, unknown>;\n try {\n jwkDict = JSON.parse(envJwk) as Record<string, unknown>;\n } catch (err) {\n throw new Error(\n `${opts.envJwkVar} is not valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (!jwkDict || typeof jwkDict !== 'object' || Array.isArray(jwkDict) || Object.keys(jwkDict).length === 0) {\n throw new Error(`${opts.envJwkVar} must be a non-empty JWK object.`);\n }\n\n const detectedAlg = detectAlgFromJwk(jwkDict);\n if (!detectedAlg) {\n throw new Error(\n `${opts.envJwkVar} has unsupported kty/crv (got kty=${String(jwkDict.kty)} crv=${String(jwkDict.crv)}); ` +\n 'expected OKP+Ed25519 or EC+P-256.',\n );\n }\n\n // Project the env JWK to its canonical key fields before importing. Unknown\n // env-JWK fields (`key_ops`, `x5c`, `x5t`, `x5u`, etc.) trip Node's\n // createPublicKey with NotSupportedError on some runtimes; canonical-only\n // input is stable across Node + Bun + browser WebCrypto.\n const canonicalPrivateJwk: Record<string, unknown> =\n detectedAlg === 'EdDSA'\n ? { kty: jwkDict.kty, crv: jwkDict.crv, x: jwkDict.x, d: jwkDict.d }\n : { kty: jwkDict.kty, crv: jwkDict.crv, x: jwkDict.x, y: jwkDict.y, d: jwkDict.d };\n\n // Import the private key. Sanitize errors so JWK byte material can never reach logs.\n const { importJWK } = await import('jose');\n const { createPublicKey } = await import('node:crypto');\n let privateKey: Awaited<ReturnType<typeof importJWK>>;\n let publicNodeKey: ReturnType<typeof createPublicKey>;\n try {\n privateKey = await importJWK(\n canonicalPrivateJwk as unknown as Parameters<typeof importJWK>[0],\n detectedAlg,\n );\n publicNodeKey = createPublicKey({ key: canonicalPrivateJwk as never, format: 'jwk' });\n } catch (err) {\n const className = err instanceof Error ? err.constructor.name : typeof err;\n const code =\n err && typeof err === 'object' && 'code' in err\n ? String((err as { code?: unknown }).code)\n : null;\n const codeSuffix = code ? ` [${code}]` : '';\n throw new Error(\n `${opts.envJwkVar} has malformed key material (${className}${codeSuffix}). ` +\n 'Verify the JWK is well-formed and matches the declared kty/crv. ' +\n 'Underlying details suppressed to avoid leaking key bytes.',\n );\n }\n\n // Derive a canonical public JWK from the public node key — drops `d` and any other\n // private-only fields (and unknown env JWK fields like key_ops, x5c, x5t).\n const publicJWK = publicNodeKey.export({ format: 'jwk' }) as unknown as UCPSigningKey;\n // Empty-string kid in env JWK falls through to the configured default —\n // publishing `\"kid\": \"\"` breaks every kid-pinning verifier.\n publicJWK.kid = (jwkDict.kid as string | undefined) || kidDefault;\n publicJWK.alg = detectedAlg;\n publicJWK.use = 'sig';\n\n return { privateKey, publicJWK };\n }\n\n // Ephemeral fallback — generate a fresh keypair.\n return generateUCPSigningKey({ kid: kidDefault, alg: algFallback });\n}\n\n/**\n * Load the merchant's UCP signing key from env, with concurrent-safe caching.\n *\n * On first call (per `opts`): reads `opts.envJwkVar`, parses it as a JWK, validates\n * `kty`/`crv` (OKP+Ed25519 or EC+P-256), and projects to a canonical public JWK.\n * Falls back to an ephemeral keypair when the env var is missing or whitespace-only.\n *\n * Subsequent calls with the same `opts` return the cached key without re-reading env.\n * Concurrent first-callers await the same in-flight Promise so only one key generation\n * runs (preventing the race where two callers each generate an independent ephemeral\n * pair and one signs a JWS the published JWKS then rejects).\n *\n * Different `opts` values get separate cache entries.\n *\n * Env-driven precedence:\n *\n * - Embedded `kid` in the JWK wins over `opts.envKidVar` env value;\n * empty-string `kid` in the env JWK falls through to `opts.defaultKid`.\n * - Structural `kty`+`crv` in the JWK wins over `opts.envAlgVar` env value\n * (which is only consulted in the ephemeral fallback path).\n *\n * @throws Error with a sanitized message for malformed env JWKs; raw exception\n * detail is intentionally suppressed so key bytes can never reach logs.\n */\nexport async function loadUCPSigningKeyFromEnv({\n envJwkVar,\n envKidVar,\n envAlgVar,\n defaultKid,\n defaultAlg,\n}: {\n /** Env var name carrying the JSON-encoded private JWK. Default `UCP_SIGNING_KEY_JWK_PRIVATE`. */\n envJwkVar?: string;\n /** Env var name carrying an explicit kid override. Default `UCP_SIGNING_KEY_KID`. */\n envKidVar?: string;\n /** Env var name carrying the alg in the ephemeral fallback. Default `UCP_SIGNING_KEY_ALG`. */\n envAlgVar?: string;\n /** Kid to publish when neither the env JWK nor `envKidVar` carries one. Default `merchant-default`. */\n defaultKid?: string;\n /** Alg for the ephemeral fallback path. Default `EdDSA`. */\n defaultAlg?: 'EdDSA' | 'ES256';\n} = {}): Promise<GeneratedUCPKey> {\n const resolved: ResolvedLoadUCPSigningKeyOpts = {\n ...DEFAULT_LOAD_OPTS,\n ...(envJwkVar !== undefined && { envJwkVar }),\n ...(envKidVar !== undefined && { envKidVar }),\n ...(envAlgVar !== undefined && { envAlgVar }),\n ...(defaultKid !== undefined && { defaultKid }),\n ...(defaultAlg !== undefined && { defaultAlg }),\n };\n const key = cacheKey(resolved);\n let cached = envLoaderCache.get(key);\n if (cached) return cached;\n // Pin the in-flight Promise so concurrent first-callers await the same generation.\n cached = buildEnvSigningKey(resolved).catch((err) => {\n // Clear on rejection so a transient malformed env doesn't permanently poison\n // every future call — the next caller retries the build.\n envLoaderCache.delete(key);\n throw err;\n });\n envLoaderCache.set(key, cached);\n return cached;\n}\n\n/** Test-only: clear the env-loader cache.\n *\n * Use after stubbing `process.env.UCP_SIGNING_KEY_*` to force the next\n * {@link loadUCPSigningKeyFromEnv} call to re-read the env state. */\nexport function _resetUCPSigningKeyCache(): void {\n envLoaderCache.clear();\n}\n","/**\n * Spec-rooted helpers for `/.well-known/{ucp,jwks.json}` discovery surfaces.\n *\n * What this module collapses for every UCP-publishing merchant:\n *\n * - Loading + caching the signing key via `loadUCPSigningKeyFromEnv`.\n * - Composing the `payment_handlers` map from the merchant's `Checkout` rails\n * (TempoRailSpec → mppPaymentHandler; X402BaseRailSpec → x402PaymentHandler;\n * StripeRailSpec → stripeSptPaymentHandler).\n * - Building the unsigned profile + signing it.\n * - Cache-Control + CORS + X-Request-ID echo per UCP section 6.\n * - RFC 7517 section 8.5 `application/jwk-set+json` media type on JWKS.\n * - The 503 `ucp_misconfigured` fallback envelope when no handlers can be\n * derived (empty rails dict OR all rails have empty recipients).\n *\n * Each helper returns a framework-neutral `SignedDiscoveryResponse` that\n * merchants wrap in their framework's Response builder (Hono `c.body`, Express\n * `res.set/.status/.send`, Fastify `reply.headers/.code/.send`, Next.js\n * `NextResponse`, Web Fetch `new Response`, etc.).\n */\n\nimport {\n type AgentScoreGatePolicy,\n buildUCPProfile,\n mppPaymentHandler,\n stripeSptPaymentHandler,\n type UCPPaymentHandlerBinding,\n type UCPServiceBinding,\n UCPSigningKey,\n x402PaymentHandler,\n} from '../identity/ucp';\nimport {\n buildJWKSResponse,\n loadUCPSigningKeyFromEnv,\n signUCPProfile,\n} from '../identity/ucp-jwks';\nimport type { Checkout, CheckoutRailSpec } from '../checkout';\nimport type {\n SolanaMppRailSpec,\n StripeRailSpec,\n TempoRailSpec,\n TempoSessionRailSpec,\n X402BaseRailSpec,\n} from '../payment/rail_spec';\n\nconst UCP_CACHE_SECONDS = 60;\nconst JWKS_CACHE_SECONDS = 300;\nconst UCP_SHOPPING_SPEC_2026_04_08 = 'https://ucp.dev/2026-04-08/specification/overview';\n\n/**\n * Framework-neutral response shape for discovery endpoints.\n *\n * Wrap in your framework's response builder. `body` is already JSON-encoded\n * bytes (as a string); do not re-serialize.\n */\nexport interface SignedDiscoveryResponse {\n body: string;\n mediaType: string;\n headers: Record<string, string>;\n status: number;\n}\n\nfunction requestId(headers: Headers | Record<string, string> | undefined): string | undefined {\n if (headers === undefined) return undefined;\n if (headers instanceof Headers) return headers.get('x-request-id') ?? undefined;\n for (const [k, v] of Object.entries(headers)) {\n if (k.toLowerCase() === 'x-request-id') return v;\n }\n return undefined;\n}\n\nfunction attachRequestId(\n headers: Record<string, string>,\n requestHeaders: Headers | Record<string, string> | undefined,\n): void {\n const rid = requestId(requestHeaders);\n if (rid !== undefined) headers['X-Request-ID'] = rid;\n}\n\nfunction isTempoSession(s: CheckoutRailSpec): s is TempoSessionRailSpec {\n return 'escrowContract' in s && 'store' in s;\n}\nfunction isStripe(s: CheckoutRailSpec): s is StripeRailSpec {\n return !('recipient' in s);\n}\n/** A rail spec qualifies for UCP publication when `recipient` is defined —\n * whether concrete (`'0xabc'`), empty-string sentinel (per-order minted by\n * the consumer), or a factory callable (per-order minted on demand). The\n * `tempoToNetworkEntry` / `x402ToNetworkEntry` builders drop the recipient\n * field from the emitted UCP entry when it's not a static address, so per-\n * order-mint merchants advertise the rail without leaking a sentinel. */\nfunction railHasRecipientField(spec: { recipient?: unknown }): boolean {\n return Object.hasOwn(spec, 'recipient');\n}\n\nfunction composeHandlers(checkout: Checkout): Record<string, UCPPaymentHandlerBinding[]> {\n const handlers: Record<string, UCPPaymentHandlerBinding[]> = {};\n const mpp: (TempoRailSpec | SolanaMppRailSpec | TempoSessionRailSpec)[] = [];\n const x402: X402BaseRailSpec[] = [];\n const stripe: StripeRailSpec[] = [];\n\n for (const spec of Object.values(checkout.rails)) {\n if (isStripe(spec)) {\n stripe.push(spec);\n continue;\n }\n if (isTempoSession(spec)) {\n if (railHasRecipientField(spec)) mpp.push(spec);\n continue;\n }\n // Distinguish Tempo (`symbol: 'USDC.e'` or `network: 'tempo-*'`) from x402-Base\n // (CAIP-2 `eip155:*`) and Solana (`network: 'solana:*'`).\n const network = (spec as { network?: string }).network ?? '';\n if (network.startsWith('eip155:') || ('mode' in spec)) {\n if (railHasRecipientField(spec)) x402.push(spec as X402BaseRailSpec);\n } else if (network.startsWith('solana:') || 'rpcUrl' in spec) {\n if (railHasRecipientField(spec)) mpp.push(spec as SolanaMppRailSpec);\n } else {\n // Default to Tempo (network starts with `tempo-` or symbol is `USDC.e`).\n if (railHasRecipientField(spec)) mpp.push(spec as TempoRailSpec);\n }\n }\n\n if (mpp.length > 0) Object.assign(handlers, mppPaymentHandler({ networks: mpp }));\n if (x402.length > 0) Object.assign(handlers, x402PaymentHandler({ networks: x402 }));\n for (const spec of stripe) Object.assign(handlers, stripeSptPaymentHandler({ spec }));\n return handlers;\n}\n\nfunction misconfiguredResponse(\n requestHeaders: Headers | Record<string, string> | undefined,\n): SignedDiscoveryResponse {\n const body = {\n error: {\n code: 'ucp_misconfigured',\n message: 'Merchant has no configured payment handlers.',\n },\n next_steps: {\n action: 'contact_merchant',\n user_message: 'This merchant is temporarily unable to accept agent payments.',\n },\n agent_instructions: {\n action: 'contact_merchant',\n steps: [\n 'Surface a transient error to the user.',\n 'Retry later; the merchant operator will repair the configuration.',\n ],\n user_message: 'Merchant temporarily offline for agent payments.',\n },\n };\n // UCP section 6 forbids `no-store` on profile responses; 60s is the minimum\n // cache age (short enough that recovery is fast once the merchant restores\n // config).\n const headers: Record<string, string> = {\n 'Access-Control-Allow-Origin': '*',\n 'Cache-Control': `public, max-age=${UCP_CACHE_SECONDS}`,\n };\n attachRequestId(headers, requestHeaders);\n return {\n body: JSON.stringify(body),\n mediaType: 'application/json',\n headers,\n status: 503,\n };\n}\n\n/**\n * Build the signed UCP profile response for `/.well-known/ucp`.\n *\n * Composes payment handlers from the Checkout's rails dict, builds the profile\n * via `buildUCPProfile`, signs via `signUCPProfile`, and attaches the UCP\n * section 6-prescribed Cache-Control + CORS + X-Request-ID headers.\n *\n * Returns a 503 `ucp_misconfigured` envelope (still with the section 6-compliant\n * Cache-Control) when no payment handlers can be derived from rails.\n *\n * `services` is the spec-compliant services map (keyed by reverse-DNS service\n * name). `wellKnownUcpUrl` is the canonical URL of this profile, surfaced as\n * the value in `supported_versions`.\n */\nexport async function buildSignedUcpResponse(opts: {\n checkout: Checkout;\n name: string;\n wellKnownUcpUrl: string;\n services: Record<string, UCPServiceBinding[]>;\n requestHeaders?: Headers | Record<string, string>;\n signingKid?: string;\n agentscoreGate?: AgentScoreGatePolicy;\n}): Promise<SignedDiscoveryResponse> {\n const {\n checkout,\n name,\n wellKnownUcpUrl,\n services,\n requestHeaders,\n signingKid = 'merchant-default',\n agentscoreGate,\n } = opts;\n\n const handlers = composeHandlers(checkout);\n if (Object.keys(handlers).length === 0) {\n return misconfiguredResponse(requestHeaders);\n }\n\n const key = await loadUCPSigningKeyFromEnv({ defaultKid: signingKid });\n const signingKeyEntry = UCPSigningKey.fromJWK(key.publicJWK);\n\n const profile = buildUCPProfile({\n name,\n supported_versions: { '2026-04-08': wellKnownUcpUrl },\n agentscore_gate: agentscoreGate,\n services,\n payment_handlers: handlers,\n signing_keys: [signingKeyEntry],\n });\n const signed = await signUCPProfile(profile, {\n signingKey: key.privateKey,\n kid: key.publicJWK.kid as string,\n alg: (key.publicJWK.alg as 'EdDSA' | 'ES256' | undefined) ?? 'EdDSA',\n });\n const headers: Record<string, string> = {\n 'Cache-Control': `public, max-age=${UCP_CACHE_SECONDS}`,\n 'Access-Control-Allow-Origin': '*',\n };\n attachRequestId(headers, requestHeaders);\n return {\n body: JSON.stringify(signed),\n mediaType: 'application/json',\n headers,\n status: 200,\n };\n}\n\n/**\n * Build the JWKS response for `/.well-known/jwks.json`.\n *\n * RFC 7517 section 8.5 prescribes `application/jwk-set+json`. Five-minute\n * Cache-Control balances verifier-side cache hit rate against rotation\n * propagation latency.\n */\nexport async function buildSignedJwksResponse(opts?: {\n requestHeaders?: Headers | Record<string, string>;\n signingKid?: string;\n}): Promise<SignedDiscoveryResponse> {\n const { requestHeaders, signingKid = 'merchant-default' } = opts ?? {};\n const key = await loadUCPSigningKeyFromEnv({ defaultKid: signingKid });\n const jwks = buildJWKSResponse([UCPSigningKey.fromJWK(key.publicJWK)]);\n const headers: Record<string, string> = {\n 'Cache-Control': `public, max-age=${JWKS_CACHE_SECONDS}`,\n 'Access-Control-Allow-Origin': '*',\n };\n attachRequestId(headers, requestHeaders);\n return {\n body: JSON.stringify(jwks),\n mediaType: 'application/jwk-set+json',\n headers,\n status: 200,\n };\n}\n\n/**\n * CORS preflight headers for `/.well-known/*` endpoints.\n *\n * Echoes `Access-Control-Request-Headers` verbatim when present rather than\n * advertising `*` (which browsers reject with credentials in scope). Returns\n * a 204 on the corresponding response via the merchant's framework.\n */\nexport function wellKnownCorsPreflightHeaders(\n requestHeaders?: Headers | Record<string, string>,\n): Record<string, string> {\n const headers: Record<string, string> = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, OPTIONS',\n 'Access-Control-Max-Age': '86400',\n Vary: 'Access-Control-Request-Headers',\n };\n if (requestHeaders === undefined) return headers;\n const acrh =\n requestHeaders instanceof Headers\n ? requestHeaders.get('access-control-request-headers')\n : Object.entries(requestHeaders).find(([k]) => k.toLowerCase() === 'access-control-request-headers')?.[1];\n if (acrh) headers['Access-Control-Allow-Headers'] = acrh;\n return headers;\n}\n\n/**\n * Build a 204 CORS preflight `Response` for `/.well-known/*` endpoints, wrapping\n * {@link wellKnownCorsPreflightHeaders}. Universal across every UCP-publishing\n * merchant; saves the 4-line `new Response(null, { status: 204, headers: ... })`\n * wrapper every consumer otherwise hand-rolls.\n */\nexport function wellKnownPreflightResponse(\n requestHeaders?: Headers | Record<string, string>,\n): Response {\n return new Response(null, {\n status: 204,\n headers: wellKnownCorsPreflightHeaders(requestHeaders),\n });\n}\n\n/**\n * Canonical UCP services map for a merchant publishing an A2A agent card.\n *\n * Returns `{\"dev.ucp.shopping\": [UCPServiceBinding(version: '2026-04-08',\n * spec: <UCP shopping spec>, transport: 'a2a', endpoint: agentCardUrl)]}`;\n * the binding every UCP-publishing merchant declares when their primary agent\n * surface is the A2A v1.0 `/.well-known/agent-card.json` (versus a UCP MCP or\n * REST endpoint).\n *\n * Merchants who additionally expose a UCP MCP or REST transport append further\n * bindings to the same `dev.ucp.shopping` list.\n */\nexport function defaultA2aServices(opts: {\n agentCardUrl: string;\n}): Record<string, UCPServiceBinding[]> {\n return {\n 'dev.ucp.shopping': [\n {\n version: '2026-04-08',\n spec: UCP_SHOPPING_SPEC_2026_04_08,\n transport: 'a2a',\n endpoint: opts.agentCardUrl,\n },\n ],\n };\n}\n\n/**\n * Eager-load the UCP signing key at startup.\n *\n * A malformed `UCP_SIGNING_KEY_JWK_PRIVATE` env value otherwise surfaces on\n * the first `/.well-known/ucp` hit after deploy, masquerading as a runtime\n * 500. Calling this in the framework's startup hook fails the deploy fast.\n *\n * Wraps `loadUCPSigningKeyFromEnv`; throws (per that helper's contract) on a\n * malformed JWK so the orchestrator marks the task unhealthy.\n */\nexport async function bootstrapUcpSigningKey(opts?: {\n defaultKid?: string;\n}): Promise<void> {\n const defaultKid = opts?.defaultKid ?? 'merchant-default';\n await loadUCPSigningKeyFromEnv({ defaultKid });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// signedResponse<Framework> wrappers\n//\n// Convert the framework-neutral SignedDiscoveryResponse / Response (preflight)\n// into a framework-specific response. Saves the 4-line per-framework wrapper\n// every UCP-publishing merchant otherwise hand-rolls.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Hono / Web Fetch wrapper. Returns a `Response`. */\nexport function signedResponseHono(resp: SignedDiscoveryResponse): Response {\n return new Response(resp.body, {\n status: resp.status,\n headers: { ...resp.headers, 'Content-Type': resp.mediaType },\n });\n}\n\n/** Next.js wrapper. Returns a `Response` (interchangeable with NextResponse). */\nexport function signedResponseNextjs(resp: SignedDiscoveryResponse): Response {\n return signedResponseHono(resp);\n}\n\n/** Web Fetch wrapper. Returns a standard `Response`. */\nexport function signedResponseWeb(resp: SignedDiscoveryResponse): Response {\n return signedResponseHono(resp);\n}\n\n/** Express wrapper. Writes onto `res`; returns `void` to match Express convention. */\nexport function signedResponseExpress(\n res: {\n status: (code: number) => unknown;\n set: (headers: Record<string, string>) => unknown;\n type: (mt: string) => unknown;\n send: (body: string) => unknown;\n },\n resp: SignedDiscoveryResponse,\n): void {\n res.status(resp.status);\n res.set(resp.headers);\n res.type(resp.mediaType);\n res.send(resp.body);\n}\n\n/** Fastify wrapper. Writes onto `reply` and returns it. */\nexport function signedResponseFastify(\n reply: {\n code: (code: number) => unknown;\n header: (k: string, v: string) => unknown;\n type: (mt: string) => unknown;\n send: (body: string) => unknown;\n },\n resp: SignedDiscoveryResponse,\n): unknown {\n reply.code(resp.status);\n for (const [k, v] of Object.entries(resp.headers)) reply.header(k, v);\n reply.type(resp.mediaType);\n return reply.send(resp.body);\n}\n","/**\n * Echo the request-id middleware sets on the context as an `X-Request-ID`\n * response header. Agents correlate logs across 4xx retries by reading this.\n *\n * Hono variant — reads `c.get('requestId')` populated by `hono/request-id`.\n * Express / Fastify / Next.js / Web Fetch variants will follow when consumers\n * need them.\n *\n * Universal for AgentScore commerce merchants: every retry-loop pattern\n * (probe-then-pay, 403-then-resume, settle-then-retry) benefits from the\n * agent being able to grep server logs for the request id.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono';\n * import { requestId } from 'hono/request-id';\n * import { echoRequestIdHeaderHono } from '@agent-score/commerce/discovery';\n *\n * const app = new Hono();\n * app.use('*', requestId());\n * app.use('*', echoRequestIdHeaderHono());\n * ```\n */\nexport function echoRequestIdHeaderHono(): (\n c: {\n get: (key: 'requestId') => string | undefined;\n header: (name: string, value: string) => void;\n },\n next: () => Promise<void>,\n) => Promise<void> {\n return async (c, next) => {\n await next();\n const id = c.get('requestId');\n if (id) c.header('X-Request-ID', id);\n };\n}\n"],"mappings":"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","names":["rails","isStripe","rails","networks"]}