@agent-score/commerce 1.8.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +73 -9
  2. package/dist/{_response-9yp6Fit2.d.mts → _response-BFYN3b6i.d.mts} +17 -19
  3. package/dist/{_response-CC6jNb8q.d.ts → _response-_iPD5AIj.d.ts} +17 -19
  4. package/dist/challenge/index.d.mts +106 -198
  5. package/dist/challenge/index.d.ts +106 -198
  6. package/dist/challenge/index.js +238 -111
  7. package/dist/challenge/index.js.map +1 -1
  8. package/dist/challenge/index.mjs +238 -111
  9. package/dist/challenge/index.mjs.map +1 -1
  10. package/dist/checkout-BoFwnVsj.d.ts +931 -0
  11. package/dist/checkout-DRbQ0Fsh.d.mts +931 -0
  12. package/dist/core.d.mts +2 -2
  13. package/dist/core.d.ts +2 -2
  14. package/dist/core.js +1 -1
  15. package/dist/core.js.map +1 -1
  16. package/dist/core.mjs +1 -1
  17. package/dist/core.mjs.map +1 -1
  18. package/dist/discovery/index.d.mts +453 -51
  19. package/dist/discovery/index.d.ts +453 -51
  20. package/dist/discovery/index.js +1092 -58
  21. package/dist/discovery/index.js.map +1 -1
  22. package/dist/discovery/index.mjs +1060 -57
  23. package/dist/discovery/index.mjs.map +1 -1
  24. package/dist/identity/express.d.mts +3 -3
  25. package/dist/identity/express.d.ts +3 -3
  26. package/dist/identity/express.js +30 -19
  27. package/dist/identity/express.js.map +1 -1
  28. package/dist/identity/express.mjs +30 -19
  29. package/dist/identity/express.mjs.map +1 -1
  30. package/dist/identity/fastify.d.mts +4 -4
  31. package/dist/identity/fastify.d.ts +4 -4
  32. package/dist/identity/fastify.js +30 -19
  33. package/dist/identity/fastify.js.map +1 -1
  34. package/dist/identity/fastify.mjs +30 -19
  35. package/dist/identity/fastify.mjs.map +1 -1
  36. package/dist/identity/hono.d.mts +3 -3
  37. package/dist/identity/hono.d.ts +3 -3
  38. package/dist/identity/hono.js +30 -19
  39. package/dist/identity/hono.js.map +1 -1
  40. package/dist/identity/hono.mjs +30 -19
  41. package/dist/identity/hono.mjs.map +1 -1
  42. package/dist/identity/nextjs.d.mts +6 -7
  43. package/dist/identity/nextjs.d.ts +6 -7
  44. package/dist/identity/nextjs.js +30 -19
  45. package/dist/identity/nextjs.js.map +1 -1
  46. package/dist/identity/nextjs.mjs +30 -19
  47. package/dist/identity/nextjs.mjs.map +1 -1
  48. package/dist/identity/policy.d.mts +41 -4
  49. package/dist/identity/policy.d.ts +41 -4
  50. package/dist/identity/policy.js +3662 -18
  51. package/dist/identity/policy.js.map +1 -1
  52. package/dist/identity/policy.mjs +3648 -3
  53. package/dist/identity/policy.mjs.map +1 -1
  54. package/dist/identity/web.d.mts +3 -3
  55. package/dist/identity/web.d.ts +3 -3
  56. package/dist/identity/web.js +30 -19
  57. package/dist/identity/web.js.map +1 -1
  58. package/dist/identity/web.mjs +30 -19
  59. package/dist/identity/web.mjs.map +1 -1
  60. package/dist/index.d.mts +72 -329
  61. package/dist/index.d.ts +72 -329
  62. package/dist/index.js +3651 -373
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +3628 -361
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/payment/index.d.mts +256 -265
  67. package/dist/payment/index.d.ts +256 -265
  68. package/dist/payment/index.js +586 -149
  69. package/dist/payment/index.js.map +1 -1
  70. package/dist/payment/index.mjs +573 -148
  71. package/dist/payment/index.mjs.map +1 -1
  72. package/dist/{agent_instructions-DiMSGkdm.d.mts → pricing-CQ9DIFaw.d.ts} +109 -56
  73. package/dist/{agent_instructions-DiMSGkdm.d.ts → pricing-CxzwyiO6.d.mts} +109 -56
  74. package/dist/rail_spec-XP0wKgJV.d.mts +132 -0
  75. package/dist/rail_spec-XP0wKgJV.d.ts +132 -0
  76. package/dist/{signer-CFVQsWjL.d.mts → signer-3FAit11j.d.mts} +27 -1
  77. package/dist/{signer-CFVQsWjL.d.ts → signer-3FAit11j.d.ts} +27 -1
  78. package/dist/solana-Cds87OTu.d.mts +67 -0
  79. package/dist/solana-Cds87OTu.d.ts +67 -0
  80. package/dist/stripe-multichain/index.d.mts +55 -66
  81. package/dist/stripe-multichain/index.d.ts +55 -66
  82. package/dist/stripe-multichain/index.js +68 -42
  83. package/dist/stripe-multichain/index.js.map +1 -1
  84. package/dist/stripe-multichain/index.mjs +68 -41
  85. package/dist/stripe-multichain/index.mjs.map +1 -1
  86. package/dist/{wwwauthenticate-CU1eNvMQ.d.mts → wwwauthenticate-D_FMnPgU.d.mts} +9 -10
  87. package/dist/{wwwauthenticate-CU1eNvMQ.d.ts → wwwauthenticate-D_FMnPgU.d.ts} +9 -10
  88. package/dist/x402_server-hgQzWQwB.d.mts +81 -0
  89. package/dist/x402_server-hgQzWQwB.d.ts +81 -0
  90. package/package.json +9 -7
