mithril_common/crypto_helper/
codec.rs1use 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#[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 pub fn new(msg: &str, source: anyhow::Error) -> Self {
25 Self {
26 msg: msg.to_string(),
27 source,
28 }
29 }
30}
31
32pub 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
42pub 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
64pub 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}