use std::{ collections::HashMap, path::{Path, PathBuf}, }; pub use keyfork_mnemonic_util::Mnemonic; pub use tower::ServiceBuilder; #[cfg(feature = "tracing")] use tracing::debug; pub mod error; pub mod middleware; pub mod server; pub mod service; pub use error::KeyforkdError; pub use server::UnixServer; pub use service::Keyforkd; pub async fn start_and_run_server_on( mnemonic: Mnemonic, socket_path: &Path, ) -> Result<(), Box> { let service = ServiceBuilder::new() .layer(middleware::BincodeLayer::new()) .service(Keyforkd::new(mnemonic)); let mut server = match UnixServer::bind(socket_path) { Ok(s) => s, Err(e) => { #[cfg(feature = "tracing")] debug!(%e, "Encountered error attempting to bind socket: {}", socket_path.display()); return Err(e.into()); } }; match server.run(service).await { Ok(_) => (), Err(e) => { #[cfg(feature = "tracing")] debug!(%e, "Encountered error while running"); } } Ok(()) } pub async fn start_and_run_server(mnemonic: Mnemonic) -> Result<(), Box> { let runtime_vars = std::env::vars() .filter(|(key, _)| ["XDG_RUNTIME_DIR", "KEYFORKD_SOCKET_PATH"].contains(&key.as_str())) .collect::>(); let mut runtime_path: PathBuf; #[allow(clippy::single_match_else)] match runtime_vars.get("KEYFORKD_SOCKET_PATH") { Some(occupied) => { runtime_path = PathBuf::from(occupied); } None => { runtime_path = PathBuf::from( runtime_vars .get("XDG_RUNTIME_DIR") .ok_or(KeyforkdError::NoSocketPath)?, ); runtime_path.push("keyforkd"); #[cfg(feature = "tracing")] debug!("ensuring directory exists: {}", runtime_path.display()); if !runtime_path.is_dir() { tokio::fs::create_dir(&runtime_path).await?; } runtime_path.push("keyforkd.sock"); } } #[cfg(feature = "tracing")] debug!( "binding UNIX socket in runtime dir: {}", runtime_path.display() ); start_and_run_server_on(mnemonic, &runtime_path).await }