use client::{ShadowNodeBuilder, ShadowApi};
use shadow_core::{PeerId, PeerInfo};
use crypto::Keypair;
use bytes::Bytes;
#[tokio::main]
async fn main() -> shadow_core::error::Result<()> {
tracing_subscriber::fmt::init();
println!("=== Shadow Network DHT Demo ===\n");
println!("1. Creating two Shadow Network nodes...");
let node1_keypair = Keypair::generate();
let node1 = ShadowNodeBuilder::new()
.with_keypair(node1_keypair)
.with_bucket_size(20)
.build()?;
let node2_keypair = Keypair::generate();
let node2 = ShadowNodeBuilder::new()
.with_keypair(node2_keypair)
.with_bucket_size(20)
.build()?;
let mut api1 = ShadowApi::new(node1);
let mut api2 = ShadowApi::new(node2);
println!(" Node 1 ID: {:?}", api1.peer_id());
println!(" Node 2 ID: {:?}", api2.peer_id());
println!("\n2. Starting nodes and discovering NAT type...");
api1.start().await?;
api2.start().await?;
println!(" Nodes started");
println!("\n3. Initial node statistics:");
let stats1 = api1.stats();
let stats2 = api2.stats();
println!(" Node 1: {} peers, {} values stored", stats1.peers, stats1.stored);
println!(" Node 2: {} peers, {} values stored", stats2.peers, stats2.stored);
println!("\n4. Connecting nodes...");
let node2_peer_info = PeerInfo::new(
api2.peer_id(),
vec!["127.0.0.1:9001".to_string()],
api2.peer_id().as_bytes().clone(),
api2.peer_id().as_bytes().clone(),
);
api1.add_peer(node2_peer_info).await?;
println!(" Node 2 added to Node 1's peer list");
println!("\n5. Storing data in DHT...");
let key1 = [1u8; 32];
let data1 = Bytes::from("Secret data stored in distributed hash table!");
api1.store(key1, data1.clone()).await?;
println!(" Stored {} bytes with key {:?}...{:?}",
data1.len(), &key1[..4], &key1[28..]);
println!("\n6. Retrieving data from DHT...");
if let Some(retrieved) = api1.retrieve(&key1).await {
println!(" Retrieved: {:?}", String::from_utf8_lossy(&retrieved));
if retrieved == data1 {
println!(" Data integrity verified");
}
} else {
println!(" Data not found");
}
println!("\n7. Storing multiple values...");
for i in 0..5 {
let mut key = [0u8; 32];
key[0] = i;
let data = Bytes::from(format!("Value number {}", i));
api1.store(key, data).await?;
}
println!(" Stored 5 additional values");
println!("\n8. Updated statistics:");
let stats1_updated = api1.stats();
println!(" Node 1: {} values stored ({}MB storage used)",
stats1_updated.stored, stats1_updated.storage_mb);
println!("\n9. Demonstrating steganographic file transfer API...");
let secret_file = b"This is confidential data that will be hidden in an image";
println!(" Preparing {} bytes for steganographic transfer", secret_file.len());
println!(" (Note: Requires cover image in production use)");
println!("\n10. Cryptographic features:");
println!(" • Each node has unique Ed25519 signing key");
println!(" • X25519 key exchange for session encryption");
println!(" • ChaCha20-Poly1305 AEAD for message encryption");
println!(" • BLAKE3 hashing for content addressing");
println!("\n11. Shutting down nodes...");
api1.stop().await?;
api2.stop().await?;
println!(" Nodes stopped");
println!("\n=== Demo Complete ===");
println!("\nKey Features Demonstrated:");
println!("• Peer-to-peer node creation and management");
println!("• Kademlia DHT for distributed storage");
println!("• NAT type discovery via STUN");
println!("• High-level API for easy integration");
println!("• Cryptographic identity system");
println!("\nNext Steps:");
println!("• Add actual P2P transport (libp2p/QUIC)");
println!("• Implement DHT replication");
println!("• Add real-time messaging");
println!("• Enable steganographic data transfer");
Ok(())
}