radix_common/address/
decoder.rs1use super::hrpset::HrpSet;
2use crate::address::AddressBech32DecodeError;
3use crate::network::NetworkDefinition;
4use crate::types::EntityType;
5use bech32::{self, FromBase32, Variant};
6use sbor::rust::prelude::*;
7
8pub struct AddressBech32Decoder {
10 pub hrp_set: HrpSet,
11}
12
13impl AddressBech32Decoder {
14 pub fn for_simulator() -> Self {
15 Self::new(&NetworkDefinition::simulator())
16 }
17
18 pub fn new(network: &NetworkDefinition) -> Self {
20 Self {
21 hrp_set: network.into(),
22 }
23 }
24
25 pub fn validate_and_decode_ignore_hrp(
26 address: &str,
27 ) -> Result<(String, EntityType, Vec<u8>), AddressBech32DecodeError> {
28 let (hrp, data, variant) = bech32::decode(address)
30 .map_err(|err| AddressBech32DecodeError::Bech32mDecodingError(err))?;
31
32 match variant {
34 Variant::Bech32m => {}
35 _ => return Err(AddressBech32DecodeError::InvalidVariant(variant)),
36 };
37
38 let data = Vec::<u8>::from_base32(&data)
40 .map_err(|err| AddressBech32DecodeError::Bech32mDecodingError(err))?;
41
42 let entity_type = if let Some(entity_type_id) = data.get(0) {
44 EntityType::from_repr(*entity_type_id).ok_or(
45 AddressBech32DecodeError::InvalidEntityTypeId(*entity_type_id),
46 )?
47 } else {
48 return Err(AddressBech32DecodeError::MissingEntityTypeByte);
49 };
50
51 Ok((hrp, entity_type, data))
53 }
54
55 pub fn validate_and_decode(
57 &self,
58 address: &str,
59 ) -> Result<(EntityType, Vec<u8>), AddressBech32DecodeError> {
60 let (actual_hrp, entity_type, data) = Self::validate_and_decode_ignore_hrp(address)?;
61 let expected_hrp = self.hrp_set.get_entity_hrp(&entity_type);
62
63 if actual_hrp != expected_hrp {
65 return Err(AddressBech32DecodeError::InvalidHrp);
66 }
67
68 Ok((entity_type, data))
70 }
71}