import { getExplorerApiBase } from './blockscout' export interface RouteMatrixLeg { protocol?: string executor?: string poolAddress?: string } export interface RouteMatrixRoute { routeId: string status?: string label?: string routeType?: string fromChainId?: number toChainId?: number tokenInSymbol?: string tokenOutSymbol?: string assetSymbol?: string hopCount?: number aggregatorFamilies?: string[] notes?: string[] reason?: string tokenInSymbols?: string[] legs?: RouteMatrixLeg[] } export interface RouteMatrixCounts { liveSwapRoutes?: number liveBridgeRoutes?: number blockedOrPlannedRoutes?: number filteredLiveRoutes?: number } export interface RouteMatrixResponse { generatedAt?: string updated?: string version?: string homeChainId?: number liveRoutes?: RouteMatrixRoute[] blockedOrPlannedRoutes?: RouteMatrixRoute[] counts?: RouteMatrixCounts } export interface ExplorerNetwork { chainIdDecimal?: number chainName?: string shortName?: string } export interface NetworksResponse { version?: string source?: string lastModified?: string networks?: ExplorerNetwork[] } export interface MissionControlLiquidityPool { address: string dex?: string token0?: { symbol?: string } token1?: { symbol?: string } tvl?: number } export interface MissionControlLiquidityPoolsResponse { count?: number pools?: MissionControlLiquidityPool[] } interface RawMissionControlLiquidityPoolsResponse { count?: number pools?: MissionControlLiquidityPool[] data?: { count?: number pools?: MissionControlLiquidityPool[] } } export function normalizeMissionControlLiquidityPools( raw: RawMissionControlLiquidityPoolsResponse | null | undefined ): MissionControlLiquidityPoolsResponse { if (!raw) { return { count: 0, pools: [] } } const nested = raw.data const pools = Array.isArray(raw.pools) ? raw.pools : Array.isArray(nested?.pools) ? nested.pools : [] const count = typeof raw.count === 'number' ? raw.count : typeof nested?.count === 'number' ? nested.count : pools.length return { count, pools } } const tokenAggregationBase = `${getExplorerApiBase()}/token-aggregation/api/v1` const missionControlBase = `${getExplorerApiBase()}/explorer-api/v1/mission-control` async function fetchJson(url: string): Promise { const response = await fetch(url) if (!response.ok) { throw new Error(`HTTP ${response.status}`) } return (await response.json()) as T } export const routesApi = { getNetworks: async (): Promise => fetchJson(`${tokenAggregationBase}/networks`), getRouteMatrix: async (): Promise => fetchJson(`${tokenAggregationBase}/routes/matrix?includeNonLive=true`), getTokenPools: async (tokenAddress: string): Promise => normalizeMissionControlLiquidityPools( await fetchJson( `${missionControlBase}/liquidity/token/${tokenAddress}/pools` ) ), }