use futures::{SinkExt, StreamExt}; use nym_client_websocket_requests::{requests::ClientRequest, responses::ServerResponse}; use nym_sphinx::addressing::clients::Recipient; use tokio::net::TcpStream; use tokio_tungstenite::{ connect_async, tungstenite::protocol::Message, MaybeTlsStream, WebSocketStream, }; // just helpers functions that work in this very particular context because we are sending to ourselves // and hence will always get a response back (i.e. the message we sent) async fn send_message_and_get_response( ws_stream: &mut WebSocketStream>, req: Vec, ) -> ServerResponse { ws_stream.send(Message::Binary(req)).await.unwrap(); let raw_message = ws_stream.next().await.unwrap().unwrap(); match raw_message { Message::Binary(bin_payload) => ServerResponse::deserialize(&bin_payload).unwrap(), _ => panic!("received an unexpected response type!"), } } async fn get_self_address(ws_stream: &mut WebSocketStream>) -> Recipient { let self_address_request = ClientRequest::SelfAddress.serialize(); let response = send_message_and_get_response(ws_stream, self_address_request).await; match response { ServerResponse::SelfAddress(recipient) => *recipient, _ => panic!("received an unexpected response!"), } } async fn send_file_with_reply() { todo!("reimplement surb usage here : )") // let uri = "ws://localhost:1977"; // let (mut ws_stream, _) = connect_async(uri).await.unwrap(); // // let recipient = get_self_address(&mut ws_stream).await; // println!("our full address is: {}", recipient); // // let read_data = std::fs::read("examples/dummy_file").unwrap(); // // let send_request = ClientRequest::Send { // recipient, // message: read_data, // with_reply_surb: true, // connection_id: Some(0), // }; // // println!("sending content of 'dummy_file' over the mix network..."); // let response = send_message_and_get_response(&mut ws_stream, send_request.serialize()).await; // // let received = match response { // ServerResponse::Received(received) => received, // _ => panic!("received an unexpected response!"), // }; // // println!("writing the file back to the disk!"); // std::fs::write("examples/received_file_withreply", received.message).unwrap(); // // let reply_message = b"hello from reply SURB! - thanks for sending me the file!".to_vec(); // let reply_request = ClientRequest::Reply { // message: reply_message.clone(), // reply_surb: received.reply_surb.unwrap(), // }; // // println!( // "sending {:?} (using reply SURB!) over the mix network...", // String::from_utf8(reply_message).unwrap() // ); // let response = send_message_and_get_response(&mut ws_stream, reply_request.serialize()).await; // let received = match response { // ServerResponse::Received(received) => received, // _ => panic!("received an unexpected response!"), // }; // // println!( // "received {:#?} from the mix network!", // String::from_utf8(received.message).unwrap() // ); } async fn send_file_without_reply() { let uri = "ws://localhost:1977"; let (mut ws_stream, _) = connect_async(uri).await.unwrap(); let recipient = get_self_address(&mut ws_stream).await; println!("our full address is: {recipient}"); let read_data = std::fs::read("examples/dummy_file").unwrap(); let send_request = ClientRequest::Send { recipient, message: read_data, connection_id: Some(0), }; println!("sending content of 'dummy_file' over the mix network..."); let response = send_message_and_get_response(&mut ws_stream, send_request.serialize()).await; let received = match response { ServerResponse::Received(received) => received, _ => panic!("received an unexpected response!"), }; println!("writing the file back to the disk!"); std::fs::write("examples/received_file_noreply", received.message).unwrap(); } #[tokio::main] async fn main() { println!("#############################"); println!("Example without using replies"); send_file_without_reply().await; println!("\n\n#############################"); println!("Example using replies"); send_file_with_reply().await; }