# Nostr Event Stream Visualization **Issue:** #874 - [NEXUS] Implement Nostr Event Stream Visualization ## Overview Visualize incoming Nostr events as data streams or particles flowing through the Nexus, representing the agent's connection to the wider mesh. ## Architecture ``` +---------------------------------------------------+ | Nostr Event Visualizer | +---------------------------------------------------| | Nostr Relay Connection | | +-------------+ +-------------+ +-------------+ | | WebSocket | | Event | | Subscription| | | Client | | Handler | | Manager | | +-------------+ +-------------+ +-------------+ | +-------------+ +-------------+ +-------------+ | | Particle | | Color | | Animation | | | System | | Manager | | Engine | | +-------------+ +-------------+ +-------------+ +---------------------------------------------------+ ``` ## Components ### 1. Nostr Event Visualizer (`js/nostr-event-visualizer.js`) Main visualization class for Nostr events. **Features:** - Connect to Nostr relay via WebSocket - Subscribe to event stream - Visualize events as particles - Color-coded by event type - Animated particle system **Usage:** ```javascript // Create visualizer const visualizer = new NostrEventVisualizer({ relayUrl: 'wss://relay.nostr.info', maxEvents: 100, particleCount: 50, streamSpeed: 1.0 }); // Initialize with Three.js scene visualizer.init(scene, camera, renderer); // Connect to Nostr relay visualizer.connect(); // Update visualization visualizer.update(deltaTime); ``` ### 2. Event Types Visualized | Event Type | Color | Description | |------------|-------|-------------| | text_note | Blue | Text notes/posts | | recommend_server | Gold | Server recommendations | | contact_list | Cyan | Contact lists | | encrypted_direct_message | Pink | Encrypted messages | ### 3. Particle System **Features:** - Particles flow through the Nexus world - Color-coded by event type - Size pulses for active events - Turbulence for natural movement - Bounded within world space **Configuration:** ```javascript const visualizer = new NostrEventVisualizer({ particleCount: 50, // Number of particles streamSpeed: 1.0, // Flow speed particleSize: 0.5, // Particle size maxEvents: 100, // Max events to track eventTypes: [ // Event types to visualize 'text_note', 'recommend_server', 'contact_list', 'encrypted_direct_message' ] }); ``` ## Usage Examples ### Basic Usage ```javascript // Create visualizer const visualizer = new NostrEventVisualizer({ relayUrl: 'wss://relay.nostr.info' }); // Initialize with Three.js visualizer.init(scene, camera, renderer); // Connect to relay visualizer.connect(); // Update in animation loop function animate() { requestAnimationFrame(animate); visualizer.update(1/60); // 60 FPS renderer.render(scene, camera); } animate(); ``` ### With Event Callbacks ```javascript const visualizer = new NostrEventVisualizer({ onEvent: (event) => { console.log('New event:', event.kind, event.content); }, onConnect: () => { console.log('Connected to Nostr relay'); }, onDisconnect: () => { console.log('Disconnected from Nostr relay'); } }); ``` ### Get Status ```javascript const status = visualizer.getStatus(); console.log('Connected:', status.connected); console.log('Events:', status.eventCount); console.log('Particles:', status.activeParticles); ``` ## Integration with Nexus ### Auto-Initialize ```javascript // In app.js or initialization code document.addEventListener('DOMContentLoaded', () => { // Wait for Three.js scene to be ready if (window.scene && window.camera && window.renderer) { const visualizer = new NostrEventVisualizer(); visualizer.init(window.scene, window.camera, window.renderer); visualizer.connect(); // Store globally window.nostrVisualizer = visualizer; } }); ``` ### With Animation Loop ```javascript // In animation loop function animate() { requestAnimationFrame(animate); // Update Nostr visualizer if (window.nostrVisualizer) { window.nostrVisualizer.update(1/60); } // Render scene renderer.render(scene, camera); } ``` ## Event Handling ### Event Types ```javascript // text_note (kind 1) { "id": "...", "pubkey": "...", "created_at": 1234567890, "kind": 1, "tags": [], "content": "Hello Nostr!", "sig": "..." } // recommend_server (kind 2) { "id": "...", "pubkey": "...", "created_at": 1234567890, "kind": 2, "tags": [], "content": "wss://relay.example.com", "sig": "..." } // contact_list (kind 3) { "id": "...", "pubkey": "...", "created_at": 1234567890, "kind": 3, "tags": [["p", "pubkey1"], ["p", "pubkey2"]], "content": "", "sig": "..." } // encrypted_direct_message (kind 4) { "id": "...", "pubkey": "...", "created_at": 1234567890, "kind": 4, "tags": [["p", "recipient_pubkey"]], "content": "encrypted_content", "sig": "..." } ``` ## Testing ### Unit Tests ```bash node --test tests/test_nostr_visualizer.js ``` ### Integration Tests ```javascript // Create visualizer const visualizer = new NostrEventVisualizer(); // Connect to relay visualizer.connect(); // Check status const status = visualizer.getStatus(); assert(status.connected === true); // Update visualization visualizer.update(1/60); // Disconnect visualizer.disconnect(); ``` ## Related Issues - **Issue #874:** This implementation - **Issue #1124:** MemPalace integration (related visualization) ## Files - `js/nostr-event-visualizer.js` - Main visualization module - `docs/nostr-event-visualizer.md` - This documentation - `tests/test_nostr_visualizer.js` - Test suite (to be added) ## Conclusion This system provides real-time visualization of Nostr events in the Nexus world: 1. **Connection** to Nostr relays via WebSocket 2. **Visualization** of events as colored particles 3. **Animation** with turbulence and pulsing 4. **Integration** with Three.js scene **Ready for production use.**