import WebSocket from 'ws'; export function manageFeeWebSocket( wsUrl: string, rollingWindowSize: number = 120, onMeanCalculated: (mean: number | null) => void, ): () => void { let ws: WebSocket | null = null; const recentValues: number[] = []; function calculateRollingMean(values: number[]): number | null { if (values.length === 0) return null; const sum = values.reduce((acc, val) => acc + val, 0); return Math.floor(sum / values.length); } function connectWebSocket(): void { try { ws = new WebSocket(wsUrl); ws.addEventListener('open', () => { try { // console.log('Fee WebSocket opened'); const message = JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'blockPrioritizationFeesSubscribe', interval: 30, }); ws?.send(message); } catch (error) { console.error('Error in open event:', error); onMeanCalculated(null); } }); ws.addEventListener('close', () => { // console.log('Fee WebSocket closed'); ws = null; // Attempt to reconnect after a delay setTimeout(connectWebSocket, 5000); }); ws.addEventListener('error', (error) => { console.log('Fee WebSocket error:', error); onMeanCalculated(-1); ws?.close(); }); ws.addEventListener( 'message', (event: { data: any; type: string; target: WebSocket }): void => { try { const parsedData = JSON.parse(event.data as string); const value = parsedData?.params?.result?.value.by_tx[15]; if (value !== undefined && typeof value === 'number') { recentValues.push(value); if (recentValues.length > rollingWindowSize) { recentValues.shift(); } const rollingMean = calculateRollingMean(recentValues); onMeanCalculated(rollingMean); } } catch (error) { console.error('Error processing message:', error); onMeanCalculated(-1); } }, ); } catch (error) { console.error('Error in connectWebSocket:', error); onMeanCalculated(-1); // Attempt to reconnect after a delay setTimeout(connectWebSocket, 5000); } } // Start the WebSocket connection connectWebSocket(); // Return a function to close the WebSocket return () => { if (ws) { try { ws.close(); } catch (error) { console.error('Error closing WebSocket:', error); } } }; }