@bankofai/x402-core 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +294 -0
  2. package/dist/cjs/client/index.d.ts +149 -0
  3. package/dist/cjs/client/index.js +909 -0
  4. package/dist/cjs/client/index.js.map +1 -0
  5. package/dist/cjs/facilitator/index.d.ts +206 -0
  6. package/dist/cjs/facilitator/index.js +431 -0
  7. package/dist/cjs/facilitator/index.js.map +1 -0
  8. package/dist/cjs/http/index.d.ts +50 -0
  9. package/dist/cjs/http/index.js +1452 -0
  10. package/dist/cjs/http/index.js.map +1 -0
  11. package/dist/cjs/index.d.ts +3 -0
  12. package/dist/cjs/index.js +31 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/schemas/index.d.ts +891 -0
  15. package/dist/cjs/schemas/index.js +216 -0
  16. package/dist/cjs/schemas/index.js.map +1 -0
  17. package/dist/cjs/server/index.d.ts +79 -0
  18. package/dist/cjs/server/index.js +2568 -0
  19. package/dist/cjs/server/index.js.map +1 -0
  20. package/dist/cjs/types/index.d.ts +1 -0
  21. package/dist/cjs/types/index.js +97 -0
  22. package/dist/cjs/types/index.js.map +1 -0
  23. package/dist/cjs/types/v1/index.d.ts +1 -0
  24. package/dist/cjs/types/v1/index.js +19 -0
  25. package/dist/cjs/types/v1/index.js.map +1 -0
  26. package/dist/cjs/utils/index.d.ts +77 -0
  27. package/dist/cjs/utils/index.js +179 -0
  28. package/dist/cjs/utils/index.js.map +1 -0
  29. package/dist/cjs/x402Client-BgegfQgE.d.ts +1807 -0
  30. package/dist/cjs/x402Client-TQHctrG7.d.ts +1807 -0
  31. package/dist/esm/chunk-ABS7D6VX.mjs +145 -0
  32. package/dist/esm/chunk-ABS7D6VX.mjs.map +1 -0
  33. package/dist/esm/chunk-AGOUMC4P.mjs +68 -0
  34. package/dist/esm/chunk-AGOUMC4P.mjs.map +1 -0
  35. package/dist/esm/chunk-BJTO5JO5.mjs +11 -0
  36. package/dist/esm/chunk-BJTO5JO5.mjs.map +1 -0
  37. package/dist/esm/chunk-FPXAE3OS.mjs +161 -0
  38. package/dist/esm/chunk-FPXAE3OS.mjs.map +1 -0
  39. package/dist/esm/chunk-IL77TMJL.mjs +1275 -0
  40. package/dist/esm/chunk-IL77TMJL.mjs.map +1 -0
  41. package/dist/esm/chunk-VE37GDG2.mjs +7 -0
  42. package/dist/esm/chunk-VE37GDG2.mjs.map +1 -0
  43. package/dist/esm/client/index.d.mts +149 -0
  44. package/dist/esm/client/index.mjs +504 -0
  45. package/dist/esm/client/index.mjs.map +1 -0
  46. package/dist/esm/facilitator/index.d.mts +206 -0
  47. package/dist/esm/facilitator/index.mjs +399 -0
  48. package/dist/esm/facilitator/index.mjs.map +1 -0
  49. package/dist/esm/http/index.d.mts +50 -0
  50. package/dist/esm/http/index.mjs +35 -0
  51. package/dist/esm/http/index.mjs.map +1 -0
  52. package/dist/esm/index.d.mts +3 -0
  53. package/dist/esm/index.mjs +8 -0
  54. package/dist/esm/index.mjs.map +1 -0
  55. package/dist/esm/schemas/index.d.mts +891 -0
  56. package/dist/esm/schemas/index.mjs +70 -0
  57. package/dist/esm/schemas/index.mjs.map +1 -0
  58. package/dist/esm/server/index.d.mts +79 -0
  59. package/dist/esm/server/index.mjs +1318 -0
  60. package/dist/esm/server/index.mjs.map +1 -0
  61. package/dist/esm/types/index.d.mts +1 -0
  62. package/dist/esm/types/index.mjs +14 -0
  63. package/dist/esm/types/index.mjs.map +1 -0
  64. package/dist/esm/types/v1/index.d.mts +1 -0
  65. package/dist/esm/types/v1/index.mjs +1 -0
  66. package/dist/esm/types/v1/index.mjs.map +1 -0
  67. package/dist/esm/utils/index.d.mts +77 -0
  68. package/dist/esm/utils/index.mjs +28 -0
  69. package/dist/esm/utils/index.mjs.map +1 -0
  70. package/dist/esm/x402Client-BgegfQgE.d.mts +1807 -0
  71. package/dist/esm/x402Client-TQHctrG7.d.mts +1807 -0
  72. package/package.json +142 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/types/index.ts","../../../src/types/facilitator.ts"],"sourcesContent":["export type {\n VerifyRequest,\n VerifyResponse,\n SettleRequest,\n SettleResponse,\n SupportedResponse,\n SupportedKind,\n} from \"./facilitator\";\nexport {\n VerifyError,\n SettleError,\n FacilitatorResponseError,\n getFacilitatorResponseError,\n} from \"./facilitator\";\nexport type {\n PaymentRequirements,\n PaymentPayload,\n PaymentRequired,\n ResourceInfo,\n} from \"./payments\";\nexport type {\n SchemeNetworkClient,\n SchemeClientHooks,\n SchemeNetworkFacilitator,\n SchemeNetworkServer,\n SchemeServerHooks,\n MoneyParser,\n PaymentPayloadResult,\n PaymentPayloadContext,\n FacilitatorContext,\n SchemePaymentRequiredContext,\n SchemeEnrichPaymentRequiredResponseHook,\n} from \"./mechanisms\";\nexport type { PaymentRequirementsV1, PaymentRequiredV1, PaymentPayloadV1 } from \"./v1\";\nexport type {\n FacilitatorExtension,\n ResourceServerExtension,\n ResourceServerExtensionHooks,\n PaymentRequiredContext,\n ResourceServerTransportExtensionHooks,\n HTTPResourceServerExtensionHooks,\n SettleResultContext,\n VerifyContext,\n VerifyResultContext,\n VerifyFailureContext,\n SettleContext,\n SettleFailureContext,\n VerifiedPaymentCanceledContext,\n} from \"./extensions\";\n\nexport type { DeepReadonly } from \"./readonly\";\n\nexport type Network = `${string}:${string}`;\n\nexport type Money = string | number;\nexport type AssetAmount = {\n asset: string;\n amount: string;\n extra?: Record<string, unknown>;\n};\nexport type Price = Money | AssetAmount;\n","import { PaymentPayload, PaymentRequirements } from \"./payments\";\nimport { Network } from \"./\";\n\nexport type VerifyRequest = {\n x402Version: number;\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n};\n\nexport type VerifyResponse = {\n isValid: boolean;\n invalidReason?: string;\n invalidMessage?: string;\n payer?: string;\n extensions?: Record<string, unknown>;\n extra?: Record<string, unknown>;\n};\n\nexport type SettleRequest = {\n x402Version: number;\n paymentPayload: PaymentPayload;\n paymentRequirements: PaymentRequirements;\n};\n\nexport type SettleResponse = {\n success: boolean;\n errorReason?: string;\n errorMessage?: string;\n payer?: string;\n transaction: string;\n network: Network;\n /** Actual amount settled in atomic token units. Present for schemes like `upto` where settlement amount may differ from the authorized maximum. */\n amount?: string;\n extensions?: Record<string, unknown>;\n extra?: Record<string, unknown>;\n};\n\nexport type SupportedKind = {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n};\n\nexport type SupportedResponse = {\n kinds: SupportedKind[];\n extensions: string[];\n signers: Record<string, string[]>; // CAIP family pattern → Signer addresses\n};\n\n/**\n * Error thrown when payment verification fails.\n */\nexport class VerifyError extends Error {\n readonly invalidReason?: string;\n readonly invalidMessage?: string;\n readonly payer?: string;\n readonly statusCode: number;\n\n /**\n * Creates a VerifyError from a failed verification response.\n *\n * @param statusCode - HTTP status code from the facilitator\n * @param response - The verify response containing failure details\n */\n constructor(statusCode: number, response: VerifyResponse) {\n const reason = response.invalidReason || \"unknown reason\";\n const message = response.invalidMessage;\n super(message ? `${reason}: ${message}` : reason);\n this.name = \"VerifyError\";\n this.statusCode = statusCode;\n this.invalidReason = response.invalidReason;\n this.invalidMessage = response.invalidMessage;\n this.payer = response.payer;\n }\n}\n\n/**\n * Error thrown when payment settlement fails.\n */\nexport class SettleError extends Error {\n readonly errorReason?: string;\n readonly errorMessage?: string;\n readonly payer?: string;\n readonly transaction: string;\n readonly network: Network;\n readonly statusCode: number;\n\n /**\n * Creates a SettleError from a failed settlement response.\n *\n * @param statusCode - HTTP status code from the facilitator\n * @param response - The settle response containing error details\n */\n constructor(statusCode: number, response: SettleResponse) {\n const reason = response.errorReason || \"unknown reason\";\n const message = response.errorMessage;\n super(message ? `${reason}: ${message}` : reason);\n this.name = \"SettleError\";\n this.statusCode = statusCode;\n this.errorReason = response.errorReason;\n this.errorMessage = response.errorMessage;\n this.payer = response.payer;\n this.transaction = response.transaction;\n this.network = response.network;\n }\n}\n\n/**\n * Error thrown when a facilitator returns malformed success payload data.\n */\nexport class FacilitatorResponseError extends Error {\n /**\n * Creates a FacilitatorResponseError for malformed facilitator responses.\n *\n * @param message - The boundary error message\n */\n constructor(message: string) {\n super(message);\n this.name = \"FacilitatorResponseError\";\n }\n}\n\n/**\n * Walks an error cause chain to find the first facilitator response error.\n *\n * @param error - The thrown value to inspect\n * @returns The nested facilitator response error, if present\n */\nexport function getFacilitatorResponseError(error: unknown): FacilitatorResponseError | null {\n let current = error;\n\n while (current instanceof Error) {\n if (current instanceof FacilitatorResponseError) {\n return current;\n }\n current = current.cause;\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACqDO,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYrC,YAAY,YAAoB,UAA0B;AACxD,UAAM,SAAS,SAAS,iBAAiB;AACzC,UAAM,UAAU,SAAS;AACzB,UAAM,UAAU,GAAG,MAAM,KAAK,OAAO,KAAK,MAAM;AAChD,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,gBAAgB,SAAS;AAC9B,SAAK,iBAAiB,SAAS;AAC/B,SAAK,QAAQ,SAAS;AAAA,EACxB;AACF;AAKO,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcrC,YAAY,YAAoB,UAA0B;AACxD,UAAM,SAAS,SAAS,eAAe;AACvC,UAAM,UAAU,SAAS;AACzB,UAAM,UAAU,GAAG,MAAM,KAAK,OAAO,KAAK,MAAM;AAChD,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,cAAc,SAAS;AAC5B,SAAK,eAAe,SAAS;AAC7B,SAAK,QAAQ,SAAS;AACtB,SAAK,cAAc,SAAS;AAC5B,SAAK,UAAU,SAAS;AAAA,EAC1B;AACF;AAKO,IAAM,2BAAN,cAAuC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAQO,SAAS,4BAA4B,OAAiD;AAC3F,MAAI,UAAU;AAEd,SAAO,mBAAmB,OAAO;AAC/B,QAAI,mBAAmB,0BAA0B;AAC/C,aAAO;AAAA,IACT;AACA,cAAU,QAAQ;AAAA,EACpB;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1 @@
