@agent-score/commerce 2.0.1 → 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-B1JuEcbx.d.ts → checkout-BH-I_Ns8.d.ts} +19 -12
  11. package/dist/{checkout-BN5i1Fi7.d.mts → checkout-Bd_4aQ6c.d.mts} +19 -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 +220 -129
  49. package/dist/identity/policy.js.map +1 -1
  50. package/dist/identity/policy.mjs +222 -131
  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 +951 -152
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +939 -152
  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 +43 -5
  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
@@ -33,64 +33,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  ));
34
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
35
 
36
- // src/payment/usdc.ts
37
- var USDC;
38
- var init_usdc = __esm({
39
- "src/payment/usdc.ts"() {
40
- "use strict";
41
- USDC = {
42
- base: {
43
- mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
44
- sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
45
- },
46
- solana: {
47
- mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
48
- devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
49
- },
50
- tempo: {
51
- mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
52
- testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
53
- }
54
- };
55
- }
56
- });
57
-
58
- // src/payment/wwwauthenticate.ts
59
- function paymentRequiredHeader({
60
- x402Version,
61
- accepts,
62
- resource
63
- }) {
64
- return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
65
- }
66
- var init_wwwauthenticate = __esm({
67
- "src/payment/wwwauthenticate.ts"() {
68
- "use strict";
69
- }
70
- });
71
-
72
- // src/payment/networks.ts
73
- var networks;
74
- var init_networks = __esm({
75
- "src/payment/networks.ts"() {
76
- "use strict";
77
- networks = {
78
- base: {
79
- mainnet: { caip2: "eip155:8453", chainId: 8453 },
80
- sepolia: { caip2: "eip155:84532", chainId: 84532 }
81
- },
82
- solana: {
83
- mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
84
- devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
85
- },
86
- tempo: {
87
- mainnet: { caip2: "eip155:4217", chainId: 4217 },
88
- testnet: { caip2: "eip155:42431", chainId: 42431 }
89
- }
90
- };
91
- }
92
- });
93
-
94
36
  // node_modules/ox/_esm/core/Abi.js
