use std::collections::HashMap; use hero_websocket_server::ServerBuilder; #[tokio::main] async fn main() -> Result<(), Box> { env_logger::init(); // Define circles and their members let mut circles = HashMap::new(); // Circle "alpha" with two members circles.insert("alpha".to_string(), vec![ "04a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab".to_string(), "04b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd".to_string(), ]); // Circle "beta" with one member circles.insert("beta".to_string(), vec![ "04c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef".to_string(), ]); // Circle "gamma" with three members circles.insert("gamma".to_string(), vec![ "04d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01".to_string(), "04e5f6789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123".to_string(), "04f6789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef012345".to_string(), ]); // Build server with circle-based authentication let server = ServerBuilder::new() .host("127.0.0.1") .port(8080) .redis_url("redis://localhost:6379") .with_auth() .circles(circles) .build()?; println!("Starting WebSocket server with circle-based authentication..."); println!("Available circles:"); for (circle_id, members) in &server.circles { println!(" Circle '{}' has {} members:", circle_id, members.len()); for (i, member) in members.iter().enumerate() { println!(" Member {}: {}...{}", i + 1, &member[..10], &member[member.len()-10..]); } } println!("\nTo connect to a specific circle, use URLs like:"); println!(" ws://127.0.0.1:8080/ws/alpha (for circle 'alpha')"); println!(" ws://127.0.0.1:8080/ws/beta (for circle 'beta')"); println!(" ws://127.0.0.1:8080/ws/gamma (for circle 'gamma')"); println!("\nAuthentication flow:"); println!("1. Connect to WebSocket URL for specific circle"); println!("2. Call 'fetch_nonce' method to get a nonce"); println!("3. Sign the nonce with your private key"); println!("4. Call 'authenticate' with your public key and signature"); println!("5. Server will verify signature AND check circle membership"); println!("6. Only members of the target circle will be authenticated"); // Start the server let (task_handle, server_handle) = server.spawn_circle_server()?; println!("\nServer started! Press Ctrl+C to stop."); // Wait for the server to complete match task_handle.await { Ok(Ok(())) => println!("Server stopped successfully"), Ok(Err(e)) => eprintln!("Server error: {}", e), Err(e) => eprintln!("Task join error: {}", e), } Ok(()) }