1use crate::{
2 error::Error,
3 keys::{KeyPair, VerificationKey},
4};
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use wasm_bindgen::prelude::wasm_bindgen;
8#[cfg(feature = "wasm")]
9use wasm_bindgen::JsValue;
10
11pub const DID_CONTEXT_URL: &str = "https://www.w3.org/ns/did/v1";
12
13#[derive(Serialize, Deserialize, Clone)]
14#[wasm_bindgen]
15pub struct DidDocument {
16 #[serde(rename = "@context")]
17 #[wasm_bindgen(skip)]
18 pub context: Vec<Value>,
19 #[wasm_bindgen(skip)]
20 pub id: String,
21 #[wasm_bindgen(skip)]
22 #[serde(rename = "verificationMethod")]
23 pub verification_method: Option<Vec<KeyPair>>,
24 #[wasm_bindgen(skip)]
25 pub authentication: Option<Vec<String>>,
26 #[wasm_bindgen(skip)]
27 #[serde(rename = "assertionMethod")]
28 pub assertion_method: Option<Vec<String>>,
29 #[wasm_bindgen(skip)]
30 #[serde(rename = "capabilityDelegation")]
31 pub capability_delegation: Option<Vec<String>>,
32 #[wasm_bindgen(skip)]
33 #[serde(rename = "capabilityInvocation")]
34 pub capability_invocation: Option<Vec<String>>,
35 #[serde(rename = "keyAgreement")]
36 #[wasm_bindgen(skip)]
37 pub key_agreement: Option<Vec<KeyPair>>,
38 #[wasm_bindgen(skip)]
39 pub services: Option<Vec<Service>>,
40}
41
42pub trait KeyPairToDidDocument {
43 fn key_pair_to_did_doc(
44 key_pair: &Box<dyn VerificationKey>,
45 fingerprint: &str,
46 ) -> Result<DidDocument, Error>;
47}
48
49#[wasm_bindgen]
50impl DidDocument {
51 #[wasm_bindgen(js_name = "getKeyPair")]
52 pub fn get_key_pair(&self, key_id_fragment: &str) -> Result<KeyPair, Error> {
53 let key_id = format!("{}#{}", self.id, key_id_fragment);
54
55 if self
56 .verification_method
57 .as_ref()
58 .is_some_and(|val| val.len() > 0)
59 || self.key_agreement.as_ref().is_some_and(|val| val.len() > 0)
60 {
61 let verification_method = self.verification_method.as_ref().unwrap();
62 let key_agreement = self.key_agreement.as_ref().unwrap();
63
64 let public_key: KeyPair;
65 if verification_method.len() > 0
66 && verification_method[0]
67 .id
68 .as_ref()
69 .is_some_and(|val| val.eq(&key_id))
70 {
71 public_key = verification_method[0].clone();
72 } else {
73 public_key = key_agreement[0].clone();
74 }
75 return Ok(public_key);
76 }
77
78 return Err(Error::new("No key pair could be found."));
79 }
80
81 #[cfg(feature = "wasm")]
82 #[wasm_bindgen(js_name = "toObject")]
83 pub fn to_object(&self) -> Result<JsValue, serde_wasm_bindgen::Error> {
84 serde_wasm_bindgen::to_value(self)
85 }
86
87 #[cfg(feature = "wasm")]
88 #[wasm_bindgen(getter)]
89 pub fn context(&self) -> JsValue {
90 use wasm_bindgen::JsValue;
91
92 match serde_wasm_bindgen::to_value(&self.context) {
93 Ok(val) => val,
94 Err(_error) => JsValue::NULL,
95 }
96 }
97
98 #[cfg(feature = "wasm")]
99 #[wasm_bindgen(setter)]
100 pub fn set_context(&mut self, context: JsValue) {
101 self.context = match serde_wasm_bindgen::from_value(context) {
102 Ok(val) => val,
103 Err(_error) => Vec::new(),
104 };
105 }
106
107 #[cfg(feature = "wasm")]
108 #[wasm_bindgen(getter)]
109 pub fn id(&self) -> String {
110 self.id.clone()
111 }
112
113 #[cfg(feature = "wasm")]
114 #[wasm_bindgen(setter)]
115 pub fn set_id(&mut self, id: String) {
116 self.id = id;
117 }
118
119 #[cfg(feature = "wasm")]
120 #[wasm_bindgen(setter, js_name = "verificationMethod")]
121 pub fn set_verification_method(&mut self, verification_method: Option<Vec<KeyPair>>) {
122 self.verification_method = verification_method;
123 }
124
125 #[cfg(feature = "wasm")]
126 #[wasm_bindgen(getter, js_name = "verificationMethod")]
127 pub fn verification_method(&self) -> Option<Vec<KeyPair>> {
128 self.verification_method.clone()
129 }
130
131 #[cfg(feature = "wasm")]
132 #[wasm_bindgen(setter)]
133 pub fn set_authentication(&mut self, authentication: Option<Vec<String>>) {
134 self.authentication = authentication;
135 }
136
137 #[cfg(feature = "wasm")]
138 #[wasm_bindgen(getter)]
139 pub fn authentication(&self) -> Option<Vec<String>> {
140 self.authentication.clone()
141 }
142
143 #[cfg(feature = "wasm")]
144 #[wasm_bindgen(setter, js_name = "assertionMethod")]
145 pub fn set_assertion_method(&mut self, assertion_method: Option<Vec<String>>) {
146 self.assertion_method = assertion_method;
147 }
148
149 #[cfg(feature = "wasm")]
150 #[wasm_bindgen(getter, js_name = "assertionMethod")]
151 pub fn assertion_method(&self) -> Option<Vec<String>> {
152 self.assertion_method.clone()
153 }
154
155 #[cfg(feature = "wasm")]
156 #[wasm_bindgen(setter, js_name = "capabilityDelegation")]
157 pub fn set_capability_delegation(&mut self, capability_delegation: Option<Vec<String>>) {
158 self.capability_delegation = capability_delegation;
159 }
160
161 #[cfg(feature = "wasm")]
162 #[wasm_bindgen(getter, js_name = "capabilityDelegation")]
163 pub fn capability_delegation(&self) -> Option<Vec<String>> {
164 self.capability_delegation.clone()
165 }
166
167 #[cfg(feature = "wasm")]
168 #[wasm_bindgen(setter, js_name = "capabilityInvocation")]
169 pub fn set_capability_invocation(&mut self, capability_invocation: Option<Vec<String>>) {
170 self.capability_invocation = capability_invocation;
171 }
172
173 #[cfg(feature = "wasm")]
174 #[wasm_bindgen(getter, js_name = "capabilityInvocation")]
175 pub fn capability_invocation(&self) -> Option<Vec<String>> {
176 self.capability_invocation.clone()
177 }
178
179 #[cfg(feature = "wasm")]
180 #[wasm_bindgen(setter, js_name = "keyAgreement")]
181 pub fn set_key_agreement(&mut self, key_agreement: Option<Vec<KeyPair>>) {
182 self.key_agreement = key_agreement;
183 }
184
185 #[cfg(feature = "wasm")]
186 #[wasm_bindgen(getter, js_name = "keyAgreement")]
187 pub fn key_agreement(&self) -> Option<Vec<KeyPair>> {
188 self.key_agreement.clone()
189 }
190
191 #[cfg(feature = "wasm")]
192 pub fn set_services(&mut self, services: Option<Vec<Service>>) {
193 self.services = services;
194 }
195
196 #[cfg(feature = "wasm")]
197 pub fn services(&self) -> Option<Vec<Service>> {
198 self.services.clone()
199 }
200}
201
202#[derive(Serialize, Deserialize, Debug, Clone)]
203#[wasm_bindgen]
204pub struct Service {
205 #[wasm_bindgen(skip)]
206 pub id: String,
207 #[serde(rename = "type")]
208 #[wasm_bindgen(skip)]
209 pub _type: String,
210 #[wasm_bindgen(skip)]
211 pub service_endpoint: Value,
212}
213
214#[wasm_bindgen]
215impl Service {
216 #[cfg(feature = "wasm")]
217 #[wasm_bindgen(setter)]
218 pub fn set_id(&mut self, id: String) {
219 self.id = id;
220 }
221
222 #[cfg(feature = "wasm")]
223 #[wasm_bindgen(getter)]
224 pub fn id(&self) -> String {
225 self.id.clone()
226 }
227
228 #[cfg(feature = "wasm")]
229 #[wasm_bindgen(setter, js_name = "type")]
230 pub fn set_type(&mut self, _type: String) {
231 self._type = _type;
232 }
233
234 #[cfg(feature = "wasm")]
235 #[wasm_bindgen(getter, js_name = "type")]
236 pub fn _type(&self) -> String {
237 self._type.clone()
238 }
239
240 #[cfg(feature = "wasm")]
241 #[wasm_bindgen(setter, js_name = "serviceEndpoint")]
242 pub fn set_service_endpoint(
243 &mut self,
244 service_endpoint: JsValue,
245 ) -> Result<(), serde_wasm_bindgen::Error> {
246 self.service_endpoint = match serde_wasm_bindgen::from_value(service_endpoint) {
247 Ok(val) => val,
248 Err(error) => return Err(error),
249 };
250
251 Ok(())
252 }
253
254 #[cfg(feature = "wasm")]
255 #[wasm_bindgen(getter, js_name = "serviceEndpoint")]
256 pub fn service_endpoint(&self) -> Result<JsValue, serde_wasm_bindgen::Error> {
257 match serde_wasm_bindgen::to_value(&self.service_endpoint) {
258 Err(error) => Err(error),
259 Ok(val) => Ok(val),
260 }
261 }
262}