opentool 0.7.2 → 0.7.3

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.
@@ -0,0 +1,708 @@
1
+ import { z } from 'zod';
2
+ import { createWalletClient, http } from 'viem';
3
+ import { privateKeyToAccount } from 'viem/accounts';
4
+ import { baseSepolia } from 'viem/chains';
5
+
6
+ // src/x402/types.ts
7
+ var X402_VERSION = 1;
8
+ var HEADER_X402 = "X-PAYMENT";
9
+ var HEADER_PAYMENT_RESPONSE = "X-PAYMENT-RESPONSE";
10
+ var x402RequirementSchema = z.object({
11
+ scheme: z.string().min(1),
12
+ network: z.string().min(1),
13
+ maxAmountRequired: z.string().min(1),
14
+ asset: z.string().min(1),
15
+ payTo: z.string().min(1),
16
+ resource: z.string().optional(),
17
+ description: z.string().optional(),
18
+ mimeType: z.string().optional(),
19
+ outputSchema: z.unknown().optional(),
20
+ maxTimeoutSeconds: z.number().int().positive().optional(),
21
+ extra: z.record(z.string(), z.unknown()).nullable().optional()
22
+ });
23
+ var x402PaymentHeaderSchema = z.object({
24
+ x402Version: z.number().int().positive(),
25
+ scheme: z.string().min(1),
26
+ network: z.string().min(1),
27
+ correlationId: z.string().optional(),
28
+ payload: z.unknown()
29
+ });
30
+ var SUPPORTED_CURRENCIES = {
31
+ USDC: {
32
+ decimals: 6,
33
+ symbol: "USDC",
34
+ network: "base",
35
+ assetAddress: "0x833589fCD6eDb6E08f4c7C37b7b4c6e997E08A43"
36
+ }
37
+ };
38
+ var DEFAULT_FACILITATOR = {
39
+ url: "https://facilitator.x402.rs",
40
+ verifyPath: "/verify",
41
+ settlePath: "/settle",
42
+ apiKeyHeader: "Authorization"
43
+ };
44
+
45
+ // src/x402/helpers.ts
46
+ function createX402PaymentRequired(definition) {
47
+ const requirement = toX402Requirement(definition);
48
+ const body = {
49
+ schemaVersion: 1,
50
+ message: definition.description ?? "Payment required",
51
+ resource: definition.resource,
52
+ accepts: [
53
+ {
54
+ id: "x402",
55
+ title: `Pay ${definition.amount} ${definition.currency.code}`,
56
+ description: definition.description,
57
+ amount: {
58
+ value: definition.amount,
59
+ currency: {
60
+ code: definition.currency.code,
61
+ symbol: definition.currency.symbol,
62
+ decimals: definition.currency.decimals,
63
+ kind: "crypto"
64
+ }
65
+ },
66
+ asset: {
67
+ symbol: definition.asset.symbol,
68
+ network: definition.asset.network,
69
+ address: definition.asset.address,
70
+ decimals: definition.asset.decimals,
71
+ standard: "erc20"
72
+ },
73
+ payTo: definition.payTo,
74
+ resource: definition.resource,
75
+ proof: {
76
+ mode: "x402",
77
+ scheme: definition.scheme,
78
+ network: definition.network,
79
+ version: X402_VERSION,
80
+ facilitator: definition.facilitator,
81
+ verifier: "x402:facilitator"
82
+ }
83
+ }
84
+ ],
85
+ metadata: definition.metadata ?? {},
86
+ x402: {
87
+ x402Version: X402_VERSION,
88
+ error: definition.description ?? "Payment required",
89
+ accepts: [requirement]
90
+ }
91
+ };
92
+ return new Response(JSON.stringify(body), {
93
+ status: 402,
94
+ headers: {
95
+ "Content-Type": "application/json"
96
+ }
97
+ });
98
+ }
99
+ function extractX402Attempt(request) {
100
+ const raw = request.headers.get(HEADER_X402);
101
+ if (!raw) {
102
+ return null;
103
+ }
104
+ try {
105
+ const payload = decodeJson(raw, x402PaymentHeaderSchema);
106
+ return {
107
+ type: "x402",
108
+ headerName: HEADER_X402,
109
+ raw,
110
+ payload
111
+ };
112
+ } catch {
113
+ return null;
114
+ }
115
+ }
116
+ async function verifyX402Payment(attempt, definition, options = {}) {
117
+ const fetchImpl = options.fetchImpl ?? fetch;
118
+ const facilitator = definition.facilitator;
119
+ const verifierUrl = new URL(
120
+ facilitator.verifyPath ?? "/verify",
121
+ ensureTrailingSlash(facilitator.url)
122
+ ).toString();
123
+ const requirement = toX402Requirement(definition);
124
+ const headers = buildFacilitatorHeaders(facilitator);
125
+ try {
126
+ const verifyResponse = await fetchImpl(verifierUrl, {
127
+ method: "POST",
128
+ headers,
129
+ body: JSON.stringify({
130
+ x402Version: attempt.payload.x402Version,
131
+ paymentPayload: attempt.payload,
132
+ paymentRequirements: requirement
133
+ })
134
+ });
135
+ if (!verifyResponse.ok) {
136
+ return {
137
+ success: false,
138
+ failure: {
139
+ reason: `Facilitator verify request failed: ${verifyResponse.status}`,
140
+ code: "verification_failed"
141
+ }
142
+ };
143
+ }
144
+ const verifyPayload = await verifyResponse.json();
145
+ if (!verifyPayload.isValid) {
146
+ return {
147
+ success: false,
148
+ failure: {
149
+ reason: verifyPayload.invalidReason ?? "Facilitator verification failed",
150
+ code: "verification_failed"
151
+ }
152
+ };
153
+ }
154
+ const responseHeaders = {};
155
+ if (options.settle) {
156
+ const settleUrl = new URL(
157
+ facilitator.settlePath ?? "/settle",
158
+ ensureTrailingSlash(facilitator.url)
159
+ ).toString();
160
+ try {
161
+ const settleResponse = await fetchImpl(settleUrl, {
162
+ method: "POST",
163
+ headers,
164
+ body: JSON.stringify({
165
+ x402Version: attempt.payload.x402Version,
166
+ paymentPayload: attempt.payload,
167
+ paymentRequirements: requirement
168
+ })
169
+ });
170
+ if (settleResponse.ok) {
171
+ const settlePayload = await settleResponse.json();
172
+ if (settlePayload.txHash) {
173
+ responseHeaders[HEADER_PAYMENT_RESPONSE] = JSON.stringify({
174
+ settled: true,
175
+ txHash: settlePayload.txHash
176
+ });
177
+ }
178
+ }
179
+ } catch {
180
+ }
181
+ }
182
+ const result = {
183
+ success: true,
184
+ metadata: {
185
+ optionId: "x402",
186
+ verifier: "x402:facilitator",
187
+ amount: definition.amount,
188
+ currency: definition.currency.code,
189
+ network: definition.network
190
+ }
191
+ };
192
+ if (Object.keys(responseHeaders).length > 0) {
193
+ result.responseHeaders = responseHeaders;
194
+ }
195
+ return result;
196
+ } catch (error) {
197
+ return {
198
+ success: false,
199
+ failure: {
200
+ reason: error instanceof Error ? error.message : "Unknown error",
201
+ code: "verification_failed"
202
+ }
203
+ };
204
+ }
205
+ }
206
+ function toX402Requirement(definition) {
207
+ const decimals = definition.asset.decimals;
208
+ const units = decimalToBaseUnits(definition.amount, decimals);
209
+ return x402RequirementSchema.parse({
210
+ scheme: definition.scheme,
211
+ network: definition.network,
212
+ maxAmountRequired: units,
213
+ asset: definition.asset.address,
214
+ payTo: definition.payTo,
215
+ resource: definition.resource,
216
+ description: definition.description,
217
+ mimeType: "application/json",
218
+ maxTimeoutSeconds: 900,
219
+ extra: {
220
+ symbol: definition.asset.symbol,
221
+ currencyCode: definition.currency.code,
222
+ decimals
223
+ }
224
+ });
225
+ }
226
+ function decimalToBaseUnits(value, decimals) {
227
+ const [whole, fraction = ""] = value.split(".");
228
+ const sanitizedFraction = fraction.slice(0, decimals);
229
+ const paddedFraction = sanitizedFraction.padEnd(decimals, "0");
230
+ const combined = `${whole}${paddedFraction}`.replace(/^0+/, "");
231
+ return combined.length > 0 ? combined : "0";
232
+ }
233
+ function decodeJson(value, schema) {
234
+ const base64 = normalizeBase64(value);
235
+ const json = Buffer.from(base64, "base64").toString("utf-8");
236
+ const parsed = JSON.parse(json);
237
+ return schema.parse(parsed);
238
+ }
239
+ function normalizeBase64(input) {
240
+ if (/^[A-Za-z0-9+/=]+$/.test(input)) {
241
+ return input;
242
+ }
243
+ const restored = input.replace(/-/g, "+").replace(/_/g, "/");
244
+ const paddingNeeded = (4 - restored.length % 4) % 4;
245
+ return restored + "=".repeat(paddingNeeded);
246
+ }
247
+ function buildFacilitatorHeaders(facilitator) {
248
+ const headers = {
249
+ "Content-Type": "application/json"
250
+ };
251
+ if (facilitator.apiKeyHeader && process.env.X402_FACILITATOR_API_KEY) {
252
+ headers[facilitator.apiKeyHeader] = process.env.X402_FACILITATOR_API_KEY;
253
+ }
254
+ return headers;
255
+ }
256
+ function ensureTrailingSlash(url) {
257
+ return url.endsWith("/") ? url : `${url}/`;
258
+ }
259
+ var PAYMENT_HEADERS = [HEADER_X402, HEADER_PAYMENT_RESPONSE];
260
+ var X402Client = class {
261
+ constructor(config) {
262
+ this.account = privateKeyToAccount(config.privateKey);
263
+ const chain = baseSepolia;
264
+ this.walletClient = createWalletClient({
265
+ account: this.account,
266
+ chain,
267
+ transport: http(config.rpcUrl)
268
+ });
269
+ }
270
+ async pay(request) {
271
+ try {
272
+ const initialResponse = await fetch(request.url, {
273
+ method: request.method ?? "POST",
274
+ headers: {
275
+ "Content-Type": "application/json",
276
+ ...request.headers
277
+ },
278
+ ...request.body ? { body: JSON.stringify(request.body) } : {}
279
+ });
280
+ if (initialResponse.status !== 402) {
281
+ return {
282
+ success: initialResponse.ok,
283
+ response: initialResponse
284
+ };
285
+ }
286
+ const paymentRequirements = await initialResponse.json();
287
+ const x402Requirements = paymentRequirements.x402?.accepts?.[0];
288
+ if (!x402Requirements) {
289
+ return {
290
+ success: false,
291
+ error: "No x402 payment requirements found in 402 response"
292
+ };
293
+ }
294
+ const authorization = await this.signTransferAuthorization({
295
+ from: this.account.address,
296
+ to: x402Requirements.payTo,
297
+ value: BigInt(x402Requirements.maxAmountRequired),
298
+ validAfter: BigInt(Math.floor(Date.now() / 1e3)),
299
+ validBefore: BigInt(Math.floor(Date.now() / 1e3) + 900),
300
+ // 15 min
301
+ nonce: `0x${Array.from(
302
+ { length: 32 },
303
+ () => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")
304
+ ).join("")}`,
305
+ tokenAddress: x402Requirements.asset
306
+ });
307
+ const paymentProof = {
308
+ x402Version: 1,
309
+ scheme: x402Requirements.scheme,
310
+ network: x402Requirements.network,
311
+ correlationId: "",
312
+ payload: {
313
+ signature: authorization.signature,
314
+ authorization: {
315
+ from: authorization.from,
316
+ to: authorization.to,
317
+ value: authorization.value.toString(),
318
+ validAfter: authorization.validAfter.toString(),
319
+ validBefore: authorization.validBefore.toString(),
320
+ nonce: authorization.nonce
321
+ }
322
+ }
323
+ };
324
+ const paymentHeader = Buffer.from(JSON.stringify(paymentProof)).toString("base64");
325
+ const paidResponse = await fetch(request.url, {
326
+ method: request.method ?? "POST",
327
+ headers: {
328
+ "Content-Type": "application/json",
329
+ "X-PAYMENT": paymentHeader,
330
+ ...request.headers
331
+ },
332
+ ...request.body ? { body: JSON.stringify(request.body) } : {}
333
+ });
334
+ return {
335
+ success: paidResponse.ok,
336
+ response: paidResponse,
337
+ paymentDetails: {
338
+ amount: x402Requirements.maxAmountRequired,
339
+ currency: x402Requirements.extra?.currencyCode ?? "USDC",
340
+ network: x402Requirements.network,
341
+ signature: authorization.signature
342
+ }
343
+ };
344
+ } catch (error) {
345
+ return {
346
+ success: false,
347
+ error: error instanceof Error ? error.message : String(error)
348
+ };
349
+ }
350
+ }
351
+ async signTransferAuthorization(params) {
352
+ if (!this.walletClient.chain) {
353
+ throw new Error("Wallet client chain not configured");
354
+ }
355
+ const domain = {
356
+ name: "USD Coin",
357
+ version: "2",
358
+ chainId: this.walletClient.chain.id,
359
+ verifyingContract: params.tokenAddress
360
+ };
361
+ const types = {
362
+ TransferWithAuthorization: [
363
+ { name: "from", type: "address" },
364
+ { name: "to", type: "address" },
365
+ { name: "value", type: "uint256" },
366
+ { name: "validAfter", type: "uint256" },
367
+ { name: "validBefore", type: "uint256" },
368
+ { name: "nonce", type: "bytes32" }
369
+ ]
370
+ };
371
+ const message = {
372
+ from: params.from,
373
+ to: params.to,
374
+ value: params.value,
375
+ validAfter: params.validAfter,
376
+ validBefore: params.validBefore,
377
+ nonce: params.nonce
378
+ };
379
+ const signature = await this.walletClient.signTypedData({
380
+ account: this.account,
381
+ domain,
382
+ types,
383
+ primaryType: "TransferWithAuthorization",
384
+ message
385
+ });
386
+ return {
387
+ signature,
388
+ from: params.from,
389
+ to: params.to,
390
+ value: params.value,
391
+ validAfter: params.validAfter,
392
+ validBefore: params.validBefore,
393
+ nonce: params.nonce
394
+ };
395
+ }
396
+ getAddress() {
397
+ return this.account.address;
398
+ }
399
+ };
400
+ async function payX402(config) {
401
+ const client = new X402Client({
402
+ privateKey: config.privateKey,
403
+ ...config.rpcUrl ? { rpcUrl: config.rpcUrl } : {}
404
+ });
405
+ return client.pay({
406
+ url: config.url,
407
+ body: config.body
408
+ });
409
+ }
410
+ var X402BrowserClient = class {
411
+ constructor(config) {
412
+ this.walletClient = config.walletClient;
413
+ this.chainId = config.chainId;
414
+ }
415
+ async pay(request) {
416
+ try {
417
+ const initialResponse = await fetch(request.url, {
418
+ method: request.method ?? "POST",
419
+ headers: {
420
+ "Content-Type": "application/json",
421
+ ...request.headers
422
+ },
423
+ ...request.body ? { body: JSON.stringify(request.body) } : {}
424
+ });
425
+ if (initialResponse.status !== 402) {
426
+ return {
427
+ success: initialResponse.ok,
428
+ response: initialResponse
429
+ };
430
+ }
431
+ const paymentRequirements = await initialResponse.json();
432
+ const x402Requirements = paymentRequirements.x402?.accepts?.[0];
433
+ if (!x402Requirements) {
434
+ return {
435
+ success: false,
436
+ error: "No x402 payment requirements found in 402 response"
437
+ };
438
+ }
439
+ const account = this.walletClient.account;
440
+ if (!account) {
441
+ return {
442
+ success: false,
443
+ error: "No account connected to wallet"
444
+ };
445
+ }
446
+ const authorization = {
447
+ from: account.address,
448
+ to: x402Requirements.payTo,
449
+ value: BigInt(x402Requirements.maxAmountRequired),
450
+ validAfter: BigInt(Math.floor(Date.now() / 1e3)),
451
+ validBefore: BigInt(Math.floor(Date.now() / 1e3) + 900),
452
+ nonce: `0x${Array.from(
453
+ { length: 32 },
454
+ () => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")
455
+ ).join("")}`
456
+ };
457
+ const signature = await this.signTransferAuthorization(
458
+ authorization,
459
+ x402Requirements.asset
460
+ );
461
+ const paymentProof = {
462
+ x402Version: 1,
463
+ scheme: x402Requirements.scheme,
464
+ network: x402Requirements.network,
465
+ correlationId: "",
466
+ payload: {
467
+ signature,
468
+ authorization: {
469
+ from: authorization.from,
470
+ to: authorization.to,
471
+ value: authorization.value.toString(),
472
+ validAfter: authorization.validAfter.toString(),
473
+ validBefore: authorization.validBefore.toString(),
474
+ nonce: authorization.nonce
475
+ }
476
+ }
477
+ };
478
+ const paymentHeader = btoa(JSON.stringify(paymentProof));
479
+ const paidResponse = await fetch(request.url, {
480
+ method: request.method ?? "POST",
481
+ headers: {
482
+ "Content-Type": "application/json",
483
+ "X-PAYMENT": paymentHeader,
484
+ ...request.headers
485
+ },
486
+ ...request.body ? { body: JSON.stringify(request.body) } : {}
487
+ });
488
+ return {
489
+ success: paidResponse.ok,
490
+ response: paidResponse,
491
+ paymentDetails: {
492
+ amount: x402Requirements.maxAmountRequired,
493
+ currency: x402Requirements.extra?.currencyCode ?? "USDC",
494
+ network: x402Requirements.network,
495
+ signature
496
+ }
497
+ };
498
+ } catch (error) {
499
+ return {
500
+ success: false,
501
+ error: error instanceof Error ? error.message : String(error)
502
+ };
503
+ }
504
+ }
505
+ async signTransferAuthorization(authorization, tokenAddress) {
506
+ const account = this.walletClient.account;
507
+ if (!account) {
508
+ throw new Error("No account connected to wallet");
509
+ }
510
+ const domain = {
511
+ name: "USD Coin",
512
+ version: "2",
513
+ chainId: this.chainId,
514
+ verifyingContract: tokenAddress
515
+ };
516
+ const types = {
517
+ TransferWithAuthorization: [
518
+ { name: "from", type: "address" },
519
+ { name: "to", type: "address" },
520
+ { name: "value", type: "uint256" },
521
+ { name: "validAfter", type: "uint256" },
522
+ { name: "validBefore", type: "uint256" },
523
+ { name: "nonce", type: "bytes32" }
524
+ ]
525
+ };
526
+ const message = {
527
+ from: authorization.from,
528
+ to: authorization.to,
529
+ value: authorization.value,
530
+ validAfter: authorization.validAfter,
531
+ validBefore: authorization.validBefore,
532
+ nonce: authorization.nonce
533
+ };
534
+ return await this.walletClient.signTypedData({
535
+ account,
536
+ domain,
537
+ types,
538
+ primaryType: "TransferWithAuthorization",
539
+ message
540
+ });
541
+ }
542
+ };
543
+ async function payX402WithWallet(walletClient, chainId, request) {
544
+ const client = new X402BrowserClient({ walletClient, chainId });
545
+ return client.pay(request);
546
+ }
547
+
548
+ // src/x402/index.ts
549
+ var PAYMENT_CONTEXT_SYMBOL = Symbol.for("opentool.x402.context");
550
+ var X402PaymentRequiredError = class extends Error {
551
+ constructor(response, verification) {
552
+ super("X402 Payment required");
553
+ this.name = "X402PaymentRequiredError";
554
+ this.response = response;
555
+ this.verification = verification;
556
+ }
557
+ };
558
+ function setPaymentContext(request, context) {
559
+ try {
560
+ Object.defineProperty(request, PAYMENT_CONTEXT_SYMBOL, {
561
+ value: context,
562
+ configurable: true,
563
+ enumerable: false,
564
+ writable: true
565
+ });
566
+ } catch {
567
+ request[PAYMENT_CONTEXT_SYMBOL] = context;
568
+ }
569
+ }
570
+ function getX402PaymentContext(request) {
571
+ return request[PAYMENT_CONTEXT_SYMBOL];
572
+ }
573
+ function defineX402Payment(config) {
574
+ const currencyCode = normalizeCurrency(config.currency);
575
+ const currencySpec = SUPPORTED_CURRENCIES[currencyCode];
576
+ if (!currencySpec) {
577
+ throw new Error(`Unsupported currency for x402 payments: ${currencyCode}`);
578
+ }
579
+ const network = config.network ?? currencySpec.network;
580
+ const assetAddress = config.assetAddress ?? currencySpec.assetAddress;
581
+ if (!network || !assetAddress) {
582
+ throw new Error(
583
+ "x402 payments require a network and assetAddress; supply them or choose a supported currency."
584
+ );
585
+ }
586
+ const facilitator = resolveFacilitator(config.facilitator);
587
+ const value = toDecimalString(config.amount);
588
+ const definition = {
589
+ amount: value,
590
+ currency: {
591
+ code: currencyCode,
592
+ symbol: currencySpec.symbol,
593
+ decimals: currencySpec.decimals
594
+ },
595
+ asset: {
596
+ symbol: currencySpec.symbol,
597
+ network,
598
+ address: assetAddress,
599
+ decimals: currencySpec.decimals
600
+ },
601
+ payTo: config.payTo,
602
+ scheme: config.scheme ?? "exact",
603
+ network,
604
+ facilitator
605
+ };
606
+ if (config.resource) {
607
+ definition.resource = config.resource;
608
+ }
609
+ if (config.message) {
610
+ definition.description = config.message;
611
+ }
612
+ if (config.metadata) {
613
+ definition.metadata = config.metadata;
614
+ }
615
+ const baseMetadata = {
616
+ amountUSDC: currencyCode === "USDC" ? Number(value) : void 0,
617
+ facilitator: "x402rs",
618
+ network
619
+ };
620
+ const metadata = config.metadata ? { ...baseMetadata, ...config.metadata } : baseMetadata;
621
+ return {
622
+ definition,
623
+ metadata
624
+ };
625
+ }
626
+ async function requireX402Payment(request, payment, options = {}) {
627
+ const definition = isX402Payment(payment) ? payment.definition : payment;
628
+ const attempt = extractX402Attempt(request);
629
+ if (!attempt) {
630
+ const response = createX402PaymentRequired(definition);
631
+ throw new X402PaymentRequiredError(response);
632
+ }
633
+ const verifyOptions = {};
634
+ if (options.settle !== void 0) {
635
+ verifyOptions.settle = options.settle;
636
+ }
637
+ if (options.fetchImpl !== void 0) {
638
+ verifyOptions.fetchImpl = options.fetchImpl;
639
+ }
640
+ const verification = await verifyX402Payment(attempt, definition, verifyOptions);
641
+ if (!verification.success || !verification.metadata) {
642
+ if (options.onFailure) {
643
+ return options.onFailure(verification);
644
+ }
645
+ const response = createX402PaymentRequired(definition);
646
+ throw new X402PaymentRequiredError(response, verification);
647
+ }
648
+ return {
649
+ payment: verification.metadata,
650
+ headers: verification.responseHeaders ?? {},
651
+ result: verification
652
+ };
653
+ }
654
+ function withX402Payment(handler, payment, options = {}) {
655
+ return async (request) => {
656
+ const verification = await requireX402Payment(request, payment, options);
657
+ if (verification instanceof Response) {
658
+ return verification;
659
+ }
660
+ setPaymentContext(request, verification);
661
+ const response = await Promise.resolve(handler(request));
662
+ return applyPaymentHeaders(response, verification.headers);
663
+ };
664
+ }
665
+ function applyPaymentHeaders(response, headers) {
666
+ const entries = Object.entries(headers ?? {});
667
+ if (entries.length === 0) {
668
+ return response;
669
+ }
670
+ let mutated = false;
671
+ const merged = new Headers(response.headers);
672
+ for (const [key, value] of entries) {
673
+ if (!merged.has(key)) {
674
+ merged.set(key, value);
675
+ mutated = true;
676
+ }
677
+ }
678
+ if (!mutated) {
679
+ return response;
680
+ }
681
+ return new Response(response.body, {
682
+ status: response.status,
683
+ statusText: response.statusText,
684
+ headers: merged
685
+ });
686
+ }
687
+ function isX402Payment(value) {
688
+ return !!value && typeof value === "object" && "definition" in value && value.definition !== void 0;
689
+ }
690
+ function resolveFacilitator(value) {
691
+ if (!value) {
692
+ return DEFAULT_FACILITATOR;
693
+ }
694
+ if (typeof value === "string") {
695
+ return { ...DEFAULT_FACILITATOR, url: value };
696
+ }
697
+ return value;
698
+ }
699
+ function normalizeCurrency(currency) {
700
+ return (currency ?? "USDC").toUpperCase();
701
+ }
702
+ function toDecimalString(value) {
703
+ return typeof value === "number" ? value.toString() : value;
704
+ }
705
+
706
+ export { DEFAULT_FACILITATOR, PAYMENT_HEADERS, SUPPORTED_CURRENCIES, X402BrowserClient, X402Client, X402PaymentRequiredError, defineX402Payment, getX402PaymentContext, payX402, payX402WithWallet, requireX402Payment, withX402Payment };
707
+ //# sourceMappingURL=index.js.map
708
+ //# sourceMappingURL=index.js.map