@devlab.group/agent-commerce 2.4.0 → 2.5.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 (108) hide show
  1. package/README.md +115 -15
  2. package/dist/ap2.d.ts +24 -12
  3. package/dist/ap2.js +31 -13
  4. package/dist/ap2.js.map +1 -1
  5. package/dist/{chunk-AITMDXKW.js → chunk-3OTCFFFT.js} +37 -4
  6. package/dist/chunk-3OTCFFFT.js.map +1 -0
  7. package/dist/{chunk-4OEXK3YG.js → chunk-4K7FIBJM.js} +25 -4
  8. package/dist/chunk-4K7FIBJM.js.map +1 -0
  9. package/dist/{chunk-WUIAUAA7.js → chunk-FKQK5XZA.js} +652 -68
  10. package/dist/chunk-FKQK5XZA.js.map +1 -0
  11. package/dist/chunk-GA3O2A7R.js +92 -0
  12. package/dist/chunk-GA3O2A7R.js.map +1 -0
  13. package/dist/{chunk-6WACRJVT.js → chunk-VUCMBGUR.js} +3 -3
  14. package/dist/{chunk-6WACRJVT.js.map → chunk-VUCMBGUR.js.map} +1 -1
  15. package/dist/cli/{ap2-QDHPRSTF.js → ap2-YAPLERSC.js} +34 -15
  16. package/dist/cli/ap2-YAPLERSC.js.map +1 -0
  17. package/dist/cli/{chunk-G2JEY7MB.js → chunk-2J2IQQ4X.js} +8 -7
  18. package/dist/cli/chunk-2J2IQQ4X.js.map +1 -0
  19. package/dist/cli/chunk-2UPPX3FJ.js +311 -0
  20. package/dist/cli/chunk-2UPPX3FJ.js.map +1 -0
  21. package/dist/cli/{chunk-WYOGIANL.js → chunk-4H2QLHQI.js} +4 -4
  22. package/dist/cli/{chunk-WYOGIANL.js.map → chunk-4H2QLHQI.js.map} +1 -1
  23. package/dist/cli/{chunk-OZ4LAWBK.js → chunk-5R7DM5LM.js} +25 -4
  24. package/dist/cli/chunk-5R7DM5LM.js.map +1 -0
  25. package/dist/cli/chunk-663ALDZA.js +92 -0
  26. package/dist/cli/chunk-663ALDZA.js.map +1 -0
  27. package/dist/cli/{chunk-QQ3WY5L3.js → chunk-IDY2735M.js} +36 -104
  28. package/dist/cli/chunk-IDY2735M.js.map +1 -0
  29. package/dist/cli/chunk-JFVRG2HH.js +107 -0
  30. package/dist/cli/chunk-JFVRG2HH.js.map +1 -0
  31. package/dist/cli/chunk-M7NXVRU5.js +8 -0
  32. package/dist/cli/{chunk-UXB65XCS.js.map → chunk-M7NXVRU5.js.map} +1 -1
  33. package/dist/cli/chunk-NIU5EMSB.js +119 -0
  34. package/dist/cli/chunk-NIU5EMSB.js.map +1 -0
  35. package/dist/cli/{chunk-AZDWFVDW.js → chunk-QA2OPHBF.js} +655 -70
  36. package/dist/cli/chunk-QA2OPHBF.js.map +1 -0
  37. package/dist/cli/{chunk-DCMW67JM.js → chunk-QLUCNPRT.js} +404 -161
  38. package/dist/cli/chunk-QLUCNPRT.js.map +1 -0
  39. package/dist/cli/chunk-SYQLJXIU.js +105 -0
  40. package/dist/cli/chunk-SYQLJXIU.js.map +1 -0
  41. package/dist/cli/{chunk-3MGAJ5FX.js → chunk-VJ4EO4LE.js} +3 -3
  42. package/dist/cli/{chunk-3MGAJ5FX.js.map → chunk-VJ4EO4LE.js.map} +1 -1
  43. package/dist/cli/{chunk-PIMFPCNZ.js → chunk-Z34UMZBB.js} +234 -85
  44. package/dist/cli/chunk-Z34UMZBB.js.map +1 -0
  45. package/dist/cli/config-BWFMN2ZB.js +12 -0
  46. package/dist/cli/{config-UI4EDG4L.js.map → config-BWFMN2ZB.js.map} +1 -1
  47. package/dist/cli/index.js +258 -11
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/cli/{mcp-26LJMN4N.js → mcp-KZEMXLHR.js} +5 -4
  50. package/dist/cli/mcp-KZEMXLHR.js.map +1 -0
  51. package/dist/cli/{near-5AY3HWYF.js → near-U6365VFX.js} +15 -4
  52. package/dist/cli/near-U6365VFX.js.map +1 -0
  53. package/dist/cli/payment-providers-SZL36H3Y.js +6 -0
  54. package/dist/cli/payment-providers-SZL36H3Y.js.map +1 -0
  55. package/dist/cli/{provider-Z4OJNAYI.js → provider-6TKB5ADJ.js} +30 -16
  56. package/dist/cli/provider-6TKB5ADJ.js.map +1 -0
  57. package/dist/cli/receipts-ZGLJWMQG.js +8 -0
  58. package/dist/cli/receipts-ZGLJWMQG.js.map +1 -0
  59. package/dist/cli/reconcile-IC22MJD5.js +4 -0
  60. package/dist/cli/reconcile-IC22MJD5.js.map +1 -0
  61. package/dist/cli/{run-TEPYJUHG.js → run-ZTYPQI4D.js} +151 -115
  62. package/dist/cli/run-ZTYPQI4D.js.map +1 -0
  63. package/dist/cli/svm-KDSPDFJG.js +48 -0
  64. package/dist/cli/svm-KDSPDFJG.js.map +1 -0
  65. package/dist/cli/{x402-BMVONZKA.js → x402-WLYBLODI.js} +10 -9
  66. package/dist/cli/x402-WLYBLODI.js.map +1 -0
  67. package/dist/index.d.ts +112 -12
  68. package/dist/index.js +948 -157
  69. package/dist/index.js.map +1 -1
  70. package/dist/mcp.d.ts +1 -2
  71. package/dist/mcp.js +1 -1
  72. package/dist/mpp.js +24 -11
  73. package/dist/mpp.js.map +1 -1
  74. package/dist/{near-D6C42VPE.js → near-FH7HPZV3.js} +15 -4
  75. package/dist/near-FH7HPZV3.js.map +1 -0
  76. package/dist/{protocol-adapter-C9odYl6l.d.ts → protocol-adapter-DEXpdp8m.d.ts} +102 -48
  77. package/dist/{runtime-Cl_BLVZV.d.ts → runtime-Dz2fSO-P.d.ts} +220 -2
  78. package/dist/svm-KNC3PHMS.js +48 -0
  79. package/dist/svm-KNC3PHMS.js.map +1 -0
  80. package/dist/x402.js +5 -5
  81. package/package.json +1 -1
  82. package/dist/authorization-DjAecwuW.d.ts +0 -115
  83. package/dist/chunk-4OEXK3YG.js.map +0 -1
  84. package/dist/chunk-AITMDXKW.js.map +0 -1
  85. package/dist/chunk-KA2AX5FH.js +0 -44
  86. package/dist/chunk-KA2AX5FH.js.map +0 -1
  87. package/dist/chunk-WUIAUAA7.js.map +0 -1
  88. package/dist/cli/ap2-QDHPRSTF.js.map +0 -1
  89. package/dist/cli/chunk-AZDWFVDW.js.map +0 -1
  90. package/dist/cli/chunk-DCMW67JM.js.map +0 -1
  91. package/dist/cli/chunk-G2JEY7MB.js.map +0 -1
  92. package/dist/cli/chunk-OSTCU6ZK.js +0 -44
  93. package/dist/cli/chunk-OSTCU6ZK.js.map +0 -1
  94. package/dist/cli/chunk-OZ4LAWBK.js.map +0 -1
  95. package/dist/cli/chunk-PIMFPCNZ.js.map +0 -1
  96. package/dist/cli/chunk-QQ3WY5L3.js.map +0 -1
  97. package/dist/cli/chunk-UXB65XCS.js +0 -8
  98. package/dist/cli/config-UI4EDG4L.js +0 -11
  99. package/dist/cli/mcp-26LJMN4N.js.map +0 -1
  100. package/dist/cli/near-5AY3HWYF.js.map +0 -1
  101. package/dist/cli/provider-Z4OJNAYI.js.map +0 -1
  102. package/dist/cli/run-TEPYJUHG.js.map +0 -1
  103. package/dist/cli/svm-3MMYFPC7.js +0 -33
  104. package/dist/cli/svm-3MMYFPC7.js.map +0 -1
  105. package/dist/cli/x402-BMVONZKA.js.map +0 -1
  106. package/dist/near-D6C42VPE.js.map +0 -1
  107. package/dist/svm-QEUAUNPQ.js +0 -33
  108. package/dist/svm-QEUAUNPQ.js.map +0 -1
