@agent-score/commerce 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +26 -11
  2. package/dist/_core-kI7FRAiZ.d.mts +10 -0
  3. package/dist/_core-kI7FRAiZ.d.ts +10 -0
  4. package/dist/challenge/index.d.mts +3 -3
  5. package/dist/challenge/index.d.ts +3 -3
  6. package/dist/challenge/index.js +21 -14
  7. package/dist/challenge/index.js.map +1 -1
  8. package/dist/challenge/index.mjs +21 -14
  9. package/dist/challenge/index.mjs.map +1 -1
  10. package/dist/{checkout-DhSj_h94.d.ts → checkout-BH-I_Ns8.d.ts} +13 -12
  11. package/dist/{checkout-jNUIql6D.d.mts → checkout-Bd_4aQ6c.d.mts} +13 -12
  12. package/dist/core.js +1 -1
  13. package/dist/core.js.map +1 -1
  14. package/dist/core.mjs +1 -1
  15. package/dist/core.mjs.map +1 -1
  16. package/dist/default_rails-BWAquZeu.d.mts +188 -0
  17. package/dist/default_rails-BxBzcCA1.d.ts +188 -0
  18. package/dist/discovery/index.d.mts +5 -5
  19. package/dist/discovery/index.d.ts +5 -5
  20. package/dist/discovery/index.js +14 -1
  21. package/dist/discovery/index.js.map +1 -1
  22. package/dist/discovery/index.mjs +14 -1
  23. package/dist/discovery/index.mjs.map +1 -1
  24. package/dist/identity/express.d.mts +7 -3
  25. package/dist/identity/express.d.ts +7 -3
  26. package/dist/identity/express.js +39 -96
  27. package/dist/identity/express.js.map +1 -1
  28. package/dist/identity/express.mjs +37 -87
  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 +60 -96
  33. package/dist/identity/fastify.js.map +1 -1
  34. package/dist/identity/fastify.mjs +58 -87
  35. package/dist/identity/fastify.mjs.map +1 -1
  36. package/dist/identity/hono.d.mts +11 -3
  37. package/dist/identity/hono.d.ts +11 -3
  38. package/dist/identity/hono.js +39 -93
  39. package/dist/identity/hono.js.map +1 -1
  40. package/dist/identity/hono.mjs +37 -84
  41. package/dist/identity/hono.mjs.map +1 -1
  42. package/dist/identity/nextjs.d.mts +10 -3
  43. package/dist/identity/nextjs.d.ts +10 -3
  44. package/dist/identity/nextjs.js +49 -93
  45. package/dist/identity/nextjs.js.map +1 -1
  46. package/dist/identity/nextjs.mjs +46 -84
  47. package/dist/identity/nextjs.mjs.map +1 -1
  48. package/dist/identity/policy.js +185 -139
  49. package/dist/identity/policy.js.map +1 -1
  50. package/dist/identity/policy.mjs +187 -141
  51. package/dist/identity/policy.mjs.map +1 -1
  52. package/dist/identity/web.d.mts +9 -3
  53. package/dist/identity/web.d.ts +9 -3
  54. package/dist/identity/web.js +45 -93
  55. package/dist/identity/web.js.map +1 -1
  56. package/dist/identity/web.mjs +42 -84
  57. package/dist/identity/web.mjs.map +1 -1
  58. package/dist/index.d.mts +554 -90
  59. package/dist/index.d.ts +554 -90
  60. package/dist/index.js +916 -162
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +904 -162
  63. package/dist/index.mjs.map +1 -1
  64. package/dist/middleware/express.d.mts +10 -0
  65. package/dist/middleware/express.d.ts +10 -0
  66. package/dist/middleware/express.js +128 -0
  67. package/dist/middleware/express.js.map +1 -0
  68. package/dist/middleware/express.mjs +91 -0
  69. package/dist/middleware/express.mjs.map +1 -0
  70. package/dist/middleware/fastify.d.mts +10 -0
  71. package/dist/middleware/fastify.d.ts +10 -0
  72. package/dist/middleware/fastify.js +127 -0
  73. package/dist/middleware/fastify.js.map +1 -0
  74. package/dist/middleware/fastify.mjs +90 -0
  75. package/dist/middleware/fastify.mjs.map +1 -0
  76. package/dist/middleware/hono.d.mts +10 -0
  77. package/dist/middleware/hono.d.ts +10 -0
  78. package/dist/middleware/hono.js +122 -0
  79. package/dist/middleware/hono.js.map +1 -0
  80. package/dist/middleware/hono.mjs +85 -0
  81. package/dist/middleware/hono.mjs.map +1 -0
  82. package/dist/middleware/nextjs.d.mts +22 -0
  83. package/dist/middleware/nextjs.d.ts +22 -0
  84. package/dist/middleware/nextjs.js +143 -0
  85. package/dist/middleware/nextjs.js.map +1 -0
  86. package/dist/middleware/nextjs.mjs +105 -0
  87. package/dist/middleware/nextjs.mjs.map +1 -0
  88. package/dist/middleware/web.d.mts +25 -0
  89. package/dist/middleware/web.d.ts +25 -0
  90. package/dist/middleware/web.js +128 -0
  91. package/dist/middleware/web.js.map +1 -0
  92. package/dist/middleware/web.mjs +91 -0
  93. package/dist/middleware/web.mjs.map +1 -0
  94. package/dist/payment/index.d.mts +21 -6
  95. package/dist/payment/index.d.ts +21 -6
  96. package/dist/payment/index.js +136 -9
  97. package/dist/payment/index.js.map +1 -1
  98. package/dist/payment/index.mjs +127 -9
  99. package/dist/payment/index.mjs.map +1 -1
  100. package/dist/{pricing-CxzwyiO6.d.mts → pricing-4n5Ota0D.d.mts} +14 -4
  101. package/dist/{pricing-CQ9DIFaw.d.ts → pricing-DHfH3ogG.d.ts} +14 -4
  102. package/dist/{rail_spec-XP0wKgJV.d.mts → rail_spec-D6qzh3J0.d.mts} +1 -1
  103. package/dist/{rail_spec-XP0wKgJV.d.ts → rail_spec-D6qzh3J0.d.ts} +1 -1
  104. package/dist/stripe-multichain/index.d.mts +150 -47
  105. package/dist/stripe-multichain/index.d.ts +150 -47
  106. package/dist/stripe-multichain/index.js +19749 -42
  107. package/dist/stripe-multichain/index.js.map +1 -1
  108. package/dist/stripe-multichain/index.mjs +19758 -27
  109. package/dist/stripe-multichain/index.mjs.map +1 -1
  110. package/dist/{x402_server-hgQzWQwB.d.mts → x402_server-Ciz2mls2.d.mts} +1 -1
  111. package/dist/{x402_server-hgQzWQwB.d.ts → x402_server-Ciz2mls2.d.ts} +1 -1
  112. package/package.json +40 -2
  113. package/dist/_response-BFYN3b6i.d.mts +0 -142
  114. package/dist/_response-_iPD5AIj.d.ts +0 -142
  115. package/dist/solana-Cds87OTu.d.mts +0 -67
  116. package/dist/solana-Cds87OTu.d.ts +0 -67
package/dist/index.mjs CHANGED
@@ -31,6 +31,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  mod
32
32
  ));
33
33
 
34
+ // src/payment/network_kind.ts
35
+ function readNetwork(input) {
36
+ if (typeof input === "string") return input;
37
+ if (input && typeof input === "object") {
38
+ const network = input.network;
39
+ return typeof network === "string" ? network : "";
40
+ }
41
+ return "";
42
+ }
43
+ function isEvmNetwork(input) {
44
+ return readNetwork(input).startsWith("eip155:");
45
+ }
46
+ function isSolanaNetwork(input) {
47
+ return readNetwork(input).startsWith("solana:");
48
+ }
49
+ var init_network_kind = __esm({
50
+ "src/payment/network_kind.ts"() {
51
+ "use strict";
52
+ }
53
+ });
54
+
34
55
  // src/identity/ucp.ts
