1use crate::error::CoreError;
4use prost::bytes::Bytes;
5
6pub fn decode_bech32(hrp_addr: &str) -> Result<Bytes, CoreError> {
19 let (_hrp, raw) =
20 bech32::decode(hrp_addr).map_err(|e| CoreError::InvalidBech32(e.to_string()))?;
21
22 if raw.len() != 32 {
23 return Err(CoreError::InvalidAddressLength(raw.len()));
24 }
25
26 Ok(Bytes::from(raw))
27}
28
29pub fn decode_optional_bech32(addr: Option<&str>) -> Result<Bytes, CoreError> {
37 match addr {
38 Some(a) if !a.trim().is_empty() => decode_bech32(a),
39 _ => Ok(Bytes::new()),
40 }
41}
42
43pub fn encode_bech32(hrp: &str, data: &[u8]) -> Result<String, CoreError> {
55 bech32::encode::<bech32::Bech32>(
56 bech32::Hrp::parse(hrp).map_err(|e| CoreError::InvalidHrp(e.to_string()))?,
57 data,
58 )
59 .map_err(|e| CoreError::Bech32Encode(e.to_string()))
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn test_decode_bech32() {
68 let addr = "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th";
69 let result = decode_bech32(addr);
70 assert!(result.is_ok());
71 assert_eq!(result.unwrap().len(), 32);
72 }
73
74 #[test]
75 fn test_decode_bech32_invalid() {
76 let result = decode_bech32("invalid");
77 assert!(result.is_err());
78 }
79
80 #[test]
81 fn test_encode_decode_roundtrip() {
82 let original = "erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th";
83 let decoded = decode_bech32(original).unwrap();
84 let encoded = encode_bech32("erd", &decoded).unwrap();
85 assert_eq!(original, encoded);
86 }
87
88 #[test]
89 fn test_decode_optional_bech32_none() {
90 let result = decode_optional_bech32(None);
91 assert!(result.is_ok());
92 assert!(result.unwrap().is_empty());
93 }
94
95 #[test]
96 fn test_decode_optional_bech32_empty() {
97 let result = decode_optional_bech32(Some(""));
98 assert!(result.is_ok());
99 assert!(result.unwrap().is_empty());
100 }
101}