@@ -0,0 +1,311 @@
1
+ import { CommerceError, redactedErrorText } from './chunk-SYQLJXIU.js';
2
+
3
+ // src/core/execution/reconcile.ts
4
+ var DEFAULT_RECONCILE_MIN_AGE_MS = 15 * 60 * 1e3;
5
+ var PAGE = 200;
6
+ var OUTCOMES = ["settled", "not-settled", "unknown"];
7
+ function journalOf(store) {
8
+ const {
9
+ listTransactions,
10
+ getTransaction,
11
+ getPaymentAttempt,
12
+ resolvePaymentAttempt,
13
+ recordTransactionStep
14
+ } = store;
15
+ if (!listTransactions || !getTransaction || !getPaymentAttempt || !resolvePaymentAttempt || !recordTransactionStep) {
16
+ throw new CommerceError("STORAGE_ERROR", "The receipt store has no transaction journal");
17
+ }
18
+ return {
19
+ listTransactions: listTransactions.bind(store),
20
+ getTransaction: getTransaction.bind(store),
21
+ getPaymentAttempt: getPaymentAttempt.bind(store),
22
+ resolvePaymentAttempt: resolvePaymentAttempt.bind(store),
23
+ recordTransactionStep: recordTransactionStep.bind(store)
24
+ };
25
+ }
26
+ async function runReconcile(options) {
27
+ const { store, providers, clock, actor, logger } = options;
28
+ const dryRun = options.dryRun === true;
29
+ const journal = journalOf(store);
30
+ const candidates = await collectCandidates(options, journal);
31
+ const entries = [];
32
+ for (const { attempt, transactionId, locator } of candidates) {
33
+ const provider = providers.find((candidate) => candidate.name === attempt.provider);
34
+ const result = await ask(provider, attempt, locator, clock, logger);
35
+ let written = false;
36
+ let error;
37
+ if (!dryRun && result.outcome !== "unknown") {
38
+ try {
39
+ written = await journal.resolvePaymentAttempt({
40
+ attemptId: attempt.id,
41
+ expectedStatus: attempt.status,
42
+ status: result.outcome === "settled" ? "settled" : "rejected",
43
+ ...result.outcome === "not-settled" ? { rejectionReason: "not_settled" } : {},
44
+ resolution: {
45
+ method: "reconcile",
46
+ actor,
47
+ reason: result.reason,
48
+ at: clock.nowIso(),
49
+ ...result.externalReference !== void 0 ? { externalReference: result.externalReference } : {},
50
+ ...result.evidence !== void 0 ? { evidence: result.evidence } : {}
51
+ }
52
+ });
53
+ } catch (err) {
54
+ logger?.warn(
55
+ { attemptId: attempt.id, err: redactedErrorText(err) },
56
+ "reconcile: could not save the resolution"
57
+ );
58
+ error = "storage_error";
59
+ }
60
+ }
61
+ entries.push({
62
+ attemptId: attempt.id,
63
+ ...transactionId !== void 0 ? { transactionId } : {},
64
+ requestId: attempt.requestId,
65
+ provider: attempt.provider,
66
+ status: attempt.status,
67
+ outcome: result.outcome,
68
+ reason: result.reason,
69
+ written,
70
+ ...error !== void 0 ? { error } : {},
71
+ ...result.externalReference !== void 0 ? { externalReference: result.externalReference } : {},
72
+ ...result.retryAfter !== void 0 ? { retryAfter: result.retryAfter } : {}
73
+ });
74
+ }
75
+ const authorizationProviders = options.authorizationProviders ?? [];
76
+ const holds = [];
77
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
78
+ let cursor;
79
+ scan: while (authorizationProviders.length > 0) {
80
+ const page = await journal.listTransactions({
81
+ pendingHold: true,
82
+ limit: PAGE,
83
+ ...cursor !== void 0 ? { cursor } : {}
84
+ });
85
+ for (const transaction of page.transactions) {
86
+ const target = holdTarget(transaction);
87
+ if (target === void 0) continue;
88
+ if (holds.length >= limit) break scan;
89
+ holds.push(
90
+ dryRun ? holdEntry(transaction, target, false) : await alignHold(transaction, target, {
91
+ journal,
92
+ authorizationProviders,
93
+ clock,
94
+ logger
95
+ })
96
+ );
97
+ }
98
+ cursor = page.nextCursor;
99
+ if (cursor === void 0) break;
100
+ }
101
+ return { dryRun, entries, holds };
102
+ }
103
+ var REFUSAL_MESSAGES = {
104
+ already_resolved: "The payment attempt already has a resolution",
105
+ not_resolvable: "Only reserved, settlement-uncertain and failed payment attempts can be resolved",
106
+ too_recent: "The payment attempt is reserved and may still be in flight; retry once it is 15 minutes old",
107
+ not_expired: "The recorded authorization expiry is still in the future",
108
+ expiry_unknown: "No expiry is recorded for this authorization; confirm that it has expired"
109
+ };
110
+ var MAX_ACTOR_LENGTH = 256;
111
+ var MAX_REASON_LENGTH = 1024;
112
+ var MAX_REFERENCE_LENGTH = 256;
113
+ var RESOLVABLE = [
114
+ "reserved",
115
+ "settlement-uncertain",
116
+ "failed"
117
+ ];
118
+ async function resolveManually(options) {
119
+ const { clock, logger, attemptId, status, externalReference } = options;
120
+ if (status !== "settled" && status !== "rejected") {
121
+ throw invalid("status", 'status must be "settled" or "rejected"');
122
+ }
123
+ const actor = requiredText(options.actor, "actor", MAX_ACTOR_LENGTH);
124
+ const reason = requiredText(options.reason, "reason", MAX_REASON_LENGTH);
125
+ if (externalReference !== void 0) {
126
+ requiredText(externalReference, "externalReference", MAX_REFERENCE_LENGTH);
127
+ }
128
+ const journal = journalOf(options.store);
129
+ const attempt = await journal.getPaymentAttempt(attemptId);
130
+ if (attempt === void 0) {
131
+ throw new CommerceError("RESOURCE_NOT_FOUND", `Payment attempt "${attemptId}" was not found`);
132
+ }
133
+ const refuse = (refusal, current2 = attempt) => ({
134
+ resolved: false,
135
+ refusal,
136
+ message: REFUSAL_MESSAGES[refusal],
137
+ attempt: current2
138
+ });
139
+ if (attempt.resolution !== void 0) return refuse("already_resolved");
140
+ if (!RESOLVABLE.includes(attempt.status)) return refuse("not_resolvable");
141
+ if (attempt.status === "reserved" && !(clock.now().getTime() - Date.parse(attempt.createdAt) >= DEFAULT_RECONCILE_MIN_AGE_MS)) {
142
+ return refuse("too_recent");
143
+ }
144
+ const transaction = attempt.transactionId !== void 0 ? await journal.getTransaction(attempt.transactionId) : void 0;
145
+ if (status === "rejected") {
146
+ const expiresAt = Date.parse(transaction?.payment.expiresAt ?? "");
147
+ if (expiresAt > clock.now().getTime()) return refuse("not_expired");
148
+ if (Number.isNaN(expiresAt) && options.confirmExpired !== true) {
149
+ return refuse("expiry_unknown");
150
+ }
151
+ }
152
+ const written = await journal.resolvePaymentAttempt({
153
+ attemptId,
154
+ expectedStatus: attempt.status,
155
+ status,
156
+ ...status === "rejected" ? { rejectionReason: "not_settled" } : {},
157
+ resolution: {
158
+ method: "manual",
159
+ actor,
160
+ reason,
161
+ at: clock.nowIso(),
162
+ ...externalReference !== void 0 ? { externalReference } : {}
163
+ }
164
+ });
165
+ const current = await journal.getPaymentAttempt(attemptId) ?? attempt;
166
+ if (!written) {
167
+ return refuse(
168
+ current.resolution !== void 0 ? "already_resolved" : "not_resolvable",
169
+ current
170
+ );
171
+ }
172
+ const resolved = transaction !== void 0 ? await journal.getTransaction(transaction.id) : void 0;
173
+ const target = resolved !== void 0 ? holdTarget(resolved) : void 0;
174
+ const hold = resolved !== void 0 && target !== void 0 ? await alignHold(resolved, target, {
175
+ journal,
176
+ authorizationProviders: options.authorizationProviders,
177
+ clock,
178
+ logger
179
+ }) : void 0;
180
+ return { resolved: true, attempt: current, ...hold !== void 0 ? { hold } : {} };
181
+ }
182
+ function requiredText(value, field, max) {
183
+ if (value.trim() === "" || value.length > max) {
184
+ throw invalid(field, `${field} must be non-empty and at most ${max} characters`);
185
+ }
186
+ return value;
187
+ }
188
+ function invalid(field, message) {
189
+ return new CommerceError("INPUT_INVALID", message, { details: { field } });
190
+ }
191
+ function holdTarget(transaction) {
192
+ const hold = transaction.authorization?.hold;
193
+ if (hold !== "reserved" && hold !== "uncertain") return void 0;
194
+ if (transaction.payment.status === "settled") return "consumed";
195
+ if (transaction.payment.status === "rejected") return "released";
196
+ return void 0;
197
+ }
198
+ function holdEntry(transaction, hold, written, reason) {
199
+ return {
200
+ transactionId: transaction.id,
201
+ attemptId: transaction.payment.attemptId,
202
+ method: transaction.authorization?.method ?? "",
203
+ hold,
204
+ written,
205
+ ...reason !== void 0 ? { reason } : {}
206
+ };
207
+ }
208
+ async function alignHold(transaction, target, deps) {
209
+ const authorization = transaction.authorization;
210
+ const provider = deps.authorizationProviders.find(
211
+ (candidate) => candidate.name === authorization?.method
212
+ );
213
+ if (authorization === void 0 || provider === void 0) {
214
+ return holdEntry(transaction, target, false, "provider_not_enabled");
215
+ }
216
+ const context = { requestId: transaction.requestId, resourceId: transaction.resourceId };
217
+ try {
218
+ if (target === "consumed") await provider.consume(authorization.reservationId, context);
219
+ else await provider.release(authorization.reservationId, context);
220
+ } catch (err) {
221
+ deps.logger?.warn(
222
+ { transactionId: transaction.id, method: provider.name, err: redactedErrorText(err) },
223
+ "reconcile: authorization provider threw"
224
+ );
225
+ return holdEntry(transaction, target, false, "provider_error");
226
+ }
227
+ try {
228
+ await deps.journal.recordTransactionStep({
229
+ transactionId: transaction.id,
230
+ at: deps.clock.nowIso(),
231
+ kind: "hold",
232
+ hold: target
233
+ });
234
+ } catch (err) {
235
+ deps.logger?.warn(
236
+ { transactionId: transaction.id, err: redactedErrorText(err) },
237
+ "reconcile: could not record the hold update"
238
+ );
239
+ return holdEntry(transaction, target, false, "journal_error");
240
+ }
241
+ return holdEntry(transaction, target, true);
242
+ }
243
+ async function collectCandidates(options, journal) {
244
+ const { store, clock } = options;
245
+ const limit = options.limit ?? Number.POSITIVE_INFINITY;
246
+ const minAgeMs = options.minAgeMs ?? DEFAULT_RECONCILE_MIN_AGE_MS;
247
+ const now = clock.now().getTime();
248
+ const eligible = (attempt) => attempt.resolution === void 0 && (attempt.status === "settlement-uncertain" || attempt.status === "failed" || attempt.status === "reserved" && now - Date.parse(attempt.createdAt) >= minAgeMs);
249
+ const candidates = [];
250
+ const seen = /* @__PURE__ */ new Set();
251
+ for (const state of ["payment-uncertain", "payment-pending", "delivery-started"]) {
252
+ let cursor;
253
+ do {
254
+ const page = await journal.listTransactions({
255
+ state,
256
+ limit: PAGE,
257
+ ...cursor !== void 0 ? { cursor } : {}
258
+ });
259
+ for (const transaction of page.transactions) {
260
+ if (candidates.length >= limit) return candidates;
261
+ const { attemptId, status, locator } = transaction.payment;
262
+ if (status !== "settlement-uncertain" && status !== "failed" && status !== "reserved") {
263
+ continue;
264
+ }
265
+ const attempt = await journal.getPaymentAttempt(attemptId);
266
+ if (attempt === void 0 || !eligible(attempt) || seen.has(attempt.id)) continue;
267
+ seen.add(attempt.id);
268
+ candidates.push({
269
+ attempt,
270
+ transactionId: transaction.id,
271
+ ...locator !== void 0 ? { locator } : {}
272
+ });
273
+ }
274
+ cursor = page.nextCursor;
275
+ } while (cursor !== void 0);
276
+ }
277
+ for (const attempt of await store.listPaymentAttempts({ uncertain: true, limit: 500 })) {
278
+ if (candidates.length >= limit) break;
279
+ if (attempt.transactionId !== void 0 || seen.has(attempt.id) || !eligible(attempt)) continue;
280
+ seen.add(attempt.id);
281
+ candidates.push({ attempt });
282
+ }
283
+ return candidates;
284
+ }
285
+ async function ask(provider, attempt, locator, clock, logger) {
286
+ if (provider === void 0) return { outcome: "unknown", reason: "provider_not_enabled" };
287
+ if (provider.reconcile === void 0) {
288
+ return { outcome: "unknown", reason: "reconcile_unsupported" };
289
+ }
290
+ try {
291
+ const result = await provider.reconcile({
292
+ attempt,
293
+ ...locator !== void 0 ? { locator } : {},
294
+ now: clock.nowIso()
295
+ });
296
+ if (!OUTCOMES.includes(result.outcome) || typeof result.reason !== "string") {
297
+ return { outcome: "unknown", reason: "invalid_provider_result" };
298
+ }
299
+ return result;
300
+ } catch (err) {
301
+ logger?.warn(
302
+ { attemptId: attempt.id, provider: attempt.provider, err: redactedErrorText(err) },
303
+ "reconcile: provider threw"
304
+ );
305
+ return { outcome: "unknown", reason: "provider_error" };
306
+ }
307
+ }
308
+
309
+ export { DEFAULT_RECONCILE_MIN_AGE_MS, journalOf, resolveManually, runReconcile };
310
+ //# sourceMappingURL=chunk-2UPPX3FJ.js.map
311
+ //# sourceMappingURL=chunk-2UPPX3FJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/execution/reconcile.ts"],"names":["current"],"mappings":"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","file":"chunk-2UPPX3FJ.js","sourcesContent":["/**\n * Reconciliation records chain-evidence outcomes, and manual resolution\n * records operator verdicts, through conditional payment-attempt updates.\n * Neither path settles, refunds or retries delivery.\n *\n * An `unknown` result leaves the attempt unresolved. Later runs skip resolved\n * attempts as payment candidates but can retry their pending authorization\n * holds. Both paths attempt hold updates after recording payment resolution.\n */\nimport type { AuthorizationProvider } from '../domain/authorization';\nimport type { PaymentProvider, PaymentReconciliationResult } from '../domain/payment';\nimport type { PaymentAttempt } from '../domain/receipt';\nimport type { Transaction } from '../domain/transaction';\nimport { CommerceError, redactedErrorText } from '../errors';\nimport type { Logger } from '../interfaces/logger';\nimport type { Clock } from '../interfaces/runtime';\nimport type { ReceiptStore } from '../interfaces/store';\n\n/** Default age threshold for reserved attempts, to reduce races with a running gateway */\nexport const DEFAULT_RECONCILE_MIN_AGE_MS = 15 * 60 * 1000;\n\n// Journal page size while collecting candidates\nconst PAGE = 200;\n\nconst OUTCOMES: readonly string[] = ['settled', 'not-settled', 'unknown'];\n\nexport interface ReconcileRunOptions {\n readonly store: ReceiptStore;\n readonly providers: readonly PaymentProvider[];\n readonly clock: Clock;\n /** Stored with each resolution */\n readonly actor: string;\n /** Check provider evidence and report without recording resolutions */\n readonly dryRun?: boolean;\n readonly minAgeMs?: number;\n /** Separate caps on payment candidates checked and hold updates attempted */\n readonly limit?: number;\n /** Providers for hold updates; an omitted or empty list skips the hold scan */\n readonly authorizationProviders?: readonly AuthorizationProvider[];\n readonly logger?: Logger;\n}\n\n/** Reconciliation result for one candidate */\nexport interface ReconcileEntry {\n readonly attemptId: string;\n /** Absent for attempts without a journal entry */\n readonly transactionId?: string;\n readonly requestId: string;\n readonly provider: string;\n readonly status: PaymentAttempt['status'];\n readonly outcome: PaymentReconciliationResult['outcome'];\n readonly reason: string;\n /** True when this run saved the attempt's resolution */\n readonly written: boolean;\n /** Set when saving the resolution throws */\n readonly error?: 'storage_error';\n readonly externalReference?: string;\n readonly retryAfter?: string;\n}\n\n/** Requested hold update for one resolved payment */\nexport interface HoldEntry {\n readonly transactionId: string;\n readonly attemptId: string;\n readonly method: string;\n /** `consumed` for a settled payment, `released` for a rejected one */\n readonly hold: 'consumed' | 'released';\n /** True when the provider call succeeded and the journal hold was recorded */\n readonly written: boolean;\n /**\n * Why the journal hold remains pending; `journal_error` means the provider\n * call succeeded but the journal write failed\n */\n readonly reason?: 'provider_not_enabled' | 'provider_error' | 'journal_error';\n}\n\nexport interface ReconcileReport {\n readonly dryRun: boolean;\n readonly entries: readonly ReconcileEntry[];\n readonly holds: readonly HoldEntry[];\n}\n\ninterface Candidate {\n readonly attempt: PaymentAttempt;\n readonly transactionId?: string;\n readonly locator?: Readonly<Record<string, unknown>>;\n}\n\n/** Store methods required by reconciliation, manual resolution and the operator view */\nexport type Journal = Required<\n Pick<\n ReceiptStore,\n | 'listTransactions'\n | 'getTransaction'\n | 'getPaymentAttempt'\n | 'resolvePaymentAttempt'\n | 'recordTransactionStep'\n >\n>;\n\n/** Binds the required journal methods to the store, or throws `STORAGE_ERROR` if one is missing */\nexport function journalOf(store: ReceiptStore): Journal {\n const {\n listTransactions,\n getTransaction,\n getPaymentAttempt,\n resolvePaymentAttempt,\n recordTransactionStep,\n } = store;\n if (\n !listTransactions ||\n !getTransaction ||\n !getPaymentAttempt ||\n !resolvePaymentAttempt ||\n !recordTransactionStep\n ) {\n throw new CommerceError('STORAGE_ERROR', 'The receipt store has no transaction journal');\n }\n return {\n listTransactions: listTransactions.bind(store),\n getTransaction: getTransaction.bind(store),\n getPaymentAttempt: getPaymentAttempt.bind(store),\n resolvePaymentAttempt: resolvePaymentAttempt.bind(store),\n recordTransactionStep: recordTransactionStep.bind(store),\n };\n}\n\nexport async function runReconcile(options: ReconcileRunOptions): Promise<ReconcileReport> {\n const { store, providers, clock, actor, logger } = options;\n const dryRun = options.dryRun === true;\n const journal = journalOf(store);\n\n const candidates = await collectCandidates(options, journal);\n const entries: ReconcileEntry[] = [];\n for (const { attempt, transactionId, locator } of candidates) {\n const provider = providers.find((candidate) => candidate.name === attempt.provider);\n const result = await ask(provider, attempt, locator, clock, logger);\n let written = false;\n let error: ReconcileEntry['error'];\n if (!dryRun && result.outcome !== 'unknown') {\n // Report a failed resolution write and continue with the remaining candidates\n try {\n written = await journal.resolvePaymentAttempt({\n attemptId: attempt.id,\n expectedStatus: attempt.status,\n status: result.outcome === 'settled' ? 'settled' : 'rejected',\n ...(result.outcome === 'not-settled' ? { rejectionReason: 'not_settled' } : {}),\n resolution: {\n method: 'reconcile',\n actor,\n reason: result.reason,\n at: clock.nowIso(),\n ...(result.externalReference !== undefined\n ? { externalReference: result.externalReference }\n : {}),\n ...(result.evidence !== undefined ? { evidence: result.evidence } : {}),\n },\n });\n } catch (err) {\n logger?.warn(\n { attemptId: attempt.id, err: redactedErrorText(err) },\n 'reconcile: could not save the resolution',\n );\n error = 'storage_error';\n }\n }\n entries.push({\n attemptId: attempt.id,\n ...(transactionId !== undefined ? { transactionId } : {}),\n requestId: attempt.requestId,\n provider: attempt.provider,\n status: attempt.status,\n outcome: result.outcome,\n reason: result.reason,\n written,\n ...(error !== undefined ? { error } : {}),\n ...(result.externalReference !== undefined\n ? { externalReference: result.externalReference }\n : {}),\n ...(result.retryAfter !== undefined ? { retryAfter: result.retryAfter } : {}),\n });\n }\n\n const authorizationProviders = options.authorizationProviders ?? [];\n const holds: HoldEntry[] = [];\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n // Include pending holds left by earlier runs. Hold updates have no age\n // filter: the pipeline attempts finalization before recording a settled or\n // rejected payment status.\n let cursor: string | undefined;\n scan: while (authorizationProviders.length > 0) {\n const page = await journal.listTransactions({\n pendingHold: true,\n limit: PAGE,\n ...(cursor !== undefined ? { cursor } : {}),\n });\n for (const transaction of page.transactions) {\n const target = holdTarget(transaction);\n if (target === undefined) continue;\n if (holds.length >= limit) break scan;\n holds.push(\n dryRun\n ? holdEntry(transaction, target, false)\n : await alignHold(transaction, target, {\n journal,\n authorizationProviders,\n clock,\n logger,\n }),\n );\n }\n cursor = page.nextCursor;\n if (cursor === undefined) break;\n }\n return { dryRun, entries, holds };\n}\n\n/** Input to {@link resolveManually}; `actor` is a caller-supplied label */\nexport interface ManualResolveOptions {\n readonly store: ReceiptStore;\n readonly authorizationProviders: readonly AuthorizationProvider[];\n readonly clock: Clock;\n readonly logger?: Logger;\n readonly attemptId: string;\n /** `settled` or `rejected`; anything else is `INPUT_INVALID` */\n readonly status: string;\n readonly actor: string;\n readonly reason: string;\n /** Recorded as the operator's claim without checking the chain */\n readonly externalReference?: string;\n /** Required for rejection when no valid expiry is recorded */\n readonly confirmExpired?: boolean;\n}\n\n/** Why a manual resolution was not written */\nexport type ManualResolveRefusal =\n | 'already_resolved'\n | 'not_resolvable'\n | 'too_recent'\n | 'not_expired'\n | 'expiry_unknown';\n\nexport type ManualResolveResult =\n | {\n readonly resolved: true;\n readonly attempt: PaymentAttempt;\n /** Present when the attempt's transaction holds an authorization to align */\n readonly hold?: HoldEntry;\n }\n | {\n readonly resolved: false;\n readonly refusal: ManualResolveRefusal;\n readonly message: string;\n readonly attempt: PaymentAttempt;\n };\n\nconst REFUSAL_MESSAGES: Record<ManualResolveRefusal, string> = {\n already_resolved: 'The payment attempt already has a resolution',\n not_resolvable: 'Only reserved, settlement-uncertain and failed payment attempts can be resolved',\n too_recent:\n 'The payment attempt is reserved and may still be in flight; retry once it is 15 minutes old',\n not_expired: 'The recorded authorization expiry is still in the future',\n expiry_unknown: 'No expiry is recorded for this authorization; confirm that it has expired',\n};\n\n// Bounds on operator-supplied text stored with the resolution\nconst MAX_ACTOR_LENGTH = 256;\nconst MAX_REASON_LENGTH = 1024;\nconst MAX_REFERENCE_LENGTH = 256;\n\nconst RESOLVABLE: readonly PaymentAttempt['status'][] = [\n 'reserved',\n 'settlement-uncertain',\n 'failed',\n];\n\n/**\n * Record an operator's verdict on an unresolved payment attempt, then try to\n * update its pending authorization hold. A `reserved` attempt younger than\n * {@link DEFAULT_RECONCILE_MIN_AGE_MS} is refused because the gateway may still\n * be settling it. A `rejected` verdict is refused while\n * the recorded expiry is in the future. Without a valid expiry, `confirmExpired`\n * is required. Throws `INPUT_INVALID` for invalid input and\n * `RESOURCE_NOT_FOUND` for an unknown attempt.\n */\nexport async function resolveManually(options: ManualResolveOptions): Promise<ManualResolveResult> {\n const { clock, logger, attemptId, status, externalReference } = options;\n if (status !== 'settled' && status !== 'rejected') {\n throw invalid('status', 'status must be \"settled\" or \"rejected\"');\n }\n const actor = requiredText(options.actor, 'actor', MAX_ACTOR_LENGTH);\n const reason = requiredText(options.reason, 'reason', MAX_REASON_LENGTH);\n if (externalReference !== undefined) {\n requiredText(externalReference, 'externalReference', MAX_REFERENCE_LENGTH);\n }\n const journal = journalOf(options.store);\n\n const attempt = await journal.getPaymentAttempt(attemptId);\n if (attempt === undefined) {\n throw new CommerceError('RESOURCE_NOT_FOUND', `Payment attempt \"${attemptId}\" was not found`);\n }\n const refuse = (refusal: ManualResolveRefusal, current = attempt): ManualResolveResult => ({\n resolved: false,\n refusal,\n message: REFUSAL_MESSAGES[refusal],\n attempt: current,\n });\n if (attempt.resolution !== undefined) return refuse('already_resolved');\n if (!RESOLVABLE.includes(attempt.status)) return refuse('not_resolvable');\n if (\n attempt.status === 'reserved' &&\n !(clock.now().getTime() - Date.parse(attempt.createdAt) >= DEFAULT_RECONCILE_MIN_AGE_MS)\n ) {\n return refuse('too_recent');\n }\n\n const transaction =\n attempt.transactionId !== undefined\n ? await journal.getTransaction(attempt.transactionId)\n : undefined;\n if (status === 'rejected') {\n const expiresAt = Date.parse(transaction?.payment.expiresAt ?? '');\n if (expiresAt > clock.now().getTime()) return refuse('not_expired');\n if (Number.isNaN(expiresAt) && options.confirmExpired !== true) {\n return refuse('expiry_unknown');\n }\n }\n\n const written = await journal.resolvePaymentAttempt({\n attemptId,\n expectedStatus: attempt.status,\n status,\n ...(status === 'rejected' ? { rejectionReason: 'not_settled' } : {}),\n resolution: {\n method: 'manual',\n actor,\n reason,\n at: clock.nowIso(),\n ...(externalReference !== undefined ? { externalReference } : {}),\n },\n });\n const current = (await journal.getPaymentAttempt(attemptId)) ?? attempt;\n // The conditional update lost a race; use the current attempt to classify it\n if (!written) {\n return refuse(\n current.resolution !== undefined ? 'already_resolved' : 'not_resolvable',\n current,\n );\n }\n\n const resolved =\n transaction !== undefined ? await journal.getTransaction(transaction.id) : undefined;\n const target = resolved !== undefined ? holdTarget(resolved) : undefined;\n const hold =\n resolved !== undefined && target !== undefined\n ? await alignHold(resolved, target, {\n journal,\n authorizationProviders: options.authorizationProviders,\n clock,\n logger,\n })\n : undefined;\n return { resolved: true, attempt: current, ...(hold !== undefined ? { hold } : {}) };\n}\n\nfunction requiredText(value: string, field: string, max: number): string {\n if (value.trim() === '' || value.length > max) {\n throw invalid(field, `${field} must be non-empty and at most ${max} characters`);\n }\n return value;\n}\n\nfunction invalid(field: string, message: string): CommerceError {\n return new CommerceError('INPUT_INVALID', message, { details: { field } });\n}\n\n// Desired state for a resolved payment's journal hold still reserved or uncertain\nfunction holdTarget(transaction: Transaction): HoldEntry['hold'] | undefined {\n const hold = transaction.authorization?.hold;\n if (hold !== 'reserved' && hold !== 'uncertain') return undefined;\n if (transaction.payment.status === 'settled') return 'consumed';\n if (transaction.payment.status === 'rejected') return 'released';\n return undefined;\n}\n\nfunction holdEntry(\n transaction: Transaction,\n hold: HoldEntry['hold'],\n written: boolean,\n reason?: HoldEntry['reason'],\n): HoldEntry {\n return {\n transactionId: transaction.id,\n attemptId: transaction.payment.attemptId,\n method: transaction.authorization?.method ?? '',\n hold,\n written,\n ...(reason !== undefined ? { reason } : {}),\n };\n}\n\n// Call the provider before updating the journal, so a crash can leave the\n// journal hold pending. After an AP2 consume/release succeeds, repeating it\n// leaves replay state unchanged; the request guard protects later reservations.\nasync function alignHold(\n transaction: Transaction,\n target: HoldEntry['hold'],\n deps: {\n readonly journal: Journal;\n readonly authorizationProviders: readonly AuthorizationProvider[];\n readonly clock: Clock;\n readonly logger: Logger | undefined;\n },\n): Promise<HoldEntry> {\n const authorization = transaction.authorization;\n const provider = deps.authorizationProviders.find(\n (candidate) => candidate.name === authorization?.method,\n );\n if (authorization === undefined || provider === undefined) {\n return holdEntry(transaction, target, false, 'provider_not_enabled');\n }\n // Bind the update to this transaction's reserving request\n const context = { requestId: transaction.requestId, resourceId: transaction.resourceId };\n try {\n if (target === 'consumed') await provider.consume(authorization.reservationId, context);\n else await provider.release(authorization.reservationId, context);\n } catch (err) {\n deps.logger?.warn(\n { transactionId: transaction.id, method: provider.name, err: redactedErrorText(err) },\n 'reconcile: authorization provider threw',\n );\n return holdEntry(transaction, target, false, 'provider_error');\n }\n // If the provider call succeeded but journaling fails, report the pending\n // journal update so a later run can retry both calls\n try {\n await deps.journal.recordTransactionStep({\n transactionId: transaction.id,\n at: deps.clock.nowIso(),\n kind: 'hold',\n hold: target,\n });\n } catch (err) {\n deps.logger?.warn(\n { transactionId: transaction.id, err: redactedErrorText(err) },\n 'reconcile: could not record the hold update',\n );\n return holdEntry(transaction, target, false, 'journal_error');\n }\n return holdEntry(transaction, target, true);\n}\n\n// Include uncertain and legacy `failed` attempts, plus `reserved` attempts\n// whose journal entries are present and whose age meets the threshold.\n// Journal rows supply locators; older attempts may have none.\nasync function collectCandidates(\n options: ReconcileRunOptions,\n journal: Journal,\n): Promise<readonly Candidate[]> {\n const { store, clock } = options;\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n const minAgeMs = options.minAgeMs ?? DEFAULT_RECONCILE_MIN_AGE_MS;\n const now = clock.now().getTime();\n const eligible = (attempt: PaymentAttempt) =>\n attempt.resolution === undefined &&\n (attempt.status === 'settlement-uncertain' ||\n attempt.status === 'failed' ||\n (attempt.status === 'reserved' && now - Date.parse(attempt.createdAt) >= minAgeMs));\n\n const candidates: Candidate[] = [];\n const seen = new Set<string>();\n // Scan states that can contain unresolved payments. delivery-started also\n // includes settled payments, which the attempt-status check below skips.\n for (const state of ['payment-uncertain', 'payment-pending', 'delivery-started'] as const) {\n let cursor: string | undefined;\n do {\n const page = await journal.listTransactions({\n state,\n limit: PAGE,\n ...(cursor !== undefined ? { cursor } : {}),\n });\n for (const transaction of page.transactions) {\n if (candidates.length >= limit) return candidates;\n const { attemptId, status, locator } = transaction.payment;\n if (status !== 'settlement-uncertain' && status !== 'failed' && status !== 'reserved') {\n continue;\n }\n const attempt = await journal.getPaymentAttempt(attemptId);\n if (attempt === undefined || !eligible(attempt) || seen.has(attempt.id)) continue;\n seen.add(attempt.id);\n candidates.push({\n attempt,\n transactionId: transaction.id,\n ...(locator !== undefined ? { locator } : {}),\n });\n }\n cursor = page.nextCursor;\n } while (cursor !== undefined);\n }\n\n // ponytail: attempts without journal entries are capped at one page; paginate for larger legacy stores\n for (const attempt of await store.listPaymentAttempts({ uncertain: true, limit: 500 })) {\n if (candidates.length >= limit) break;\n if (attempt.transactionId !== undefined || seen.has(attempt.id) || !eligible(attempt)) continue;\n seen.add(attempt.id);\n candidates.push({ attempt });\n }\n return candidates;\n}\n\nasync function ask(\n provider: PaymentProvider | undefined,\n attempt: PaymentAttempt,\n locator: Readonly<Record<string, unknown>> | undefined,\n clock: Clock,\n logger: Logger | undefined,\n): Promise<PaymentReconciliationResult> {\n if (provider === undefined) return { outcome: 'unknown', reason: 'provider_not_enabled' };\n if (provider.reconcile === undefined) {\n return { outcome: 'unknown', reason: 'reconcile_unsupported' };\n }\n try {\n const result = await provider.reconcile({\n attempt,\n ...(locator !== undefined ? { locator } : {}),\n now: clock.nowIso(),\n });\n if (!OUTCOMES.includes(result.outcome) || typeof result.reason !== 'string') {\n return { outcome: 'unknown', reason: 'invalid_provider_result' };\n }\n return result;\n } catch (err) {\n logger?.warn(\n { attemptId: attempt.id, provider: attempt.provider, err: redactedErrorText(err) },\n 'reconcile: provider threw',\n );\n return { outcome: 'unknown', reason: 'provider_error' };\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
- import { ANVIL_WELL_KNOWN_ACCOUNTS, requireX402Network, resolveDeploymentMode, LOCAL_CHAIN_ID, isBurnAddress, sameAddress, normalizeAddress } from './chunk-OZ4LAWBK.js';
2
- import { CommerceError } from './chunk-QQ3WY5L3.js';
1
+ import { ANVIL_WELL_KNOWN_ACCOUNTS, requireX402Network, resolveDeploymentMode, LOCAL_CHAIN_ID, isBurnAddress, sameAddress, normalizeAddress } from './chunk-5R7DM5LM.js';
2
+ import { CommerceError } from './chunk-SYQLJXIU.js';
3
3
 