@@ -1,60 +1,124 @@
1
+ // src/payment/usdc.ts
2
+ var USDC = {
3
+ base: {
4
+ mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
5
+ sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
6
+ },
7
+ solana: {
8
+ mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
9
+ devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
10
+ },
11
+ tempo: {
12
+ mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
13
+ testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
14
+ }
15
+ };
16
+
17
+ // src/payment/rail_spec.ts
18
+ async function resolveRecipient(r) {
19
+ if (typeof r === "string") return r;
20
+ return Promise.resolve(r());
21
+ }
22
+ var RAIL_SPEC_DEFAULTS = {
23
+ tempo: {
24
+ network: "tempo-mainnet",
25
+ chainId: 4217,
26
+ token: USDC.tempo.mainnet.address,
27
+ symbol: "USDC.e",
28
+ decimals: 6,
29
+ testnet: false,
30
+ recommend: "both"
31
+ },
32
+ x402Base: {
33
+ network: "eip155:8453",
34
+ chainId: 8453,
35
+ token: USDC.base.mainnet.address,
36
+ symbol: "USDC",
37
+ decimals: 6,
38
+ mode: "exact"
39
+ },
40
+ solanaMpp: {
41
+ network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
42
+ token: USDC.solana.mainnet.mint,
43
+ symbol: "USDC",
44
+ decimals: 6
45
+ },
46
+ stripe: {
47
+ rails: ["card", "link", "shared_payment_token"]
48
+ },
49
+ tempoSession: {
50
+ currency: USDC.tempo.mainnet.address,
51
+ testnet: false
52
+ }
53
+ };
54
+
1
55
  // src/challenge/accepted_methods.ts
