use atproto_identity::key::{KeyData, to_public}; use atproto_identity::model::Document; use axum::Json; use axum::Router; use axum::http::StatusCode; use axum::response::IntoResponse; use axum::routing::get; pub fn document(did: &str, signing_key: &KeyData) -> anyhow::Result { let public = to_public(signing_key)?; Ok(Document::builder() .context(vec![ "https://www.w3.org/ns/did/v1".to_string(), "https://w3id.org/security/multikey/v1".to_string(), ]) .id(did) .add_multikey(format!("{did}#atproto"), did, public.to_string()) .build()?) } pub fn router(did: String, signing_key: KeyData) -> Router { Router::new().route( "/.well-known/did.json", get(move || async move { match document(&did, &signing_key) { Ok(doc) => Json(doc).into_response(), Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), } }), ) } #[cfg(test)] mod tests { use super::*; use atproto_identity::key::{KeyType, generate_key}; #[test] fn document_shape() { let key = generate_key(KeyType::K256Private).unwrap(); let value = serde_json::to_value(document("did:web:h.zkwid.test", &key).unwrap()).unwrap(); let method = &value["verificationMethod"][0]; assert_eq!(value["id"], "did:web:h.zkwid.test"); assert_eq!(method["id"], "did:web:h.zkwid.test#atproto"); assert_eq!(method["type"], "Multikey"); assert_eq!(method["controller"], "did:web:h.zkwid.test"); assert!( method["publicKeyMultibase"] .as_str() .unwrap() .starts_with('z') ); } }