@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
@@ -31,64 +31,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  mod
32
32
  ));
33
33
 
34
- // src/payment/usdc.ts
35
- var USDC;
36
- var init_usdc = __esm({
37
- "src/payment/usdc.ts"() {
38
- "use strict";
39
- USDC = {
40
- base: {
41
- mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
42
- sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
43
- },
44
- solana: {
45
- mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
46
- devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
47
- },
48
- tempo: {
49
- mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
50
- testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
51
- }
52
- };
53
- }
54
- });
55
-
56
- // src/payment/wwwauthenticate.ts
57
- function paymentRequiredHeader({
58
- x402Version,
59
- accepts,
60
- resource
61
- }) {
62
- return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
63
- }
64
- var init_wwwauthenticate = __esm({
65
- "src/payment/wwwauthenticate.ts"() {
66
- "use strict";
67
- }
68
- });
69
-
70
- // src/payment/networks.ts
71
- var networks;
72
- var init_networks = __esm({
73
- "src/payment/networks.ts"() {
74
- "use strict";
75
- networks = {
76
- base: {
77
- mainnet: { caip2: "eip155:8453", chainId: 8453 },
78
- sepolia: { caip2: "eip155:84532", chainId: 84532 }
79
- },
80
- solana: {
81
- mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
82
- devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
83
- },
84
- tempo: {
85
- mainnet: { caip2: "eip155:4217", chainId: 4217 },
86
- testnet: { caip2: "eip155:42431", chainId: 42431 }
87
- }
88
- };
89
- }
90
- });
91
-
92
34
  // node_modules/ox/_esm/core/Abi.js
