@agent-score/commerce 1.8.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +73 -9
  2. package/dist/{_response-9yp6Fit2.d.mts → _response-BFYN3b6i.d.mts} +17 -19
  3. package/dist/{_response-CC6jNb8q.d.ts → _response-_iPD5AIj.d.ts} +17 -19
  4. package/dist/challenge/index.d.mts +106 -198
  5. package/dist/challenge/index.d.ts +106 -198
  6. package/dist/challenge/index.js +238 -111
  7. package/dist/challenge/index.js.map +1 -1
  8. package/dist/challenge/index.mjs +238 -111
  9. package/dist/challenge/index.mjs.map +1 -1
  10. package/dist/checkout-B1JuEcbx.d.ts +939 -0
  11. package/dist/checkout-BN5i1Fi7.d.mts +939 -0
  12. package/dist/core.d.mts +2 -2
  13. package/dist/core.d.ts +2 -2
  14. package/dist/core.js +1 -1
  15. package/dist/core.js.map +1 -1
  16. package/dist/core.mjs +1 -1
  17. package/dist/core.mjs.map +1 -1
  18. package/dist/discovery/index.d.mts +453 -51
  19. package/dist/discovery/index.d.ts +453 -51
  20. package/dist/discovery/index.js +1092 -58
  21. package/dist/discovery/index.js.map +1 -1
  22. package/dist/discovery/index.mjs +1060 -57
  23. package/dist/discovery/index.mjs.map +1 -1
  24. package/dist/identity/express.d.mts +3 -3
  25. package/dist/identity/express.d.ts +3 -3
  26. package/dist/identity/express.js +30 -19
  27. package/dist/identity/express.js.map +1 -1
  28. package/dist/identity/express.mjs +30 -19
  29. package/dist/identity/express.mjs.map +1 -1
  30. package/dist/identity/fastify.d.mts +4 -4
  31. package/dist/identity/fastify.d.ts +4 -4
  32. package/dist/identity/fastify.js +30 -19
  33. package/dist/identity/fastify.js.map +1 -1
  34. package/dist/identity/fastify.mjs +30 -19
  35. package/dist/identity/fastify.mjs.map +1 -1
  36. package/dist/identity/hono.d.mts +3 -3
  37. package/dist/identity/hono.d.ts +3 -3
  38. package/dist/identity/hono.js +30 -19
  39. package/dist/identity/hono.js.map +1 -1
  40. package/dist/identity/hono.mjs +30 -19
  41. package/dist/identity/hono.mjs.map +1 -1
  42. package/dist/identity/nextjs.d.mts +6 -7
  43. package/dist/identity/nextjs.d.ts +6 -7
  44. package/dist/identity/nextjs.js +30 -19
  45. package/dist/identity/nextjs.js.map +1 -1
  46. package/dist/identity/nextjs.mjs +30 -19
  47. package/dist/identity/nextjs.mjs.map +1 -1
  48. package/dist/identity/policy.d.mts +41 -4
  49. package/dist/identity/policy.d.ts +41 -4
  50. package/dist/identity/policy.js +23307 -18
  51. package/dist/identity/policy.js.map +1 -1
  52. package/dist/identity/policy.mjs +23313 -3
  53. package/dist/identity/policy.mjs.map +1 -1
  54. package/dist/identity/web.d.mts +3 -3
  55. package/dist/identity/web.d.ts +3 -3
  56. package/dist/identity/web.js +30 -19
  57. package/dist/identity/web.js.map +1 -1
  58. package/dist/identity/web.mjs +30 -19
  59. package/dist/identity/web.mjs.map +1 -1
  60. package/dist/index.d.mts +72 -329
  61. package/dist/index.d.ts +72 -329
  62. package/dist/index.js +23301 -378
  63. package/dist/index.js.map +1 -1
  64. package/dist/index.mjs +23294 -362
  65. package/dist/index.mjs.map +1 -1
  66. package/dist/payment/index.d.mts +297 -265
  67. package/dist/payment/index.d.ts +297 -265
  68. package/dist/payment/index.js +605 -149
  69. package/dist/payment/index.js.map +1 -1
  70. package/dist/payment/index.mjs +590 -148
  71. package/dist/payment/index.mjs.map +1 -1
  72. package/dist/{agent_instructions-DiMSGkdm.d.mts → pricing-CQ9DIFaw.d.ts} +109 -56
  73. package/dist/{agent_instructions-DiMSGkdm.d.ts → pricing-CxzwyiO6.d.mts} +109 -56
  74. package/dist/rail_spec-XP0wKgJV.d.mts +132 -0
  75. package/dist/rail_spec-XP0wKgJV.d.ts +132 -0
  76. package/dist/{signer-CFVQsWjL.d.mts → signer-3FAit11j.d.mts} +27 -1
  77. package/dist/{signer-CFVQsWjL.d.ts → signer-3FAit11j.d.ts} +27 -1
  78. package/dist/solana-Cds87OTu.d.mts +67 -0
  79. package/dist/solana-Cds87OTu.d.ts +67 -0
  80. package/dist/stripe-multichain/index.d.mts +55 -66
  81. package/dist/stripe-multichain/index.d.ts +55 -66
  82. package/dist/stripe-multichain/index.js +68 -42
  83. package/dist/stripe-multichain/index.js.map +1 -1
  84. package/dist/stripe-multichain/index.mjs +68 -41
  85. package/dist/stripe-multichain/index.mjs.map +1 -1
  86. package/dist/{wwwauthenticate-CU1eNvMQ.d.mts → wwwauthenticate-D_FMnPgU.d.mts} +9 -10
  87. package/dist/{wwwauthenticate-CU1eNvMQ.d.ts → wwwauthenticate-D_FMnPgU.d.ts} +9 -10
  88. package/dist/x402_server-hgQzWQwB.d.mts +81 -0
  89. package/dist/x402_server-hgQzWQwB.d.ts +81 -0
  90. package/package.json +9 -7
