miden_standards/note/
utils.rs1use miden_protocol::account::AccountId;
2use miden_protocol::asset::Asset;
3use miden_protocol::block::BlockNumber;
4use miden_protocol::errors::NoteError;
5use miden_protocol::note::{NoteInputs, NoteRecipient, NoteTag, NoteType};
6use miden_protocol::{Felt, Word};
7
8use super::well_known_note::WellKnownNote;
9
10pub fn build_p2id_recipient(
15 target: AccountId,
16 serial_num: Word,
17) -> Result<NoteRecipient, NoteError> {
18 let note_script = WellKnownNote::P2ID.script();
19 let note_inputs = NoteInputs::new(vec![target.suffix(), target.prefix().as_felt()])?;
20
21 Ok(NoteRecipient::new(serial_num, note_script, note_inputs))
22}
23
24pub fn build_p2ide_recipient(
29 target: AccountId,
30 reclaim_block_height: Option<BlockNumber>,
31 timelock_block_height: Option<BlockNumber>,
32 serial_num: Word,
33) -> Result<NoteRecipient, NoteError> {
34 let note_script = WellKnownNote::P2IDE.script();
35
36 let reclaim_height_u32 = reclaim_block_height.map_or(0, |bn| bn.as_u32());
37 let timelock_height_u32 = timelock_block_height.map_or(0, |bn| bn.as_u32());
38
39 let note_inputs = NoteInputs::new(vec![
40 target.suffix(),
41 target.prefix().into(),
42 Felt::new(reclaim_height_u32 as u64),
43 Felt::new(timelock_height_u32 as u64),
44 ])?;
45
46 Ok(NoteRecipient::new(serial_num, note_script, note_inputs))
47}
48
49pub fn build_swap_tag(
62 note_type: NoteType,
63 offered_asset: &Asset,
64 requested_asset: &Asset,
65) -> NoteTag {
66 let swap_root_bytes = WellKnownNote::SWAP.script().root().as_bytes();
67 let mut swap_use_case_id = (swap_root_bytes[0] as u16) << 6;
70 swap_use_case_id |= (swap_root_bytes[1] >> 2) as u16;
71
72 let offered_asset_id: u64 = offered_asset.faucet_id_prefix().into();
74 let offered_asset_tag = (offered_asset_id >> 56) as u8;
75
76 let requested_asset_id: u64 = requested_asset.faucet_id_prefix().into();
77 let requested_asset_tag = (requested_asset_id >> 56) as u8;
78
79 let asset_pair = ((offered_asset_tag as u16) << 8) | (requested_asset_tag as u16);
80
81 let tag =
82 ((note_type as u8 as u32) << 30) | ((swap_use_case_id as u32) << 16) | asset_pair as u32;
83
84 NoteTag::new(tag)
85}
86
87#[cfg(test)]
88mod tests {
89 use miden_protocol::account::{AccountIdVersion, AccountStorageMode, AccountType};
90 use miden_protocol::asset::{FungibleAsset, NonFungibleAsset, NonFungibleAssetDetails};
91 use miden_protocol::{self};
92
93 use super::*;
94
95 #[test]
96 fn swap_tag() {
97 let mut fungible_faucet_id_bytes = [0; 15];
99 fungible_faucet_id_bytes[0] = 0xcd;
100 fungible_faucet_id_bytes[1] = 0xb1;
101
102 let mut non_fungible_faucet_id_bytes = [0; 15];
104 non_fungible_faucet_id_bytes[0] = 0xab;
105 non_fungible_faucet_id_bytes[1] = 0xec;
106
107 let offered_asset = Asset::Fungible(
108 FungibleAsset::new(
109 AccountId::dummy(
110 fungible_faucet_id_bytes,
111 AccountIdVersion::Version0,
112 AccountType::FungibleFaucet,
113 AccountStorageMode::Public,
114 ),
115 2500,
116 )
117 .unwrap(),
118 );
119
120 let requested_asset = Asset::NonFungible(
121 NonFungibleAsset::new(
122 &NonFungibleAssetDetails::new(
123 AccountId::dummy(
124 non_fungible_faucet_id_bytes,
125 AccountIdVersion::Version0,
126 AccountType::NonFungibleFaucet,
127 AccountStorageMode::Public,
128 )
129 .prefix(),
130 vec![0xaa, 0xbb, 0xcc, 0xdd],
131 )
132 .unwrap(),
133 )
134 .unwrap(),
135 );
136
137 let expected_asset_pair = 0xcdab;
141
142 let note_type = NoteType::Public;
143 let actual_tag = build_swap_tag(note_type, &offered_asset, &requested_asset);
144
145 assert_eq!(actual_tag.as_u32() as u16, expected_asset_pair, "asset pair should match");
146 assert_eq!((actual_tag.as_u32() >> 30) as u8, note_type as u8, "note type should match");
147 assert_eq!(
149 (actual_tag.as_u32() >> 22) as u8,
150 WellKnownNote::SWAP.script().root().as_bytes()[0],
151 "swap script root byte 0 should match"
152 );
153 assert_eq!(
155 ((actual_tag.as_u32() & 0b00000000_00111111_00000000_00000000) >> 16) as u8,
156 WellKnownNote::SWAP.script().root().as_bytes()[1] >> 2,
157 "swap script root byte 1 should match with the lower two bits set to zero"
158 );
159 }
160}