@t402/smart-router 1.0.0-beta.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/routing/engine.ts","../src/routing/algorithms.ts"],"sourcesContent":["import {\n RouteRequest,\n Route,\n RouteStep,\n RouteValidation,\n RoutingGraph,\n GraphEdge,\n OptimizationStrategy,\n ChainId,\n AssetId,\n} from './types.js';\n\n/**\n * Route scoring weights for different optimization strategies\n */\nconst OPTIMIZATION_WEIGHTS: Record<OptimizationStrategy, {\n cost: number;\n speed: number;\n confidence: number;\n slippage: number;\n}> = {\n cost: { cost: 0.6, speed: 0.1, confidence: 0.2, slippage: 0.1 },\n speed: { cost: 0.1, speed: 0.6, confidence: 0.2, slippage: 0.1 },\n privacy: { cost: 0.2, speed: 0.1, confidence: 0.3, slippage: 0.4 },\n balanced: { cost: 0.3, speed: 0.3, confidence: 0.2, slippage: 0.2 },\n slippage: { cost: 0.1, speed: 0.1, confidence: 0.2, slippage: 0.6 },\n};\n\n/**\n * Router configuration\n */\nexport interface RouterConfig {\n maxRoutes?: number;\n cacheTtl?: number; // ms\n minConfidence?: number;\n defaultSlippage?: string;\n}\n\n/**\n * Smart routing engine\n */\nexport class RoutingEngine {\n private graph: RoutingGraph;\n private config: Required<RouterConfig>;\n private routeCache: Map<string, { routes: Route[]; expiresAt: number }> = new Map();\n\n constructor(config: RouterConfig = {}) {\n this.config = {\n maxRoutes: config.maxRoutes ?? 5,\n cacheTtl: config.cacheTtl ?? 30000,\n minConfidence: config.minConfidence ?? 50,\n defaultSlippage: config.defaultSlippage ?? '0.5',\n };\n\n this.graph = {\n nodes: new Map(),\n edges: [],\n lastUpdated: Date.now(),\n };\n }\n\n /**\n * Find optimal routes for a payment\n */\n async findRoutes(request: RouteRequest): Promise<Route[]> {\n // Check cache\n const cacheKey = this.getCacheKey(request);\n const cached = this.routeCache.get(cacheKey);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.routes;\n }\n\n // Validate request\n const validation = this.validateRequest(request);\n if (!validation.valid) {\n throw new RoutingError(\n `Invalid route request: ${validation.errors[0]?.message}`,\n 'INVALID_REQUEST',\n );\n }\n\n // Find all possible paths\n const paths = this.findAllPaths(\n request.sourceChain,\n request.sourceAsset,\n request.destinationChain,\n request.destinationAsset ?? request.sourceAsset,\n request.maxHops,\n );\n\n if (paths.length === 0) {\n throw new RoutingError(\n 'No route found between source and destination',\n 'NO_ROUTE',\n );\n }\n\n // Convert paths to routes with cost estimation\n const routes: Route[] = [];\n for (const path of paths) {\n try {\n const route = await this.buildRoute(request, path);\n if (route.confidence >= this.config.minConfidence) {\n routes.push(route);\n }\n } catch {\n // Skip invalid routes\n continue;\n }\n }\n\n if (routes.length === 0) {\n throw new RoutingError(\n 'No valid routes found',\n 'NO_VALID_ROUTE',\n );\n }\n\n // Score and sort routes\n const scoredRoutes = routes\n .map(route => ({\n route,\n score: this.scoreRoute(route, request.optimization),\n }))\n .sort((a, b) => b.score - a.score)\n .slice(0, this.config.maxRoutes)\n .map(({ route }) => route);\n\n // Cache results\n this.routeCache.set(cacheKey, {\n routes: scoredRoutes,\n expiresAt: Date.now() + this.config.cacheTtl,\n });\n\n return scoredRoutes;\n }\n\n /**\n * Get the best route for a payment\n */\n async getBestRoute(request: RouteRequest): Promise<Route | null> {\n const routes = await this.findRoutes(request);\n return routes[0] ?? null;\n }\n\n /**\n * Validate a route is still executable\n */\n async validateRoute(route: Route): Promise<RouteValidation> {\n const errors: RouteValidation['errors'] = [];\n const warnings: RouteValidation['warnings'] = [];\n\n // Check expiration\n if (route.expiresAt < Date.now()) {\n errors.push({\n code: 'EXPIRED',\n message: 'Route has expired',\n });\n }\n\n // Validate each step\n for (let i = 0; i < route.steps.length; i++) {\n const step = route.steps[i];\n\n // Check if protocol is still available\n const edge = this.findEdge(\n step.chain,\n step.inputAsset,\n step.chain,\n step.outputAsset,\n step.protocol,\n );\n\n if (!edge) {\n errors.push({\n step: i,\n code: 'PROTOCOL_UNAVAILABLE',\n message: `Protocol ${step.protocol} not available for step ${i}`,\n });\n continue;\n }\n\n // Check liquidity\n if (BigInt(step.inputAmount) > BigInt(edge.maxAmount)) {\n errors.push({\n step: i,\n code: 'INSUFFICIENT_LIQUIDITY',\n message: `Insufficient liquidity for step ${i}`,\n });\n }\n\n // Check minimum amount\n if (BigInt(step.inputAmount) < BigInt(edge.minAmount)) {\n errors.push({\n step: i,\n code: 'BELOW_MINIMUM',\n message: `Amount below minimum for step ${i}`,\n });\n }\n }\n\n // Add warnings for high slippage\n if (parseFloat(route.priceImpact) > 1) {\n warnings.push({\n code: 'HIGH_PRICE_IMPACT',\n message: `Price impact is ${route.priceImpact}%`,\n });\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n }\n\n /**\n * Update the routing graph with new data\n */\n updateGraph(edges: GraphEdge[]): void {\n // Clear existing edges\n this.graph.edges = [];\n this.graph.nodes.clear();\n\n // Add new edges\n for (const edge of edges) {\n this.addEdge(edge);\n }\n\n this.graph.lastUpdated = Date.now();\n\n // Clear route cache\n this.routeCache.clear();\n }\n\n /**\n * Add an edge to the routing graph\n */\n addEdge(edge: GraphEdge): void {\n this.graph.edges.push(edge);\n\n // Update nodes\n const fromKey = `${edge.from}:${edge.fromAsset}`;\n const toKey = `${edge.to}:${edge.toAsset}`;\n\n if (!this.graph.nodes.has(fromKey)) {\n this.graph.nodes.set(fromKey, {\n chain: edge.from,\n asset: edge.fromAsset,\n edges: [],\n });\n }\n this.graph.nodes.get(fromKey)!.edges.push(edge);\n\n if (!this.graph.nodes.has(toKey)) {\n this.graph.nodes.set(toKey, {\n chain: edge.to,\n asset: edge.toAsset,\n edges: [],\n });\n }\n }\n\n /**\n * Get the current routing graph\n */\n getGraph(): RoutingGraph {\n return this.graph;\n }\n\n private validateRequest(request: RouteRequest): RouteValidation {\n const errors: RouteValidation['errors'] = [];\n\n if (!request.sourceChain) {\n errors.push({ code: 'MISSING_SOURCE_CHAIN', message: 'Source chain is required' });\n }\n if (!request.sourceAsset) {\n errors.push({ code: 'MISSING_SOURCE_ASSET', message: 'Source asset is required' });\n }\n if (!request.sourceAmount || BigInt(request.sourceAmount) <= 0n) {\n errors.push({ code: 'INVALID_AMOUNT', message: 'Source amount must be positive' });\n }\n if (!request.destinationChain) {\n errors.push({ code: 'MISSING_DEST_CHAIN', message: 'Destination chain is required' });\n }\n if (!request.sender) {\n errors.push({ code: 'MISSING_SENDER', message: 'Sender address is required' });\n }\n if (!request.recipient) {\n errors.push({ code: 'MISSING_RECIPIENT', message: 'Recipient address is required' });\n }\n\n return { valid: errors.length === 0, errors, warnings: [] };\n }\n\n private findAllPaths(\n fromChain: ChainId,\n fromAsset: AssetId,\n toChain: ChainId,\n toAsset: AssetId,\n maxHops: number,\n ): GraphEdge[][] {\n const paths: GraphEdge[][] = [];\n const startKey = `${fromChain}:${fromAsset}`;\n const endKey = `${toChain}:${toAsset}`;\n\n // BFS to find all paths\n const queue: { key: string; path: GraphEdge[] }[] = [{ key: startKey, path: [] }];\n const visited = new Set<string>();\n\n while (queue.length > 0) {\n const { key, path } = queue.shift()!;\n\n if (path.length > maxHops) continue;\n\n if (key === endKey && path.length > 0) {\n paths.push([...path]);\n continue;\n }\n\n const node = this.graph.nodes.get(key);\n if (!node) continue;\n\n for (const edge of node.edges) {\n const nextKey = `${edge.to}:${edge.toAsset}`;\n const pathKey = `${key}->${nextKey}`;\n\n if (visited.has(pathKey)) continue;\n visited.add(pathKey);\n\n queue.push({\n key: nextKey,\n path: [...path, edge],\n });\n }\n }\n\n return paths;\n }\n\n private async buildRoute(request: RouteRequest, path: GraphEdge[]): Promise<Route> {\n const steps: RouteStep[] = [];\n let currentAmount = request.sourceAmount;\n let totalGasCost = 0n;\n let totalProtocolFees = 0n;\n let totalBridgeFees = 0n;\n let totalTime = 0;\n let cumulativePriceImpact = 0;\n\n for (let i = 0; i < path.length; i++) {\n const edge = path[i];\n\n // Calculate output amount (simplified - in production would call pricing service)\n const slippage = parseFloat(request.maxSlippage) / 100;\n const outputAmount = this.calculateOutput(currentAmount, edge);\n const minOutput = BigInt(Math.floor(Number(outputAmount) * (1 - slippage))).toString();\n\n // Estimate gas (simplified)\n const gasEstimate = this.estimateGas(edge.type);\n\n // Calculate fees\n const protocolFee = this.calculateProtocolFee(currentAmount, edge);\n const bridgeFee = edge.type === 'bridge' ? this.calculateBridgeFee(currentAmount, edge) : '0';\n\n const step: RouteStep = {\n id: `step-${i}`,\n type: edge.type,\n chain: edge.from,\n protocol: edge.protocol,\n inputAsset: edge.fromAsset,\n outputAsset: edge.toAsset,\n inputAmount: currentAmount,\n outputAmount,\n minOutputAmount: minOutput,\n contract: this.getProtocolContract(edge),\n estimatedGas: gasEstimate,\n estimatedTime: edge.estimatedTime,\n protocolFee,\n bridgeFee: edge.type === 'bridge' ? bridgeFee : undefined,\n priceImpact: this.calculatePriceImpact(currentAmount, edge),\n exchangeRate: this.calculateExchangeRate(edge),\n };\n\n steps.push(step);\n\n // Update for next iteration\n currentAmount = outputAmount;\n totalGasCost += BigInt(gasEstimate);\n totalProtocolFees += BigInt(protocolFee);\n totalBridgeFees += BigInt(bridgeFee);\n totalTime += edge.estimatedTime;\n cumulativePriceImpact += parseFloat(step.priceImpact ?? '0');\n }\n\n const totalCost = totalGasCost + totalProtocolFees + totalBridgeFees;\n const slippage = parseFloat(request.maxSlippage) / 100;\n const minDestination = BigInt(Math.floor(Number(currentAmount) * (1 - slippage))).toString();\n\n return {\n id: crypto.randomUUID(),\n steps,\n sourceChain: request.sourceChain,\n destinationChain: request.destinationChain,\n sourceAsset: request.sourceAsset,\n destinationAsset: request.destinationAsset ?? request.sourceAsset,\n sourceAmount: request.sourceAmount,\n destinationAmount: currentAmount,\n minDestinationAmount: minDestination,\n totalGasCost: totalGasCost.toString(),\n totalProtocolFees: totalProtocolFees.toString(),\n totalBridgeFees: totalBridgeFees.toString(),\n totalCost: totalCost.toString(),\n estimatedTime: totalTime,\n priceImpact: cumulativePriceImpact.toFixed(4),\n confidence: this.calculateConfidence(path),\n optimization: request.optimization,\n warnings: this.generateWarnings(steps, request),\n createdAt: Date.now(),\n expiresAt: Date.now() + 60000, // 1 minute\n };\n }\n\n private scoreRoute(route: Route, strategy: OptimizationStrategy): number {\n const weights = OPTIMIZATION_WEIGHTS[strategy];\n\n // Normalize metrics (0-100 scale)\n const costScore = 100 - Math.min(100, Number(route.totalCost) / 1000000);\n const speedScore = 100 - Math.min(100, route.estimatedTime / 600); // Max 10 min\n const confidenceScore = route.confidence;\n const slippageScore = 100 - Math.min(100, parseFloat(route.priceImpact) * 10);\n\n return (\n costScore * weights.cost +\n speedScore * weights.speed +\n confidenceScore * weights.confidence +\n slippageScore * weights.slippage\n );\n }\n\n private calculateOutput(input: string, _edge: GraphEdge): string {\n // Simplified calculation - in production would use actual pricing\n const inputBigInt = BigInt(input);\n const fee = inputBigInt * 3n / 1000n; // 0.3% fee\n return (inputBigInt - fee).toString();\n }\n\n private calculateProtocolFee(amount: string, edge: GraphEdge): string {\n // 0.1% to 0.5% depending on protocol type\n const feeRate = edge.type === 'swap' ? 30n : 10n; // basis points\n return (BigInt(amount) * feeRate / 10000n).toString();\n }\n\n private calculateBridgeFee(amount: string, _edge: GraphEdge): string {\n // Simplified bridge fee (0.1% + fixed)\n const variableFee = BigInt(amount) * 10n / 10000n;\n const fixedFee = 100000n; // 0.1 USDT\n return (variableFee + fixedFee).toString();\n }\n\n private calculatePriceImpact(amount: string, edge: GraphEdge): string {\n // Simplified price impact calculation\n const liquidity = BigInt(edge.liquidity);\n if (liquidity === 0n) return '100';\n\n const amountBigInt = BigInt(amount);\n const impact = Number(amountBigInt * 10000n / liquidity) / 100;\n return impact.toFixed(4);\n }\n\n private calculateExchangeRate(edge: GraphEdge): string {\n // Simplified - same asset = 1:1, different = estimate\n if (edge.fromAsset === edge.toAsset) {\n return '1.0';\n }\n return '0.997'; // ~0.3% spread\n }\n\n private estimateGas(type: RouteStep['type']): string {\n const gasEstimates: Record<RouteStep['type'], string> = {\n transfer: '65000',\n swap: '150000',\n bridge: '200000',\n wrap: '45000',\n unwrap: '45000',\n approve: '46000',\n deposit: '100000',\n withdraw: '100000',\n };\n return gasEstimates[type] ?? '100000';\n }\n\n private getProtocolContract(edge: GraphEdge): string {\n // Return mock contract address\n return `0x${edge.protocol?.slice(0, 40).padEnd(40, '0') ?? '0'.repeat(40)}`;\n }\n\n private calculateConfidence(path: GraphEdge[]): number {\n // Base confidence decreases with each hop\n let confidence = 100;\n for (const edge of path) {\n // Reduce confidence based on step type\n const reduction = edge.type === 'bridge' ? 10 : 3;\n confidence -= reduction;\n\n // Liquidity factor\n if (BigInt(edge.liquidity) < 1000000n) {\n confidence -= 5;\n }\n }\n return Math.max(0, Math.min(100, confidence));\n }\n\n private generateWarnings(steps: RouteStep[], request: RouteRequest): string[] {\n const warnings: string[] = [];\n\n // Check for high number of hops\n if (steps.length > 3) {\n warnings.push(`Route has ${steps.length} steps which may increase risk`);\n }\n\n // Check for bridge steps\n const bridgeSteps = steps.filter(s => s.type === 'bridge');\n if (bridgeSteps.length > 0) {\n warnings.push('Route includes cross-chain bridge which may take longer');\n }\n\n // Check deadline\n if (request.deadline) {\n const totalTime = steps.reduce((sum, s) => sum + s.estimatedTime, 0);\n const timeRemaining = request.deadline - Date.now() / 1000;\n if (totalTime > timeRemaining * 0.8) {\n warnings.push('Route may not complete before deadline');\n }\n }\n\n return warnings;\n }\n\n private findEdge(\n fromChain: ChainId,\n fromAsset: AssetId,\n toChain: ChainId,\n toAsset: AssetId,\n protocol?: string,\n ): GraphEdge | undefined {\n return this.graph.edges.find(e =>\n e.from === fromChain &&\n e.fromAsset === fromAsset &&\n e.to === toChain &&\n e.toAsset === toAsset &&\n (!protocol || e.protocol === protocol)\n );\n }\n\n private getCacheKey(request: RouteRequest): string {\n return JSON.stringify({\n sourceChain: request.sourceChain,\n sourceAsset: request.sourceAsset,\n sourceAmount: request.sourceAmount,\n destinationChain: request.destinationChain,\n destinationAsset: request.destinationAsset,\n optimization: request.optimization,\n });\n }\n}\n\n/**\n * Routing error codes\n */\nexport type RoutingErrorCode =\n | 'INVALID_REQUEST'\n | 'NO_ROUTE'\n | 'NO_VALID_ROUTE'\n | 'INSUFFICIENT_LIQUIDITY'\n | 'ROUTE_EXPIRED';\n\n/**\n * Custom error for routing operations\n */\nexport class RoutingError extends Error {\n code: RoutingErrorCode;\n\n constructor(message: string, code: RoutingErrorCode) {\n super(message);\n this.name = 'RoutingError';\n this.code = code;\n }\n}\n","import { GraphEdge, ChainId, AssetId, OptimizationStrategy } from './types.js';\n\n/**\n * Priority queue implementation for path finding algorithms\n */\nclass PriorityQueue<T> {\n private items: { item: T; priority: number }[] = [];\n\n enqueue(item: T, priority: number): void {\n this.items.push({ item, priority });\n this.items.sort((a, b) => a.priority - b.priority);\n }\n\n dequeue(): T | undefined {\n return this.items.shift()?.item;\n }\n\n isEmpty(): boolean {\n return this.items.length === 0;\n }\n}\n\n/**\n * Node key generator\n */\nfunction nodeKey(chain: ChainId, asset: AssetId): string {\n return `${chain}:${asset}`;\n}\n\n/**\n * Cost function configuration\n */\nexport interface CostConfig {\n gasCostWeight: number;\n feeWeight: number;\n timeWeight: number;\n slippageWeight: number;\n hopPenalty: number;\n bridgePenalty: number;\n}\n\n/**\n * Default cost configurations for different strategies\n */\nexport const COST_CONFIGS: Record<OptimizationStrategy, CostConfig> = {\n cost: {\n gasCostWeight: 0.4,\n feeWeight: 0.4,\n timeWeight: 0.1,\n slippageWeight: 0.1,\n hopPenalty: 0.05,\n bridgePenalty: 0.1,\n },\n speed: {\n gasCostWeight: 0.1,\n feeWeight: 0.1,\n timeWeight: 0.6,\n slippageWeight: 0.2,\n hopPenalty: 0.1,\n bridgePenalty: 0.2,\n },\n privacy: {\n gasCostWeight: 0.2,\n feeWeight: 0.2,\n timeWeight: 0.1,\n slippageWeight: 0.5,\n hopPenalty: 0.15,\n bridgePenalty: 0.05,\n },\n balanced: {\n gasCostWeight: 0.25,\n feeWeight: 0.25,\n timeWeight: 0.25,\n slippageWeight: 0.25,\n hopPenalty: 0.08,\n bridgePenalty: 0.12,\n },\n slippage: {\n gasCostWeight: 0.1,\n feeWeight: 0.1,\n timeWeight: 0.1,\n slippageWeight: 0.7,\n hopPenalty: 0.12,\n bridgePenalty: 0.15,\n },\n};\n\n/**\n * Calculate edge cost based on optimization strategy\n */\nexport function calculateEdgeCost(edge: GraphEdge, config: CostConfig): number {\n // Normalize each factor to 0-1 scale\n const normalizedGas = edge.cost / 1000000; // Assume max 1M units\n const normalizedTime = edge.estimatedTime / 3600; // Assume max 1 hour\n\n // Calculate weighted cost\n let cost =\n normalizedGas * config.gasCostWeight +\n normalizedTime * config.timeWeight;\n\n // Add penalties\n cost += config.hopPenalty;\n if (edge.type === 'bridge') {\n cost += config.bridgePenalty;\n }\n\n return Math.max(0.001, cost); // Ensure positive cost\n}\n\n/**\n * Dijkstra's algorithm for finding shortest path\n */\nexport function dijkstra(\n edges: GraphEdge[],\n startChain: ChainId,\n startAsset: AssetId,\n endChain: ChainId,\n endAsset: AssetId,\n costConfig: CostConfig,\n maxHops: number = 5,\n): GraphEdge[] | null {\n const startKey = nodeKey(startChain, startAsset);\n const endKey = nodeKey(endChain, endAsset);\n\n // Build adjacency list\n const adjacency = new Map<string, GraphEdge[]>();\n for (const edge of edges) {\n const key = nodeKey(edge.from, edge.fromAsset);\n if (!adjacency.has(key)) {\n adjacency.set(key, []);\n }\n adjacency.get(key)!.push(edge);\n }\n\n // Dijkstra's algorithm\n const distances = new Map<string, number>();\n const previous = new Map<string, { edge: GraphEdge; node: string } | null>();\n const hops = new Map<string, number>();\n const pq = new PriorityQueue<string>();\n\n distances.set(startKey, 0);\n hops.set(startKey, 0);\n previous.set(startKey, null);\n pq.enqueue(startKey, 0);\n\n while (!pq.isEmpty()) {\n const currentKey = pq.dequeue()!;\n const currentDistance = distances.get(currentKey) ?? Infinity;\n const currentHops = hops.get(currentKey) ?? 0;\n\n if (currentKey === endKey) {\n break;\n }\n\n if (currentHops >= maxHops) {\n continue;\n }\n\n const neighbors = adjacency.get(currentKey) ?? [];\n for (const edge of neighbors) {\n const neighborKey = nodeKey(edge.to, edge.toAsset);\n const edgeCost = calculateEdgeCost(edge, costConfig);\n const newDistance = currentDistance + edgeCost;\n\n if (newDistance < (distances.get(neighborKey) ?? Infinity)) {\n distances.set(neighborKey, newDistance);\n hops.set(neighborKey, currentHops + 1);\n previous.set(neighborKey, { edge, node: currentKey });\n pq.enqueue(neighborKey, newDistance);\n }\n }\n }\n\n // Reconstruct path\n if (!previous.has(endKey)) {\n return null;\n }\n\n const path: GraphEdge[] = [];\n let current = endKey;\n\n while (previous.get(current) !== null) {\n const prev = previous.get(current)!;\n path.unshift(prev.edge);\n current = prev.node;\n }\n\n return path;\n}\n\n/**\n * A* algorithm with heuristic for faster path finding\n */\nexport function astar(\n edges: GraphEdge[],\n startChain: ChainId,\n startAsset: AssetId,\n endChain: ChainId,\n endAsset: AssetId,\n costConfig: CostConfig,\n maxHops: number = 5,\n): GraphEdge[] | null {\n const startKey = nodeKey(startChain, startAsset);\n const endKey = nodeKey(endChain, endAsset);\n\n // Build adjacency list\n const adjacency = new Map<string, GraphEdge[]>();\n for (const edge of edges) {\n const key = nodeKey(edge.from, edge.fromAsset);\n if (!adjacency.has(key)) {\n adjacency.set(key, []);\n }\n adjacency.get(key)!.push(edge);\n }\n\n // Heuristic function (estimates remaining cost)\n const heuristic = (key: string): number => {\n if (key === endKey) return 0;\n\n // Parse chain and asset from key\n const [chain] = key.split(':');\n\n // If same chain as destination, lower heuristic\n if (chain === endChain) {\n return 0.1;\n }\n\n // Cross-chain, higher heuristic\n return 0.5;\n };\n\n // A* algorithm\n const gScore = new Map<string, number>();\n const fScore = new Map<string, number>();\n const previous = new Map<string, { edge: GraphEdge; node: string } | null>();\n const hops = new Map<string, number>();\n const pq = new PriorityQueue<string>();\n\n gScore.set(startKey, 0);\n fScore.set(startKey, heuristic(startKey));\n hops.set(startKey, 0);\n previous.set(startKey, null);\n pq.enqueue(startKey, fScore.get(startKey)!);\n\n const visited = new Set<string>();\n\n while (!pq.isEmpty()) {\n const currentKey = pq.dequeue()!;\n\n if (currentKey === endKey) {\n break;\n }\n\n if (visited.has(currentKey)) {\n continue;\n }\n visited.add(currentKey);\n\n const currentHops = hops.get(currentKey) ?? 0;\n if (currentHops >= maxHops) {\n continue;\n }\n\n const neighbors = adjacency.get(currentKey) ?? [];\n for (const edge of neighbors) {\n const neighborKey = nodeKey(edge.to, edge.toAsset);\n const edgeCost = calculateEdgeCost(edge, costConfig);\n const tentativeGScore = (gScore.get(currentKey) ?? Infinity) + edgeCost;\n\n if (tentativeGScore < (gScore.get(neighborKey) ?? Infinity)) {\n gScore.set(neighborKey, tentativeGScore);\n fScore.set(neighborKey, tentativeGScore + heuristic(neighborKey));\n hops.set(neighborKey, currentHops + 1);\n previous.set(neighborKey, { edge, node: currentKey });\n pq.enqueue(neighborKey, fScore.get(neighborKey)!);\n }\n }\n }\n\n // Reconstruct path\n if (!previous.has(endKey)) {\n return null;\n }\n\n const path: GraphEdge[] = [];\n let current = endKey;\n\n while (previous.get(current) !== null) {\n const prev = previous.get(current)!;\n path.unshift(prev.edge);\n current = prev.node;\n }\n\n return path;\n}\n\n/**\n * Find k-shortest paths using Yen's algorithm\n */\nexport function kShortestPaths(\n edges: GraphEdge[],\n startChain: ChainId,\n startAsset: AssetId,\n endChain: ChainId,\n endAsset: AssetId,\n costConfig: CostConfig,\n k: number = 5,\n maxHops: number = 5,\n): GraphEdge[][] {\n const paths: GraphEdge[][] = [];\n\n // Find first shortest path\n const firstPath = dijkstra(\n edges,\n startChain,\n startAsset,\n endChain,\n endAsset,\n costConfig,\n maxHops,\n );\n\n if (!firstPath) {\n return [];\n }\n\n paths.push(firstPath);\n\n // Candidate paths\n const candidates: { path: GraphEdge[]; cost: number }[] = [];\n\n for (let i = 1; i < k; i++) {\n const prevPath = paths[i - 1];\n\n // For each node in the previous path (except the last)\n for (let j = 0; j < prevPath.length; j++) {\n // Create a modified edge set that excludes certain edges\n const excludedEdges = new Set<string>();\n\n // Exclude edges that would lead to duplicate paths\n for (const existingPath of paths) {\n if (existingPath.length > j) {\n let match = true;\n for (let m = 0; m < j; m++) {\n if (existingPath[m] !== prevPath[m]) {\n match = false;\n break;\n }\n }\n if (match && existingPath[j]) {\n const edgeKey = `${existingPath[j].from}:${existingPath[j].fromAsset}->${existingPath[j].to}:${existingPath[j].toAsset}`;\n excludedEdges.add(edgeKey);\n }\n }\n }\n\n // Create filtered edge set\n const filteredEdges = edges.filter(e => {\n const edgeKey = `${e.from}:${e.fromAsset}->${e.to}:${e.toAsset}`;\n return !excludedEdges.has(edgeKey);\n });\n\n // Find spur path from the spur node\n const spurNode = j === 0\n ? { chain: startChain, asset: startAsset }\n : { chain: prevPath[j - 1].to, asset: prevPath[j - 1].toAsset };\n\n const spurPath = dijkstra(\n filteredEdges,\n spurNode.chain,\n spurNode.asset,\n endChain,\n endAsset,\n costConfig,\n maxHops - j,\n );\n\n if (spurPath) {\n // Combine root path and spur path\n const rootPath = prevPath.slice(0, j);\n const candidatePath = [...rootPath, ...spurPath];\n\n // Calculate total cost\n const cost = candidatePath.reduce(\n (sum, edge) => sum + calculateEdgeCost(edge, costConfig),\n 0,\n );\n\n // Check if this path is already in candidates or paths\n const pathKey = candidatePath.map(e =>\n `${e.from}:${e.fromAsset}->${e.to}:${e.toAsset}`\n ).join('|');\n\n const isDuplicate = paths.some(p =>\n p.map(e => `${e.from}:${e.fromAsset}->${e.to}:${e.toAsset}`).join('|') === pathKey\n ) || candidates.some(c =>\n c.path.map(e => `${e.from}:${e.fromAsset}->${e.to}:${e.toAsset}`).join('|') === pathKey\n );\n\n if (!isDuplicate) {\n candidates.push({ path: candidatePath, cost });\n }\n }\n }\n\n if (candidates.length === 0) {\n break;\n }\n\n // Sort candidates by cost and add the best one\n candidates.sort((a, b) => a.cost - b.cost);\n const best = candidates.shift()!;\n paths.push(best.path);\n }\n\n return paths;\n}\n\n/**\n * Multi-objective path finding (Pareto-optimal paths)\n */\nexport function paretoOptimalPaths(\n edges: GraphEdge[],\n startChain: ChainId,\n startAsset: AssetId,\n endChain: ChainId,\n endAsset: AssetId,\n maxHops: number = 5,\n): { path: GraphEdge[]; metrics: { cost: number; time: number; hops: number } }[] {\n // Find paths optimized for different objectives\n const costPaths = kShortestPaths(\n edges,\n startChain,\n startAsset,\n endChain,\n endAsset,\n COST_CONFIGS.cost,\n 3,\n maxHops,\n );\n\n const speedPaths = kShortestPaths(\n edges,\n startChain,\n startAsset,\n endChain,\n endAsset,\n COST_CONFIGS.speed,\n 3,\n maxHops,\n );\n\n // Combine and deduplicate\n const allPaths = [...costPaths, ...speedPaths];\n const uniquePaths = new Map<string, GraphEdge[]>();\n\n for (const path of allPaths) {\n const key = path.map(e =>\n `${e.from}:${e.fromAsset}->${e.to}:${e.toAsset}:${e.protocol}`\n ).join('|');\n if (!uniquePaths.has(key)) {\n uniquePaths.set(key, path);\n }\n }\n\n // Calculate metrics for each path\n const results = Array.from(uniquePaths.values()).map(path => {\n const cost = path.reduce((sum, e) => sum + e.cost, 0);\n const time = path.reduce((sum, e) => sum + e.estimatedTime, 0);\n return {\n path,\n metrics: { cost, time, hops: path.length },\n };\n });\n\n // Filter to Pareto-optimal (non-dominated) solutions\n return results.filter((r, i) => {\n for (let j = 0; j < results.length; j++) {\n if (i === j) continue;\n const other = results[j];\n\n // Check if other dominates r\n const otherDominates =\n other.metrics.cost <= r.metrics.cost &&\n other.metrics.time <= r.metrics.time &&\n other.metrics.hops <= r.metrics.hops &&\n (other.metrics.cost < r.metrics.cost ||\n other.metrics.time < r.metrics.time ||\n other.metrics.hops < r.metrics.hops);\n\n if (otherDominates) {\n return false;\n }\n }\n return true;\n });\n}\n"],"mappings":"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","names":["slippage"]}
@@ -0,0 +1,450 @@
1
+ import {
2
+ AssetId,
3
+ ChainId,
4
+ ProtocolId
5
+ } from "./chunk-QIZPPHGB.js";
6
+
7
+ // src/liquidity/types.ts
8
+ import { z } from "zod";
9
+ var PoolType = z.enum([
10
+ "constant_product",
11
+ // Uniswap V2 style (x * y = k)
12
+ "concentrated",
13
+ // Uniswap V3 style
14
+ "stable",
15
+ // Curve stable pools
16
+ "weighted",
17
+ // Balancer weighted pools
18
+ "hybrid"
19
+ // Mixed pool types
20
+ ]);
21
+ var LiquidityPool = z.object({
22
+ id: z.string(),
23
+ protocol: ProtocolId,
24
+ chain: ChainId,
25
+ type: PoolType,
26
+ // Tokens
27
+ tokens: z.array(z.object({
28
+ asset: AssetId,
29
+ reserve: z.string(),
30
+ weight: z.string().optional()
31
+ // For weighted pools
32
+ })),
33
+ // Pool parameters
34
+ fee: z.string(),
35
+ // Percentage
36
+ tvl: z.string(),
37
+ // Total value locked in USD
38
+ // For concentrated liquidity
39
+ tickSpacing: z.number().optional(),
40
+ currentTick: z.number().optional(),
41
+ sqrtPriceX96: z.string().optional(),
42
+ // Metadata
43
+ address: z.string(),
44
+ createdAt: z.number(),
45
+ lastUpdated: z.number()
46
+ });
47
+ var LiquiditySource = z.object({
48
+ chain: ChainId,
49
+ inputAsset: AssetId,
50
+ outputAsset: AssetId,
51
+ // Aggregated liquidity
52
+ totalLiquidity: z.string(),
53
+ bestPrice: z.string(),
54
+ // Best available rate
55
+ averagePrice: z.string(),
56
+ // Sources
57
+ pools: z.array(z.object({
58
+ poolId: z.string(),
59
+ protocol: ProtocolId,
60
+ liquidity: z.string(),
61
+ price: z.string(),
62
+ maxAmountIn: z.string(),
63
+ maxAmountOut: z.string(),
64
+ priceImpact1Percent: z.string()
65
+ // Price impact for 1% of liquidity
66
+ })),
67
+ lastUpdated: z.number()
68
+ });
69
+ var CrossChainLiquidity = z.object({
70
+ sourceChain: ChainId,
71
+ destinationChain: ChainId,
72
+ asset: AssetId,
73
+ // Bridge liquidity
74
+ bridges: z.array(z.object({
75
+ bridge: ProtocolId,
76
+ liquidity: z.string(),
77
+ maxTransfer: z.string(),
78
+ minTransfer: z.string(),
79
+ fee: z.string(),
80
+ estimatedTime: z.number(),
81
+ available: z.boolean()
82
+ })),
83
+ // Total available
84
+ totalLiquidity: z.string(),
85
+ bestBridge: ProtocolId,
86
+ lastUpdated: z.number()
87
+ });
88
+ var SlippageResult = z.object({
89
+ inputAmount: z.string(),
90
+ outputAmount: z.string(),
91
+ priceImpact: z.string(),
92
+ // Percentage
93
+ effectivePrice: z.string(),
94
+ slippageTolerance: z.string(),
95
+ minOutputAmount: z.string(),
96
+ executionPath: z.array(z.object({
97
+ poolId: z.string(),
98
+ amountIn: z.string(),
99
+ amountOut: z.string(),
100
+ priceImpact: z.string()
101
+ }))
102
+ });
103
+ var LiquidityDepth = z.object({
104
+ chain: ChainId,
105
+ inputAsset: AssetId,
106
+ outputAsset: AssetId,
107
+ currentPrice: z.string(),
108
+ depth: z.array(z.object({
109
+ priceLevel: z.string(),
110
+ // Percentage from current price
111
+ bidLiquidity: z.string(),
112
+ // Liquidity available to buy
113
+ askLiquidity: z.string()
114
+ // Liquidity available to sell
115
+ })),
116
+ spread: z.string(),
117
+ // Bid-ask spread
118
+ lastUpdated: z.number()
119
+ });
120
+
121
+ // src/liquidity/aggregator.ts
122
+ var LiquidityAggregator = class {
123
+ providers = /* @__PURE__ */ new Map();
124
+ bridgeProviders = /* @__PURE__ */ new Map();
125
+ poolCache = /* @__PURE__ */ new Map();
126
+ config;
127
+ constructor(config = {}) {
128
+ this.config = {
129
+ cacheTtl: config.cacheTtl ?? 3e4,
130
+ maxPoolsPerSource: config.maxPoolsPerSource ?? 10,
131
+ minLiquidity: config.minLiquidity ?? "1000"
132
+ // $1000 minimum
133
+ };
134
+ }
135
+ /**
136
+ * Register a liquidity provider
137
+ */
138
+ registerProvider(provider) {
139
+ const key = `${provider.chain}:${provider.protocol}`;
140
+ this.providers.set(key, provider);
141
+ }
142
+ /**
143
+ * Register a bridge provider
144
+ */
145
+ registerBridgeProvider(provider) {
146
+ this.bridgeProviders.set(provider.bridge, provider);
147
+ }
148
+ /**
149
+ * Get aggregated liquidity for a trading pair
150
+ */
151
+ async getLiquidity(chain, inputAsset, outputAsset) {
152
+ const cacheKey = `${chain}:${inputAsset}:${outputAsset}`;
153
+ const cached = this.poolCache.get(cacheKey);
154
+ if (cached && cached.expiresAt > Date.now()) {
155
+ return this.aggregatePools(chain, inputAsset, outputAsset, cached.pools);
156
+ }
157
+ const pools = [];
158
+ for (const [key, provider] of this.providers) {
159
+ if (!key.startsWith(chain)) continue;
160
+ try {
161
+ const providerPools = await provider.getPools(inputAsset, outputAsset);
162
+ pools.push(...providerPools.slice(0, this.config.maxPoolsPerSource));
163
+ } catch {
164
+ continue;
165
+ }
166
+ }
167
+ this.poolCache.set(cacheKey, {
168
+ pools,
169
+ expiresAt: Date.now() + this.config.cacheTtl
170
+ });
171
+ return this.aggregatePools(chain, inputAsset, outputAsset, pools);
172
+ }
173
+ /**
174
+ * Get cross-chain liquidity
175
+ */
176
+ async getCrossChainLiquidity(sourceChain, destinationChain, asset) {
177
+ const bridges = [];
178
+ for (const [, provider] of this.bridgeProviders) {
179
+ try {
180
+ const liquidity = await provider.getLiquidity(
181
+ sourceChain,
182
+ destinationChain,
183
+ asset
184
+ );
185
+ if (liquidity) {
186
+ bridges.push(liquidity);
187
+ }
188
+ } catch {
189
+ continue;
190
+ }
191
+ }
192
+ bridges.sort((a, b) => parseFloat(a.fee) - parseFloat(b.fee));
193
+ const totalLiquidity = bridges.reduce(
194
+ (sum, b) => sum + BigInt(b.liquidity),
195
+ 0n
196
+ ).toString();
197
+ return {
198
+ sourceChain,
199
+ destinationChain,
200
+ asset,
201
+ bridges,
202
+ totalLiquidity,
203
+ bestBridge: bridges[0]?.bridge ?? "",
204
+ lastUpdated: Date.now()
205
+ };
206
+ }
207
+ /**
208
+ * Calculate slippage for a trade
209
+ */
210
+ calculateSlippage(source, inputAmount, slippageTolerance) {
211
+ const inputBigInt = BigInt(inputAmount);
212
+ const tolerance = parseFloat(slippageTolerance) / 100;
213
+ const sortedPools = [...source.pools].sort(
214
+ (a, b) => parseFloat(a.price) - parseFloat(b.price)
215
+ );
216
+ let remainingInput = inputBigInt;
217
+ let totalOutput = 0n;
218
+ const executionPath = [];
219
+ for (const pool of sortedPools) {
220
+ if (remainingInput <= 0n) break;
221
+ const poolMaxIn = BigInt(pool.maxAmountIn);
222
+ const amountIn = remainingInput < poolMaxIn ? remainingInput : poolMaxIn;
223
+ const baseOutput = amountIn * BigInt(Math.floor(parseFloat(pool.price) * 1e6)) / 1000000n;
224
+ const priceImpact = this.calculatePoolPriceImpact(amountIn, BigInt(pool.liquidity));
225
+ const adjustedOutput = baseOutput * BigInt(1e4 - Math.floor(priceImpact * 100)) / 10000n;
226
+ totalOutput += adjustedOutput;
227
+ remainingInput -= amountIn;
228
+ executionPath.push({
229
+ poolId: pool.poolId,
230
+ amountIn: amountIn.toString(),
231
+ amountOut: adjustedOutput.toString(),
232
+ priceImpact: priceImpact.toFixed(4)
233
+ });
234
+ }
235
+ const effectivePrice = inputBigInt > 0n ? (Number(totalOutput) / Number(inputBigInt)).toFixed(8) : "0";
236
+ const totalPriceImpact = this.calculateTotalPriceImpact(
237
+ inputAmount,
238
+ totalOutput.toString(),
239
+ source.bestPrice
240
+ );
241
+ const minOutput = BigInt(Math.floor(Number(totalOutput) * (1 - tolerance)));
242
+ return {
243
+ inputAmount,
244
+ outputAmount: totalOutput.toString(),
245
+ priceImpact: totalPriceImpact.toFixed(4),
246
+ effectivePrice,
247
+ slippageTolerance,
248
+ minOutputAmount: minOutput.toString(),
249
+ executionPath
250
+ };
251
+ }
252
+ /**
253
+ * Get liquidity depth at different price levels
254
+ */
255
+ async getLiquidityDepth(chain, inputAsset, outputAsset, levels = [0.5, 1, 2, 5, 10]) {
256
+ const source = await this.getLiquidity(chain, inputAsset, outputAsset);
257
+ const currentPrice = source.bestPrice;
258
+ const depth = [];
259
+ for (const level of levels) {
260
+ const bidLiquidity = this.calculateLiquidityAtLevel(source.pools, level, "bid");
261
+ const askLiquidity = this.calculateLiquidityAtLevel(source.pools, level, "ask");
262
+ depth.push({
263
+ priceLevel: level.toString(),
264
+ bidLiquidity,
265
+ askLiquidity
266
+ });
267
+ }
268
+ const bestBid = source.pools.length > 0 ? Math.max(...source.pools.map((p) => parseFloat(p.price))) : 0;
269
+ const bestAsk = source.pools.length > 0 ? Math.min(...source.pools.map((p) => parseFloat(p.price))) : 0;
270
+ const spread = bestBid > 0 ? ((bestAsk - bestBid) / bestBid * 100).toFixed(4) : "0";
271
+ return {
272
+ chain,
273
+ inputAsset,
274
+ outputAsset,
275
+ currentPrice,
276
+ depth,
277
+ spread,
278
+ lastUpdated: Date.now()
279
+ };
280
+ }
281
+ /**
282
+ * Find best route across multiple pools
283
+ */
284
+ findBestRoute(source, inputAmount, maxPools = 3) {
285
+ const inputBigInt = BigInt(inputAmount);
286
+ const sortedPools = [...source.pools].filter((p) => BigInt(p.liquidity) > BigInt(this.config.minLiquidity)).sort((a, b) => parseFloat(b.price) - parseFloat(a.price)).slice(0, maxPools);
287
+ if (sortedPools.length === 0) {
288
+ return { pools: [], expectedOutput: "0", priceImpact: "100" };
289
+ }
290
+ const totalLiquidity = sortedPools.reduce(
291
+ (sum, p) => sum + BigInt(p.liquidity),
292
+ 0n
293
+ );
294
+ let totalOutput = 0n;
295
+ const pools = [];
296
+ for (const pool of sortedPools) {
297
+ const proportion = BigInt(pool.liquidity) * 10000n / totalLiquidity;
298
+ const poolInput = inputBigInt * proportion / 10000n;
299
+ if (poolInput > 0n) {
300
+ const priceImpact2 = this.calculatePoolPriceImpact(poolInput, BigInt(pool.liquidity));
301
+ const output = poolInput * BigInt(Math.floor(parseFloat(pool.price) * 1e6)) / 1000000n;
302
+ const adjustedOutput = output * BigInt(1e4 - Math.floor(priceImpact2 * 100)) / 10000n;
303
+ totalOutput += adjustedOutput;
304
+ pools.push(pool.poolId);
305
+ }
306
+ }
307
+ const priceImpact = this.calculateTotalPriceImpact(
308
+ inputAmount,
309
+ totalOutput.toString(),
310
+ source.bestPrice
311
+ );
312
+ return {
313
+ pools,
314
+ expectedOutput: totalOutput.toString(),
315
+ priceImpact: priceImpact.toFixed(4)
316
+ };
317
+ }
318
+ /**
319
+ * Clear cache
320
+ */
321
+ clearCache() {
322
+ this.poolCache.clear();
323
+ }
324
+ aggregatePools(chain, inputAsset, outputAsset, pools) {
325
+ const relevantPools = pools.filter(
326
+ (p) => p.tokens.some((t) => t.asset === inputAsset) && p.tokens.some((t) => t.asset === outputAsset)
327
+ );
328
+ if (relevantPools.length === 0) {
329
+ return {
330
+ chain,
331
+ inputAsset,
332
+ outputAsset,
333
+ totalLiquidity: "0",
334
+ bestPrice: "0",
335
+ averagePrice: "0",
336
+ pools: [],
337
+ lastUpdated: Date.now()
338
+ };
339
+ }
340
+ const poolData = relevantPools.map((pool) => {
341
+ const inputToken = pool.tokens.find((t) => t.asset === inputAsset);
342
+ const outputToken = pool.tokens.find((t) => t.asset === outputAsset);
343
+ if (!inputToken || !outputToken) {
344
+ return null;
345
+ }
346
+ const inputReserve = BigInt(inputToken.reserve);
347
+ const outputReserve = BigInt(outputToken.reserve);
348
+ const price = inputReserve > 0n ? (Number(outputReserve) / Number(inputReserve)).toFixed(8) : "0";
349
+ const maxAmountIn = (inputReserve / 10n).toString();
350
+ const maxAmountOut = (outputReserve / 10n).toString();
351
+ const onePercent = inputReserve / 100n;
352
+ const priceImpact1Percent = this.calculatePoolPriceImpact(onePercent, inputReserve);
353
+ return {
354
+ poolId: pool.id,
355
+ protocol: pool.protocol,
356
+ liquidity: pool.tvl,
357
+ price,
358
+ maxAmountIn,
359
+ maxAmountOut,
360
+ priceImpact1Percent: priceImpact1Percent.toFixed(4)
361
+ };
362
+ }).filter((p) => p !== null);
363
+ const totalLiquidity = poolData.reduce(
364
+ (sum, p) => sum + BigInt(p.liquidity),
365
+ 0n
366
+ );
367
+ const prices = poolData.map((p) => parseFloat(p.price)).filter((p) => p > 0);
368
+ const bestPrice = prices.length > 0 ? Math.max(...prices).toFixed(8) : "0";
369
+ const averagePrice = prices.length > 0 ? (prices.reduce((a, b) => a + b, 0) / prices.length).toFixed(8) : "0";
370
+ return {
371
+ chain,
372
+ inputAsset,
373
+ outputAsset,
374
+ totalLiquidity: totalLiquidity.toString(),
375
+ bestPrice,
376
+ averagePrice,
377
+ pools: poolData,
378
+ lastUpdated: Date.now()
379
+ };
380
+ }
381
+ calculatePoolPriceImpact(amount, liquidity) {
382
+ if (liquidity <= 0n) return 100;
383
+ const impact = Number(amount * 10000n / (liquidity + amount)) / 100;
384
+ return Math.min(impact, 100);
385
+ }
386
+ calculateTotalPriceImpact(inputAmount, outputAmount, bestPrice) {
387
+ const expectedOutput = parseFloat(inputAmount) * parseFloat(bestPrice);
388
+ const actualOutput = parseFloat(outputAmount);
389
+ if (expectedOutput <= 0) return 100;
390
+ const impact = (expectedOutput - actualOutput) / expectedOutput * 100;
391
+ return Math.max(0, Math.min(impact, 100));
392
+ }
393
+ calculateLiquidityAtLevel(pools, level, _side) {
394
+ const adjustedLiquidity = pools.reduce((sum, pool) => {
395
+ const impact1Pct = parseFloat(pool.priceImpact1Percent);
396
+ const usablePortion = level / (impact1Pct || 0.01);
397
+ const usableLiquidity = BigInt(pool.liquidity) * BigInt(Math.min(Math.floor(usablePortion * 100), 1e4)) / 10000n;
398
+ return sum + usableLiquidity;
399
+ }, 0n);
400
+ return adjustedLiquidity.toString();
401
+ }
402
+ };
403
+ var MockLiquidityProvider = class {
404
+ chain;
405
+ protocol;
406
+ pools = [];
407
+ constructor(chain, protocol) {
408
+ this.chain = chain;
409
+ this.protocol = protocol;
410
+ }
411
+ addPool(pool) {
412
+ this.pools.push(pool);
413
+ }
414
+ async getPools(inputAsset, outputAsset) {
415
+ return this.pools.filter(
416
+ (p) => p.tokens.some((t) => t.asset === inputAsset) && (!outputAsset || p.tokens.some((t) => t.asset === outputAsset))
417
+ );
418
+ }
419
+ async getPool(poolId) {
420
+ return this.pools.find((p) => p.id === poolId) ?? null;
421
+ }
422
+ };
423
+ var MockBridgeProvider = class {
424
+ bridge;
425
+ liquidity = /* @__PURE__ */ new Map();
426
+ constructor(bridge) {
427
+ this.bridge = bridge;
428
+ }
429
+ setLiquidity(sourceChain, destinationChain, asset, data) {
430
+ const key = `${sourceChain}:${destinationChain}:${asset}`;
431
+ this.liquidity.set(key, data);
432
+ }
433
+ async getLiquidity(sourceChain, destinationChain, asset) {
434
+ const key = `${sourceChain}:${destinationChain}:${asset}`;
435
+ return this.liquidity.get(key) ?? null;
436
+ }
437
+ };
438
+
439
+ export {
440
+ PoolType,
441
+ LiquidityPool,
442
+ LiquiditySource,
443
+ CrossChainLiquidity,
444
+ SlippageResult,
445
+ LiquidityDepth,
446
+ LiquidityAggregator,
447
+ MockLiquidityProvider,
448
+ MockBridgeProvider
449
+ };
450
+ //# sourceMappingURL=chunk-PCDWVENA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/liquidity/types.ts","../src/liquidity/aggregator.ts"],"sourcesContent":["import { z } from 'zod';\nimport { ChainId, AssetId, ProtocolId } from '../routing/types.js';\n\n/**\n * Liquidity pool type\n */\nexport const PoolType = z.enum([\n 'constant_product', // Uniswap V2 style (x * y = k)\n 'concentrated', // Uniswap V3 style\n 'stable', // Curve stable pools\n 'weighted', // Balancer weighted pools\n 'hybrid', // Mixed pool types\n]);\nexport type PoolType = z.infer<typeof PoolType>;\n\n/**\n * Liquidity pool\n */\nexport const LiquidityPool = z.object({\n id: z.string(),\n protocol: ProtocolId,\n chain: ChainId,\n type: PoolType,\n\n // Tokens\n tokens: z.array(z.object({\n asset: AssetId,\n reserve: z.string(),\n weight: z.string().optional(), // For weighted pools\n })),\n\n // Pool parameters\n fee: z.string(), // Percentage\n tvl: z.string(), // Total value locked in USD\n\n // For concentrated liquidity\n tickSpacing: z.number().optional(),\n currentTick: z.number().optional(),\n sqrtPriceX96: z.string().optional(),\n\n // Metadata\n address: z.string(),\n createdAt: z.number(),\n lastUpdated: z.number(),\n});\nexport type LiquidityPool = z.infer<typeof LiquidityPool>;\n\n/**\n * Liquidity source (aggregated from multiple pools)\n */\nexport const LiquiditySource = z.object({\n chain: ChainId,\n inputAsset: AssetId,\n outputAsset: AssetId,\n\n // Aggregated liquidity\n totalLiquidity: z.string(),\n bestPrice: z.string(), // Best available rate\n averagePrice: z.string(),\n\n // Sources\n pools: z.array(z.object({\n poolId: z.string(),\n protocol: ProtocolId,\n liquidity: z.string(),\n price: z.string(),\n maxAmountIn: z.string(),\n maxAmountOut: z.string(),\n priceImpact1Percent: z.string(), // Price impact for 1% of liquidity\n })),\n\n lastUpdated: z.number(),\n});\nexport type LiquiditySource = z.infer<typeof LiquiditySource>;\n\n/**\n * Cross-chain liquidity\n */\nexport const CrossChainLiquidity = z.object({\n sourceChain: ChainId,\n destinationChain: ChainId,\n asset: AssetId,\n\n // Bridge liquidity\n bridges: z.array(z.object({\n bridge: ProtocolId,\n liquidity: z.string(),\n maxTransfer: z.string(),\n minTransfer: z.string(),\n fee: z.string(),\n estimatedTime: z.number(),\n available: z.boolean(),\n })),\n\n // Total available\n totalLiquidity: z.string(),\n bestBridge: ProtocolId,\n\n lastUpdated: z.number(),\n});\nexport type CrossChainLiquidity = z.infer<typeof CrossChainLiquidity>;\n\n/**\n * Slippage calculation result\n */\nexport const SlippageResult = z.object({\n inputAmount: z.string(),\n outputAmount: z.string(),\n priceImpact: z.string(), // Percentage\n effectivePrice: z.string(),\n slippageTolerance: z.string(),\n minOutputAmount: z.string(),\n executionPath: z.array(z.object({\n poolId: z.string(),\n amountIn: z.string(),\n amountOut: z.string(),\n priceImpact: z.string(),\n })),\n});\nexport type SlippageResult = z.infer<typeof SlippageResult>;\n\n/**\n * Liquidity depth at different price levels\n */\nexport const LiquidityDepth = z.object({\n chain: ChainId,\n inputAsset: AssetId,\n outputAsset: AssetId,\n currentPrice: z.string(),\n depth: z.array(z.object({\n priceLevel: z.string(), // Percentage from current price\n bidLiquidity: z.string(), // Liquidity available to buy\n askLiquidity: z.string(), // Liquidity available to sell\n })),\n spread: z.string(), // Bid-ask spread\n lastUpdated: z.number(),\n});\nexport type LiquidityDepth = z.infer<typeof LiquidityDepth>;\n","import {\n LiquidityPool,\n LiquiditySource,\n CrossChainLiquidity,\n SlippageResult,\n LiquidityDepth,\n} from './types.js';\nimport { ChainId, AssetId, ProtocolId } from '../routing/types.js';\n\n/**\n * Liquidity provider interface\n */\nexport interface ILiquidityProvider {\n chain: ChainId;\n protocol: ProtocolId;\n getPools(inputAsset: AssetId, outputAsset?: AssetId): Promise<LiquidityPool[]>;\n getPool(poolId: string): Promise<LiquidityPool | null>;\n}\n\n/**\n * Bridge liquidity provider interface\n */\nexport interface IBridgeProvider {\n bridge: ProtocolId;\n getLiquidity(\n sourceChain: ChainId,\n destinationChain: ChainId,\n asset: AssetId,\n ): Promise<CrossChainLiquidity['bridges'][0] | null>;\n}\n\n/**\n * Aggregator configuration\n */\nexport interface AggregatorConfig {\n cacheTtl?: number;\n maxPoolsPerSource?: number;\n minLiquidity?: string;\n}\n\n/**\n * Liquidity aggregator - combines liquidity from multiple sources\n */\nexport class LiquidityAggregator {\n private providers: Map<string, ILiquidityProvider> = new Map();\n private bridgeProviders: Map<string, IBridgeProvider> = new Map();\n private poolCache: Map<string, { pools: LiquidityPool[]; expiresAt: number }> = new Map();\n private config: Required<AggregatorConfig>;\n\n constructor(config: AggregatorConfig = {}) {\n this.config = {\n cacheTtl: config.cacheTtl ?? 30000,\n maxPoolsPerSource: config.maxPoolsPerSource ?? 10,\n minLiquidity: config.minLiquidity ?? '1000', // $1000 minimum\n };\n }\n\n /**\n * Register a liquidity provider\n */\n registerProvider(provider: ILiquidityProvider): void {\n const key = `${provider.chain}:${provider.protocol}`;\n this.providers.set(key, provider);\n }\n\n /**\n * Register a bridge provider\n */\n registerBridgeProvider(provider: IBridgeProvider): void {\n this.bridgeProviders.set(provider.bridge, provider);\n }\n\n /**\n * Get aggregated liquidity for a trading pair\n */\n async getLiquidity(\n chain: ChainId,\n inputAsset: AssetId,\n outputAsset: AssetId,\n ): Promise<LiquiditySource> {\n const cacheKey = `${chain}:${inputAsset}:${outputAsset}`;\n const cached = this.poolCache.get(cacheKey);\n\n if (cached && cached.expiresAt > Date.now()) {\n return this.aggregatePools(chain, inputAsset, outputAsset, cached.pools);\n }\n\n // Fetch from all providers for this chain\n const pools: LiquidityPool[] = [];\n\n for (const [key, provider] of this.providers) {\n if (!key.startsWith(chain)) continue;\n\n try {\n const providerPools = await provider.getPools(inputAsset, outputAsset);\n pools.push(...providerPools.slice(0, this.config.maxPoolsPerSource));\n } catch {\n // Skip failed providers\n continue;\n }\n }\n\n // Cache results\n this.poolCache.set(cacheKey, {\n pools,\n expiresAt: Date.now() + this.config.cacheTtl,\n });\n\n return this.aggregatePools(chain, inputAsset, outputAsset, pools);\n }\n\n /**\n * Get cross-chain liquidity\n */\n async getCrossChainLiquidity(\n sourceChain: ChainId,\n destinationChain: ChainId,\n asset: AssetId,\n ): Promise<CrossChainLiquidity> {\n const bridges: CrossChainLiquidity['bridges'] = [];\n\n for (const [, provider] of this.bridgeProviders) {\n try {\n const liquidity = await provider.getLiquidity(\n sourceChain,\n destinationChain,\n asset,\n );\n if (liquidity) {\n bridges.push(liquidity);\n }\n } catch {\n // Skip failed bridges\n continue;\n }\n }\n\n // Sort by fee (lowest first)\n bridges.sort((a, b) => parseFloat(a.fee) - parseFloat(b.fee));\n\n const totalLiquidity = bridges.reduce(\n (sum, b) => sum + BigInt(b.liquidity),\n 0n,\n ).toString();\n\n return {\n sourceChain,\n destinationChain,\n asset,\n bridges,\n totalLiquidity,\n bestBridge: bridges[0]?.bridge ?? '',\n lastUpdated: Date.now(),\n };\n }\n\n /**\n * Calculate slippage for a trade\n */\n calculateSlippage(\n source: LiquiditySource,\n inputAmount: string,\n slippageTolerance: string,\n ): SlippageResult {\n const inputBigInt = BigInt(inputAmount);\n const tolerance = parseFloat(slippageTolerance) / 100;\n\n // Sort pools by price (best first)\n const sortedPools = [...source.pools].sort(\n (a, b) => parseFloat(a.price) - parseFloat(b.price),\n );\n\n // Split order across pools for optimal execution\n let remainingInput = inputBigInt;\n let totalOutput = 0n;\n const executionPath: SlippageResult['executionPath'] = [];\n\n for (const pool of sortedPools) {\n if (remainingInput <= 0n) break;\n\n const poolMaxIn = BigInt(pool.maxAmountIn);\n const amountIn = remainingInput < poolMaxIn ? remainingInput : poolMaxIn;\n\n // Calculate output with price impact\n const baseOutput = amountIn * BigInt(Math.floor(parseFloat(pool.price) * 1e6)) / 1000000n;\n const priceImpact = this.calculatePoolPriceImpact(amountIn, BigInt(pool.liquidity));\n const adjustedOutput = baseOutput * BigInt(10000 - Math.floor(priceImpact * 100)) / 10000n;\n\n totalOutput += adjustedOutput;\n remainingInput -= amountIn;\n\n executionPath.push({\n poolId: pool.poolId,\n amountIn: amountIn.toString(),\n amountOut: adjustedOutput.toString(),\n priceImpact: priceImpact.toFixed(4),\n });\n }\n\n const effectivePrice = inputBigInt > 0n\n ? (Number(totalOutput) / Number(inputBigInt)).toFixed(8)\n : '0';\n\n const totalPriceImpact = this.calculateTotalPriceImpact(\n inputAmount,\n totalOutput.toString(),\n source.bestPrice,\n );\n\n const minOutput = BigInt(Math.floor(Number(totalOutput) * (1 - tolerance)));\n\n return {\n inputAmount,\n outputAmount: totalOutput.toString(),\n priceImpact: totalPriceImpact.toFixed(4),\n effectivePrice,\n slippageTolerance,\n minOutputAmount: minOutput.toString(),\n executionPath,\n };\n }\n\n /**\n * Get liquidity depth at different price levels\n */\n async getLiquidityDepth(\n chain: ChainId,\n inputAsset: AssetId,\n outputAsset: AssetId,\n levels: number[] = [0.5, 1, 2, 5, 10], // Percentage from current price\n ): Promise<LiquidityDepth> {\n const source = await this.getLiquidity(chain, inputAsset, outputAsset);\n\n const currentPrice = source.bestPrice;\n const depth: LiquidityDepth['depth'] = [];\n\n for (const level of levels) {\n // Calculate liquidity available at this price level\n const bidLiquidity = this.calculateLiquidityAtLevel(source.pools, level, 'bid');\n const askLiquidity = this.calculateLiquidityAtLevel(source.pools, level, 'ask');\n\n depth.push({\n priceLevel: level.toString(),\n bidLiquidity,\n askLiquidity,\n });\n }\n\n // Calculate spread\n const bestBid = source.pools.length > 0\n ? Math.max(...source.pools.map(p => parseFloat(p.price)))\n : 0;\n const bestAsk = source.pools.length > 0\n ? Math.min(...source.pools.map(p => parseFloat(p.price)))\n : 0;\n const spread = bestBid > 0 ? ((bestAsk - bestBid) / bestBid * 100).toFixed(4) : '0';\n\n return {\n chain,\n inputAsset,\n outputAsset,\n currentPrice,\n depth,\n spread,\n lastUpdated: Date.now(),\n };\n }\n\n /**\n * Find best route across multiple pools\n */\n findBestRoute(\n source: LiquiditySource,\n inputAmount: string,\n maxPools: number = 3,\n ): { pools: string[]; expectedOutput: string; priceImpact: string } {\n const inputBigInt = BigInt(inputAmount);\n\n // Simple greedy approach: use pools with best price first\n const sortedPools = [...source.pools]\n .filter(p => BigInt(p.liquidity) > BigInt(this.config.minLiquidity))\n .sort((a, b) => parseFloat(b.price) - parseFloat(a.price))\n .slice(0, maxPools);\n\n if (sortedPools.length === 0) {\n return { pools: [], expectedOutput: '0', priceImpact: '100' };\n }\n\n // Split across pools proportionally to liquidity\n const totalLiquidity = sortedPools.reduce(\n (sum, p) => sum + BigInt(p.liquidity),\n 0n,\n );\n\n let totalOutput = 0n;\n const pools: string[] = [];\n\n for (const pool of sortedPools) {\n const proportion = BigInt(pool.liquidity) * 10000n / totalLiquidity;\n const poolInput = inputBigInt * proportion / 10000n;\n\n if (poolInput > 0n) {\n const priceImpact = this.calculatePoolPriceImpact(poolInput, BigInt(pool.liquidity));\n const output = poolInput * BigInt(Math.floor(parseFloat(pool.price) * 1e6)) / 1000000n;\n const adjustedOutput = output * BigInt(10000 - Math.floor(priceImpact * 100)) / 10000n;\n\n totalOutput += adjustedOutput;\n pools.push(pool.poolId);\n }\n }\n\n const priceImpact = this.calculateTotalPriceImpact(\n inputAmount,\n totalOutput.toString(),\n source.bestPrice,\n );\n\n return {\n pools,\n expectedOutput: totalOutput.toString(),\n priceImpact: priceImpact.toFixed(4),\n };\n }\n\n /**\n * Clear cache\n */\n clearCache(): void {\n this.poolCache.clear();\n }\n\n private aggregatePools(\n chain: ChainId,\n inputAsset: AssetId,\n outputAsset: AssetId,\n pools: LiquidityPool[],\n ): LiquiditySource {\n // Filter relevant pools\n const relevantPools = pools.filter(p =>\n p.tokens.some(t => t.asset === inputAsset) &&\n p.tokens.some(t => t.asset === outputAsset),\n );\n\n if (relevantPools.length === 0) {\n return {\n chain,\n inputAsset,\n outputAsset,\n totalLiquidity: '0',\n bestPrice: '0',\n averagePrice: '0',\n pools: [],\n lastUpdated: Date.now(),\n };\n }\n\n // Calculate metrics for each pool\n const poolData = relevantPools.map(pool => {\n const inputToken = pool.tokens.find(t => t.asset === inputAsset);\n const outputToken = pool.tokens.find(t => t.asset === outputAsset);\n\n if (!inputToken || !outputToken) {\n return null;\n }\n\n const inputReserve = BigInt(inputToken.reserve);\n const outputReserve = BigInt(outputToken.reserve);\n\n // Calculate price (output per input)\n const price = inputReserve > 0n\n ? (Number(outputReserve) / Number(inputReserve)).toFixed(8)\n : '0';\n\n // Calculate max amounts\n const maxAmountIn = (inputReserve / 10n).toString(); // 10% of reserve\n const maxAmountOut = (outputReserve / 10n).toString();\n\n // Price impact for 1% of liquidity\n const onePercent = inputReserve / 100n;\n const priceImpact1Percent = this.calculatePoolPriceImpact(onePercent, inputReserve);\n\n return {\n poolId: pool.id,\n protocol: pool.protocol,\n liquidity: pool.tvl,\n price,\n maxAmountIn,\n maxAmountOut,\n priceImpact1Percent: priceImpact1Percent.toFixed(4),\n };\n }).filter((p): p is NonNullable<typeof p> => p !== null);\n\n // Calculate aggregated metrics\n const totalLiquidity = poolData.reduce(\n (sum, p) => sum + BigInt(p.liquidity),\n 0n,\n );\n\n const prices = poolData.map(p => parseFloat(p.price)).filter(p => p > 0);\n const bestPrice = prices.length > 0 ? Math.max(...prices).toFixed(8) : '0';\n const averagePrice = prices.length > 0\n ? (prices.reduce((a, b) => a + b, 0) / prices.length).toFixed(8)\n : '0';\n\n return {\n chain,\n inputAsset,\n outputAsset,\n totalLiquidity: totalLiquidity.toString(),\n bestPrice,\n averagePrice,\n pools: poolData,\n lastUpdated: Date.now(),\n };\n }\n\n private calculatePoolPriceImpact(amount: bigint, liquidity: bigint): number {\n if (liquidity <= 0n) return 100;\n\n // Simplified constant product impact: impact = amount / (liquidity + amount)\n const impact = Number(amount * 10000n / (liquidity + amount)) / 100;\n return Math.min(impact, 100);\n }\n\n private calculateTotalPriceImpact(\n inputAmount: string,\n outputAmount: string,\n bestPrice: string,\n ): number {\n const expectedOutput = parseFloat(inputAmount) * parseFloat(bestPrice);\n const actualOutput = parseFloat(outputAmount);\n\n if (expectedOutput <= 0) return 100;\n\n const impact = ((expectedOutput - actualOutput) / expectedOutput) * 100;\n return Math.max(0, Math.min(impact, 100));\n }\n\n private calculateLiquidityAtLevel(\n pools: LiquiditySource['pools'],\n level: number,\n _side: 'bid' | 'ask',\n ): string {\n // Sum liquidity from pools that can provide at this price level\n const adjustedLiquidity = pools.reduce((sum, pool) => {\n const impact1Pct = parseFloat(pool.priceImpact1Percent);\n\n // Rough estimate: if 1% of liquidity causes X% impact,\n // then at Y% price level, we can use Y/X * 1% of liquidity\n const usablePortion = level / (impact1Pct || 0.01);\n const usableLiquidity = BigInt(pool.liquidity) * BigInt(Math.min(Math.floor(usablePortion * 100), 10000)) / 10000n;\n\n return sum + usableLiquidity;\n }, 0n);\n\n return adjustedLiquidity.toString();\n }\n}\n\n/**\n * Mock liquidity provider for testing\n */\nexport class MockLiquidityProvider implements ILiquidityProvider {\n chain: ChainId;\n protocol: ProtocolId;\n private pools: LiquidityPool[] = [];\n\n constructor(chain: ChainId, protocol: ProtocolId) {\n this.chain = chain;\n this.protocol = protocol;\n }\n\n addPool(pool: LiquidityPool): void {\n this.pools.push(pool);\n }\n\n async getPools(inputAsset: AssetId, outputAsset?: AssetId): Promise<LiquidityPool[]> {\n return this.pools.filter(p =>\n p.tokens.some(t => t.asset === inputAsset) &&\n (!outputAsset || p.tokens.some(t => t.asset === outputAsset)),\n );\n }\n\n async getPool(poolId: string): Promise<LiquidityPool | null> {\n return this.pools.find(p => p.id === poolId) ?? null;\n }\n}\n\n/**\n * Mock bridge provider for testing\n */\nexport class MockBridgeProvider implements IBridgeProvider {\n bridge: ProtocolId;\n private liquidity: Map<string, CrossChainLiquidity['bridges'][0]> = new Map();\n\n constructor(bridge: ProtocolId) {\n this.bridge = bridge;\n }\n\n setLiquidity(\n sourceChain: ChainId,\n destinationChain: ChainId,\n asset: AssetId,\n data: CrossChainLiquidity['bridges'][0],\n ): void {\n const key = `${sourceChain}:${destinationChain}:${asset}`;\n this.liquidity.set(key, data);\n }\n\n async getLiquidity(\n sourceChain: ChainId,\n destinationChain: ChainId,\n asset: AssetId,\n ): Promise<CrossChainLiquidity['bridges'][0] | null> {\n const key = `${sourceChain}:${destinationChain}:${asset}`;\n return this.liquidity.get(key) ?? null;\n }\n}\n"],"mappings":"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","names":["priceImpact"]}