{"version":3,"sources":["../../../../src/exact/server/scheme.ts","../../../../src/exact/server/register.ts"],"sourcesContent":["import {\n  AssetAmount,\n  Network,\n  PaymentRequirements,\n  Price,\n  SchemeNetworkServer,\n  MoneyParser,\n} from \"@aeon-ai-pay/core/types\";\n\n/**\n * EVM server implementation for the Exact payment scheme.\n */\nexport class ExactEvmScheme implements SchemeNetworkServer {\n  readonly scheme = \"exact\";\n  private moneyParsers: MoneyParser[] = [];\n\n  /**\n   * Register a custom money parser in the parser chain.\n   * Multiple parsers can be registered - they will be tried in registration order.\n   * Each parser receives a decimal amount (e.g., 1.50 for $1.50).\n   * If a parser returns null, the next parser in the chain will be tried.\n   * The default parser is always the final fallback.\n   *\n   * @param parser - Custom function to convert amount to AssetAmount (or null to skip)\n   * @returns The server instance for chaining\n   *\n   * @example\n   * evmServer.registerMoneyParser(async (amount, network) => {\n   *   // Custom conversion logic\n   *   if (amount > 100) {\n   *     // Use different token for large amounts\n   *     return { amount: (amount * 1e18).toString(), asset: \"0xCustomToken\" };\n   *   }\n   *   return null; // Use next parser\n   * });\n   */\n  registerMoneyParser(parser: MoneyParser): ExactEvmScheme {\n    this.moneyParsers.push(parser);\n    return this;\n  }\n\n  /**\n   * Parses a price into an asset amount.\n   * If price is already an AssetAmount, returns it directly.\n   * If price is Money (string | number), parses to decimal and tries custom parsers.\n   * Falls back to default conversion if all custom parsers return null.\n   *\n   * @param price - The price to parse\n   * @param network - The network to use\n   * @returns Promise that resolves to the parsed asset amount\n   */\n  async parsePrice(price: Price, network: Network): Promise<AssetAmount> {\n    // If already an AssetAmount, return it directly\n    if (typeof price === \"object\" && price !== null && \"amount\" in price) {\n      if (!price.asset) {\n        throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);\n      }\n      return {\n        amount: price.amount,\n        asset: price.asset,\n        extra: price.extra || {},\n      };\n    }\n\n    // Parse Money to decimal number\n    const amount = this.parseMoneyToDecimal(price);\n\n    // Try each custom money parser in order\n    for (const parser of this.moneyParsers) {\n      const result = await parser(amount, network);\n      if (result !== null) {\n        return result;\n      }\n    }\n\n    // All custom parsers returned null, use default conversion\n    return this.defaultMoneyConversion(amount, network);\n  }\n\n  /**\n   * Build payment requirements for this scheme/network combination\n   *\n   * @param paymentRequirements - The base payment requirements\n   * @param supportedKind - The supported kind from facilitator (unused)\n   * @param supportedKind.x402Version - The x402 version\n   * @param supportedKind.scheme - The logical payment scheme\n   * @param supportedKind.network - The network identifier in CAIP-2 format\n   * @param supportedKind.extra - Optional extra metadata regarding scheme/network implementation details\n   * @param extensionKeys - Extension keys supported by the facilitator (unused)\n   * @returns Payment requirements ready to be sent to clients\n   */\n  enhancePaymentRequirements(\n    paymentRequirements: PaymentRequirements,\n    supportedKind: {\n      x402Version: number;\n      scheme: string;\n      network: Network;\n      extra?: Record<string, unknown>;\n    },\n    extensionKeys: string[],\n  ): Promise<PaymentRequirements> {\n    // Mark unused parameters to satisfy linter\n    void supportedKind;\n    void extensionKeys;\n    return Promise.resolve(paymentRequirements);\n  }\n\n  /**\n   * Parse Money (string | number) to a decimal number.\n   * Handles formats like \"$1.50\", \"1.50\", 1.50, etc.\n   *\n   * @param money - The money value to parse\n   * @returns Decimal number\n   */\n  private parseMoneyToDecimal(money: string | number): number {\n    if (typeof money === \"number\") {\n      return money;\n    }\n\n    // Remove $ sign and whitespace, then parse\n    const cleanMoney = money.replace(/^\\$/, \"\").trim();\n    const amount = parseFloat(cleanMoney);\n\n    if (isNaN(amount)) {\n      throw new Error(`Invalid money format: ${money}`);\n    }\n\n    return amount;\n  }\n\n  /**\n   * Default money conversion implementation.\n   * Converts decimal amount to USDC on the specified network.\n   *\n   * @param amount - The decimal amount (e.g., 1.50)\n   * @param network - The network to use\n   * @returns The parsed asset amount in USDC\n   */\n  private defaultMoneyConversion(amount: number, network: Network): AssetAmount {\n    // Convert decimal amount to token amount (USDC has 6 decimals)\n    const tokenAmount = this.convertToTokenAmount(amount.toString(), network);\n    const assetInfo = this.getDefaultAsset(network);\n\n    return {\n      amount: tokenAmount,\n      asset: assetInfo.address,\n      extra: {\n        name: assetInfo.name,\n        version: assetInfo.version,\n      },\n    };\n  }\n\n  /**\n   * Convert decimal amount to token units (e.g., 0.10 -> 100000 for 6-decimal USDC)\n   *\n   * @param decimalAmount - The decimal amount to convert\n   * @param network - The network to use\n   * @returns The token amount as a string\n   */\n  private convertToTokenAmount(decimalAmount: string, network: Network): string {\n    const decimals = this.getAssetDecimals(network);\n    const amount = parseFloat(decimalAmount);\n    if (isNaN(amount)) {\n      throw new Error(`Invalid amount: ${decimalAmount}`);\n    }\n    // Convert to smallest unit (e.g., for USDC with 6 decimals: 0.10 * 10^6 = 100000)\n    const tokenAmount = Math.floor(amount * Math.pow(10, decimals));\n    return tokenAmount.toString();\n  }\n\n  /**\n   * Get the default asset info for a network (typically USDC)\n   *\n   * @param network - The network to get asset info for\n   * @returns The asset information including address, name, and version\n   */\n  private getDefaultAsset(network: Network): { address: string; name: string; version: string } {\n    // Map of network to USDC info including EIP-712 domain parameters\n    const usdcInfo: Record<string, { address: string; name: string; version: string }> = {\n      \"eip155:8453\": {\n        address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n        name: \"USD Coin\",\n        version: \"2\",\n      }, // Base mainnet USDC\n      \"eip155:84532\": {\n        address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n        name: \"USDC\",\n        version: \"2\",\n      }, // Base Sepolia USDC\n      \"eip155:1\": {\n        address: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n        name: \"USD Coin\",\n        version: \"2\",\n      }, // Ethereum mainnet USDC\n      \"eip155:11155111\": {\n        address: \"0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238\",\n        name: \"USDC\",\n        version: \"2\",\n      },\n      // \"eip155:56\": {\n      //   address: \"0xA0f09D908279ddd28B5370c2b0612d1A10ee87cA\",\n      //   name: \"TESTU\",\n      //   version: \"1\",\n      // },\n      \"eip155:56\": {\n        address: \"0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d\",\n        name: \"USDT\",\n        version: \"1\",\n      },\n      \"eip155:196\": {\n        address: \"0x74b7F16337b8972027F6196A17a631aC6dE26d22\",\n        name: \"USD Coin\",\n        version: \"2\",\n      },\n      \"eip155:2366\": {\n        address: \"0x7aB6f3ed87C42eF0aDb67Ed95090f8bF5240149e\",\n        name: \"Bridged USDC (Kite AI)\",\n        version: \"2\",\n      },\n      \"eip155:97\": {\n        address: \"0xA0f09D908279ddd28B5370c2b0612d1A10ee87cA\",\n        name: \"TESTU\",\n        version: \"1\",\n      },\n    };\n\n    const assetInfo = usdcInfo[network];\n    if (!assetInfo) {\n      throw new Error(`No default asset configured for network ${network}`);\n    }\n\n    return assetInfo;\n  }\n\n  /**\n   * Get asset info for a given symbol on a network\n   *\n   * @param symbol - The asset symbol\n   * @param network - The network to use\n   * @returns The asset information including address, name, and version\n   */\n  private getAssetInfo(\n    symbol: string,\n    network: Network,\n  ): { address: string; name: string; version: string } {\n    const upperSymbol = symbol.toUpperCase();\n\n    // For now, only support USDC\n    if (upperSymbol === \"USDC\" || upperSymbol === \"USD\") {\n      return this.getDefaultAsset(network);\n    }\n\n    // Could extend to support other tokens\n    throw new Error(`Unsupported asset: ${symbol} on network ${network}`);\n  }\n\n  /**\n   * Get the number of decimals for the asset\n   *\n   * @param _ - The network to use (unused)\n   * @returns The number of decimals for the asset\n   */\n  private getAssetDecimals(_: Network): number {\n    // USDC has 6 decimals on all EVM chains\n    return 6;\n  }\n}\n","import { x402ResourceServer } from \"@aeon-ai-pay/core/server\";\nimport { Network } from \"@aeon-ai-pay/core/types\";\nimport { ExactEvmScheme } from \"./scheme\";\n\n/**\n * Configuration options for registering EVM schemes to an x402ResourceServer\n */\nexport interface EvmResourceServerConfig {\n  /**\n   * Optional specific networks to register\n   * If not provided, registers wildcard support (eip155:*)\n   */\n  networks?: Network[];\n}\n\n/**\n * Registers EVM exact payment schemes to an x402ResourceServer instance.\n *\n * This function registers:\n * - V2: eip155:* wildcard scheme with ExactEvmScheme (or specific networks if provided)\n *\n * @param server - The x402ResourceServer instance to register schemes to\n * @param config - Configuration for EVM resource server registration\n * @returns The server instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactEvmScheme } from \"@aeon-ai-pay/evm/exact/server/register\";\n * import { x402ResourceServer } from \"@aeon-ai-pay/core/server\";\n *\n * const server = new x402ResourceServer(facilitatorClient);\n * registerExactEvmScheme(server, {});\n * ```\n */\nexport function registerExactEvmScheme(\n  server: x402ResourceServer,\n  config: EvmResourceServerConfig = {},\n): x402ResourceServer {\n  // Register V2 scheme\n  if (config.networks && config.networks.length > 0) {\n    // Register specific networks\n    config.networks.forEach(network => {\n      server.register(network, new ExactEvmScheme());\n    });\n  } else {\n    // Register wildcard for all EVM chains\n    server.register(\"eip155:*\", new ExactEvmScheme());\n  }\n\n  return server;\n}\n"],"mappings":"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","names":[]}