use phantom_protocol::api::{PhantomListener, PhantomSession, TcpSessionTransport};
use phantom_protocol::crypto::hybrid_sign::HybridVerifyingKey;
use std::time::Duration;
use tokio::net::TcpStream;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
let listener = PhantomListener::bind("127.0.0.1:0".to_string()).await?;
let server_addr: std::net::SocketAddr = listener.local_addr().parse()?;
let server_key_bytes = listener.verifying_key_bytes();
let expected_server_key = HybridVerifyingKey::from_bytes(&server_key_bytes)?;
println!("▶ server listening on {}", server_addr);
println!(
"▶ server verifying_key ({} bytes) shared with client out-of-band",
server_key_bytes.len(),
);
let server_handle = tokio::spawn(async move {
let session = listener.accept().await.expect("accept failed").session();
println!("▶ server: accepted connection from {}", session.peer_addr());
let request = session.recv().await.expect("server recv failed");
println!(
"▶ server: got decrypted request ({} bytes): {:?}",
request.len(),
String::from_utf8_lossy(&request),
);
let reply = b"hello, post-quantum world".to_vec();
session.send(reply).await.expect("server send failed");
tokio::time::sleep(Duration::from_millis(100)).await;
let _ = session.disconnect().await;
});
let stream = TcpStream::connect(server_addr).await?;
let transport = TcpSessionTransport::new(stream);
let client_session = PhantomSession::connect_with_transport(
&server_addr.to_string(),
transport,
expected_server_key,
);
println!("▶ client: started handshake (pinned server key required)");
tokio::time::sleep(Duration::from_millis(500)).await;
let request = b"ping from a pinned client".to_vec();
client_session.send(request).await?;
println!("▶ client: sent encrypted request");
let reply = client_session.recv().await?;
println!(
"▶ client: got decrypted reply ({} bytes): {:?}",
reply.len(),
String::from_utf8_lossy(&reply),
);
server_handle.await?;
client_session.disconnect().await?;
println!("▶ demo complete");
Ok(())
}