{"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":[]}