Also fix casing of VerificationMethodMap, and comply with weirdness of W3C-
endorsed multibase encoding.
4TPKSHZTLLJJZ2JUKCQIOKY3KM2VKN5DWZAUMOWMVZCX5MNZZHPAC /// Create a JSON [DID document] from a [DID] and a public key.////// [DID document]: https://www.w3.org/TR/did-core/#dfn-did-documents/// [did-web]: https://w3c-ccg.github.io/did-method-web/pub fn create(did: DID, key: ed25519::PublicKey) -> serde_json::Value {let key = {let mut buf = [0u8; ed25519::PublicKey::BYTES + 2];buf[0] = 0xed;buf[1] = 0x01;buf[2..].copy_from_slice(&*key);multibase::encode(multibase::Base::Base58Btc, buf)};json!({"@context": ["https://www.w3.org/ns/did/v1","https://w3id.org/security/suites/ed25519-2020/v1",],"id": *did,"verificationMethod": [{"id": format!("{did}#key-0"),"type": "Ed25519VerificationKey2020","controller": *did,"publicKeyMultiBase": key,}],})}
}}impl TryFrom<Url> for DID {type Error = anyhow::Error;fn try_from(url: Url) -> Result<Self, Self::Error> {let host = match url.host().context("missing host")? {url::Host::Domain(host) => host,url::Host::Ipv4(_) | url::Host::Ipv6(_) => {bail!("Host must be a domain name, not IP address")},};let port = url.port().map(|p| format!("%3A{p}")).unwrap_or_default();let mut path: Vec<&str> = url.path().split('/').filter(|s| !s.is_empty()).collect();if let Some(&"did.json") = path.last() {path.pop();}if let Some(&".well-known") = path.last() {path.pop();}let path = path.join(":");Ok(Self(format!("did:web:{host}{port}:{path}")))
if bytes.len() != 34 {fn exp() -> impl serde::de::Expected {"34"}return Err(serde::de::Error::invalid_length(bytes.len(), &exp()));}if bytes[0] != 0xed {return Err(serde::de::Error::custom(format!("Expected first byte of multikey to be 0xed, got {}",bytes[0])));}if bytes[1] != 0x01 {return Err(serde::de::Error::custom(format!("Expected second byte of multikey to 0x01, got {}",bytes[1])));}
eprintln!("{doc:#?}");
#[test]fn create_valid() {let did = DID::parse("did:web:eagain.io:kim").unwrap();let key = ed25519::KeyPair::generate().pk;let doc = super::create(did, key);let js = serde_json::to_string_pretty(&doc).unwrap();let doc: PartialDocument = serde_json::from_str(&js).unwrap_or_else(|e| {panic!("failed to decode\n{js}:\n{e:#?}");});assert!(doc.validate().is_some());