93
35
  var init_Abi = __esm({
94
36
  "node_modules/ox/_esm/core/Abi.js"() {
@@ -19087,7 +19029,7 @@ function deserialize3(value) {
19087
19029
  try {
19088
19030
  const json2 = Base64_exports.toString(prefixMatch[1]);
19089
19031
  const parsed = JSON.parse(json2);
19090
- const { opaque: challengeOpaque, request, ...challengeFields } = parsed.challenge;
19032
+ const { opaque: challengeOpaque, request, meta: _meta, ...challengeFields } = parsed.challenge;
19091
19033
  const { meta: meta4, opaque } = normalizeCredentialOpaque(challengeOpaque);
19092
19034
  const challenge = Schema.parse({
19093
19035
  ...challengeFields,
@@ -19204,11 +19146,11 @@ __export(Errors_exports2, {
19204
19146
  PaymentExpiredError: () => PaymentExpiredError,
19205
19147
  PaymentInsufficientError: () => PaymentInsufficientError,
19206
19148
  PaymentMethodUnsupportedError: () => PaymentMethodUnsupportedError,
19207
- PaymentRequiredError: () => PaymentRequiredError2,
19149
+ PaymentRequiredError: () => PaymentRequiredError,
19208
19150
  SignerMismatchError: () => SignerMismatchError,
19209
19151
  VerificationFailedError: () => VerificationFailedError
19210
19152
  });
19211
- var PaymentError, MalformedCredentialError, InvalidChallengeError, VerificationFailedError, PaymentActionRequiredError, PaymentExpiredError, PaymentRequiredError2, InvalidPayloadError, BadRequestError, PaymentInsufficientError, PaymentMethodUnsupportedError, InsufficientBalanceError, InvalidSignatureError, SignerMismatchError, AmountExceedsDepositError, DeltaTooSmallError, ChannelNotFoundError, ChannelClosedError;
19153
+ var PaymentError, MalformedCredentialError, InvalidChallengeError, VerificationFailedError, PaymentActionRequiredError, PaymentExpiredError, PaymentRequiredError, InvalidPayloadError, BadRequestError, PaymentInsufficientError, PaymentMethodUnsupportedError, InsufficientBalanceError, InvalidSignatureError, SignerMismatchError, AmountExceedsDepositError, DeltaTooSmallError, ChannelNotFoundError, ChannelClosedError;
19212
19154
  var init_Errors2 = __esm({
19213
19155
  "node_modules/mppx/dist/Errors.js"() {
19214
19156
  "use strict";
@@ -19275,7 +19217,7 @@ var init_Errors2 = __esm({
19275
19217
  super(expires ? `Payment expired at ${expires}.` : "Payment has expired.");
19276
19218
  }
19277
19219
  };
19278
- PaymentRequiredError2 = class extends PaymentError {
19220
+ PaymentRequiredError = class extends PaymentError {
19279
19221
  name = "PaymentRequiredError";
19280
19222
  title = "Payment Required";
19281
19223
  type = "https://paymentauth.org/problems/payment-required";
@@ -19700,6 +19642,85 @@ var init_dist2 = __esm({
19700
19642
  }
19701
19643
  });
19702
19644
 
19645
+ // src/payment/usdc.ts
19646
+ var USDC;
19647
+ var init_usdc = __esm({
19648
+ "src/payment/usdc.ts"() {
19649
+ "use strict";
19650
+ USDC = {
19651
+ base: {
19652
+ mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
19653
+ sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
19654
+ },
19655
+ solana: {
19656
+ mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
19657
+ devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
19658
+ },
19659
+ tempo: {
19660
+ mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
19661
+ testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
19662
+ }
19663
+ };
19664
+ }
19665
+ });
19666
+
19667
+ // src/payment/wwwauthenticate.ts
19668
+ function paymentRequiredHeader({
19669
+ x402Version,
19670
+ accepts,
19671
+ resource
19672
+ }) {
19673
+ return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
19674
+ }
19675
+ var init_wwwauthenticate = __esm({
19676
+ "src/payment/wwwauthenticate.ts"() {
19677
+ "use strict";
19678
+ }
19679
+ });
19680
+
19681
+ // src/payment/networks.ts
19682
+ var networks;
19683
+ var init_networks = __esm({
19684
+ "src/payment/networks.ts"() {
19685
+ "use strict";
19686
+ networks = {
19687
+ base: {
19688
+ mainnet: { caip2: "eip155:8453", chainId: 8453 },
19689
+ sepolia: { caip2: "eip155:84532", chainId: 84532 }
19690
+ },
19691
+ solana: {
19692
+ mainnet: { caip2: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" },
19693
+ devnet: { caip2: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1" }
19694
+ },
19695
+ tempo: {
19696
+ mainnet: { caip2: "eip155:4217", chainId: 4217 },
19697
+ testnet: { caip2: "eip155:42431", chainId: 42431 }
19698
+ }
19699
+ };
19700
+ }
19701
+ });
19702
+
19703
+ // src/payment/network_kind.ts
19704
+ function readNetwork(input) {
19705
+ if (typeof input === "string") return input;
19706
+ if (input && typeof input === "object") {
19707
+ const network = input.network;
19708
+ return typeof network === "string" ? network : "";
19709
+ }
19710
+ return "";
19711
+ }
19712
+ function isEvmNetwork(input) {
19713
+ return readNetwork(input).startsWith("eip155:");
19714
+ }
19715
+ function isSolanaNetwork(input) {
19716
+ return readNetwork(input).startsWith("solana:");
19717
+ }
19718
+ var init_network_kind = __esm({
19719
+ "src/payment/network_kind.ts"() {
19720
+ "use strict";
19721
+ }
19722
+ });
19723
+
19703
19724
  // src/payment/rails.ts
19704
19725
  function lookupRail(name) {
19705
19726
  return rails[name];
@@ -20082,7 +20103,7 @@ function isTempoSessionRailSpec2(s) {
20082
20103
  }
20083
20104
  function mppRailToNetworkEntry(spec) {
20084
20105
  if (isTempoSessionRailSpec2(spec)) return tempoSessionToNetworkEntry(spec);
20085
- if ("rpcUrl" in spec || "tokenProgram" in spec || (spec.network?.startsWith("solana:") ?? false)) {
20106
+ if ("rpcUrl" in spec || "tokenProgram" in spec || isSolanaNetwork(spec)) {
20086
20107
  return solanaMppToNetworkEntry(spec);
20087
20108
  }
20088
20109
  if (isTempoRailSpec(spec)) return tempoToNetworkEntry(spec);
@@ -20139,6 +20160,7 @@ var UCPSigningKey, DEFAULT_VERSION, AGENTSCORE_CAPABILITY_NAME, AGENTSCORE_CAPAB
20139
20160
  var init_ucp = __esm({
20140
20161
  "src/identity/ucp.ts"() {
20141
20162
  "use strict";
20163
+ init_network_kind();
20142
20164
  UCPSigningKey = {
20143
20165
  fromJWK: ucpSigningKeyFromJWKImpl
20144
20166
  };
@@ -20640,6 +20662,34 @@ var init_well_known = __esm({
20640
20662
  // src/checkout.ts
20641
20663
  import { randomUUID } from "crypto";
20642
20664
 
20665
+ // src/_headers.ts
20666
+ function normalizeHeadersToLowercase(headers) {
20667
+ const out = {};
20668
+ for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
20669
+ return out;
20670
+ }
20671
+
20672
+ // src/_mppx_receipt.ts
20673
+ function extractMppxReceiptHeaderFromRaw(raw) {
20674
+ if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
20675
+ const fn = raw.withReceipt;
20676
+ if (typeof fn !== "function") return null;
20677
+ try {
20678
+ const wrapped = fn.call(raw, new Response());
20679
+ return wrapped.headers.get("Payment-Receipt");
20680
+ } catch {
20681
+ return null;
20682
+ }
20683
+ }
20684
+ async function extractMppxReceiptMethod(header) {
20685
+ try {
20686
+ const { Receipt } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
20687
+ return Receipt.deserialize(header).method;
20688
+ } catch {
20689
+ return void 0;
20690
+ }
20691
+ }
20692
+
20643
20693
  // src/_response.ts
20644
20694
  var WALLET_NOT_TRUSTED_INSTRUCTIONS = JSON.stringify({
20645
20695
  action: "contact_support",
@@ -20911,7 +20961,7 @@ function buildAgentInstructions({
20911
20961
  import {
20912
20962
  AgentScore,
20913
20963
  InvalidCredentialError,
20914
- PaymentRequiredError,
20964
+ PaymentRequiredError as PaymentRequiredError2,
20915
20965
  QuotaExceededError,
20916
20966
  TimeoutError as SdkTimeoutError,
20917
20967
  TokenExpiredError
@@ -21056,7 +21106,7 @@ function createAgentScoreCore(options) {
21056
21106
  } = options;
21057
21107
  const baseUrl = stripTrailingSlashes(rawBaseUrl);
21058
21108
  const agentMemoryHint = buildAgentMemoryHint();
21059
- const defaultUa = `@agent-score/commerce@${"2.0.1"}`;
21109
+ const defaultUa = `@agent-score/commerce@${"2.1.0"}`;
21060
21110
  const userAgentHeader = userAgent ? `${userAgent} (${defaultUa})` : defaultUa;
21061
21111
  const sdk = new AgentScore({ apiKey, baseUrl, userAgent: userAgentHeader });
21062
21112
  const sessionSdkCache = /* @__PURE__ */ new Map();
@@ -21200,7 +21250,7 @@ function createAgentScoreCore(options) {
21200
21250
  const result = identity.address ? await sdk.assess(identity.address, { ...opts, operatorToken: identity.operatorToken }) : await sdk.assess(null, { ...opts, operatorToken: identity.operatorToken });
21201
21251
  data = result;
21202
21252
  } catch (err) {
21203
- if (err instanceof PaymentRequiredError) {
21253
+ if (err instanceof PaymentRequiredError2) {
21204
21254
  if (failOpen) return { kind: "allow" };
21205
21255
  return { kind: "deny", reason: { code: "payment_required" } };
21206
21256
  }
@@ -21422,10 +21472,13 @@ function buildHowToPay({
21422
21472
  totalUsd,
21423
21473
  rails: rails2,
21424
21474
  opTokenPlaceholder,
21425
- maxSpend
21475
+ maxSpend,
21476
+ decimals
21426
21477
  }) {
21427
21478
  const totalNum = typeof totalUsd === "string" ? Number(totalUsd) : totalUsd;
21428
- const maxSpendStr = String(maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
21479
+ const d = decimals ?? 2;
21480
+ const defaultMaxSpend = totalNum >= 1 ? (Math.ceil(totalNum) + 1).toFixed(d) : totalNum.toFixed(d);
21481
+ const maxSpendStr = String(maxSpend ?? defaultMaxSpend);
21429
21482
  const opToken = opTokenPlaceholder ?? "<your_opc_token>";
21430
21483
  const block = {};
21431
21484
  if (rails2.tempo) {
@@ -21518,26 +21571,26 @@ function buildPricingBlock({
21518
21571
  totalCents,
21519
21572
  taxRate,
21520
21573
  taxState,
21521
- currency
21574
+ currency,
21575
+ decimals
21522
21576
  }) {
21523
21577
  const shipping = shippingCents ?? 0;
21524
21578
  const discount = discountCents ?? 0;
21525
21579
  const total = totalCents ?? Math.max(0, subtotalCents + taxCents + shipping - discount);
21580
+ const d = decimals ?? 2;
21581
+ const fmt = (cents) => (cents / 100).toFixed(d);
21526
21582
  const block = {
21527
- subtotal: formatCents(subtotalCents),
21528
- tax: formatCents(taxCents),
21529
- total: formatCents(total)
21583
+ subtotal: fmt(subtotalCents),
21584
+ tax: fmt(taxCents),
21585
+ total: fmt(total)
21530
21586
  };
21531
- if (shippingCents !== void 0) block.shipping = formatCents(shipping);
21532
- if (discountCents !== void 0) block.discount = formatCents(discount);
21587
+ if (shippingCents !== void 0) block.shipping = fmt(shipping);
21588
+ if (discountCents !== void 0) block.discount = fmt(discount);
21533
21589
  if (taxRate !== void 0) block.tax_rate = taxRate;
21534
21590
  if (taxState !== void 0) block.tax_state = taxState;
21535
21591
  if (currency !== void 0) block.currency = currency;
21536
21592
  return block;
21537
21593
  }
21538
- function formatCents(cents) {
21539
- return (cents / 100).toFixed(2);
21540
- }
21541
21594
 
21542
21595
  // src/challenge/respond_402.ts
21543
21596
  init_wwwauthenticate();
@@ -21546,10 +21599,7 @@ function respond402({
21546
21599
  body,
21547
21600
  x402
21548
21601
  }) {
21549
- const headers = {};
21550
- for (const [k, v] of Object.entries(mppxChallengeHeaders)) {
21551
- headers[k.toLowerCase()] = v;
21552
- }
21602
+ const headers = normalizeHeadersToLowercase(mppxChallengeHeaders);
21553
21603
  headers["content-type"] = "application/json";
21554
21604
  if (x402) {
21555
21605
  headers["payment-required"] = paymentRequiredHeader(x402);
@@ -21612,7 +21662,8 @@ function isSolanaMppRailSpec(s) {
21612
21662
  return s.network?.startsWith("solana:") ?? false;
21613
21663
  }
21614
21664
  function solanaNetworkFromCAIP2(caip2) {
21615
- if (caip2 === networks.solana.devnet.caip2) return "devnet";
21665
+ if (caip2 === "devnet" || caip2 === networks.solana.devnet.caip2) return "devnet";
21666
+ if (caip2 === "localnet") return "localnet";
21616
21667
  return "mainnet-beta";
21617
21668
  }
21618
21669
  function solanaDefaultRpcUrl(network) {
@@ -21896,6 +21947,35 @@ function lazyMppxServer(opts) {
21896
21947
  };
21897
21948
  }
21898
21949
 
21950
+ // src/checkout.ts
21951
+ init_network_kind();
21952
+
21953
+ // src/payment/payment_header.ts
21954
+ function toTitleCase(name) {
21955
+ return name.replace(/(^|-)([a-z])/g, (_m, sep, c) => sep + c.toUpperCase());
21956
+ }
21957
+ function readHeader(headers, name) {
21958
+ if (typeof headers.get === "function") {
21959
+ return headers.get(name);
21960
+ }
21961
+ const rec = headers;
21962
+ const v = rec[name] ?? rec[name.toLowerCase()] ?? rec[toTitleCase(name)];
21963
+ if (typeof v === "string") return v;
21964
+ if (Array.isArray(v) && typeof v[0] === "string") return v[0];
21965
+ return null;
21966
+ }
21967
+ function asHeaders(input) {
21968
+ return typeof input.headers === "object" && input instanceof Request ? input.headers : input;
21969
+ }
21970
+ function hasX402Header(input) {
21971
+ const headers = asHeaders(input);
21972
+ return Boolean(readHeader(headers, "payment-signature") || readHeader(headers, "x-payment"));
21973
+ }
21974
+ function hasMppxHeader(input) {
21975
+ const headers = asHeaders(input);
21976
+ return Boolean(readHeader(headers, "authorization")?.startsWith("Payment "));
21977
+ }
21978
+
21899
21979
  // src/payment/x402_settle.ts
21900
21980
  function classifyX402SettleResult(result) {
21901
21981
  if (result.success) return null;
@@ -22266,21 +22346,8 @@ var CheckoutValidationError = class extends Error {
22266
22346
  this.extra = opts.extra;
22267
22347
  }
22268
22348
  };
22269
- function lowerHeaders(headers) {
22270
- const out = {};
22271
- for (const [k, v] of Object.entries(headers)) out[k.toLowerCase()] = v;
22272
- return out;
22273
- }
22274
- function hasX402Header(headers) {
22275
- const h = lowerHeaders(headers);
22276
- return Boolean(h["payment-signature"] ?? h["x-payment"]);
22277
- }
22278
- function hasMppxHeader(headers) {
22279
- const h = lowerHeaders(headers);
22280
- return (h["authorization"] ?? "").startsWith("Payment ");
22281
- }
22282
22349
  function resolveIdentityMetadata(ctx) {
22283
- const h = lowerHeaders(ctx.request.headers);
22350
+ const h = normalizeHeadersToLowercase(ctx.request.headers);
22284
22351
  const wallet = h["x-wallet-address"];
22285
22352
  if (!wallet) return void 0;
22286
22353
  let linkedWallets;
@@ -22309,26 +22376,24 @@ function isTempoSessionRailSpec3(s) {
22309
22376
  function specRailKey(spec) {
22310
22377
  if (isStripeRailSpec2(spec)) return "stripe";
22311
22378
  if (isTempoSessionRailSpec3(spec)) return "tempo_mpp";
22312
- const network = spec.network ?? "";
22313
- if (network.startsWith("eip155:")) return "x402_base";
22314
- if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana_mpp";
22379
+ if (isEvmNetwork(spec)) return "x402_base";
22380
+ if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana_mpp";
22315
22381
  return "tempo_mpp";
22316
22382
  }
22317
22383
  function specMethodName(spec) {
22318
22384
  if (isStripeRailSpec2(spec)) return "stripe/spt";
22319
22385
  if (isTempoSessionRailSpec3(spec)) return "tempo/charge";
22320
- const network = spec.network ?? "";
22321
- if (network.startsWith("eip155:")) return "x402/exact (base)";
22322
- if (network.startsWith("solana:") || "rpcUrl" in spec) return "solana/charge";
22386
+ if (isEvmNetwork(spec)) return "x402/exact (base)";
22387
+ if (isSolanaNetwork(spec) || "rpcUrl" in spec) return "solana/charge";
22323
22388
  return "tempo/charge";
22324
22389
  }
22325
22390
  function makeMppxComposeHook(opts) {
22326
22391
  return async (ctx) => {
22327
22392
  if (ctx.pricing === null) return { status: 402 };
22328
22393
  const mpp = await opts.serverGetter();
22329
- const lower = lowerHeaders(ctx.request.headers);
22394
+ const lower = normalizeHeadersToLowercase(ctx.request.headers);
22330
22395
  const authorization = lower["authorization"];
22331
- const amountStr = ctx.pricing.amountUsd.toFixed(2);
22396
+ const amountStr = ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2);
22332
22397
  let result;
22333
22398
  try {
22334
22399
  result = await mpp.charge({ authorization, amount: amountStr });
@@ -22412,7 +22477,7 @@ var Checkout = class {
22412
22477
  let x402ServerGetter;
22413
22478
  if (x402Server === void 0) {
22414
22479
  const baseSpec = Object.values(opts.rails).find(
22415
- (s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && (s.network ?? "").startsWith("eip155:")
22480
+ (s) => !isTempoSessionRailSpec3(s) && !isStripeRailSpec2(s) && "recipient" in s && isEvmNetwork(s)
22416
22481
  );
22417
22482
  if (baseSpec !== void 0) {
22418
22483
  x402ServerGetter = lazyX402Server({
@@ -22502,7 +22567,7 @@ var Checkout = class {
22502
22567
  * `"x402_base"` when no match found. */
22503
22568
  x402RailKey() {
22504
22569
  for (const [k, v] of Object.entries(this.rails)) {
22505
- if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && (v.network ?? "").startsWith("eip155:")) {
22570
+ if (!isStripeRailSpec2(v) && !isTempoSessionRailSpec3(v) && isEvmNetwork(v)) {
22506
22571
  return k;
22507
22572
  }
22508
22573
  }
@@ -22511,18 +22576,47 @@ var Checkout = class {
22511
22576
  /** Return the rails-dict key for the primary MPP rail. */
22512
22577
  mppRailKey() {
22513
22578
  for (const [k, v] of Object.entries(this.rails)) {
22514
- const network = v.network ?? "";
22515
- if (!isStripeRailSpec2(v) && !network.startsWith("eip155:")) return k;
22579
+ if (!isStripeRailSpec2(v) && !isEvmNetwork(v)) return k;
22516
22580
  }
22517
22581
  return "tempo";
22518
22582
  }
22583
+ /** Map an mppx credential `method` (`tempo` | `solana` | `stripe`) to the
22584
+ * merchant's rails-dict key. Used in handleMppx so onSettled outcomes
22585
+ * distinguish Solana from Tempo (both settle under `rail: 'mpp'`) and from
22586
+ * Stripe SPT. Returns the first matching key or `undefined` when no rail in
22587
+ * the merchant's config corresponds to that method. */
22588
+ railsKeyForMppxMethod(method) {
22589
+ if (method === "stripe") {
22590
+ for (const [k, v] of Object.entries(this.rails)) {
22591
+ if (isStripeRailSpec2(v)) return k;
22592
+ }
22593
+ return void 0;
22594
+ }
22595
+ if (method === "solana") {
22596
+ for (const [k, v] of Object.entries(this.rails)) {
22597
+ if (isStripeRailSpec2(v) || isTempoSessionRailSpec3(v)) continue;
22598
+ if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) return k;
22599
+ }
22600
+ return void 0;
22601
+ }
22602
+ if (method === "tempo") {
22603
+ for (const [k, v] of Object.entries(this.rails)) {
22604
+ if (isStripeRailSpec2(v)) continue;
22605
+ if (isSolanaNetwork(v) || "rpcUrl" in v || "tokenProgram" in v) continue;
22606
+ if (isEvmNetwork(v)) continue;
22607
+ return k;
22608
+ }
22609
+ return void 0;
22610
+ }
22611
+ return void 0;
22612
+ }
22519
22613
  /** CAIP-2 read from `rails['x402_base'].network` (or its default).
22520
22614
  * Defined only when an `X402BaseRailSpec` is present in rails AND a server
22521
22615
  * is configured (explicit or auto-derived); otherwise `null`. */
22522
22616
  get x402BaseNetwork() {
22523
22617
  if (!this.x402ServerAvailable()) return null;
22524
22618
  for (const spec of Object.values(this.rails)) {
22525
- if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && (spec.network ?? "").startsWith("eip155:")) {
22619
+ if (!isStripeRailSpec2(spec) && !isTempoSessionRailSpec3(spec) && isEvmNetwork(spec)) {
22526
22620
  return spec.network ?? "eip155:8453";
22527
22621
  }
22528
22622
  }
@@ -22665,7 +22759,7 @@ var Checkout = class {
22665
22759
  ...policyOverride ?? {}
22666
22760
  };
22667
22761
  const core = createAgentScoreCore(coreOpts);
22668
- const headers = lowerHeaders(ctx.request.headers);
22762
+ const headers = normalizeHeadersToLowercase(ctx.request.headers);
22669
22763
  const walletAddress = headers["x-wallet-address"];
22670
22764
  const operatorToken = headers["x-operator-token"];
22671
22765
  const identity = walletAddress !== void 0 || operatorToken !== void 0 ? {
@@ -22727,7 +22821,7 @@ var Checkout = class {
22727
22821
  if (!this.zeroSettleCarveOut || ctx.pricing === null) return null;
22728
22822
  const cents = Math.round(ctx.pricing.amountUsd * 100);
22729
22823
  if (cents !== 0) return null;
22730
- const headers = lowerHeaders(ctx.request.headers);
22824
+ const headers = normalizeHeadersToLowercase(ctx.request.headers);
22731
22825
  let zero;
22732
22826
  if (rail === "x402-base") {
22733
22827
  const x402Header = headers["payment-signature"] ?? headers["x-payment"];
@@ -22801,7 +22895,7 @@ var Checkout = class {
22801
22895
  resourceConfig: {
22802
22896
  scheme: "exact",
22803
22897
  network: verified.signedNetwork,
22804
- price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
22898
+ price: `$${ctx.pricing.amountUsd.toFixed(ctx.pricing.decimals ?? 2)}`,
22805
22899
  payTo: verified.signedPayTo,
22806
22900
  maxTimeoutSeconds: 300
22807
22901
  },
@@ -22862,15 +22956,20 @@ var Checkout = class {
22862
22956
  }
22863
22957
  const composed = await this.composeMppx(ctx);
22864
22958
  if (composed.status === 200) {
22959
+ const paymentReceiptHeader = composed.paymentReceiptHeader ?? extractMppxReceiptHeaderFromRaw(composed.raw);
22960
+ const directMethod = composed.raw?.receipt?.method;
22961
+ const headerMethod = paymentReceiptHeader ? await extractMppxReceiptMethod(paymentReceiptHeader) : void 0;
22962
+ const receiptMethod = directMethod ?? headerMethod;
22963
+ const derivedKey = typeof receiptMethod === "string" ? this.railsKeyForMppxMethod(receiptMethod) : void 0;
22865
22964
  const outcome = {
22866
22965
  rail: "mpp",
22867
22966
  paymentResponseHeader: composed.paymentResponseHeader ?? null,
22868
- paymentReceiptHeader: composed.paymentReceiptHeader ?? extractMppxReceiptHeaderFromRaw(composed.raw),
22967
+ paymentReceiptHeader,
22869
22968
  raw: composed.raw,
22870
22969
  txHash: composed.txHash ?? null,
22871
22970
  signerAddress: composed.signerAddress ?? null,
22872
22971
  signerNetwork: composed.signerNetwork ?? null,
22873
- railKey: composed.railKey ?? this.mppRailKey()
22972
+ railKey: derivedKey ?? composed.railKey ?? this.mppRailKey()
22874
22973
  };
22875
22974
  return await this.buildSuccess(ctx, outcome);
22876
22975
  }
@@ -22905,15 +23004,18 @@ var Checkout = class {
22905
23004
  howToPayRails[k] = v;
22906
23005
  }
22907
23006
  }
23007
+ const pricingDecimals = ctx.pricing.decimals ?? 2;
22908
23008
  const howToPay = buildHowToPay({
22909
23009
  url: this.url,
22910
23010
  retryBodyJson: JSON.stringify(ctx.request.body),
22911
- totalUsd: ctx.pricing.amountUsd.toFixed(2),
22912
- rails: howToPayRails
23011
+ totalUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
23012
+ rails: howToPayRails,
23013
+ ...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
22913
23014
  });
22914
23015
  const pricingBlock = ctx.pricing.block ?? buildPricingBlock({
22915
- subtotalCents: Math.round(ctx.pricing.amountUsd * 100),
22916
- currency: ctx.pricing.currency ?? "USD"
23016
+ subtotalCents: ctx.pricing.amountUsd * 100,
23017
+ currency: ctx.pricing.currency ?? "USD",
23018
+ ...ctx.pricing.decimals !== void 0 && { decimals: ctx.pricing.decimals }
22917
23019
  });
22918
23020
  let x402Accepts = [];
22919
23021
  let x402Resource;
@@ -22926,7 +23028,7 @@ var Checkout = class {
22926
23028
  try {
22927
23029
  x402Accepts = await buildX402AcceptsFor402(x402Server, {
22928
23030
  network: baseNetwork,
22929
- price: `$${ctx.pricing.amountUsd.toFixed(2)}`,
23031
+ price: `$${ctx.pricing.amountUsd.toFixed(pricingDecimals)}`,
22930
23032
  payTo: recipient,
22931
23033
  maxTimeoutSeconds: 300
22932
23034
  });
@@ -22942,7 +23044,7 @@ var Checkout = class {
22942
23044
  agentInstructions: buildAgentInstructions({ howToPay }),
22943
23045
  ...identityMetadata !== void 0 ? { identityMetadata } : {},
22944
23046
  pricing: pricingBlock,
22945
- amountUsd: ctx.pricing.amountUsd.toFixed(2),
23047
+ amountUsd: ctx.pricing.amountUsd.toFixed(pricingDecimals),
22946
23048
  retryBody: ctx.request.body,
22947
23049
  agentMemory: firstEncounterAgentMemory({ firstEncounter: true }),
22948
23050
  ...ctx.pricing.product ? { product: ctx.pricing.product } : {},
@@ -23024,17 +23126,6 @@ function stripContentType(headers) {
23024
23126
  }
23025
23127
  return out;
23026
23128
  }
23027
- function extractMppxReceiptHeaderFromRaw(raw) {
23028
- if (!raw || typeof raw !== "object" || !("withReceipt" in raw)) return null;
23029
- const fn = raw.withReceipt;
23030
- if (typeof fn !== "function") return null;
23031
- try {
23032
- const wrapped = fn.call(raw, new Response());
23033
- return wrapped.headers.get("Payment-Receipt");
23034
- } catch {
23035
- return null;
23036
- }
23037
- }
23038
23129
  function headersToRecord(h) {
23039
23130
  if (h === void 0) return {};
23040
23131
  if (h instanceof Headers) {