mithril_common/crypto_helper/
codec.rs

1use crate::entities::{HexEncodedKey, HexEncodedKeySlice};
2
3use hex::{FromHex, ToHex};
4use serde::de::DeserializeOwned;
5use serde::Serialize;
6use thiserror::Error;
7
8use anyhow::anyhow;
9use bech32::{self, Bech32, Hrp};
10
11use crate::StdResult;
12
13/// Error raised when the encoding or decoding fails
14#[derive(Error, Debug)]
15#[error("Codec error: {msg}")]
16pub struct CodecError {
17    msg: String,
18    #[source]
19    source: anyhow::Error,
20}
21
22impl CodecError {
23    /// [CodecError] factory.
24    pub fn new(msg: &str, source: anyhow::Error) -> Self {
25        Self {
26            msg: msg.to_string(),
27            source,
28        }
29    }
30}
31
32/// Encode key to hex helper
33pub fn key_encode_hex<T>(from: T) -> Result<HexEncodedKey, CodecError>
34where
35    T: Serialize,
36{
37    Ok(serde_json::to_string(&from)
38        .map_err(|e| CodecError::new("Key encode hex: can not convert to hex", e.into()))?
39        .encode_hex::<String>())
40}
41
42/// Decode key from hex helper
43pub fn key_decode_hex<T>(from: HexEncodedKeySlice) -> Result<T, CodecError>
44where
45    T: DeserializeOwned,
46{
47    let from_vec = Vec::from_hex(from.trim()).map_err(|e| {
48        CodecError::new(
49            "Key decode hex: can not turn hexadecimal value into bytes",
50            e.into(),
51        )
52    })?;
53    serde_json::from_slice(from_vec.as_slice()).map_err(|e| {
54        CodecError::new(
55            &format!(
56                "Key decode hex: can not deserialize to type '{}' from binary JSON",
57                std::any::type_name::<T>()
58            ),
59            e.into(),
60        )
61    })
62}
63
64/// Encode to bech32 given Human Readable Part (hrp) and data
65pub fn encode_bech32(human_readable_part: &str, data: &[u8]) -> StdResult<String> {
66    let human_readable_part = Hrp::parse(human_readable_part).map_err(|e| anyhow!(e))?;
67    bech32::encode::<Bech32>(human_readable_part, data).map_err(|e| anyhow!(e))
68}
69
70#[cfg(test)]
71mod tests {
72    use hex::FromHex;
73    use serde::{Deserialize, Serialize};
74
75    use super::{encode_bech32, key_decode_hex, key_encode_hex};
76
77    #[derive(Debug, PartialEq, Serialize, Deserialize)]
78    struct TestSerialize {
79        inner_string: String,
80    }
81
82    #[test]
83    fn test_key_encode_decode_hex() {
84        let test_to_serialize = TestSerialize {
85            inner_string: "my inner string".to_string(),
86        };
87        let test_to_serialize_hex =
88            key_encode_hex(&test_to_serialize).expect("unexpected hex encoding error");
89        let test_to_serialize_restored =
90            key_decode_hex(&test_to_serialize_hex).expect("unexpected hex decoding error");
91        assert_eq!(test_to_serialize, test_to_serialize_restored);
92    }
93
94    #[test]
95    fn test_key_decode_hex_with_leading_and_trailing_whitespace() {
96        let test_to_serialize = TestSerialize {
97            inner_string: "my inner string".to_string(),
98        };
99        let test_to_serialize_hex =
100            key_encode_hex(&test_to_serialize).expect("unexpected hex encoding error");
101        let test_to_serialize_restored = key_decode_hex(&format!(" \r{test_to_serialize_hex} \n"))
102            .expect("unexpected hex decoding error");
103        assert_eq!(test_to_serialize, test_to_serialize_restored);
104    }
105
106    #[test]
107    fn test_bech32_encode() {
108        let hrp = "pool";
109        let data =
110            Vec::from_hex("edfa208d441511f9595ba80e8f3a7b07b6a80cbc9dda9d8e9d1dc039").unwrap();
111        let encoded_data = encode_bech32(hrp, &data).unwrap();
112        let expected_encoded_data =
113            "pool1ahazpr2yz5gljk2m4q8g7wnmq7m2sr9unhdfmr5arhqrjnntwdz".to_string();
114
115        assert_eq!(expected_encoded_data, encoded_data);
116    }
117}