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