use serde_json::{Value, json};
use dpp_crypto::keystore::KeyStore;
pub fn build_did_document(store: &KeyStore, base_url: &str, key_id: &str) -> anyhow::Result<Value> {
if !store.has_key(key_id) {
store.generate_key(key_id)?;
}
let current = store
.public_key(key_id)
.ok_or_else(|| anyhow::anyhow!("no key found for {key_id}"))?;
let hostname = base_url
.trim_start_matches("https://")
.trim_start_matches("http://");
let did = format!("did:web:{}", hostname.replace(':', "%3A"));
let primary_vm_id = format!("{did}#key-1");
let mut verification_methods = vec![json!({
"id": primary_vm_id,
"type": "JsonWebKey2020",
"controller": did,
"publicKeyJwk": current
.algorithm
.public_key_jwk(&hex::decode(¤t.verifying_key_hex)?)
})];
let archived: Vec<_> = store
.archived_public_keys(key_id)
.into_iter()
.filter(|k| !k.revoked)
.collect();
for (idx, archived_key) in archived.iter().enumerate() {
let vm_id = format!("{did}#key-{}", idx + 2);
verification_methods.push(json!({
"id": vm_id,
"type": "JsonWebKey2020",
"controller": did,
"publicKeyJwk": archived_key
.algorithm
.public_key_jwk(&hex::decode(&archived_key.verifying_key_hex)?)
}));
}
let assertion_methods: Vec<String> = verification_methods
.iter()
.filter_map(|vm| vm["id"].as_str().map(String::from))
.collect();
let doc = json!({
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/jws-2020/v1"
],
"id": did,
"verificationMethod": verification_methods,
"authentication": [primary_vm_id],
"assertionMethod": assertion_methods
});
Ok(doc)
}