//! Basic usage example for sigsocket_client //! //! This example demonstrates how to: //! 1. Create a sigsocket client //! 2. Set up a sign request handler //! 3. Connect to a sigsocket server //! 4. Handle incoming signature requests //! //! This example only runs on native (non-WASM) targets. #[cfg(not(target_arch = "wasm32"))] use sigsocket_client::{SigSocketClient, SignRequest, SignResponse, SignRequestHandler, Result, SigSocketError}; #[cfg(not(target_arch = "wasm32"))] /// Example sign request handler /// /// In a real application, this would: /// - Present the request to the user /// - Get user approval /// - Use a secure signing method (hardware wallet, etc.) /// - Return the signature struct ExampleSignHandler; #[cfg(not(target_arch = "wasm32"))] impl SignRequestHandler for ExampleSignHandler { fn handle_sign_request(&self, request: &SignRequest) -> Result> { println!("šŸ“ Received sign request:"); println!(" ID: {}", request.id); println!(" Message (base64): {}", request.message); // Decode the message to show what we're signing match request.message_bytes() { Ok(message_bytes) => { println!(" Message (hex): {}", hex::encode(&message_bytes)); println!(" Message (text): {}", String::from_utf8_lossy(&message_bytes)); } Err(e) => { println!(" āš ļø Failed to decode message: {}", e); return Err(SigSocketError::Base64(e.to_string())); } } // In a real implementation, you would: // 1. Show this to the user // 2. Get user approval // 3. Sign the message using a secure method println!("šŸ¤” Would you like to sign this message? (This is a simulation)"); println!("āœ… Auto-approving for demo purposes..."); // Simulate signing - in reality, this would be a real signature let fake_signature = format!("fake_signature_for_{}", request.id); Ok(fake_signature.into_bytes()) } } #[cfg(not(target_arch = "wasm32"))] #[tokio::main] async fn main() -> Result<()> { // Initialize logging env_logger::init(); println!("šŸš€ SigSocket Client Example"); println!("============================"); // Example public key (in a real app, this would be your actual public key) let public_key = hex::decode("02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388") .expect("Invalid public key hex"); println!("šŸ”‘ Public key: {}", hex::encode(&public_key)); // Create the client let mut client = SigSocketClient::new("ws://localhost:8080/ws", public_key)?; println!("šŸ“” Created client for: {}", client.url()); // Set up the sign request handler client.set_sign_handler(ExampleSignHandler); println!("āœ… Sign request handler configured"); // Connect to the server println!("šŸ”Œ Connecting to sigsocket server..."); match client.connect().await { Ok(()) => { println!("āœ… Connected successfully!"); println!("šŸ“Š Connection state: {:?}", client.state()); } Err(e) => { println!("āŒ Failed to connect: {}", e); println!("šŸ’” Make sure the sigsocket server is running on localhost:8080"); return Err(e); } } // Keep the connection alive and handle requests println!("šŸ‘‚ Listening for signature requests..."); println!(" (Press Ctrl+C to exit)"); // In a real application, you might want to: // - Handle reconnection // - Provide a UI for user interaction // - Manage multiple concurrent requests // - Store and manage signatures // For this example, we'll just wait tokio::signal::ctrl_c().await.expect("Failed to listen for ctrl-c"); println!("\nšŸ›‘ Shutting down..."); client.disconnect().await?; println!("āœ… Disconnected cleanly"); Ok(()) } // Example of how you might manually send a response (if needed) #[cfg(not(target_arch = "wasm32"))] #[allow(dead_code)] async fn send_manual_response(client: &SigSocketClient) -> Result<()> { let response = SignResponse::new( "example-request-id", "dGVzdCBtZXNzYWdl", // "test message" in base64 "ZmFrZV9zaWduYXR1cmU=", // "fake_signature" in base64 ); client.send_sign_response(&response).await?; println!("šŸ“¤ Sent manual response: {}", response.id); Ok(()) } // WASM main function (does nothing since this example is native-only) #[cfg(target_arch = "wasm32")] fn main() { // This example is designed for native use only }