import { AnkFlag } from 'pkg/sdk_client'; import Services from './services/service'; import { messageValidator } from './services/message-validator'; import { secureLogger } from './services/secure-logger'; let ws: WebSocket; const messageQueue: string[] = []; export async function initWebsocket(url: string) { ws = new WebSocket(url); if (ws !== null) { ws.onopen = async (_event) => { console.log('WebSocket connection established'); while (messageQueue.length > 0) { const message = messageQueue.shift(); if (message) { ws.send(message); } } }; // Listen for messages ws.onmessage = event => { const msgData = event.data; (async () => { if (typeof msgData === 'string') { try { // Valider le message avant traitement console.log('🔍 DEBUG: Raw WebSocket message:', msgData); const validation = messageValidator.validateWebSocketMessage(msgData); console.log('🔍 DEBUG: Validation result:', validation); if (!validation.isValid) { console.warn('⚠️ Invalid WebSocket message received:', { errors: validation.errors, messagePreview: msgData.substring(0, 100) }); console.log('🔍 DEBUG: Full validation errors:', validation.errors); secureLogger.warn('Invalid WebSocket message received', { component: 'WebSocket', operation: 'message_validation', errors: validation.errors, messagePreview: msgData.substring(0, 100) // Log first 100 chars for debugging }); return; } const parsedMessage = validation.sanitizedData!; const services = await Services.getInstance(); secureLogger.debug('Processing WebSocket message', { component: 'WebSocket', operation: 'message_processing', flag: parsedMessage.flag }); switch (parsedMessage.flag) { case 'Handshake': await services.handleHandshakeMsg(url, parsedMessage.content); break; case 'NewTx': await services.parseNewTx(parsedMessage.content); break; case 'Cipher': await services.parseCipher(parsedMessage.content); break; case 'Commit': // Basically if we see this it means we have an error await services.handleCommitError(parsedMessage.content); break; default: secureLogger.warn('Unknown WebSocket message flag', { component: 'WebSocket', operation: 'message_processing', flag: parsedMessage.flag }); } } catch (error) { secureLogger.error('Failed to process WebSocket message', error as Error, { component: 'WebSocket', operation: 'message_processing' }); } } else { secureLogger.warn('Received non-string WebSocket message', { component: 'WebSocket', operation: 'message_validation', messageType: typeof msgData }); } })(); }; // Listen for possible errors ws.onerror = (_event) => { secureLogger.error('WebSocket error occurred', new Error('WebSocket error'), { component: 'WebSocket', operation: 'connection_error' }); }; // Listen for when the connection is closed ws.onclose = event => { secureLogger.info('WebSocket connection closed', { component: 'WebSocket', operation: 'connection_closed', code: event.code, reason: event.reason }); }; } } // Method to send messages export function sendMessage(flag: AnkFlag, message: string): void { if (ws.readyState === WebSocket.OPEN) { const networkMessage = { flag: flag, content: message, }; console.log('Sending message of type:', flag); ws.send(JSON.stringify(networkMessage)); } else { console.error('WebSocket is not open. ReadyState:', ws.readyState); messageQueue.push(message); } } export function getUrl(): string { return ws.url; } // Method to close the WebSocket connection export function close(): void { ws.close(); }