4
4
  // src/payments/x402/dev-key-guard.ts
5
5
  var WELL_KNOWN_DEV_KEYS = new Set(
@@ -334,5 +334,5 @@ function resolveX402Option(input, path, custom) {
334
334
  }
335
335
 
336
336
  export { assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress, describeRpc, isWellKnownDevKey, resolveX402Deployment, resolveX402Option, x402OfferName };
337
- //# sourceMappingURL=chunk-WYOGIANL.js.map
338
- //# sourceMappingURL=chunk-WYOGIANL.js.map
337
+ //# sourceMappingURL=chunk-4H2QLHQI.js.map
338
+ //# sourceMappingURL=chunk-4H2QLHQI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/payments/x402/dev-key-guard.ts","../../src/payments/x402/guardrails.ts","../../src/payments/x402/options.ts"],"names":["invalid"],"mappings":";;;;AAWA,IAAM,sBAA2C,IAAI,GAAA;AAAA,EACnD,0BAA0B,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,UAAA,CAAW,aAAa;AACjE,CAAA;AAEA,IAAM,2BAAgD,IAAI,GAAA;AAAA,EACxD,0BAA0B,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,OAAA,CAAQ,aAAa;AAC9D,CAAA;AAGA,IAAM,iBAAA,GAAoB,qBAAA;AAEnB,SAAS,kBAAkB,UAAA,EAA6B;AAC7D,EAAA,OAAO,mBAAA,CAAoB,GAAA,CAAI,UAAA,CAAW,WAAA,EAAa,CAAA;AACzD;AAEO,SAAS,sBAAsB,OAAA,EAA0B;AAC9D,EAAA,OAAO,wBAAA,CAAyB,GAAA,CAAI,OAAA,CAAQ,WAAA,EAAa,CAAA;AAC3D;AASO,SAAS,2BAA2B,QAAA,EAA2B;AACpE,EAAA,MAAM,IAAI,QAAA,CAAS,WAAA,EAAY,CAAE,OAAA,CAAQ,YAAY,EAAE,CAAA;AACvD,EAAA,IAAI,CAAA,KAAM,WAAA,IAAe,CAAA,KAAM,KAAA,EAAO,OAAO,IAAA;AAC7C,EAAA,IAAI,kCAAA,CAAmC,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,IAAA;AACvD,EAAA,IAAI,iCAAA,CAAkC,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,IAAA;AACtD,EAAA,IAAI,8BAAA,CAA+B,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,IAAA;AACnD,EAAA,IAAI,6CAAA,CAA8C,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,IAAA;AAClE,EAAA,IAAI,CAAC,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,IAAK,CAAC,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AACjD,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,qBAAqB,MAAA,EAAwB;AACpD,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,MAAM,CAAA,CAAE,QAAA;AAAA,EACzB,SAAS,KAAA,EAAO;AAGd,IAAA,MAAM,IAAI,aAAA,CAAc,gBAAA,EAAkB,0CAAA,EAA4C;AAAA,MACpF;AAAA,KACD,CAAA;AAAA,EACH;AACF;AAGO,SAAS,YAAY,MAAA,EAAwB;AAClD,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,MAAM,CAAA,CAAE,MAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,sBAAA;AAAA,EACT;AACF;AASO,SAAS,uBAAA,CAAwB,QAAgB,gBAAA,EAAgC;AACtF,EAAA,IAAI,CAAC,iBAAA,CAAkB,IAAA,CAAK,gBAAgB,CAAA,EAAG;AAC7C,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,gBAAA;AAAA,MACA;AAAA,KAEF;AAAA,EACF;AAEA,EAAA,IAAI,CAAC,iBAAA,CAAkB,gBAAgB,CAAA,EAAG;AAE1C,EAAA,MAAM,QAAA,GAAW,qBAAqB,MAAM,CAAA;AAE5C,EAAA,IAAI,CAAC,0BAAA,CAA2B,QAAQ,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,gBAAA;AAAA,MACA,CAAA,8FAAA,EACK,WAAA,CAAY,MAAM,CAAC,CAAA,+QAAA;AAAA,KAG1B;AAAA,EACF;AACF;AAUO,SAAS,0BAAA,CAA2B,QAAgB,KAAA,EAAqB;AAC9E,EAAA,IAAI,CAAC,qBAAA,CAAsB,KAAK,CAAA,EAAG;AAEnC,EAAA,MAAM,QAAA,GAAW,qBAAqB,MAAM,CAAA;AAE5C,EAAA,IAAI,CAAC,0BAAA,CAA2B,QAAQ,CAAA,EAAG;AACzC,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,gBAAA;AAAA,MACA,CAAA,wBAAA,EAA2B,KAAK,CAAA,wDAAA,EAC3B,WAAA,CAAY,MAAM,CAAC,CAAA,4QAAA;AAAA,KAI1B;AAAA,EACF;AACF;;;AC7CA,IAAM,YAAA,GAAe,cAAA;AAErB,SAAS,OAAA,CAAQ,SAAiB,IAAA,EAA6B;AAC7D,EAAA,OAAO,IAAI,cAAc,gBAAA,EAAkB,OAAA,EAAS,EAAE,OAAA,EAAS,EAAE,IAAA,EAAK,EAAG,CAAA;AAC3E;AAOO,SAAS,sBAAsB,KAAA,EAA4C;AAChF,EAAA,MAAM,EAAA,GAAK,MAAM,UAAA,IAAc,eAAA;AAC/B,EAAA,MAAM,KAAA,GAAQ,MAAM,UAAA,IAAc,OAAA;AAClC,EAAA,MAAM,OAAA,GAAU,mBAAmB,KAAA,CAAM,OAAA,EAAS,GAAG,EAAE,CAAA,QAAA,CAAA,EAAY,MAAM,cAAc,CAAA;AACvF,EAAA,MAAM,IAAA,GAAO,sBAAsB,OAAO,CAAA;AAI1C,EAAA,IAAI,QAAQ,IAAA,KAAS,SAAA,IAAa,KAAA,CAAM,WAAA,CAAY,SAAS,OAAA,EAAS;AACpE,IAAA,MAAM,OAAA;AAAA,MACJ,GAAG,EAAE,CAAA,WAAA,EAAc,QAAQ,EAAE,CAAA,GAAA,EAAM,QAAQ,WAAW,CAAA,+HAAA,CAAA;AAAA,MACtD,GAAG,EAAE,CAAA,iBAAA;AAAA,KACP;AAAA,EACF;AAGA,EAAA,IAAI,KAAA,CAAM,WAAA,CAAY,IAAA,KAAS,OAAA,IAAW,SAAS,OAAA,EAAS;AAC1D,IAAA,MAAM,OAAA;AAAA,MACJ,OAAA,CAAQ,OAAO,YAAA,GACX,CAAA,EAAG,EAAE,CAAA,kCAAA,EAAqC,cAAc,CAAA,6BAAA,EAAgC,YAAY,CAAA,8BAAA,EAAiC,EAAE,sBAAsB,cAAc,CAAA,qHAAA,CAAA,GAC3K,CAAA,EAAG,EAAE,CAAA,gEAAA,EAAmE,cAAc,gBAAgB,OAAA,CAAQ,EAAE,CAAA,GAAA,EAAM,OAAA,CAAQ,WAAW,CAAA,4BAAA,CAAA;AAAA,MAC7I,GAAG,EAAE,CAAA,iBAAA;AAAA,KACP;AAAA,EACF;AAEA,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,KAAA,CAAM,YAAA,KAAiB,IAAA,EAAM;AACrD,IAAA,MAAM,OAAA;AAAA,MACJ,CAAA,EAAG,EAAE,CAAA,WAAA,EAAc,OAAA,CAAQ,EAAE,CAAA,GAAA,EAAM,OAAA,CAAQ,WAAW,CAAA,0BAAA,EAA6B,EAAE,CAAA,6EAAA,CAAA;AAAA,MACrF,GAAG,EAAE,CAAA,aAAA;AAAA,KACP;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,WAAA,CAAY,IAAA,KAAS,QAAA,EAAU;AACvC,IAAA,0BAAA,CAA2B,KAAA,CAAM,WAAA,CAAY,GAAA,EAAK,IAAA,EAAM,EAAE,CAAA;AAG1D,IAAA,IAAI,KAAA,CAAM,WAAA,CAAY,IAAA,CAAK,IAAA,KAAS,KAAA,IAAS,CAAC,mBAAA,CAAoB,KAAA,CAAM,WAAA,CAAY,GAAG,CAAA,EAAG;AACxF,MAAA,MAAM,OAAA;AAAA,QACJ,CAAA,EAAG,EAAE,CAAA,iDAAA,EAAoD,mBAAmB,CAAA,sBAAA,EAAyB,cAAA,CAAe,KAAA,CAAM,WAAA,CAAY,GAAG,CAAC,CAAA,sDAAA,EAAyD,mBAAmB,CAAA,sCAAA,CAAA;AAAA,QACtN,GAAG,EAAE,CAAA,gBAAA;AAAA,OACP;AAAA,IACF;AAIA,IAAA,IACE,IAAA,KAAS,aACT,KAAA,CAAM,WAAA,CAAY,KAAK,IAAA,KAAS,MAAA,IAChC,KAAA,CAAM,+BAAA,KAAoC,IAAA,EAC1C;AACA,MAAA,MAAM,OAAA;AAAA,QACJ,CAAA,EAAG,EAAE,CAAA,8CAAA,EAAiD,cAAA,CAAe,MAAM,WAAA,CAAY,GAAG,CAAC,CAAA,iBAAA,EAAoB,EAAE,CAAA,8HAAA,CAAA;AAAA,QACjH,GAAG,EAAE,CAAA,gCAAA;AAAA,OACP;AAAA,IACF;AAIA,IAAA,KAAA,MAAW,CAAC,OAAO,KAAK,CAAA,IAAK,iBAAiB,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA,EAAG;AACrE,MAAA,IAAI,KAAA,CAAM,IAAA,EAAK,KAAM,EAAA,EAAI;AACvB,QAAA,MAAM,OAAA;AAAA,UACJ,CAAA,EAAG,EAAE,CAAA,4BAAA,EAA+B,KAAA,CAAM,YAAY,IAAA,CAAK,IAAI,SAAS,KAAK,CAAA,2DAAA,CAAA;AAAA,UAC7E,CAAA,EAAG,EAAE,CAAA,kBAAA,EAAqB,KAAK,CAAA;AAAA,SACjC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,EAAA,IAAI,aAAA,CAAc,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA,EAAG;AACvC,IAAA,MAAM,OAAA;AAAA,MACJ,CAAA,EAAG,EAAE,CAAA,GAAA,EAAM,KAAK,CAAA,gEAAA,CAAA;AAAA,MAChB,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,KAChB;AAAA,EACF;AAKA,EAAA,IAAI,IAAA,KAAS,OAAA,IAAW,qBAAA,CAAsB,KAAA,CAAM,KAAK,CAAA,EAAG;AAC1D,IAAA,MAAM,OAAA;AAAA,MACJ,CAAA,EAAG,EAAE,CAAA,GAAA,EAAM,KAAK,CAAA,GAAA,EAAM,MAAM,KAAK,CAAA,0DAAA,EAA6D,IAAI,CAAA,sDAAA,EAAyD,KAAK,CAAA,6BAAA,CAAA;AAAA,MAChK,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,KAChB;AAAA,EACF;AAIA,EAAA,MAAM,YAAY,OAAA,CAAQ,cAAA;AAC1B,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,IAAI,CAAC,WAAA,CAAY,OAAA,EAAS,MAAM,KAAA,EAAO,SAAA,CAAU,OAAO,CAAA,EAAG;AACzD,MAAA,IAAI,KAAA,CAAM,kBAAA,KAAuB,IAAA,IAAQ,OAAA,CAAQ,WAAW,KAAA,EAAO;AACjE,QAAA,MAAM,IAAA,GACJ,KAAA,CAAM,kBAAA,KAAuB,IAAA,GACzB,CAAA,2CAAA,EAA8C,OAAA,CAAQ,WAAW,CAAA,qBAAA,EAAwB,SAAA,CAAU,MAAM,CAAA,CAAA,CAAA,GACzG,CAAA,uCAAA,EAA0C,UAAU,MAAM,CAAA,CAAA,CAAA;AAChE,QAAA,MAAM,OAAA;AAAA,UACJ,CAAA,EAAG,EAAE,CAAA,QAAA,EAAW,KAAA,CAAM,KAAK,CAAA,QAAA,EAAW,SAAA,CAAU,MAAM,CAAA,IAAA,EAAO,QAAQ,WAAW,CAAA,WAAA,EAAc,SAAA,CAAU,OAAO,MAAM,IAAI,CAAA,CAAA;AAAA,UACzH,GAAG,EAAE,CAAA,MAAA;AAAA,SACP;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AAGL,MAAA,MAAM,MAAA,GAAS,MAAA,IAAU,SAAA,GAAY,SAAA,GAAY,MAAA;AACjD,MAAA,IAAI,UAAU,KAAA,CAAM,SAAA,KAAc,UAAa,KAAA,CAAM,SAAA,KAAc,OAAO,IAAA,EAAM;AAC9E,QAAA,MAAM,OAAA;AAAA,UACJ,CAAA,EAAG,EAAE,CAAA,aAAA,EAAgB,KAAA,CAAM,SAAS,CAAA,iCAAA,EAAoC,SAAA,CAAU,MAAM,CAAA,YAAA,EAAe,OAAA,CAAQ,WAAW,CAAA,YAAA,EAAe,OAAO,IAAI,CAAA,0DAAA,CAAA;AAAA,UACpJ,GAAG,EAAE,CAAA,UAAA;AAAA,SACP;AAAA,MACF;AACA,MAAA,IAAI,UAAU,KAAA,CAAM,YAAA,KAAiB,UAAa,KAAA,CAAM,YAAA,KAAiB,OAAO,OAAA,EAAS;AACvF,QAAA,MAAM,OAAA;AAAA,UACJ,CAAA,EAAG,EAAE,CAAA,gBAAA,EAAmB,KAAA,CAAM,YAAY,CAAA,oCAAA,EAAuC,SAAA,CAAU,MAAM,CAAA,YAAA,EAAe,OAAA,CAAQ,WAAW,CAAA,YAAA,EAAe,OAAO,OAAO,CAAA,GAAA,CAAA;AAAA,UAChK,GAAG,EAAE,CAAA,aAAA;AAAA,SACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,SAAS,IAAA,EAAK;AACzB;AAQA,SAAS,0BAAA,CAA2B,GAAA,EAAa,IAAA,EAAsB,EAAA,EAAkB;AACvF,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,GAAG,CAAA;AAAA,EACtB,SAAS,KAAA,EAAO;AACd,IAAA,MAAM,IAAI,aAAA,CAAc,gBAAA,EAAkB,CAAA,EAAG,EAAE,CAAA,oCAAA,CAAA,EAAwC;AAAA,MACrF,KAAA;AAAA,MACA,OAAA,EAAS,EAAE,IAAA,EAAM,CAAA,EAAG,EAAE,CAAA,gBAAA,CAAA;AAAmB,KAC1C,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,MAAA,CAAO,aAAa,QAAA,EAAU;AAClC,EAAA,IAAI,MAAA,CAAO,aAAa,OAAA,EAAS;AAC/B,IAAA,MAAM,OAAA;AAAA,MACJ,CAAA,EAAG,EAAE,CAAA,cAAA,EAAiB,cAAA,CAAe,GAAG,CAAC,CAAA,oEAAA,EAAuE,OAAO,QAAQ,CAAA,GAAA,CAAA;AAAA,MAC/H,GAAG,EAAE,CAAA,gBAAA;AAAA,KACP;AAAA,EACF;AACA,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,0BAAA,CAA2B,MAAA,CAAO,QAAQ,CAAA,EAAG;AAIvE,EAAA,MAAM,OAAA;AAAA,IACJ,CAAA,EAAG,EAAE,CAAA,cAAA,EAAiB,cAAA,CAAe,GAAG,CAAC,CAAA,6KAAA,CAAA;AAAA,IACzC,GAAG,EAAE,CAAA,gBAAA;AAAA,GACP;AACF;AAGO,IAAM,mBAAA,GAAsB,+CAAA;AAGnC,SAAS,oBAAoB,GAAA,EAAsB;AACjD,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,IAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,mBAAmB,CAAA;AAC5C,IAAA,OACE,MAAA,CAAO,MAAA,KAAW,QAAA,CAAS,MAAA,IAC3B,MAAA,CAAO,QAAA,CAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA,KAAM,QAAA,CAAS,QAAA,IACjD,OAAO,MAAA,KAAW,EAAA;AAAA,EAEtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAGA,SAAS,eAAe,GAAA,EAAqB;AAC3C,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,GAAG,CAAA,CAAE,MAAA;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,+BAAA;AAAA,EACT;AACF;AAGA,SAAS,iBAAiB,IAAA,EAA+D;AACvF,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,QAAA;AACH,MAAA,OAAO,CAAC,CAAC,OAAA,EAAS,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,IAC/B,KAAK,KAAA;AACH,MAAA,OAAO;AAAA,QACL,CAAC,UAAA,EAAY,IAAA,CAAK,QAAQ,CAAA;AAAA,QAC1B,CAAC,cAAA,EAAgB,IAAA,CAAK,YAAY;AAAA,OACpC;AAAA,IACF;AACE,MAAA,OAAO,EAAC;AAAA;AAEd;;;ACjPO,SAAS,cAAc,KAAA,EAInB;AACT,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,SAAS,CAAA;AAC9C,EAAA,MAAM,UAAU,CAAC,KAAA,KAAmB,GAAA,GAAM,KAAA,CAAM,aAAY,GAAI,KAAA;AAChE,EAAA,OAAO,CAAA,EAAG,KAAA,CAAM,OAAO,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAC,CAAA,CAAA;AACzE;AAMA,IAAM,cAAA,GAAiB;AAAA,EACrB,SAAA,EAAW,qBAAA;AAAA,EACX,YAAA,EAAc,wBAAA;AAAA,EACd,aAAA,EAAe;AACjB,CAAA;AAEA,IAAM,cAAA,GAAiB;AAAA,EACrB,GAAA,EAAK,oCAAA;AAAA,EACL,GAAA,EAAK,iCAAA;AAAA,EACL,IAAA,EAAM;AACR,CAAA;AAEA,SAASA,QAAAA,CAAQ,SAAiB,IAAA,EAA6B;AAC7D,EAAA,OAAO,IAAI,cAAc,gBAAA,EAAkB,OAAA,EAAS,EAAE,OAAA,EAAS,EAAE,IAAA,EAAK,EAAG,CAAA;AAC3E;AAEO,SAAS,iBAAA,CACd,KAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,MAAA,IAAa,KAAA,CAAM,WAAW,OAAA,EAAS;AAC1D,IAAA,MAAMA,QAAAA;AAAA,MACJ,CAAA,EAAG,IAAI,CAAA,UAAA,EAAa,KAAA,CAAM,MAAM,CAAA,mDAAA,CAAA;AAAA,MAChC,GAAG,IAAI,CAAA,OAAA;AAAA,KACT;AAAA,EACF;AACA,EAAA,MAAM,UAAU,kBAAA,CAAmB,KAAA,CAAM,SAAS,CAAA,EAAG,IAAI,YAAY,MAAM,CAAA;AAC3E,EAAA,MAAM,OAAA,GAAU,CAAC,KAAA,EAA0B,KAAA,KAA0B;AACnE,IAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,OAAA,EAAS,KAAK,CAAA;AAC5C,IAAA,IAAI,SAAS,MAAA,EAAW;AACtB,MAAA,MAAMA,QAAAA;AAAA;AAAA,QAEJ,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,+BAAA,EAAkC,OAAA,CAAQ,WAAW,CAAA,WAAA,EAAc,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAC,CAAA,CAAA,CAAA;AAAA,QACjH,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,OAClB;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AAEA,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA;AAC1C,EAAA,IAAI,aAAA,CAAc,OAAA,EAAS,KAAK,CAAA,EAAG;AACjC,IAAA,MAAMA,QAAAA;AAAA,MACJ,CAAA,EAAG,IAAI,CAAA,8BAAA,EAAiC,OAAA,CAAQ,WAAW,CAAA,2CAAA,CAAA;AAAA,MAC3D,GAAG,IAAI,CAAA,MAAA;AAAA,KACT;AAAA,EACF;AAEA,EAAA,MAAM,MAAA,GAAS,MAAM,mBAAA,IAAuB,SAAA;AAC5C,EAAA,IAAI,MAAA,KAAW,SAAA,IAAa,MAAA,KAAW,SAAA,EAAW;AAChD,IAAA,MAAMA,QAAAA;AAAA,MACJ,CAAA,EAAG,IAAI,CAAA,uBAAA,EAA0B,MAAM,CAAA,8CAAA,CAAA;AAAA,MACvC,GAAG,IAAI,CAAA,oBAAA;AAAA,KACT;AAAA,EACF;AACA,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,KAAA,IAAS,KAAA,CAAM,wBAAwB,MAAA,EAAW;AACvE,IAAA,MAAMA,QAAAA;AAAA,MACJ,CAAA,EAAG,IAAI,CAAA,0DAAA,EAA6D,OAAA,CAAQ,WAAW,CAAA,CAAA;AAAA,MACvF,GAAG,IAAI,CAAA,oBAAA;AAAA,KACT;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,CAAQ,WAAW,KAAA,EAAO;AAC5B,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,WAAA,EAAa,cAAc,CAAA,EAAY;AAC1D,MAAA,IAAI,KAAA,CAAM,KAAK,CAAA,KAAM,MAAA,EAAW;AAC9B,QAAA,MAAMA,QAAAA;AAAA,UACJ,GAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,uDAAA,EAA0D,QAAQ,WAAW,CAAA,CAAA;AAAA,UAC7F,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,SAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,YAAY,OAAA,CAAQ,cAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,SAAA,IAAa,MAAA,IAAU,SAAA,GAAY,SAAA,GAAY,MAAA;AAE9D,EAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,KAAU,MAAA,GAAY,QAAQ,OAAA,EAAS,KAAA,CAAM,KAAK,CAAA,GAAI,MAAA;AAC1E,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,aAAA,CAAc,OAAA,EAAS,KAAK,CAAA,EAAG;AACxD,IAAA,MAAMA,SAAQ,CAAA,EAAG,IAAI,CAAA,mCAAA,CAAA,EAAuC,CAAA,EAAG,IAAI,CAAA,MAAA,CAAQ,CAAA;AAAA,EAC7E;AAGA,EAAA,IAAI,SAAA,KAAc,UAAU,MAAA,IAAa,WAAA,CAAY,SAAS,KAAA,EAAO,SAAA,CAAU,OAAO,CAAA,CAAA,EAAI;AACxF,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,WAAW,MAAA,EAAQ,IAAA;AAAA,MACnB,cAAc,MAAA,EAAQ,OAAA;AAAA,MACtB,eAAe,SAAA,CAAU;AAAA,KAC3B;AACA,IAAA,KAAA,MAAW,KAAA,IAAS,CAAC,WAAA,EAAa,cAAA,EAAgB,eAAe,CAAA,EAAY;AAC3E,MAAA,MAAM,KAAA,GAAQ,MAAM,KAAK,CAAA;AACzB,MAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,QAAA,CAAS,KAAK,CAAA,EAAG;AACpD,QAAA,MAAMA,QAAAA;AAAA,UACJ,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,mBAAmB,SAAA,CAAU,MAAM,CAAA,IAAA,EAAO,OAAA,CAAQ,WAAW,CAAA,gBAAA,EAAmB,eAAe,KAAK,CAAC,IAAI,IAAA,CAAK,SAAA,CAAU,SAAS,KAAK,CAAC,CAAC,CAAA,SAAA,EAAY,KAAK,CAAA,yCAAA,CAAA;AAAA,UACzK,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,SAClB;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,OAAA;AAAA,MACR,OAAA;AAAA,MACA,KAAA;AAAA,MACA,KAAA,EAAO,SAAS,SAAA,CAAU,OAAA;AAAA,MAC1B,GAAI,MAAA,GAAS,EAAE,SAAA,EAAW,MAAA,CAAO,MAAM,YAAA,EAAc,MAAA,CAAO,OAAA,EAAQ,GAAI,EAAC;AAAA,MACzE,eAAe,SAAA,CAAU,QAAA;AAAA,MACzB,oBAAoB,SAAA,CAAU,MAAA;AAAA,MAC9B,mBAAA,EAAqB;AAAA,KACvB;AAAA,EACF;AAKA,EAAA,MAAM,QAAA,GACJ,OAAA,CAAQ,MAAA,KAAW,KAAA,IAAS,WAAW,SAAA,GAClC,CAAC,OAAA,EAAS,WAAA,EAAa,cAAA,EAAgB,eAAe,CAAA,GACtD,CAAC,SAAS,eAAe,CAAA;AAChC,EAAA,MAAM,OAAA,GAAU,SAAS,MAAA,CAAO,CAAC,UAAU,KAAA,CAAM,KAAK,MAAM,MAAS,CAAA;AACrE,EAAA,IAAI,KAAA,KAAU,MAAA,IAAa,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC7C,IAAA,MAAMA,QAAAA;AAAA,MACJ,SAAA,GACI,CAAA,EAAG,IAAI,CAAA,qBAAA,EAAwB,SAAA,CAAU,MAAM,CAAA,IAAA,EAAO,OAAA,CAAQ,WAAW,CAAA,OAAA,EAAU,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,GACrG,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,OAAA,CAAQ,WAAW,CAAA,2CAAA,EAA8C,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,MACnG,GAAG,IAAI,CAAA,CAAA,EAAI,OAAA,CAAQ,CAAC,KAAK,OAAO,CAAA;AAAA,KAClC;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,OAAA;AAAA,IACR,OAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAI,MAAM,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,KAAA,CAAM,SAAA,EAAU,GAAI,EAAC;AAAA,IACtE,GAAI,MAAM,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,EAAc,KAAA,CAAM,YAAA,EAAa,GAAI,EAAC;AAAA,IAC/E,eAAe,KAAA,CAAM,aAAA;AAAA,IACrB,mBAAA,EAAqB;AAAA,GACvB;AACF","file":"chunk-WYOGIANL.js","sourcesContent":["/**\n * Rejects well-known Anvil keys and payment destinations when the RPC host\n * does not look local or private. Their private keys are published, so anyone\n * can spend what such an address receives on a public chain.\n *\n * The check uses the RPC hostname because the local chain shares Base\n * Sepolia's chain id. Both guards run at provider construction.\n */\nimport { CommerceError } from '../../core';\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from './local-chain/accounts';\n\nconst WELL_KNOWN_DEV_KEYS: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.privateKey.toLowerCase()),\n);\n\nconst WELL_KNOWN_DEV_ADDRESSES: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.address.toLowerCase()),\n);\n\n// `0x` plus 64 hex characters, the only shape `privateKeyToAccount` accepts\nconst PRIVATE_KEY_SHAPE = /^0x[0-9a-fA-F]{64}$/;\n\nexport function isWellKnownDevKey(privateKey: string): boolean {\n return WELL_KNOWN_DEV_KEYS.has(privateKey.toLowerCase());\n}\n\nexport function isWellKnownDevAddress(address: string): boolean {\n return WELL_KNOWN_DEV_ADDRESSES.has(address.toLowerCase());\n}\n\n/**\n * True for loopback addresses, RFC 1918 private ranges, and bare (dot-free)\n * hostnames, such as the compose service name \"anvil\".\n *\n * Bare hostnames are treated as local without resolving them. Operators must\n * point them at a private chain.\n */\nexport function isLikelyLocalOrPrivateHost(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '');\n if (h === 'localhost' || h === '::1') return true;\n if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (!h.includes('.') && !h.includes(':')) return true; // bare hostname\n return false;\n}\n\nfunction parseHostnameOrThrow(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).hostname;\n } catch (cause) {\n // Never the URL itself: RPC providers commonly put an API key in the path,\n // and this message reaches startup output and CI logs\n throw new CommerceError('CONFIG_INVALID', 'x402 provider: rpcUrl is not a valid URL', {\n cause,\n });\n }\n}\n\n/** Origin only, for diagnostics: RPC URLs often carry an API key in the path or query */\nexport function describeRpc(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).origin;\n } catch {\n return '[unparseable rpcUrl]';\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `signerPrivateKey` is not shaped like a private key,\n * or if it is a well-known dev key and the RPC is not local.\n *\n * The shape check runs first, so a truncated key is reported as malformed\n * instead of passing as \"not a dev key\".\n */\nexport function assertDevKeyIsLocalOnly(rpcUrl: string, signerPrivateKey: string): void {\n if (!PRIVATE_KEY_SHAPE.test(signerPrivateKey)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is not a well-formed private key ' +\n '(expected \"0x\" followed by exactly 64 hex characters).',\n );\n }\n\n if (!isWellKnownDevKey(signerPrivateKey)) return; // the operator's own key\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ' +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. A public dev key must never sign against ` +\n 'a public network: it is instantly drainable and can grief real settlements via nonce exhaustion. ' +\n 'Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.',\n );\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `payTo` is a well-known Anvil address and `rpcUrl`\n * does not look local or private.\n *\n * Guards the receiving side, in every facilitator mode. `agent-commerce init`\n * defaults `payTo` to a well-known address for the local demo, and on a real\n * network that default sends every payment where anyone can sweep it.\n */\nexport function assertPayToIsNotDevAddress(rpcUrl: string, payTo: string): void {\n if (!isWellKnownDevAddress(payTo)) return;\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" (${payTo}) is a well-known Anvil development address, but rpcUrl ` +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. The private key behind that address ` +\n 'is public knowledge, so any revenue settled to it is immediately spendable by anyone. Set ' +\n '\"payTo\" to your own merchant wallet for any non-local RPC, or point rpcUrl at your ' +\n 'local/dev chain.',\n );\n }\n}\n","/**\n * What must hold before this gateway may settle a payment on the configured\n * network. Two callers share these checks: the provider runs them at\n * construction, so a library consumer who skips our config loader still gets\n * them, and the config loader runs them, so `validate` and `doctor` report\n * them too.\n *\n * Both run before any request, because a failure found in `settle()` would\n * come after the pipeline reserved the buyer's replay key.\n *\n * Imports no peer (no viem, no `@x402/*`), so the CLI can load it.\n */\nimport { CommerceError } from '../../core';\nimport { isBurnAddress, sameAddress } from './addresses';\nimport { isLikelyLocalOrPrivateHost, isWellKnownDevAddress } from './dev-key-guard';\nimport {\n type CustomNetworks,\n type DeploymentMode,\n LOCAL_CHAIN_ID,\n requireX402Network,\n resolveDeploymentMode,\n type X402Network,\n} from './networks';\n\n/**\n * How the gateway authenticates to a remote facilitator.\n *\n * - `none`: send no credential; use it when the facilitator accepts\n * anonymous requests.\n * - `bearer`: send a static token; no extra peer package is needed.\n * - `cdp`: Coinbase Developer Platform. The optional peer `@coinbase/x402`,\n * imported only for this type, signs a fresh JWT per request.\n *\n * Any other auth type is refused at config load.\n */\nexport type FacilitatorAuth =\n | { readonly type: 'none' }\n | { readonly type: 'bearer'; readonly token: string }\n | { readonly type: 'cdp'; readonly apiKeyId: string; readonly apiKeySecret: string };\n\nexport type X402FacilitatorConfig =\n | { readonly mode: 'local'; readonly signerPrivateKey: string }\n | { readonly mode: 'remote'; readonly url: string; readonly auth: FacilitatorAuth };\n\nexport interface X402DeploymentInput {\n readonly network: string;\n readonly payTo: string;\n readonly asset: string;\n /** EIP-712 domain of the asset, as the token itself reports it */\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet */\n readonly allowMainnet?: boolean;\n /**\n * Must be `true` on mainnet when facilitator auth is `none`. A separate\n * decision from `allowMainnet`: it accepts settling without an account at\n * the facilitator, under its anonymous-access limits.\n */\n readonly allowUnauthenticatedFacilitator?: boolean;\n /**\n * Allow other tokens on built-in EVM networks with explicit metadata.\n * MPP config leaves this unset; Solana and NEAR still require USDC.\n */\n readonly allowOtherEvmToken?: boolean;\n /** Error-path prefix, `payments.x402` by default */\n readonly configPath?: string;\n /** Settlement-recipient field named in errors, `payTo` by default */\n readonly payToField?: string;\n /** EVM networks declared under `payments.x402.networks` */\n readonly customNetworks?: CustomNetworks;\n}\n\nexport interface X402Deployment {\n readonly profile: X402Network;\n readonly mode: DeploymentMode;\n}\n\nconst BASE_SEPOLIA = 'eip155:84532';\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\n/**\n * Resolves the deployment and refuses the combinations that could move real\n * money by accident. The network must resolve first; the other checks are\n * independent.\n */\nexport function resolveX402Deployment(input: X402DeploymentInput): X402Deployment {\n const at = input.configPath ?? 'payments.x402';\n const payTo = input.payToField ?? 'payTo';\n const profile = requireX402Network(input.network, `${at}.network`, input.customNetworks);\n const mode = resolveDeploymentMode(profile);\n\n // Local mode keeps a gas-paying key in the gateway process. A compromise\n // could expose that key, so mainnet requires a remote facilitator.\n if (profile.kind === 'mainnet' && input.facilitator.mode === 'local') {\n throw invalid(\n `${at}: network \"${profile.id}\" (${profile.displayName}) is a mainnet and cannot be served by facilitator.mode \"local\". A mainnet deployment must settle through a remote facilitator.`,\n `${at}.facilitator.mode`,\n );\n }\n // The in-process facilitator signs with a client built for the Anvil chain\n // id, so on any other chain every settlement would fail\n if (input.facilitator.mode === 'local' && mode !== 'local') {\n throw invalid(\n profile.id === BASE_SEPOLIA\n ? `${at}: the local Anvil chain is eip155:${LOCAL_CHAIN_ID}, Anvil's default chain id; \"${BASE_SEPOLIA}\" is public Base Sepolia. Set ${at}.network to eip155:${LOCAL_CHAIN_ID}, start Anvil with its default chain id and redeploy the local contracts (npm run chain:start, npm run chain:deploy).`\n : `${at}: facilitator.mode \"local\" serves the local Anvil chain (eip155:${LOCAL_CHAIN_ID}) only, not \"${profile.id}\" (${profile.displayName}). Use a remote facilitator.`,\n `${at}.facilitator.mode`,\n );\n }\n\n if (mode === 'mainnet' && input.allowMainnet !== true) {\n throw invalid(\n `${at}: network \"${profile.id}\" (${profile.displayName}) settles real funds. Set ${at}.allowMainnet: true to acknowledge this explicitly - it is never the default.`,\n `${at}.allowMainnet`,\n );\n }\n\n if (input.facilitator.mode === 'remote') {\n assertFacilitatorUrlIsSafe(input.facilitator.url, mode, at);\n // `@coinbase/x402` signs each request for CDP's own host and route,\n // whatever URL is configured, so no other facilitator can accept the credential\n if (input.facilitator.auth.type === 'cdp' && !isCdpFacilitatorUrl(input.facilitator.url)) {\n throw invalid(\n `${at}: facilitator.auth.type \"cdp\" signs requests for ${CDP_FACILITATOR_URL} only, so facilitator ${describeOrigin(input.facilitator.url)} cannot accept its credential. Set facilitator.url to ${CDP_FACILITATOR_URL}, or use auth.type \"bearer\" or \"none\".`,\n `${at}.facilitator.url`,\n );\n }\n // The authorization fixes recipient, amount and chain, so a facilitator\n // cannot redirect funds. A credential adds an account: rate limits, terms\n // and support. On mainnet, going without one is an explicit choice.\n if (\n mode === 'mainnet' &&\n input.facilitator.auth.type === 'none' &&\n input.allowUnauthenticatedFacilitator !== true\n ) {\n throw invalid(\n `${at}: no credential is configured for facilitator ${describeOrigin(input.facilitator.url)} on mainnet. Set ${at}.allowUnauthenticatedFacilitator: true to accept anonymous access and the facilitator's limits, or configure facilitator.auth.`,\n `${at}.allowUnauthenticatedFacilitator`,\n );\n }\n // A blank credential reaches the facilitator as \"unauthenticated\" and fails\n // every payment after the buyer signed. `${VAR:- }` resolving to whitespace\n // is the usual cause.\n for (const [field, value] of credentialFields(input.facilitator.auth)) {\n if (value.trim() === '') {\n throw invalid(\n `${at}: facilitator.auth.type is \"${input.facilitator.auth.type}\" but ${field} is empty. An empty credential is refused rather than sent.`,\n `${at}.facilitator.auth.${field}`,\n );\n }\n }\n }\n\n // The config loader's address check refuses this too; repeated here for a\n // library consumer who calls `createX402PaymentProvider` without it\n if (isBurnAddress(profile, input.payTo)) {\n throw invalid(\n `${at}: \"${payTo}\" is the zero address. Every payment settled there is destroyed.`,\n `${at}.${payTo}`,\n );\n }\n\n // Anyone can spend from a well-known Anvil address. `dev-key-guard` refuses\n // one behind a public RPC; this refuses one on any non-local deployment,\n // whose RPC host says nothing about where a remote facilitator settles.\n if (mode !== 'local' && isWellKnownDevAddress(input.payTo)) {\n throw invalid(\n `${at}: \"${payTo}\" (${input.payTo}) is a well-known Anvil development address and this is a ${mode} deployment. Anyone can spend what settles there. Set ${payTo} to your own merchant wallet.`,\n `${at}.${payTo}`,\n );\n }\n\n // Public built-ins require USDC unless the caller allows another EVM token.\n // Local and declared networks have no default asset.\n const canonical = profile.canonicalAsset;\n if (canonical) {\n if (!sameAddress(profile, input.asset, canonical.address)) {\n if (input.allowOtherEvmToken !== true || profile.family !== 'evm') {\n const rule =\n input.allowOtherEvmToken === true\n ? `Only an EVM network accepts another token; ${profile.displayName} settles only in its ${canonical.symbol}.`\n : `A built-in network settles only in its ${canonical.symbol}.`;\n throw invalid(\n `${at}: asset ${input.asset} is not ${canonical.symbol} on ${profile.displayName} (expected ${canonical.address}). ${rule}`,\n `${at}.asset`,\n );\n }\n } else {\n // Catch USDC domain mismatches before accepting payments; a wrong name\n // can fail with `invalid_exact_evm_token_name_mismatch`\n const domain = 'name' in canonical ? canonical : undefined;\n if (domain && input.assetName !== undefined && input.assetName !== domain.name) {\n throw invalid(\n `${at}: assetName \"${input.assetName}\" is not the EIP-712 domain name ${canonical.symbol} reports on ${profile.displayName} (expected \"${domain.name}\"). Every payment would be refused after the buyer signed.`,\n `${at}.assetName`,\n );\n }\n if (domain && input.assetVersion !== undefined && input.assetVersion !== domain.version) {\n throw invalid(\n `${at}: assetVersion \"${input.assetVersion}\" is not the EIP-712 domain version ${canonical.symbol} reports on ${profile.displayName} (expected \"${domain.version}\").`,\n `${at}.assetVersion`,\n );\n }\n }\n }\n\n return { profile, mode };\n}\n\n/**\n * A facilitator sees every payment authorization this gateway handles. Plain\n * HTTP puts those on the wire in the clear and lets anyone in the path rewrite\n * a settlement result, so it is allowed only to a local or private host, and\n * never on a mainnet.\n */\nfunction assertFacilitatorUrlIsSafe(url: string, mode: DeploymentMode, at: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch (cause) {\n throw new CommerceError('CONFIG_INVALID', `${at}: facilitator.url is not a valid URL`, {\n cause,\n details: { path: `${at}.facilitator.url` },\n });\n }\n\n if (parsed.protocol === 'https:') return;\n if (parsed.protocol !== 'http:') {\n throw invalid(\n `${at}: facilitator ${describeOrigin(url)} must be reached over https (or http on a local/private host); got \"${parsed.protocol}//\"`,\n `${at}.facilitator.url`,\n );\n }\n if (mode !== 'mainnet' && isLikelyLocalOrPrivateHost(parsed.hostname)) return;\n\n // The origin, never the whole URL: the path can carry a tenant or an API\n // key, and this message reaches `validate`, `doctor`, startup output and CI logs\n throw invalid(\n `${at}: facilitator ${describeOrigin(url)} is reached over plain HTTP. Payment authorizations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,\n `${at}.facilitator.url`,\n );\n}\n\n/** The facilitator URL `@coinbase/x402` signs its JWTs for */\nexport const CDP_FACILITATOR_URL = 'https://api.cdp.coinbase.com/platform/v2/x402';\n\n// The SDK client strips trailing slashes before appending its route\nfunction isCdpFacilitatorUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const expected = new URL(CDP_FACILITATOR_URL);\n return (\n parsed.origin === expected.origin &&\n parsed.pathname.replace(/\\/+$/, '') === expected.pathname &&\n parsed.search === ''\n );\n } catch {\n return false;\n }\n}\n\n// Origin only: a facilitator URL can carry a tenant path or an API key\nfunction describeOrigin(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return '[unparseable facilitator.url]';\n }\n}\n\n// The secret-bearing fields of an auth block, for emptiness checks only. Never logged\nfunction credentialFields(auth: FacilitatorAuth): readonly (readonly [string, string])[] {\n switch (auth.type) {\n case 'bearer':\n return [['token', auth.token]];\n case 'cdp':\n return [\n ['apiKeyId', auth.apiKeyId],\n ['apiKeySecret', auth.apiKeySecret],\n ];\n default:\n return [];\n }\n}\n","/**\n * Resolves an x402 option into offer terms at config load, so `validate`\n * reports invalid options before startup. This module uses no SDK.\n *\n * Omitted assets use `canonicalAsset`. Overrides for the default token must\n * match its metadata; another token needs its own, including the EIP-712 domain\n * on EVM.\n */\nimport { CommerceError } from '../../core';\nimport { isBurnAddress, normalizeAddress, sameAddress } from './addresses';\nimport { type CustomNetworks, requireX402Network, type X402Network } from './networks';\n\nexport interface X402OptionInput {\n readonly scheme?: string;\n readonly network: string;\n readonly payTo: string;\n readonly asset?: string;\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly assetDecimals?: number;\n /** `eip3009` (the default) or `permit2`; EVM only */\n readonly assetTransferMethod?: string;\n}\n\nexport interface ResolvedX402Option {\n readonly scheme: 'exact';\n readonly network: X402Network;\n readonly payTo: string;\n readonly asset: string;\n /** EIP-712 domain; EVM only */\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly assetDecimals: number;\n /**\n * Default token symbol when `asset` is omitted; resource prices must use\n * this symbol or USD\n */\n readonly defaultAssetSymbol?: string;\n /** How the buyer authorizes the transfer; always `eip3009` off EVM */\n readonly assetTransferMethod: X402AssetTransferMethod;\n}\n\n/**\n * Names health components by network, asset and payee for discovery matching.\n * Lowercase EVM addresses so case variants identify the same offer.\n */\nexport function x402OfferName(offer: {\n readonly network: string;\n readonly asset: string;\n readonly payTo: string;\n}): string {\n const evm = offer.network.startsWith('eip155:');\n const address = (value: string) => (evm ? value.toLowerCase() : value);\n return `${offer.network} ${address(offer.asset)} ${address(offer.payTo)}`;\n}\n\n/** EIP-3009 `transferWithAuthorization`, or Permit2 with a prior token allowance */\nexport type X402AssetTransferMethod = 'eip3009' | 'permit2';\n\n// Incorrect EIP-712 domain values invalidate the buyer's signature\nconst FIELD_MEANINGS = {\n assetName: 'EIP-712 domain name',\n assetVersion: 'EIP-712 domain version',\n assetDecimals: 'decimals',\n} as const;\n\nconst ADDRESS_SHAPES = {\n evm: '\"0x\" followed by 40 hex characters',\n svm: 'a base58 public key of 32 bytes',\n near: 'a NEAR account ID: 2 to 64 lowercase characters, digits and single \"-\", \"_\" or \".\" separators',\n} as const;\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\nexport function resolveX402Option(\n input: X402OptionInput,\n path: string,\n custom?: CustomNetworks,\n): ResolvedX402Option {\n if (input.scheme !== undefined && input.scheme !== 'exact') {\n throw invalid(\n `${path}.scheme: \"${input.scheme}\" is not supported; the only x402 scheme is \"exact\"`,\n `${path}.scheme`,\n );\n }\n const network = requireX402Network(input.network, `${path}.network`, custom);\n const address = (field: 'payTo' | 'asset', value: string): string => {\n const wire = normalizeAddress(network, value);\n if (wire === undefined) {\n throw invalid(\n // The value is not echoed: a swapped variable could put a key here\n `${path}.${field} is not a plausible address on ${network.displayName} (expected ${ADDRESS_SHAPES[network.family]})`,\n `${path}.${field}`,\n );\n }\n return wire;\n };\n\n const payTo = address('payTo', input.payTo);\n if (isBurnAddress(network, payTo)) {\n throw invalid(\n `${path}.payTo is the zero address of ${network.displayName}. Every payment settled there is destroyed.`,\n `${path}.payTo`,\n );\n }\n\n const method = input.assetTransferMethod ?? 'eip3009';\n if (method !== 'eip3009' && method !== 'permit2') {\n throw invalid(\n `${path}.assetTransferMethod: \"${method}\" is not supported; use \"eip3009\" or \"permit2\"`,\n `${path}.assetTransferMethod`,\n );\n }\n if (network.family !== 'evm' && input.assetTransferMethod !== undefined) {\n throw invalid(\n `${path}.assetTransferMethod applies to EVM networks only, not to ${network.displayName}`,\n `${path}.assetTransferMethod`,\n );\n }\n\n if (network.family !== 'evm') {\n for (const field of ['assetName', 'assetVersion'] as const) {\n if (input[field] !== undefined) {\n throw invalid(\n `${path}.${field}: an EIP-712 domain applies to EVM tokens only, not to ${network.displayName}`,\n `${path}.${field}`,\n );\n }\n }\n }\n\n const canonical = network.canonicalAsset;\n const domain = canonical && 'name' in canonical ? canonical : undefined;\n\n const asset = input.asset !== undefined ? address('asset', input.asset) : undefined;\n if (asset !== undefined && isBurnAddress(network, asset)) {\n throw invalid(`${path}.asset must not be the zero address`, `${path}.asset`);\n }\n\n // The default asset applies when the option names none or names it exactly\n if (canonical && (asset === undefined || sameAddress(network, asset, canonical.address))) {\n const expected = {\n assetName: domain?.name,\n assetVersion: domain?.version,\n assetDecimals: canonical.decimals,\n };\n for (const field of ['assetName', 'assetVersion', 'assetDecimals'] as const) {\n const given = input[field];\n if (given !== undefined && given !== expected[field]) {\n throw invalid(\n `${path}.${field} does not match ${canonical.symbol} on ${network.displayName}, which reports ${FIELD_MEANINGS[field]} ${JSON.stringify(expected[field])}. Remove ${field}, or set asset to the token it describes.`,\n `${path}.${field}`,\n );\n }\n }\n return {\n scheme: 'exact',\n network,\n payTo,\n asset: asset ?? canonical.address,\n ...(domain ? { assetName: domain.name, assetVersion: domain.version } : {}),\n assetDecimals: canonical.decimals,\n defaultAssetSymbol: canonical.symbol,\n assetTransferMethod: method,\n };\n }\n\n // Another token: nothing about it can be borrowed from the default. The\n // token's EIP-712 domain matters to EIP-3009 only: a Permit2 buyer signs\n // Permit2's own domain.\n const required =\n network.family === 'evm' && method === 'eip3009'\n ? (['asset', 'assetName', 'assetVersion', 'assetDecimals'] as const)\n : (['asset', 'assetDecimals'] as const);\n const missing = required.filter((field) => input[field] === undefined);\n if (asset === undefined || missing.length > 0) {\n throw invalid(\n canonical\n ? `${path}: a token other than ${canonical.symbol} on ${network.displayName} needs ${missing.join(', ')}`\n : `${path}: ${network.displayName} has no default asset, so the option needs ${missing.join(', ')}`,\n `${path}.${missing[0] ?? 'asset'}`,\n );\n }\n return {\n scheme: 'exact',\n network,\n payTo,\n asset,\n ...(input.assetName !== undefined ? { assetName: input.assetName } : {}),\n ...(input.assetVersion !== undefined ? { assetVersion: input.assetVersion } : {}),\n assetDecimals: input.assetDecimals as number,\n assetTransferMethod: method,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/payments/x402/dev-key-guard.ts","../../src/payments/x402/guardrails.ts","../../src/payments/x402/options.ts"],"names":["invalid"],"mappings":"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","file":"chunk-4H2QLHQI.js","sourcesContent":["/**\n * Rejects well-known Anvil keys and payment destinations when the RPC host\n * does not look local or private. Their private keys are published, so anyone\n * can spend what such an address receives on a public chain.\n *\n * The check uses the RPC hostname because the local chain shares Base\n * Sepolia's chain id. Both guards run at provider construction.\n */\nimport { CommerceError } from '../../core';\nimport { ANVIL_WELL_KNOWN_ACCOUNTS } from './local-chain/accounts';\n\nconst WELL_KNOWN_DEV_KEYS: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.privateKey.toLowerCase()),\n);\n\nconst WELL_KNOWN_DEV_ADDRESSES: ReadonlySet<string> = new Set(\n ANVIL_WELL_KNOWN_ACCOUNTS.map((a) => a.address.toLowerCase()),\n);\n\n// `0x` plus 64 hex characters, the only shape `privateKeyToAccount` accepts\nconst PRIVATE_KEY_SHAPE = /^0x[0-9a-fA-F]{64}$/;\n\nexport function isWellKnownDevKey(privateKey: string): boolean {\n return WELL_KNOWN_DEV_KEYS.has(privateKey.toLowerCase());\n}\n\nexport function isWellKnownDevAddress(address: string): boolean {\n return WELL_KNOWN_DEV_ADDRESSES.has(address.toLowerCase());\n}\n\n/**\n * True for loopback addresses, RFC 1918 private ranges, and bare (dot-free)\n * hostnames, such as the compose service name \"anvil\".\n *\n * Bare hostnames are treated as local without resolving them. Operators must\n * point them at a private chain.\n */\nexport function isLikelyLocalOrPrivateHost(hostname: string): boolean {\n const h = hostname.toLowerCase().replace(/^\\[|\\]$/g, '');\n if (h === 'localhost' || h === '::1') return true;\n if (/^127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^192\\.168\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (/^172\\.(1[6-9]|2\\d|3[01])\\.\\d{1,3}\\.\\d{1,3}$/.test(h)) return true;\n if (!h.includes('.') && !h.includes(':')) return true; // bare hostname\n return false;\n}\n\nfunction parseHostnameOrThrow(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).hostname;\n } catch (cause) {\n // Never the URL itself: RPC providers commonly put an API key in the path,\n // and this message reaches startup output and CI logs\n throw new CommerceError('CONFIG_INVALID', 'x402 provider: rpcUrl is not a valid URL', {\n cause,\n });\n }\n}\n\n/** Origin only, for diagnostics: RPC URLs often carry an API key in the path or query */\nexport function describeRpc(rpcUrl: string): string {\n try {\n return new URL(rpcUrl).origin;\n } catch {\n return '[unparseable rpcUrl]';\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `signerPrivateKey` is not shaped like a private key,\n * or if it is a well-known dev key and the RPC is not local.\n *\n * The shape check runs first, so a truncated key is reported as malformed\n * instead of passing as \"not a dev key\".\n */\nexport function assertDevKeyIsLocalOnly(rpcUrl: string, signerPrivateKey: string): void {\n if (!PRIVATE_KEY_SHAPE.test(signerPrivateKey)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is not a well-formed private key ' +\n '(expected \"0x\" followed by exactly 64 hex characters).',\n );\n }\n\n if (!isWellKnownDevKey(signerPrivateKey)) return; // the operator's own key\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.signerPrivateKey is a well-known Anvil development key, but rpcUrl ' +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. A public dev key must never sign against ` +\n 'a public network: it is instantly drainable and can grief real settlements via nonce exhaustion. ' +\n 'Use a real facilitator key for any non-local RPC, or point rpcUrl at your local/dev chain.',\n );\n }\n}\n\n/**\n * Throws CONFIG_INVALID if `payTo` is a well-known Anvil address and `rpcUrl`\n * does not look local or private.\n *\n * Guards the receiving side, in every facilitator mode. `agent-commerce init`\n * defaults `payTo` to a well-known address for the local demo, and on a real\n * network that default sends every payment where anyone can sweep it.\n */\nexport function assertPayToIsNotDevAddress(rpcUrl: string, payTo: string): void {\n if (!isWellKnownDevAddress(payTo)) return;\n\n const hostname = parseHostnameOrThrow(rpcUrl);\n\n if (!isLikelyLocalOrPrivateHost(hostname)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" (${payTo}) is a well-known Anvil development address, but rpcUrl ` +\n `${describeRpc(rpcUrl)} does not look like a local/private chain. The private key behind that address ` +\n 'is public knowledge, so any revenue settled to it is immediately spendable by anyone. Set ' +\n '\"payTo\" to your own merchant wallet for any non-local RPC, or point rpcUrl at your ' +\n 'local/dev chain.',\n );\n }\n}\n","/**\n * What must hold before this gateway may settle a payment on the configured\n * network. Two callers share these checks: the provider runs them at\n * construction, so a library consumer who skips our config loader still gets\n * them, and the config loader runs them, so `validate` and `doctor` report\n * them too.\n *\n * Both run before any request, because a failure found in `settle()` would\n * come after the pipeline reserved the buyer's replay key.\n *\n * Imports no peer (no viem, no `@x402/*`), so the CLI can load it.\n */\nimport { CommerceError } from '../../core';\nimport { isBurnAddress, sameAddress } from './addresses';\nimport { isLikelyLocalOrPrivateHost, isWellKnownDevAddress } from './dev-key-guard';\nimport {\n type CustomNetworks,\n type DeploymentMode,\n LOCAL_CHAIN_ID,\n requireX402Network,\n resolveDeploymentMode,\n type X402Network,\n} from './networks';\n\n/**\n * How the gateway authenticates to a remote facilitator.\n *\n * - `none`: send no credential; use it when the facilitator accepts\n * anonymous requests.\n * - `bearer`: send a static token; no extra peer package is needed.\n * - `cdp`: Coinbase Developer Platform. The optional peer `@coinbase/x402`,\n * imported only for this type, signs a fresh JWT per request.\n *\n * Any other auth type is refused at config load.\n */\nexport type FacilitatorAuth =\n | { readonly type: 'none' }\n | { readonly type: 'bearer'; readonly token: string }\n | { readonly type: 'cdp'; readonly apiKeyId: string; readonly apiKeySecret: string };\n\nexport type X402FacilitatorConfig =\n | { readonly mode: 'local'; readonly signerPrivateKey: string }\n | { readonly mode: 'remote'; readonly url: string; readonly auth: FacilitatorAuth };\n\nexport interface X402DeploymentInput {\n readonly network: string;\n readonly payTo: string;\n readonly asset: string;\n /** EIP-712 domain of the asset, as the token itself reports it */\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet */\n readonly allowMainnet?: boolean;\n /**\n * Must be `true` on mainnet when facilitator auth is `none`. A separate\n * decision from `allowMainnet`: it accepts settling without an account at\n * the facilitator, under its anonymous-access limits.\n */\n readonly allowUnauthenticatedFacilitator?: boolean;\n /**\n * Allow other tokens on built-in EVM networks with explicit metadata.\n * MPP config leaves this unset; Solana and NEAR still require USDC.\n */\n readonly allowOtherEvmToken?: boolean;\n /** Error-path prefix, `payments.x402` by default */\n readonly configPath?: string;\n /** Settlement-recipient field named in errors, `payTo` by default */\n readonly payToField?: string;\n /** EVM networks declared under `payments.x402.networks` */\n readonly customNetworks?: CustomNetworks;\n}\n\nexport interface X402Deployment {\n readonly profile: X402Network;\n readonly mode: DeploymentMode;\n}\n\nconst BASE_SEPOLIA = 'eip155:84532';\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\n/**\n * Resolves the deployment and refuses the combinations that could move real\n * money by accident. The network must resolve first; the other checks are\n * independent.\n */\nexport function resolveX402Deployment(input: X402DeploymentInput): X402Deployment {\n const at = input.configPath ?? 'payments.x402';\n const payTo = input.payToField ?? 'payTo';\n const profile = requireX402Network(input.network, `${at}.network`, input.customNetworks);\n const mode = resolveDeploymentMode(profile);\n\n // Local mode keeps a gas-paying key in the gateway process. A compromise\n // could expose that key, so mainnet requires a remote facilitator.\n if (profile.kind === 'mainnet' && input.facilitator.mode === 'local') {\n throw invalid(\n `${at}: network \"${profile.id}\" (${profile.displayName}) is a mainnet and cannot be served by facilitator.mode \"local\". A mainnet deployment must settle through a remote facilitator.`,\n `${at}.facilitator.mode`,\n );\n }\n // The in-process facilitator signs with a client built for the Anvil chain\n // id, so on any other chain every settlement would fail\n if (input.facilitator.mode === 'local' && mode !== 'local') {\n throw invalid(\n profile.id === BASE_SEPOLIA\n ? `${at}: the local Anvil chain is eip155:${LOCAL_CHAIN_ID}, Anvil's default chain id; \"${BASE_SEPOLIA}\" is public Base Sepolia. Set ${at}.network to eip155:${LOCAL_CHAIN_ID}, start Anvil with its default chain id and redeploy the local contracts (npm run chain:start, npm run chain:deploy).`\n : `${at}: facilitator.mode \"local\" serves the local Anvil chain (eip155:${LOCAL_CHAIN_ID}) only, not \"${profile.id}\" (${profile.displayName}). Use a remote facilitator.`,\n `${at}.facilitator.mode`,\n );\n }\n\n if (mode === 'mainnet' && input.allowMainnet !== true) {\n throw invalid(\n `${at}: network \"${profile.id}\" (${profile.displayName}) settles real funds. Set ${at}.allowMainnet: true to acknowledge this explicitly - it is never the default.`,\n `${at}.allowMainnet`,\n );\n }\n\n if (input.facilitator.mode === 'remote') {\n assertFacilitatorUrlIsSafe(input.facilitator.url, mode, at);\n // `@coinbase/x402` signs each request for CDP's own host and route,\n // whatever URL is configured, so no other facilitator can accept the credential\n if (input.facilitator.auth.type === 'cdp' && !isCdpFacilitatorUrl(input.facilitator.url)) {\n throw invalid(\n `${at}: facilitator.auth.type \"cdp\" signs requests for ${CDP_FACILITATOR_URL} only, so facilitator ${describeOrigin(input.facilitator.url)} cannot accept its credential. Set facilitator.url to ${CDP_FACILITATOR_URL}, or use auth.type \"bearer\" or \"none\".`,\n `${at}.facilitator.url`,\n );\n }\n // The authorization fixes recipient, amount and chain, so a facilitator\n // cannot redirect funds. A credential adds an account: rate limits, terms\n // and support. On mainnet, going without one is an explicit choice.\n if (\n mode === 'mainnet' &&\n input.facilitator.auth.type === 'none' &&\n input.allowUnauthenticatedFacilitator !== true\n ) {\n throw invalid(\n `${at}: no credential is configured for facilitator ${describeOrigin(input.facilitator.url)} on mainnet. Set ${at}.allowUnauthenticatedFacilitator: true to accept anonymous access and the facilitator's limits, or configure facilitator.auth.`,\n `${at}.allowUnauthenticatedFacilitator`,\n );\n }\n // A blank credential reaches the facilitator as \"unauthenticated\" and fails\n // every payment after the buyer signed. `${VAR:- }` resolving to whitespace\n // is the usual cause.\n for (const [field, value] of credentialFields(input.facilitator.auth)) {\n if (value.trim() === '') {\n throw invalid(\n `${at}: facilitator.auth.type is \"${input.facilitator.auth.type}\" but ${field} is empty. An empty credential is refused rather than sent.`,\n `${at}.facilitator.auth.${field}`,\n );\n }\n }\n }\n\n // The config loader's address check refuses this too; repeated here for a\n // library consumer who calls `createX402PaymentProvider` without it\n if (isBurnAddress(profile, input.payTo)) {\n throw invalid(\n `${at}: \"${payTo}\" is the zero address. Every payment settled there is destroyed.`,\n `${at}.${payTo}`,\n );\n }\n\n // Anyone can spend from a well-known Anvil address. `dev-key-guard` refuses\n // one behind a public RPC; this refuses one on any non-local deployment,\n // whose RPC host says nothing about where a remote facilitator settles.\n if (mode !== 'local' && isWellKnownDevAddress(input.payTo)) {\n throw invalid(\n `${at}: \"${payTo}\" (${input.payTo}) is a well-known Anvil development address and this is a ${mode} deployment. Anyone can spend what settles there. Set ${payTo} to your own merchant wallet.`,\n `${at}.${payTo}`,\n );\n }\n\n // Public built-ins require USDC unless the caller allows another EVM token.\n // Local and declared networks have no default asset.\n const canonical = profile.canonicalAsset;\n if (canonical) {\n if (!sameAddress(profile, input.asset, canonical.address)) {\n if (input.allowOtherEvmToken !== true || profile.family !== 'evm') {\n const rule =\n input.allowOtherEvmToken === true\n ? `Only an EVM network accepts another token; ${profile.displayName} settles only in its ${canonical.symbol}.`\n : `A built-in network settles only in its ${canonical.symbol}.`;\n throw invalid(\n `${at}: asset ${input.asset} is not ${canonical.symbol} on ${profile.displayName} (expected ${canonical.address}). ${rule}`,\n `${at}.asset`,\n );\n }\n } else {\n // Catch USDC domain mismatches before accepting payments; a wrong name\n // can fail with `invalid_exact_evm_token_name_mismatch`\n const domain = 'name' in canonical ? canonical : undefined;\n if (domain && input.assetName !== undefined && input.assetName !== domain.name) {\n throw invalid(\n `${at}: assetName \"${input.assetName}\" is not the EIP-712 domain name ${canonical.symbol} reports on ${profile.displayName} (expected \"${domain.name}\"). Every payment would be refused after the buyer signed.`,\n `${at}.assetName`,\n );\n }\n if (domain && input.assetVersion !== undefined && input.assetVersion !== domain.version) {\n throw invalid(\n `${at}: assetVersion \"${input.assetVersion}\" is not the EIP-712 domain version ${canonical.symbol} reports on ${profile.displayName} (expected \"${domain.version}\").`,\n `${at}.assetVersion`,\n );\n }\n }\n }\n\n return { profile, mode };\n}\n\n/**\n * A facilitator sees every payment authorization this gateway handles. Plain\n * HTTP puts those on the wire in the clear and lets anyone in the path rewrite\n * a settlement result, so it is allowed only to a local or private host, and\n * never on a mainnet.\n */\nfunction assertFacilitatorUrlIsSafe(url: string, mode: DeploymentMode, at: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch (cause) {\n throw new CommerceError('CONFIG_INVALID', `${at}: facilitator.url is not a valid URL`, {\n cause,\n details: { path: `${at}.facilitator.url` },\n });\n }\n\n if (parsed.protocol === 'https:') return;\n if (parsed.protocol !== 'http:') {\n throw invalid(\n `${at}: facilitator ${describeOrigin(url)} must be reached over https (or http on a local/private host); got \"${parsed.protocol}//\"`,\n `${at}.facilitator.url`,\n );\n }\n if (mode !== 'mainnet' && isLikelyLocalOrPrivateHost(parsed.hostname)) return;\n\n // The origin, never the whole URL: the path can carry a tenant or an API\n // key, and this message reaches `validate`, `doctor`, startup output and CI logs\n throw invalid(\n `${at}: facilitator ${describeOrigin(url)} is reached over plain HTTP. Payment authorizations and settlement results would travel unencrypted. Use https, or point at a local/private host on a non-mainnet deployment.`,\n `${at}.facilitator.url`,\n );\n}\n\n/** The facilitator URL `@coinbase/x402` signs its JWTs for */\nexport const CDP_FACILITATOR_URL = 'https://api.cdp.coinbase.com/platform/v2/x402';\n\n// The SDK client strips trailing slashes before appending its route\nfunction isCdpFacilitatorUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const expected = new URL(CDP_FACILITATOR_URL);\n return (\n parsed.origin === expected.origin &&\n parsed.pathname.replace(/\\/+$/, '') === expected.pathname &&\n parsed.search === ''\n );\n } catch {\n return false;\n }\n}\n\n// Origin only: a facilitator URL can carry a tenant path or an API key\nfunction describeOrigin(url: string): string {\n try {\n return new URL(url).origin;\n } catch {\n return '[unparseable facilitator.url]';\n }\n}\n\n// The secret-bearing fields of an auth block, for emptiness checks only. Never logged\nfunction credentialFields(auth: FacilitatorAuth): readonly (readonly [string, string])[] {\n switch (auth.type) {\n case 'bearer':\n return [['token', auth.token]];\n case 'cdp':\n return [\n ['apiKeyId', auth.apiKeyId],\n ['apiKeySecret', auth.apiKeySecret],\n ];\n default:\n return [];\n }\n}\n","/**\n * Resolves an x402 option into offer terms at config load, so `validate`\n * reports invalid options before startup. This module uses no SDK.\n *\n * Omitted assets use `canonicalAsset`. Overrides for the default token must\n * match its metadata; another token needs its own, including the EIP-712 domain\n * on EVM.\n */\nimport { CommerceError } from '../../core';\nimport { isBurnAddress, normalizeAddress, sameAddress } from './addresses';\nimport { type CustomNetworks, requireX402Network, type X402Network } from './networks';\n\nexport interface X402OptionInput {\n readonly scheme?: string;\n readonly network: string;\n readonly payTo: string;\n readonly asset?: string;\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly assetDecimals?: number;\n /** `eip3009` (the default) or `permit2`; EVM only */\n readonly assetTransferMethod?: string;\n}\n\nexport interface ResolvedX402Option {\n readonly scheme: 'exact';\n readonly network: X402Network;\n readonly payTo: string;\n readonly asset: string;\n /** EIP-712 domain; EVM only */\n readonly assetName?: string;\n readonly assetVersion?: string;\n readonly assetDecimals: number;\n /**\n * Default token symbol when `asset` is omitted; resource prices must use\n * this symbol or USD\n */\n readonly defaultAssetSymbol?: string;\n /** How the buyer authorizes the transfer; always `eip3009` off EVM */\n readonly assetTransferMethod: X402AssetTransferMethod;\n}\n\n/**\n * Names health components by network, asset and payee for discovery matching.\n * Lowercase EVM addresses so case variants identify the same offer.\n */\nexport function x402OfferName(offer: {\n readonly network: string;\n readonly asset: string;\n readonly payTo: string;\n}): string {\n const evm = offer.network.startsWith('eip155:');\n const address = (value: string) => (evm ? value.toLowerCase() : value);\n return `${offer.network} ${address(offer.asset)} ${address(offer.payTo)}`;\n}\n\n/** EIP-3009 `transferWithAuthorization`, or Permit2 with a prior token allowance */\nexport type X402AssetTransferMethod = 'eip3009' | 'permit2';\n\n// Incorrect EIP-712 domain values invalidate the buyer's signature\nconst FIELD_MEANINGS = {\n assetName: 'EIP-712 domain name',\n assetVersion: 'EIP-712 domain version',\n assetDecimals: 'decimals',\n} as const;\n\nconst ADDRESS_SHAPES = {\n evm: '\"0x\" followed by 40 hex characters',\n svm: 'a base58 public key of 32 bytes',\n near: 'a NEAR account ID: 2 to 64 lowercase characters, digits and single \"-\", \"_\" or \".\" separators',\n} as const;\n\nfunction invalid(message: string, path: string): CommerceError {\n return new CommerceError('CONFIG_INVALID', message, { details: { path } });\n}\n\nexport function resolveX402Option(\n input: X402OptionInput,\n path: string,\n custom?: CustomNetworks,\n): ResolvedX402Option {\n if (input.scheme !== undefined && input.scheme !== 'exact') {\n throw invalid(\n `${path}.scheme: \"${input.scheme}\" is not supported; the only x402 scheme is \"exact\"`,\n `${path}.scheme`,\n );\n }\n const network = requireX402Network(input.network, `${path}.network`, custom);\n const address = (field: 'payTo' | 'asset', value: string): string => {\n const wire = normalizeAddress(network, value);\n if (wire === undefined) {\n throw invalid(\n // The value is not echoed: a swapped variable could put a key here\n `${path}.${field} is not a plausible address on ${network.displayName} (expected ${ADDRESS_SHAPES[network.family]})`,\n `${path}.${field}`,\n );\n }\n return wire;\n };\n\n const payTo = address('payTo', input.payTo);\n if (isBurnAddress(network, payTo)) {\n throw invalid(\n `${path}.payTo is the zero address of ${network.displayName}. Every payment settled there is destroyed.`,\n `${path}.payTo`,\n );\n }\n\n const method = input.assetTransferMethod ?? 'eip3009';\n if (method !== 'eip3009' && method !== 'permit2') {\n throw invalid(\n `${path}.assetTransferMethod: \"${method}\" is not supported; use \"eip3009\" or \"permit2\"`,\n `${path}.assetTransferMethod`,\n );\n }\n if (network.family !== 'evm' && input.assetTransferMethod !== undefined) {\n throw invalid(\n `${path}.assetTransferMethod applies to EVM networks only, not to ${network.displayName}`,\n `${path}.assetTransferMethod`,\n );\n }\n\n if (network.family !== 'evm') {\n for (const field of ['assetName', 'assetVersion'] as const) {\n if (input[field] !== undefined) {\n throw invalid(\n `${path}.${field}: an EIP-712 domain applies to EVM tokens only, not to ${network.displayName}`,\n `${path}.${field}`,\n );\n }\n }\n }\n\n const canonical = network.canonicalAsset;\n const domain = canonical && 'name' in canonical ? canonical : undefined;\n\n const asset = input.asset !== undefined ? address('asset', input.asset) : undefined;\n if (asset !== undefined && isBurnAddress(network, asset)) {\n throw invalid(`${path}.asset must not be the zero address`, `${path}.asset`);\n }\n\n // The default asset applies when the option names none or names it exactly\n if (canonical && (asset === undefined || sameAddress(network, asset, canonical.address))) {\n const expected = {\n assetName: domain?.name,\n assetVersion: domain?.version,\n assetDecimals: canonical.decimals,\n };\n for (const field of ['assetName', 'assetVersion', 'assetDecimals'] as const) {\n const given = input[field];\n if (given !== undefined && given !== expected[field]) {\n throw invalid(\n `${path}.${field} does not match ${canonical.symbol} on ${network.displayName}, which reports ${FIELD_MEANINGS[field]} ${JSON.stringify(expected[field])}. Remove ${field}, or set asset to the token it describes.`,\n `${path}.${field}`,\n );\n }\n }\n return {\n scheme: 'exact',\n network,\n payTo,\n asset: asset ?? canonical.address,\n ...(domain ? { assetName: domain.name, assetVersion: domain.version } : {}),\n assetDecimals: canonical.decimals,\n defaultAssetSymbol: canonical.symbol,\n assetTransferMethod: method,\n };\n }\n\n // Another token: nothing about it can be borrowed from the default. The\n // token's EIP-712 domain matters to EIP-3009 only: a Permit2 buyer signs\n // Permit2's own domain.\n const required =\n network.family === 'evm' && method === 'eip3009'\n ? (['asset', 'assetName', 'assetVersion', 'assetDecimals'] as const)\n : (['asset', 'assetDecimals'] as const);\n const missing = required.filter((field) => input[field] === undefined);\n if (asset === undefined || missing.length > 0) {\n throw invalid(\n canonical\n ? `${path}: a token other than ${canonical.symbol} on ${network.displayName} needs ${missing.join(', ')}`\n : `${path}: ${network.displayName} has no default asset, so the option needs ${missing.join(', ')}`,\n `${path}.${missing[0] ?? 'asset'}`,\n );\n }\n return {\n scheme: 'exact',\n network,\n payTo,\n asset,\n ...(input.assetName !== undefined ? { assetName: input.assetName } : {}),\n ...(input.assetVersion !== undefined ? { assetVersion: input.assetVersion } : {}),\n assetDecimals: input.assetDecimals as number,\n assetTransferMethod: method,\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { CommerceError } from './chunk-QQ3WY5L3.js';
1
+ import { CommerceError } from './chunk-SYQLJXIU.js';
2
2
 
3
3
  // src/core/execution/settlement-order.ts
4
4
  var SETTLE_AFTER_BACKEND_METADATA_KEY = "settleAfterBackend";
@@ -176,6 +176,27 @@ function describeDeploymentMode(mode) {
176
176
  return mode === "mainnet" ? LIVE_MAINNET_BANNER : mode.toUpperCase();
177
177
  }
178
178
 
179
+ // src/core/canonical-json.ts
180
+ var LONE_SURROGATE = new RegExp("\\p{Cs}", "u");
181
+ function canonicalJson(value) {
182
+ if (typeof value === "string")
183
+ return LONE_SURROGATE.test(value) ? void 0 : JSON.stringify(value);
184
+ if (typeof value === "number") return Number.isFinite(value) ? JSON.stringify(value) : void 0;
185
+ if (value === null || typeof value === "boolean") return JSON.stringify(value);
186
+ if (Array.isArray(value)) {
187
+ const items = value.map(canonicalJson);
188
+ return items.includes(void 0) ? void 0 : `[${items.join(",")}]`;
189
+ }
190
+ if (typeof value !== "object") return void 0;
191
+ const members = [];
192
+ for (const key of Object.keys(value).sort()) {
193
+ const member = canonicalJson(value[key]);
194
+ if (member === void 0 || LONE_SURROGATE.test(key)) return void 0;
195
+ members.push(`${JSON.stringify(key)}:${member}`);
196
+ }
197
+ return `{${members.join(",")}}`;
198
+ }
199
+
179
200
  // src/payments/x402/addresses.ts
180
201
  var EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;
181
202
  var EVM_ZERO = /^0x0{40}$/i;
@@ -251,6 +272,6 @@ ANVIL_WELL_KNOWN_ACCOUNTS[0];
251
272
  ANVIL_WELL_KNOWN_ACCOUNTS[1];
252
273
  ANVIL_WELL_KNOWN_ACCOUNTS[2];
253
274
 
254
- export { ANVIL_WELL_KNOWN_ACCOUNTS, LOCAL_CHAIN_ID, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY, SETTLE_AFTER_BACKEND_METADATA_KEY, SUPPORTED_NETWORK_IDS, X402_DEFAULT_PAYMENT_FLOW, X402_PAYMENT_FLOWS, describeDeploymentMode, findX402Network, isBurnAddress, isEvmAddress, isEvmZeroAddress, isTransactionReference, normalizeAddress, requireX402Network, resolveDeploymentMode, sameAddress, validateCustomNetworks };
255
- //# sourceMappingURL=chunk-OZ4LAWBK.js.map
256
- //# sourceMappingURL=chunk-OZ4LAWBK.js.map
275
+ export { ANVIL_WELL_KNOWN_ACCOUNTS, LOCAL_CHAIN_ID, REUSE_REJECTED_AUTHORIZATION_METADATA_KEY, SETTLE_AFTER_BACKEND_METADATA_KEY, SUPPORTED_NETWORK_IDS, X402_DEFAULT_PAYMENT_FLOW, X402_PAYMENT_FLOWS, canonicalJson, describeDeploymentMode, findX402Network, isBurnAddress, isEvmAddress, isEvmZeroAddress, isTransactionReference, normalizeAddress, requireX402Network, resolveDeploymentMode, sameAddress, validateCustomNetworks };
276
+ //# sourceMappingURL=chunk-5R7DM5LM.js.map
277
+ //# sourceMappingURL=chunk-5R7DM5LM.js.map