use atproto_identity::key::{KeyType, generate_key, identify_key}; use std::path::PathBuf; use tracing_subscriber::EnvFilter; fn env(name: &str) -> Option { std::env::var(name).ok().filter(|value| !value.is_empty()) } fn did_web(base_url: &str) -> anyhow::Result { let url = reqwest::Url::parse(base_url)?; let host = url .host_str() .ok_or_else(|| anyhow::anyhow!("ZKWID_BASE_URL has no host"))?; Ok(match url.port() { Some(port) => format!("did:web:{host}%3A{port}"), None => format!("did:web:{host}"), }) } #[tokio::main] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt() .with_env_filter( EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")), ) .init(); let base_url = env("ZKWID_BASE_URL").unwrap_or_else(|| "https://zkwid.test".into()); let base_url = base_url.trim_end_matches('/').to_string(); let did = match env("ZKWID_DID") { Some(did) => did, None => did_web(&base_url)?, }; let signing_key = match env("ZKWID_SIGNING_KEY") { Some(key) => identify_key(&key)?, None => { let key = generate_key(KeyType::P256Private)?; println!("ZKWID_SIGNING_KEY={key}"); key } }; let config = zkwid_n::Config { base_url, did, signing_key, db_path: PathBuf::from(env("ZKWID_DB").unwrap_or_else(|| "zkwid.db".into())), plc_url: env("ZKWID_PLC_URL").unwrap_or_else(|| "https://plc.directory".into()), }; let bind = env("ZKWID_BIND").unwrap_or_else(|| "127.0.0.1:8080".into()); let state = zkwid_n::state(config).await?; let listener = tokio::net::TcpListener::bind(&bind).await?; tracing::info!(bind = %bind, did = %state.config.did, "zkwid-n listening"); zkwid_n::serve(state, listener).await }