Skyfall
Quantum-Safe P2P Communication System
[!WARNING]
This library is currently tested only minimally. Documentation and stability is a work-in-progress.
libskyfall implements an abstraction layer over iroh, adding quantum-safe encryption, extended peer information gathering, serializable connection states, and REST-like routing support.
Basic Usage
This example creates two peers, one sending data to the other (source and sink respectively.)
Source:
use std::{error::Error, time::Duration};
use libskyfall::Client;
use tokio::time::sleep;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut client = Client::builder().build().await?;
client.initialize().await?;
let sink_peer = source.trust_peer(source.connect_to(<NODE ID>).await?)?;
source.share_info(sink_peer.clone()).await?;
let channel = source.send_command::<()>(sink_peer.clone(), "CORE.ECHO/echo", None, true).await?.1.unwrap();
let mut name_generator = names::Generator::default();
loop {
channel.send(name_generator.next().unwrap().as_bytes().to_vec()).await?;
sleep(Duration::from_millis(100)).await;
}
}
Sink:
use std::error::Error;
use libskyfall::{ handlers::EchoHandler, Client, ClientEvent };
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let mut client = Client::builder().build().await?.with_handler(EchoHandler);
client.initialize().await?;
let _events = tokio::spawn((|| {
let events = client.client_events().clone();
let client = client.clone();
async move {
loop {
if let Ok(evt) = events.recv().await {
println!("EVENT: {evt:?}");
if let ClientEvent::Connected { peer } = evt {
let _ = client.trust_peer(peer.clone());
let _ = client.share_info(peer).await;
}
}
}
}
})());
loop {}
}
Custom Route Handlers
Custom handlers can be created using an included proc-macro. The following example is the implementation of the EchoHandler from the previous examples.
use libskyfall::{handler, route, handlers::Request, Channel};
pub struct Echo;
#[handler(id = "core.echo", about = "Simple testing protocol")]
impl Echo {
#[route(path = "/echo", channel = channel, request = request)]
pub async fn echo(&self, request: Request, channel: Channel) -> anyhow::Result<()> {
println!("Got echo request from {:?}", request.peer);
loop {
match channel.recv().await {
Ok(data) => println!("RECV: {}", String::from_utf8(data).unwrap()),
Err(e) => eprintln!("RECVERR: {e:?}")
}
}
}
}