{"version":3,"file":"fiat-payment.mjs","names":[],"sources":["../../../src/tools/fiat-payment.ts"],"sourcesContent":["/**\n * Fiat Payment Tool — off-ramps, on-ramps, and fiat quote aggregation.\n *\n * Provides a unified interface for moving money between crypto and fiat\n * via Bridge.xyz and MoonPay providers. Aggregates quotes from all\n * configured providers and picks the best rate.\n *\n * Actions:\n *   quote      — Get aggregated quotes for off-ramp or on-ramp\n *   off_ramp   — Execute a crypto → fiat transfer\n *   on_ramp    — Execute a fiat → crypto purchase\n *   status     — Check transfer status\n *   accounts   — List linked bank accounts\n *   history    — View recent fiat transfer history\n *\n * Requires env vars: BRIDGE_API_KEY or MOONPAY_API_KEY (at least one).\n *\n * @see fiat-service.ts for provider implementations\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport { getWalletState } from '../services/walletconnect-service.js';\nimport { getFiatService, type FiatDirection, type FiatCurrency } from '../services/fiat-service.js';\nimport { checkToolConfig } from '../services/tool-config-service.js';\n\nconst ACTIONS = ['quote', 'off_ramp', 'on_ramp', 'status', 'accounts', 'history'] as const;\n\nconst FIAT_CURRENCIES = ['USD', 'EUR', 'GBP', 'CAD', 'AUD', 'CHF', 'JPY'] as const;\n\nconst FiatPaymentSchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'quote: get aggregated quotes from all providers. ' +\n      'off_ramp: sell crypto for fiat (requires wallet). ' +\n      'on_ramp: buy crypto with fiat. ' +\n      'status: check transfer status. ' +\n      'accounts: list linked bank accounts. ' +\n      'history: view recent fiat transfers.',\n  }),\n  direction: Type.Optional(stringEnum(['off_ramp', 'on_ramp'] as const, {\n    description: 'Direction for quote action. off_ramp = crypto→fiat, on_ramp = fiat→crypto.',\n  })),\n  crypto_token: Type.Optional(Type.String({\n    description: 'Crypto token symbol (e.g. \"USDC\", \"ETH\"). Default: USDC.',\n  })),\n  chain_id: Type.Optional(Type.Number({\n    description: 'Chain ID for the crypto side. Default: 8453 (Base).',\n  })),\n  amount: Type.Optional(Type.Number({\n    description: 'Amount to convert. Interpretation depends on amount_type.',\n  })),\n  amount_type: Type.Optional(stringEnum(['crypto', 'fiat'] as const, {\n    description: 'Whether amount is in crypto or fiat. Default: crypto.',\n  })),\n  fiat_currency: Type.Optional(stringEnum(FIAT_CURRENCIES, {\n    description: 'Fiat currency code. Default: USD.',\n  })),\n  transfer_id: Type.Optional(Type.String({\n    description: 'Transfer ID for status check.',\n  })),\n  bank_account_id: Type.Optional(Type.String({\n    description: 'Bank account ID for off-ramp execution.',\n  })),\n  provider: Type.Optional(Type.String({\n    description: 'Preferred provider (e.g. \"bridge\", \"moonpay\"). Optional — best rate chosen by default.',\n  })),\n});\n\nexport function createFiatPaymentTool() {\n  return {\n    name: 'fiat_payment',\n    label: 'Fiat Payment',\n    ownerOnly: true,\n    description:\n      'Fiat on-ramps and off-ramps — buy crypto with fiat or sell crypto for fiat. ' +\n      'Aggregates quotes from Bridge.xyz and MoonPay. Use \"quote\" to compare rates, ' +\n      '\"off_ramp\" to sell, \"on_ramp\" to buy.',\n    parameters: FiatPaymentSchema,\n    execute: async (_toolCallId: string, args: unknown) => {\n      // Check configuration\n      const notReady = checkToolConfig('fiat_payment');\n      if (notReady) return notReady;\n\n      const params = args as Record<string, unknown>;\n      const action = readStringParam(params, 'action', { required: true })!;\n\n      switch (action) {\n        case 'quote':\n          return handleQuote(params);\n        case 'off_ramp':\n          return handleOffRamp(params);\n        case 'on_ramp':\n          return handleOnRamp(params);\n        case 'status':\n          return handleStatus(params);\n        case 'accounts':\n          return handleAccounts();\n        case 'history':\n          return handleHistory(params);\n        default:\n          return errorResult(`Unknown action: ${action}. Use: ${ACTIONS.join(', ')}`);\n      }\n    },\n  };\n}\n\n// ─── Action Handlers ──────────────────────────────────────────────────────\n\nasync function handleQuote(params: Record<string, unknown>) {\n  const directionInput = readStringParam(params, 'direction') ?? 'off_ramp';\n  const direction = directionInput as FiatDirection;\n  const cryptoToken = readStringParam(params, 'crypto_token') ?? readStringParam(params, 'cryptoToken') ?? 'USDC';\n  const chainId = readNumberParam(params, 'chain_id') ?? readNumberParam(params, 'chainId') ?? 8453;\n  const amount = readNumberParam(params, 'amount', { required: true })!;\n  const amountType = (readStringParam(params, 'amount_type') ?? readStringParam(params, 'amountType') ?? 'crypto') as 'crypto' | 'fiat';\n  const fiatCurrency = (readStringParam(params, 'fiat_currency') ?? readStringParam(params, 'fiatCurrency') ?? 'USD') as FiatCurrency;\n\n  const fiat = getFiatService();\n  if (!fiat.isAvailable()) {\n    return errorResult('No fiat providers configured. Set BRIDGE_API_KEY or MOONPAY_API_KEY.');\n  }\n\n  try {\n    const quotes = await fiat.getQuotes({\n      direction,\n      cryptoToken,\n      cryptoChainId: chainId,\n      amount,\n      amountType,\n      fiatCurrency,\n    });\n\n    if (quotes.length === 0) {\n      return errorResult('No quotes available. Providers may be temporarily unavailable.');\n    }\n\n    return jsonResult({\n      direction,\n      cryptoToken,\n      chainId,\n      amount,\n      amountType,\n      fiatCurrency,\n      quoteCount: quotes.length,\n      quotes: quotes.map((q, idx) => ({\n        rank: idx + 1,\n        provider: q.provider,\n        cryptoAmount: q.cryptoAmount,\n        fiatAmount: q.fiatAmount,\n        fee: q.fee,\n        netFiat: direction === 'off_ramp' ? q.fiatAmount - q.fee : q.fiatAmount,\n        exchangeRate: q.exchangeRate,\n        estimatedSettlement: q.estimatedSettlement,\n        quoteId: q.quoteId,\n        expiresInMs: q.expiresIn,\n      })),\n      bestProvider: quotes[0]!.provider,\n      configuredProviders: fiat.getConfiguredProviders(),\n    });\n  } catch (err) {\n    return errorResult(`Quote failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleOffRamp(params: Record<string, unknown>) {\n  const state = getWalletState();\n  if (!state.connected) {\n    return errorResult('No wallet connected. Use clawnchconnect tool to connect first.');\n  }\n\n  const cryptoToken = readStringParam(params, 'crypto_token') ?? readStringParam(params, 'cryptoToken') ?? 'USDC';\n  const chainId = readNumberParam(params, 'chain_id') ?? readNumberParam(params, 'chainId') ?? 8453;\n  const amount = readNumberParam(params, 'amount', { required: true })!;\n  const amountType = (readStringParam(params, 'amount_type') ?? readStringParam(params, 'amountType') ?? 'crypto') as 'crypto' | 'fiat';\n  const fiatCurrency = (readStringParam(params, 'fiat_currency') ?? readStringParam(params, 'fiatCurrency') ?? 'USD') as FiatCurrency;\n  const preferredProvider = readStringParam(params, 'provider');\n  const bankAccountId = readStringParam(params, 'bank_account_id') ?? readStringParam(params, 'bankAccountId');\n\n  const fiat = getFiatService();\n\n  try {\n    // Get quotes for off-ramp\n    const quotes = await fiat.getQuotes({\n      direction: 'off_ramp',\n      cryptoToken,\n      cryptoChainId: chainId,\n      amount,\n      amountType,\n      fiatCurrency,\n    });\n\n    if (quotes.length === 0) {\n      return errorResult('No off-ramp quotes available.');\n    }\n\n    // Use preferred provider or best quote\n    const quote = preferredProvider\n      ? quotes.find(q => q.provider === preferredProvider) ?? quotes[0]!\n      : quotes[0]!;\n\n    // Execute the transfer\n    const transfer = await fiat.executeTransfer(quote, {\n      userId: state.address!,\n      walletAddress: state.address!,\n      bankAccountId,\n    });\n\n    return jsonResult({\n      status: 'initiated',\n      transferId: transfer.id,\n      provider: transfer.provider,\n      direction: 'off_ramp',\n      cryptoAmount: transfer.cryptoAmount,\n      cryptoToken: transfer.cryptoToken,\n      fiatAmount: transfer.fiatAmount,\n      fiatCurrency: transfer.fiatCurrency,\n      fee: transfer.fee,\n      externalId: transfer.externalId,\n      note: 'Transfer initiated. Use action \"status\" with this transfer_id to track progress.',\n    });\n  } catch (err) {\n    return errorResult(`Off-ramp failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleOnRamp(params: Record<string, unknown>) {\n  const state = getWalletState();\n  if (!state.connected) {\n    return errorResult('No wallet connected. Use clawnchconnect tool to connect first.');\n  }\n\n  const cryptoToken = readStringParam(params, 'crypto_token') ?? readStringParam(params, 'cryptoToken') ?? 'USDC';\n  const chainId = readNumberParam(params, 'chain_id') ?? readNumberParam(params, 'chainId') ?? 8453;\n  const amount = readNumberParam(params, 'amount', { required: true })!;\n  const amountType = (readStringParam(params, 'amount_type') ?? readStringParam(params, 'amountType') ?? 'fiat') as 'crypto' | 'fiat';\n  const fiatCurrency = (readStringParam(params, 'fiat_currency') ?? readStringParam(params, 'fiatCurrency') ?? 'USD') as FiatCurrency;\n  const preferredProvider = readStringParam(params, 'provider');\n\n  const fiat = getFiatService();\n\n  try {\n    const quotes = await fiat.getQuotes({\n      direction: 'on_ramp',\n      cryptoToken,\n      cryptoChainId: chainId,\n      amount,\n      amountType,\n      fiatCurrency,\n    });\n\n    if (quotes.length === 0) {\n      return errorResult('No on-ramp quotes available.');\n    }\n\n    const quote = preferredProvider\n      ? quotes.find(q => q.provider === preferredProvider) ?? quotes[0]!\n      : quotes[0]!;\n\n    const transfer = await fiat.executeTransfer(quote, {\n      userId: state.address!,\n      walletAddress: state.address!,\n    });\n\n    return jsonResult({\n      status: 'initiated',\n      transferId: transfer.id,\n      provider: transfer.provider,\n      direction: 'on_ramp',\n      cryptoAmount: transfer.cryptoAmount,\n      cryptoToken: transfer.cryptoToken,\n      fiatAmount: transfer.fiatAmount,\n      fiatCurrency: transfer.fiatCurrency,\n      fee: transfer.fee,\n      externalId: transfer.externalId,\n      note: 'On-ramp initiated. Use action \"status\" with this transfer_id to track progress.',\n    });\n  } catch (err) {\n    return errorResult(`On-ramp failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleStatus(params: Record<string, unknown>) {\n  const transferId = readStringParam(params, 'transfer_id') ?? readStringParam(params, 'transferId');\n  if (!transferId) return errorResult('transfer_id is required for status check.');\n\n  const fiat = getFiatService();\n\n  try {\n    const transfer = await fiat.refreshTransferStatus(transferId);\n    if (!transfer) {\n      return errorResult(`Transfer \"${transferId}\" not found.`);\n    }\n\n    return jsonResult({\n      transferId: transfer.id,\n      status: transfer.status,\n      direction: transfer.direction,\n      provider: transfer.provider,\n      cryptoAmount: transfer.cryptoAmount,\n      cryptoToken: transfer.cryptoToken,\n      fiatAmount: transfer.fiatAmount,\n      fiatCurrency: transfer.fiatCurrency,\n      fee: transfer.fee,\n      externalId: transfer.externalId,\n      txHash: transfer.txHash ?? null,\n      bankAccount: transfer.bankAccount ?? null,\n      createdAt: new Date(transfer.createdAt).toISOString(),\n      updatedAt: new Date(transfer.updatedAt).toISOString(),\n      error: transfer.error ?? null,\n    });\n  } catch (err) {\n    return errorResult(`Status check failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleAccounts() {\n  const fiat = getFiatService();\n  if (!fiat.isAvailable()) {\n    return errorResult('No fiat providers configured. Set BRIDGE_API_KEY or MOONPAY_API_KEY.');\n  }\n\n  try {\n    const accounts = await fiat.listBankAccounts();\n\n    return jsonResult({\n      accountCount: accounts.length,\n      accounts: accounts.map(a => ({\n        id: a.id,\n        label: a.label,\n        maskedNumber: a.maskedNumber,\n        bankName: a.bankName,\n        currency: a.currency,\n        provider: a.provider,\n      })),\n      configuredProviders: fiat.getConfiguredProviders(),\n      note: accounts.length === 0\n        ? 'No bank accounts linked. Use Bridge.xyz dashboard to link a bank account.'\n        : undefined,\n    });\n  } catch (err) {\n    return errorResult(`Account lookup failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleHistory(params: Record<string, unknown>) {\n  const fiat = getFiatService();\n  const state = getWalletState();\n  const userId = state.address ?? undefined;\n\n  const transfers = fiat.listTransfers(userId);\n\n  // Sort by most recent first\n  transfers.sort((a, b) => b.createdAt - a.createdAt);\n\n  // Limit to last 20\n  const recent = transfers.slice(0, 20);\n\n  return jsonResult({\n    totalTransfers: transfers.length,\n    showing: recent.length,\n    transfers: recent.map(t => ({\n      id: t.id,\n      direction: t.direction,\n      status: t.status,\n      provider: t.provider,\n      cryptoAmount: t.cryptoAmount,\n      cryptoToken: t.cryptoToken,\n      fiatAmount: t.fiatAmount,\n      fiatCurrency: t.fiatCurrency,\n      fee: t.fee,\n      createdAt: new Date(t.createdAt).toISOString(),\n      error: t.error ?? null,\n    })),\n  });\n}\n"],"mappings":"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"}