hyperware_process_lib/
sign.rs

1use std::fmt;
2
3use serde::{
4    de::{self, MapAccess, Visitor},
5    ser::{SerializeMap, SerializeStruct},
6    Deserialize, Deserializer, Serialize, Serializer,
7};
8
9use crate::hyperware::process::sign::{
10    NetKeyVerifyRequest, Request as SignRequest, Response as SignResponse,
11};
12use crate::{last_blob, Address, Request};
13
14pub fn net_key_sign(message: Vec<u8>) -> anyhow::Result<Vec<u8>> {
15    let response = Request::to(("our", "sign", "sign", "sys"))
16        .body(serde_json::to_vec(&SignRequest::NetKeySign).unwrap())
17        .blob_bytes(message)
18        .send_and_await_response(10)??;
19
20    let SignResponse::NetKeySign = serde_json::from_slice(response.body())? else {
21        return Err(anyhow::anyhow!(
22            "unexpected response from sign:sign:sys: {}",
23            String::from_utf8(response.body().into()).unwrap_or_default(),
24        ));
25    };
26
27    Ok(last_blob().unwrap().bytes)
28}
29
30pub fn net_key_verify(
31    message: Vec<u8>,
32    signer: &Address,
33    signature: Vec<u8>,
34) -> anyhow::Result<bool> {
35    let response = Request::to(("our", "sign", "sign", "sys"))
36        .body(
37            serde_json::to_vec(&SignRequest::NetKeyVerify(NetKeyVerifyRequest {
38                node: signer.to_string(),
39                signature,
40            }))
41            .unwrap(),
42        )
43        .blob_bytes(message)
44        .send_and_await_response(10)??;
45
46    let SignResponse::NetKeyVerify(response) = serde_json::from_slice(response.body())? else {
47        return Err(anyhow::anyhow!(
48            "unexpected response from sign:sign:sys: {}",
49            String::from_utf8(response.body().into()).unwrap_or_default(),
50        ));
51    };
52
53    Ok(response)
54}
55
56impl Serialize for NetKeyVerifyRequest {
57    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
58    where
59        S: Serializer,
60    {
61        let mut state = serializer.serialize_struct("NetKeyVerifyRequest", 2)?;
62        state.serialize_field("node", &self.node)?;
63        state.serialize_field("signature", &self.signature)?;
64        state.end()
65    }
66}
67
68impl<'de> Deserialize<'de> for NetKeyVerifyRequest {
69    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
70    where
71        D: Deserializer<'de>,
72    {
73        #[derive(Deserialize)]
74        #[serde(field_identifier, rename_all = "snake_case")]
75        enum Field {
76            Node,
77            Signature,
78        }
79
80        struct NetKeyVerifyRequestVisitor;
81
82        impl<'de> Visitor<'de> for NetKeyVerifyRequestVisitor {
83            type Value = NetKeyVerifyRequest;
84
85            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
86                formatter.write_str("struct NetKeyVerifyRequest")
87            }
88
89            fn visit_map<V>(self, mut map: V) -> Result<NetKeyVerifyRequest, V::Error>
90            where
91                V: MapAccess<'de>,
92            {
93                let mut node = None;
94                let mut signature = None;
95
96                while let Some(key) = map.next_key()? {
97                    match key {
98                        Field::Node => {
99                            if node.is_some() {
100                                return Err(de::Error::duplicate_field("node"));
101                            }
102                            node = Some(map.next_value()?);
103                        }
104                        Field::Signature => {
105                            if signature.is_some() {
106                                return Err(de::Error::duplicate_field("signature"));
107                            }
108                            signature = Some(map.next_value()?);
109                        }
110                    }
111                }
112
113                let node = node.ok_or_else(|| de::Error::missing_field("node"))?;
114                let signature = signature.ok_or_else(|| de::Error::missing_field("signature"))?;
115
116                Ok(NetKeyVerifyRequest { node, signature })
117            }
118        }
119
120        deserializer.deserialize_struct(
121            "NetKeyVerifyRequest",
122            &["node", "signature"],
123            NetKeyVerifyRequestVisitor,
124        )
125    }
126}
127impl Serialize for SignRequest {
128    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
129    where
130        S: Serializer,
131    {
132        match self {
133            SignRequest::NetKeySign => {
134                // Unit variants serialize as just the variant name string
135                serializer.serialize_str("NetKeySign")
136            }
137            SignRequest::NetKeyVerify(request) => {
138                // Newtype variants serialize as {"VariantName": content}
139                let mut map = serializer.serialize_map(Some(1))?;
140                map.serialize_entry("NetKeyVerify", request)?;
141                map.end()
142            }
143            SignRequest::NetKeyMakeMessage => {
144                // Unit variants serialize as just the variant name string
145                serializer.serialize_str("NetKeyMakeMessage")
146            }
147        }
148    }
149}
150
151impl<'de> Deserialize<'de> for SignRequest {
152    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153    where
154        D: Deserializer<'de>,
155    {
156        struct SignRequestVisitor;
157
158        impl<'de> Visitor<'de> for SignRequestVisitor {
159            type Value = SignRequest;
160
161            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
162                formatter.write_str("a string for unit variants or a map for other variants")
163            }
164
165            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
166            where
167                E: de::Error,
168            {
169                match value {
170                    "NetKeySign" => Ok(SignRequest::NetKeySign),
171                    "NetKeyMakeMessage" => Ok(SignRequest::NetKeyMakeMessage),
172                    _ => Err(de::Error::unknown_variant(
173                        value,
174                        &["NetKeySign", "NetKeyVerify", "NetKeyMakeMessage"],
175                    )),
176                }
177            }
178
179            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
180            where
181                A: MapAccess<'de>,
182            {
183                let (variant, value) = map
184                    .next_entry::<String, serde_json::Value>()?
185                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
186
187                // Ensure there are no extra entries
188                if map.next_entry::<String, serde_json::Value>()?.is_some() {
189                    return Err(de::Error::custom("unexpected extra entries in map"));
190                }
191
192                match variant.as_str() {
193                    "NetKeyVerify" => {
194                        let request = serde_json::from_value(value).map_err(de::Error::custom)?;
195                        Ok(SignRequest::NetKeyVerify(request))
196                    }
197                    _ => Err(de::Error::unknown_variant(
198                        &variant,
199                        &["NetKeySign", "NetKeyVerify", "NetKeyMakeMessage"],
200                    )),
201                }
202            }
203        }
204
205        deserializer.deserialize_any(SignRequestVisitor)
206    }
207}
208
209impl Serialize for SignResponse {
210    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
211    where
212        S: Serializer,
213    {
214        match self {
215            SignResponse::NetKeySign => {
216                // Unit variants serialize as just the variant name string
217                serializer.serialize_str("NetKeySign")
218            }
219            SignResponse::NetKeyVerify(valid) => {
220                // Newtype variants serialize as {"VariantName": content}
221                let mut map = serializer.serialize_map(Some(1))?;
222                map.serialize_entry("NetKeyVerify", valid)?;
223                map.end()
224            }
225            SignResponse::NetKeyMakeMessage => {
226                // Unit variants serialize as just the variant name string
227                serializer.serialize_str("NetKeyMakeMessage")
228            }
229        }
230    }
231}
232
233impl<'de> Deserialize<'de> for SignResponse {
234    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
235    where
236        D: Deserializer<'de>,
237    {
238        struct SignResponseVisitor;
239
240        impl<'de> Visitor<'de> for SignResponseVisitor {
241            type Value = SignResponse;
242
243            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
244                formatter.write_str("a string for unit variants or a map for other variants")
245            }
246
247            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
248            where
249                E: de::Error,
250            {
251                match value {
252                    "NetKeySign" => Ok(SignResponse::NetKeySign),
253                    "NetKeyMakeMessage" => Ok(SignResponse::NetKeyMakeMessage),
254                    _ => Err(de::Error::unknown_variant(
255                        value,
256                        &["NetKeySign", "NetKeyVerify", "NetKeyMakeMessage"],
257                    )),
258                }
259            }
260
261            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
262            where
263                A: MapAccess<'de>,
264            {
265                let (variant, value) = map
266                    .next_entry::<String, serde_json::Value>()?
267                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
268
269                // Ensure there are no extra entries
270                if map.next_entry::<String, serde_json::Value>()?.is_some() {
271                    return Err(de::Error::custom("unexpected extra entries in map"));
272                }
273
274                match variant.as_str() {
275                    "NetKeyVerify" => {
276                        let valid = serde_json::from_value(value).map_err(de::Error::custom)?;
277                        Ok(SignResponse::NetKeyVerify(valid))
278                    }
279                    _ => Err(de::Error::unknown_variant(
280                        &variant,
281                        &["NetKeySign", "NetKeyVerify", "NetKeyMakeMessage"],
282                    )),
283                }
284            }
285        }
286
287        deserializer.deserialize_any(SignResponseVisitor)
288    }
289}