35
56
  function ucpSigningKeyFromJWKImpl(jwk) {
36
57
  if (!jwk || typeof jwk !== "object") {
@@ -160,7 +181,7 @@ function isTempoSessionRailSpec(s) {
160
181
  }
161
182
  function mppRailToNetworkEntry(spec) {
162
183
  if (isTempoSessionRailSpec(spec)) return tempoSessionToNetworkEntry(spec);
163
- if ("rpcUrl" in spec || "tokenProgram" in spec || (spec.network?.startsWith("solana:") ?? false)) {
184
+ if ("rpcUrl" in spec || "tokenProgram" in spec || isSolanaNetwork(spec)) {
164
185
  return solanaMppToNetworkEntry(spec);
165
186
  }
166
187
  if (isTempoRailSpec(spec)) return tempoToNetworkEntry(spec);
@@ -217,6 +238,7 @@ var UCPSigningKey, DEFAULT_VERSION, AGENTSCORE_CAPABILITY_NAME, AGENTSCORE_CAPAB
217
238
  var init_ucp = __esm({
218
239
  "src/identity/ucp.ts"() {
219
240
  "use strict";
241
+ init_network_kind();
220
242
  UCPSigningKey = {
221
243
  fromJWK: ucpSigningKeyFromJWKImpl
222
244
  };
@@ -636,64 +658,6 @@ var init_ucp_jwks = __esm({
636
658
  }
637
659
  });
638
660
 
639
- // src/payment/usdc.ts
640
- var USDC;
641
- var init_usdc = __esm({
642
- "src/payment/usdc.ts"() {
643
- "use strict";
644
- USDC = {
645
- base: {
646
- mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
647
- sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
648
- },
649
- solana: {
650
- mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
651
- devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
652
- },
653
- tempo: {
654
- mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
655
- testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
656
- }
657
- };
658
- }
659
- });
660
-
661
- // src/payment/wwwauthenticate.ts
662
- function paymentRequiredHeader({
663
- x402Version,
664
- accepts,
665
- resource
666
- }) {
667
- return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
668
- }
669
- var init_wwwauthenticate = __esm({
670
- "src/payment/wwwauthenticate.ts"() {
671
- "use strict";
672
- }
673
- });
674
-
675
- // src/payment/networks.ts
676
- var networks;
677
- var init_networks = __esm({
678
- "src/payment/networks.ts"() {
679
- "use strict";
680
- networks = {
681
- base: {
682
- mainnet: { caip2: "eip155:8453", chainId: 8453 },
683
- sepolia: { caip2: "eip155:84532", chainId: 84532 }
684
- },
685
- solana: {
686
- mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
687
- devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
688
- },
689
- tempo: {
690
- mainnet: { caip2: "eip155:4217", chainId: 4217 },
691
- testnet: { caip2: "eip155:42431", chainId: 42431 }
692
- }
693
- };
694
- }
695
- });
696
-
697
661
  // node_modules/ox/_esm/core/Abi.js
698
662
  var init_Abi = __esm({
699
663
  "node_modules/ox/_esm/core/Abi.js"() {
@@ -20305,6 +20269,64 @@ var init_dist2 = __esm({
20305
20269
  }
20306
20270
  });
20307
20271
 
20272
+ // src/payment/usdc.ts
20273
+ var USDC;
20274
+ var init_usdc = __esm({
20275
+ "src/payment/usdc.ts"() {
20276
+ "use strict";
20277
+ USDC = {
20278
+ base: {
20279
+ mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
20280
+ sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
20281
+ },
20282
+ solana: {
20283
+ mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
20284
+ devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
20285
+ },
20286
+ tempo: {
20287
+ mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
20288
+ testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
20289
+ }
20290
+ };
20291
+ }
20292
+ });
20293
+
20294
+ // src/payment/wwwauthenticate.ts
20295
+ function paymentRequiredHeader({
20296
+ x402Version,
20297
+ accepts,
20298
+ resource
20299
+ }) {
20300
+ return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
20301
+ }
20302
+ var init_wwwauthenticate = __esm({
20303
+ "src/payment/wwwauthenticate.ts"() {
20304
+ "use strict";
20305
+ }
20306
+ });
20307
+
20308
+ // src/payment/networks.ts
20309
+ var networks;
20310
+ var init_networks = __esm({
20311
+ "src/payment/networks.ts"() {
20312
+ "use strict";
20313
+ networks = {
20314
+ base: {
20315
+ mainnet: { caip2: "eip155:8453", chainId: 8453 },
20316
+ sepolia: { caip2: "eip155:84532", chainId: 84532 }
20317
+ },
20318
+ solana: {
20319
+ mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
20320
+ devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
20321
+ },
20322
+ tempo: {
20323
+ mainnet: { caip2: "eip155:4217", chainId: 4217 },
20324
+ testnet: { caip2: "eip155:42431", chainId: 42431 }
20325
+ }
20326
+ };
20327
+ }
20328
+ });
20329
+
20308
20330
  // src/payment/rails.ts
20309
20331
  function lookupRail(name) {
20310
20332
  return rails[name];
@@ -21125,7 +21147,7 @@ function createAgentScoreCore(options) {
21125
21147
  } = options;
21126
21148
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
21127
21149
  const agentMemoryHint = buildAgentMemoryHint();
21128
- const defaultUa = `@agent-score/commerce@${"2.0.2"}`;
21150
+ const defaultUa = `@agent-score/commerce@${"2.1.0"}`;
21129
21151
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
21130
21152
  const sdk = new AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
21131
21153
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -21417,6 +21439,13 @@ function createAgentScoreCore(options) {
21417
21439
  return { evaluate, captureWallet, getSignerVerdict };
21418
21440
  }
21419
21441
 
21442
+ // src/_headers.ts
21443
+ function normalizeHeadersToLowercase(headers) {
21444
+ const out = {};
21445
+ for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
21446
+ return out;
21447
+ }
21448
+
21420
21449
  // src/signer.ts
21421
21450
  var TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
21422
21451
  var TOKEN_2022_PROGRAM = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
@@ -21499,13 +21528,8 @@ async function extractPaymentSignerFromAuth(authHeader, x402PaymentHeader) {
21499
21528
  function readX402PaymentHeader(request) {
21500
21529
  return request.headers.get("payment-signature") ?? request.headers.get("x-payment") ?? void 0;
21501
21530
  }
21502
- function lowerHeaders(headers) {
21503
- const out = {};
21504
- for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
21505
- return out;
21506
- }
21507
21531
  async function extractSignerForPrecheck(headers) {
21508
- const lower = lowerHeaders(headers);
21532
+ const lower = normalizeHeadersToLowercase(headers);
21509
21533
  const x402 = lower["payment-signature"] ?? lower["x-payment"];
21510
21534
  if (x402) {
21511
21535
  const signer = await extractPaymentSignerFromAuth(void 0, x402);
@@ -21520,7 +21544,7 @@ async function extractSignerForPrecheck(headers) {
21520
21544
 
21521
21545
  // src/identity/a2a.ts
21522
21546
  var PROTOCOL_VERSION = "1.0";
21523
- var DEFAULT_PROTOCOL_BINDING = "HTTP+JSON";
21547
+ var DEFAULT_TRANSPORT = "JSONRPC";
21524
21548
  var DEFAULT_INPUT_MODE = "application/json";
21525
21549
  var DEFAULT_OUTPUT_MODE = "application/json";
21526
21550
  var UCP_A2A_EXTENSION_URI = "https://ucp.dev/2026-04-08/specification/reference";
@@ -21540,30 +21564,33 @@ function buildA2AAgentCard(input) {
21540
21564
  }
21541
21565
  const capabilities = {};
21542
21566
  if (input.streaming !== void 0) capabilities.streaming = input.streaming;
21543
- if (input.push_notifications !== void 0) capabilities.push_notifications = input.push_notifications;
21567
+ if (input.pushNotifications !== void 0) capabilities.pushNotifications = input.pushNotifications;
21568
+ if (input.stateTransitionHistory !== void 0) capabilities.stateTransitionHistory = input.stateTransitionHistory;
21544
21569
  if (input.extensions && input.extensions.length > 0) capabilities.extensions = input.extensions;
21545
- if (input.extended_agent_card !== void 0) capabilities.extended_agent_card = input.extended_agent_card;
21546
- const primaryInterface = {
21547
- url: input.url,
21548
- protocol_binding: input.protocol_binding ?? DEFAULT_PROTOCOL_BINDING,
21549
- protocol_version: input.a2a_protocol_version ?? PROTOCOL_VERSION
21550
- };
21551
21570
  const card = {
21552
21571
  name: input.name,
21553
21572
  description: input.description,
21554
- supported_interfaces: [primaryInterface],
21573
+ url: input.url,
21574
+ preferredTransport: input.preferredTransport ?? "HTTP+JSON",
21575
+ protocolVersion: input.protocolVersion ?? PROTOCOL_VERSION,
21555
21576
  version: input.version ?? "1.0.0",
21556
21577
  capabilities,
21557
- default_input_modes: input.default_input_modes ?? [DEFAULT_INPUT_MODE],
21558
- default_output_modes: input.default_output_modes ?? [DEFAULT_OUTPUT_MODE],
21578
+ defaultInputModes: input.defaultInputModes ?? [DEFAULT_INPUT_MODE],
21579
+ defaultOutputModes: input.defaultOutputModes ?? [DEFAULT_OUTPUT_MODE],
21559
21580
  skills: input.skills
21560
21581
  };
21582
+ if (input.additionalInterfaces !== void 0 && input.additionalInterfaces.length > 0) {
21583
+ card.additionalInterfaces = input.additionalInterfaces;
21584
+ }
21561
21585
  if (input.provider !== void 0) card.provider = input.provider;
21562
- if (input.documentation_url !== void 0) card.documentation_url = input.documentation_url;
21563
- if (input.icon_url !== void 0) card.icon_url = input.icon_url;
21586
+ if (input.documentationUrl !== void 0) card.documentationUrl = input.documentationUrl;
21587
+ if (input.iconUrl !== void 0) card.iconUrl = input.iconUrl;
21588
+ if (input.supportsAuthenticatedExtendedCard !== void 0) {
21589
+ card.supportsAuthenticatedExtendedCard = input.supportsAuthenticatedExtendedCard;
21590
+ }
21564
21591
  if (input.signatures !== void 0 && input.signatures.length > 0) card.signatures = input.signatures;
21565
- if (input.security_schemes !== void 0) card.security_schemes = input.security_schemes;
21566
- if (input.security_requirements !== void 0) card.security_requirements = input.security_requirements;
21592
+ if (input.security !== void 0) card.security = input.security;
21593
+ if (input.securitySchemes !== void 0) card.securitySchemes = input.securitySchemes;
21567
21594
  if (input.extras) {
21568
21595
  for (const [k, v] of Object.entries(input.extras)) {
21569
21596
  card[k] = v;
@@ -21571,6 +21598,8 @@ function buildA2AAgentCard(input) {
21571
21598
  }
21572
21599
  return card;
21573
21600
  }
21601
+ var A2A_PROTOCOL_VERSION = PROTOCOL_VERSION;
21602
+ var A2A_DEFAULT_TRANSPORT = DEFAULT_TRANSPORT;
21574
21603
 
21575
21604
  // src/index.ts
21576
21605
  init_ucp();
@@ -21579,6 +21608,34 @@ init_ucp_jwks();
21579
21608
  // src/checkout.ts
21580
21609
  import { randomUUID } from "crypto";
21581
21610
 
21611
+ // src/_mppx_receipt.ts
21612
+ function extractMppxReceiptHeaderFromRaw(raw) {
21613
+ if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
21614
+ const fn = raw.withReceipt;
21615
+ if (typeof fn !== "function") return null;
21616
+ try {
21617
+ const wrapped = fn.call(raw, new Response());
21618
+ return wrapped.headers.get("Payment-Receipt");
21619
+ } catch {
21620
+ return null;
21621
+ }
21622
+ }
21623
+ async function extractMppxReceiptMethod(header) {
21624
+ try {
21625
+ const { Receipt } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
21626
+ return Receipt.deserialize(header).method;
21627
+ } catch {
21628
+ return void 0;
21629
+ }
21630
+ }
21631
+ async function deriveMppxReceiptMethod(raw) {
21632
+ const direct = raw?.receipt?.method;
21633
+ if (direct) return direct;
21634
+ const header = extractMppxReceiptHeaderFromRaw(raw);
21635
+ if (!header) return void 0;
21636
+ return extractMppxReceiptMethod(header);
21637
+ }
21638
+
21582
21639
  // src/payment/rail_spec.ts
21583
21640
  init_usdc();
21584
21641
  async function resolveRecipient(r) {
@@ -21803,10 +21860,13 @@ function buildHowToPay({
21803
21860
  totalUsd,
21804
21861
  rails: rails2,
21805
21862
  opTokenPlaceholder,
21806
- maxSpend
21863
+ maxSpend,
21864
+ decimals
21807
21865
  }) {
21808
21866
  const totalNum = typeof totalUsd === "string" ? Number(totalUsd) : totalUsd;
21809
- const maxSpendStr = String(maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
21867
+ const d = decimals ?? 2;
21868
+ const defaultMaxSpend = totalNum >= 1 ? (Math.ceil(totalNum) + 1).toFixed(d) : totalNum.toFixed(d);
21869
+ const maxSpendStr = String(maxSpend ?? defaultMaxSpend);
21810
21870
  const opToken = opTokenPlaceholder ?? "<your_opc_token>";
21811
21871
  const block = {};
21812
21872
  if (rails2.tempo) {
@@ -21899,26 +21959,26 @@ function buildPricingBlock({
21899
21959
  totalCents,
21900
21960
  taxRate,
21901
21961
  taxState,
21902
- currency
21962
+ currency,
21963
+ decimals
21903
21964
  }) {
21904
21965
  const shipping = shippingCents ?? 0;
21905
21966
  const discount = discountCents ?? 0;
21906
21967
  const total = totalCents ?? Math.max(0, subtotalCents + taxCents + shipping - discount);
21968
+ const d = decimals ?? 2;
21969
+ const fmt = (cents) => (cents / 100).toFixed(d);
21907
21970
  const block = {
21908
- subtotal: formatCents(subtotalCents),
21909
- tax: formatCents(taxCents),
21910
- total: formatCents(total)
21971
+ subtotal: fmt(subtotalCents),
21972
+ tax: fmt(taxCents),
21973
+ total: fmt(total)
21911
21974
  };
21912
- if (shippingCents !== void 0) block.shipping = formatCents(shipping);
21913
- if (discountCents !== void 0) block.discount = formatCents(discount);
21975
+ if (shippingCents !== void 0) block.shipping = fmt(shipping);
21976
+ if (discountCents !== void 0) block.discount = fmt(discount);
21914
21977
  if (taxRate !== void 0) block.tax_rate = taxRate;
21915
21978
  if (taxState !== void 0) block.tax_state = taxState;
21916
21979
  if (currency !== void 0) block.currency = currency;
21917
21980
  return block;
21918
21981
  }
21919
- function formatCents(cents) {
21920
- return (cents / 100).toFixed(2);
21921
- }
21922
21982
 
21923
21983
  // src/challenge/respond_402.ts
21924
21984
  init_wwwauthenticate();
@@ -21927,10 +21987,7 @@ function respond402({
21927
21987
  body,
21928
21988
  x402
21929
21989
  }) {
21930
- const headers = {};
21931
- for (const [k, v] of Object.entries(mppxChallengeHeaders)) {
21932
- headers[k.toLowerCase()] = v;
21933
- }
21990
+ const headers = normalizeHeadersToLowercase(mppxChallengeHeaders);
21934
21991
  headers["content-type"] = "application/json";
21935
21992
  if (x402) {
21936
21993
  headers["payment-required"] = paymentRequiredHeader(x402);
@@ -21993,7 +22050,8 @@ function isSolanaMppRailSpec(s) {
21993
22050
  return s.network?.startsWith("solana:") ?? false;
21994
22051
  }
21995
22052
  function solanaNetworkFromCAIP2(caip2) {
21996
- if (caip2 === networks.solana.devnet.caip2) return "devnet";
22053
+ if (caip2 === "devnet" || caip2 === networks.solana.devnet.caip2) return "devnet";
22054
+ if (caip2 === "localnet") return "localnet";
21997
22055
  return "mainnet-beta";
21998
22056
  }
21999
22057
  function solanaDefaultRpcUrl(network) {
@@ -22277,6 +22335,41 @@ function lazyMppxServer(opts) {
22277
22335
  };
22278
22336
  }
22279
22337
 
22338
+ // src/checkout.ts
22339
+ init_network_kind();
22340
+
22341
+ // src/payment/payment_header.ts
22342
+ function toTitleCase(name) {
22343
+ return name.replace(/(^|-)([a-z])/g, (_m, sep, c) => sep + c.toUpperCase());
22344
+ }
22345
+ function readHeader(headers, name) {
22346
+ if (typeof headers.get === "function") {
22347
+ return headers.get(name);
22348
+ }
22349
+ const rec = headers;
22350
+ const v = rec[name] ?? rec[name.toLowerCase()] ?? rec[toTitleCase(name)];
22351
+ if (typeof v === "string") return v;
22352
+ if (Array.isArray(v) && typeof v[0] === "string") return v[0];
22353
+ return null;
22354
+ }
22355
+ function asHeaders(input) {
22356
+ return typeof input.headers === "object" && input instanceof Request ? input.headers : input;
22357
+ }
22358
+ function hasPaymentHeader(input) {
22359
+ const headers = asHeaders(input);
22360
+ return Boolean(
22361
+ readHeader(headers, "payment-signature") || readHeader(headers, "x-payment") || readHeader(headers, "authorization")?.startsWith("Payment ")
22362
+ );
22363
+ }
22364
+ function hasX402Header(input) {
22365
+ const headers = asHeaders(input);
22366
+ return Boolean(readHeader(headers, "payment-signature") || readHeader(headers, "x-payment"));
22367
+ }
22368
+ function hasMppxHeader(input) {
22369
+ const headers = asHeaders(input);
22370
+ return Boolean(readHeader(headers, "authorization")?.startsWith("Payment "));
22371
+ }
22372
+
22280
22373
  // src/payment/x402_settle.ts
22281
22374
  function classifyX402SettleResult(result) {
22282
22375
  if (result.success) return null;
@@ -22568,12 +22661,14 @@ function pricingResult(opts) {
22568
22661
  ...opts.discountCents !== void 0 && { discountCents: opts.discountCents },
22569
22662
  ...opts.taxRate !== void 0 && { taxRate: opts.taxRate },
22570
22663
  ...opts.taxState !== void 0 && { taxState: opts.taxState },
22571
- currency
22664
+ currency,
22665
+ ...opts.decimals !== void 0 && { decimals: opts.decimals }
22572
22666
  });
22573
22667
  return {
22574
22668
  amountUsd: derivedAmount,
22575
22669
  currency,
22576
22670
  block,
22671
+ ...opts.decimals !== void 0 && { decimals: opts.decimals },
22577
22672
  ...opts.product !== void 0 && { product: opts.product },
22578
22673
  ...opts.bodyExtras !== void 0 && { bodyExtras: opts.bodyExtras }
22579
22674
  };
@@ -22584,6 +22679,7 @@ function pricingResult(opts) {
22584
22679
  return {
22585
22680
  amountUsd: opts.amountUsd,
22586
22681
  currency,
22682
+ ...opts.decimals !== void 0 && { decimals: opts.decimals },
22587
22683
  ...opts.product !== void 0 && { product: opts.product },
22588
22684
  ...opts.bodyExtras !== void 0 && { bodyExtras: opts.bodyExtras }
22589
22685
  };
@@ -22609,21 +22705,8 @@ var CheckoutValidationError = class extends Error {
22609
22705
  this.extra = opts.extra;
22610
22706
  }
22611
22707
  };
22612
- function lowerHeaders2(headers) {
22613
- const out = {};
22614
- for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
22615
- return out;
22616
- }
22617
- function hasX402Header(headers) {
22618
- const h = lowerHeaders2(headers);
22619
- return Boolean(h["payment-signature"] ?? h["x-payment"]);
22620
- }
22621
- function hasMppxHeader(headers) {
22622
- const h = lowerHeaders2(headers);
22623
- return (h["authorization"] ?? "").startsWith("Payment ");
22624
- }
22625
22708
  function resolveIdentityMetadata(ctx) {
22626
- const h = lowerHeaders2(ctx.request.headers);
22709
+ const h = normalizeHeadersToLowercase(ctx.request.headers);
22627
22710
  const wallet = h["x-wallet-address"];
22628
22711
  if (!wallet) return void 0;
22629
22712
  let linkedWallets;
@@ -22652,26 +22735,24 @@ function isTempoSessionRailSpec3(s) {
22652
22735
  function specRailKey(spec) {
22653
22736
  if (isStripeRailSpec2(spec)) return "stripe";
22654
22737
  if (isTempoSessionRailSpec3(spec)) return "tempo_mpp";
22655
- const network = spec.network ?? "";
22656
- if (network.startsWith("eip155:")) return "x402_base";
22657
- if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana_mpp";
22738
+ if (isEvmNetwork(spec)) return "x402_base";
22739
+ if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana_mpp";
22658
22740
  return "tempo_mpp";
22659
22741
  }
22660
22742
  function specMethodName(spec) {
22661
22743
  if (isStripeRailSpec2(spec)) return "stripe/spt";
22662
22744
  if (isTempoSessionRailSpec3(spec)) return "tempo/charge";
22663
- const network = spec.network ?? "";
22664
- if (network.startsWith("eip155:")) return "x402/exact (base)";
22665
- if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana/charge";
22745
+ if (isEvmNetwork(spec)) return "x402/exact (base)";
22746
+ if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana/charge";
22666
22747
  return "tempo/charge";
22667
22748
  }
22668
22749
  function makeMppxComposeHook(opts) {
22669
22750
  return async (ctx) => {
22670
22751
  if (ctx.pricing === null) return { status: 402 };
22671
22752
  const mpp = await opts.serverGetter();
22672
- const lower = lowerHeaders2(ctx.request.headers);
22753
+ const lower = normalizeHeadersToLowercase(ctx.request.headers);
22673
22754
  const authorization = lower["authorization"];
22674
- const amountStr = ctx.pricing.amountUsd.toFixed(2);
22755
+ const amountStr = ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2);
22675
22756
  let result;
22676
22757
  try {
22677
22758
  result = await mpp.charge({ authorization, amount: amountStr });
@@ -22755,7 +22836,7 @@ var Checkout = class {
22755
22836
  let x402ServerGetter;
22756
22837
  if (x402Server === void 0) {
22757
22838
  const baseSpec = Object.values(opts.rails).find(
22758
- (s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && (s.network ?? "").startsWith("eip155:")
22839
+ (s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && isEvmNetwork(s)
22759
22840
  );
22760
22841
  if (baseSpec !== void 0) {
22761
22842
  x402ServerGetter = lazyX402Server({
@@ -22845,7 +22926,7 @@ var Checkout = class {
22845
22926
  * `"x402_base"` when no match found. */
22846
22927
  x402RailKey() {
22847
22928
  for (const [k, v] of Object.entries(this.rails)) {
22848
- if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && (v.network ?? "").startsWith("eip155:")) {
22929
+ if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && isEvmNetwork(v)) {
22849
22930
  return k;
22850
22931
  }
22851
22932
  }
@@ -22854,8 +22935,7 @@ var Checkout = class {
22854
22935
  /** Return the rails-dict key for the primary MPP rail. */
22855
22936
  mppRailKey() {
22856
22937
  for (const [k, v] of Object.entries(this.rails)) {
22857
- const network = v.network ?? "";
22858
- if (!isStripeRailSpec2(v) && !network.startsWith("eip155:")) return k;
22938
+ if (!isStripeRailSpec2(v) && !isEvmNetwork(v)) return k;
22859
22939
  }
22860
22940
  return "tempo";
22861
22941
  }
@@ -22874,17 +22954,15 @@ var Checkout = class {
22874
22954
  if (method === "solana") {
22875
22955
  for (const [k, v] of Object.entries(this.rails)) {
22876
22956
  if (isStripeRailSpec2(v) || isTempoSessionRailSpec3(v)) continue;
22877
- const network = v.network ?? "";
22878
- if (network.startsWith("solana:") || "rpcUrl" in v || "tokenProgram" in v) return k;
22957
+ if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) return k;
22879
22958
  }
22880
22959
  return void 0;
22881
22960
  }
22882
22961
  if (method === "tempo") {
22883
22962
  for (const [k, v] of Object.entries(this.rails)) {
22884
22963
  if (isStripeRailSpec2(v)) continue;
22885
- const network = v.network ?? "";
22886
- if (network.startsWith("solana:") || "rpcUrl" in v || "tokenProgram" in v) continue;
22887
- if (network.startsWith("eip155:")) continue;
22964
+ if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) continue;
22965
+ if (isEvmNetwork(v)) continue;
22888
22966
  return k;
22889
22967
  }
22890
22968
  return void 0;
@@ -22897,7 +22975,7 @@ var Checkout = class {
22897
22975
  get x402BaseNetwork() {
22898
22976
  if (!this.x402ServerAvailable()) return null;
22899
22977
  for (const spec of Object.values(this.rails)) {
22900
- if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && (spec.network ?? "").startsWith("eip155:")) {
22978
+ if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && isEvmNetwork(spec)) {
22901
22979
  return spec.network ?? "eip155:8453";
22902
22980
  }
22903
22981
  }
@@ -22949,8 +23027,8 @@ var Checkout = class {
22949
23027
  throw err;
22950
23028
  }
22951
23029
  }
22952
- const hasPaymentHeader = hasX402Header(request.headers) || hasMppxHeader(request.headers);
22953
- if (this.gate !== void 0 && hasPaymentHeader) {
23030
+ const hasPaymentHeader2 = hasX402Header(request.headers) || hasMppxHeader(request.headers);
23031
+ if (this.gate !== void 0 && hasPaymentHeader2) {
22954
23032
  const denial = await this.runGate(ctx);
22955
23033
  if (denial !== null) {
22956
23034
  return {
@@ -23040,7 +23118,7 @@ var Checkout = class {
23040
23118
  ...policyOverride ?? {}
23041
23119
  };
23042
23120
  const core = createAgentScoreCore(coreOpts);
23043
- const headers = lowerHeaders2(ctx.request.headers);
23121
+ const headers = normalizeHeadersToLowercase(ctx.request.headers);
23044
23122
  const walletAddress = headers["x-wallet-address"];
23045
23123
  const operatorToken = headers["x-operator-token"];
23046
23124
  const identity = walletAddress !== void 0 || operatorToken !== void 0 ? {
@@ -23102,7 +23180,7 @@ var Checkout = class {
23102
23180
  if (!this.zeroSettleCarveOut || ctx.pricing === null) return null;
23103
23181
  const cents = Math.round(ctx.pricing.amountUsd * 100);
23104
23182
  if (cents !== 0) return null;
23105
- const headers = lowerHeaders2(ctx.request.headers);
23183
+ const headers = normalizeHeadersToLowercase(ctx.request.headers);
23106
23184
  let zero;
23107
23185
  if (rail === "x402-base") {
23108
23186
  const x402Header = headers["payment-signature"] ?? headers["x-payment"];
@@ -23176,7 +23254,7 @@ var Checkout = class {
23176
23254
  resourceConfig: {
23177
23255
  scheme: "exact",
23178
23256
  network: verified.signedNetwork,
23179
- price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
23257
+ price: `$${ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2)}`,
23180
23258
  payTo: verified.signedPayTo,
23181
23259
  maxTimeoutSeconds: 300
23182
23260
  },
@@ -23285,15 +23363,18 @@ var Checkout = class {
23285
23363
  howToPayRails[k] = v;
23286
23364
  }
23287
23365
  }
23366
+ const pricingDecimals = ctx.pricing.decimals ?? 2;
23288
23367
  const howToPay = buildHowToPay({
23289
23368
  url: this.url,
23290
23369
  retryBodyJson: JSON.stringify(ctx.request.body),
23291
- totalUsd: ctx.pricing.amountUsd.toFixed(2),
23292
- rails: howToPayRails
23370
+ totalUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
23371
+ rails: howToPayRails,
23372
+ ...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
23293
23373
  });
23294
23374
  const pricingBlock = ctx.pricing.block ?? buildPricingBlock({
23295
- subtotalCents: Math.round(ctx.pricing.amountUsd * 100),
23296
- currency: ctx.pricing.currency ?? "USD"
23375
+ subtotalCents: ctx.pricing.amountUsd * 100,
23376
+ currency: ctx.pricing.currency ?? "USD",
23377
+ ...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
23297
23378
  });
23298
23379
  let x402Accepts = [];
23299
23380
  let x402Resource;
@@ -23306,7 +23387,7 @@ var Checkout = class {
23306
23387
  try {
23307
23388
  x402Accepts = await buildX402AcceptsFor402(x402Server, {
23308
23389
  network: baseNetwork,
23309
- price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
23390
+ price: `$${ctx.pricing.amountUsd.toFixed(pricingDecimals)}`,
23310
23391
  payTo: recipient,
23311
23392
  maxTimeoutSeconds: 300
23312
23393
  });
@@ -23322,7 +23403,7 @@ var Checkout = class {
23322
23403
  agentInstructions: buildAgentInstructions({ howToPay }),
23323
23404
  ...identityMetadata !== void 0 ? { identityMetadata } : {},
23324
23405
  pricing: pricingBlock,
23325
- amountUsd: ctx.pricing.amountUsd.toFixed(2),
23406
+ amountUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
23326
23407
  retryBody: ctx.request.body,
23327
23408
  agentMemory: firstEncounterAgentMemory({ firstEncounter: true }),
23328
23409
  ...ctx.pricing.product ? { product: ctx.pricing.product } : {},
@@ -23430,25 +23511,6 @@ function stripContentType(headers) {
23430
23511
  }
23431
23512
  return out;
23432
23513
  }
23433
- function extractMppxReceiptHeaderFromRaw(raw) {
23434
- if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
23435
- const fn = raw.withReceipt;
23436
- if (typeof fn !== "function") return null;
23437
- try {
23438
- const wrapped = fn.call(raw, new Response());
23439
- return wrapped.headers.get("Payment-Receipt");
23440
- } catch {
23441
- return null;
23442
- }
23443
- }
23444
- async function extractMppxReceiptMethod(header) {
23445
- try {
23446
- const { Receipt } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
23447
- return Receipt.deserialize(header).method;
23448
- } catch {
23449
- return void 0;
23450
- }
23451
- }
23452
23514
  function headersToRecord(h) {
23453
23515
  if (h === void 0) return {};
23454
23516
  if (h instanceof Headers) {
@@ -23762,6 +23824,15 @@ import { createHash } from "crypto";
23762
23824
  function hashOperatorToken(plaintext) {
23763
23825
  return createHash("sha256").update(plaintext, "utf8").digest("hex");
23764
23826
  }
23827
+ function extractOwnerScope(input) {
23828
+ const headers = asHeaders(input);
23829
+ const walletAddress = readHeader(headers, "x-wallet-address");
23830
+ const operatorToken = readHeader(headers, "x-operator-token");
23831
+ return {
23832
+ ...walletAddress ? { walletAddress } : {},
23833
+ ...operatorToken ? { operatorTokenHash: hashOperatorToken(operatorToken) } : {}
23834
+ };
23835
+ }
23765
23836
 
23766
23837
  // src/payment/index.ts
23767
23838
  init_directive();
@@ -23775,8 +23846,45 @@ init_directive();
23775
23846
  init_wwwauthenticate();
23776
23847
 
23777
23848
  // src/payment/amounts.ts
23778
- function formatUsdCents(cents) {
23779
- return (cents / 100).toFixed(2);
23849
+ function usdToAtomic(usd, opts) {
23850
+ const { decimals } = opts;
23851
+ if (!Number.isInteger(decimals) || decimals < 0) {
23852
+ throw new RangeError(`decimals must be a non-negative integer, got ${decimals}`);
23853
+ }
23854
+ if (typeof usd === "number") {
23855
+ if (!Number.isFinite(usd)) {
23856
+ throw new RangeError(`usd must be finite, got ${usd}`);
23857
+ }
23858
+ if (usd < 0) {
23859
+ throw new RangeError(`usd must be non-negative, got ${usd}`);
23860
+ }
23861
+ }
23862
+ const s = (typeof usd === "number" ? usd.toString() : usd).trim();
23863
+ if (s.startsWith("-")) {
23864
+ throw new RangeError(`usd must be non-negative, got ${s}`);
23865
+ }
23866
+ if (s === "NaN" || s === "Infinity") {
23867
+ throw new RangeError(`usd must be finite, got ${s}`);
23868
+ }
23869
+ const match = /^(\d*)(?:\.(\d*))?$/.exec(s);
23870
+ if (!match || match[1] === "" && (match[2] === void 0 || match[2] === "")) {
23871
+ throw new SyntaxError(`invalid usd value: ${JSON.stringify(usd)}`);
23872
+ }
23873
+ const intPart = match[1] || "0";
23874
+ const fracPart = match[2] ?? "";
23875
+ if (fracPart.length <= decimals) {
23876
+ return BigInt(intPart + fracPart.padEnd(decimals, "0"));
23877
+ }
23878
+ const kept = fracPart.slice(0, decimals);
23879
+ const roundDigit = fracPart[decimals];
23880
+ let result = BigInt(intPart + kept);
23881
+ if (roundDigit >= "5") {
23882
+ result += 1n;
23883
+ }
23884
+ return result;
23885
+ }
23886
+ function formatUsdCents(cents, decimals = 2) {
23887
+ return (cents / 100).toFixed(decimals);
23780
23888
  }
23781
23889
 
23782
23890
  // src/payment/solana.ts
@@ -23799,7 +23907,631 @@ async function loadSolanaFeePayer(opts) {
23799
23907
  }
23800
23908
  return kit.createKeyPairSignerFromPrivateKeyBytes(bytes);
23801
23909
  }
23910
+
23911
+ // src/payment/compose_rails.ts
23912
+ init_usdc();
23913
+ function buildMppxComposeRails(opts) {
23914
+ const rails2 = [];
23915
+ if (opts.tempoRecipient) {
23916
+ rails2.push(["tempo/charge", {
23917
+ amount: opts.amountUsd,
23918
+ currency: opts.tempoTokenAddress ?? USDC.tempo.mainnet.address,
23919
+ decimals: 6,
23920
+ recipient: opts.tempoRecipient
23921
+ }]);
23922
+ }
23923
+ if (opts.solanaRecipient) {
23924
+ const atomic = usdToAtomic(opts.amountUsd, { decimals: 6 });
23925
+ rails2.push(["solana/charge", {
23926
+ amount: atomic.toString(),
23927
+ currency: opts.solanaTokenMint ?? USDC.solana.mainnet.mint,
23928
+ decimals: 6,
23929
+ recipient: opts.solanaRecipient,
23930
+ network: opts.solanaNetwork ?? "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
23931
+ }]);
23932
+ }
23933
+ if (opts.includeStripe !== false) {
23934
+ rails2.push(["stripe/charge", { amount: opts.amountUsd, currency: "usd", decimals: 2 }]);
23935
+ }
23936
+ return rails2;
23937
+ }
23938
+
23939
+ // src/payment/default_rails.ts
23940
+ init_networks();
23941
+ init_usdc();
23942
+ function buildDefaultCheckoutRails(opts) {
23943
+ const out = {};
23944
+ if (opts.tempo) {
23945
+ out.tempo = { recipient: "", ...RAIL_SPEC_DEFAULTS.tempo, ...opts.tempo };
23946
+ }
23947
+ if (opts.x402Base) {
23948
+ const merged = { recipient: "", ...RAIL_SPEC_DEFAULTS.x402Base, ...opts.x402Base };
23949
+ if (merged.network === networks.base.sepolia.caip2) {
23950
+ if (opts.x402Base.chainId === void 0) merged.chainId = networks.base.sepolia.chainId;
23951
+ if (opts.x402Base.token === void 0) merged.token = USDC.base.sepolia.address;
23952
+ } else if (merged.network === networks.base.mainnet.caip2) {
23953
+ if (opts.x402Base.chainId === void 0) merged.chainId = networks.base.mainnet.chainId;
23954
+ if (opts.x402Base.token === void 0) merged.token = USDC.base.mainnet.address;
23955
+ }
23956
+ out.x402_base = merged;
23957
+ }
23958
+ if (opts.solanaMpp) {
23959
+ const merged = { recipient: "", ...RAIL_SPEC_DEFAULTS.solanaMpp, ...opts.solanaMpp };
23960
+ const isDevnet = merged.network === "devnet" || merged.network === networks.solana.devnet.caip2;
23961
+ if (isDevnet && opts.solanaMpp.token === void 0) {
23962
+ merged.token = USDC.solana.devnet.mint;
23963
+ }
23964
+ out.solana_mpp = merged;
23965
+ }
23966
+ if (opts.stripe) {
23967
+ out.stripe = { ...RAIL_SPEC_DEFAULTS.stripe, ...opts.stripe };
23968
+ }
23969
+ return out;
23970
+ }
23971
+
23972
+ // src/payment/index.ts
23973
+ init_network_kind();
23974
+
23975
+ // src/checkout_compute_first.ts
23976
+ import { randomUUID as randomUUID2 } from "crypto";
23977
+
23978
+ // src/discovery/index.ts
23979
+ init_probe();
23980
+
23981
+ // src/discovery/agentscore_content.ts
23982
+ var PURCHASE_MODE_NOTES = Object.freeze({
23983
+ redemption_only: "Requires a single-use redemption code (printed on a mailer or other out-of-band delivery). Submit the code in the request body as `redemption_code`. Without a valid code the order is rejected.",
23984
+ coupon_applicable: "Codes are optional. Without one, settle at list price. With a valid code the discount is applied automatically (percent_off, fixed_off, or fixed_settle).",
23985
+ paid_only: "Codes are NOT accepted. Settle at the listed price. Submitting a `redemption_code` field returns 400 codes_not_accepted."
23986
+ });
23987
+ function buildSuccessNextSteps(opts) {
23988
+ const out = {
23989
+ action: "done",
23990
+ user_message: opts.userMessage ?? "Payment complete. Your AgentScore Passport is now active across every AgentScore-gated merchant."
23991
+ };
23992
+ if (opts.orderStatusUrl) out.order_status_url = opts.orderStatusUrl;
23993
+ if (opts.fulfillmentEta !== void 0) out.fulfillment_eta = opts.fulfillmentEta;
23994
+ return out;
23995
+ }
23996
+
23997
+ // src/discovery/index.ts
23998
+ init_well_known();
23999
+
24000
+ // src/quote_cache.ts
24001
+ import { createHash as createHash2 } from "crypto";
24002
+
24003
+ // src/_redis.ts
24004
+ async function tryCreateRedis(opts) {
24005
+ const url2 = opts.url ?? process.env.REDIS_URL;
24006
+ if (!url2) return null;
24007
+ try {
24008
+ const mod = await import("ioredis");
24009
+ const client = new mod.default(url2, {
24010
+ connectTimeout: opts.connectTimeout ?? 3e3,
24011
+ maxRetriesPerRequest: opts.maxRetriesPerRequest ?? 1,
24012
+ tls: url2.startsWith("rediss://") ? {} : void 0
24013
+ });
24014
+ client.on("error", (err) => console.error(`[${opts.label}] Redis error:`, err.message));
24015
+ return client;
24016
+ } catch {
24017
+ return null;
24018
+ }
24019
+ }
24020
+ function memoizedRedis(opts) {
24021
+ let promise2 = null;
24022
+ return () => {
24023
+ if (!promise2) promise2 = tryCreateRedis(opts);
24024
+ return promise2;
24025
+ };
24026
+ }
24027
+
24028
+ // src/quote_cache.ts
24029
+ function canonicalize2(value) {
24030
+ if (Array.isArray(value)) return value.map(canonicalize2);
24031
+ if (value && typeof value === "object") {
24032
+ const sorted = {};
24033
+ for (const key of Object.keys(value).sort()) {
24034
+ sorted[key] = canonicalize2(value[key]);
24035
+ }
24036
+ return sorted;
24037
+ }
24038
+ return value;
24039
+ }
24040
+ function createQuoteCache(opts = {}) {
24041
+ const ttlMs = opts.ttlMs ?? 5 * 6e4;
24042
+ const keyPrefix = opts.keyPrefix ?? "quote:";
24043
+ const memMap = /* @__PURE__ */ new Map();
24044
+ const getRedis = memoizedRedis({ url: opts.redisUrl, label: "quote-cache" });
24045
+ const evictExpired = () => {
24046
+ const now = Date.now();
24047
+ for (const [k, v] of memMap.entries()) {
24048
+ if (v.expiresAt <= now) memMap.delete(k);
24049
+ }
24050
+ };
24051
+ return {
24052
+ bodyHashKey(prefix, body) {
24053
+ const canonical = JSON.stringify(canonicalize2(body));
24054
+ const hash3 = createHash2("sha256").update(`${prefix}::${canonical}`).digest("hex").slice(0, 24);
24055
+ return `${prefix}::${hash3}`;
24056
+ },
24057
+ async read(key) {
24058
+ const r = await getRedis();
24059
+ if (r) {
24060
+ try {
24061
+ const raw = await r.get(`${keyPrefix}${key}`);
24062
+ if (!raw) return null;
24063
+ return JSON.parse(raw);
24064
+ } catch {
24065
+ }
24066
+ }
24067
+ evictExpired();
24068
+ const entry = memMap.get(key);
24069
+ return entry ? entry.entry : null;
24070
+ },
24071
+ async write(key, body, priceCents, recipients = {}) {
24072
+ const cached2 = { body, priceCents, recipients };
24073
+ const r = await getRedis();
24074
+ if (r) {
24075
+ try {
24076
+ await r.set(`${keyPrefix}${key}`, JSON.stringify(cached2), "PX", ttlMs);
24077
+ return;
24078
+ } catch {
24079
+ }
24080
+ }
24081
+ memMap.set(key, { entry: cached2, expiresAt: Date.now() + ttlMs });
24082
+ },
24083
+ async clear() {
24084
+ memMap.clear();
24085
+ const r = await getRedis();
24086
+ if (r) {
24087
+ try {
24088
+ await r.flushdb();
24089
+ } catch {
24090
+ }
24091
+ }
24092
+ }
24093
+ };
24094
+ }
24095
+
24096
+ // src/checkout_compute_first.ts
24097
+ var DEFAULT_TTL_MS = 5 * 6e4;
24098
+ function decimalsForUnit(unitPriceCents) {
24099
+ if (Number.isInteger(unitPriceCents)) return 2;
24100
+ const str = unitPriceCents.toString();
24101
+ const dotIdx = str.indexOf(".");
24102
+ const frac = dotIdx === -1 ? 0 : str.length - dotIdx - 1;
24103
+ return 2 + frac;
24104
+ }
24105
+ function computeFirstCheckout(opts) {
24106
+ const cache = opts.cache ?? createQuoteCache({ ttlMs: opts.cacheTtlMs ?? DEFAULT_TTL_MS });
24107
+ const decimals = opts.decimals ?? decimalsForUnit(opts.unitPriceCents);
24108
+ const appUrl = opts.appUrl ?? new URL(opts.url).origin;
24109
+ async function mintAndResolveRecipients(req, body, priceCents) {
24110
+ const minted = opts.mintRecipients ? await opts.mintRecipients({ request: req, body, priceCents }) : {};
24111
+ const out = {};
24112
+ const tempo = minted.tempo ?? (opts.rails.tempo ? await resolveRecipient(opts.rails.tempo.recipient) : void 0);
24113
+ const x402Base = minted.x402_base ?? (opts.rails.x402_base ? await resolveRecipient(opts.rails.x402_base.recipient) : void 0);
24114
+ const solana = minted.solana_mpp ?? (opts.rails.solana_mpp ? await resolveRecipient(opts.rails.solana_mpp.recipient) : void 0);
24115
+ if (tempo) out.tempo = tempo;
24116
+ if (x402Base) out.x402_base = x402Base;
24117
+ if (solana) out.solana_mpp = solana;
24118
+ return out;
24119
+ }
24120
+ async function emit402(req, body, priceCents, recipients) {
24121
+ const totalUsd = formatUsdCents(priceCents, decimals);
24122
+ const tempoRecipient = recipients.tempo;
24123
+ const x402BaseRecipient = recipients.x402_base;
24124
+ const solanaRecipient = recipients.solana_mpp;
24125
+ const accepted = await buildAcceptedMethods({
24126
+ ...tempoRecipient && opts.rails.tempo && { tempo: { ...opts.rails.tempo, recipient: tempoRecipient } },
24127
+ ...solanaRecipient && opts.rails.solana_mpp && { solana_mpp: { ...opts.rails.solana_mpp, recipient: solanaRecipient } },
24128
+ ...opts.rails.stripe && { stripe: opts.rails.stripe }
24129
+ });
24130
+ if (x402BaseRecipient && opts.rails.x402_base) {
24131
+ try {
24132
+ const resolvedX402PayTo = await resolveRecipient(x402BaseRecipient);
24133
+ const x402Entries = await buildX402AcceptsFor402(opts.x402Server, {
24134
+ network: opts.rails.x402_base.network ?? "eip155:8453",
24135
+ price: `$${totalUsd}`,
24136
+ payTo: resolvedX402PayTo,
24137
+ maxTimeoutSeconds: 300
24138
+ });
24139
+ accepted.push(...x402Entries);
24140
+ } catch (err) {
24141
+ console.warn(
24142
+ `[${opts.name}.computeFirst] buildX402AcceptsFor402 failed; dropping x402 from accepts:`,
24143
+ err instanceof Error ? err.message : err
24144
+ );
24145
+ }
24146
+ }
24147
+ const howToPay = buildHowToPay({
24148
+ url: opts.url,
24149
+ retryBodyJson: JSON.stringify(body),
24150
+ totalUsd,
24151
+ decimals,
24152
+ rails: {
24153
+ ...tempoRecipient && opts.rails.tempo && { tempo: { ...opts.rails.tempo, recipient: tempoRecipient } },
24154
+ ...x402BaseRecipient && opts.rails.x402_base && { x402_base: { ...opts.rails.x402_base, recipient: x402BaseRecipient } },
24155
+ ...solanaRecipient && opts.rails.solana_mpp && { solana_mpp: { ...opts.rails.solana_mpp, recipient: solanaRecipient } },
24156
+ ...opts.rails.stripe && { stripe: opts.rails.stripe }
24157
+ }
24158
+ });
24159
+ const pricing = buildPricingBlock({ subtotalCents: priceCents, currency: "USD", decimals });
24160
+ const agentInstructions = buildAgentInstructions({
24161
+ howToPay,
24162
+ warnings: [
24163
+ "The quoted price is exact: it was derived from the actual number of results returned by the work on the probe leg.",
24164
+ "The merchant cached the result against a hash of this request body. Retry with the same body within the quote TTL (default 5 min) to settle and receive the cached results; if the quote expires, re-probe."
24165
+ ]
24166
+ });
24167
+ let mppChallengeHeaders = {};
24168
+ if (opts.composeMppx) {
24169
+ try {
24170
+ const mppResult = await opts.composeMppx({
24171
+ request: req,
24172
+ cachedBody: body,
24173
+ priceCents,
24174
+ priceUsd: totalUsd,
24175
+ recipients
24176
+ });
24177
+ if (mppResult.status === 402 && mppResult.headers) {
24178
+ mppChallengeHeaders = mppResult.headers;
24179
+ }
24180
+ } catch (err) {
24181
+ console.warn(
24182
+ `[${opts.name}.computeFirst] composeMppx probe-leg failed; dropping MPP rails from 402 challenge:`,
24183
+ err instanceof Error ? err.message : err
24184
+ );
24185
+ }
24186
+ }
24187
+ const body402 = build402Body({
24188
+ product: { id: opts.name, name: opts.name },
24189
+ acceptedMethods: accepted,
24190
+ pricing,
24191
+ agentInstructions,
24192
+ amountUsd: totalUsd,
24193
+ currency: "USD",
24194
+ orderId: null,
24195
+ retryBody: body
24196
+ });
24197
+ const headers = new Headers({ "Content-Type": "application/json" });
24198
+ for (const [k, v] of Object.entries(mppChallengeHeaders)) headers.set(k, v);
24199
+ headers.set(
24200
+ "PAYMENT-REQUIRED",
24201
+ paymentRequiredHeader({ x402Version: 2, accepts: accepted, resource: { url: opts.url } })
24202
+ );
24203
+ return new Response(JSON.stringify(body402), { status: 402, headers });
24204
+ }
24205
+ async function handleX402Settle(req, referenceId, cachedBody, priceCents, recipients) {
24206
+ const verified = await verifyX402Request({
24207
+ request: req,
24208
+ isCachedAddress: async () => true,
24209
+ acceptedNetwork: opts.rails.x402_base?.network ?? "eip155:8453"
24210
+ });
24211
+ if (!verified.ok) {
24212
+ return new Response(JSON.stringify(verified.body), {
24213
+ status: verified.status,
24214
+ headers: { "Content-Type": "application/json" }
24215
+ });
24216
+ }
24217
+ const actualUsd = formatUsdCents(priceCents, decimals);
24218
+ const settle = await processX402Settle({
24219
+ x402Server: opts.x402Server,
24220
+ payload: verified.payload,
24221
+ resourceConfig: {
24222
+ scheme: "exact",
24223
+ network: verified.signedNetwork,
24224
+ price: `$${actualUsd}`,
24225
+ payTo: verified.signedPayTo,
24226
+ maxTimeoutSeconds: 300
24227
+ },
24228
+ resourceMeta: {
24229
+ url: req.url,
24230
+ description: `Agent purchase via x402-exact (${opts.name})`,
24231
+ mimeType: "application/json"
24232
+ }
24233
+ });
24234
+ if (!settle.success) {
24235
+ const detail = settle.error?.message ?? "unknown";
24236
+ return new Response(
24237
+ JSON.stringify({
24238
+ id: referenceId,
24239
+ endpoint: opts.name,
24240
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24241
+ payment_status: "failed",
24242
+ charged_usd: "0.00",
24243
+ rail: `x402-base (${verified.signedNetwork})`,
24244
+ error: {
24245
+ code: "settle_failed",
24246
+ message: "Facilitator rejected the exact settle; no on-chain capture occurred.",
24247
+ detail
24248
+ }
24249
+ }),
24250
+ { status: 502, headers: { "Content-Type": "application/json" } }
24251
+ );
24252
+ }
24253
+ const signer = await extractPaymentSigner(req, readX402PaymentHeader(req));
24254
+ const signerInfo = signer ? { address: signer.address, network: signer.network } : void 0;
24255
+ const railLabel = `Base (${verified.signedNetwork})`;
24256
+ if (opts.onSettled) {
24257
+ try {
24258
+ await opts.onSettled({
24259
+ request: req,
24260
+ rail: "x402",
24261
+ cachedBody,
24262
+ priceCents,
24263
+ priceUsd: actualUsd,
24264
+ recipients,
24265
+ ...signerInfo ? { signer: signerInfo } : {}
24266
+ });
24267
+ } catch (err) {
24268
+ console.warn(`[${opts.name}.computeFirst.onSettled] x402 side-effect failed:`, err instanceof Error ? err.message : err);
24269
+ }
24270
+ }
24271
+ const buildBody = opts.buildSuccessBody ?? defaultSuccessBody(appUrl);
24272
+ const body = buildBody({
24273
+ referenceId,
24274
+ endpoint: opts.name,
24275
+ chargedUsd: actualUsd,
24276
+ rail: railLabel,
24277
+ ...signerInfo ? { signer: signerInfo } : {},
24278
+ cachedBody
24279
+ });
24280
+ return new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } });
24281
+ }
24282
+ function mppRailLabel(method) {
24283
+ const scheme = method?.split("/")[0];
24284
+ if (scheme === "tempo") {
24285
+ const networkName = opts.rails.tempo?.testnet ? "tempo-testnet" : opts.rails.tempo?.network ?? "tempo-mainnet";
24286
+ return `Tempo (${networkName})`;
24287
+ }
24288
+ if (scheme === "solana") {
24289
+ const networkName = opts.rails.solana_mpp?.network ?? "solana";
24290
+ return `Solana (${networkName})`;
24291
+ }
24292
+ if (scheme === "stripe") return "Stripe (card+link)";
24293
+ return "MPP";
24294
+ }
24295
+ async function handleMppSettle(req, referenceId, cachedBody, priceCents, recipients) {
24296
+ if (!opts.composeMppx) {
24297
+ return new Response(
24298
+ JSON.stringify({
24299
+ id: referenceId,
24300
+ endpoint: opts.name,
24301
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24302
+ payment_status: "failed",
24303
+ charged_usd: "0.00",
24304
+ error: { code: "mpp_unavailable", message: "MPP settle hook not configured on this endpoint." }
24305
+ }),
24306
+ { status: 503, headers: { "Content-Type": "application/json" } }
24307
+ );
24308
+ }
24309
+ const priceUsd = formatUsdCents(priceCents, decimals);
24310
+ const result = await opts.composeMppx({ request: req, cachedBody, priceCents, priceUsd, recipients });
24311
+ if (result.status !== 200) {
24312
+ const headers = result.headers ?? {};
24313
+ return new Response(
24314
+ JSON.stringify({
24315
+ id: referenceId,
24316
+ endpoint: opts.name,
24317
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24318
+ payment_status: "failed",
24319
+ charged_usd: "0.00",
24320
+ error: { code: "mpp_settle_failed", message: "MPP compose did not return 200; credential rejected." }
24321
+ }),
24322
+ { status: 400, headers: { "Content-Type": "application/json", ...headers } }
24323
+ );
24324
+ }
24325
+ const signer = result.signerAddress ? { address: result.signerAddress, network: result.signerNetwork ?? "evm" } : await extractPaymentSigner(req, readX402PaymentHeader(req)).then((s) => s ? { address: s.address, network: s.network } : void 0);
24326
+ const method = await deriveMppxReceiptMethod(result.raw);
24327
+ const railLabel = mppRailLabel(method);
24328
+ if (opts.onSettled) {
24329
+ try {
24330
+ await opts.onSettled({
24331
+ request: req,
24332
+ rail: "mpp",
24333
+ mppMethod: method,
24334
+ cachedBody,
24335
+ priceCents,
24336
+ priceUsd,
24337
+ recipients,
24338
+ ...signer ? { signer } : {},
24339
+ ...result.txHash ? { paymentIntentId: result.txHash } : {}
24340
+ });
24341
+ } catch (err) {
24342
+ console.warn(`[${opts.name}.computeFirst.onSettled] MPP side-effect failed:`, err instanceof Error ? err.message : err);
24343
+ }
24344
+ }
24345
+ const buildBody = opts.buildSuccessBody ?? defaultSuccessBody(appUrl);
24346
+ const body = buildBody({
24347
+ referenceId,
24348
+ endpoint: opts.name,
24349
+ chargedUsd: priceUsd,
24350
+ rail: railLabel,
24351
+ ...result.txHash ? { paymentIntentId: result.txHash } : {},
24352
+ ...signer ? { signer } : {},
24353
+ cachedBody
24354
+ });
24355
+ return new Response(JSON.stringify(body), { status: 200, headers: { "Content-Type": "application/json" } });
24356
+ }
24357
+ async function handle(req) {
24358
+ const referenceId = `${opts.name}_${randomUUID2()}`;
24359
+ let body;
24360
+ try {
24361
+ body = await req.clone().json();
24362
+ } catch {
24363
+ body = {};
24364
+ }
24365
+ try {
24366
+ opts.validateInput?.(body);
24367
+ } catch (err) {
24368
+ if (err instanceof CheckoutValidationError) {
24369
+ return new Response(
24370
+ JSON.stringify({
24371
+ error: { code: err.code, message: err.message },
24372
+ ...err.action ? { next_steps: { action: err.action, user_message: err.message } } : {},
24373
+ ...err.extra
24374
+ }),
24375
+ { status: err.status, headers: { "Content-Type": "application/json" } }
24376
+ );
24377
+ }
24378
+ throw err;
24379
+ }
24380
+ const cacheKey2 = cache.bodyHashKey(opts.name, body);
24381
+ if (hasX402Header(req.headers) || hasMppxHeader(req.headers)) {
24382
+ const quote2 = await cache.read(cacheKey2);
24383
+ if (!quote2) {
24384
+ return new Response(
24385
+ JSON.stringify({
24386
+ id: referenceId,
24387
+ endpoint: opts.name,
24388
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24389
+ payment_status: "failed",
24390
+ charged_usd: "0.00",
24391
+ error: {
24392
+ code: "stale_quote",
24393
+ message: "No active quote for this request body. The quote may have expired or the body changed since the probe."
24394
+ },
24395
+ next_steps: {
24396
+ action: "re_probe",
24397
+ suggestion: "Send the same body without a payment header to get a fresh 402 quote, then retry with the payment credential."
24398
+ }
24399
+ }),
24400
+ { status: 400, headers: { "Content-Type": "application/json" } }
24401
+ );
24402
+ }
24403
+ if (hasX402Header(req.headers)) return handleX402Settle(req, referenceId, quote2.body, quote2.priceCents, quote2.recipients);
24404
+ return handleMppSettle(req, referenceId, quote2.body, quote2.priceCents, quote2.recipients);
24405
+ }
24406
+ let quote = await cache.read(cacheKey2);
24407
+ if (!quote) {
24408
+ let outcome;
24409
+ try {
24410
+ outcome = await opts.runWork(body, { request: req });
24411
+ } catch {
24412
+ return new Response(
24413
+ JSON.stringify({
24414
+ id: referenceId,
24415
+ endpoint: opts.name,
24416
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24417
+ payment_status: "no_charge",
24418
+ charged_usd: "0.00",
24419
+ result: { matches: [], total: 0 },
24420
+ error: {
24421
+ code: "upstream_failed",
24422
+ message: "The wrapped endpoint failed; no charge was applied."
24423
+ }
24424
+ }),
24425
+ { status: 200, headers: { "Content-Type": "application/json" } }
24426
+ );
24427
+ }
24428
+ if (outcome.resultCount === 0) {
24429
+ return new Response(
24430
+ JSON.stringify({
24431
+ id: referenceId,
24432
+ endpoint: opts.name,
24433
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24434
+ payment_status: "no_charge",
24435
+ charged_usd: "0.00",
24436
+ result: outcome.body
24437
+ }),
24438
+ { status: 200, headers: { "Content-Type": "application/json" } }
24439
+ );
24440
+ }
24441
+ const priceCents = opts.unitPriceCents * outcome.resultCount;
24442
+ const recipients = await mintAndResolveRecipients(req, body, priceCents);
24443
+ await cache.write(cacheKey2, outcome.body, priceCents, recipients);
24444
+ quote = { body: outcome.body, priceCents, recipients };
24445
+ }
24446
+ return emit402(req, body, quote.priceCents, quote.recipients);
24447
+ }
24448
+ return {
24449
+ handleWeb: handle,
24450
+ async handleHono(c) {
24451
+ return handle(c.req.raw);
24452
+ }
24453
+ };
24454
+ }
24455
+ function defaultSuccessBody(appUrl) {
24456
+ return ({ referenceId, endpoint, chargedUsd, rail, paymentIntentId, signer, cachedBody }) => ({
24457
+ id: referenceId,
24458
+ endpoint,
24459
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
24460
+ payment_status: "completed",
24461
+ charged_usd: chargedUsd,
24462
+ rail,
24463
+ ...paymentIntentId ? { payment_intent_id: paymentIntentId } : {},
24464
+ ...signer ? { signer } : {},
24465
+ result: cachedBody,
24466
+ next_steps: buildSuccessNextSteps({ orderStatusUrl: `${appUrl}/health` }),
24467
+ agent_memory: firstEncounterAgentMemory({ firstEncounter: true })
24468
+ });
24469
+ }
24470
+
24471
+ // src/identity/default_denied.ts
24472
+ function createDefaultOnDenied(opts) {
24473
+ const supportContext = opts.supportContext ?? "Contact support if you believe this denial is in error.";
24474
+ const paymentRequiredMessage = opts.paymentRequiredMessage ?? "AgentScore tier does not support assess. Contact support.";
24475
+ const walletNotTrustedMessage = opts.walletNotTrustedMessage ?? `Identity check did not satisfy policy for ${opts.merchantName}.`;
24476
+ return function defaultOnDenied(reason) {
24477
+ if (reason.code === "wallet_signer_mismatch" || reason.code === "wallet_auth_requires_wallet_signing") {
24478
+ const body = buildSignerMismatchBody({
24479
+ result: {
24480
+ kind: reason.code,
24481
+ claimedOperator: reason.claimed_operator ?? null,
24482
+ actualSignerOperator: reason.actual_signer_operator ?? null,
24483
+ expectedSigner: reason.expected_signer ?? "",
24484
+ actualSigner: reason.actual_signer ?? "",
24485
+ linkedWallets: reason.linked_wallets ?? [],
24486
+ agentInstructions: reason.agent_instructions ?? "",
24487
+ claimedWallet: reason.expected_signer ?? ""
24488
+ }
24489
+ });
24490
+ return { status: 403, body: body ?? denialReasonToBody(reason) };
24491
+ }
24492
+ if (reason.code === "wallet_not_trusted") {
24493
+ return {
24494
+ status: 403,
24495
+ body: {
24496
+ error: { code: "compliance_denied", message: walletNotTrustedMessage },
24497
+ reasons: reason.reasons ?? [],
24498
+ policy_result: reason.data?.policy_result,
24499
+ verify_url: reason.verify_url,
24500
+ next_steps: buildContactSupportNextSteps(opts.supportEmail, supportContext)
24501
+ }
24502
+ };
24503
+ }
24504
+ if (reason.code === "payment_required") {
24505
+ return {
24506
+ status: 403,
24507
+ body: {
24508
+ ...denialReasonToBody(reason),
24509
+ error: { code: "compliance_error", message: paymentRequiredMessage }
24510
+ }
24511
+ };
24512
+ }
24513
+ const status = reason.code === "token_expired" || reason.code === "invalid_credential" ? 401 : reason.code === "api_error" ? 503 : 403;
24514
+ return {
24515
+ status,
24516
+ body: denialReasonToBody(reason),
24517
+ ...status >= 500 && { headers: { "Cache-Control": "no-store" } }
24518
+ };
24519
+ };
24520
+ }
24521
+ function defaultReadOnlyOnDenied(reason) {
24522
+ const message = reason.code === "missing_identity" ? "X-Wallet-Address or X-Operator-Token header required" : "Invalid identity";
24523
+ return {
24524
+ status: 401,
24525
+ body: {
24526
+ ...denialReasonToBody(reason),
24527
+ error: { code: "unauthorized", message }
24528
+ },
24529
+ headers: { "Cache-Control": "no-store" }
24530
+ };
24531
+ }
23802
24532
  export {
24533
+ A2A_DEFAULT_TRANSPORT,
24534
+ A2A_PROTOCOL_VERSION,
23803
24535
  AGENTSCORE_UCP_CAPABILITY,
23804
24536
  Checkout,
23805
24537
  CheckoutValidationError,
@@ -23810,18 +24542,28 @@ export {
23810
24542
  buildA2AAgentCard,
23811
24543
  buildAgentMemoryHint,
23812
24544
  buildContactSupportNextSteps,
24545
+ buildDefaultCheckoutRails,
23813
24546
  buildGateFromPolicy,
23814
24547
  buildJWKSResponse,
24548
+ buildMppxComposeRails,
23815
24549
  buildSignerMismatchBody,
23816
24550
  buildUCPProfile,
24551
+ computeFirstCheckout,
24552
+ createDefaultOnDenied,
24553
+ createQuoteCache,
24554
+ defaultReadOnlyOnDenied,
23817
24555
  denialReasonStatus,
23818
24556
  denialReasonToBody,
24557
+ extractOwnerScope,
23819
24558
  extractPaymentSigner,
23820
24559
  extractPaymentSignerFromAuth,
23821
24560
  extractSignerForPrecheck,
23822
24561
  formatUsdCents,
23823
24562
  generateUCPSigningKey,
23824
24563
  getIdentityStatus,
24564
+ hasMppxHeader,
24565
+ hasPaymentHeader,
24566
+ hasX402Header,
23825
24567
  hashOperatorToken,
23826
24568
  isFixableDenial,
23827
24569
  loadSolanaFeePayer,