use base64::Engine;
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 b64 = base64::engine::general_purpose::URL_SAFE_NO_PAD;
let primary_vm_id = format!("{did}#key-1");
let primary_pub_b64 = b64.encode(hex::decode(¤t.verifying_key_hex)?);
let mut verification_methods = vec![json!({
"id": primary_vm_id,
"type": "JsonWebKey2020",
"controller": did,
"publicKeyJwk": {
"kty": "OKP",
"crv": dpp_crypto::jws::algorithm::ED25519_CRV,
"x": primary_pub_b64
}
})];
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);
let pub_b64 = b64.encode(hex::decode(&archived_key.verifying_key_hex)?);
verification_methods.push(json!({
"id": vm_id,
"type": "JsonWebKey2020",
"controller": did,
"publicKeyJwk": {
"kty": "OKP",
"crv": dpp_crypto::jws::algorithm::ED25519_CRV,
"x": pub_b64
}
}));
}
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)
}