{"version":3,"file":"bridge.mjs","names":[],"sources":["../../../src/tools/bridge.ts"],"sourcesContent":["/**\n * Bridge Tool — Cross-chain token bridging via LI.FI aggregator.\n *\n * LI.FI aggregates all major bridges (LayerZero, Across, Stargate, Hop,\n * Synapse, Connext, etc.) behind a single REST API. This tool provides:\n *\n * Actions:\n *   quote      — Get bridge quotes from multiple protocols for a transfer\n *   routes     — Get full route breakdown with steps, fees, and times\n *   execute    — Execute a bridge transaction (requires wallet)\n *   status     — Check bridge transaction status\n *   chains     — List supported chains\n *   tokens     — List bridgeable tokens on a chain\n *\n * Requires no API key for basic usage. Set LIFI_API_KEY env var for higher rate limits.\n *\n * @see https://docs.li.fi/li.fi-api/li.fi-api\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport {\n  getWalletState,\n  requireWalletClient,\n  requirePublicClient,\n  getMevWalletClient,\n} from '../services/walletconnect-service.js';\nimport { guardedFetch } from '../services/endpoint-allowlist.js';\nimport { getCredentialVault } from '../services/credential-vault.js';\n\nconst ACTIONS = ['quote', 'routes', 'execute', 'status', 'chains', 'tokens'] as const;\n\nconst LIFI_BASE_URL = 'https://li.quest/v1';\n\n// ─── Well-known chain IDs ────────────────────────────────────────────────\n\nconst CHAIN_NAMES: Record<number, string> = {\n  1: 'Ethereum',\n  8453: 'Base',\n  42161: 'Arbitrum',\n  10: 'Optimism',\n  137: 'Polygon',\n  43114: 'Avalanche',\n  56: 'BNB Chain',\n  250: 'Fantom',\n  324: 'zkSync Era',\n  59144: 'Linea',\n  534352: 'Scroll',\n  7777777: 'Zora',\n};\n\nconst CHAIN_NAME_TO_ID: Record<string, number> = {\n  ethereum: 1, eth: 1, mainnet: 1,\n  base: 8453,\n  arbitrum: 42161, arb: 42161,\n  optimism: 10, op: 10,\n  polygon: 137, matic: 137,\n  avalanche: 43114, avax: 43114,\n  bnb: 56, bsc: 56,\n  fantom: 250, ftm: 250,\n  zksync: 324,\n  linea: 59144,\n  scroll: 534352,\n  zora: 7777777,\n};\n\nfunction resolveChainId(input: string | number): number {\n  if (typeof input === 'number') return input;\n  const num = parseInt(input, 10);\n  if (!isNaN(num)) return num;\n  return CHAIN_NAME_TO_ID[input.toLowerCase()] ?? 0;\n}\n\n// ─── LI.FI API Client ───────────────────────────────────────────────────\n\nasync function lifiFetch(path: string, params?: Record<string, string>): Promise<any> {\n  const url = new URL(`${LIFI_BASE_URL}${path}`);\n  if (params) {\n    for (const [key, value] of Object.entries(params)) {\n      url.searchParams.set(key, value);\n    }\n  }\n\n  const headers: Record<string, string> = { Accept: 'application/json' };\n  const apiKey = getCredentialVault().getSecret('bridge.lifi.apiKey', 'bridge');\n  if (apiKey) headers['x-lifi-api-key'] = apiKey;\n\n  // H10: Add request timeout to prevent hanging\n  const response = await guardedFetch(url.toString(), { headers, signal: AbortSignal.timeout(30_000) });\n  if (!response.ok) {\n    const body = await response.text().catch(() => '');\n    throw new Error(`LI.FI API error: ${response.status} ${response.statusText}${body ? ` — ${body.slice(0, 200)}` : ''}`);\n  }\n\n  return response.json();\n}\n\nasync function lifiPost(path: string, body: unknown): Promise<any> {\n  const headers: Record<string, string> = {\n    Accept: 'application/json',\n    'Content-Type': 'application/json',\n  };\n  const apiKey = getCredentialVault().getSecret('bridge.lifi.apiKey', 'bridge');\n  if (apiKey) headers['x-lifi-api-key'] = apiKey;\n\n  // H10: Add request timeout to prevent hanging\n  const response = await guardedFetch(`${LIFI_BASE_URL}${path}`, {\n    method: 'POST',\n    headers,\n    body: JSON.stringify(body),\n    signal: AbortSignal.timeout(30_000),\n  });\n\n  if (!response.ok) {\n    const text = await response.text().catch(() => '');\n    throw new Error(`LI.FI API error: ${response.status} ${response.statusText}${text ? ` — ${text.slice(0, 200)}` : ''}`);\n  }\n\n  return response.json();\n}\n\n// ─── Schema ──────────────────────────────────────────────────────────────\n\nconst BridgeSchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'quote: get bridge quotes. routes: detailed route breakdown. ' +\n      'execute: execute a bridge transfer (requires wallet). ' +\n      'status: check bridge tx status. ' +\n      'chains: list supported chains. tokens: bridgeable tokens on a chain.',\n  }),\n  from_chain: Type.Optional(Type.String({\n    description: 'Source chain: name (e.g. \"base\", \"ethereum\") or chain ID. Default: base.',\n  })),\n  to_chain: Type.Optional(Type.String({\n    description: 'Destination chain: name (e.g. \"arbitrum\", \"optimism\") or chain ID.',\n  })),\n  from_token: Type.Optional(Type.String({\n    description: 'Source token address (0x...) or symbol. Use 0x0000000000000000000000000000000000000000 for native token.',\n  })),\n  to_token: Type.Optional(Type.String({\n    description: 'Destination token address (0x...) or symbol.',\n  })),\n  amount: Type.Optional(Type.String({\n    description: 'Amount in smallest unit (wei) for quote/routes. Human-readable for execute.',\n  })),\n  slippage: Type.Optional(Type.Number({\n    description: 'Slippage tolerance (e.g. 0.005 for 0.5%). Default: 0.005.',\n  })),\n  tx_hash: Type.Optional(Type.String({\n    description: 'Transaction hash for status check.',\n  })),\n  bridge: Type.Optional(Type.String({\n    description: 'Preferred bridge protocol (e.g. \"across\", \"stargate\", \"hop\"). Optional — LI.FI picks best by default.',\n  })),\n  chain_id: Type.Optional(Type.Number({\n    description: 'Chain ID for tokens action.',\n  })),\n});\n\nexport function createBridgeTool() {\n  return {\n    name: 'bridge',\n    label: 'Bridge',\n    ownerOnly: true,\n    description:\n      'Cross-chain token bridging via LI.FI aggregator. Compares quotes from Across, ' +\n      'Stargate, LayerZero, Hop, Synapse, and more. Use \"quote\" to compare, \"execute\" to bridge.',\n    parameters: BridgeSchema,\n    execute: async (_toolCallId: string, args: unknown) => {\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 'routes':\n          return handleRoutes(params);\n        case 'execute':\n          return handleExecute(params);\n        case 'status':\n          return handleStatus(params);\n        case 'chains':\n          return handleChains();\n        case 'tokens':\n          return handleTokens(params);\n        default:\n          return errorResult(`Unknown action: ${action}. Use: ${ACTIONS.join(', ')}`);\n      }\n    },\n  };\n}\n\n// ─── Native Token Addresses ──────────────────────────────────────────────\n\nconst NATIVE_TOKEN = '0x0000000000000000000000000000000000000000';\n\nconst WELL_KNOWN_TOKENS: Record<string, Record<number, string>> = {\n  ETH: { 1: NATIVE_TOKEN, 8453: NATIVE_TOKEN, 42161: NATIVE_TOKEN, 10: NATIVE_TOKEN },\n  USDC: {\n    1: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n    8453: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n    42161: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',\n    10: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',\n    137: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',\n  },\n  USDT: {\n    1: '0xdAC17F958D2ee523a2206206994597C13D831ec7',\n    42161: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',\n    10: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58',\n    137: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',\n  },\n};\n\nfunction resolveTokenAddress(input: string, chainId: number): string {\n  if (input.startsWith('0x') && input.length === 42) return input;\n  const symbol = input.toUpperCase();\n  const addr = WELL_KNOWN_TOKENS[symbol]?.[chainId];\n  if (addr) return addr;\n  // For unknown symbols, return as-is — LI.FI will resolve or error\n  return input;\n}\n\n// ─── Action Handlers ──────────────────────────────────────────────────────\n\nasync function handleQuote(params: Record<string, unknown>) {\n  const fromChainInput = readStringParam(params, 'from_chain') ?? readStringParam(params, 'fromChain') ?? 'base';\n  const toChainInput = readStringParam(params, 'to_chain') ?? readStringParam(params, 'toChain');\n  if (!toChainInput) return errorResult('to_chain is required for quote.');\n\n  const fromChainId = resolveChainId(fromChainInput);\n  const toChainId = resolveChainId(toChainInput);\n  if (!fromChainId) return errorResult(`Unknown source chain: ${fromChainInput}`);\n  if (!toChainId) return errorResult(`Unknown destination chain: ${toChainInput}`);\n\n  const fromTokenInput = readStringParam(params, 'from_token') ?? readStringParam(params, 'fromToken') ?? 'ETH';\n  const toTokenInput = readStringParam(params, 'to_token') ?? readStringParam(params, 'toToken') ?? 'ETH';\n  const amount = readStringParam(params, 'amount', { required: true })!;\n  const slippage = readNumberParam(params, 'slippage') ?? 0.005; // 0.5% default (was 3% — too high, sandwich-exploitable)\n\n  const fromToken = resolveTokenAddress(fromTokenInput, fromChainId);\n  const toToken = resolveTokenAddress(toTokenInput, toChainId);\n\n  // Use connected wallet address or zero address for quote\n  const state = getWalletState();\n  const fromAddress = state.address ?? '0x0000000000000000000000000000000000000001';\n\n  try {\n    const data = await lifiFetch('/quote', {\n      fromChain: String(fromChainId),\n      toChain: String(toChainId),\n      fromToken,\n      toToken,\n      fromAmount: amount,\n      fromAddress,\n      slippage: String(slippage),\n    });\n\n    const estimate = data.estimate ?? {};\n    const toolData = data.toolDetails ?? data.tool ?? {};\n\n    return jsonResult({\n      fromChain: { id: fromChainId, name: CHAIN_NAMES[fromChainId] ?? String(fromChainId) },\n      toChain: { id: toChainId, name: CHAIN_NAMES[toChainId] ?? String(toChainId) },\n      fromToken: { address: fromToken, symbol: data.action?.fromToken?.symbol ?? fromTokenInput },\n      toToken: { address: toToken, symbol: data.action?.toToken?.symbol ?? toTokenInput },\n      fromAmount: amount,\n      toAmount: estimate.toAmount ?? null,\n      toAmountMin: estimate.toAmountMin ?? null,\n      bridgeProtocol: toolData.name ?? data.tool ?? 'unknown',\n      estimatedGasCostUsd: estimate.gasCosts?.[0]?.amountUSD ?? null,\n      estimatedFeeCostUsd: estimate.feeCosts?.reduce?.((sum: number, f: any) => sum + parseFloat(f.amountUSD ?? '0'), 0) ?? null,\n      executionDurationSeconds: estimate.executionDuration ?? null,\n      slippage,\n      transactionRequest: data.transactionRequest ? {\n        to: data.transactionRequest.to,\n        value: data.transactionRequest.value,\n        gasLimit: data.transactionRequest.gasLimit,\n      } : null,\n    });\n  } catch (err) {\n    return errorResult(`Quote failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleRoutes(params: Record<string, unknown>) {\n  const fromChainInput = readStringParam(params, 'from_chain') ?? readStringParam(params, 'fromChain') ?? 'base';\n  const toChainInput = readStringParam(params, 'to_chain') ?? readStringParam(params, 'toChain');\n  if (!toChainInput) return errorResult('to_chain is required for routes.');\n\n  const fromChainId = resolveChainId(fromChainInput);\n  const toChainId = resolveChainId(toChainInput);\n  if (!fromChainId) return errorResult(`Unknown source chain: ${fromChainInput}`);\n  if (!toChainId) return errorResult(`Unknown destination chain: ${toChainInput}`);\n\n  const fromTokenInput = readStringParam(params, 'from_token') ?? readStringParam(params, 'fromToken') ?? 'ETH';\n  const toTokenInput = readStringParam(params, 'to_token') ?? readStringParam(params, 'toToken') ?? 'ETH';\n  const amount = readStringParam(params, 'amount', { required: true })!;\n  const slippage = readNumberParam(params, 'slippage') ?? 0.005; // 0.5% default (was 3% — too high, sandwich-exploitable)\n  const preferredBridge = readStringParam(params, 'bridge');\n\n  const fromToken = resolveTokenAddress(fromTokenInput, fromChainId);\n  const toToken = resolveTokenAddress(toTokenInput, toChainId);\n\n  const state = getWalletState();\n  const fromAddress = state.address ?? '0x0000000000000000000000000000000000000001';\n\n  try {\n    const body: any = {\n      fromChainId,\n      toChainId,\n      fromTokenAddress: fromToken,\n      toTokenAddress: toToken,\n      fromAmount: amount,\n      fromAddress,\n      options: {\n        slippage,\n        order: 'RECOMMENDED',\n      },\n    };\n\n    if (preferredBridge) {\n      body.options.bridges = { allow: [preferredBridge] };\n    }\n\n    const data = await lifiPost('/advanced/routes', body);\n    const routes = data.routes ?? [];\n\n    return jsonResult({\n      fromChain: { id: fromChainId, name: CHAIN_NAMES[fromChainId] ?? String(fromChainId) },\n      toChain: { id: toChainId, name: CHAIN_NAMES[toChainId] ?? String(toChainId) },\n      fromAmount: amount,\n      routeCount: routes.length,\n      routes: routes.slice(0, 5).map((route: any, idx: number) => ({\n        rank: idx + 1,\n        toAmount: route.toAmount,\n        toAmountUsd: route.toAmountUSD,\n        gasCostUsd: route.gasCostUSD,\n        executionDurationSeconds: route.steps?.reduce?.((sum: number, s: any) => sum + (s.estimate?.executionDuration ?? 0), 0) ?? null,\n        steps: route.steps?.map((step: any) => ({\n          type: step.type,\n          tool: step.toolDetails?.name ?? step.tool,\n          fromChain: step.action?.fromChainId,\n          toChain: step.action?.toChainId,\n          fromToken: step.action?.fromToken?.symbol,\n          toToken: step.action?.toToken?.symbol,\n          estimatedOutput: step.estimate?.toAmount,\n        })),\n        tags: route.tags ?? [],\n      })),\n      preferredBridge: preferredBridge ?? null,\n    });\n  } catch (err) {\n    return errorResult(`Routes failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleExecute(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 fromChainInput = readStringParam(params, 'from_chain') ?? readStringParam(params, 'fromChain') ?? 'base';\n  const toChainInput = readStringParam(params, 'to_chain') ?? readStringParam(params, 'toChain');\n  if (!toChainInput) return errorResult('to_chain is required for execute.');\n\n  const fromChainId = resolveChainId(fromChainInput);\n  const toChainId = resolveChainId(toChainInput);\n  if (!fromChainId) return errorResult(`Unknown source chain: ${fromChainInput}`);\n  if (!toChainId) return errorResult(`Unknown destination chain: ${toChainInput}`);\n\n  const fromTokenInput = readStringParam(params, 'from_token') ?? readStringParam(params, 'fromToken') ?? 'ETH';\n  const toTokenInput = readStringParam(params, 'to_token') ?? readStringParam(params, 'toToken') ?? 'ETH';\n  const amount = readStringParam(params, 'amount', { required: true })!;\n  const slippage = readNumberParam(params, 'slippage') ?? 0.005; // 0.5% default (was 3% — too high, sandwich-exploitable)\n\n  const fromToken = resolveTokenAddress(fromTokenInput, fromChainId);\n  const toToken = resolveTokenAddress(toTokenInput, toChainId);\n\n  try {\n    // Step 1: Get quote with transaction data\n    const quoteData = await lifiFetch('/quote', {\n      fromChain: String(fromChainId),\n      toChain: String(toChainId),\n      fromToken,\n      toToken,\n      fromAmount: amount,\n      fromAddress: state.address!,\n      slippage: String(slippage),\n    });\n\n    const txRequest = quoteData.transactionRequest;\n    if (!txRequest) {\n      return errorResult('No transaction data returned from LI.FI. The route may not be available.');\n    }\n\n    // Step 2: Send transaction via wallet (MEV-protected when available)\n    const wallet = await getMevWalletClient();\n    const publicClient = requirePublicClient();\n\n    const txHash = await wallet.sendTransaction({\n      to: txRequest.to as `0x${string}`,\n      data: txRequest.data as `0x${string}`,\n      value: txRequest.value ? BigInt(txRequest.value) : 0n,\n      gasLimit: txRequest.gasLimit ? BigInt(txRequest.gasLimit) : undefined,\n    } as any);\n\n    // Step 3: Wait for source chain confirmation (120s timeout — bridges can be slow)\n    const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash, timeout: 120_000 });\n\n    const estimate = quoteData.estimate ?? {};\n    const toolData = quoteData.toolDetails ?? {};\n\n    return jsonResult({\n      status: receipt.status === 'reverted' ? 'source_reverted' : 'source_confirmed',\n      txHash,\n      blockNumber: receipt.blockNumber.toString(),\n      gasUsed: receipt.gasUsed.toString(),\n      fromChain: { id: fromChainId, name: CHAIN_NAMES[fromChainId] ?? String(fromChainId) },\n      toChain: { id: toChainId, name: CHAIN_NAMES[toChainId] ?? String(toChainId) },\n      fromToken: fromTokenInput,\n      toToken: toTokenInput,\n      fromAmount: amount,\n      expectedToAmount: estimate.toAmount ?? null,\n      bridgeProtocol: toolData.name ?? quoteData.tool ?? 'unknown',\n      estimatedDurationSeconds: estimate.executionDuration ?? null,\n      note: 'Source chain transaction confirmed. Bridge transfer is in progress. Use action \"status\" with this tx_hash to check destination chain delivery.',\n    });\n  } catch (err) {\n    return errorResult(`Execute failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleStatus(params: Record<string, unknown>) {\n  const txHash = readStringParam(params, 'tx_hash') ?? readStringParam(params, 'txHash');\n  if (!txHash) return errorResult('tx_hash is required for status.');\n\n  const fromChainInput = readStringParam(params, 'from_chain') ?? readStringParam(params, 'fromChain') ?? 'base';\n  const toChainInput = readStringParam(params, 'to_chain') ?? readStringParam(params, 'toChain') ?? 'ethereum';\n  const fromChainId = resolveChainId(fromChainInput);\n  const toChainId = resolveChainId(toChainInput);\n\n  try {\n    const data = await lifiFetch('/status', {\n      txHash,\n      fromChain: String(fromChainId),\n      toChain: String(toChainId),\n    });\n\n    return jsonResult({\n      txHash,\n      status: data.status ?? 'UNKNOWN',\n      substatus: data.substatus ?? null,\n      fromChain: { id: fromChainId, name: CHAIN_NAMES[fromChainId] ?? String(fromChainId) },\n      toChain: { id: toChainId, name: CHAIN_NAMES[toChainId] ?? String(toChainId) },\n      sending: data.sending ? {\n        txHash: data.sending.txHash,\n        amount: data.sending.amount,\n        token: data.sending.token?.symbol,\n      } : null,\n      receiving: data.receiving ? {\n        txHash: data.receiving.txHash,\n        amount: data.receiving.amount,\n        token: data.receiving.token?.symbol,\n      } : null,\n      bridgeProtocol: data.tool ?? null,\n      bridgeExplorerUrl: data.bridgeExplorerUrl ?? null,\n    });\n  } catch (err) {\n    return errorResult(`Status check failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleChains() {\n  try {\n    const data = await lifiFetch('/chains');\n    const chains = data.chains ?? [];\n\n    return jsonResult({\n      totalChains: chains.length,\n      chains: chains.map((c: any) => ({\n        id: c.id,\n        name: c.name,\n        nativeToken: c.nativeToken?.symbol ?? null,\n        type: c.chainType ?? 'EVM',\n      })),\n    });\n  } catch (err) {\n    return errorResult(`Chains lookup failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n\nasync function handleTokens(params: Record<string, unknown>) {\n  const chainId = readNumberParam(params, 'chain_id') ?? readNumberParam(params, 'chainId') ?? 8453;\n\n  try {\n    const data = await lifiFetch('/tokens', {\n      chains: String(chainId),\n    });\n\n    const tokens = data.tokens?.[String(chainId)] ?? [];\n\n    return jsonResult({\n      chainId,\n      chainName: CHAIN_NAMES[chainId] ?? String(chainId),\n      tokenCount: tokens.length,\n      tokens: tokens.slice(0, 50).map((t: any) => ({\n        address: t.address,\n        symbol: t.symbol,\n        name: t.name,\n        decimals: t.decimals,\n        logoURI: t.logoURI ?? null,\n      })),\n      note: tokens.length > 50 ? `Showing first 50 of ${tokens.length} tokens.` : undefined,\n    });\n  } catch (err) {\n    return errorResult(`Tokens lookup failed: ${err instanceof Error ? err.message : String(err)}`);\n  }\n}\n"],"mappings":"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"}