import { getExplorerApiBase } from './blockscout' export interface MissionControlRelaySummary { text: string tone: 'normal' | 'warning' | 'danger' items: MissionControlRelayItemSummary[] } export interface MissionControlRelayItemSummary { key: string label: string status: string text: string tone: 'normal' | 'warning' | 'danger' } export interface MissionControlRelaySnapshot { status?: string last_error?: { scope?: string message?: string message_id?: string target_bridge?: string token?: string available_amount?: string required_amount?: string shortfall?: string } monitoring?: { delivery_enabled?: boolean shedding?: boolean } service?: { profile?: string } source?: { chain_name?: string bridge_filter?: string } destination?: { chain_name?: string relay_bridge?: string relay_bridge_default?: string } queue?: { size?: number processed?: number failed?: number } last_source_poll?: { at?: string ok?: boolean logs_fetched?: number } } export interface MissionControlRelayProbe { ok?: boolean body?: MissionControlRelaySnapshot } export interface MissionControlRelayPayload { url_probe?: MissionControlRelayProbe file_snapshot?: MissionControlRelaySnapshot file_snapshot_error?: string } export interface MissionControlChainStatus { status?: string name?: string head_age_sec?: number latency_ms?: number block_number?: string } export interface MissionControlMode { kind?: string | null updated_at?: string | null age_seconds?: number | null reason?: string | null scope?: string | null source?: string | null confidence?: string | null provenance?: string | null } export interface MissionControlSubsystemStatus { status?: string | null updated_at?: string | null age_seconds?: number | null source?: string | null confidence?: string | null provenance?: string | null completeness?: string | null } export interface MissionControlBridgeStatusResponse { data?: { status?: string checked_at?: string freshness?: unknown sampling?: { stats_generated_at?: string | null rpc_probe_at?: string | null stats_window_seconds?: number | null issues?: Record | null } mode?: MissionControlMode subsystems?: Record chains?: Record ccip_relay?: MissionControlRelayPayload ccip_relays?: Record } } const missionControlRelayLabels: Record = { mainnet: 'Mainnet', mainnet_weth: 'Mainnet WETH', mainnet_cw: 'Mainnet cW', bsc: 'BSC', avax: 'Avalanche', avalanche: 'Avalanche', avax_cw: 'Avalanche cW', avax_to_138: 'Avalanche -> 138', } function getMissionControlStreamUrl(): string { return `${getExplorerApiBase()}/explorer-api/v1/mission-control/stream` } function getMissionControlBridgeStatusUrl(): string { return `${getExplorerApiBase()}/explorer-api/v1/track1/bridge/status` } function relativeAge(isoString?: string): string { if (!isoString) return '' const parsed = Date.parse(isoString) if (!Number.isFinite(parsed)) return '' const seconds = Math.max(0, Math.round((Date.now() - parsed) / 1000)) if (seconds < 60) return `${seconds}s ago` const minutes = Math.round(seconds / 60) if (minutes < 60) return `${minutes}m ago` const hours = Math.round(minutes / 60) return `${hours}h ago` } function describeRelayStatus(snapshot: MissionControlRelaySnapshot, status: string): string { if (snapshot.last_error?.scope === 'bridge_inventory') { return snapshot.queue?.size && snapshot.queue.size > 0 ? 'underfunded queued release' : 'underfunded release' } if (status === 'paused' && snapshot.monitoring?.delivery_enabled === false) { return snapshot.queue?.size && snapshot.queue.size > 0 ? 'delivery paused (queueing)' : 'delivery paused' } if (status === 'paused' && snapshot.monitoring?.shedding) { return 'paused (shedding)' } return status } export function summarizeMissionControlRelay( response: MissionControlBridgeStatusResponse | null | undefined ): MissionControlRelaySummary | null { const relays = getMissionControlRelays(response) if (!relays) return null const items = Object.entries(relays) .map(([key, relay]): MissionControlRelayItemSummary | null => { const label = getMissionControlRelayLabel(key) if (relay.url_probe && relay.url_probe.ok === false) { return { key, label, status: 'down', text: `${label}: probe failed`, tone: 'danger', } } if (relay.file_snapshot_error) { return { key, label, status: 'snapshot-error', text: `${label}: snapshot error`, tone: 'danger', } } const snapshot = relay.url_probe?.body || relay.file_snapshot if (!snapshot) { return { key, label, status: 'configured', text: `${label}: probe configured`, tone: 'normal', } } const status = String(snapshot.status || 'unknown').toLowerCase() const statusLabel = describeRelayStatus(snapshot, status) const destination = snapshot.destination?.chain_name const queueSize = snapshot.queue?.size const pollAge = relativeAge(snapshot.last_source_poll?.at) let text = `${label}: ${statusLabel}` if (destination) text += ` -> ${destination}` if (queueSize != null) text += ` · queue ${queueSize}` if (pollAge) text += ` · polled ${pollAge}` let tone: MissionControlRelaySummary['tone'] = 'normal' if (['paused', 'starting'].includes(status)) { tone = 'warning' } if (['degraded', 'stale', 'stopped', 'down'].includes(status)) { tone = 'danger' } return { key, label, status, text, tone } }) .filter((item): item is MissionControlRelayItemSummary => item !== null) if (items.length === 0) return null const tone: MissionControlRelaySummary['tone'] = items.some((item) => item.tone === 'danger') ? 'danger' : items.some((item) => item.tone === 'warning') ? 'warning' : 'normal' const text = items.length === 1 ? items[0].text : tone === 'normal' ? `${items.length} relay lanes operational` : `Relay lanes need attention` return { text, tone, items } } export function getMissionControlRelays( response: MissionControlBridgeStatusResponse | null | undefined ): Record | null { return response?.data?.ccip_relays && Object.keys(response.data.ccip_relays).length > 0 ? response.data.ccip_relays : response?.data?.ccip_relay ? { mainnet: response.data.ccip_relay } : null } export function getMissionControlRelayLabel(key: string): string { return missionControlRelayLabels[key] || key.toUpperCase() } export const missionControlApi = { getBridgeStatus: async (): Promise => { const response = await fetch(getMissionControlBridgeStatusUrl()) if (!response.ok) { throw new Error(`HTTP ${response.status}`) } return (await response.json()) as MissionControlBridgeStatusResponse }, subscribeBridgeStatus: ( onStatus: (status: MissionControlBridgeStatusResponse) => void, onError?: (error: unknown) => void ): (() => void) => { if (typeof window === 'undefined' || typeof window.EventSource === 'undefined') { onError?.(new Error('EventSource is not available in this environment')) return () => {} } const eventSource = new window.EventSource(getMissionControlStreamUrl()) const handleMessage = (event: MessageEvent) => { try { const payload = JSON.parse(event.data) as MissionControlBridgeStatusResponse onStatus(payload) } catch (error) { onError?.(error) } } eventSource.addEventListener('mission-control', handleMessage) eventSource.onmessage = handleMessage eventSource.onerror = () => { onError?.(new Error('Mission-control live stream connection lost')) } return () => { eventSource.removeEventListener('mission-control', handleMessage) eventSource.close() } }, }