1
+ export { aw as PaymentPayloadV1, av as PaymentRequiredV1, au as PaymentRequirementsV1, ay as SettleRequestV1, az as SettleResponseV1, aA as SupportedResponseV1, ax as VerifyRequestV1 } from '../../x402Client-TQHctrG7.js';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/types/v1/index.ts
17
+ var v1_exports = {};
18
+ module.exports = __toCommonJS(v1_exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/types/v1/index.ts"],"sourcesContent":["import { Network } from \"../\";\n\n// Payments\nexport type PaymentRequirementsV1 = {\n scheme: string;\n network: Network;\n maxAmountRequired: string;\n resource: string;\n description: string;\n mimeType: string;\n outputSchema: Record<string, unknown>;\n payTo: string;\n maxTimeoutSeconds: number;\n asset: string;\n extra: Record<string, unknown>;\n};\n\nexport type PaymentRequiredV1 = {\n x402Version: 1;\n error?: string;\n accepts: PaymentRequirementsV1[];\n};\n\nexport type PaymentPayloadV1 = {\n x402Version: 1;\n scheme: string;\n network: Network;\n payload: Record<string, unknown>;\n};\n\n// Facilitator Requests/Responses\nexport type VerifyRequestV1 = {\n x402Version: number;\n paymentPayload: PaymentPayloadV1;\n paymentRequirements: PaymentRequirementsV1;\n};\n\nexport type SettleRequestV1 = {\n x402Version: number;\n paymentPayload: PaymentPayloadV1;\n paymentRequirements: PaymentRequirementsV1;\n};\n\nexport type SettleResponseV1 = {\n success: boolean;\n errorReason?: string;\n errorMessage?: string;\n payer?: string;\n transaction: string;\n network: Network;\n};\n\nexport type SupportedResponseV1 = {\n kinds: {\n x402Version: number;\n scheme: string;\n network: Network;\n extra?: Record<string, unknown>;\n }[];\n // NO extensions field - V1 doesn't support extensions\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,77 @@
1
+ import { N as Network } from '../x402Client-TQHctrG7.js';
2
+
3
+ /**
4
+ * Converts a JavaScript number to a plain decimal string, expanding scientific notation
5
+ * via string manipulation rather than parseFloat round-tripping.
6
+ *
7
+ * e.g. 1e-7 → "0.0000001", 4.02 → "4.02"
8
+ *
9
+ * @param n - The number to convert
10
+ * @returns A plain decimal string representation with no scientific notation
11
+ */
12
+ declare function numberToDecimalString(n: number): string;
13
+ /**
14
+ * Parses a money string into a finite, non-negative decimal number.
15
+ * Accepts plain decimal strings with an optional leading dollar sign.
16
+ *
17
+ * @param money - The money string to parse
18
+ * @returns Decimal number
19
+ */
20
+ declare function parseMoneyString(money: string): number;
21
+ /**
22
+ * Convert a decimal amount to token smallest units.
23
+ * Accepts only plain decimal strings — scientific notation is not allowed.
24
+ * Throws if the amount is non-zero but too small to represent with the given decimal precision.
25
+ *
26
+ * @param decimalAmount - The decimal amount as a plain string (e.g., "0.10")
27
+ * @param decimals - The number of decimals for the token (e.g., 6 for USDC)
28
+ * @returns The amount in smallest units as a string
29
+ */
30
+ declare function convertToTokenAmount(decimalAmount: string, decimals: number): string;
31
+ /**
32
+ * Scheme data structure for facilitator storage
33
+ */
34
+ interface SchemeData<T> {
35
+ facilitator: T;
36
+ networks: Set<Network>;
37
+ pattern: Network;
38
+ }
39
+ declare const networkMatchesPattern: (pattern: Network, network: Network) => boolean;
40
+ declare const findSchemesByNetwork: <T>(map: Map<string, Map<string, T>>, network: Network) => Map<string, T> | undefined;
41
+ declare const findByNetworkAndScheme: <T>(map: Map<string, Map<string, T>>, scheme: string, network: Network) => T | undefined;
42
+ /**
43
+ * Finds a facilitator by scheme and network using pattern matching.
44
+ * Works with new SchemeData storage structure.
45
+ *
46
+ * @param schemeMap - Map of scheme names to SchemeData
47
+ * @param scheme - The scheme to find
48
+ * @param network - The network to match against
49
+ * @returns The facilitator if found, undefined otherwise
50
+ */
51
+ declare const findFacilitatorBySchemeAndNetwork: <T>(schemeMap: Map<string, SchemeData<T>>, scheme: string, network: Network) => T | undefined;
52
+ declare const Base64EncodedRegex: RegExp;
53
+ /**
54
+ * Encodes a string to base64 format
55
+ *
56
+ * @param data - The string to be encoded to base64
57
+ * @returns The base64 encoded string
58
+ */
59
+ declare function safeBase64Encode(data: string): string;
60
+ /**
61
+ * Decodes a base64 string back to its original format
62
+ *
63
+ * @param data - The base64 encoded string to be decoded
64
+ * @returns The decoded string in UTF-8 format
65
+ */
66
+ declare function safeBase64Decode(data: string): string;
67
+ /**
68
+ * Deep equality comparison for payment requirements
69
+ * Uses a normalized JSON.stringify for consistent comparison
70
+ *
71
+ * @param obj1 - First object to compare
72
+ * @param obj2 - Second object to compare
73
+ * @returns True if objects are deeply equal
74
+ */
75
+ declare function deepEqual(obj1: unknown, obj2: unknown): boolean;
76
+
77
+ export { Base64EncodedRegex, type SchemeData, convertToTokenAmount, deepEqual, findByNetworkAndScheme, findFacilitatorBySchemeAndNetwork, findSchemesByNetwork, networkMatchesPattern, numberToDecimalString, parseMoneyString, safeBase64Decode, safeBase64Encode };
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/utils/index.ts
21
+ var utils_exports = {};
22
+ __export(utils_exports, {
23
+ Base64EncodedRegex: () => Base64EncodedRegex,
24
+ convertToTokenAmount: () => convertToTokenAmount,
25
+ deepEqual: () => deepEqual,
26
+ findByNetworkAndScheme: () => findByNetworkAndScheme,
27
+ findFacilitatorBySchemeAndNetwork: () => findFacilitatorBySchemeAndNetwork,
28
+ findSchemesByNetwork: () => findSchemesByNetwork,
29
+ networkMatchesPattern: () => networkMatchesPattern,
30
+ numberToDecimalString: () => numberToDecimalString,
31
+ parseMoneyString: () => parseMoneyString,
32
+ safeBase64Decode: () => safeBase64Decode,
33
+ safeBase64Encode: () => safeBase64Encode
34
+ });
35
+ module.exports = __toCommonJS(utils_exports);
36
+ function numberToDecimalString(n) {
37
+ const str = n.toString();
38
+ if (!/[eE]/.test(str)) return str;
39
+ const [significand, exponentStr] = str.split(/[eE]/);
40
+ const exp = parseInt(exponentStr, 10);
41
+ const negative = significand.startsWith("-");
42
+ const abs = negative ? significand.slice(1) : significand;
43
+ const [intDigits, fracDigits = ""] = abs.split(".");
44
+ const allDigits = intDigits + fracDigits;
45
+ const decimalPos = intDigits.length + exp;
46
+ let result;
47
+ if (decimalPos <= 0) {
48
+ result = "0." + "0".repeat(-decimalPos) + allDigits;
49
+ } else if (decimalPos >= allDigits.length) {
50
+ result = allDigits + "0".repeat(decimalPos - allDigits.length);
51
+ } else {
52
+ result = allDigits.slice(0, decimalPos) + "." + allDigits.slice(decimalPos);
53
+ }
54
+ return (negative ? "-" : "") + result;
55
+ }
56
+ function parseMoneyString(money) {
57
+ const cleaned = money.replace(/^\$/, "").trim();
58
+ if (!/^-?\d+(?:\.\d+)?$/.test(cleaned) || /[eE]/.test(cleaned)) {
59
+ throw new Error(`Invalid money format: ${money}`);
60
+ }
61
+ const amount = Number(cleaned);
62
+ if (!Number.isFinite(amount) || amount < 0) {
63
+ throw new Error(`Invalid money format: ${money}`);
64
+ }
65
+ return amount;
66
+ }
67
+ function convertToTokenAmount(decimalAmount, decimals) {
68
+ if (/[eE]/.test(decimalAmount)) {
69
+ throw new Error(
70
+ `Invalid amount: ${decimalAmount} \u2014 use decimal notation, not scientific notation`
71
+ );
72
+ }
73
+ if (!/^-?\d+\.?\d*$/.test(decimalAmount)) {
74
+ throw new Error(`Invalid amount: ${decimalAmount}`);
75
+ }
76
+ const [intPart, decPart = ""] = decimalAmount.split(".");
77
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
78
+ const tokenAmount = (intPart + paddedDec).replace(/^0+/, "") || "0";
79
+ if (tokenAmount === "0" && /[1-9]/.test(decimalAmount)) {
80
+ throw new Error(
81
+ `Amount ${decimalAmount} is too small to represent with ${decimals} decimal places`
82
+ );
83
+ }
84
+ return tokenAmount;
85
+ }
86
+ var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
87
+ var networkPatternToRegExp = (pattern) => {
88
+ const source = escapeRegExp(pattern).replace(/\\\*/g, ".*");
89
+ return new RegExp(`^${source}$`);
90
+ };
91
+ var networkMatchesPattern = (pattern, network) => {
92
+ return networkPatternToRegExp(pattern).test(network);
93
+ };
94
+ var findSchemesByNetwork = (map, network) => {
95
+ let implementationsByScheme = map.get(network);
96
+ if (!implementationsByScheme) {
97
+ for (const [registeredNetworkPattern, implementations] of map.entries()) {
98
+ if (networkMatchesPattern(registeredNetworkPattern, network)) {
99
+ implementationsByScheme = implementations;
100
+ break;
101
+ }
102
+ }
103
+ }
104
+ return implementationsByScheme;
105
+ };
106
+ var findByNetworkAndScheme = (map, scheme, network) => {
107
+ return findSchemesByNetwork(map, network)?.get(scheme);
108
+ };
109
+ var findFacilitatorBySchemeAndNetwork = (schemeMap, scheme, network) => {
110
+ const schemeData = schemeMap.get(scheme);
111
+ if (!schemeData) return void 0;
112
+ if (schemeData.networks.has(network)) {
113
+ return schemeData.facilitator;
114
+ }
115
+ if (networkMatchesPattern(schemeData.pattern, network)) {
116
+ return schemeData.facilitator;
117
+ }
118
+ return void 0;
119
+ };
120
+ var Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/;
121
+ function safeBase64Encode(data) {
122
+ if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") {
123
+ const bytes = new TextEncoder().encode(data);
124
+ const binaryString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
125
+ return globalThis.btoa(binaryString);
126
+ }
127
+ return Buffer.from(data, "utf8").toString("base64");
128
+ }
129
+ function safeBase64Decode(data) {
130
+ if (typeof globalThis !== "undefined" && typeof globalThis.atob === "function") {
131
+ const binaryString = globalThis.atob(data);
132
+ const bytes = new Uint8Array(binaryString.length);
133
+ for (let i = 0; i < binaryString.length; i++) {
134
+ bytes[i] = binaryString.charCodeAt(i);
135
+ }
136
+ const decoder = new TextDecoder("utf-8");
137
+ return decoder.decode(bytes);
138
+ }
139
+ return Buffer.from(data, "base64").toString("utf-8");
140
+ }
141
+ function deepEqual(obj1, obj2) {
142
+ const normalize = (obj) => {
143
+ if (obj === null || obj === void 0) return JSON.stringify(obj);
144
+ if (typeof obj !== "object") return JSON.stringify(obj);
145
+ if (Array.isArray(obj)) {
146
+ return JSON.stringify(
147
+ obj.map(
148
+ (item) => typeof item === "object" && item !== null ? JSON.parse(normalize(item)) : item
149
+ )
150
+ );
151
+ }
152
+ const sorted = {};
153
+ Object.keys(obj).sort().forEach((key) => {
154
+ const value = obj[key];
155
+ sorted[key] = typeof value === "object" && value !== null ? JSON.parse(normalize(value)) : value;
156
+ });
157
+ return JSON.stringify(sorted);
158
+ };
159
+ try {
160
+ return normalize(obj1) === normalize(obj2);
161
+ } catch {
162
+ return JSON.stringify(obj1) === JSON.stringify(obj2);
163
+ }
164
+ }
165
+ // Annotate the CommonJS export names for ESM import in node:
166
+ 0 && (module.exports = {
167
+ Base64EncodedRegex,
168
+ convertToTokenAmount,
169
+ deepEqual,
170
+ findByNetworkAndScheme,
171
+ findFacilitatorBySchemeAndNetwork,
172
+ findSchemesByNetwork,
173
+ networkMatchesPattern,
174
+ numberToDecimalString,
175
+ parseMoneyString,
176
+ safeBase64Decode,
177
+ safeBase64Encode
178
+ });
179
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/index.ts"],"sourcesContent":["import { Network } from \"../types\";\n\n/**\n * Converts a JavaScript number to a plain decimal string, expanding scientific notation\n * via string manipulation rather than parseFloat round-tripping.\n *\n * e.g. 1e-7 → \"0.0000001\", 4.02 → \"4.02\"\n *\n * @param n - The number to convert\n * @returns A plain decimal string representation with no scientific notation\n */\nexport function numberToDecimalString(n: number): string {\n const str = n.toString();\n if (!/[eE]/.test(str)) return str;\n\n const [significand, exponentStr] = str.split(/[eE]/);\n const exp = parseInt(exponentStr, 10);\n const negative = significand.startsWith(\"-\");\n const abs = negative ? significand.slice(1) : significand;\n const [intDigits, fracDigits = \"\"] = abs.split(\".\");\n const allDigits = intDigits + fracDigits;\n const decimalPos = intDigits.length + exp;\n\n let result: string;\n if (decimalPos <= 0) {\n result = \"0.\" + \"0\".repeat(-decimalPos) + allDigits;\n } else if (decimalPos >= allDigits.length) {\n result = allDigits + \"0\".repeat(decimalPos - allDigits.length);\n } else {\n result = allDigits.slice(0, decimalPos) + \".\" + allDigits.slice(decimalPos);\n }\n return (negative ? \"-\" : \"\") + result;\n}\n\n/**\n * Parses a money string into a finite, non-negative decimal number.\n * Accepts plain decimal strings with an optional leading dollar sign.\n *\n * @param money - The money string to parse\n * @returns Decimal number\n */\nexport function parseMoneyString(money: string): number {\n const cleaned = money.replace(/^\\$/, \"\").trim();\n if (!/^-?\\d+(?:\\.\\d+)?$/.test(cleaned) || /[eE]/.test(cleaned)) {\n throw new Error(`Invalid money format: ${money}`);\n }\n\n const amount = Number(cleaned);\n if (!Number.isFinite(amount) || amount < 0) {\n throw new Error(`Invalid money format: ${money}`);\n }\n return amount;\n}\n\n/**\n * Convert a decimal amount to token smallest units.\n * Accepts only plain decimal strings — scientific notation is not allowed.\n * Throws if the amount is non-zero but too small to represent with the given decimal precision.\n *\n * @param decimalAmount - The decimal amount as a plain string (e.g., \"0.10\")\n * @param decimals - The number of decimals for the token (e.g., 6 for USDC)\n * @returns The amount in smallest units as a string\n */\nexport function convertToTokenAmount(decimalAmount: string, decimals: number): string {\n if (/[eE]/.test(decimalAmount)) {\n throw new Error(\n `Invalid amount: ${decimalAmount} — use decimal notation, not scientific notation`,\n );\n }\n if (!/^-?\\d+\\.?\\d*$/.test(decimalAmount)) {\n throw new Error(`Invalid amount: ${decimalAmount}`);\n }\n const [intPart, decPart = \"\"] = decimalAmount.split(\".\");\n const paddedDec = decPart.padEnd(decimals, \"0\").slice(0, decimals);\n const tokenAmount = (intPart + paddedDec).replace(/^0+/, \"\") || \"0\";\n if (tokenAmount === \"0\" && /[1-9]/.test(decimalAmount)) {\n throw new Error(\n `Amount ${decimalAmount} is too small to represent with ${decimals} decimal places`,\n );\n }\n return tokenAmount;\n}\n\n/**\n * Scheme data structure for facilitator storage\n */\nexport interface SchemeData<T> {\n facilitator: T;\n networks: Set<Network>;\n pattern: Network;\n}\n\nconst escapeRegExp = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\nconst networkPatternToRegExp = (pattern: Network): RegExp => {\n const source = escapeRegExp(pattern).replace(/\\\\\\*/g, \".*\");\n return new RegExp(`^${source}$`);\n};\n\nexport const networkMatchesPattern = (pattern: Network, network: Network): boolean => {\n return networkPatternToRegExp(pattern).test(network);\n};\n\nexport const findSchemesByNetwork = <T>(\n map: Map<string, Map<string, T>>,\n network: Network,\n): Map<string, T> | undefined => {\n // Direct match first\n let implementationsByScheme = map.get(network);\n\n if (!implementationsByScheme) {\n // Try pattern matching for registered network patterns\n for (const [registeredNetworkPattern, implementations] of map.entries()) {\n if (networkMatchesPattern(registeredNetworkPattern as Network, network)) {\n implementationsByScheme = implementations;\n break;\n }\n }\n }\n\n return implementationsByScheme;\n};\n\nexport const findByNetworkAndScheme = <T>(\n map: Map<string, Map<string, T>>,\n scheme: string,\n network: Network,\n): T | undefined => {\n return findSchemesByNetwork(map, network)?.get(scheme);\n};\n\n/**\n * Finds a facilitator by scheme and network using pattern matching.\n * Works with new SchemeData storage structure.\n *\n * @param schemeMap - Map of scheme names to SchemeData\n * @param scheme - The scheme to find\n * @param network - The network to match against\n * @returns The facilitator if found, undefined otherwise\n */\nexport const findFacilitatorBySchemeAndNetwork = <T>(\n schemeMap: Map<string, SchemeData<T>>,\n scheme: string,\n network: Network,\n): T | undefined => {\n const schemeData = schemeMap.get(scheme);\n if (!schemeData) return undefined;\n\n // Check if network is in the stored networks set\n if (schemeData.networks.has(network)) {\n return schemeData.facilitator;\n }\n\n // Try pattern matching\n if (networkMatchesPattern(schemeData.pattern, network)) {\n return schemeData.facilitator;\n }\n\n return undefined;\n};\n\nexport const Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/;\n\n/**\n * Encodes a string to base64 format\n *\n * @param data - The string to be encoded to base64\n * @returns The base64 encoded string\n */\nexport function safeBase64Encode(data: string): string {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.btoa === \"function\") {\n const bytes = new TextEncoder().encode(data);\n const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join(\"\");\n return globalThis.btoa(binaryString);\n }\n return Buffer.from(data, \"utf8\").toString(\"base64\");\n}\n\n/**\n * Decodes a base64 string back to its original format\n *\n * @param data - The base64 encoded string to be decoded\n * @returns The decoded string in UTF-8 format\n */\nexport function safeBase64Decode(data: string): string {\n if (typeof globalThis !== \"undefined\" && typeof globalThis.atob === \"function\") {\n const binaryString = globalThis.atob(data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n const decoder = new TextDecoder(\"utf-8\");\n return decoder.decode(bytes);\n }\n return Buffer.from(data, \"base64\").toString(\"utf-8\");\n}\n\n/**\n * Deep equality comparison for payment requirements\n * Uses a normalized JSON.stringify for consistent comparison\n *\n * @param obj1 - First object to compare\n * @param obj2 - Second object to compare\n * @returns True if objects are deeply equal\n */\nexport function deepEqual(obj1: unknown, obj2: unknown): boolean {\n // Normalize and stringify both objects for comparison\n // This handles nested objects, arrays, and different property orders\n const normalize = (obj: unknown): string => {\n // Handle primitives and null/undefined\n if (obj === null || obj === undefined) return JSON.stringify(obj);\n if (typeof obj !== \"object\") return JSON.stringify(obj);\n\n // Handle arrays\n if (Array.isArray(obj)) {\n return JSON.stringify(\n obj.map(item =>\n typeof item === \"object\" && item !== null ? JSON.parse(normalize(item)) : item,\n ),\n );\n }\n\n // Handle objects - sort keys and recursively normalize values\n const sorted: Record<string, unknown> = {};\n Object.keys(obj as Record<string, unknown>)\n .sort()\n .forEach(key => {\n const value = (obj as Record<string, unknown>)[key];\n sorted[key] =\n typeof value === \"object\" && value !== null ? JSON.parse(normalize(value)) : value;\n });\n return JSON.stringify(sorted);\n };\n\n try {\n return normalize(obj1) === normalize(obj2);\n } catch {\n // Fallback to simple comparison if normalization fails\n return JSON.stringify(obj1) === JSON.stringify(obj2);\n }\n}\n"],"mappings":"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","names":[]}