@@ -34,63 +34,127 @@ __export(challenge_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(challenge_exports);
36
36
 
37
+ // src/payment/usdc.ts
38
+ var USDC = {
39
+ base: {
40
+ mainnet: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
41
+ sepolia: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
42
+ },
43
+ solana: {
44
+ mainnet: { mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", decimals: 6 },
45
+ devnet: { mint: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", decimals: 6 }
46
+ },
47
+ tempo: {
48
+ mainnet: { address: "0x20C000000000000000000000b9537d11c60E8b50", decimals: 6 },
49
+ testnet: { address: "0x20c0000000000000000000000000000000000000", decimals: 6 }
50
+ }
51
+ };
52
+
53
+ // src/payment/rail_spec.ts
54
+ async function resolveRecipient(r) {
55
+ if (typeof r === "string") return r;
56
+ return Promise.resolve(r());
57
+ }
58
+ var RAIL_SPEC_DEFAULTS = {
59
+ tempo: {
60
+ network: "tempo-mainnet",
61
+ chainId: 4217,
62
+ token: USDC.tempo.mainnet.address,
63
+ symbol: "USDC.e",
64
+ decimals: 6,
65
+ testnet: false,
66
+ recommend: "both"
67
+ },
68
+ x402Base: {
69
+ network: "eip155:8453",
70
+ chainId: 8453,
71
+ token: USDC.base.mainnet.address,
72
+ symbol: "USDC",
73
+ decimals: 6,
74
+ mode: "exact"
75
+ },
76
+ solanaMpp: {
77
+ network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
78
+ token: USDC.solana.mainnet.mint,
79
+ symbol: "USDC",
80
+ decimals: 6
81
+ },
82
+ stripe: {
83
+ rails: ["card", "link", "shared_payment_token"]
84
+ },
85
+ tempoSession: {
86
+ currency: USDC.tempo.mainnet.address,
87
+ testnet: false
88
+ }
89
+ };
90
+
37
91
  // src/challenge/accepted_methods.ts
38
- function buildAcceptedMethods(input) {
92
+ async function buildAcceptedMethods({
93
+ tempo,
94
+ x402_base,
95
+ solana_mpp,
96
+ stripe
97
+ }) {
39
98
  const out = [];
40
- if (input.tempo) {
99
+ if (tempo) {
41
100
  out.push({
42
101
  method: "tempo/charge",
43
- network: input.tempo.network ?? "tempo-mainnet",
44
- chain_id: input.tempo.chainId ?? 4217,
45
- token: input.tempo.token ?? "0x20C000000000000000000000b9537d11c60E8b50",
46
- symbol: input.tempo.symbol ?? "USDC.e",
47
- decimals: input.tempo.decimals ?? 6,
48
- pay_to: input.tempo.recipient
102
+ network: tempo.network ?? RAIL_SPEC_DEFAULTS.tempo.network,
103
+ chain_id: tempo.chainId ?? RAIL_SPEC_DEFAULTS.tempo.chainId,
104
+ token: tempo.token ?? RAIL_SPEC_DEFAULTS.tempo.token,
105
+ symbol: tempo.symbol ?? RAIL_SPEC_DEFAULTS.tempo.symbol,
106
+ decimals: tempo.decimals ?? RAIL_SPEC_DEFAULTS.tempo.decimals,
107
+ pay_to: await resolveRecipient(tempo.recipient)
49
108
  });
50
109
  }
51
- if (input.x402_base) {
110
+ if (x402_base) {
52
111
  out.push({
53
112
  method: "x402/exact",
54
- network: input.x402_base.network ?? "eip155:8453",
55
- chain_id: input.x402_base.chainId ?? 8453,
56
- token: input.x402_base.token ?? "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
57
- symbol: input.x402_base.symbol ?? "USDC",
58
- decimals: input.x402_base.decimals ?? 6,
59
- pay_to: input.x402_base.recipient
113
+ network: x402_base.network ?? RAIL_SPEC_DEFAULTS.x402Base.network,
114
+ chain_id: x402_base.chainId ?? RAIL_SPEC_DEFAULTS.x402Base.chainId,
115
+ token: x402_base.token ?? RAIL_SPEC_DEFAULTS.x402Base.token,
116
+ symbol: x402_base.symbol ?? RAIL_SPEC_DEFAULTS.x402Base.symbol,
117
+ decimals: x402_base.decimals ?? RAIL_SPEC_DEFAULTS.x402Base.decimals,
118
+ pay_to: await resolveRecipient(x402_base.recipient)
60
119
  });
61
120
  }
62
- if (input.solana_mpp) {
121
+ if (solana_mpp) {
63
122
  out.push({
64
123
  method: "solana/charge",
65
- network: input.solana_mpp.network ?? "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
66
- token: input.solana_mpp.token ?? "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
67
- symbol: input.solana_mpp.symbol ?? "USDC",
68
- decimals: input.solana_mpp.decimals ?? 6,
69
- pay_to: input.solana_mpp.recipient,
70
- ...input.solana_mpp.feePayerKey ? { fee_payer_key: input.solana_mpp.feePayerKey } : {}
124
+ network: solana_mpp.network ?? RAIL_SPEC_DEFAULTS.solanaMpp.network,
125
+ token: solana_mpp.token ?? RAIL_SPEC_DEFAULTS.solanaMpp.token,
126
+ symbol: solana_mpp.symbol ?? RAIL_SPEC_DEFAULTS.solanaMpp.symbol,
127
+ decimals: solana_mpp.decimals ?? RAIL_SPEC_DEFAULTS.solanaMpp.decimals,
128
+ pay_to: await resolveRecipient(solana_mpp.recipient)
71
129
  });
72
130
  }
73
- if (input.stripe) {
131
+ if (stripe) {
74
132
  out.push({
75
133
  method: "stripe/charge",
76
- rails: input.stripe.rails ?? ["card", "link", "shared_payment_token"],
77
- profile_id: input.stripe.profileId ?? null
134
+ rails: stripe.rails ?? [...RAIL_SPEC_DEFAULTS.stripe.rails],
135
+ profile_id: stripe.profileId ?? null
78
136
  });
79
137
  }
80
138
  return out;
81
139
  }
82
140
 
83
141
  // src/challenge/identity.ts
84
- function buildIdentityMetadata(input) {
85
- const block = { identity_mode: input.mode };
86
- if (input.mode !== "wallet") return block;
87
- if (input.wallet) {
88
- block.required_signer = input.signerMatchResult?.expectedSigner ?? input.wallet;
142
+ function buildIdentityMetadata({
143
+ mode,
144
+ wallet,
145
+ signerMatchResult,
146
+ linkedWallets,
147
+ signerConstraint
148
+ }) {
149
+ const block = { identity_mode: mode };
150
+ if (mode !== "wallet") return block;
151
+ if (wallet) {
152
+ block.required_signer = signerMatchResult?.expectedSigner ?? wallet;
89
153
  }
90
- if (input.linkedWallets && input.linkedWallets.length > 0) {
91
- block.linked_wallets = input.linkedWallets;
154
+ if (linkedWallets && linkedWallets.length > 0) {
155
+ block.linked_wallets = linkedWallets;
92
156
  }
93
- block.signer_constraint = input.signerConstraint ?? "Payment must be signed with the claimed wallet OR any same-operator linked wallet listed in linked_wallets.";
157
+ block.signer_constraint = signerConstraint ?? "Payment must be signed with the claimed wallet OR any same-operator linked wallet listed in linked_wallets.";
94
158
  return block;
95
159
  }
96
160
 
@@ -111,45 +175,52 @@ var PAY_SETUP_SOLANA = [
111
175
  "agentscore-pay wallet create --chain solana",
112
176
  "agentscore-pay balance --chain solana # fund the printed address with USDC on Solana"
113
177
  ];
114
- function buildHowToPay(input) {
115
- const totalNum = typeof input.totalUsd === "string" ? Number(input.totalUsd) : input.totalUsd;
116
- const maxSpend = String(input.maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
117
- const opToken = input.opTokenPlaceholder ?? "<your_opc_token>";
178
+ function buildHowToPay({
179
+ url,
180
+ retryBodyJson,
181
+ totalUsd,
182
+ rails,
183
+ opTokenPlaceholder,
184
+ maxSpend
185
+ }) {
186
+ const totalNum = typeof totalUsd === "string" ? Number(totalUsd) : totalUsd;
187
+ const maxSpendStr = String(maxSpend ?? (Math.ceil(totalNum) + 1).toFixed(2));
188
+ const opToken = opTokenPlaceholder ?? "<your_opc_token>";
118
189
  const block = {};
119
- if (input.rails.tempo) {
120
- const networkName = input.rails.tempo.networkName ?? "tempo-mainnet";
121
- const chainId = input.rails.tempo.chainId ?? 4217;
122
- const recommend = input.rails.tempo.recommend ?? "both";
123
- const tempoCommand = `tempo request -X POST -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' --json '${input.retryBodyJson}' --max-spend ${maxSpend} ${input.url}`;
124
- 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}`;
190
+ if (rails.tempo) {
191
+ const networkName = rails.tempo.testnet ? "tempo-testnet" : rails.tempo.network ?? RAIL_SPEC_DEFAULTS.tempo.network;
192
+ const chainId = rails.tempo.chainId ?? RAIL_SPEC_DEFAULTS.tempo.chainId;
193
+ const recommend = rails.tempo.recommend ?? RAIL_SPEC_DEFAULTS.tempo.recommend;
194
+ const tempoCommand = `tempo request -X POST -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' --json '${retryBodyJson}' --max-spend ${maxSpendStr} ${url}`;
195
+ const payCommand = `agentscore-pay pay POST ${url} --chain tempo -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${retryBodyJson}' --max-spend ${maxSpendStr}`;
125
196
  block.tempo = {
126
197
  setup: TEMPO_SETUP,
127
- 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.`,
198
+ 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.`,
128
199
  command: recommend === "agentscore-pay" ? payCommand : tempoCommand,
129
200
  ...recommend === "both" ? { alternative_command: payCommand } : recommend === "agentscore-pay" ? { alternative_command: tempoCommand } : {},
130
201
  what_it_does: `Pays via Tempo USDC on ${networkName}.`
131
202
  };
132
203
  }
133
- if (input.rails.x402_base) {
134
- const network = input.rails.x402_base.network ?? "eip155:8453";
204
+ if (rails.x402_base) {
205
+ const network = rails.x402_base.network ?? RAIL_SPEC_DEFAULTS.x402Base.network;
135
206
  block.x402_base = {
136
207
  setup: PAY_SETUP_BASE,
137
- 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.`,
138
- 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}`,
208
+ 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.`,
209
+ command: `agentscore-pay pay POST ${url} --chain base -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${retryBodyJson}' --max-spend ${maxSpendStr}`,
139
210
  what_it_does: "Pays via USDC on Base."
140
211
  };
141
212
  }
142
- if (input.rails.solana_mpp) {
143
- const network = input.rails.solana_mpp.network ?? "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
213
+ if (rails.solana_mpp) {
214
+ const network = rails.solana_mpp.network ?? RAIL_SPEC_DEFAULTS.solanaMpp.network;
144
215
  block.solana_mpp = {
145
216
  setup: PAY_SETUP_SOLANA,
146
- 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.`,
147
- 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}`,
217
+ 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.`,
218
+ command: `agentscore-pay pay POST ${url} --chain solana -H 'X-Operator-Token: ${opToken}' -H 'Content-Type: application/json' -d '${retryBodyJson}' --max-spend ${maxSpendStr}`,
148
219
  what_it_does: "Pays via USDC on Solana."
149
220
  };
150
221
  }
151
- if (input.rails.stripe) {
152
- const stripeCfg = input.rails.stripe;
222
+ if (rails.stripe) {
223
+ const stripeCfg = rails.stripe;
153
224
  const amountCents = Math.round(totalNum * 100);
154
225
  const linkCliBlocked = amountCents > 5e4;
155
226
  const productName = stripeCfg.productName ?? "this purchase";
@@ -166,7 +237,7 @@ function buildHowToPay(input) {
166
237
  ];
167
238
  stripe.command_link_cli = [
168
239
  `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)`,
169
- `link-cli mpp pay ${input.url} --spend-request-id $SPEND_ID --method POST --data '${input.retryBodyJson}' --header 'X-Operator-Token: ${opToken}' --output-json`
240
+ `link-cli mpp pay ${url} --spend-request-id $SPEND_ID --method POST --data '${retryBodyJson}' --header 'X-Operator-Token: ${opToken}' --output-json`
170
241
  ];
171
242
  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.";
172
243
  } else if (linkCliBlocked) {
@@ -178,8 +249,8 @@ function buildHowToPay(input) {
178
249
  }
179
250
 
180
251
  // src/challenge/agent_instructions.ts
181
- 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.";
182
- 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.";
252
+ 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.";
253
+ 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.";
183
254
  var TEMPO_TOOL = "`tempo request` for Tempo USDC";
184
255
  var AGENTSCORE_PAY_TOOL = "`agentscore-pay` \u2014 Base + Solana + Tempo from one CLI";
185
256
  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.";
@@ -214,17 +285,27 @@ function defaultCompatibleClients(howToPay) {
214
285
  if (howToPay.stripe) rails.push("stripe");
215
286
  return compatibleClientsByRails(rails);
216
287
  }
217
- function buildAgentInstructions(input) {
218
- const compatibleClients = input.compatibleClients ?? defaultCompatibleClients(input.howToPay);
288
+ function buildAgentInstructions({
289
+ howToPay,
290
+ recommendedTools,
291
+ walletCompatibility,
292
+ timeoutSeconds,
293
+ warnings,
294
+ extraWarnings,
295
+ recommended,
296
+ compatibleClients,
297
+ extra
298
+ }) {
299
+ const compatibleClientsOut = compatibleClients ?? defaultCompatibleClients(howToPay);
219
300
  return {
220
- how_to_pay: input.howToPay,
221
- recommended_tools: input.recommendedTools ?? defaultRecommendedTools(input.howToPay),
222
- wallet_compatibility: input.walletCompatibility ?? DEFAULT_WALLET_COMPATIBILITY,
223
- timeout_seconds: input.timeoutSeconds ?? 300,
224
- warnings: input.warnings ?? [...defaultWarnings(input.howToPay), ...input.extraWarnings ?? []],
225
- ...input.recommended ? { recommended: input.recommended } : {},
226
- ...compatibleClients ? { compatible_clients: compatibleClients } : {},
227
- ...input.extra ?? {}
301
+ how_to_pay: howToPay,
302
+ recommended_tools: recommendedTools ?? defaultRecommendedTools(howToPay),
303
+ wallet_compatibility: walletCompatibility ?? DEFAULT_WALLET_COMPATIBILITY,
304
+ timeout_seconds: timeoutSeconds ?? 300,
305
+ warnings: warnings ?? [...defaultWarnings(howToPay), ...extraWarnings ?? []],
306
+ ...recommended ? { recommended } : {},
307
+ ...compatibleClientsOut ? { compatible_clients: compatibleClientsOut } : {},
308
+ ...extra ?? {}
228
309
  };
229
310
  }
230
311
 
@@ -331,51 +412,80 @@ function buildAgentMemoryHint() {
331
412
  }
332
413
 
333
414
  // src/challenge/agent_memory.ts
334
- function firstEncounterAgentMemory(input) {
335
- if (!input.firstEncounter) return void 0;
415
+ function firstEncounterAgentMemory({
416
+ firstEncounter
417
+ }) {
418
+ if (!firstEncounter) return void 0;
336
419
  return buildAgentMemoryHint();
337
420
  }
338
421
 
339
422
  // src/challenge/body.ts
340
- function build402Body(input) {
423
+ function build402Body({
424
+ acceptedMethods,
425
+ agentInstructions,
426
+ identityMetadata,
427
+ agentMemory,
428
+ pricing,
429
+ amountUsd,
430
+ currency,
431
+ orderId,
432
+ product,
433
+ retryBody,
434
+ recommended,
435
+ x402,
436
+ extra
437
+ }) {
341
438
  const body = {
342
439
  payment_required: true,
343
- accepted_methods: input.acceptedMethods
440
+ accepted_methods: acceptedMethods
344
441
  };
345
- if (input.x402) {
346
- body.x402Version = input.x402.version ?? 2;
347
- body.accepts = input.x402.accepts;
442
+ if (x402) {
443
+ body.x402Version = x402.version ?? 2;
444
+ body.accepts = x402.accepts;
445
+ if (x402.extensions !== void 0 && Object.keys(x402.extensions).length > 0) {
446
+ body.extensions = x402.extensions;
447
+ }
348
448
  }
349
- if (input.amountUsd !== void 0) body.amount_usd = input.amountUsd;
350
- if (input.currency) body.currency = input.currency;
351
- if (input.pricing) body.pricing = input.pricing;
352
- if (input.orderId !== void 0) body.order_id = input.orderId;
353
- if (input.product) body.product = input.product;
354
- if (input.recommended) body.recommended = input.recommended;
355
- if (input.retryBody !== void 0) body.retry_body = input.retryBody;
356
- if (input.identityMetadata) {
357
- Object.assign(body, input.identityMetadata);
449
+ if (amountUsd !== void 0) body.amount_usd = amountUsd;
450
+ if (currency) body.currency = currency;
451
+ if (pricing) body.pricing = pricing;
452
+ if (orderId !== void 0) body.order_id = orderId;
453
+ if (product) body.product = product;
454
+ if (recommended) body.recommended = recommended;
455
+ if (retryBody !== void 0) body.retry_body = retryBody;
456
+ if (identityMetadata) {
457
+ Object.assign(body, identityMetadata);
358
458
  }
359
- if (input.agentInstructions) body.agent_instructions = input.agentInstructions;
360
- if (input.agentMemory !== void 0) body.agent_memory = input.agentMemory;
361
- if (input.extra) Object.assign(body, input.extra);
459
+ if (agentInstructions) body.agent_instructions = agentInstructions;
460
+ if (agentMemory !== void 0) body.agent_memory = agentMemory;
461
+ if (extra) Object.assign(body, extra);
362
462
  return body;
363
463
  }
364
464
 
365
465
  // src/challenge/pricing.ts
366
- function buildPricingBlock(input) {
367
- const tax = input.taxCents ?? 0;
368
- const shipping = input.shippingCents ?? 0;
369
- const total = input.totalCents ?? input.subtotalCents + tax + shipping;
466
+ function buildPricingBlock({
467
+ subtotalCents,
468
+ taxCents = 0,
469
+ shippingCents,
470
+ discountCents,
471
+ totalCents,
472
+ taxRate,
473
+ taxState,
474
+ currency
475
+ }) {
476
+ const shipping = shippingCents ?? 0;
477
+ const discount = discountCents ?? 0;
478
+ const total = totalCents ?? Math.max(0, subtotalCents + taxCents + shipping - discount);
370
479
  const block = {
371
- subtotal: formatCents(input.subtotalCents),
372
- tax: formatCents(tax),
480
+ subtotal: formatCents(subtotalCents),
481
+ tax: formatCents(taxCents),
373
482
  total: formatCents(total)
374
483
  };
375
- if (input.shippingCents !== void 0) block.shipping = formatCents(shipping);
376
- if (input.taxRate !== void 0) block.tax_rate = input.taxRate;
377
- if (input.taxState !== void 0) block.tax_state = input.taxState;
378
- if (input.currency !== void 0) block.currency = input.currency;
484
+ if (shippingCents !== void 0) block.shipping = formatCents(shipping);
485
+ if (discountCents !== void 0) block.discount = formatCents(discount);
486
+ if (taxRate !== void 0) block.tax_rate = taxRate;
487
+ if (taxState !== void 0) block.tax_state = taxState;
488
+ if (currency !== void 0) block.currency = currency;
379
489
  return block;
380
490
  }
381
491
  function formatCents(cents) {
@@ -383,30 +493,47 @@ function formatCents(cents) {
383
493
  }
384
494
 
385
495
  // src/payment/wwwauthenticate.ts
386
- function paymentRequiredHeader(input) {
387
- return Buffer.from(JSON.stringify(input)).toString("base64");
496
+ function paymentRequiredHeader({
497
+ x402Version,
498
+ accepts,
499
+ resource
500
+ }) {
501
+ return Buffer.from(JSON.stringify({ x402Version, accepts, ...resource ? { resource } : {} })).toString("base64");
388
502
  }
389
503
 
390
504
  // src/challenge/respond_402.ts
391
- function respond402(input) {
392
- const body = build402Body(input.body);
393
- const headers = new Headers(input.mppxChallenge.headers);
394
- headers.set("content-type", "application/json");
395
- if (input.x402) {
396
- headers.set("PAYMENT-REQUIRED", paymentRequiredHeader(input.x402));
505
+ function respond402({
506
+ mppxChallengeHeaders,
507
+ body,
508
+ x402
509
+ }) {
510
+ const headers = {};
511
+ for (const [k, v] of Object.entries(mppxChallengeHeaders)) {
512
+ headers[k.toLowerCase()] = v;
513
+ }
514
+ headers["content-type"] = "application/json";
515
+ if (x402) {
516
+ headers["payment-required"] = paymentRequiredHeader(x402);
397
517
  }
398
- return new Response(JSON.stringify(body), { headers, status: 402 });
518
+ return { body, headers, status: 402 };
399
519
  }
400
520
 
401
521
  // src/challenge/validation_error.ts
402
- function buildValidationError(input) {
522
+ function buildValidationError({
523
+ code,
524
+ message,
525
+ requiredFields,
526
+ exampleBody,
527
+ nextSteps,
528
+ extra
529
+ }) {
403
530
  const body = {
404
- error: { code: input.code, message: input.message }
531
+ error: { code, message }
405
532
  };
406
- if (input.requiredFields) body.required_fields = input.requiredFields;
407
- if (input.exampleBody !== void 0) body.example_body = input.exampleBody;
408
- if (input.nextSteps) body.next_steps = input.nextSteps;
409
- if (input.extra) Object.assign(body, input.extra);
533
+ if (requiredFields) body.required_fields = requiredFields;
534
+ if (exampleBody !== void 0) body.example_body = exampleBody;
535
+ if (nextSteps) body.next_steps = nextSteps;
536
+ if (extra) Object.assign(body, extra);
410
537
  return body;
411
538
  }
412
539
  // Annotate the CommonJS export names for ESM import in node: