xdid_method_key/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! [xdid](https://github.com/unavi-xyz/xdid) implementation of [did:key](https://w3c-ccg.github.io/did-method-key/).

use multibase::Base;
use parser::DidKeyParser;
use xdid_core::{
    did::{Did, MethodId, MethodName},
    did_url::DidUrl,
    document::{Document, VerificationMethod, VerificationMethodMap},
    Method, ResolutionError,
};

pub mod keys;
mod parser;

const NAME: &str = "key";

pub struct DidKey {
    key: Box<dyn keys::PublicKey>,
}

impl DidKey {
    pub fn new(key: impl keys::PublicKey + 'static) -> Self {
        Self { key: Box::new(key) }
    }

    pub fn to_did(&self) -> Did {
        let bytes = self.key.public_key();
        let code = self.key.codec().code();

        let mut inner = Vec::with_capacity(code.len() + bytes.len());
        inner.extend(code);
        inner.extend(bytes);

        let id = multibase::encode(Base::Base58Btc, inner);

        Did {
            method_name: MethodName(NAME.to_string()),
            method_id: MethodId(id),
        }
    }
}

pub struct MethodDidKey;

impl Method for MethodDidKey {
    fn method_name(&self) -> &'static str {
        NAME
    }

    fn resolve(
        &self,
        did: Did,
    ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Document, ResolutionError>>>>
    {
        debug_assert_eq!(did.method_name.0, self.method_name());

        Box::pin(async move {
            let parser = DidKeyParser::default();
            let did_key = parser
                .parse(&did)
                .map_err(|_| ResolutionError::InvalidDid)?;

            let did_url = DidUrl {
                did: did.clone(),
                path_abempty: String::new(),
                query: None,
                fragment: Some(did.method_id.0.clone()),
            };

            Ok(Document {
                id: did.clone(),
                also_known_as: None,
                controller: None,
                verification_method: Some(vec![VerificationMethodMap {
                    id: did_url.clone(),
                    typ: "JsonWebKey2020".to_string(),
                    controller: did.clone(),
                    public_key_jwk: Some(did_key.key.to_jwk()),
                    public_key_multibase: None,
                }]),
                authentication: Some(vec![VerificationMethod::URL(did_url.clone())]),
                assertion_method: Some(vec![VerificationMethod::URL(did_url.clone())]),
                capability_invocation: Some(vec![VerificationMethod::URL(did_url.clone())]),
                capability_delegation: Some(vec![VerificationMethod::URL(did_url)]),
                service: None,
                key_agreement: None,
            })
        })
    }
}