2
- function buildAcceptedMethods(input) {
56
+ async function buildAcceptedMethods({
57
+ tempo,
58
+ x402_base,
59
+ solana_mpp,
60
+ stripe
61
+ }) {
3
62
  const out = [];
4
- if (input.tempo) {
63
+ if (tempo) {
5
64
  out.push({
6
65
  method: "tempo/charge",
7
- network: input.tempo.network ?? "tempo-mainnet",
8
- chain_id: input.tempo.chainId ?? 4217,
9
- token: input.tempo.token ?? "0x20C000000000000000000000b9537d11c60E8b50",
10
- symbol: input.tempo.symbol ?? "USDC.e",
11
- decimals: input.tempo.decimals ?? 6,
12
- pay_to: input.tempo.recipient
66
+ network: tempo.network ?? RAIL_SPEC_DEFAULTS.tempo.network,
67
+ chain_id: tempo.chainId ?? RAIL_SPEC_DEFAULTS.tempo.chainId,
68
+ token: tempo.token ?? RAIL_SPEC_DEFAULTS.tempo.token,
69
+ symbol: tempo.symbol ?? RAIL_SPEC_DEFAULTS.tempo.symbol,
70
+ decimals: tempo.decimals ?? RAIL_SPEC_DEFAULTS.tempo.decimals,
71
+ pay_to: await resolveRecipient(tempo.recipient)
13
72
  });
14
73
  }
15
- if (input.x402_base) {
74
+ if (x402_base) {
16
75
  out.push({
17
76
  method: "x402/exact",
18
- network: input.x402_base.network ?? "eip155:8453",
19
- chain_id: input.x402_base.chainId ?? 8453,
20
- token: input.x402_base.token ?? "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
21
- symbol: input.x402_base.symbol ?? "USDC",
22
- decimals: input.x402_base.decimals ?? 6,
23
- pay_to: input.x402_base.recipient
77
+ network: x402_base.network ?? RAIL_SPEC_DEFAULTS.x402Base.network,
78
+ chain_id: x402_base.chainId ?? RAIL_SPEC_DEFAULTS.x402Base.chainId,
79
+ token: x402_base.token ?? RAIL_SPEC_DEFAULTS.x402Base.token,
80
+ symbol: x402_base.symbol ?? RAIL_SPEC_DEFAULTS.x402Base.symbol,
81
+ decimals: x402_base.decimals ?? RAIL_SPEC_DEFAULTS.x402Base.decimals,
82
+ pay_to: await resolveRecipient(x402_base.recipient)
24
83
  });
25
84
  }
26
- if (input.solana_mpp) {
85
+ if (solana_mpp) {
27
86
  out.push({
28
87
  method: "solana/charge",
29
- network: input.solana_mpp.network ?? "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
30
- token: input.solana_mpp.token ?? "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
31
- symbol: input.solana_mpp.symbol ?? "USDC",
32
- decimals: input.solana_mpp.decimals ?? 6,
33
- pay_to: input.solana_mpp.recipient,
34
- ...input.solana_mpp.feePayerKey ? { fee_payer_key: input.solana_mpp.feePayerKey } : {}
88
+ network: solana_mpp.network ?? RAIL_SPEC_DEFAULTS.solanaMpp.network,
89
+ token: solana_mpp.token ?? RAIL_SPEC_DEFAULTS.solanaMpp.token,
90
+ symbol: solana_mpp.symbol ?? RAIL_SPEC_DEFAULTS.solanaMpp.symbol,
91
+ decimals: solana_mpp.decimals ?? RAIL_SPEC_DEFAULTS.solanaMpp.decimals,
92
+ pay_to: await resolveRecipient(solana_mpp.recipient)
35
93
  });
36
94
  }
37
- if (input.stripe) {
95
+ if (stripe) {
38
96
  out.push({
39
97
  method: "stripe/charge",
40
- rails: input.stripe.rails ?? ["card", "link", "shared_payment_token"],
41
- profile_id: input.stripe.profileId ?? null
98
+ rails: stripe.rails ?? [...RAIL_SPEC_DEFAULTS.stripe.rails],
99
+ profile_id: stripe.profileId ?? null
42
100
  });
43
101
  }
44
102
  return out;
45
103
  }
46
104
 
47
105
  // src/challenge/identity.ts
48
- function buildIdentityMetadata(input) {
49
- const block = { identity_mode: input.mode };
50
- if (input.mode !== "wallet") return block;
51
- if (input.wallet) {
52
- block.required_signer = input.signerMatchResult?.expectedSigner ?? input.wallet;
106
+ function buildIdentityMetadata({
107
+ mode,
108
+ wallet,
109
+ signerMatchResult,
110
+ linkedWallets,
111
+ signerConstraint
112
+ }) {
113
+ const block = { identity_mode: mode };
114
+ if (mode !== "wallet") return block;
115
+ if (wallet) {
116
+ block.required_signer = signerMatchResult?.expectedSigner ?? wallet;
53
117
  }
54
- if (input.linkedWallets && input.linkedWallets.length > 0) {
55
- block.linked_wallets = input.linkedWallets;
118
+ if (linkedWallets && linkedWallets.length > 0) {
119
+ block.linked_wallets = linkedWallets;
56
120
  }
57
- block.signer_constraint = input.signerConstraint ?? "Payment must be signed with the claimed wallet OR any same-operator linked wallet listed in linked_wallets.";
121
+ block.signer_constraint = signerConstraint ?? "Payment must be signed with the claimed wallet OR any same-operator linked wallet listed in linked_wallets.";
58
122
  return block;
59
123
  }
60
124
 
@@ -75,45 +139,52 @@ var PAY_SETUP_SOLANA = [
75
139
  "agentscore-pay wallet create --chain solana",
76
140
  "agentscore-pay balance --chain solana # fund the printed address with USDC on Solana"
77
141
  ];
78
- function buildHowToPay(input) {
79
- const totalNum = typeof input.totalUsd === "string" ? Number(input.totalUsd) : input.totalUsd;
80
- const maxSpend = String(input.maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
81
- const opToken = input.opTokenPlaceholder ?? "<your_opc_token>";
142
+ function buildHowToPay({
143
+ url,
144
+ retryBodyJson,
145
+ totalUsd,
146
+ rails,
147
+ opTokenPlaceholder,
148
+ maxSpend
149
+ }) {
150
+ const totalNum = typeof totalUsd === "string" ? Number(totalUsd) : totalUsd;
151
+ const maxSpendStr = String(maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
152
+ const opToken = opTokenPlaceholder ?? "<your_opc_token>";
82
153
  const block = {};
83
- if (input.rails.tempo) {
84
- const networkName = input.rails.tempo.networkName ?? "tempo-mainnet";
85
- const chainId = input.rails.tempo.chainId ?? 4217;
86
- const recommend = input.rails.tempo.recommend ?? "both";
87
- const tempoCommand = `tempo request -X POST -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' --json '${input.retryBodyJson}' --max-spend ${maxSpend} ${input.url}`;
88
- const payCommand = `agentscore-pay pay POST ${input.url} --chain tempo -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${input.retryBodyJson}' --max-spend ${maxSpend}`;
154
+ if (rails.tempo) {
155
+ const networkName = rails.tempo.testnet ? "tempo-testnet" : rails.tempo.network ?? RAIL_SPEC_DEFAULTS.tempo.network;
156
+ const chainId = rails.tempo.chainId ?? RAIL_SPEC_DEFAULTS.tempo.chainId;
157
+ const recommend = rails.tempo.recommend ?? RAIL_SPEC_DEFAULTS.tempo.recommend;
158
+ const tempoCommand = `tempo request -X POST -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' --json '${retryBodyJson}' --max-spend ${maxSpendStr} ${url}`;
159
+ const payCommand = `agentscore-pay pay POST ${url} --chain tempo -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${retryBodyJson}' --max-spend ${maxSpendStr}`;
89
160
  block.tempo = {
90
161
  setup: TEMPO_SETUP,
91
- prerequisite: `Run \`tempo wallet whoami\` and confirm USDC.e balance on ${networkName} (chain ${chainId}) is at least $${maxSpend}. If the tempo CLI is not installed, run the setup commands above first.`,
162
+ prerequisite: `Run \`tempo wallet whoami\` and confirm USDC.e balance on ${networkName} (chain ${chainId}) is at least $${maxSpendStr}. If the tempo CLI is not installed, run the setup commands above first.`,
92
163
  command: recommend === "agentscore-pay" ? payCommand : tempoCommand,
93
164
  ...recommend === "both" ? { alternative_command: payCommand } : recommend === "agentscore-pay" ? { alternative_command: tempoCommand } : {},
94
165
  what_it_does: `Pays via Tempo USDC on ${networkName}.`
95
166
  };
96
167
  }
97
- if (input.rails.x402_base) {
98
- const network = input.rails.x402_base.network ?? "eip155:8453";
168
+ if (rails.x402_base) {
169
+ const network = rails.x402_base.network ?? RAIL_SPEC_DEFAULTS.x402Base.network;
99
170
  block.x402_base = {
100
171
  setup: PAY_SETUP_BASE,
101
- prerequisite: `Run \`agentscore-pay balance --chain base\` and confirm USDC balance on Base (${network}) is at least $${maxSpend}. If the CLI is not installed, run the setup commands above first.`,
102
- command: `agentscore-pay pay POST ${input.url} --chain base -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${input.retryBodyJson}' --max-spend ${maxSpend}`,
172
+ prerequisite: `Run \`agentscore-pay balance --chain base\` and confirm USDC balance on Base (${network}) is at least $${maxSpendStr}. If the CLI is not installed, run the setup commands above first.`,
173
+ command: `agentscore-pay pay POST ${url} --chain base -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${retryBodyJson}' --max-spend ${maxSpendStr}`,
103
174
  what_it_does: "Pays via USDC on Base."
104
175
  };
105
176
  }
106
- if (input.rails.solana_mpp) {
107
- const network = input.rails.solana_mpp.network ?? "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
177
+ if (rails.solana_mpp) {
178
+ const network = rails.solana_mpp.network ?? RAIL_SPEC_DEFAULTS.solanaMpp.network;
108
179
  block.solana_mpp = {
109
180
  setup: PAY_SETUP_SOLANA,
110
- prerequisite: `Run \`agentscore-pay balance --chain solana\` and confirm USDC balance on Solana (${network}) is at least $${maxSpend}. If the CLI is not installed, run the setup commands above first.`,
111
- command: `agentscore-pay pay POST ${input.url} --chain solana -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${input.retryBodyJson}' --max-spend ${maxSpend}`,
181
+ prerequisite: `Run \`agentscore-pay balance --chain solana\` and confirm USDC balance on Solana (${network}) is at least $${maxSpendStr}. If the CLI is not installed, run the setup commands above first.`,
182
+ command: `agentscore-pay pay POST ${url} --chain solana -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${retryBodyJson}' --max-spend ${maxSpendStr}`,
112
183
  what_it_does: "Pays via USDC on Solana."
113
184
  };
114
185
  }
115
- if (input.rails.stripe) {
116
- const stripeCfg = input.rails.stripe;
186
+ if (rails.stripe) {
187
+ const stripeCfg = rails.stripe;
117
188
  const amountCents = Math.round(totalNum * 100);
118
189
  const linkCliBlocked = amountCents > 5e4;
119
190
  const productName = stripeCfg.productName ?? "this purchase";
@@ -130,7 +201,7 @@ function buildHowToPay(input) {
130
201
  ];
131
202
  stripe.command_link_cli = [
132
203
  `SPEND_ID=$(link-cli spend-request create --payment-method-id <csmrpd_id_from_payment_methods_list> --credential-type shared_payment_token --network-id ${stripeCfg.profileId} --amount ${amountCents} --context "${sptContext}" --request-approval --output-json | jq -r .id)`,
133
- `link-cli mpp pay ${input.url} --spend-request-id $SPEND_ID --method POST --data '${input.retryBodyJson}' --header 'X-Operator-Token: ${opToken}' --output-json`
204
+ `link-cli mpp pay ${url} --spend-request-id $SPEND_ID --method POST --data '${retryBodyJson}' --header 'X-Operator-Token: ${opToken}' --output-json`
134
205
  ];
135
206
  stripe.what_it_does_link_cli = "Mints a one-time-use SharedPaymentToken scoped to this purchase (user approves in Link wallet), then submits it as the payment credential.";
136
207
  } else if (linkCliBlocked) {
@@ -142,8 +213,8 @@ function buildHowToPay(input) {
142
213
  }
143
214
 
144
215
  // src/challenge/agent_instructions.ts
145
- var TEMPO_WARNING = "Do NOT use `tempo wallet transfer`. That moves USDC on-chain without completing the protocol handshake, so the order will not complete. Use `tempo request` instead.";
146
- var X402_WARNING = "Do NOT send USDC manually to the deposit addresses. Use `agentscore-pay pay` so the credential is signed and submitted; otherwise the order will not complete even though the deposit lands.";
216
+ var TEMPO_WARNING = "Do NOT use `tempo wallet transfer`. That moves USDC on-chain without completing the protocol handshake, so the request will not complete. Use `tempo request` instead.";
217
+ var X402_WARNING = "Do NOT send USDC manually to the deposit addresses. Use `agentscore-pay pay` so the credential is signed and submitted; otherwise the request will not complete even though the deposit lands.";
147
218
  var TEMPO_TOOL = "`tempo request` for Tempo USDC";
148
219
  var AGENTSCORE_PAY_TOOL = "`agentscore-pay` \u2014 Base + Solana + Tempo from one CLI";
149
220
  var DEFAULT_WALLET_COMPATIBILITY = "Any client that can produce a valid MPP credential (Authorization: Payment) or x402 X-Payment header. Use the CLI commands above; sign-it-yourself is also fine.";
@@ -178,17 +249,27 @@ function defaultCompatibleClients(howToPay) {
178
249
  if (howToPay.stripe) rails.push("stripe");
179
250
  return compatibleClientsByRails(rails);
180
251
  }
181
- function buildAgentInstructions(input) {
182
- const compatibleClients = input.compatibleClients ?? defaultCompatibleClients(input.howToPay);
252
+ function buildAgentInstructions({
253
+ howToPay,
254
+ recommendedTools,
255
+ walletCompatibility,
256
+ timeoutSeconds,
257
+ warnings,
258
+ extraWarnings,
259
+ recommended,
260
+ compatibleClients,
261
+ extra
262
+ }) {
263
+ const compatibleClientsOut = compatibleClients ?? defaultCompatibleClients(howToPay);
183
264
  return {
184
- how_to_pay: input.howToPay,
185
- recommended_tools: input.recommendedTools ?? defaultRecommendedTools(input.howToPay),
186
- wallet_compatibility: input.walletCompatibility ?? DEFAULT_WALLET_COMPATIBILITY,
187
- timeout_seconds: input.timeoutSeconds ?? 300,
188
- warnings: input.warnings ?? [...defaultWarnings(input.howToPay), ...input.extraWarnings ?? []],
189
- ...input.recommended ? { recommended: input.recommended } : {},
190
- ...compatibleClients ? { compatible_clients: compatibleClients } : {},
191
- ...input.extra ?? {}
265
+ how_to_pay: howToPay,
266
+ recommended_tools: recommendedTools ?? defaultRecommendedTools(howToPay),
267
+ wallet_compatibility: walletCompatibility ?? DEFAULT_WALLET_COMPATIBILITY,
268
+ timeout_seconds: timeoutSeconds ?? 300,
269
+ warnings: warnings ?? [...defaultWarnings(howToPay), ...extraWarnings ?? []],
270
+ ...recommended ? { recommended } : {},
271
+ ...compatibleClientsOut ? { compatible_clients: compatibleClientsOut } : {},
272
+ ...extra ?? {}
192
273
  };
193
274
  }
194
275
 
@@ -302,51 +383,80 @@ function buildAgentMemoryHint() {
302
383
  }
303
384
 
304
385
  // src/challenge/agent_memory.ts
305
- function firstEncounterAgentMemory(input) {
306
- if (!input.firstEncounter) return void 0;
386
+ function firstEncounterAgentMemory({
387
+ firstEncounter
388
+ }) {
389
+ if (!firstEncounter) return void 0;
307
390
  return buildAgentMemoryHint();
308
391
  }
309
392
 
310
393
  // src/challenge/body.ts
311
- function build402Body(input) {
394
+ function build402Body({
395
+ acceptedMethods,
396
+ agentInstructions,
397
+ identityMetadata,
398
+ agentMemory,
399
+ pricing,
400
+ amountUsd,
401
+ currency,
402
+ orderId,
403
+ product,
404
+ retryBody,
405
+ recommended,
406
+ x402,
407
+ extra
408
+ }) {
312
409
  const body = {
313
410
  payment_required: true,
314
- accepted_methods: input.acceptedMethods
411
+ accepted_methods: acceptedMethods
315
412
  };
316
- if (input.x402) {
317
- body.x402Version = input.x402.version ?? 2;
318
- body.accepts = input.x402.accepts;
413
+ if (x402) {
414
+ body.x402Version = x402.version ?? 2;
415
+ body.accepts = x402.accepts;
416
+ if (x402.extensions !== void 0 && Object.keys(x402.extensions).length > 0) {
417
+ body.extensions = x402.extensions;
418
+ }
319
419
  }
320
- if (input.amountUsd !== void 0) body.amount_usd = input.amountUsd;
321
- if (input.currency) body.currency = input.currency;
322
- if (input.pricing) body.pricing = input.pricing;
323
- if (input.orderId !== void 0) body.order_id = input.orderId;
324
- if (input.product) body.product = input.product;
325
- if (input.recommended) body.recommended = input.recommended;
326
- if (input.retryBody !== void 0) body.retry_body = input.retryBody;
327
- if (input.identityMetadata) {
328
- Object.assign(body, input.identityMetadata);
420
+ if (amountUsd !== void 0) body.amount_usd = amountUsd;
421
+ if (currency) body.currency = currency;
422
+ if (pricing) body.pricing = pricing;
423
+ if (orderId !== void 0) body.order_id = orderId;
424
+ if (product) body.product = product;
425
+ if (recommended) body.recommended = recommended;
426
+ if (retryBody !== void 0) body.retry_body = retryBody;
427
+ if (identityMetadata) {
428
+ Object.assign(body, identityMetadata);
329
429
  }
330
- if (input.agentInstructions) body.agent_instructions = input.agentInstructions;
331
- if (input.agentMemory !== void 0) body.agent_memory = input.agentMemory;
332
- if (input.extra) Object.assign(body, input.extra);
430
+ if (agentInstructions) body.agent_instructions = agentInstructions;
431
+ if (agentMemory !== void 0) body.agent_memory = agentMemory;
432
+ if (extra) Object.assign(body, extra);
333
433
  return body;
334
434
  }
335
435
 
336
436
  // src/challenge/pricing.ts
337
- function buildPricingBlock(input) {
338
- const tax = input.taxCents ?? 0;
339
- const shipping = input.shippingCents ?? 0;
340
- const total = input.totalCents ?? input.subtotalCents + tax + shipping;
437
+ function buildPricingBlock({
438
+ subtotalCents,
439
+ taxCents = 0,
440
+ shippingCents,
441
+ discountCents,
442
+ totalCents,
443
+ taxRate,
444
+ taxState,
445
+ currency
446
+ }) {
447
+ const shipping = shippingCents ?? 0;
448
+ const discount = discountCents ?? 0;
449
+ const total = totalCents ?? Math.max(0, subtotalCents + taxCents + shipping - discount);
341
450
  const block = {
342
- subtotal: formatCents(input.subtotalCents),
343
- tax: formatCents(tax),
451
+ subtotal: formatCents(subtotalCents),
452
+ tax: formatCents(taxCents),
344
453
  total: formatCents(total)
345
454
  };
346
- if (input.shippingCents !== void 0) block.shipping = formatCents(shipping);
347
- if (input.taxRate !== void 0) block.tax_rate = input.taxRate;
348
- if (input.taxState !== void 0) block.tax_state = input.taxState;
349
- if (input.currency !== void 0) block.currency = input.currency;
455
+ if (shippingCents !== void 0) block.shipping = formatCents(shipping);
456
+ if (discountCents !== void 0) block.discount = formatCents(discount);
457
+ if (taxRate !== void 0) block.tax_rate = taxRate;
458
+ if (taxState !== void 0) block.tax_state = taxState;
459
+ if (currency !== void 0) block.currency = currency;
350
460
  return block;
351
461
  }
352
462
  function formatCents(cents) {
@@ -354,30 +464,47 @@ function formatCents(cents) {
354
464
  }
355
465
 
356
466
  // src/payment/wwwauthenticate.ts
357
- function paymentRequiredHeader(input) {
358
- return Buffer.from(JSON.stringify(input)).toString("base64");
467
+ function paymentRequiredHeader({
468
+ x402Version,
469
+ accepts,
470
+ resource
471
+ }) {
472
+ return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
359
473
  }
360
474
 
361
475
  // src/challenge/respond_402.ts
362
- function respond402(input) {
363
- const body = build402Body(input.body);
364
- const headers = new Headers(input.mppxChallenge.headers);
365
- headers.set("content-type", "application/json");
366
- if (input.x402) {
367
- headers.set("PAYMENT-REQUIRED", paymentRequiredHeader(input.x402));
476
+ function respond402({
477
+ mppxChallengeHeaders,
478
+ body,
479
+ x402
480
+ }) {
481
+ const headers = {};
482
+ for (const [k, v] of Object.entries(mppxChallengeHeaders)) {
483
+ headers[k.toLowerCase()] = v;
484
+ }
485
+ headers["content-type"] = "application/json";
486
+ if (x402) {
487
+ headers["payment-required"] = paymentRequiredHeader(x402);
368
488
  }
369
- return new Response(JSON.stringify(body), { headers, status: 402 });
489
+ return { body, headers, status: 402 };
370
490
  }
371
491
 
372
492
  // src/challenge/validation_error.ts
373
- function buildValidationError(input) {
493
+ function buildValidationError({
494
+ code,
495
+ message,
496
+ requiredFields,
497
+ exampleBody,
498
+ nextSteps,
499
+ extra
500
+ }) {
374
501
  const body = {
375
- error: { code: input.code, message: input.message }
502
+ error: { code, message }
376
503
  };
377
- if (input.requiredFields) body.required_fields = input.requiredFields;
378
- if (input.exampleBody !== void 0) body.example_body = input.exampleBody;
379
- if (input.nextSteps) body.next_steps = input.nextSteps;
380
- if (input.extra) Object.assign(body, input.extra);
504
+ if (requiredFields) body.required_fields = requiredFields;
505
+ if (exampleBody !== void 0) body.example_body = exampleBody;
506
+ if (nextSteps) body.next_steps = nextSteps;
507
+ if (extra) Object.assign(body, extra);
381
508
  return body;
382
509
  }
383
510
  export {