95
37
  var init_Abi = __esm({
96
38
  "node_modules/ox/_esm/core/Abi.js"() {
@@ -19089,7 +19031,7 @@ function deserialize3(value) {
19089
19031
  try {
19090
19032
  const json2 = Base64_exports.toString(prefixMatch[1]);
19091
19033
  const parsed = JSON.parse(json2);
19092
- const { opaque: challengeOpaque, request, ...challengeFields } = parsed.challenge;
19034
+ const { opaque: challengeOpaque, request, meta: _meta, ...challengeFields } = parsed.challenge;
19093
19035
  const { meta: meta4, opaque } = normalizeCredentialOpaque(challengeOpaque);
19094
19036
  const challenge = Schema.parse({
19095
19037
  ...challengeFields,
@@ -19206,11 +19148,11 @@ __export(Errors_exports2, {
19206
19148
  PaymentExpiredError: () => PaymentExpiredError,
19207
19149
  PaymentInsufficientError: () => PaymentInsufficientError,
19208
19150
  PaymentMethodUnsupportedError: () => PaymentMethodUnsupportedError,
19209
- PaymentRequiredError: () => PaymentRequiredError2,
19151
+ PaymentRequiredError: () => PaymentRequiredError,
19210
19152
  SignerMismatchError: () => SignerMismatchError,
19211
19153
  VerificationFailedError: () => VerificationFailedError
19212
19154
  });
19213
- var PaymentError, MalformedCredentialError, InvalidChallengeError, VerificationFailedError, PaymentActionRequiredError, PaymentExpiredError, PaymentRequiredError2, InvalidPayloadError, BadRequestError, PaymentInsufficientError, PaymentMethodUnsupportedError, InsufficientBalanceError, InvalidSignatureError, SignerMismatchError, AmountExceedsDepositError, DeltaTooSmallError, ChannelNotFoundError, ChannelClosedError;
19155
+ var PaymentError, MalformedCredentialError, InvalidChallengeError, VerificationFailedError, PaymentActionRequiredError, PaymentExpiredError, PaymentRequiredError, InvalidPayloadError, BadRequestError, PaymentInsufficientError, PaymentMethodUnsupportedError, InsufficientBalanceError, InvalidSignatureError, SignerMismatchError, AmountExceedsDepositError, DeltaTooSmallError, ChannelNotFoundError, ChannelClosedError;
19214
19156
  var init_Errors2 = __esm({
19215
19157
  "node_modules/mppx/dist/Errors.js"() {
19216
19158
  "use strict";
@@ -19277,7 +19219,7 @@ var init_Errors2 = __esm({
19277
19219
  super(expires ? `Payment expired at ${expires}.` : "Payment has expired.");
19278
19220
  }
19279
19221
  };
19280
- PaymentRequiredError2 = class extends PaymentError {
19222
+ PaymentRequiredError = class extends PaymentError {
19281
19223
  name = "PaymentRequiredError";
19282
19224
  title = "Payment Required";
19283
19225
  type = "https://paymentauth.org/problems/payment-required";
@@ -19702,6 +19644,85 @@ var init_dist2 = __esm({
19702
19644
  }
19703
19645
  });
19704
19646
 
19647
+ // src/payment/usdc.ts
19648
+ var USDC;
19649
+ var init_usdc = __esm({
19650
+ "src/payment/usdc.ts"() {
19651
+ "use strict";
19652
+ USDC = {
19653
+ base: {
19654
+ mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
19655
+ sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
19656
+ },
19657
+ solana: {
19658
+ mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
19659
+ devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
19660
+ },
19661
+ tempo: {
19662
+ mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
19663
+ testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
19664
+ }
19665
+ };
19666
+ }
19667
+ });
19668
+
19669
+ // src/payment/wwwauthenticate.ts
19670
+ function paymentRequiredHeader({
19671
+ x402Version,
19672
+ accepts,
19673
+ resource
19674
+ }) {
19675
+ return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
19676
+ }
19677
+ var init_wwwauthenticate = __esm({
19678
+ "src/payment/wwwauthenticate.ts"() {
19679
+ "use strict";
19680
+ }
19681
+ });
19682
+
19683
+ // src/payment/networks.ts
19684
+ var networks;
19685
+ var init_networks = __esm({
19686
+ "src/payment/networks.ts"() {
19687
+ "use strict";
19688
+ networks = {
19689
+ base: {
19690
+ mainnet: { caip2: "eip155:8453", chainId: 8453 },
19691
+ sepolia: { caip2: "eip155:84532", chainId: 84532 }
19692
+ },
19693
+ solana: {
19694
+ mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
19695
+ devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
19696
+ },
19697
+ tempo: {
19698
+ mainnet: { caip2: "eip155:4217", chainId: 4217 },
19699
+ testnet: { caip2: "eip155:42431", chainId: 42431 }
19700
+ }
19701
+ };
19702
+ }
19703
+ });
19704
+
19705
+ // src/payment/network_kind.ts
19706
+ function readNetwork(input) {
19707
+ if (typeof input === "string") return input;
19708
+ if (input && typeof input === "object") {
19709
+ const network = input.network;
19710
+ return typeof network === "string" ? network : "";
19711
+ }
19712
+ return "";
19713
+ }
19714
+ function isEvmNetwork(input) {
19715
+ return readNetwork(input).startsWith("eip155:");
19716
+ }
19717
+ function isSolanaNetwork(input) {
19718
+ return readNetwork(input).startsWith("solana:");
19719
+ }
19720
+ var init_network_kind = __esm({
19721
+ "src/payment/network_kind.ts"() {
19722
+ "use strict";
19723
+ }
19724
+ });
19725
+
19705
19726
  // src/payment/rails.ts
19706
19727
  function lookupRail(name) {
19707
19728
  return rails[name];
@@ -20084,7 +20105,7 @@ function isTempoSessionRailSpec2(s) {
20084
20105
  }
20085
20106
  function mppRailToNetworkEntry(spec) {
20086
20107
  if (isTempoSessionRailSpec2(spec)) return tempoSessionToNetworkEntry(spec);
20087
- if ("rpcUrl" in spec || "tokenProgram" in spec || (spec.network?.startsWith("solana:") ?? false)) {
20108
+ if ("rpcUrl" in spec || "tokenProgram" in spec || isSolanaNetwork(spec)) {
20088
20109
  return solanaMppToNetworkEntry(spec);
20089
20110
  }
20090
20111
  if (isTempoRailSpec(spec)) return tempoToNetworkEntry(spec);
@@ -20141,6 +20162,7 @@ var UCPSigningKey, DEFAULT_VERSION, AGENTSCORE_CAPABILITY_NAME, AGENTSCORE_CAPAB
20141
20162
  var init_ucp = __esm({
20142
20163
  "src/identity/ucp.ts"() {
20143
20164
  "use strict";
20165
+ init_network_kind();
20144
20166
  UCPSigningKey = {
20145
20167
  fromJWK: ucpSigningKeyFromJWKImpl
20146
20168
  };
@@ -20653,6 +20675,34 @@ module.exports = __toCommonJS(policy_exports);
20653
20675
  // src/checkout.ts
20654
20676
  var import_node_crypto = require("crypto");
20655
20677
 
20678
+ // src/_headers.ts
20679
+ function normalizeHeadersToLowercase(headers) {
20680
+ const out = {};
20681
+ for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
20682
+ return out;
20683
+ }
20684
+
20685
+ // src/_mppx_receipt.ts
20686
+ function extractMppxReceiptHeaderFromRaw(raw) {
20687
+ if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
20688
+ const fn = raw.withReceipt;
20689
+ if (typeof fn !== "function") return null;
20690
+ try {
20691
+ const wrapped = fn.call(raw, new Response());
20692
+ return wrapped.headers.get("Payment-Receipt");
20693
+ } catch {
20694
+ return null;
20695
+ }
20696
+ }
20697
+ async function extractMppxReceiptMethod(header) {
20698
+ try {
20699
+ const { Receipt } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
20700
+ return Receipt.deserialize(header).method;
20701
+ } catch {
20702
+ return void 0;
20703
+ }
20704
+ }
20705
+
20656
20706
  // src/_response.ts
20657
20707
  var WALLET_NOT_TRUSTED_INSTRUCTIONS = JSON.stringify({
20658
20708
  action: "contact_support",
@@ -21062,7 +21112,7 @@ function createAgentScoreCore(options) {
21062
21112
  } = options;
21063
21113
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
21064
21114
  const agentMemoryHint = buildAgentMemoryHint();
21065
- const defaultUa = `@agent-score/commerce@${"2.0.1"}`;
21115
+ const defaultUa = `@agent-score/commerce@${"2.1.0"}`;
21066
21116
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
21067
21117
  const sdk = new import_sdk.AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
21068
21118
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -21428,10 +21478,13 @@ function buildHowToPay({
21428
21478
  totalUsd,
21429
21479
  rails: rails2,
21430
21480
  opTokenPlaceholder,
21431
- maxSpend
21481
+ maxSpend,
21482
+ decimals
21432
21483
  }) {
21433
21484
  const totalNum = typeof totalUsd === "string" ? Number(totalUsd) : totalUsd;
21434
- const maxSpendStr = String(maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
21485
+ const d = decimals ?? 2;
21486
+ const defaultMaxSpend = totalNum >= 1 ? (Math.ceil(totalNum) + 1).toFixed(d) : totalNum.toFixed(d);
21487
+ const maxSpendStr = String(maxSpend ?? defaultMaxSpend);
21435
21488
  const opToken = opTokenPlaceholder ?? "<your_opc_token>";
21436
21489
  const block = {};
21437
21490
  if (rails2.tempo) {
@@ -21524,26 +21577,26 @@ function buildPricingBlock({
21524
21577
  totalCents,
21525
21578
  taxRate,
21526
21579
  taxState,
21527
- currency
21580
+ currency,
21581
+ decimals
21528
21582
  }) {
21529
21583
  const shipping = shippingCents ?? 0;
21530
21584
  const discount = discountCents ?? 0;
21531
21585
  const total = totalCents ?? Math.max(0, subtotalCents + taxCents + shipping - discount);
21586
+ const d = decimals ?? 2;
21587
+ const fmt = (cents) => (cents / 100).toFixed(d);
21532
21588
  const block = {
21533
- subtotal: formatCents(subtotalCents),
21534
- tax: formatCents(taxCents),
21535
- total: formatCents(total)
21589
+ subtotal: fmt(subtotalCents),
21590
+ tax: fmt(taxCents),
21591
+ total: fmt(total)
21536
21592
  };
21537
- if (shippingCents !== void 0) block.shipping = formatCents(shipping);
21538
- if (discountCents !== void 0) block.discount = formatCents(discount);
21593
+ if (shippingCents !== void 0) block.shipping = fmt(shipping);
21594
+ if (discountCents !== void 0) block.discount = fmt(discount);
21539
21595
  if (taxRate !== void 0) block.tax_rate = taxRate;
21540
21596
  if (taxState !== void 0) block.tax_state = taxState;
21541
21597
  if (currency !== void 0) block.currency = currency;
21542
21598
  return block;
21543
21599
  }
21544
- function formatCents(cents) {
21545
- return (cents / 100).toFixed(2);
21546
- }
21547
21600
 
21548
21601
  // src/challenge/respond_402.ts
21549
21602
  init_wwwauthenticate();
@@ -21552,10 +21605,7 @@ function respond402({
21552
21605
  body,
21553
21606
  x402
21554
21607
  }) {
21555
- const headers = {};
21556
- for (const [k, v] of Object.entries(mppxChallengeHeaders)) {
21557
- headers[k.toLowerCase()] = v;
21558
- }
21608
+ const headers = normalizeHeadersToLowercase(mppxChallengeHeaders);
21559
21609
  headers["content-type"] = "application/json";
21560
21610
  if (x402) {
21561
21611
  headers["payment-required"] = paymentRequiredHeader(x402);
@@ -21618,7 +21668,8 @@ function isSolanaMppRailSpec(s) {
21618
21668
  return s.network?.startsWith("solana:") ?? false;
21619
21669
  }
21620
21670
  function solanaNetworkFromCAIP2(caip2) {
21621
- if (caip2 === networks.solana.devnet.caip2) return "devnet";
21671
+ if (caip2 === "devnet" || caip2 === networks.solana.devnet.caip2) return "devnet";
21672
+ if (caip2 === "localnet") return "localnet";
21622
21673
  return "mainnet-beta";
21623
21674
  }
21624
21675
  function solanaDefaultRpcUrl(network) {
@@ -21902,6 +21953,35 @@ function lazyMppxServer(opts) {
21902
21953
  };
21903
21954
  }
21904
21955
 
21956
+ // src/checkout.ts
21957
+ init_network_kind();
21958
+
21959
+ // src/payment/payment_header.ts
21960
+ function toTitleCase(name) {
21961
+ return name.replace(/(^|-)([a-z])/g, (_m, sep, c) => sep + c.toUpperCase());
21962
+ }
21963
+ function readHeader(headers, name) {
21964
+ if (typeof headers.get === "function") {
21965
+ return headers.get(name);
21966
+ }
21967
+ const rec = headers;
21968
+ const v = rec[name] ?? rec[name.toLowerCase()] ?? rec[toTitleCase(name)];
21969
+ if (typeof v === "string") return v;
21970
+ if (Array.isArray(v) && typeof v[0] === "string") return v[0];
21971
+ return null;
21972
+ }
21973
+ function asHeaders(input) {
21974
+ return typeof input.headers === "object" && input instanceof Request ? input.headers : input;
21975
+ }
21976
+ function hasX402Header(input) {
21977
+ const headers = asHeaders(input);
21978
+ return Boolean(readHeader(headers, "payment-signature") || readHeader(headers, "x-payment"));
21979
+ }
21980
+ function hasMppxHeader(input) {
21981
+ const headers = asHeaders(input);
21982
+ return Boolean(readHeader(headers, "authorization")?.startsWith("Payment "));
21983
+ }
21984
+
21905
21985
  // src/payment/x402_settle.ts
21906
21986
  function classifyX402SettleResult(result) {
21907
21987
  if (result.success) return null;
@@ -22272,21 +22352,8 @@ var CheckoutValidationError = class extends Error {
22272
22352
  this.extra = opts.extra;
22273
22353
  }
22274
22354
  };
22275
- function lowerHeaders(headers) {
22276
- const out = {};
22277
- for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
22278
- return out;
22279
- }
22280
- function hasX402Header(headers) {
22281
- const h = lowerHeaders(headers);
22282
- return Boolean(h["payment-signature"] ?? h["x-payment"]);
22283
- }
22284
- function hasMppxHeader(headers) {
22285
- const h = lowerHeaders(headers);
22286
- return (h["authorization"] ?? "").startsWith("Payment ");
22287
- }
22288
22355
  function resolveIdentityMetadata(ctx) {
22289
- const h = lowerHeaders(ctx.request.headers);
22356
+ const h = normalizeHeadersToLowercase(ctx.request.headers);
22290
22357
  const wallet = h["x-wallet-address"];
22291
22358
  if (!wallet) return void 0;
22292
22359
  let linkedWallets;
@@ -22315,26 +22382,24 @@ function isTempoSessionRailSpec3(s) {
22315
22382
  function specRailKey(spec) {
22316
22383
  if (isStripeRailSpec2(spec)) return "stripe";
22317
22384
  if (isTempoSessionRailSpec3(spec)) return "tempo_mpp";
22318
- const network = spec.network ?? "";
22319
- if (network.startsWith("eip155:")) return "x402_base";
22320
- if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana_mpp";
22385
+ if (isEvmNetwork(spec)) return "x402_base";
22386
+ if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana_mpp";
22321
22387
  return "tempo_mpp";
22322
22388
  }
22323
22389
  function specMethodName(spec) {
22324
22390
  if (isStripeRailSpec2(spec)) return "stripe/spt";
22325
22391
  if (isTempoSessionRailSpec3(spec)) return "tempo/charge";
22326
- const network = spec.network ?? "";
22327
- if (network.startsWith("eip155:")) return "x402/exact (base)";
22328
- if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana/charge";
22392
+ if (isEvmNetwork(spec)) return "x402/exact (base)";
22393
+ if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana/charge";
22329
22394
  return "tempo/charge";
22330
22395
  }
22331
22396
  function makeMppxComposeHook(opts) {
22332
22397
  return async (ctx) => {
22333
22398
  if (ctx.pricing === null) return { status: 402 };
22334
22399
  const mpp = await opts.serverGetter();
22335
- const lower = lowerHeaders(ctx.request.headers);
22400
+ const lower = normalizeHeadersToLowercase(ctx.request.headers);
22336
22401
  const authorization = lower["authorization"];
22337
- const amountStr = ctx.pricing.amountUsd.toFixed(2);
22402
+ const amountStr = ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2);
22338
22403
  let result;
22339
22404
  try {
22340
22405
  result = await mpp.charge({ authorization, amount: amountStr });
@@ -22418,7 +22483,7 @@ var Checkout = class {
22418
22483
  let x402ServerGetter;
22419
22484
  if (x402Server === void 0) {
22420
22485
  const baseSpec = Object.values(opts.rails).find(
22421
- (s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && (s.network ?? "").startsWith("eip155:")
22486
+ (s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && isEvmNetwork(s)
22422
22487
  );
22423
22488
  if (baseSpec !== void 0) {
22424
22489
  x402ServerGetter = lazyX402Server({
@@ -22508,7 +22573,7 @@ var Checkout = class {
22508
22573
  * `"x402_base"` when no match found. */
22509
22574
  x402RailKey() {
22510
22575
  for (const [k, v] of Object.entries(this.rails)) {
22511
- if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && (v.network ?? "").startsWith("eip155:")) {
22576
+ if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && isEvmNetwork(v)) {
22512
22577
  return k;
22513
22578
  }
22514
22579
  }
@@ -22517,18 +22582,47 @@ var Checkout = class {
22517
22582
  /** Return the rails-dict key for the primary MPP rail. */
22518
22583
  mppRailKey() {
22519
22584
  for (const [k, v] of Object.entries(this.rails)) {
22520
- const network = v.network ?? "";
22521
- if (!isStripeRailSpec2(v) && !network.startsWith("eip155:")) return k;
22585
+ if (!isStripeRailSpec2(v) && !isEvmNetwork(v)) return k;
22522
22586
  }
22523
22587
  return "tempo";
22524
22588
  }
22589
+ /** Map an mppx credential `method` (`tempo` | `solana` | `stripe`) to the
22590
+ * merchant's rails-dict key. Used in handleMppx so onSettled outcomes
22591
+ * distinguish Solana from Tempo (both settle under `rail: 'mpp'`) and from
22592
+ * Stripe SPT. Returns the first matching key or `undefined` when no rail in
22593
+ * the merchant's config corresponds to that method. */
22594
+ railsKeyForMppxMethod(method) {
22595
+ if (method === "stripe") {
22596
+ for (const [k, v] of Object.entries(this.rails)) {
22597
+ if (isStripeRailSpec2(v)) return k;
22598
+ }
22599
+ return void 0;
22600
+ }
22601
+ if (method === "solana") {
22602
+ for (const [k, v] of Object.entries(this.rails)) {
22603
+ if (isStripeRailSpec2(v) || isTempoSessionRailSpec3(v)) continue;
22604
+ if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) return k;
22605
+ }
22606
+ return void 0;
22607
+ }
22608
+ if (method === "tempo") {
22609
+ for (const [k, v] of Object.entries(this.rails)) {
22610
+ if (isStripeRailSpec2(v)) continue;
22611
+ if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) continue;
22612
+ if (isEvmNetwork(v)) continue;
22613
+ return k;
22614
+ }
22615
+ return void 0;
22616
+ }
22617
+ return void 0;
22618
+ }
22525
22619
  /** CAIP-2 read from `rails['x402_base'].network` (or its default).
22526
22620
  * Defined only when an `X402BaseRailSpec` is present in rails AND a server
22527
22621
  * is configured (explicit or auto-derived); otherwise `null`. */
22528
22622
  get x402BaseNetwork() {
22529
22623
  if (!this.x402ServerAvailable()) return null;
22530
22624
  for (const spec of Object.values(this.rails)) {
22531
- if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && (spec.network ?? "").startsWith("eip155:")) {
22625
+ if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && isEvmNetwork(spec)) {
22532
22626
  return spec.network ?? "eip155:8453";
22533
22627
  }
22534
22628
  }
@@ -22671,7 +22765,7 @@ var Checkout = class {
22671
22765
  ...policyOverride ?? {}
22672
22766
  };
22673
22767
  const core = createAgentScoreCore(coreOpts);
22674
- const headers = lowerHeaders(ctx.request.headers);
22768
+ const headers = normalizeHeadersToLowercase(ctx.request.headers);
22675
22769
  const walletAddress = headers["x-wallet-address"];
22676
22770
  const operatorToken = headers["x-operator-token"];
22677
22771
  const identity = walletAddress !== void 0 || operatorToken !== void 0 ? {
@@ -22733,7 +22827,7 @@ var Checkout = class {
22733
22827
  if (!this.zeroSettleCarveOut || ctx.pricing === null) return null;
22734
22828
  const cents = Math.round(ctx.pricing.amountUsd * 100);
22735
22829
  if (cents !== 0) return null;
22736
- const headers = lowerHeaders(ctx.request.headers);
22830
+ const headers = normalizeHeadersToLowercase(ctx.request.headers);
22737
22831
  let zero;
22738
22832
  if (rail === "x402-base") {
22739
22833
  const x402Header = headers["payment-signature"] ?? headers["x-payment"];
@@ -22807,7 +22901,7 @@ var Checkout = class {
22807
22901
  resourceConfig: {
22808
22902
  scheme: "exact",
22809
22903
  network: verified.signedNetwork,
22810
- price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
22904
+ price: `$${ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2)}`,
22811
22905
  payTo: verified.signedPayTo,
22812
22906
  maxTimeoutSeconds: 300
22813
22907
  },
@@ -22868,15 +22962,20 @@ var Checkout = class {
22868
22962
  }
22869
22963
  const composed = await this.composeMppx(ctx);
22870
22964
  if (composed.status === 200) {
22965
+ const paymentReceiptHeader = composed.paymentReceiptHeader ?? extractMppxReceiptHeaderFromRaw(composed.raw);
22966
+ const directMethod = composed.raw?.receipt?.method;
22967
+ const headerMethod = paymentReceiptHeader ? await extractMppxReceiptMethod(paymentReceiptHeader) : void 0;
22968
+ const receiptMethod = directMethod ?? headerMethod;
22969
+ const derivedKey = typeof receiptMethod === "string" ? this.railsKeyForMppxMethod(receiptMethod) : void 0;
22871
22970
  const outcome = {
22872
22971
  rail: "mpp",
22873
22972
  paymentResponseHeader: composed.paymentResponseHeader ?? null,
22874
- paymentReceiptHeader: composed.paymentReceiptHeader ?? extractMppxReceiptHeaderFromRaw(composed.raw),
22973
+ paymentReceiptHeader,
22875
22974
  raw: composed.raw,
22876
22975
  txHash: composed.txHash ?? null,
22877
22976
  signerAddress: composed.signerAddress ?? null,
22878
22977
  signerNetwork: composed.signerNetwork ?? null,
22879
- railKey: composed.railKey ?? this.mppRailKey()
22978
+ railKey: derivedKey ?? composed.railKey ?? this.mppRailKey()
22880
22979
  };
22881
22980
  return await this.buildSuccess(ctx, outcome);
22882
22981
  }
@@ -22911,15 +23010,18 @@ var Checkout = class {
22911
23010
  howToPayRails[k] = v;
22912
23011
  }
22913
23012
  }
23013
+ const pricingDecimals = ctx.pricing.decimals ?? 2;
22914
23014
  const howToPay = buildHowToPay({
22915
23015
  url: this.url,
22916
23016
  retryBodyJson: JSON.stringify(ctx.request.body),
22917
- totalUsd: ctx.pricing.amountUsd.toFixed(2),
22918
- rails: howToPayRails
23017
+ totalUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
23018
+ rails: howToPayRails,
23019
+ ...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
22919
23020
  });
22920
23021
  const pricingBlock = ctx.pricing.block ?? buildPricingBlock({
22921
- subtotalCents: Math.round(ctx.pricing.amountUsd * 100),
22922
- currency: ctx.pricing.currency ?? "USD"
23022
+ subtotalCents: ctx.pricing.amountUsd * 100,
23023
+ currency: ctx.pricing.currency ?? "USD",
23024
+ ...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
22923
23025
  });
22924
23026
  let x402Accepts = [];
22925
23027
  let x402Resource;
@@ -22932,7 +23034,7 @@ var Checkout = class {
22932
23034
  try {
22933
23035
  x402Accepts = await buildX402AcceptsFor402(x402Server, {
22934
23036
  network: baseNetwork,
22935
- price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
23037
+ price: `$${ctx.pricing.amountUsd.toFixed(pricingDecimals)}`,
22936
23038
  payTo: recipient,
22937
23039
  maxTimeoutSeconds: 300
22938
23040
  });
@@ -22948,7 +23050,7 @@ var Checkout = class {
22948
23050
  agentInstructions: buildAgentInstructions({ howToPay }),
22949
23051
  ...identityMetadata !== void 0 ? { identityMetadata } : {},
22950
23052
  pricing: pricingBlock,
22951
- amountUsd: ctx.pricing.amountUsd.toFixed(2),
23053
+ amountUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
22952
23054
  retryBody: ctx.request.body,
22953
23055
  agentMemory: firstEncounterAgentMemory({ firstEncounter: true }),
22954
23056
  ...ctx.pricing.product ? { product: ctx.pricing.product } : {},
@@ -23030,17 +23132,6 @@ function stripContentType(headers) {
23030
23132
  }
23031
23133
  return out;
23032
23134
  }
23033
- function extractMppxReceiptHeaderFromRaw(raw) {
23034
- if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
23035
- const fn = raw.withReceipt;
23036
- if (typeof fn !== "function") return null;
23037
- try {
23038
- const wrapped = fn.call(raw, new Response());
23039
- return wrapped.headers.get("Payment-Receipt");
23040
- } catch {
23041
- return null;
23042
- }
23043
- }
23044
23135
  function headersToRecord(h) {
23045
23136
  if (h === void 0) return {};
23046
23137
  if (h instanceof Headers) {