did_utils/methods/key/
resolver.rs1use async_trait::async_trait;
2
3use crate::{
4 ldmodel::Context,
5 methods::{errors::DIDResolutionError, traits::DIDResolver},
6};
7
8use crate::methods::resolution::{DIDResolutionMetadata, DIDResolutionOptions, MediaType, ResolutionOutput};
9
10use crate::methods::DidKey;
11
12#[async_trait]
13impl DIDResolver for DidKey {
14 async fn resolve(&self, did: &str, _options: &DIDResolutionOptions) -> ResolutionOutput {
24 let context = Context::SingleString(String::from("https://w3id.org/did-resolution/v1"));
25
26 match self.expand(did) {
27 Ok(diddoc) => ResolutionOutput {
28 context,
29 did_document: Some(diddoc),
30 did_resolution_metadata: Some(DIDResolutionMetadata {
31 error: None,
32 content_type: Some(MediaType::DidLdJson.to_string()),
33 additional_properties: None,
34 }),
35 did_document_metadata: None,
36 additional_properties: None,
37 },
38 Err(err) => ResolutionOutput {
39 context,
40 did_document: None,
41 did_resolution_metadata: Some(DIDResolutionMetadata {
42 error: Some(if !did.starts_with("did:key:") {
43 DIDResolutionError::MethodNotSupported
44 } else {
45 err
46 }),
47 content_type: None,
48 additional_properties: None,
49 }),
50 did_document_metadata: None,
51 additional_properties: None,
52 },
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60 use crate::{crypto::PublicKeyFormat, methods::resolution::DereferencingOptions};
61 use serde_json::Value;
62
63 #[async_std::test]
64 async fn test_did_key_resolution_with_encryption_derivation() {
65 let did_method = DidKey::new_full(true, PublicKeyFormat::default());
66
67 let did = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK";
68 let expected: Value = serde_json::from_str(
69 r#"{
70 "@context": "https://w3id.org/did-resolution/v1",
71 "didDocument": {
72 "@context": [
73 "https://www.w3.org/ns/did/v1",
74 "https://w3id.org/security/suites/ed25519-2020/v1",
75 "https://w3id.org/security/suites/x25519-2020/v1"
76 ],
77 "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
78 "verificationMethod": [
79 {
80 "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
81 "type": "Ed25519VerificationKey2020",
82 "controller": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
83 "publicKeyMultibase": "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"
84 },
85 {
86 "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p",
87 "type": "X25519KeyAgreementKey2020",
88 "controller": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
89 "publicKeyMultibase": "z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p"
90 }
91 ],
92 "authentication": ["did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"],
93 "assertionMethod": ["did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"],
94 "capabilityDelegation": ["did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"],
95 "capabilityInvocation": ["did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK"],
96 "keyAgreement": ["did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p"]
97 },
98 "didResolutionMetadata": {
99 "contentType": "application/did+ld+json"
100 },
101 "didDocumentMetadata": null
102 }"#,
103 )
104 .unwrap();
105
106 let output = did_method.resolve(did, &DIDResolutionOptions::default()).await;
107
108 assert_eq!(
109 json_canon::to_string(&output).unwrap(), json_canon::to_string(&expected).unwrap(), );
112 }
113
114 #[async_std::test]
115 async fn test_did_key_resolution_fails_as_expected() {
116 let did_method = DidKey::default();
117
118 let did = "did:key:Z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK";
119 let expected: Value = serde_json::from_str(
120 r#"{
121 "@context": "https://w3id.org/did-resolution/v1",
122 "didDocument": null,
123 "didResolutionMetadata": {
124 "error": "invalidDid"
125 },
126 "didDocumentMetadata": null
127 }"#,
128 )
129 .unwrap();
130
131 let output = did_method.resolve(did, &DIDResolutionOptions::default()).await;
132
133 assert_eq!(
134 json_canon::to_string(&output).unwrap(), json_canon::to_string(&expected).unwrap(), );
137 }
138
139 #[async_std::test]
140 async fn test_dereferencing_did_key_url() {
141 let did_method = DidKey::new_full(true, PublicKeyFormat::default());
142
143 let did_url = "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p";
144 let expected: Value = serde_json::from_str(
145 r#"{
146 "@context": "https://w3id.org/did-resolution/v1",
147 "content": {
148 "id": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p",
149 "type": "X25519KeyAgreementKey2020",
150 "controller": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
151 "publicKeyMultibase": "z6LSj72tK8brWgZja8NLRwPigth2T9QRiG1uH9oKZuKjdh9p"
152 },
153 "dereferencingMetadata": {
154 "contentType": "application/json"
155 },
156 "contentMetadata": null
157 }"#,
158 )
159 .unwrap();
160
161 let output = did_method.dereference(did_url, &DereferencingOptions::default()).await;
162
163 assert_eq!(
164 json_canon::to_string(&output).unwrap(), json_canon::to_string(&expected).unwrap(), );
167 }
168}