use crate::{
any::*,
error::*,
requests,
util::{AsyncReadExtraExt, AsyncWriteExtraExt},
daemon_path
};
use std::path::Path;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::UnixStream
};
pub struct Daemon {
sock: UnixStream
}
impl Daemon {
pub async fn new(service: &str) -> Result<Self> {
Self::connect(service, &daemon_path()).await
}
pub async fn connect(service: &str, path: impl AsRef<Path>) -> Result<Self> {
let mut sock = UnixStream::connect(path).await?;
sock.write_str(service).await?;
Ok(Self {
sock
})
}
pub async fn authenticate(&mut self, name: &str, action: &str, nonce: &[u8]) -> Result<AnySignature> {
let sock = &mut self.sock;
sock.write_u8(requests::AUTHENTICATE).await?;
sock.write_str(name).await?;
sock.write_str(action).await?;
sock.write_b8(nonce).await?;
let status = sock.read_u8().await?;
Error::from_status(status)?;
let algo = sock.read_str().await?;
let bytes = sock.read_b16().await?;
AnySignature::new(&algo, &bytes)
}
pub async fn pubkey(&mut self, name: &str) -> Result<AnyPubkey> {
let sock = &mut self.sock;
sock.write_u8(requests::PUBKEY).await?;
sock.write_str(name).await?;
let status = sock.read_u8().await?;
Error::from_status(status)?;
let algo = sock.read_str().await?;
let bytes = sock.read_b16().await?;
AnyPubkey::new(&algo, &bytes)
}
pub async fn store(&mut self, name: &str, keypair: AnyKeypair) -> Result<()> {
let sock = &mut self.sock;
sock.write_u8(requests::STORE).await?;
sock.write_str(name).await?;
sock.write_str(keypair.name()).await?;
sock.write_b16(keypair.public_bytes()).await?;
sock.write_b16(keypair.secret_bytes()).await?;
let status = sock.read_u8().await?;
Error::from_status(status)
}
pub async fn generate(&mut self, name: &str) -> Result<AnyPubkey> {
let sock = &mut self.sock;
sock.write_u8(requests::GENERATE).await?;
sock.write_str(name).await?;
let status = sock.read_u8().await?;
Error::from_status(status)?;
let algo = sock.read_str().await?;
let bytes = sock.read_b16().await?;
AnyPubkey::new(&algo, &bytes)
}
}