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, AccountStorageMode};
8use crate::address::{AddressType, NetworkId};
9use crate::errors::{AddressError, Bech32Error};
10use crate::note::NoteTag;
11use crate::utils::serde::{ByteWriter, Deserializable, Serializable};
12
13#[non_exhaustive]
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub enum AddressId {
19 AccountId(AccountId),
20}
21
22impl AddressId {
23 pub fn address_type(&self) -> AddressType {
25 match self {
26 AddressId::AccountId(_) => AddressType::AccountId,
27 }
28 }
29
30 pub fn default_note_tag_len(&self) -> u8 {
36 match self {
37 AddressId::AccountId(id) => {
38 if id.storage_mode() == AccountStorageMode::Network {
39 NoteTag::DEFAULT_NETWORK_ACCOUNT_TARGET_TAG_LENGTH
40 } else {
41 NoteTag::DEFAULT_LOCAL_ACCOUNT_TARGET_TAG_LENGTH
42 }
43 },
44 }
45 }
46
47 pub(crate) fn decode(bech32_string: &str) -> Result<(NetworkId, Self), AddressError> {
49 let checked_string = CheckedHrpstring::new::<Bech32m>(bech32_string).map_err(|source| {
52 AddressError::Bech32DecodeError(Bech32Error::DecodeError(source.to_string().into()))
57 })?;
58
59 let hrp = checked_string.hrp();
60 let network_id = NetworkId::from_hrp(hrp);
61
62 let mut byte_iter = checked_string.byte_iter();
63
64 let address_byte = byte_iter.next().ok_or_else(|| {
67 AddressError::Bech32DecodeError(Bech32Error::InvalidDataLength {
68 expected: 1,
69 actual: byte_iter.len(),
70 })
71 })?;
72
73 let address_type = AddressType::try_from(address_byte)?;
74
75 let identifier = match address_type {
76 AddressType::AccountId => AccountId::from_bech32_byte_iter(byte_iter)
77 .map_err(AddressError::AccountIdDecodeError)
78 .map(AddressId::AccountId)?,
79 };
80
81 Ok((network_id, identifier))
82 }
83}
84
85impl From<AccountId> for AddressId {
86 fn from(id: AccountId) -> Self {
87 Self::AccountId(id)
88 }
89}
90
91impl Serializable for AddressId {
92 fn write_into<W: ByteWriter>(&self, target: &mut W) {
93 target.write_u8(self.address_type() as u8);
94 match self {
95 AddressId::AccountId(id) => {
96 id.write_into(target);
97 },
98 }
99 }
100}
101
102impl Deserializable for AddressId {
103 fn read_from<R: miden_core::utils::ByteReader>(
104 source: &mut R,
105 ) -> Result<Self, DeserializationError> {
106 let address_type: u8 = source.read_u8()?;
107 let address_type = AddressType::try_from(address_type)
108 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))?;
109
110 match address_type {
111 AddressType::AccountId => {
112 let id: AccountId = source.read()?;
113 Ok(AddressId::AccountId(id))
114 },
115 }
116 }
117}