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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use serde::{ser::SerializeMap, Deserialize, Serialize, Serializer};

#[derive(Debug, Clone, Copy)]
pub struct Config {
    pub use_jose_format: bool,
    pub serialize_secrets: bool,
}

pub const CONFIG_JOSE_PUBLIC: Config = Config {
    use_jose_format: true,
    serialize_secrets: false,
};
pub const CONFIG_JOSE_PRIVATE: Config = Config {
    use_jose_format: true,
    serialize_secrets: true,
};
pub const CONFIG_LD_PUBLIC: Config = Config {
    use_jose_format: false,
    serialize_secrets: false,
};
pub const CONFIG_LD_PRIVATE: Config = Config {
    use_jose_format: false,
    serialize_secrets: true,
};

#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Document {
    #[serde(rename = "@context")]
    pub context: String,
    pub id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub assertion_method: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub authentication: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub capability_delegation: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub capability_invocation: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub key_agreement: Option<Vec<String>>,
    pub verification_method: Vec<VerificationMethod>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct IetfJsonPatch {
    #[serde(rename = "ietf-json-patch")]
    pub value: serde_json::Value,
}

#[derive(Debug, Clone, PartialEq, Default, Deserialize)]
pub struct VerificationMethod {
    pub id: String,
    #[serde(rename = "type")]
    pub key_type: String,
    pub controller: String,
    #[serde(alias = "publicKeyBase58")]
    #[serde(alias = "publicKeyMultibase")]
    #[serde(alias = "publicKeyJwk")]
    pub public_key: Option<KeyFormat>,
    #[serde(alias = "privateKeyBase58")]
    #[serde(alias = "privateKeyMultibase")]
    #[serde(alias = "privateKeyJwk")]
    pub private_key: Option<KeyFormat>,
}

#[derive(Serialize, Debug, Clone, PartialEq, Deserialize)]
#[serde(untagged)]
pub enum KeyFormat {
    Base58(String),
    Multibase(Vec<u8>),
    JWK(JWK),
}

#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, Default)]
pub struct JWK {
    #[serde(rename = "kid", skip_serializing_if = "Option::is_none")]
    pub key_id: Option<String>,
    #[serde(rename = "kty")]
    pub key_type: String,
    #[serde(rename = "crv")]
    pub curve: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub x: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub y: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub d: Option<String>,
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct JWSHeader {
    #[serde(rename = "alg")]
    pub algorithm: String,
    #[serde(rename = "kid", default, skip_serializing_if = "Option::is_none")]
    pub key_id: Option<String>,
}

#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub struct JWS {
    pub header: JWSHeader,
    pub payload: Vec<u8>,
    pub signature: Vec<u8>,
}

impl Serialize for VerificationMethod {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(None)?;

        map.serialize_entry("id", &self.id)?;
        map.serialize_entry("type", &self.key_type)?;
        map.serialize_entry("controller", &self.controller)?;

        match &self.public_key {
            Some(pk) => match pk {
                KeyFormat::Base58(pk) => map.serialize_entry("publicKeyBase58", &pk)?,
                KeyFormat::Multibase(pk) => map.serialize_entry("publicKeyMultibase", &pk)?,
                KeyFormat::JWK(pk) => map.serialize_entry("publicKeyJwk", &pk)?,
            },
            None => {}
        }
        match &self.private_key {
            Some(pk) => match pk {
                KeyFormat::Base58(pk) => map.serialize_entry("privateKeyBase58", &pk)?,
                KeyFormat::Multibase(pk) => map.serialize_entry("privateKeyMultibase", &pk)?,
                KeyFormat::JWK(pk) => map.serialize_entry("privateKeyJwk", &pk)?,
            },
            None => {}
        }

        map.end()
    }
}

impl Default for Config {
    fn default() -> Self {
        CONFIG_LD_PRIVATE
    }
}

#[cfg(test)]
pub mod tests {
    use super::KeyFormat;

    #[test]
    fn test_key_format() {
        let key = KeyFormat::Base58("key-1".to_string());
        let serialized = serde_json::to_string_pretty(&key).unwrap();

        println!("{}", serialized)
    }
}