@devlab.group/agent-commerce 1.6.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +187 -2
- package/README.md +6 -6
- package/dist/ap2.d.ts +2 -2
- package/dist/ap2.js +94 -28
- package/dist/ap2.js.map +1 -1
- package/dist/{chunk-V2V2E7HX.js → chunk-3LUJHVKX.js} +4 -4
- package/dist/{chunk-V2V2E7HX.js.map → chunk-3LUJHVKX.js.map} +1 -1
- package/dist/{chunk-N5KRK7YA.js → chunk-53WXXIPR.js} +3 -3
- package/dist/{chunk-N5KRK7YA.js.map → chunk-53WXXIPR.js.map} +1 -1
- package/dist/chunk-CKJRITWY.js +113 -0
- package/dist/chunk-CKJRITWY.js.map +1 -0
- package/dist/chunk-HOZA3IWP.js +115 -0
- package/dist/chunk-HOZA3IWP.js.map +1 -0
- package/dist/{chunk-JKEKKXRJ.js → chunk-RKBGCPCK.js} +78 -25
- package/dist/chunk-RKBGCPCK.js.map +1 -0
- package/dist/{chunk-VKDXMXHL.js → chunk-SYEGCNJZ.js} +3 -3
- package/dist/{chunk-VKDXMXHL.js.map → chunk-SYEGCNJZ.js.map} +1 -1
- package/dist/{chunk-CBJIT7QP.js → chunk-TWRUNWDR.js} +11 -4
- package/dist/chunk-TWRUNWDR.js.map +1 -0
- package/dist/cli/index.js +142 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/{constants-Bkq04FRZ.d.ts → constants-BSBRlKRR.d.ts} +2 -2
- package/dist/index.d.ts +42 -22
- package/dist/index.js +1254 -377
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +247 -94
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +6 -2
- package/dist/mpp.js +65 -28
- package/dist/mpp.js.map +1 -1
- package/dist/{guardrails-71XwtXlT.d.ts → payment-flow-DCS882tR.d.ts} +9 -1
- package/dist/{protocol-adapter-DTkrXTev.d.ts → protocol-adapter-DonxfAwa.d.ts} +2 -0
- package/dist/{types-O6lg3Q5V.d.ts → types-CVw6Sf46.d.ts} +11 -0
- package/dist/x402.d.ts +11 -3
- package/dist/x402.js +4 -4
- package/package.json +16 -13
- package/dist/chunk-AFI2CEZS.js +0 -10
- package/dist/chunk-AFI2CEZS.js.map +0 -1
- package/dist/chunk-CBJIT7QP.js.map +0 -1
- package/dist/chunk-JKEKKXRJ.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeRpc, LOCAL_CHAIN_ID, describeDeploymentMode } from './chunk-
|
|
2
|
-
import { CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, redactedErrorText } from './chunk-
|
|
1
|
+
import { assertPayToIsNotDevAddress, resolveX402Deployment, assertDevKeyIsLocalOnly, describeRpc, X402_DEFAULT_PAYMENT_FLOW, SETTLE_AFTER_BACKEND_METADATA_KEY, LOCAL_CHAIN_ID, describeDeploymentMode } from './chunk-TWRUNWDR.js';
|
|
2
|
+
import { CommerceError, systemClock, NOOP_LOGGER, PACKAGE_VERSION, redactedErrorText } from './chunk-53WXXIPR.js';
|
|
3
3
|
import { encodeAbiParameters, keccak256, isAddress, getAddress, formatUnits, createWalletClient, http, publicActions, createPublicClient, HttpRequestError, TimeoutError, WaitForTransactionReceiptTimeoutError, BaseError, ContractFunctionRevertedError } from 'viem';
|
|
4
4
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
5
5
|
import { x402Facilitator } from '@x402/core/facilitator';
|
|
6
6
|
import { HTTPFacilitatorClient } from '@x402/core/http';
|
|
7
|
-
import { VerifyError } from '@x402/core/types';
|
|
7
|
+
import { SettleError, VerifyError } from '@x402/core/types';
|
|
8
8
|
import { isEIP3009Payload, toFacilitatorEvmSigner } from '@x402/evm';
|
|
9
9
|
import { registerExactEvmScheme } from '@x402/evm/exact/facilitator';
|
|
10
10
|
import { PaymentPayloadV2Schema } from '@x402/core/schemas';
|
|
@@ -139,6 +139,18 @@ function verdictFromVerifyError(err) {
|
|
|
139
139
|
}
|
|
140
140
|
throw err;
|
|
141
141
|
}
|
|
142
|
+
function verdictFromSettleError(err, network) {
|
|
143
|
+
if (err instanceof SettleError && err.statusCode === 400 && typeof err.errorReason === "string" && err.errorReason !== "" && !err.transaction) {
|
|
144
|
+
return {
|
|
145
|
+
success: false,
|
|
146
|
+
errorReason: err.errorReason,
|
|
147
|
+
transaction: "",
|
|
148
|
+
network: err.network ?? network,
|
|
149
|
+
...err.payer !== void 0 ? { payer: err.payer } : {}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
142
154
|
function createRemoteFacilitatorBinding(options) {
|
|
143
155
|
const auth = options.auth;
|
|
144
156
|
let createAuthHeaders;
|
|
@@ -170,7 +182,9 @@ function createRemoteFacilitatorBinding(options) {
|
|
|
170
182
|
};
|
|
171
183
|
return {
|
|
172
184
|
verify: (payload, requirements) => watch(() => client.verify(payload, requirements).catch(verdictFromVerifyError)),
|
|
173
|
-
settle: (payload, requirements) => watch(
|
|
185
|
+
settle: (payload, requirements) => watch(
|
|
186
|
+
() => client.settle(payload, requirements).catch((err) => verdictFromSettleError(err, requirements.network))
|
|
187
|
+
),
|
|
174
188
|
transportFailed: () => failed
|
|
175
189
|
};
|
|
176
190
|
},
|
|
@@ -181,15 +195,25 @@ function createRemoteFacilitatorBinding(options) {
|
|
|
181
195
|
};
|
|
182
196
|
}
|
|
183
197
|
function decodePaymentSubmission(payloadBase64) {
|
|
184
|
-
|
|
198
|
+
const json = decodeJson(payloadBase64);
|
|
199
|
+
if (json === void 0) return void 0;
|
|
200
|
+
const result = PaymentPayloadV2Schema.safeParse(json);
|
|
201
|
+
return result.success ? result.data : void 0;
|
|
202
|
+
}
|
|
203
|
+
function declaredX402Version(payloadBase64) {
|
|
204
|
+
const json = decodeJson(payloadBase64);
|
|
205
|
+
return typeof json === "object" && json !== null ? json["x402Version"] : void 0;
|
|
206
|
+
}
|
|
207
|
+
function withoutResource(payload) {
|
|
208
|
+
const { resource: _resource, ...rest } = payload;
|
|
209
|
+
return rest;
|
|
210
|
+
}
|
|
211
|
+
function decodeJson(payloadBase64) {
|
|
185
212
|
try {
|
|
186
|
-
|
|
187
|
-
json = JSON.parse(decoded);
|
|
213
|
+
return JSON.parse(Buffer.from(payloadBase64, "base64").toString("utf8"));
|
|
188
214
|
} catch {
|
|
189
215
|
return void 0;
|
|
190
216
|
}
|
|
191
|
-
const result = PaymentPayloadV2Schema.safeParse(json);
|
|
192
|
-
return result.success ? result.data : void 0;
|
|
193
217
|
}
|
|
194
218
|
function isExactEvmPayload(payload) {
|
|
195
219
|
return payload.accepted.scheme === "exact" && typeof payload.payload === "object" && payload.payload !== null && isEIP3009Payload(payload.payload) && typeof payload.payload.signature === "string";
|
|
@@ -295,13 +319,22 @@ function createX402PaymentProvider(options) {
|
|
|
295
319
|
`${binding.kind}-facilitator`,
|
|
296
320
|
"eip-3009",
|
|
297
321
|
"caip-2",
|
|
298
|
-
`mode=${mode}
|
|
322
|
+
`mode=${mode}`,
|
|
323
|
+
"authorization-flow",
|
|
324
|
+
"upfront-flow"
|
|
299
325
|
],
|
|
300
326
|
status: "stable",
|
|
301
|
-
unsupported: [
|
|
327
|
+
unsupported: [
|
|
328
|
+
"svm",
|
|
329
|
+
"permit2",
|
|
330
|
+
"upto scheme",
|
|
331
|
+
"batch-settlement scheme",
|
|
332
|
+
"auth-capture scheme"
|
|
333
|
+
]
|
|
302
334
|
};
|
|
303
335
|
async function createRequirement(context) {
|
|
304
336
|
const amount = parseCanonicalAmount(context.amount, options.assetDecimals).toString();
|
|
337
|
+
const paymentFlow = options.resourcePaymentFlows?.[context.resource.id] ?? options.paymentFlow ?? X402_DEFAULT_PAYMENT_FLOW;
|
|
305
338
|
const requirements = {
|
|
306
339
|
scheme: "exact",
|
|
307
340
|
network,
|
|
@@ -313,10 +346,13 @@ function createX402PaymentProvider(options) {
|
|
|
313
346
|
// EIP-712 domain without calling `version()` on the token.
|
|
314
347
|
// `assetTransferMethod` names the one method this provider settles, so a
|
|
315
348
|
// conforming client never picks the `exact` scheme's Permit2 path.
|
|
349
|
+
// x402 requires an explicit non-default flow. Omit the default
|
|
350
|
+
// `authorization` flow here.
|
|
316
351
|
extra: {
|
|
317
352
|
name: options.assetName,
|
|
318
353
|
version: options.assetVersion,
|
|
319
|
-
assetTransferMethod: "eip3009"
|
|
354
|
+
assetTransferMethod: "eip3009",
|
|
355
|
+
...paymentFlow === "upfront" ? { paymentFlow } : {}
|
|
320
356
|
}
|
|
321
357
|
};
|
|
322
358
|
const envelope = {
|
|
@@ -345,7 +381,8 @@ function createX402PaymentProvider(options) {
|
|
|
345
381
|
version: X402_PROTOCOL_VERSION,
|
|
346
382
|
accepts: [requirements],
|
|
347
383
|
envelope
|
|
348
|
-
}
|
|
384
|
+
},
|
|
385
|
+
metadata: { [SETTLE_AFTER_BACKEND_METADATA_KEY]: paymentFlow === "authorization" }
|
|
349
386
|
};
|
|
350
387
|
}
|
|
351
388
|
async function verify(context) {
|
|
@@ -374,23 +411,30 @@ function createX402PaymentProvider(options) {
|
|
|
374
411
|
}
|
|
375
412
|
const payload = decodePaymentSubmission(submission.payload);
|
|
376
413
|
if (!payload) {
|
|
377
|
-
|
|
414
|
+
const version = declaredX402Version(submission.payload);
|
|
415
|
+
return rejected(
|
|
416
|
+
typeof version === "number" && version !== X402_VERSION ? "invalid_x402_version" : "invalid_payload"
|
|
417
|
+
);
|
|
378
418
|
}
|
|
379
419
|
if (payload.x402Version !== X402_VERSION) {
|
|
380
|
-
return rejected("
|
|
420
|
+
return rejected("invalid_x402_version");
|
|
381
421
|
}
|
|
382
422
|
if (!isExactEvmPayload(payload)) {
|
|
383
423
|
return rejected("unsupported_scheme");
|
|
384
424
|
}
|
|
385
425
|
const { authorization } = payload.payload;
|
|
386
426
|
if (!isAddress(authorization.from) || !isAddress(authorization.to)) {
|
|
387
|
-
return rejected("
|
|
427
|
+
return rejected("invalid_payload");
|
|
388
428
|
}
|
|
389
429
|
if (payload.accepted.network !== options.network) {
|
|
390
|
-
return rejected("
|
|
430
|
+
return rejected("invalid_network");
|
|
431
|
+
}
|
|
432
|
+
const offeredUrl = requirement.challenge.envelope?.resource?.url;
|
|
433
|
+
if (!acceptedMatchesOffer(requirements, payload.accepted) || payload.resource !== void 0 && payload.resource.url !== offeredUrl) {
|
|
434
|
+
return rejected("invalid_payment_requirements");
|
|
391
435
|
}
|
|
392
436
|
if (getAddress(authorization.to) !== getAddress(options.payTo)) {
|
|
393
|
-
return rejected("
|
|
437
|
+
return rejected("invalid_exact_evm_payload_recipient_mismatch");
|
|
394
438
|
}
|
|
395
439
|
let authorizedValue;
|
|
396
440
|
let required;
|
|
@@ -398,15 +442,15 @@ function createX402PaymentProvider(options) {
|
|
|
398
442
|
authorizedValue = BigInt(authorization.value);
|
|
399
443
|
required = BigInt(requirements.amount);
|
|
400
444
|
} catch {
|
|
401
|
-
return rejected("
|
|
445
|
+
return rejected("invalid_payload");
|
|
402
446
|
}
|
|
403
447
|
if (authorizedValue !== required) {
|
|
404
|
-
return rejected("
|
|
448
|
+
return rejected("invalid_exact_evm_payload_authorization_value_mismatch");
|
|
405
449
|
}
|
|
406
450
|
const scope = binding.open();
|
|
407
451
|
let sdkResult;
|
|
408
452
|
try {
|
|
409
|
-
sdkResult = await scope.verify(payload, requirements);
|
|
453
|
+
sdkResult = await scope.verify(withoutResource(payload), requirements);
|
|
410
454
|
} catch (err) {
|
|
411
455
|
if (!isProviderUnavailableError(err) && !scope.transportFailed()) {
|
|
412
456
|
logger.warn({ err: redactedErrorText(err) }, "x402 verify(): unexpected SDK error");
|
|
@@ -491,7 +535,7 @@ function createX402PaymentProvider(options) {
|
|
|
491
535
|
const scope = binding.open();
|
|
492
536
|
let sdkResult;
|
|
493
537
|
try {
|
|
494
|
-
sdkResult = await scope.settle(payload, requirements);
|
|
538
|
+
sdkResult = await scope.settle(withoutResource(payload), requirements);
|
|
495
539
|
} catch (err) {
|
|
496
540
|
if (isProviderUnavailableError(err) || scope.transportFailed()) {
|
|
497
541
|
throw new CommerceError(
|
|
@@ -560,7 +604,9 @@ function createX402PaymentProvider(options) {
|
|
|
560
604
|
network: sdkResult.network,
|
|
561
605
|
...verification.asset !== void 0 ? { asset: verification.asset } : {},
|
|
562
606
|
...verification.replayKey !== void 0 ? { replayKey: verification.replayKey } : {},
|
|
563
|
-
settledAt: clock.nowIso()
|
|
607
|
+
settledAt: clock.nowIso(),
|
|
608
|
+
// `amount` is the display value; x402's settlement response reports base units
|
|
609
|
+
metadata: { amountBaseUnits: payload.payload.authorization.value }
|
|
564
610
|
};
|
|
565
611
|
}
|
|
566
612
|
async function computeHealth() {
|
|
@@ -655,6 +701,13 @@ function createX402PaymentProvider(options) {
|
|
|
655
701
|
health
|
|
656
702
|
};
|
|
657
703
|
}
|
|
704
|
+
function acceptedMatchesOffer(offered, accepted) {
|
|
705
|
+
const sameAddress = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
706
|
+
const offeredExtra = offered.extra ?? {};
|
|
707
|
+
const acceptedExtra = accepted.extra ?? {};
|
|
708
|
+
const flow = (extra) => extra["paymentFlow"] ?? X402_DEFAULT_PAYMENT_FLOW;
|
|
709
|
+
return accepted.scheme === offered.scheme && accepted.network === offered.network && accepted.amount === offered.amount && sameAddress(accepted.asset, offered.asset) && sameAddress(accepted.payTo, offered.payTo) && Object.entries(offeredExtra).every(([key, value]) => acceptedExtra[key] === value) && flow(acceptedExtra) === flow(offeredExtra);
|
|
710
|
+
}
|
|
658
711
|
function isOnChainRevertError(err) {
|
|
659
712
|
return err instanceof BaseError && err.walk((e) => e instanceof ContractFunctionRevertedError) !== null;
|
|
660
713
|
}
|
|
@@ -676,5 +729,5 @@ async function probeIsAnvilNode(client) {
|
|
|
676
729
|
}
|
|
677
730
|
|
|
678
731
|
export { DEFAULT_IDS, chainIdFromCaip2, computeReplayKey, createX402PaymentProvider, parseCanonicalAmount };
|
|
679
|
-
//# sourceMappingURL=chunk-
|
|
680
|
-
//# sourceMappingURL=chunk-
|
|
732
|
+
//# sourceMappingURL=chunk-RKBGCPCK.js.map
|
|
733
|
+
//# sourceMappingURL=chunk-RKBGCPCK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/payments/x402/amount.ts","../src/payments/x402/chain.ts","../src/payments/x402/facilitator.ts","../src/payments/x402/payload.ts","../src/payments/x402/replay-key.ts","../src/payments/x402/provider.ts"],"names":[],"mappings":";;;;;;;;;;;;AAYA,IAAM,sBAAA,GAAyB,iBAAA;AAUxB,SAAS,oBAAA,CAAqB,QAAgB,QAAA,EAA0B;AAC7E,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA,IAAK,WAAW,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,aAAA,CAAc,gBAAA,EAAkB,CAAA,wBAAA,EAA2B,QAAQ,CAAA,CAAE,CAAA;AAAA,EACjF;AACA,EAAA,IAAI,CAAC,sBAAA,CAAuB,IAAA,CAAK,MAAM,CAAA,EAAG;AACxC,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,iBAAA;AAAA,MACA,WAAW,MAAM,CAAA,4CAAA,CAAA;AAAA,MACjB;AAAA,QACE,OAAA,EAAS,EAAE,MAAA;AAAO;AACpB,KACF;AAAA,EACF;AAEA,EAAA,MAAM,CAAC,cAAc,GAAA,EAAK,YAAA,GAAe,EAAE,CAAA,GAAI,MAAA,CAAO,MAAM,GAAG,CAAA;AAE/D,EAAA,IAAI,YAAA,CAAa,SAAS,QAAA,EAAU;AAClC,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,iBAAA;AAAA,MACA,CAAA,QAAA,EAAW,MAAM,CAAA,8CAAA,EAAiD,QAAQ,CAAA,UAAA,CAAA;AAAA,MAC1E,EAAE,OAAA,EAAS,EAAE,MAAA,EAAQ,aAAA,EAAe,UAAS;AAAE,KACjD;AAAA,EACF;AAEA,EAAA,MAAM,cAAA,GAAiB,YAAA,CAAa,MAAA,CAAO,QAAA,EAAU,GAAG,CAAA;AACxD,EAAA,MAAM,QAAA,GAAW,CAAA,EAAG,WAAW,CAAA,EAAG,cAAc,CAAA,CAAA;AAChD,EAAA,OAAO,OAAO,QAAQ,CAAA;AACxB;ACJO,SAAS,iBAAiB,OAAA,EAAqC;AACpE,EAAA,MAAM,KAAA,GAAQ,gBAAA,CAAiB,IAAA,CAAK,OAAO,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAA,GAAQ,CAAC,CAAA,EAAG,OAAO,MAAA;AACxB,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AAC/B,EAAA,OAAO,OAAO,aAAA,CAAc,OAAO,CAAA,IAAK,OAAA,GAAU,IAAI,OAAA,GAAU,MAAA;AAClE;AAMA,SAAS,eAAA,CAAgB,MAAA,EAAgB,OAAA,GAAkB,cAAA,EAAuB;AAChF,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,OAAA;AAAA,IACJ,IAAA,EAAM,sBAAA;AAAA,IACN,gBAAgB,EAAE,IAAA,EAAM,SAAS,MAAA,EAAQ,KAAA,EAAO,UAAU,EAAA,EAAG;AAAA,IAC7D,OAAA,EAAS;AAAA,MACP,OAAA,EAAS,EAAE,IAAA,EAAM,CAAC,MAAM,CAAA;AAAE;AAC5B,GACF;AACF;AASO,SAAS,uBAAA,CACd,MAAA,EACA,SAAA,EACA,OAAA,EACc;AACd,EAAA,OAAO,kBAAA,CAAmB;AAAA,IACxB,KAAA,EAAO,eAAA,CAAgB,MAAA,EAAQ,OAAO,CAAA;AAAA,IACtC,SAAA,EAAW,KAAK,MAAA,EAAkC,EAAE,OAAA,EAAS,SAAA,EAAU,CAAa;AAAA,GACrF,CAAA;AACH;AAWO,SAAS,4BAAA,CACd,QACA,gBAAA,EACwB;AACxB,EAAA,MAAM,KAAA,GAAQ,gBAAgB,MAAM,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,oBAAoB,gBAAgB,CAAA;AACpD,EAAA,OAAO,kBAAA,CAAmB;AAAA,IACxB,OAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA,EAAW,KAAK,MAAM;AAAA,GACvB,CAAA,CAAE,MAAA,CAAO,aAAa,CAAA;AACzB;ACtCA,IAAM,kCAAA,GAAqC,GAAA;AAOpC,SAAS,6BAAA,CACd,MAAA,EACA,OAAA,EACA,gBAAA,EACoB;AACpB,EAAA,MAAM,QAAQ,MAA+D;AAC3E,IAAA,IAAI,MAAA,GAAS,KAAA;AACb,IAAA,MAAM,QAAQ,CAAI,OAAA,KAChB,OAAA,CAAQ,KAAA,CAAM,CAAC,GAAA,KAAiB;AAC9B,MAAA,IAAI,gBAAA,CAAiB,GAAG,CAAA,EAAG,MAAA,GAAS,IAAA;AACpC,MAAA,MAAM,GAAA;AAAA,IACR,CAAC,CAAA;AAKH,IAAA,MAAM,MAAA,GAAS;AAAA,MACb,OAAA,EAAS,OAAO,OAAA,CAAQ,OAAA;AAAA,MACxB,cAAc,CAAC,IAAA,KACb,MAAM,MAAA,CAAO,YAAA,CAAa,IAAI,CAAC,CAAA;AAAA,MACjC,iBAAiB,CAAC,IAAA,KAChB,MAAM,MAAA,CAAO,eAAA,CAAgB,IAAI,CAAC,CAAA;AAAA,MACpC,eAAe,CAAC,IAAA,KACd,MAAM,MAAA,CAAO,aAAA,CAAc,IAAI,CAAC,CAAA;AAAA,MAClC,iBAAiB,CAAC,IAAA,KAChB,MAAM,MAAA,CAAO,eAAA,CAAgB,IAAI,CAAC,CAAA;AAAA,MACpC,2BAA2B,CACzB,IAAA,KACG,MAAM,MAAA,CAAO,yBAAA,CAA0B,IAAI,CAAC,CAAA;AAAA,MACjD,SAAS,CAAC,IAAA,KACR,MAAM,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAC;AAAA,KAC9B;AAIA,IAAA,MAAM,WAAA,GAAc,sBAAA,CAAuB,IAAI,eAAA,EAAgB,EAAG;AAAA,MAChE,MAAA,EAAQ,uBAAuB,MAAA,EAAQ;AAAA,QACrC,qBAAA,EAAuB;AAAA,OACxB,CAAA;AAAA,MACD,QAAA,EAAU;AAAA,KACX,CAAA;AAED,IAAA,OAAO,EAAE,WAAA,EAAa,MAAA,EAAQ,MAAM,MAAA,EAAO;AAAA,EAC7C,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,OAAA;AAAA,IACN,QAAA,EAAU,oBAAA;AAAA,IACV,IAAA,GAA2B;AACzB,MAAA,MAAM,EAAE,WAAA,EAAa,MAAA,EAAO,GAAI,KAAA,EAAM;AACtC,MAAA,OAAO;AAAA,QACL,QAAQ,CAAC,OAAA,EAAS,iBAAiB,WAAA,CAAY,MAAA,CAAO,SAAS,YAAY,CAAA;AAAA,QAC3E,QAAQ,CAAC,OAAA,EAAS,iBAAiB,WAAA,CAAY,MAAA,CAAO,SAAS,YAAY,CAAA;AAAA,QAC3E,eAAA,EAAiB;AAAA,OACnB;AAAA,IACF;AAAA,GACF;AACF;AAoBA,SAAS,cAAA,CAAe,UAAkB,YAAA,EAAyC;AACjF,EAAA,MAAM,OAAA,GAAU,OAAO,gBAAgB,CAAA,CAAE,IAAA;AAAA,IACvC,CAAC,GAAA,KAAQ,GAAA,CAAI,oBAAA,CAAqB,UAAU,YAAY,CAAA;AAAA,IACxD,CAAC,KAAA,KAAmB;AAClB,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,gBAAA;AAAA,QACA,mNAAA;AAAA,QAGA,EAAE,KAAA;AAAM,OACV;AAAA,IACF;AAAA,GACF;AAGA,EAAA,OAAA,CAAQ,MAAM,MAAM;AAAA,EAAC,CAAC,CAAA;AAEtB,EAAA,OAAO,YAAY;AACjB,IAAA,MAAM,SAAS,MAAM,OAAA;AACrB,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,8BAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAQ,MAAM,MAAA,EAAO;AAAA,EACvB,CAAA;AACF;AASA,SAAS,uBAAuB,GAAA,EAA8B;AAC5D,EAAA,IACE,GAAA,YAAe,eACf,GAAA,CAAI,UAAA,KAAe,OACnB,OAAO,GAAA,CAAI,kBAAkB,QAAA,EAC7B;AACA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,eAAe,GAAA,CAAI,aAAA;AAAA,MACnB,GAAI,IAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,GAAA,CAAI,KAAA,EAAM,GAAI;AAAC,KACxD;AAAA,EACF;AACA,EAAA,MAAM,GAAA;AACR;AAOA,SAAS,sBAAA,CAAuB,KAAc,OAAA,EAAkC;AAC9E,EAAA,IACE,GAAA,YAAe,WAAA,IACf,GAAA,CAAI,UAAA,KAAe,OACnB,OAAO,GAAA,CAAI,WAAA,KAAgB,QAAA,IAC3B,GAAA,CAAI,WAAA,KAAgB,EAAA,IACpB,CAAC,IAAI,WAAA,EACL;AACA,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,aAAa,GAAA,CAAI,WAAA;AAAA,MACjB,WAAA,EAAa,EAAA;AAAA,MACb,OAAA,EAAS,IAAI,OAAA,IAAW,OAAA;AAAA,MACxB,GAAI,IAAI,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,GAAA,CAAI,KAAA,EAAM,GAAI;AAAC,KACxD;AAAA,EACF;AACA,EAAA,MAAM,GAAA;AACR;AAOO,SAAS,+BACd,OAAA,EACoB;AACpB,EAAA,MAAM,OAAO,OAAA,CAAQ,IAAA;AACrB,EAAA,IAAI,iBAAA;AACJ,EAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,IAAA,iBAAA,GAAoB,YAAY;AAE9B,MAAA,MAAM,UAAU,EAAE,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,KAAK,CAAA,CAAA,EAAG;AACxD,MAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,OAAA,EAAS,WAAW,OAAA,EAAQ;AAAA,IAChE,CAAA;AAAA,EACF,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,KAAA,EAAO;AAC9B,IAAA,iBAAA,GAAoB,cAAA,CAAe,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,YAAY,CAAA;AAAA,EACrE;AAEA,EAAA,MAAM,MAAA,GAAS,IAAI,qBAAA,CAAsB;AAAA,IACvC,KAAK,OAAA,CAAQ,GAAA;AAAA,IACb,SAAA,EAAW,kCAAA;AAAA,IACX,GAAI,iBAAA,GAAoB,EAAE,iBAAA,KAAsB;AAAC,GAClD,CAAA;AAED,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,QAAA,EAAU,CAAA,OAAA,EAAU,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CAAE,MAAM,CAAA,OAAA,EAAU,IAAA,CAAK,IAAI,CAAA,CAAA,CAAA;AAAA,IAClE,IAAA,GAA2B;AACzB,MAAA,IAAI,MAAA,GAAS,KAAA;AACb,MAAA,MAAM,KAAA,GAAQ,OAAU,IAAA,KAAuC;AAC7D,QAAA,IAAI;AACF,UAAA,OAAO,MAAM,IAAA,EAAK;AAAA,QACpB,SAAS,GAAA,EAAK;AAIZ,UAAA,MAAA,GAAS,IAAA;AACT,UAAA,MAAM,GAAA;AAAA,QACR;AAAA,MACF,CAAA;AACA,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,CAAC,OAAA,EAAS,YAAA,KAChB,KAAA,CAAM,MAAM,MAAA,CAAO,MAAA,CAAO,OAAA,EAAS,YAAY,CAAA,CAAE,KAAA,CAAM,sBAAsB,CAAC,CAAA;AAAA,QAChF,MAAA,EAAQ,CAAC,OAAA,EAAS,YAAA,KAChB,KAAA;AAAA,UAAM,MACJ,MAAA,CACG,MAAA,CAAO,OAAA,EAAS,YAAY,CAAA,CAC5B,KAAA,CAAM,CAAC,GAAA,KAAiB,sBAAA,CAAuB,GAAA,EAAK,YAAA,CAAa,OAAO,CAAC;AAAA,SAC9E;AAAA,QACF,iBAAiB,MAAM;AAAA,OACzB;AAAA,IACF,CAAA;AAAA,IACA,MAAM,SAAA,GAA+C;AACnD,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,CAAO,YAAA,EAAa;AAC3C,MAAA,OAAO,QAAA,CAAS,KAAA;AAAA,IAClB;AAAA,GACF;AACF;ACjRO,SAAS,wBAAwB,aAAA,EAAmD;AACzF,EAAA,MAAM,IAAA,GAAO,WAAW,aAAa,CAAA;AACrC,EAAA,IAAI,IAAA,KAAS,QAAW,OAAO,MAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,sBAAA,CAAuB,SAAA,CAAU,IAAI,CAAA;AACpD,EAAA,OAAO,MAAA,CAAO,OAAA,GAAW,MAAA,CAAO,IAAA,GAA0B,MAAA;AAC5D;AAGO,SAAS,oBAAoB,aAAA,EAAgC;AAClE,EAAA,MAAM,IAAA,GAAO,WAAW,aAAa,CAAA;AACrC,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,IAAY,SAAS,IAAA,GACvC,IAAA,CAAiC,aAAa,CAAA,GAC/C,MAAA;AACN;AAQO,SAAS,gBAA0C,OAAA,EAAiC;AACzF,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAW,GAAG,MAAK,GAAI,OAAA;AACzC,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,WAAW,aAAA,EAAgC;AAClD,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,MAAM,MAAA,CAAO,IAAA,CAAK,eAAe,QAAQ,CAAA,CAAE,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,EACzE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAWO,SAAS,kBACd,OAAA,EAC8D;AAC9D,EAAA,OACE,QAAQ,QAAA,CAAS,MAAA,KAAW,WAC5B,OAAO,OAAA,CAAQ,YAAY,QAAA,IAC3B,OAAA,CAAQ,OAAA,KAAY,IAAA,IACpB,iBAAiB,OAAA,CAAQ,OAA8B,KACvD,OAAQ,OAAA,CAAQ,QAAgC,SAAA,KAAc,QAAA;AAElE;AClDO,SAAS,iBAAiB,KAAA,EAA+B;AAC9D,EAAA,MAAM,OAAA,GAAU,mBAAA;AAAA,IACd,CAAC,EAAE,IAAA,EAAM,SAAA,EAAU,EAAG,EAAE,IAAA,EAAM,SAAA,EAAU,EAAG,EAAE,MAAM,SAAA,EAAU,EAAG,EAAE,IAAA,EAAM,WAAW,CAAA;AAAA,IACnF,CAAC,MAAA,CAAO,KAAA,CAAM,OAAO,CAAA,EAAG,MAAM,KAAA,EAAO,KAAA,CAAM,IAAA,EAAM,KAAA,CAAM,KAAK;AAAA,GAC9D;AACA,EAAA,OAAO,UAAU,OAAO,CAAA;AAC1B;;;ACgDA,IAAM,YAAA,GAAe,CAAA;AACrB,IAAM,qBAAA,GAAwB,OAAO,YAAY,CAAA;AACjD,IAAM,2BAAA,GAA8B,EAAA;AACpC,IAAM,iBAAA,GAAoB,kBAAA;AAC1B,IAAM,iBAAA,GAAoB,GAAA;AAE1B,IAAM,yBAAA,GAA4B,oBAAA;AAMlC,IAAM,yBAAA,GAA4B,sCAAA;AAOlC,IAAM,iBAAA,GAAoB,EAAA;AAC1B,IAAM,YAAA,GAAe,iBAAA;AAErB,SAAS,cAAA,CAAe,QAA4B,QAAA,EAA0B;AAC5E,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,QAAA;AACjC,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,EAAA,IAAI,QAAQ,MAAA,KAAW,CAAA,IAAK,OAAA,CAAQ,MAAA,GAAS,mBAAmB,OAAO,QAAA;AACvE,EAAA,OAAO,YAAA,CAAa,IAAA,CAAK,OAAO,CAAA,GAAI,OAAA,GAAU,QAAA;AAChD;AA8CO,IAAM,WAAA,GAA2B;AAAA,EACtC,IAAA,EAAM,CAAC,MAAA,KAAoB,CAAA,EAAG,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,EAAG,MAAA,CAAO,UAAA,EAAY,CAAA;AAChF;AAEO,SAAS,0BAA0B,OAAA,EAA+C;AACvF,EAAA,IAAI,CAAC,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,gBAAA;AAAA,MACA,CAAA,mDAAA,EAAsD,QAAQ,KAAK,CAAA;AAAA,KACrE;AAAA,EACF;AACA,EAAA,IAAI,CAAC,SAAA,CAAU,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC7B,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,gBAAA;AAAA,MACA,CAAA,mDAAA,EAAsD,QAAQ,KAAK,CAAA;AAAA,KACrE;AAAA,EACF;AAGA,EAAA,0BAAA,CAA2B,OAAA,CAAQ,MAAA,EAAQ,OAAA,CAAQ,KAAK,CAAA;AACxD,EAAA,IAAI,CAAC,OAAO,SAAA,CAAU,OAAA,CAAQ,aAAa,CAAA,IAAK,OAAA,CAAQ,gBAAgB,CAAA,EAAG;AACzE,IAAA,MAAM,IAAI,aAAA;AAAA,MACR,gBAAA;AAAA,MACA,CAAA,6DAAA;AAAA,KACF;AAAA,EACF;AAGA,EAAA,MAAM,EAAE,OAAA,EAAS,IAAA,EAAK,GAAI,qBAAA,CAAsB;AAAA,IAC9C,SAAS,OAAA,CAAQ,OAAA;AAAA,IACjB,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,cAAc,OAAA,CAAQ,YAAA;AAAA,IACtB,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,GAAI,QAAQ,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAa,GAAI,EAAC;AAAA,IACnF,GAAI,QAAQ,+BAAA,KAAoC,MAAA,GAC5C,EAAE,+BAAA,EAAiC,OAAA,CAAQ,+BAAA,EAAgC,GAC3E;AAAC,GACN,CAAA;AACD,EAAA,MAAM,UAAU,OAAA,CAAQ,OAAA;AAIxB,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,OAAA,CAAQ,WAAA,CAAY,IAAA,KAAS,OAAA,EAAS;AACxC,IAAA,uBAAA,CAAwB,OAAA,CAAQ,MAAA,EAAQ,OAAA,CAAQ,WAAA,CAAY,gBAAgB,CAAA;AAC5E,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,4BAAA;AAAA,QACP,OAAA,CAAQ,MAAA;AAAA,QACR,QAAQ,WAAA,CAAY;AAAA,OACtB;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,gBAAA;AAAA,QACA,8IAAA;AAAA,QAEA,EAAE,KAAA;AAAM,OACV;AAAA,IACF;AACA,IAAA,OAAA,GAAU,6BAAA,CAA8B,MAAA,EAAQ,OAAA,EAAS,0BAA0B,CAAA;AAAA,EACrF,CAAA,MAAO;AACL,IAAA,OAAA,GAAU,8BAAA,CAA+B;AAAA,MACvC,GAAA,EAAK,QAAQ,WAAA,CAAY,GAAA;AAAA,MACzB,IAAA,EAAM,QAAQ,WAAA,CAAY;AAAA,KAC3B,CAAA;AAAA,EACH;AAKA,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,OAAA,CAAQ,MAAM,CAAA;AAC5C,EAAA,MAAM,kBAAA,GAAqB,uBAAA;AAAA,IACzB,OAAA,CAAQ,MAAA;AAAA,IACR,iBAAA;AAAA,IACA,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,WAAA;AAC/B,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,IAAO,WAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,WAAA;AACjC,EAAA,MAAM,iBAAA,GAAoB,QAAQ,iBAAA,IAAqB,2BAAA;AAEvD,EAAA,MAAM,UAAA,GAAgC;AAAA,IACpC,IAAA,EAAM,MAAA;AAAA,IACN,IAAA,EAAM,SAAA;AAAA,IACN,qBAAA,EAAuB,eAAA;AAAA,IACvB,aAAA,EAAe,SAAS,YAAY,CAAA,2BAAA,CAAA;AAAA,IACpC,YAAA,EAAc;AAAA,MACZ,WAAA;AAAA,MACA,CAAA,EAAG,QAAQ,IAAI,CAAA,YAAA,CAAA;AAAA,MACf,UAAA;AAAA,MACA,QAAA;AAAA,MACA,QAAQ,IAAI,CAAA,CAAA;AAAA,MACZ,oBAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,MAAA,EAAQ,QAAA;AAAA,IACR,WAAA,EAAa;AAAA,MACX,KAAA;AAAA,MACA,SAAA;AAAA,MACA,aAAA;AAAA,MACA,yBAAA;AAAA,MACA;AAAA;AACF,GACF;AAEA,EAAA,eAAe,kBAAkB,OAAA,EAAsD;AACrF,IAAA,MAAM,SAAS,oBAAA,CAAqB,OAAA,CAAQ,QAAQ,OAAA,CAAQ,aAAa,EAAE,QAAA,EAAS;AACpF,IAAA,MAAM,WAAA,GACJ,QAAQ,oBAAA,GAAuB,OAAA,CAAQ,SAAS,EAAE,CAAA,IAClD,QAAQ,WAAA,IACR,yBAAA;AAEF,IAAA,MAAM,YAAA,GAAoC;AAAA,MACxC,MAAA,EAAQ,OAAA;AAAA,MACR,OAAA;AAAA,MACA,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,MAAA;AAAA,MACA,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,iBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,KAAA,EAAO;AAAA,QACL,MAAM,OAAA,CAAQ,SAAA;AAAA,QACd,SAAS,OAAA,CAAQ,YAAA;AAAA,QACjB,mBAAA,EAAqB,SAAA;AAAA,QACrB,GAAI,WAAA,KAAgB,SAAA,GAAY,EAAE,WAAA,KAAgB;AAAC;AACrD,KACF;AAQA,IAAA,MAAM,QAAA,GAA4B;AAAA,MAChC,WAAA,EAAa,YAAA;AAAA,MACb,QAAA,EAAU;AAAA,QACR,GAAA,EAAK,CAAA,0BAAA,EAA6B,kBAAA,CAAmB,OAAA,CAAQ,OAAO,CAAC,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAK,CAAA,WAAA,EAAc,kBAAA,CAAmB,OAAA,CAAQ,QAAA,CAAS,EAAE,CAAC,CAAA,CAAA;AAAA,QAC3I,WAAA,EAAa,OAAA,CAAQ,QAAA,CAAS,WAAA,IAAe,QAAQ,QAAA,CAAS,IAAA;AAAA,QAC9D,QAAA,EAAU;AAAA,OACZ;AAAA,MACA,OAAA,EAAS,CAAC,YAAY;AAAA,KACxB;AAEA,IAAA,MAAM,SAAA,GAAY,IAAI,IAAA,CAAK,KAAA,CAAM,GAAA,EAAI,CAAE,OAAA,EAAQ,GAAI,iBAAA,GAAoB,GAAI,CAAA,CAAE,WAAA,EAAY;AAEzF,IAAA,OAAO;AAAA,MACL,EAAA,EAAI,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA;AAAA,MACrB,WAAW,OAAA,CAAQ,SAAA;AAAA,MACnB,UAAA,EAAY,QAAQ,QAAA,CAAS,EAAA;AAAA,MAC7B,QAAA,EAAU,MAAA;AAAA,MACV,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,UAAU,OAAA,CAAQ,QAAA;AAAA,MAClB,aAAa,OAAA,CAAQ,KAAA;AAAA,MACrB,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,OAAO,OAAA,CAAQ,KAAA;AAAA,MACf,SAAA;AAAA,MACA,SAAA,EAAW;AAAA,QACT,QAAA,EAAU,MAAA;AAAA,QACV,OAAA,EAAS,qBAAA;AAAA,QACT,OAAA,EAAS,CAAC,YAAkD,CAAA;AAAA,QAC5D;AAAA,OACF;AAAA,MACA,UAAU,EAAE,CAAC,iCAAiC,GAAG,gBAAgB,eAAA;AAAgB,KACnF;AAAA,EACF;AAWA,EAAA,eAAe,OAAO,OAAA,EAA6D;AACjF,IAAA,MAAM,EAAE,WAAA,EAAa,UAAA,EAAW,GAAI,OAAA;AAEpC,IAAA,MAAM,QAAA,GAAW,CAAC,MAAA,MAAmC;AAAA,MACnD,MAAA,EAAQ,UAAA;AAAA,MACR,QAAA,EAAU,MAAA;AAAA,MACV,QAAQ,WAAA,CAAY,MAAA;AAAA,MACpB,UAAU,WAAA,CAAY,QAAA;AAAA,MACtB,GAAI,YAAY,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,WAAA,CAAY,OAAA,EAAQ,GAAI,EAAC;AAAA,MAC5E,GAAI,YAAY,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,WAAA,CAAY,KAAA,EAAM,GAAI,EAAC;AAAA,MACtE,eAAA,EAAiB;AAAA,KACnB,CAAA;AAEA,IAAA,IAAI,YAAY,QAAA,KAAa,MAAA,IAAU,WAAA,CAAY,SAAA,CAAU,aAAa,MAAA,EAAQ;AAChF,MAAA,OAAO,SAAS,gBAAgB,CAAA;AAAA,IAClC;AAEA,IAAA,MAAM,YAAA,GAAe,WAAA,CAAY,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA;AACpD,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAO,SAAS,8BAA8B,CAAA;AAAA,IAChD;AAKA,IAAA,IACE,WAAA,CAAY,SAAA,KAAc,MAAA,IAC1B,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,SAAS,CAAA,GAAI,KAAA,CAAM,GAAA,EAAI,CAAE,OAAA,EAAQ,EACxD;AACA,MAAA,OAAO,SAAS,qBAAqB,CAAA;AAAA,IACvC;AAKA,IAAA,IACE,CAAC,SAAA,CAAU,YAAA,CAAa,KAAK,CAAA,IAC7B,UAAA,CAAW,YAAA,CAAa,KAAK,CAAA,KAAM,UAAA,CAAW,OAAA,CAAQ,KAAK,CAAA,EAC3D;AACA,MAAA,OAAO,SAAS,aAAa,CAAA;AAAA,IAC/B;AAEA,IAAA,MAAM,OAAA,GAAU,uBAAA,CAAwB,UAAA,CAAW,OAAO,CAAA;AAC1D,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,UAAA,CAAW,OAAO,CAAA;AACtD,MAAA,OAAO,QAAA;AAAA,QACL,OAAO,OAAA,KAAY,QAAA,IAAY,OAAA,KAAY,eACvC,sBAAA,GACA;AAAA,OACN;AAAA,IACF;AACA,IAAA,IAAI,OAAA,CAAQ,gBAAgB,YAAA,EAAc;AACxC,MAAA,OAAO,SAAS,sBAAsB,CAAA;AAAA,IACxC;AACA,IAAA,IAAI,CAAC,iBAAA,CAAkB,OAAO,CAAA,EAAG;AAC/B,MAAA,OAAO,SAAS,oBAAoB,CAAA;AAAA,IACtC;AAEA,IAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,CAAQ,OAAA;AAElC,IAAA,IAAI,CAAC,UAAU,aAAA,CAAc,IAAI,KAAK,CAAC,SAAA,CAAU,aAAA,CAAc,EAAE,CAAA,EAAG;AAClE,MAAA,OAAO,SAAS,iBAAiB,CAAA;AAAA,IACnC;AAGA,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,OAAA,KAAY,OAAA,CAAQ,OAAA,EAAS;AAChD,MAAA,OAAO,SAAS,iBAAiB,CAAA;AAAA,IACnC;AAGA,IAAA,MAAM,UAAA,GAAc,WAAA,CAAY,SAAA,CAAU,QAAA,EAA0C,QAAA,EAChF,GAAA;AACJ,IAAA,IACE,CAAC,oBAAA,CAAqB,YAAA,EAAc,OAAA,CAAQ,QAAQ,CAAA,IACnD,OAAA,CAAQ,QAAA,KAAa,MAAA,IAAa,OAAA,CAAQ,QAAA,CAAS,GAAA,KAAQ,UAAA,EAC5D;AACA,MAAA,OAAO,SAAS,8BAA8B,CAAA;AAAA,IAChD;AACA,IAAA,IAAI,WAAW,aAAA,CAAc,EAAE,MAAM,UAAA,CAAW,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC9D,MAAA,OAAO,SAAS,8CAA8C,CAAA;AAAA,IAChE;AACA,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,eAAA,GAAkB,MAAA,CAAO,cAAc,KAAK,CAAA;AAC5C,MAAA,QAAA,GAAW,MAAA,CAAO,aAAa,MAAM,CAAA;AAAA,IACvC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,SAAS,iBAAiB,CAAA;AAAA,IACnC;AACA,IAAA,IAAI,oBAAoB,QAAA,EAAU;AAChC,MAAA,OAAO,SAAS,wDAAwD,CAAA;AAAA,IAC1E;AAEA,IAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,EAAK;AAC3B,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI;AACF,MAAA,SAAA,GAAY,MAAM,KAAA,CAAM,MAAA,CAAO,eAAA,CAAgB,OAAO,GAAG,YAAY,CAAA;AAAA,IACvE,SAAS,GAAA,EAAK;AAGZ,MAAA,IAAI,CAAC,0BAAA,CAA2B,GAAG,KAAK,CAAC,KAAA,CAAM,iBAAgB,EAAG;AAChE,QAAA,MAAA,CAAO,KAAK,EAAE,GAAA,EAAK,kBAAkB,GAAG,CAAA,IAAK,qCAAqC,CAAA;AAAA,MACpF;AACA,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,8BAAA;AAAA,QACA,CAAA,eAAA,EAAkB,QAAQ,IAAI,CAAA,gDAAA,CAAA;AAAA,QAC9B,EAAE,OAAO,GAAA;AAAI,OACf;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AAEtB,MAAA,IAAI,KAAA,CAAM,iBAAgB,EAAG;AAC3B,QAAA,IAAI,SAAA,CAAU,kBAAkB,MAAA,EAAW;AACzC,UAAA,MAAA,CAAO,KAAA;AAAA,YACL,EAAE,cAAA,EAAgB,SAAA,CAAU,aAAA,EAAc;AAAA,YAC1C;AAAA,WACF;AAAA,QACF;AACA,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,8BAAA;AAAA,UACA,CAAA,eAAA,EAAkB,QAAQ,IAAI,CAAA,wCAAA;AAAA,SAChC;AAAA,MACF;AAGA,MAAA,IAAI,SAAA,CAAU,kBAAkB,MAAA,EAAW;AACzC,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,EAAE,cAAA,EAAgB,SAAA,CAAU,aAAA,EAAc;AAAA,UAC1C;AAAA,SACF;AAAA,MACF;AACA,MAAA,OAAO,QAAA,CAAS,cAAA,CAAe,SAAA,CAAU,aAAA,EAAe,iBAAiB,CAAC,CAAA;AAAA,IAC5E;AAIA,IAAA,MAAM,YAAY,gBAAA,CAAiB;AAAA,MACjC,SAAS,OAAA,CAAQ,OAAA;AAAA,MACjB,KAAA,EAAO,UAAA,CAAW,YAAA,CAAa,KAAK,CAAA;AAAA,MACpC,IAAA,EAAM,UAAA,CAAW,aAAA,CAAc,IAAI,CAAA;AAAA,MACnC,OAAO,aAAA,CAAc;AAAA,KACtB,CAAA;AAED,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,UAAA;AAAA,MACR,QAAA,EAAU,MAAA;AAAA,MACV,KAAA,EAAO,UAAA,CAAW,aAAA,CAAc,IAAI,CAAA;AAAA,MACpC,KAAA,EAAO,UAAA,CAAW,aAAA,CAAc,EAAE,CAAA;AAAA,MAClC,MAAA,EAAQ,WAAA,CAAY,eAAA,EAAiB,OAAA,CAAQ,aAAa,CAAA;AAAA,MAC1D,UAAU,WAAA,CAAY,QAAA;AAAA,MACtB,OAAA,EAAS,QAAQ,QAAA,CAAS,OAAA;AAAA,MAC1B,KAAA,EAAO,UAAA,CAAW,YAAA,CAAa,KAAK,CAAA;AAAA,MACpC;AAAA,KACF;AAAA,EACF;AAEA,EAAA,eAAe,OAAO,OAAA,EAA2D;AAC/E,IAAA,MAAM,EAAE,WAAA,EAAa,UAAA,EAAY,YAAA,EAAa,GAAI,OAAA;AAElD,IAAA,IAAI,YAAA,CAAa,WAAW,UAAA,EAAY;AACtC,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,iBAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,YAAA,GAAe,WAAA,CAAY,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA;AACpD,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,iBAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,uBAAA,CAAwB,UAAA,CAAW,OAAO,CAAA;AAC1D,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,iBAAA,CAAkB,OAAO,CAAA,EAAG;AAC3C,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,iBAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,MAAM,kBAAA,GAAqB,CAAC,eAAA,MAA4C;AAAA,MACtE,MAAA,EAAQ,UAAA;AAAA,MACR,QAAA,EAAU,MAAA;AAAA,MACV,QAAQ,YAAA,CAAa,MAAA;AAAA,MACrB,UAAU,WAAA,CAAY,QAAA;AAAA,MACtB,GAAI,aAAa,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,YAAA,CAAa,OAAA,EAAQ,GAAI,EAAC;AAAA,MAC9E,GAAI,aAAa,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,YAAA,CAAa,KAAA,EAAM,GAAI,EAAC;AAAA,MACxE,GAAI,aAAa,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,YAAA,CAAa,SAAA,EAAU,GAAI,EAAC;AAAA,MACpF;AAAA,KACF,CAAA;AAEA,IAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,EAAK;AAC3B,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI;AACF,MAAA,SAAA,GAAY,MAAM,KAAA,CAAM,MAAA,CAAO,eAAA,CAAgB,OAAO,GAAG,YAAY,CAAA;AAAA,IACvE,SAAS,GAAA,EAAK;AACZ,MAAA,IAAI,0BAAA,CAA2B,GAAG,CAAA,IAAK,KAAA,CAAM,iBAAgB,EAAG;AAC9D,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,8BAAA;AAAA,UACA,CAAA,eAAA,EAAkB,QAAQ,IAAI,CAAA,wCAAA,CAAA;AAAA,UAC9B,EAAE,OAAO,GAAA;AAAI,SACf;AAAA,MACF;AAOA,MAAA,IAAI,CAAC,oBAAA,CAAqB,GAAG,CAAA,EAAG;AAC9B,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,EAAE,GAAA,EAAK,iBAAA,CAAkB,GAAG,CAAA,EAAE;AAAA,UAC9B;AAAA,SACF;AACA,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,8BAAA;AAAA,UACA,8EAAA;AAAA,UACA,EAAE,OAAO,GAAA;AAAI,SACf;AAAA,MACF;AACA,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,EAAE,GAAA,EAAK,iBAAA,CAAkB,GAAG,CAAA,EAAG,iBAAiB,sBAAA,EAAuB;AAAA,QACvE;AAAA,OACF;AACA,MAAA,OAAO,mBAAmB,sBAAsB,CAAA;AAAA,IAClD;AAEA,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;AAOtB,MAAA,IACE,SAAA,CAAU,gBAAgB,yBAAA,IAC1B,CAAC,oBAAoB,IAAA,CAAK,SAAA,CAAU,WAAW,CAAA,EAC/C;AACA,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,EAAE,cAAA,EAAgB,SAAA,CAAU,WAAA,EAAY;AAAA,UACxC;AAAA,SACF;AACA,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,8BAAA;AAAA,UACA;AAAA,SACF;AAAA,MACF;AACA,MAAA,IAAI,SAAA,CAAU,WAAA,KAAgB,yBAAA,IAA6B,KAAA,CAAM,iBAAgB,EAAG;AAClF,QAAA,MAAM,IAAI,aAAA;AAAA,UACR,8BAAA;AAAA,UACA,oEAAA;AAAA,UACA;AAAA,YACE,GAAI,SAAA,CAAU,WAAA,GACV,EAAE,OAAA,EAAS,EAAE,eAAA,EAAiB,SAAA,CAAU,WAAA,EAAY,EAAE,GACtD;AAAC;AACP,SACF;AAAA,MACF;AACA,MAAA,IAAI,SAAA,CAAU,gBAAgB,MAAA,EAAW;AACvC,QAAA,MAAA,CAAO,KAAA;AAAA,UACL,EAAE,cAAA,EAAgB,SAAA,CAAU,WAAA,EAAY;AAAA,UACxC;AAAA,SACF;AAAA,MACF;AACA,MAAA,OAAO;AAAA,QACL,GAAG,kBAAA,CAAmB,cAAA,CAAe,SAAA,CAAU,WAAA,EAAa,mBAAmB,CAAC,CAAA;AAAA,QAChF,SAAS,SAAA,CAAU,OAAA;AAAA,QACnB,GAAI,UAAU,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAM,GAAI;AAAC,OACpE;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,SAAA;AAAA,MACR,QAAA,EAAU,MAAA;AAAA,MACV,mBAAmB,SAAA,CAAU,WAAA;AAAA,MAC7B,GAAI,UAAU,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,SAAA,CAAU,KAAA,EAAM,GAAI,EAAC;AAAA,MAClE,OAAO,YAAA,CAAa,KAAA;AAAA,MACpB,QAAQ,YAAA,CAAa,MAAA;AAAA,MACrB,UAAU,WAAA,CAAY,QAAA;AAAA,MACtB,SAAS,SAAA,CAAU,OAAA;AAAA,MACnB,GAAI,aAAa,KAAA,KAAU,MAAA,GAAY,EAAE,KAAA,EAAO,YAAA,CAAa,KAAA,EAAM,GAAI,EAAC;AAAA,MACxE,GAAI,aAAa,SAAA,KAAc,MAAA,GAAY,EAAE,SAAA,EAAW,YAAA,CAAa,SAAA,EAAU,GAAI,EAAC;AAAA,MACpF,SAAA,EAAW,MAAM,MAAA,EAAO;AAAA;AAAA,MAExB,UAAU,EAAE,eAAA,EAAiB,OAAA,CAAQ,OAAA,CAAQ,cAAc,KAAA;AAAM,KACnE;AAAA,EACF;AAEA,EAAA,eAAe,aAAA,GAAwC;AACrD,IAAA,MAAM,SAAA,GAAY,MAAM,WAAA,EAAY;AACpC,IAAA,MAAM,SAAA,GAAY,MAAM,MAAA,EAAO;AAE/B,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,kBAAA,CAAmB,UAAA,EAAW;AACpD,MAAA,IAAI,OAAA,KAAY,QAAQ,OAAA,EAAS;AAC/B,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,MAAA;AAAA,UACR,MAAA,EAAQ,CAAA,OAAA,EAAU,SAAS,CAAA,kBAAA,EAAqB,OAAO,cAAc,OAAA,CAAQ,OAAO,CAAA,EAAA,EAAK,OAAA,CAAQ,WAAW,CAAA,CAAA,CAAA;AAAA,UAC5G,SAAA;AAAA,UACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,SACpC;AAAA,MACF;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,kBAAA,CAAmB,OAAA,CAAQ,EAAE,OAAA,EAAS,OAAA,CAAQ,OAAO,CAAA;AACxE,MAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,KAAS,IAAA,EAAM;AAC1B,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,MAAA;AAAA,UACR,MAAA,EAAQ,CAAA,mDAAA,EAAsD,OAAA,CAAQ,KAAK,CAAA,CAAA;AAAA,UAC3E,SAAA;AAAA,UACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,SACpC;AAAA,MACF;AAEA,MAAA,IAAI,OAAA,CAAQ,SAAS,QAAA,EAAU;AAG7B,QAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,SAAA,EAAU;AACtC,QAAA,MAAM,aAAa,KAAA,CAAM,IAAA;AAAA,UACvB,CAAC,IAAA,KACC,IAAA,CAAK,WAAA,KAAgB,YAAA,IACrB,KAAK,MAAA,KAAW,OAAA,IAChB,IAAA,CAAK,OAAA,KAAY,OAAA,CAAQ;AAAA,SAC7B;AACA,QAAA,IAAI,CAAC,UAAA,EAAY;AACf,UAAA,OAAO;AAAA,YACL,MAAA,EAAQ,MAAA;AAAA,YACR,MAAA,EACE,CAAA,YAAA,EAAe,OAAA,CAAQ,QAAQ,CAAA,0BAAA,EAA6B,YAAY,CAAA,iBAAA,EAClE,OAAA,CAAQ,OAAO,CAAA,EAAA,EAAK,OAAA,CAAQ,WAAW,CAAA,2CAAA,CAAA;AAAA,YAC/C,SAAA;AAAA,YACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,WACpC;AAAA,QACF;AACA,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,MAAA;AAAA,UACR,MAAA,EACE,GAAG,sBAAA,CAAuB,IAAI,CAAC,CAAA,MAAA,EAAS,SAAS,wBAC9C,OAAA,CAAQ,OAAO,KAAK,OAAA,CAAQ,WAAW,YAAY,OAAA,CAAQ,KAAK,0BACpD,OAAA,CAAQ,QAAQ,CAAA,gBAAA,EAAmB,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,UACnE,SAAA;AAAA,UACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,SACpC;AAAA,MACF;AAKA,MAAA,MAAM,OAAA,GAAU,MAAM,gBAAA,CAAiB,kBAAkB,CAAA;AACzD,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAO;AAAA,UACL,MAAA,EAAQ,MAAA;AAAA,UACR,MAAA,EACE,CAAA,OAAA,EAAU,SAAS,CAAA,kBAAA,EAAqB,QAAQ,OAAO,CAAA,qJAAA,CAAA;AAAA,UAGzD,SAAA;AAAA,UACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,SACpC;AAAA,MACF;AAEA,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,MAAA;AAAA,QACR,MAAA,EACE,CAAA,EAAG,sBAAA,CAAuB,IAAI,CAAC,CAAA,MAAA,EAAS,SAAS,CAAA,qBAAA,EAC9C,OAAA,CAAQ,OAAO,CAAA,QAAA,EAAW,OAAA,CAAQ,KAAK,CAAA,mCAAA,CAAA;AAAA,QAC5C,SAAA;AAAA,QACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,OACpC;AAAA,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,MAAA;AAAA,QACR,MAAA,EAAQ,CAAA,0BAAA,EAA6B,iBAAA,CAAkB,GAAG,CAAC,CAAA,CAAA;AAAA,QAC3D,SAAA;AAAA,QACA,UAAA,EAAY,KAAA,CAAM,WAAA,EAAY,GAAI;AAAA,OACpC;AAAA,IACF;AAAA,EACF;AAQA,EAAA,MAAM,eAAA,GAAkB,GAAA;AACxB,EAAA,IAAI,YAAA;AACJ,EAAA,IAAI,cAAA;AAEJ,EAAA,eAAe,MAAA,GAAiC;AAC9C,IAAA,MAAM,GAAA,GAAM,MAAM,WAAA,EAAY;AAC9B,IAAA,IAAI,YAAA,IAAgB,GAAA,GAAM,YAAA,CAAa,EAAA,GAAK,eAAA,EAAiB;AAC3D,MAAA,OAAO,YAAA,CAAa,KAAA;AAAA,IACtB;AACA,IAAA,IAAI,gBAAgB,OAAO,cAAA;AAE3B,IAAA,cAAA,GAAiB,aAAA,EAAc,CAC5B,IAAA,CAAK,CAAC,KAAA,KAAU;AACf,MAAA,YAAA,GAAe,EAAE,EAAA,EAAI,KAAA,CAAM,WAAA,IAAe,KAAA,EAAM;AAChD,MAAA,OAAO,KAAA;AAAA,IACT,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;AACb,MAAA,cAAA,GAAiB,MAAA;AAAA,IACnB,CAAC,CAAA;AACH,IAAA,OAAO,cAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,UAAA;AAAA,IACA,iBAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF;AAOA,SAAS,oBAAA,CACP,SACA,QAAA,EACS;AACT,EAAA,MAAM,WAAA,GAAc,CAAC,CAAA,EAAW,CAAA,KAAc,EAAE,WAAA,EAAY,KAAM,EAAE,WAAA,EAAY;AAChF,EAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,KAAA,IAAS,EAAC;AACvC,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,KAAA,IAAS,EAAC;AACzC,EAAA,MAAM,IAAA,GAAO,CAAC,KAAA,KACZ,KAAA,CAAM,aAAa,CAAA,IAAK,yBAAA;AAC1B,EAAA,OACE,SAAS,MAAA,KAAW,OAAA,CAAQ,UAC5B,QAAA,CAAS,OAAA,KAAY,QAAQ,OAAA,IAC7B,QAAA,CAAS,WAAW,OAAA,CAAQ,MAAA,IAC5B,YAAY,QAAA,CAAS,KAAA,EAAO,QAAQ,KAAK,CAAA,IACzC,YAAY,QAAA,CAAS,KAAA,EAAO,QAAQ,KAAK,CAAA,IACzC,OAAO,OAAA,CAAQ,YAAY,EAAE,KAAA,CAAM,CAAC,CAAC,GAAA,EAAK,KAAK,MAAM,aAAA,CAAc,GAAG,MAAM,KAAK,CAAA,IACjF,KAAK,aAAa,CAAA,KAAM,KAAK,YAAY,CAAA;AAE7C;AAMA,SAAS,qBAAqB,GAAA,EAAuB;AACnD,EAAA,OACE,GAAA,YAAe,aAAa,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,YAAa,6BAA6B,CAAA,KAAM,IAAA;AAEhG;AAUA,SAAS,2BAA2B,GAAA,EAAuB;AACzD,EAAA,IACE,GAAA,YAAe,gBAAA,IACf,GAAA,YAAe,YAAA,IACf,eAAe,qCAAA,EACf;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,GAAG,CAAA,CAAE,WAAA,EAAY;AACnD,EAAA,OACE,OAAA,CAAQ,SAAS,cAAc,CAAA,IAC/B,QAAQ,QAAA,CAAS,cAAc,CAAA,IAC/B,OAAA,CAAQ,QAAA,CAAS,WAAW,KAC5B,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,IAC5B,OAAA,CAAQ,SAAS,WAAW,CAAA,IAC5B,OAAA,CAAQ,QAAA,CAAS,eAAe,CAAA;AAEpC;AAMA,eAAe,iBACb,MAAA,EACkB;AAElB,EAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AAIvB,EAAA,IAAI;AACF,IAAA,MAAM,QAAQ,EAAE,MAAA,EAAQ,kBAAkB,MAAA,EAAQ,IAAI,CAAA;AACtD,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"chunk-RKBGCPCK.js","sourcesContent":["/**\n * Exact conversion from display amounts (\"0.01\" USDC) to the integer base\n * units x402 and EIP-3009 carry (\"10000\" at 6 decimals).\n *\n * It never goes through a JS `number`, which cannot represent most decimal\n * fractions. viem's `parseUnits` is not used either: it silently rounds excess\n * fractional digits, and \"0.0000001\" against a 6-decimal asset is a\n * configuration bug that must be refused, not rounded. The reverse direction\n * is viem's `formatUnits`, which is exact.\n */\nimport { CommerceError } from '../../core';\n\nconst DECIMAL_STRING_PATTERN = /^\\d+(?:\\.\\d+)?$/;\n\n/**\n * Parses a canonical decimal display amount (e.g. \"0.01\") into base units\n * for an asset with the given number of decimals, without floating point.\n *\n * Throws `CommerceError('PAYMENT_INVALID')` if the string is not a plain\n * non-negative decimal, or if it carries more fractional digits than the\n * asset supports.\n */\nexport function parseCanonicalAmount(amount: string, decimals: number): bigint {\n if (!Number.isInteger(decimals) || decimals < 0) {\n throw new CommerceError('INTERNAL_ERROR', `Invalid asset decimals: ${decimals}`);\n }\n if (!DECIMAL_STRING_PATTERN.test(amount)) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n `Amount \"${amount}\" is not a valid non-negative decimal string`,\n {\n details: { amount },\n },\n );\n }\n\n const [integerPart = '0', fractionPart = ''] = amount.split('.');\n\n if (fractionPart.length > decimals) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n `Amount \"${amount}\" has more precision than the asset supports (${decimals} decimals)`,\n { details: { amount, assetDecimals: decimals } },\n );\n }\n\n const paddedFraction = fractionPart.padEnd(decimals, '0');\n const combined = `${integerPart}${paddedFraction}`;\n return BigInt(combined);\n}\n","/**\n * viem clients for the x402 provider, built on the configured `rpcUrl`. The\n * SDK uses the client it is handed, so the provider's chain calls reach no\n * other RPC.\n *\n * Despite the `Local` names, `createLocalFacilitatorClient` sits on the\n * settlement path and `createLocalPublicClient` backs `health()`. The health\n * client is built for whichever network is configured. The facilitator client\n * always uses chain id 84532: an in-process facilitator is refused on a\n * mainnet, and Base Sepolia is the registry's only testnet. Registering a\n * second testnet means building this client for the configured chain.\n */\nimport {\n type Account,\n type Chain,\n type Client,\n createPublicClient,\n createWalletClient,\n http,\n type PublicActions,\n type PublicClient,\n publicActions,\n type Transport,\n type WalletActions,\n} from 'viem';\nimport { privateKeyToAccount } from 'viem/accounts';\nimport { LOCAL_CHAIN_ID } from './networks';\n\n/** A wallet client that can also read chain state, matching x402's `SignerWallet` */\nexport type LocalFacilitatorClient = Client<\n Transport,\n Chain,\n Account,\n undefined,\n PublicActions<Transport, Chain, Account> & WalletActions<Chain, Account>\n>;\n\n/** CAIP-2 identifier the local dev chain is advertised under */\nexport const LOCAL_NETWORK = `eip155:${LOCAL_CHAIN_ID}`;\n\n/**\n * Chain id carried by a CAIP-2 `eip155` network identifier, or `undefined` for\n * anything else. A caller must never fall back to a default chain id, because\n * the chain id is part of the EIP-712 domain the buyer signed.\n */\nexport function chainIdFromCaip2(network: string): number | undefined {\n const match = /^eip155:(\\d+)$/.exec(network);\n if (!match?.[1]) return undefined;\n const chainId = Number(match[1]);\n return Number.isSafeInteger(chainId) && chainId > 0 ? chainId : undefined;\n}\n\n/**\n * `chainId` defaults to the local dev chain, the only chain the facilitator\n * client is built for. The health client passes the configured network's id.\n */\nfunction buildLocalChain(rpcUrl: string, chainId: number = LOCAL_CHAIN_ID): Chain {\n return {\n id: chainId,\n name: 'agent-commerce-local',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: {\n default: { http: [rpcUrl] },\n },\n } satisfies Chain;\n}\n\n/**\n * A read-only viem `PublicClient`.\n *\n * `timeoutMs` goes to viem's `http()` transport, which aborts the underlying\n * `fetch` when it expires rather than only abandoning the wait. Omit it to keep\n * viem's default of 10s.\n */\nexport function createLocalPublicClient(\n rpcUrl: string,\n timeoutMs?: number,\n chainId?: number,\n): PublicClient {\n return createPublicClient({\n chain: buildLocalChain(rpcUrl, chainId),\n transport: http(rpcUrl, timeoutMs !== undefined ? { timeout: timeoutMs } : undefined),\n });\n}\n\n/**\n * A viem `WalletClient` extended with public actions, for the local\n * facilitator signer only: the SDK's settlement both writes and reads through\n * it.\n *\n * LOCAL DEVELOPMENT ONLY. The key behind it pays gas on the dev chain. It is\n * usually an Anvil well-known key, and must never be a merchant, buyer or\n * production key.\n */\nexport function createLocalFacilitatorClient(\n rpcUrl: string,\n signerPrivateKey: `0x${string}`,\n): LocalFacilitatorClient {\n const chain = buildLocalChain(rpcUrl);\n const account = privateKeyToAccount(signerPrivateKey);\n return createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n }).extend(publicActions);\n}\n","/**\n * The facilitator verifies an authorization and broadcasts the transfer. Two\n * kinds sit behind one interface, both driving the SDK's own code:\n *\n * local the SDK's in-process `x402Facilitator`, signing against a dev node\n * remote the SDK's HTTP facilitator client, with or without a credential\n *\n * Each verify or settle call opens its own session so that `transportFailed()`\n * covers one request only: concurrent payments must not see each other's\n * transport failures.\n */\nimport { x402Facilitator } from '@x402/core/facilitator';\nimport { HTTPFacilitatorClient } from '@x402/core/http';\nimport {\n type Network,\n type PaymentPayload,\n type PaymentRequirements,\n SettleError,\n type SettleResponse,\n VerifyError,\n type VerifyResponse,\n} from '@x402/core/types';\nimport { toFacilitatorEvmSigner } from '@x402/evm';\nimport { registerExactEvmScheme } from '@x402/evm/exact/facilitator';\nimport { CommerceError } from '../../core';\nimport type { LocalFacilitatorClient } from './chain';\nimport type { FacilitatorAuth } from './guardrails';\n\n/** One verify or one settle, with its own transport-failure flag */\nexport interface FacilitatorSession {\n verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;\n settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;\n /**\n * True when the call produced no verdict: the local binding sets it when an\n * RPC call to the chain fails in transport, the remote binding on every\n * throw other than a 400 refusal of a verify or a settle.\n *\n * The SDK's `exact`/EVM scheme reports its own RPC errors as ordinary\n * verification failures: an unreachable node comes back as\n * `invalid_exact_evm_signature`. Without this flag the buyer would be told\n * their signature is bad for a payment nothing checked.\n */\n transportFailed(): boolean;\n}\n\nexport interface SupportedKind {\n readonly x402Version: number;\n readonly scheme: string;\n readonly network: string;\n}\n\ninterface BindingBase {\n /** Human-readable, never a credential */\n readonly describe: string;\n open(): FacilitatorSession;\n}\n\nexport type FacilitatorBinding =\n | (BindingBase & { readonly kind: 'local' })\n | (BindingBase & {\n readonly kind: 'remote';\n /** What the facilitator says it can settle. Used by health(), not by the payment path */\n supported(): Promise<readonly SupportedKind[]>;\n });\n\n// Bounds each receipt wait of the in-process facilitator, and each request to a\n// remote one\nconst SETTLEMENT_CONFIRMATION_TIMEOUT_MS = 60_000;\n\n/**\n * An in-process `x402Facilitator` with the `exact`/EVM scheme registered for\n * one network rather than an `eip155:*` wildcard, so a payload naming another\n * chain finds no scheme at all\n */\nexport function createLocalFacilitatorBinding(\n client: LocalFacilitatorClient,\n network: string,\n isTransportError: (err: unknown) => boolean,\n): FacilitatorBinding {\n const build = (): { facilitator: x402Facilitator; failed: () => boolean } => {\n let failed = false;\n const watch = <T>(promise: Promise<T>): Promise<T> =>\n promise.catch((err: unknown) => {\n if (isTransportError(err)) failed = true;\n throw err;\n });\n\n // Exactly the `FacilitatorEvmSigner` surface, so every call the SDK makes is\n // watched. `toFacilitatorEvmSigner` wants a flat `address`, which viem\n // keeps on `client.account`.\n const signer = {\n address: client.account.address,\n readContract: (args: Parameters<LocalFacilitatorClient['readContract']>[0]) =>\n watch(client.readContract(args)),\n verifyTypedData: (args: Parameters<LocalFacilitatorClient['verifyTypedData']>[0]) =>\n watch(client.verifyTypedData(args)),\n writeContract: (args: Parameters<LocalFacilitatorClient['writeContract']>[0]) =>\n watch(client.writeContract(args)),\n sendTransaction: (args: Parameters<LocalFacilitatorClient['sendTransaction']>[0]) =>\n watch(client.sendTransaction(args)),\n waitForTransactionReceipt: (\n args: Parameters<LocalFacilitatorClient['waitForTransactionReceipt']>[0],\n ) => watch(client.waitForTransactionReceipt(args)),\n getCode: (args: Parameters<LocalFacilitatorClient['getCode']>[0]) =>\n watch(client.getCode(args)),\n } as unknown as Parameters<typeof toFacilitatorEvmSigner>[0];\n\n // `confirmationTimeoutMs` turns a lost receipt wait into `settlement_pending`\n // with the broadcast hash, instead of a discarded broadcast\n const facilitator = registerExactEvmScheme(new x402Facilitator(), {\n signer: toFacilitatorEvmSigner(signer, {\n confirmationTimeoutMs: SETTLEMENT_CONFIRMATION_TIMEOUT_MS,\n }),\n networks: network as Network,\n });\n\n return { facilitator, failed: () => failed };\n };\n\n return {\n kind: 'local',\n describe: 'local (in-process)',\n open(): FacilitatorSession {\n const { facilitator, failed } = build();\n return {\n verify: (payload, requirements) => facilitator.verify(payload, requirements),\n settle: (payload, requirements) => facilitator.settle(payload, requirements),\n transportFailed: failed,\n };\n },\n };\n}\n\nexport interface RemoteFacilitatorOptions {\n readonly url: string;\n readonly auth: FacilitatorAuth;\n}\n\n// The SDK's path-keyed auth-header shape. A flat object throws inside it\ntype AuthHeaderFactory = () => Promise<Record<string, Record<string, string>>>;\n\n/**\n * CDP needs a fresh JWT per request over method, host and path, which a static\n * header cannot express. The optional peer `@coinbase/x402` does the signing.\n * It is imported dynamically, so only `auth.type: cdp` pulls in the CDP SDK and\n * its Solana, axios and JOSE dependencies.\n *\n * The import starts at construction, so a missing peer fails the health check\n * before any payment needs it. A payment that arrives first fails as\n * `PAYMENT_PROVIDER_UNAVAILABLE`, never as a rejection blamed on the buyer.\n */\nfunction cdpAuthHeaders(apiKeyId: string, apiKeySecret: string): AuthHeaderFactory {\n const loading = import('@coinbase/x402').then(\n (mod) => mod.createCdpAuthHeaders(apiKeyId, apiKeySecret),\n (cause: unknown) => {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: facilitator.auth.type is \"cdp\", which needs the optional peer ' +\n '\"@coinbase/x402\". Install it (npm install @coinbase/x402), or use a facilitator ' +\n 'that accepts a static token with auth.type \"bearer\".',\n { cause },\n );\n },\n );\n // Nothing awaits this before the first call, so without a handler a failed\n // import would be an unhandled rejection at startup\n loading.catch(() => {});\n\n return async () => {\n const create = await loading;\n if (!create) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: @coinbase/x402 returned no auth-header factory',\n );\n }\n return (await create()) as Record<string, Record<string, string>>;\n };\n}\n\n/**\n * A 400 from `/verify` whose body names an `invalidReason` is the facilitator\n * refusing the payment, so it returns as an invalid verdict. The SDK throws it\n * as a `VerifyError`, which keeps the status and reason but not `isValid`.\n * A 400 without a reason and every other status, 401, 403, 429 and 5xx\n * included, are rethrown as \"no verdict\".\n */\nfunction verdictFromVerifyError(err: unknown): VerifyResponse {\n if (\n err instanceof VerifyError &&\n err.statusCode === 400 &&\n typeof err.invalidReason === 'string'\n ) {\n return {\n isValid: false,\n invalidReason: err.invalidReason,\n ...(err.payer !== undefined ? { payer: err.payer } : {}),\n };\n }\n throw err;\n}\n\n/**\n * Treat a remote 400 as a refusal only when it names a reason and no\n * transaction. A transaction may have broadcast; other errors have no\n * verdict. `SettleError` does not retain the response's `success`.\n */\nfunction verdictFromSettleError(err: unknown, network: Network): SettleResponse {\n if (\n err instanceof SettleError &&\n err.statusCode === 400 &&\n typeof err.errorReason === 'string' &&\n err.errorReason !== '' &&\n !err.transaction\n ) {\n return {\n success: false,\n errorReason: err.errorReason,\n transaction: '',\n network: err.network ?? network,\n ...(err.payer !== undefined ? { payer: err.payer } : {}),\n };\n }\n throw err;\n}\n\n/**\n * An HTTP facilitator. The SDK client produces the auth headers per request;\n * this module never logs them, and they appear neither in `/.well-known` nor\n * in `describe`.\n */\nexport function createRemoteFacilitatorBinding(\n options: RemoteFacilitatorOptions,\n): FacilitatorBinding {\n const auth = options.auth;\n let createAuthHeaders: AuthHeaderFactory | undefined;\n if (auth.type === 'bearer') {\n createAuthHeaders = async () => {\n // Path-keyed, as the SDK requires (see `AuthHeaderFactory`)\n const headers = { Authorization: `Bearer ${auth.token}` };\n return { verify: headers, settle: headers, supported: headers };\n };\n } else if (auth.type === 'cdp') {\n createAuthHeaders = cdpAuthHeaders(auth.apiKeyId, auth.apiKeySecret);\n }\n\n const client = new HTTPFacilitatorClient({\n url: options.url,\n timeoutMs: SETTLEMENT_CONFIRMATION_TIMEOUT_MS,\n ...(createAuthHeaders ? { createAuthHeaders } : {}),\n });\n\n return {\n kind: 'remote',\n describe: `remote ${new URL(options.url).origin} (auth=${auth.type})`,\n open(): FacilitatorSession {\n let failed = false;\n const watch = async <T>(call: () => Promise<T>): Promise<T> => {\n try {\n return await call();\n } catch (err) {\n // After known 400 refusals, a throw gives no verdict. It may be\n // transport or authentication failure; settlement may have broadcast.\n // Do not record it as a payer refusal.\n failed = true;\n throw err;\n }\n };\n return {\n verify: (payload, requirements) =>\n watch(() => client.verify(payload, requirements).catch(verdictFromVerifyError)),\n settle: (payload, requirements) =>\n watch(() =>\n client\n .settle(payload, requirements)\n .catch((err: unknown) => verdictFromSettleError(err, requirements.network)),\n ),\n transportFailed: () => failed,\n };\n },\n async supported(): Promise<readonly SupportedKind[]> {\n const response = await client.getSupported();\n return response.kinds as readonly SupportedKind[];\n },\n };\n}\n","/**\n * Decodes and validates the base64 `PAYMENT-SIGNATURE` submission.\n *\n * A malformed payload must become a `rejected` verification, never a thrown\n * request, so this returns `undefined` on any failure. That is why it parses\n * the schema itself instead of calling the SDK's `decodePaymentSignatureHeader`,\n * which throws.\n */\nimport { PaymentPayloadV2Schema } from '@x402/core/schemas';\nimport type { PaymentPayload } from '@x402/core/types';\nimport { type ExactEIP3009Payload, isEIP3009Payload } from '@x402/evm';\n\nexport function decodePaymentSubmission(payloadBase64: string): PaymentPayload | undefined {\n const json = decodeJson(payloadBase64);\n if (json === undefined) return undefined;\n const result = PaymentPayloadV2Schema.safeParse(json);\n return result.success ? (result.data as PaymentPayload) : undefined;\n}\n\n/** Read the declared version before v2 schema validation */\nexport function declaredX402Version(payloadBase64: string): unknown {\n const json = decodeJson(payloadBase64);\n return typeof json === 'object' && json !== null\n ? (json as Record<string, unknown>)['x402Version']\n : undefined;\n}\n\n/**\n * The payload as sent to a facilitator. `resource` is optional in v2 and\n * verify() has already matched it against the offer; hosted facilitators have\n * settled payloads without it, and none has been shown to accept this\n * gateway's `resource://` URL\n */\nexport function withoutResource<T extends PaymentPayload>(payload: T): Omit<T, 'resource'> {\n const { resource: _resource, ...rest } = payload;\n return rest;\n}\n\nfunction decodeJson(payloadBase64: string): unknown {\n try {\n return JSON.parse(Buffer.from(payloadBase64, 'base64').toString('utf8'));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Narrows a decoded payload to the EIP-3009 `exact`/EVM shape this provider\n * settles.\n *\n * The `exact` scheme on EVM also has a Permit2 method. The challenge names\n * EIP-3009 (`extra.assetTransferMethod`), and a Permit2 payload is rejected\n * here rather than handed to the SDK. On the local chain, which has no Permit2\n * proxy, it would fail as an opaque settlement revert.\n */\nexport function isExactEvmPayload(\n payload: PaymentPayload,\n): payload is PaymentPayload & { payload: ExactEIP3009Payload } {\n return (\n payload.accepted.scheme === 'exact' &&\n typeof payload.payload === 'object' &&\n payload.payload !== null &&\n isEIP3009Payload(payload.payload as ExactEIP3009Payload) &&\n typeof (payload.payload as ExactEIP3009Payload).signature === 'string'\n );\n}\n","/**\n * `PaymentResult.replayKey` is derived from the payment authorization alone\n * (chain id, asset, payer, nonce), never from the request id, so the same\n * authorization replayed on another request collides in the receipt store's\n * reservation. The MPP provider uses the same derivation.\n */\nimport { encodeAbiParameters, keccak256 } from 'viem';\n\nexport interface ReplayKeyInput {\n readonly chainId: number;\n readonly asset: `0x${string}`;\n readonly from: `0x${string}`;\n readonly nonce: `0x${string}`;\n}\n\nexport function computeReplayKey(input: ReplayKeyInput): string {\n const encoded = encodeAbiParameters(\n [{ type: 'uint256' }, { type: 'address' }, { type: 'address' }, { type: 'bytes32' }],\n [BigInt(input.chainId), input.asset, input.from, input.nonce],\n );\n return keccak256(encoded);\n}\n","/**\n * x402 payment provider: protocol v2, `exact` scheme, EVM, EIP-3009\n * `transferWithAuthorization`.\n *\n * `verify()` never moves funds. `settle()` does, and throws unless it is handed\n * a successful verification. Both run through a facilitator (see\n * `facilitator.ts`): the SDK's own `x402Facilitator` in this process, or a\n * remote HTTP facilitator.\n */\n\nimport type {\n Network,\n PaymentRequired,\n PaymentRequirements,\n SettleResponse,\n VerifyResponse,\n} from '@x402/core/types';\nimport {\n BaseError,\n ContractFunctionRevertedError,\n formatUnits,\n getAddress,\n HttpRequestError,\n isAddress,\n TimeoutError,\n WaitForTransactionReceiptTimeoutError,\n} from 'viem';\nimport {\n type AdapterDescriptor,\n type AdapterHealth,\n type Clock,\n CommerceError,\n type IdGenerator,\n type Logger,\n NOOP_LOGGER,\n type PaymentContext,\n type PaymentProvider,\n type PaymentRequirement,\n type PaymentResult,\n type PaymentSettlementContext,\n type PaymentVerificationContext,\n systemClock,\n} from '../../core';\nimport { redactedErrorText } from '../../core/errors';\nimport { SETTLE_AFTER_BACKEND_METADATA_KEY } from '../../core/execution/settlement-order';\nimport { PACKAGE_VERSION } from '../../version';\nimport { parseCanonicalAmount } from './amount';\nimport {\n createLocalFacilitatorClient,\n createLocalPublicClient,\n type LocalFacilitatorClient,\n} from './chain';\nimport { assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress, describeRpc } from './dev-key-guard';\nimport {\n createLocalFacilitatorBinding,\n createRemoteFacilitatorBinding,\n type FacilitatorBinding,\n} from './facilitator';\nimport { resolveX402Deployment, type X402FacilitatorConfig } from './guardrails';\nimport { describeDeploymentMode } from './networks';\nimport {\n declaredX402Version,\n decodePaymentSubmission,\n isExactEvmPayload,\n withoutResource,\n} from './payload';\nimport { X402_DEFAULT_PAYMENT_FLOW, type X402PaymentFlow } from './payment-flow';\nimport { computeReplayKey } from './replay-key';\n\nconst X402_VERSION = 2;\nconst X402_PROTOCOL_VERSION = String(X402_VERSION);\nconst DEFAULT_MAX_TIMEOUT_SECONDS = 60;\nconst DEFAULT_MIME_TYPE = 'application/json';\nconst HEALTH_TIMEOUT_MS = 4_000;\n// `SettleResponse.errorReason` the SDK uses for \"broadcast, not confirmed\"\nconst SETTLEMENT_PENDING_REASON = 'settlement_pending';\n/**\n * The SDK's catch-all for a throw from the broadcast call, and its reason for\n * a mined transaction that reverted. Only the second carries a hash. A revert\n * the SDK recognizes during gas estimation gets its own reason instead.\n */\nconst TRANSACTION_FAILED_REASON = 'invalid_exact_evm_transaction_failed';\n/**\n * `invalidReason`/`errorReason` are `z.string()` in the SDK schema, with no\n * length or charset bound. They reach the buyer's error, the persisted events\n * and the merchant's ledger. A remote facilitator controls these values, so\n * they are treated as untrusted input rather than diagnostic text.\n */\nconst MAX_REASON_LENGTH = 64;\nconst REASON_SHAPE = /^[a-z0-9_.-]+$/i;\n\nfunction sanitizeReason(reason: string | undefined, fallback: string): string {\n if (reason === undefined) return fallback;\n const trimmed = reason.trim();\n if (trimmed.length === 0 || trimmed.length > MAX_REASON_LENGTH) return fallback;\n return REASON_SHAPE.test(trimmed) ? trimmed : fallback;\n}\n\nexport interface X402ProviderOptions {\n /**\n * CAIP-2 network identifier, e.g. `eip155:84532`. The chain id it carries is\n * part of the EIP-712 domain the buyer signs, so it is read from this value\n * rather than defaulted.\n */\n readonly network: string;\n /** RPC endpoint. Local chain: http://127.0.0.1:8545 */\n readonly rpcUrl: string;\n /** ERC-20 (EIP-3009) asset address used for settlement */\n readonly asset: `0x${string}`;\n /** EIP-712 domain name of the asset, e.g. 'MockUSDC' */\n readonly assetName: string;\n /** EIP-712 domain version of the asset, e.g. '2' */\n readonly assetVersion: string;\n readonly assetDecimals: number;\n /** Merchant-controlled settlement destination. Never a gateway-owned wallet */\n readonly payTo: `0x${string}`;\n readonly maxTimeoutSeconds?: number;\n /**\n * When the payment settles relative to the backend call. Defaults to\n * `authorization`, the x402 default: settle only after the backend succeeds.\n * `upfront` settles before the backend call.\n */\n readonly paymentFlow?: X402PaymentFlow;\n /** Per-resource overrides of `paymentFlow`, keyed by resource id */\n readonly resourcePaymentFlows?: Readonly<Record<string, X402PaymentFlow>>;\n /**\n * Which facilitator verifies and broadcasts. `local` runs one in this process\n * against a dev chain, and its `signerPrivateKey` pays gas there, usually\n * an Anvil well-known key (LOCAL DEVELOPMENT ONLY - DO NOT FUND). `remote`\n * calls an HTTP facilitator, and the gateway then holds no signing key.\n */\n readonly facilitator: X402FacilitatorConfig;\n /** Must be `true` before anything settles on a mainnet. Never a default */\n readonly allowMainnet?: boolean;\n /** Required on mainnet when facilitator auth is `none` */\n readonly allowUnauthenticatedFacilitator?: boolean;\n readonly logger?: Logger;\n readonly clock?: Clock;\n readonly ids?: IdGenerator;\n}\n\n/** Prefixed random UUIDs, shared with the MPP rail */\nexport const DEFAULT_IDS: IdGenerator = {\n next: (prefix?: string) => `${prefix ? `${prefix}_` : ''}${crypto.randomUUID()}`,\n};\n\nexport function createX402PaymentProvider(options: X402ProviderOptions): PaymentProvider {\n if (!isAddress(options.asset)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"asset\" is not a valid EVM address: ${options.asset}`,\n );\n }\n if (!isAddress(options.payTo)) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"payTo\" is not a valid EVM address: ${options.payTo}`,\n );\n }\n // In every facilitator mode. `resolveX402Deployment` below also refuses a dev\n // payTo on any non-local deployment, whatever the RPC host.\n assertPayToIsNotDevAddress(options.rpcUrl, options.payTo);\n if (!Number.isInteger(options.assetDecimals) || options.assetDecimals < 0) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `x402 provider: \"assetDecimals\" must be a non-negative integer`,\n );\n }\n // The chain id is signed into the buyer's EIP-712 domain, so a network it\n // cannot be resolved from fails here, never at request time\n const { profile, mode } = resolveX402Deployment({\n network: options.network,\n payTo: options.payTo,\n asset: options.asset,\n assetName: options.assetName,\n assetVersion: options.assetVersion,\n facilitator: options.facilitator,\n ...(options.allowMainnet !== undefined ? { allowMainnet: options.allowMainnet } : {}),\n ...(options.allowUnauthenticatedFacilitator !== undefined\n ? { allowUnauthenticatedFacilitator: options.allowUnauthenticatedFacilitator }\n : {}),\n });\n const network = options.network as Network;\n // Built once, here, rather than in settle(): an unusable key fails the\n // provider at startup, not on the first paid request after that buyer's\n // replay key is already reserved\n let binding: FacilitatorBinding;\n if (options.facilitator.mode === 'local') {\n assertDevKeyIsLocalOnly(options.rpcUrl, options.facilitator.signerPrivateKey);\n let client: LocalFacilitatorClient;\n try {\n client = createLocalFacilitatorClient(\n options.rpcUrl,\n options.facilitator.signerPrivateKey as `0x${string}`,\n );\n } catch (cause) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n 'x402 provider: could not construct a local facilitator signer from ' +\n 'facilitator.signerPrivateKey. It must be a valid 32-byte hex private key.',\n { cause },\n );\n }\n binding = createLocalFacilitatorBinding(client, network, isProviderUnavailableError);\n } else {\n binding = createRemoteFacilitatorBinding({\n url: options.facilitator.url,\n auth: options.facilitator.auth,\n });\n }\n\n // health() reads the chain through its own client, whose timeout aborts the\n // request. Verification and settlement go through the facilitator instead.\n // Health details can reach logs, so they name the RPC by origin only.\n const rpcOrigin = describeRpc(options.rpcUrl);\n const healthPublicClient = createLocalPublicClient(\n options.rpcUrl,\n HEALTH_TIMEOUT_MS,\n profile.chainId,\n );\n\n const clock = options.clock ?? systemClock;\n const ids = options.ids ?? DEFAULT_IDS;\n const logger = options.logger ?? NOOP_LOGGER;\n const maxTimeoutSeconds = options.maxTimeoutSeconds ?? DEFAULT_MAX_TIMEOUT_SECONDS;\n\n const descriptor: AdapterDescriptor = {\n name: 'x402',\n kind: 'payment',\n implementationVersion: PACKAGE_VERSION,\n supportedSpec: `x402/v${X402_VERSION} scheme=exact family=eip155`,\n capabilities: [\n 'exact-evm',\n `${binding.kind}-facilitator`,\n 'eip-3009',\n 'caip-2',\n `mode=${mode}`,\n 'authorization-flow',\n 'upfront-flow',\n ],\n status: 'stable',\n unsupported: [\n 'svm',\n 'permit2',\n 'upto scheme',\n 'batch-settlement scheme',\n 'auth-capture scheme',\n ],\n };\n\n async function createRequirement(context: PaymentContext): Promise<PaymentRequirement> {\n const amount = parseCanonicalAmount(context.amount, options.assetDecimals).toString();\n const paymentFlow =\n options.resourcePaymentFlows?.[context.resource.id] ??\n options.paymentFlow ??\n X402_DEFAULT_PAYMENT_FLOW;\n\n const requirements: PaymentRequirements = {\n scheme: 'exact',\n network,\n asset: options.asset,\n amount,\n payTo: options.payTo,\n maxTimeoutSeconds,\n // `name`/`version` let the buyer and the facilitator build the same\n // EIP-712 domain without calling `version()` on the token.\n // `assetTransferMethod` names the one method this provider settles, so a\n // conforming client never picks the `exact` scheme's Permit2 path.\n // x402 requires an explicit non-default flow. Omit the default\n // `authorization` flow here.\n extra: {\n name: options.assetName,\n version: options.assetVersion,\n assetTransferMethod: 'eip3009',\n ...(paymentFlow === 'upfront' ? { paymentFlow } : {}),\n },\n };\n\n // The v2 challenge document as sent on the wire. The HTTP adapter\n // base64-encodes it into `PAYMENT-REQUIRED` and MCP passes it through, so\n // both surfaces offer the same challenge.\n //\n // `resource.url` is outside the EIP-3009 signature. Include public\n // network and payee terms so the buyer's echo can identify this offer.\n const envelope: PaymentRequired = {\n x402Version: X402_VERSION,\n resource: {\n url: `resource://agent-commerce/${encodeURIComponent(options.network)}/${options.payTo}/resources/${encodeURIComponent(context.resource.id)}`,\n description: context.resource.description ?? context.resource.name,\n mimeType: DEFAULT_MIME_TYPE,\n },\n accepts: [requirements],\n };\n\n const expiresAt = new Date(clock.now().getTime() + maxTimeoutSeconds * 1000).toISOString();\n\n return {\n id: ids.next('payreq'),\n requestId: context.requestId,\n resourceId: context.resource.id,\n provider: 'x402',\n amount: context.amount,\n currency: context.currency,\n destination: options.payTo,\n network: options.network,\n asset: options.asset,\n expiresAt,\n challenge: {\n provider: 'x402',\n version: X402_PROTOCOL_VERSION,\n accepts: [requirements as unknown as Record<string, unknown>],\n envelope: envelope as unknown as Record<string, unknown>,\n },\n metadata: { [SETTLE_AFTER_BACKEND_METADATA_KEY]: paymentFlow === 'authorization' },\n };\n }\n\n /**\n * Checks a submission against the requirement this provider built, never\n * against `payload.accepted`, the copy the client echoes back. That copy\n * must itself match the offer, or the proof is refused.\n *\n * The `exact` scheme requires the authorized amount to match exactly,\n * including when the buyer offers more. Local refusals use x402 error codes\n * where available.\n */\n async function verify(context: PaymentVerificationContext): Promise<PaymentResult> {\n const { requirement, submission } = context;\n\n const rejected = (reason: string): PaymentResult => ({\n status: 'rejected',\n provider: 'x402',\n amount: requirement.amount,\n currency: requirement.currency,\n ...(requirement.network !== undefined ? { network: requirement.network } : {}),\n ...(requirement.asset !== undefined ? { asset: requirement.asset } : {}),\n rejectionReason: reason,\n });\n\n if (requirement.provider !== 'x402' || requirement.challenge.provider !== 'x402') {\n return rejected('wrong_provider');\n }\n\n const requirements = requirement.challenge.accepts[0] as PaymentRequirements | undefined;\n if (!requirements) {\n return rejected('missing_payment_requirements');\n }\n\n // Defense in depth only: the pipeline builds a fresh requirement for every\n // request, so this rarely fires. The real expiry is EIP-3009's\n // `validBefore`, which the facilitator checks.\n if (\n requirement.expiresAt !== undefined &&\n Date.parse(requirement.expiresAt) < clock.now().getTime()\n ) {\n return rejected('requirement_expired');\n }\n\n // This provider built the requirement, so the asset always matches in\n // normal operation. A corrupted one must still never authorize a transfer\n // of a different asset.\n if (\n !isAddress(requirements.asset) ||\n getAddress(requirements.asset) !== getAddress(options.asset)\n ) {\n return rejected('wrong_asset');\n }\n\n const payload = decodePaymentSubmission(submission.payload);\n if (!payload) {\n const version = declaredX402Version(submission.payload);\n return rejected(\n typeof version === 'number' && version !== X402_VERSION\n ? 'invalid_x402_version'\n : 'invalid_payload',\n );\n }\n if (payload.x402Version !== X402_VERSION) {\n return rejected('invalid_x402_version');\n }\n if (!isExactEvmPayload(payload)) {\n return rejected('unsupported_scheme');\n }\n\n const { authorization } = payload.payload;\n\n if (!isAddress(authorization.from) || !isAddress(authorization.to)) {\n return rejected('invalid_payload');\n }\n // `accepted.network` names the chain the buyer signed for, so a mismatch\n // means a signature bound to a chain we do not settle on\n if (payload.accepted.network !== options.network) {\n return rejected('invalid_network');\n }\n // The signature omits flow and resource. Check the echoed offer;\n // `resource` is optional, but must match when present.\n const offeredUrl = (requirement.challenge.envelope as PaymentRequired | undefined)?.resource\n ?.url;\n if (\n !acceptedMatchesOffer(requirements, payload.accepted) ||\n (payload.resource !== undefined && payload.resource.url !== offeredUrl)\n ) {\n return rejected('invalid_payment_requirements');\n }\n if (getAddress(authorization.to) !== getAddress(options.payTo)) {\n return rejected('invalid_exact_evm_payload_recipient_mismatch');\n }\n let authorizedValue: bigint;\n let required: bigint;\n try {\n authorizedValue = BigInt(authorization.value);\n required = BigInt(requirements.amount);\n } catch {\n return rejected('invalid_payload');\n }\n if (authorizedValue !== required) {\n return rejected('invalid_exact_evm_payload_authorization_value_mismatch');\n }\n\n const scope = binding.open();\n let sdkResult: VerifyResponse;\n try {\n sdkResult = await scope.verify(withoutResource(payload), requirements);\n } catch (err) {\n // A throw means no verdict was obtained, so it is never held against the\n // buyer. Only an unclassified one is logged, as it may be an SDK fault.\n if (!isProviderUnavailableError(err) && !scope.transportFailed()) {\n logger.warn({ err: redactedErrorText(err) }, 'x402 verify(): unexpected SDK error');\n }\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator returned no verdict during verify()`,\n { cause: err },\n );\n }\n\n if (!sdkResult.isValid) {\n // An RPC that never answered is not a payment that failed a check\n if (scope.transportFailed()) {\n if (sdkResult.invalidReason !== undefined) {\n logger.debug(\n { reportedReason: sdkResult.invalidReason },\n 'x402 verify(): local facilitator transport failure reason',\n );\n }\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during verify()`,\n );\n }\n // The raw reason is logged at debug level. Only what the buyer sees and\n // the ledger records is constrained.\n if (sdkResult.invalidReason !== undefined) {\n logger.debug(\n { reportedReason: sdkResult.invalidReason },\n 'x402 verify(): facilitator rejection reason',\n );\n }\n return rejected(sanitizeReason(sdkResult.invalidReason, 'invalid_payment'));\n }\n\n // `accepted.network` equals the configured network (checked above), so the\n // profile's chain id is the one the authorization is bound to\n const replayKey = computeReplayKey({\n chainId: profile.chainId,\n asset: getAddress(requirements.asset),\n from: getAddress(authorization.from),\n nonce: authorization.nonce,\n });\n\n return {\n status: 'verified',\n provider: 'x402',\n payer: getAddress(authorization.from),\n payee: getAddress(authorization.to),\n amount: formatUnits(authorizedValue, options.assetDecimals),\n currency: requirement.currency,\n network: payload.accepted.network,\n asset: getAddress(requirements.asset),\n replayKey,\n };\n }\n\n async function settle(context: PaymentSettlementContext): Promise<PaymentResult> {\n const { requirement, submission, verification } = context;\n\n if (verification.status !== 'verified') {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() called without a successful verify()',\n );\n }\n\n const requirements = requirement.challenge.accepts[0] as PaymentRequirements | undefined;\n if (!requirements) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() found no payment requirements to settle against',\n );\n }\n\n const payload = decodePaymentSubmission(submission.payload);\n if (!payload || !isExactEvmPayload(payload)) {\n throw new CommerceError(\n 'PAYMENT_INVALID',\n 'x402 provider: settle() received an undecodable payment payload',\n );\n }\n\n const rejectedSettlement = (rejectionReason: string): PaymentResult => ({\n status: 'rejected',\n provider: 'x402',\n amount: verification.amount,\n currency: requirement.currency,\n ...(verification.network !== undefined ? { network: verification.network } : {}),\n ...(verification.asset !== undefined ? { asset: verification.asset } : {}),\n ...(verification.replayKey !== undefined ? { replayKey: verification.replayKey } : {}),\n rejectionReason,\n });\n\n const scope = binding.open();\n let sdkResult: SettleResponse;\n try {\n sdkResult = await scope.settle(withoutResource(payload), requirements);\n } catch (err) {\n if (isProviderUnavailableError(err) || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n `x402 provider: ${binding.kind} facilitator unreachable during settle()`,\n { cause: err },\n );\n }\n // The pinned SDK returns a result for every failure from gas estimation\n // on, so a throw comes from its checks before anything is sent. A revert\n // there is a real rejection, which releases any mandate the pipeline\n // holds for the purchase. Any other throw goes back as an unavailable\n // provider, which the pipeline records as `settlement-uncertain`, never\n // as a rejection blamed on the buyer.\n if (!isOnChainRevertError(err)) {\n logger.warn(\n { err: redactedErrorText(err) },\n 'x402 settle(): settlement failed with an unclassified error; outcome unknown',\n );\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: settlement failed with an unclassified error; outcome unknown',\n { cause: err },\n );\n }\n logger.warn(\n { err: redactedErrorText(err), rejectionReason: 'transaction_reverted' },\n 'x402 settle(): settlement transaction reverted on chain',\n );\n return rejectedSettlement('transaction_reverted');\n }\n\n if (!sdkResult.success) {\n // \"Broadcast, never confirmed\" is not \"did not happen\": the transfer may\n // be on-chain, so it throws as an unavailable provider carrying the hash,\n // and the pipeline records the attempt `settlement-uncertain`, not\n // `rejected`. The SDK's catch-all without a hash is treated the same way,\n // because its throw may have followed a broadcast and viem reports an\n // RPC error on the send as a revert. Everything else is a real rejection.\n if (\n sdkResult.errorReason === TRANSACTION_FAILED_REASON &&\n !/^0x[0-9a-f]{64}$/i.test(sdkResult.transaction)\n ) {\n logger.warn(\n { reportedReason: sdkResult.errorReason },\n 'x402 settle(): the broadcast failed without a transaction hash; outcome unknown',\n );\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: settlement failed with an unclassified error; outcome unknown',\n );\n }\n if (sdkResult.errorReason === SETTLEMENT_PENDING_REASON || scope.transportFailed()) {\n throw new CommerceError(\n 'PAYMENT_PROVIDER_UNAVAILABLE',\n 'x402 provider: settlement was broadcast but could not be confirmed',\n {\n ...(sdkResult.transaction\n ? { details: { transactionHash: sdkResult.transaction } }\n : {}),\n },\n );\n }\n if (sdkResult.errorReason !== undefined) {\n logger.debug(\n { reportedReason: sdkResult.errorReason },\n 'x402 settle(): facilitator failure reason',\n );\n }\n return {\n ...rejectedSettlement(sanitizeReason(sdkResult.errorReason, 'settlement_failed')),\n network: sdkResult.network,\n ...(sdkResult.payer !== undefined ? { payer: sdkResult.payer } : {}),\n };\n }\n\n return {\n status: 'settled',\n provider: 'x402',\n externalReference: sdkResult.transaction,\n ...(sdkResult.payer !== undefined ? { payer: sdkResult.payer } : {}),\n payee: requirements.payTo,\n amount: verification.amount,\n currency: requirement.currency,\n network: sdkResult.network,\n ...(verification.asset !== undefined ? { asset: verification.asset } : {}),\n ...(verification.replayKey !== undefined ? { replayKey: verification.replayKey } : {}),\n settledAt: clock.nowIso(),\n // `amount` is the display value; x402's settlement response reports base units\n metadata: { amountBaseUnits: payload.payload.authorization.value },\n };\n }\n\n async function computeHealth(): Promise<AdapterHealth> {\n const startedAt = clock.monotonicMs();\n const checkedAt = clock.nowIso();\n\n try {\n const chainId = await healthPublicClient.getChainId();\n if (chainId !== profile.chainId) {\n return {\n status: 'fail',\n detail: `RPC at ${rpcOrigin} reports chain id ${chainId}, expected ${profile.chainId} (${profile.displayName})`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n const code = await healthPublicClient.getCode({ address: options.asset });\n if (!code || code === '0x') {\n return {\n status: 'fail',\n detail: `No contract code found at configured asset address ${options.asset}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n if (binding.kind === 'remote') {\n // Reachable is not enough: a facilitator that does not carry our\n // scheme on our network fails every payment after the buyer has signed\n const kinds = await binding.supported();\n const supportsUs = kinds.some(\n (kind) =>\n kind.x402Version === X402_VERSION &&\n kind.scheme === 'exact' &&\n kind.network === options.network,\n );\n if (!supportsUs) {\n return {\n status: 'fail',\n detail:\n `Facilitator ${binding.describe} does not advertise x402 v${X402_VERSION} scheme=exact ` +\n `on ${options.network} (${profile.displayName}); no payment on this deployment can settle`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n return {\n status: 'pass',\n detail:\n `${describeDeploymentMode(mode)}: RPC ${rpcOrigin} reachable, chain id ` +\n `${profile.chainId} (${profile.displayName}), asset ${options.asset} has code, ` +\n `facilitator ${binding.describe} supports exact/${options.network}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n // Chain id alone cannot prove this is a dev chain, because Base Sepolia\n // reports the same 84532 as the local chain. An Anvil-only RPC method\n // must answer before a local facilitator counts as healthy.\n const isAnvil = await probeIsAnvilNode(healthPublicClient);\n if (!isAnvil) {\n return {\n status: 'fail',\n detail:\n `RPC at ${rpcOrigin} reports chain id ${profile.chainId} but does not answer ` +\n '\"anvil_nodeInfo\", so it does not look like a local Anvil dev node. Refusing to treat it ' +\n 'as safe for a local-facilitator dev key.',\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n\n return {\n status: 'pass',\n detail:\n `${describeDeploymentMode(mode)}: RPC ${rpcOrigin} reachable, chain id ` +\n `${profile.chainId}, asset ${options.asset} has code, confirmed Anvil dev node`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n } catch (err) {\n return {\n status: 'fail',\n detail: `x402 health check failed: ${redactedErrorText(err)}`,\n checkedAt,\n durationMs: clock.monotonicMs() - startedAt,\n };\n }\n }\n\n // A probe makes several upstream calls, and `/ready` is unauthenticated.\n // A short TTL plus one shared in-flight probe keeps upstream volume independent\n // of request volume, for library callers as well as the gateway, whose\n // readiness probe adds its own cache on top. Pass and fail share the TTL: a\n // shorter one for fail would bring the load back during an RPC outage,\n // exactly when each call is slowest.\n const HEALTH_CACHE_MS = 5_000;\n let cachedHealth: { at: number; value: AdapterHealth } | undefined;\n let inFlightHealth: Promise<AdapterHealth> | undefined;\n\n async function health(): Promise<AdapterHealth> {\n const now = clock.monotonicMs();\n if (cachedHealth && now - cachedHealth.at < HEALTH_CACHE_MS) {\n return cachedHealth.value;\n }\n if (inFlightHealth) return inFlightHealth;\n\n inFlightHealth = computeHealth()\n .then((value) => {\n cachedHealth = { at: clock.monotonicMs(), value };\n return value;\n })\n .finally(() => {\n inFlightHealth = undefined;\n });\n return inFlightHealth;\n }\n\n return {\n name: 'x402',\n descriptor,\n createRequirement,\n verify,\n settle,\n health,\n };\n}\n\n/**\n * Match echoed terms against the offer. Extra client keys and\n * `maxTimeoutSeconds` do not matter; addresses ignore case. Compare effective\n * payment flows so an upfront proof cannot pay a default authorization offer.\n */\nfunction acceptedMatchesOffer(\n offered: PaymentRequirements,\n accepted: PaymentRequirements,\n): boolean {\n const sameAddress = (a: string, b: string) => a.toLowerCase() === b.toLowerCase();\n const offeredExtra = offered.extra ?? {};\n const acceptedExtra = accepted.extra ?? {};\n const flow = (extra: Record<string, unknown>) =>\n extra['paymentFlow'] ?? X402_DEFAULT_PAYMENT_FLOW;\n return (\n accepted.scheme === offered.scheme &&\n accepted.network === offered.network &&\n accepted.amount === offered.amount &&\n sameAddress(accepted.asset, offered.asset) &&\n sameAddress(accepted.payTo, offered.payTo) &&\n Object.entries(offeredExtra).every(([key, value]) => acceptedExtra[key] === value) &&\n flow(acceptedExtra) === flow(offeredExtra)\n );\n}\n\n// viem wraps every failed contract call in ContractFunctionExecutionError, so\n// only the cause chain can show a revert. A revert alone does not prove nothing\n// moved, because viem also reports an RPC error on a send as one; settle()\n// relies on the SDK throwing only before the broadcast.\nfunction isOnChainRevertError(err: unknown): boolean {\n return (\n err instanceof BaseError && err.walk((e) => e instanceof ContractFunctionRevertedError) !== null\n );\n}\n\n/**\n * The `instanceof` checks cover what the pinned viem HTTP transport throws\n * (`HttpRequestError` for every fetch failure, including connection refused,\n * or `TimeoutError`) and what `waitForTransactionReceipt` throws when it stops\n * polling after a broadcast. Message matching is only a fallback for errors\n * outside those classes, such as a raw undici error, because message text can\n * change with any viem or undici upgrade.\n */\nfunction isProviderUnavailableError(err: unknown): boolean {\n if (\n err instanceof HttpRequestError ||\n err instanceof TimeoutError ||\n err instanceof WaitForTransactionReceiptTimeoutError\n ) {\n return true;\n }\n const message = redactedErrorText(err).toLowerCase();\n return (\n message.includes('econnrefused') ||\n message.includes('fetch failed') ||\n message.includes('enotfound') ||\n message.includes('etimedout') ||\n message.includes('timed out') ||\n message.includes('network error')\n );\n}\n\n/**\n * True only when the RPC answers Anvil's own `anvil_nodeInfo` method. A public\n * node, Base Sepolia included, answers \"method not found\". Never throws.\n */\nasync function probeIsAnvilNode(\n client: ReturnType<typeof createLocalPublicClient>,\n): Promise<boolean> {\n // Anvil-only method, absent from viem's typed PublicRpcSchema, hence the cast\n const request = client.request as unknown as (args: {\n method: string;\n params: unknown[];\n }) => Promise<unknown>;\n try {\n await request({ method: 'anvil_nodeInfo', params: [] });\n return true;\n } catch {\n return false;\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommerceError } from './chunk-
|
|
1
|
+
import { CommerceError } from './chunk-53WXXIPR.js';
|
|
2
2
|
import { mkdirSync, existsSync, accessSync, constants, closeSync, openSync, chmodSync } from 'fs';
|
|
3
3
|
import { dirname } from 'path';
|
|
4
4
|
import Database from 'better-sqlite3';
|
|
@@ -61,5 +61,5 @@ function restrictDatabasePermissions(path, label, logger) {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export { AP2_CHECKOUT_MANDATE_VCT, AP2_CHECKOUT_PROFILE, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_DIGEST_ALGORITHM, AP2_JWK_COORDINATE_BYTES, AP2_JWK_CURVE, AP2_JWK_MEMBERS, AP2_KEY_TYPE, AP2_MAX_CLOCK_SKEW_SECONDS, AP2_MODES, AP2_SIGNING_ALGORITHM, AP2_SPEC_VERSION, openSqliteDatabase };
|
|
64
|
-
//# sourceMappingURL=chunk-
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
64
|
+
//# sourceMappingURL=chunk-SYEGCNJZ.js.map
|
|
65
|
+
//# sourceMappingURL=chunk-SYEGCNJZ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/authorization/ap2/constants.ts","../src/storage/sqlite.ts"],"names":["fsConstants"],"mappings":";;;;;;AAQO,IAAM,gBAAA,GAAmB;AAOzB,IAAM,SAAA,GAAY,CAAC,QAAQ;AAO3B,IAAM,qBAAA,GAAwB;AAG9B,IAAM,YAAA,GAAe;AACrB,IAAM,aAAA,GAAgB;AAGtB,IAAM,wBAAA,GAA2B;AAOjC,IAAM,eAAA,GAAkB,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,GAAA,EAAK,KAAA,EAAO,OAAO,KAAK;AAOpE,IAAM,wBAAA,GAA2B;AAQjC,IAAM,oBAAA,GAAuB;AAO7B,IAAM,oBAAA,GAAuB;AAG7B,IAAM,8BAAA,GAAiC;AAMvC,IAAM,0BAAA,GAA6B;ACtCnC,SAAS,mBAAmB,OAAA,EAA+C;AAChF,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,MAAA,EAAO,GAAI,OAAA;AAChC,EAAA,MAAM,eAAe,IAAA,KAAS,UAAA;AAE9B,EAAA,IAAI,YAAA,EAAc;AAGhB,IAAA,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA,EAAG,EAAE,WAAW,IAAA,EAAM,IAAA,EAAM,KAAO,CAAA;AAAA,EAC3D;AAIA,EAAA,IAAI,YAAA,IAAgB,UAAA,CAAW,IAAI,CAAA,EAAG;AACpC,IAAA,IAAI;AACF,MAAA,UAAA,CAAW,IAAA,EAAMA,UAAY,IAAI,CAAA;AAAA,IACnC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,eAAA;AAAA,QACA,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,IAAI,CAAA,kDAAA,EAAqD,OAAO,OAAA,CAAQ,MAAA,KAAW,UAAA,GAAa,OAAA,CAAQ,MAAA,EAAO,GAAI,SAAS,CAAA,4KAAA,CAAA;AAAA,QACzI,EAAE,OAAA,EAAS,EAAE,IAAA,EAAK;AAAE,OACtB;AAAA,IACF;AAAA,EACF;AAOA,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,QAAA,CAAS,IAAA,EAAM,GAAA,EAAK,GAAK,CAAC,CAAA;AAAA,IACtC,CAAA,CAAA,MAAQ;AAAA,IAGR;AAAA,EACF;AAEA,EAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,IAAI,CAAA;AAC5B,EAAA,EAAA,CAAG,OAAO,oBAAoB,CAAA;AAC9B,EAAA,EAAA,CAAG,OAAO,mBAAmB,CAAA;AAC7B,EAAA,IAAI,YAAA,EAAc,2BAAA,CAA4B,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AACjE,EAAA,OAAO,EAAA;AACT;AAWA,SAAS,2BAAA,CAA4B,IAAA,EAAc,KAAA,EAAe,MAAA,EAAsB;AACtF,EAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,IAAA,CAAA,EAAQ,CAAA,EAAG,IAAI,CAAA,IAAA,CAAM,CAAA,EAAG;AACvD,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,MAAM,GAAK,CAAA;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAQ,KAAA,CAAgC,IAAA;AAC9C,MAAA,IAAI,SAAS,QAAA,EAAU;AACvB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,QAAQ,SAAA,EAAU;AAAA,QACxC;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/authorization/ap2/constants.ts","../src/storage/sqlite.ts"],"names":["fsConstants"],"mappings":";;;;;;AAQO,IAAM,gBAAA,GAAmB;AAOzB,IAAM,SAAA,GAAY,CAAC,QAAQ;AAO3B,IAAM,qBAAA,GAAwB;AAG9B,IAAM,YAAA,GAAe;AACrB,IAAM,aAAA,GAAgB;AAGtB,IAAM,wBAAA,GAA2B;AAOjC,IAAM,eAAA,GAAkB,CAAC,KAAA,EAAO,KAAA,EAAO,KAAK,GAAA,EAAK,KAAA,EAAO,OAAO,KAAK;AAOpE,IAAM,wBAAA,GAA2B;AAQjC,IAAM,oBAAA,GAAuB;AAO7B,IAAM,oBAAA,GAAuB;AAG7B,IAAM,8BAAA,GAAiC;AAMvC,IAAM,0BAAA,GAA6B;ACtCnC,SAAS,mBAAmB,OAAA,EAA+C;AAChF,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,MAAA,EAAO,GAAI,OAAA;AAChC,EAAA,MAAM,eAAe,IAAA,KAAS,UAAA;AAE9B,EAAA,IAAI,YAAA,EAAc;AAGhB,IAAA,SAAA,CAAU,OAAA,CAAQ,IAAI,CAAA,EAAG,EAAE,WAAW,IAAA,EAAM,IAAA,EAAM,KAAO,CAAA;AAAA,EAC3D;AAIA,EAAA,IAAI,YAAA,IAAgB,UAAA,CAAW,IAAI,CAAA,EAAG;AACpC,IAAA,IAAI;AACF,MAAA,UAAA,CAAW,IAAA,EAAMA,UAAY,IAAI,CAAA;AAAA,IACnC,CAAA,CAAA,MAAQ;AACN,MAAA,MAAM,IAAI,aAAA;AAAA,QACR,eAAA;AAAA,QACA,CAAA,EAAG,KAAK,CAAA,EAAA,EAAK,IAAI,CAAA,kDAAA,EAAqD,OAAO,OAAA,CAAQ,MAAA,KAAW,UAAA,GAAa,OAAA,CAAQ,MAAA,EAAO,GAAI,SAAS,CAAA,4KAAA,CAAA;AAAA,QACzI,EAAE,OAAA,EAAS,EAAE,IAAA,EAAK;AAAE,OACtB;AAAA,IACF;AAAA,EACF;AAOA,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,QAAA,CAAS,IAAA,EAAM,GAAA,EAAK,GAAK,CAAC,CAAA;AAAA,IACtC,CAAA,CAAA,MAAQ;AAAA,IAGR;AAAA,EACF;AAEA,EAAA,MAAM,EAAA,GAAK,IAAI,QAAA,CAAS,IAAI,CAAA;AAC5B,EAAA,EAAA,CAAG,OAAO,oBAAoB,CAAA;AAC9B,EAAA,EAAA,CAAG,OAAO,mBAAmB,CAAA;AAC7B,EAAA,IAAI,YAAA,EAAc,2BAAA,CAA4B,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AACjE,EAAA,OAAO,EAAA;AACT;AAWA,SAAS,2BAAA,CAA4B,IAAA,EAAc,KAAA,EAAe,MAAA,EAAsB;AACtF,EAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,IAAA,CAAA,EAAQ,CAAA,EAAG,IAAI,CAAA,IAAA,CAAM,CAAA,EAAG;AACvD,IAAA,IAAI;AACF,MAAA,SAAA,CAAU,MAAM,GAAK,CAAA;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,OAAQ,KAAA,CAAgC,IAAA;AAC9C,MAAA,IAAI,SAAS,QAAA,EAAU;AACvB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,EAAE,IAAA,EAAM,KAAA,EAAO,KAAA,EAAO,QAAQ,SAAA,EAAU;AAAA,QACxC;AAAA,OACF;AAAA,IACF;AAAA,EACF;AACF","file":"chunk-SYEGCNJZ.js","sourcesContent":["/**\n * Pinned AP2 identifiers and key policy.\n *\n * AP2 v0.2.0 (2026-04-28, commit b4587ac) is the tagged release this gateway\n * verifies against; unversioned `main` is never implemented against. Config,\n * the verifier and `doctor` all read these, so a bump lands in one place.\n */\n\nexport const AP2_SPEC_VERSION = '0.2.0';\n\n/**\n * Direct only. Autonomous mode needs open mandates, cnf-bound agent keys and\n * constraint evaluation over `checkout.line_items`, none of which is\n * implemented, so it is refused rather than partly served.\n */\nexport const AP2_MODES = ['direct'] as const;\nexport type Ap2Mode = (typeof AP2_MODES)[number];\n\n/**\n * A single algorithm, so `alg=none` and the HMAC family are excluded by\n * construction rather than by a denylist\n */\nexport const AP2_SIGNING_ALGORITHM = 'ES256';\n\n/** The key type and curve ES256 implies. Any other pair is refused at load */\nexport const AP2_KEY_TYPE = 'EC';\nexport const AP2_JWK_CURVE = 'P-256';\n\n/** Byte length of a P-256 coordinate, before base64url encoding */\nexport const AP2_JWK_COORDINATE_BYTES = 32;\n\n/**\n * JWK members a verification key may carry. An allowlist, so private material\n * (`d`) and URL members (`x5u`, `jku`) are refused without the list naming\n * them. Keys are configured inline and never fetched; see docs/security.md.\n */\nexport const AP2_JWK_MEMBERS = ['kty', 'crv', 'x', 'y', 'kid', 'alg', 'use'] as const;\n\n/**\n * Compared against this literal, never as a prefix. `mandate.checkout.open.1`\n * carries spending constraints nothing here evaluates, so accepting it would\n * tell a buyer their limits were checked when nothing read them.\n */\nexport const AP2_CHECKOUT_MANDATE_VCT = 'mandate.checkout.1';\n\n/**\n * Merchant checkout JWTs declare this gateway-specific profile; AP2 leaves\n * the checkout payload out of scope. The identifier is a namespace that\n * clients do not dereference. Merchants sign it into each checkout JWT, so\n * changing the expected value would reject previously signed JWTs.\n */\nexport const AP2_CHECKOUT_PROFILE = 'agent-commerce/ap2/checkout/v1';\n\n/**\n * The only accepted SD-JWT `_sd_alg` (an absent one means sha-256). Any other\n * value is refused rather than hashed as sha-256, which would check a\n * presentation under an algorithm it never claimed.\n */\nexport const AP2_DIGEST_ALGORITHM = 'sha-256';\n\n/** Seconds of clock skew tolerated on mandate and checkout time claims */\nexport const AP2_DEFAULT_CLOCK_SKEW_SECONDS = 60;\n\n/**\n * Skew as wide as a mandate's validity window would stop `exp` rejecting\n * anything. An operator who needs more than five minutes has a clock to fix.\n */\nexport const AP2_MAX_CLOCK_SKEW_SECONDS = 300;\n","/**\n * Opens a SQLite file with owner-only permissions. Every store that keeps a\n * SQLite file opens it here, so the hardening below exists once: the file is\n * pre-created at 0600, the WAL sidecars are narrowed once WAL creates them, and\n * an existing but unwritable file fails at startup.\n *\n * Callers own their schema; this function migrates nothing.\n */\nimport {\n accessSync,\n chmodSync,\n closeSync,\n existsSync,\n constants as fsConstants,\n mkdirSync,\n openSync,\n} from 'node:fs';\nimport { dirname } from 'node:path';\nimport Database from 'better-sqlite3';\nimport { CommerceError, type Logger } from '../core';\n\nexport interface OpenSqliteOptions {\n /** File path, or ':memory:' for tests. Parent directory is created if missing */\n readonly path: string;\n /** Names the database in operator-facing errors, e.g. \"Receipt database\" */\n readonly label: string;\n readonly logger: Logger;\n}\n\nexport function openSqliteDatabase(options: OpenSqliteOptions): Database.Database {\n const { path, label, logger } = options;\n const isFileBacked = path !== ':memory:';\n\n if (isFileBacked) {\n // 0700 on a directory this creates. A recursive mkdir leaves an existing\n // one, the operator's, with its mode.\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n }\n\n // Check write access at startup. SQLite can open a read-only database and\n // report the problem only when the first write is attempted.\n if (isFileBacked && existsSync(path)) {\n try {\n accessSync(path, fsConstants.W_OK);\n } catch {\n throw new CommerceError(\n 'STORAGE_ERROR',\n `${label} \"${path}\" exists but is not writable by this process (uid ${typeof process.getuid === 'function' ? process.getuid() : 'unknown'}). If this is a container that recently changed user, an existing volume may still be owned by the previous one - recreate it (docker compose down -v) or fix its ownership.`,\n { details: { path } },\n );\n }\n }\n\n // Create the file at 0600 before SQLite creates it at 0644 (less the umask).\n // A chmod afterwards is too late: a local user who opens the file in between\n // keeps a readable descriptor across the chmod. SQLite copies the main file's\n // mode onto the -wal/-shm sidecars, so this covers all three. `mode` applies\n // on creation only; an existing file is left to the chmod below.\n if (isFileBacked) {\n try {\n closeSync(openSync(path, 'a', 0o600));\n } catch {\n // Silent on purpose: `new Database` reports the same cause with a better\n // message, or the failure is harmless and the chmod below covers it\n }\n }\n\n const db = new Database(path);\n db.pragma('journal_mode = WAL');\n db.pragma('foreign_keys = ON');\n if (isFileBacked) restrictDatabasePermissions(path, label, logger);\n return db;\n}\n\n/**\n * Narrows the database and its WAL sidecars to owner-only. The receipt ledger\n * holds no key material, but it does hold payer and payee addresses, amounts,\n * settlement hashes, replay keys and the commerce event log.\n *\n * Runs after `journal_mode = WAL`, which creates the sidecars, and also\n * tightens a database that already existed with a looser mode. A failure only\n * warns: a filesystem without POSIX modes must not stop the gateway starting.\n */\nfunction restrictDatabasePermissions(path: string, label: string, logger: Logger): void {\n for (const file of [path, `${path}-wal`, `${path}-shm`]) {\n try {\n chmodSync(file, 0o600);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') continue;\n logger.warn(\n { file, label, error: code ?? 'unknown' },\n 'could not restrict database permissions to owner-only',\n );\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommerceError } from './chunk-
|
|
1
|
+
import { CommerceError } from './chunk-53WXXIPR.js';
|
|
2
2
|
|
|
3
3
|
// src/payments/x402/networks.ts
|
|
4
4
|
var LOCAL_CHAIN_ID = 84532;
|
|
@@ -50,6 +50,9 @@ function describeDeploymentMode(mode) {
|
|
|
50
50
|
return mode === "mainnet" ? LIVE_MAINNET_BANNER : mode.toUpperCase();
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// src/core/execution/settlement-order.ts
|
|
54
|
+
var SETTLE_AFTER_BACKEND_METADATA_KEY = "settleAfterBackend";
|
|
55
|
+
|
|
53
56
|
// src/payments/x402/local-chain/accounts.ts
|
|
54
57
|
var ANVIL_WELL_KNOWN_ACCOUNTS = [
|
|
55
58
|
{
|
|
@@ -253,6 +256,10 @@ function sameAddress(a, b) {
|
|
|
253
256
|
return a.toLowerCase() === b.toLowerCase();
|
|
254
257
|
}
|
|
255
258
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
+
// src/payments/x402/payment-flow.ts
|
|
260
|
+
var X402_PAYMENT_FLOWS = ["authorization", "upfront"];
|
|
261
|
+
var X402_DEFAULT_PAYMENT_FLOW = "authorization";
|
|
262
|
+
|
|
263
|
+
export { LOCAL_CHAIN_ID, SETTLE_AFTER_BACKEND_METADATA_KEY, SUPPORTED_NETWORK_IDS, X402_DEFAULT_PAYMENT_FLOW, X402_PAYMENT_FLOWS, assertDevKeyIsLocalOnly, assertPayToIsNotDevAddress, describeDeploymentMode, describeRpc, requireNetworkProfile, resolveDeploymentMode, resolveX402Deployment };
|
|
264
|
+
//# sourceMappingURL=chunk-TWRUNWDR.js.map
|
|
265
|
+
//# sourceMappingURL=chunk-TWRUNWDR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/payments/x402/networks.ts","../src/core/execution/settlement-order.ts","../src/payments/x402/local-chain/accounts.ts","../src/payments/x402/dev-key-guard.ts","../src/payments/x402/guardrails.ts","../src/payments/x402/payment-flow.ts"],"names":[],"mappings":"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","file":"chunk-TWRUNWDR.js","sourcesContent":["/**\n * The networks this gateway settles on, as data: the chain id to sign against,\n * a display name, and whether real money is involved.\n *\n * A registry rather than \"parse any `eip155:*`\": the chain id parses from any\n * such string, but whether it is a mainnet does not, and the guardrails key off\n * that. An unknown id is refused at startup instead of passing as a testnet.\n *\n * The local dev chain runs under Base Sepolia's `eip155:84532`, so nothing may\n * infer \"public network\" from the id alone. `resolveDeploymentMode` derives\n * the mode from the facilitator too, and the provider's health check confirms\n * that a local facilitator's node is Anvil.\n */\nimport { CommerceError } from '../../core';\n\n/** Chain id of the local dev chain, which Base Sepolia uses too */\nexport const LOCAL_CHAIN_ID = 84532;\n\nexport interface NetworkProfile {\n /** CAIP-2 identifier, e.g. `eip155:84532` */\n readonly id: string;\n /** Signed into the buyer's EIP-712 domain */\n readonly chainId: number;\n readonly displayName: string;\n readonly kind: 'testnet' | 'mainnet';\n /**\n * The USDC deployment this network settles in, with the EIP-712 domain the\n * token reports. Enforced on mainnet only, since a testnet may use a mock\n * token.\n *\n * `name` is the signed EIP-712 domain name, not the symbol, and the two\n * deployments differ: `\"USDC\"` on Base Sepolia, `\"USD Coin\"` on Base. The\n * values were read back from the contracts.\n */\n readonly canonicalAsset?: {\n readonly symbol: string;\n readonly address: string;\n readonly name: string;\n readonly version: string;\n };\n}\n\nconst PROFILES: readonly NetworkProfile[] = [\n {\n id: 'eip155:84532',\n chainId: 84532,\n displayName: 'Base Sepolia',\n kind: 'testnet',\n canonicalAsset: {\n symbol: 'USDC',\n address: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n name: 'USDC',\n version: '2',\n },\n },\n {\n id: 'eip155:8453',\n chainId: 8453,\n displayName: 'Base',\n kind: 'mainnet',\n canonicalAsset: {\n symbol: 'USDC',\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n name: 'USD Coin',\n version: '2',\n },\n },\n];\n\nconst BY_ID = new Map(PROFILES.map((profile) => [profile.id, profile]));\n\nexport const SUPPORTED_NETWORK_IDS: readonly string[] = PROFILES.map((p) => p.id);\n\nexport function findNetworkProfile(id: string): NetworkProfile | undefined {\n return BY_ID.get(id);\n}\n\nexport function requireNetworkProfile(id: string, path: string): NetworkProfile {\n const profile = BY_ID.get(id);\n if (!profile) {\n throw new CommerceError(\n 'CONFIG_INVALID',\n `${path}: \"${id}\" is not a supported network. Supported CAIP-2 identifiers: ${SUPPORTED_NETWORK_IDS.join(', ')}`,\n { details: { path, network: id } },\n );\n }\n return profile;\n}\n\n/**\n * What a deployment is, as opposed to the network it names. `local` comes from\n * the facilitator: the in-process facilitator makes a deployment local whatever\n * CAIP-2 id it is configured with, which lets diagnostics show `eip155:84532`\n * without claiming public Base Sepolia.\n */\nexport type DeploymentMode = 'local' | 'testnet' | 'mainnet';\n\nexport function resolveDeploymentMode(\n profile: NetworkProfile,\n facilitatorMode: 'local' | 'remote',\n): DeploymentMode {\n if (facilitatorMode === 'local') return 'local';\n return profile.kind;\n}\n\n// The banner an operator must not miss. Printed for mainnet only\nconst LIVE_MAINNET_BANNER = 'LIVE MAINNET MODE - REAL FUNDS';\n\nexport function describeDeploymentMode(mode: DeploymentMode): string {\n return mode === 'mainnet' ? LIVE_MAINNET_BANNER : mode.toUpperCase();\n}\n","/**\n * Set on a payment requirement to run the backend before settlement.\n * The pipeline settles first unless this metadata value is `true`.\n */\nexport const SETTLE_AFTER_BACKEND_METADATA_KEY = 'settleAfterBackend';\n","/**\n * Anvil's well-known development accounts.\n *\n * LOCAL DEVELOPMENT ONLY - DO NOT FUND. The keys come from Foundry's public\n * default mnemonic (\"test test ... junk\"), so value sent to these addresses on\n * a real network can be taken by anyone.\n *\n * Index layout on the local demo chain:\n * 0 - deployer and local facilitator signer (pays gas, broadcasts settlement)\n * 1 - merchant settlement destination (`payTo`)\n * 2 - buyer (signs EIP-3009 authorizations; never held by the gateway)\n */\nexport interface AnvilWellKnownAccount {\n readonly address: `0x${string}`;\n readonly privateKey: `0x${string}`;\n}\n\n/** A fixed-length tuple, so indexing by the layout above is typed */\nexport const ANVIL_WELL_KNOWN_ACCOUNTS: readonly [\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n AnvilWellKnownAccount,\n] = [\n {\n address: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',\n privateKey: '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',\n },\n {\n address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',\n privateKey: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d',\n },\n {\n address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',\n privateKey: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a',\n },\n];\n\nexport const LOCAL_FACILITATOR_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[0];\nexport const LOCAL_MERCHANT_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[1];\nexport const LOCAL_BUYER_ACCOUNT = ANVIL_WELL_KNOWN_ACCOUNTS[2];\n\n/** Label printed wherever a dev key appears in output, logs or manifests */\nexport const DEV_KEY_LABEL = 'LOCAL DEVELOPMENT ONLY - DO NOT FUND';\n","/**\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 { isLikelyLocalOrPrivateHost, isWellKnownDevAddress } from './dev-key-guard';\nimport {\n type DeploymentMode,\n type NetworkProfile,\n requireNetworkProfile,\n resolveDeploymentMode,\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 /** 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}\n\nexport interface X402Deployment {\n readonly profile: NetworkProfile;\n readonly mode: DeploymentMode;\n}\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 = requireNetworkProfile(input.network, `${at}.network`);\n const mode = resolveDeploymentMode(profile, input.facilitator.mode);\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\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 // 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 (/^0x0{40}$/i.test(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 // Mainnet only: a testnet is where pointing at a mock token is normal\n const canonical = profile.canonicalAsset;\n if (mode === 'mainnet' && canonical) {\n if (!sameAddress(input.asset, canonical.address)) {\n throw invalid(\n `${at}: asset ${input.asset} is not ${canonical.symbol} on ${profile.displayName} (expected ${canonical.address}). Settling a mainnet payment in an unintended token is refused.`,\n `${at}.asset`,\n );\n }\n // The buyer signs the EIP-712 domain and the scheme checks it. A wrong one\n // refuses every payment with `invalid_exact_evm_token_name_mismatch` after\n // the buyer signed, so it is caught here, before the gateway starts.\n if (input.assetName !== undefined && input.assetName !== canonical.name) {\n throw invalid(\n `${at}: assetName \"${input.assetName}\" is not the EIP-712 domain name ${canonical.symbol} reports on ${profile.displayName} (expected \"${canonical.name}\"). Every payment would be refused after the buyer signed.`,\n `${at}.assetName`,\n );\n }\n if (input.assetVersion !== undefined && input.assetVersion !== canonical.version) {\n throw invalid(\n `${at}: assetVersion \"${input.assetVersion}\" is not the EIP-712 domain version ${canonical.symbol} reports on ${profile.displayName} (expected \"${canonical.version}\").`,\n `${at}.assetVersion`,\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// 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\nfunction sameAddress(a: string, b: string): boolean {\n return a.toLowerCase() === b.toLowerCase();\n}\n","/**\n * x402 exact-scheme flows, shared by the config loader and CLI.\n * The default `authorization` flow settles after a successful backend call;\n * `upfront` settles first.\n */\nexport const X402_PAYMENT_FLOWS = ['authorization', 'upfront'] as const;\n\nexport type X402PaymentFlow = (typeof X402_PAYMENT_FLOWS)[number];\n\nexport const X402_DEFAULT_PAYMENT_FLOW: X402PaymentFlow = 'authorization';\n"]}
|