radix_transactions/model/hash/
decoder.rs1use bech32::{FromBase32, Variant};
2
3use crate::internal_prelude::*;
4
5pub struct TransactionHashBech32Decoder {
6 pub hrp_set: HrpSet,
7}
8
9impl TransactionHashBech32Decoder {
10 pub fn for_simulator() -> Self {
11 Self::new(&NetworkDefinition::simulator())
12 }
13
14 pub fn new(network: &NetworkDefinition) -> Self {
16 Self {
17 hrp_set: network.into(),
18 }
19 }
20
21 pub fn validate_and_decode<T>(&self, hash: &str) -> Result<T, TransactionHashBech32DecodeError>
22 where
23 T: IsTransactionHash,
24 {
25 let (hrp, data, variant) =
27 bech32::decode(hash).map_err(TransactionHashBech32DecodeError::Bech32mDecodingError)?;
28
29 match variant {
31 Variant::Bech32m => {}
32 _ => return Err(TransactionHashBech32DecodeError::InvalidVariant(variant)),
33 };
34
35 let data = Vec::<u8>::from_base32(&data)
37 .map_err(TransactionHashBech32DecodeError::Bech32mDecodingError)?;
38
39 let hash = data
41 .try_into()
42 .map(Hash)
43 .map_err(|_| TransactionHashBech32DecodeError::InvalidLength)?;
44
45 T::create_from_hrp_and_hash(&hrp, hash, &self.hrp_set).map_err(|err| match err {
47 HashCreationError::InvalidHrp => TransactionHashBech32DecodeError::InvalidHrp,
48 })
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::internal_prelude::*;
55
56 #[test]
57 fn intent_hash_is_decoded_as_expected() {
58 let decoder = TransactionHashBech32Decoder::for_simulator();
60 let encoded_hash = "txid_sim1vrjkzlt8pekg5s46tum5na8lzpulvc3p72p92nkdm2dd8p0vkx2svr7ejr";
61 let expected_hash =
62 Hash::from_str("60e5617d670e6c8a42ba5f3749f4ff1079f66221f282554ecdda9ad385ecb195")
63 .unwrap();
64
65 let decoded = decoder
67 .validate_and_decode::<TransactionIntentHash>(encoded_hash)
68 .unwrap();
69
70 assert_eq!(decoded.0, expected_hash)
72 }
73
74 #[test]
75 fn signed_intent_hash_is_decoded_as_expected() {
76 let decoder = TransactionHashBech32Decoder::for_simulator();
78 let encoded_hash =
79 "signedintent_sim1c3f6q287pvw2pfs2extnh4yfmtc6ephgga7shf23nck85467026qrzn64x";
80 let expected_hash =
81 Hash::from_str("c453a028fe0b1ca0a60ac9973bd489daf1ac86e8477d0ba5519e2c7a575e7ab4")
82 .unwrap();
83
84 let decoded = decoder
86 .validate_and_decode::<SignedTransactionIntentHash>(encoded_hash)
87 .unwrap();
88
89 assert_eq!(decoded.0, expected_hash)
91 }
92
93 #[test]
94 fn notarized_transaction_hash_is_decoded_as_expected() {
95 let decoder = TransactionHashBech32Decoder::for_simulator();
97 let encoded_hash =
98 "notarizedtransaction_sim16aya9aqejr35u23g4gklcs3mya5nllxyy4y2y4yw9lur3wq6cdfsgpgkww";
99 let expected_hash =
100 Hash::from_str("d749d2f41990e34e2a28aa2dfc423b27693ffcc42548a2548e2ff838b81ac353")
101 .unwrap();
102
103 let decoded = decoder
105 .validate_and_decode::<NotarizedTransactionHash>(encoded_hash)
106 .unwrap();
107
108 assert_eq!(decoded.0, expected_hash)
110 }
111}