miden_protocol/address/
address_id.rs1use alloc::string::ToString;
2
3use bech32::Bech32m;
4use bech32::primitives::decode::CheckedHrpstring;
5
6use crate::account::AccountId;
7use crate::address::{AddressType, NetworkId};
8use crate::errors::{AddressError, Bech32Error};
9use crate::utils::serde::{
10 ByteReader,
11 ByteWriter,
12 Deserializable,
13 DeserializationError,
14 Serializable,
15};
16
17#[non_exhaustive]
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
22pub enum AddressId {
23 AccountId(AccountId),
24}
25
26impl AddressId {
27 pub fn address_type(&self) -> AddressType {
29 match self {
30 AddressId::AccountId(_) => AddressType::AccountId,
31 }
32 }
33
34 pub(crate) fn decode(bech32_string: &str) -> Result<(NetworkId, Self), AddressError> {
36 let checked_string = CheckedHrpstring::new::<Bech32m>(bech32_string).map_err(|source| {
39 AddressError::Bech32DecodeError(Bech32Error::DecodeError(source.to_string().into()))
44 })?;
45
46 let hrp = checked_string.hrp();
47 let network_id = NetworkId::from_hrp(hrp);
48
49 let mut byte_iter = checked_string.byte_iter();
50
51 let address_byte = byte_iter.next().ok_or_else(|| {
54 AddressError::Bech32DecodeError(Bech32Error::InvalidDataLength {
55 expected: 1,
56 actual: byte_iter.len(),
57 })
58 })?;
59
60 let address_type = AddressType::try_from(address_byte)?;
61
62 let identifier = match address_type {
63 AddressType::AccountId => AccountId::from_bech32_byte_iter(byte_iter)
64 .map_err(AddressError::AccountIdDecodeError)
65 .map(AddressId::AccountId)?,
66 };
67
68 Ok((network_id, identifier))
69 }
70}
71
72impl From<AccountId> for AddressId {
73 fn from(id: AccountId) -> Self {
74 Self::AccountId(id)
75 }
76}
77
78impl Serializable for AddressId {
79 fn write_into<W: ByteWriter>(&self, target: &mut W) {
80 target.write_u8(self.address_type() as u8);
81 match self {
82 AddressId::AccountId(id) => {
83 id.write_into(target);
84 },
85 }
86 }
87}
88
89impl Deserializable for AddressId {
90 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
91 let address_type: u8 = source.read_u8()?;
92 let address_type = AddressType::try_from(address_type)
93 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))?;
94
95 match address_type {
96 AddressType::AccountId => {
97 let id: AccountId = source.read()?;
98 Ok(AddressId::AccountId(id))
99 },
100 }
101 }
102}