//! `knot-static init`: establishes the knot's persistent admin/build state. use std::sync::Arc; use anyhow::Context as _; use knot_runtime::OsEntropy; use knot_secrets::SealedStore; use knot_types::ActorId; use crate::config::ValidatedConfig; pub async fn run(config: Arc) -> anyhow::Result<()> { config .layout()? .bootstrap_meta(&config.knot_did) .context("bootstrap meta-repo")?; let master_key = crate::identity::load_master_key(&config)?; if let Some(parent) = config.sealed_key_file.parent() { std::fs::create_dir_all(parent).with_context(|| { format!( "create parent directory for sealed key file: {}", parent.display() ) })?; } if !config.sealed_key_file.exists() { tracing::info!( path = %config.sealed_key_file.display(), "sealing new knot signing identity" ); } let secrets = SealedStore::open(&config.sealed_key_file, &master_key, Box::new(OsEntropy)) .context("open sealed key store")?; let knot_signing_key = secrets .ensure(&config.knot_did) .context("seal knot signing key")?; let knot_actor = ActorId::from_secp256k1(knot_signing_key.as_bytes()); // validate static knot DID document generation (packet ยง7 step 6). let _did_doc = crate::identity::knot_did_document_from_key(&config, &knot_signing_key) .context("generate static knot DID document")?; let cas_dir = config.output_root.join("cas/sha256"); std::fs::create_dir_all(&cas_dir) .with_context(|| format!("create CAS directory {}", cas_dir.display()))?; let generations_dir = config.output_root.join("generations"); std::fs::create_dir_all(&generations_dir) .with_context(|| format!("create generations directory {}", generations_dir.display()))?; println!("knot DID: {}", config.knot_did); println!("public key (multikey): {knot_actor}"); Ok(()) }