1use alloc::vec::Vec;
2
3use miden_objects::account::AccountId;
4use miden_objects::asset::Asset;
5use miden_objects::block::BlockNumber;
6use miden_objects::crypto::rand::FeltRng;
7use miden_objects::note::{
8 Note,
9 NoteAssets,
10 NoteDetails,
11 NoteExecutionHint,
12 NoteInputs,
13 NoteMetadata,
14 NoteRecipient,
15 NoteTag,
16 NoteType,
17};
18use miden_objects::{Felt, NoteError, Word};
19use utils::build_swap_tag;
20
21pub mod utils;
22
23mod well_known_note;
24pub use well_known_note::{NoteConsumptionStatus, WellKnownNote};
25
26pub fn create_p2id_note<R: FeltRng>(
40 sender: AccountId,
41 target: AccountId,
42 assets: Vec<Asset>,
43 note_type: NoteType,
44 aux: Felt,
45 rng: &mut R,
46) -> Result<Note, NoteError> {
47 let serial_num = rng.draw_word();
48 let recipient = utils::build_p2id_recipient(target, serial_num)?;
49
50 let tag = NoteTag::from_account_id(target);
51
52 let metadata = NoteMetadata::new(sender, note_type, tag, NoteExecutionHint::always(), aux)?;
53 let vault = NoteAssets::new(assets)?;
54
55 Ok(Note::new(vault, metadata, recipient))
56}
57
58pub fn create_p2ide_note<R: FeltRng>(
72 sender: AccountId,
73 target: AccountId,
74 assets: Vec<Asset>,
75 reclaim_height: Option<BlockNumber>,
76 timelock_height: Option<BlockNumber>,
77 note_type: NoteType,
78 aux: Felt,
79 rng: &mut R,
80) -> Result<Note, NoteError> {
81 let serial_num = rng.draw_word();
82 let recipient =
83 utils::build_p2ide_recipient(target, reclaim_height, timelock_height, serial_num)?;
84 let tag = NoteTag::from_account_id(target);
85
86 let execution_hint = match timelock_height {
87 Some(height) => NoteExecutionHint::after_block(height)?,
88 None => NoteExecutionHint::always(),
89 };
90
91 let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
92 let vault = NoteAssets::new(assets)?;
93
94 Ok(Note::new(vault, metadata, recipient))
95}
96
97pub fn create_swap_note<R: FeltRng>(
107 sender: AccountId,
108 offered_asset: Asset,
109 requested_asset: Asset,
110 swap_note_type: NoteType,
111 swap_note_aux: Felt,
112 payback_note_type: NoteType,
113 payback_note_aux: Felt,
114 rng: &mut R,
115) -> Result<(Note, NoteDetails), NoteError> {
116 if requested_asset == offered_asset {
117 return Err(NoteError::other("requested asset same as offered asset"));
118 }
119
120 let note_script = WellKnownNote::SWAP.script();
121
122 let payback_serial_num = rng.draw_word();
123 let payback_recipient = utils::build_p2id_recipient(sender, payback_serial_num)?;
124
125 let payback_recipient_word: Word = payback_recipient.digest();
126 let requested_asset_word: Word = requested_asset.into();
127 let payback_tag = NoteTag::from_account_id(sender);
128
129 let inputs = NoteInputs::new(vec![
130 requested_asset_word[0],
131 requested_asset_word[1],
132 requested_asset_word[2],
133 requested_asset_word[3],
134 payback_recipient_word[0],
135 payback_recipient_word[1],
136 payback_recipient_word[2],
137 payback_recipient_word[3],
138 NoteExecutionHint::always().into(),
139 payback_note_type.into(),
140 payback_note_aux,
141 payback_tag.into(),
142 ])?;
143
144 let tag = build_swap_tag(swap_note_type, &offered_asset, &requested_asset)?;
146 let serial_num = rng.draw_word();
147
148 let metadata =
150 NoteMetadata::new(sender, swap_note_type, tag, NoteExecutionHint::always(), swap_note_aux)?;
151 let assets = NoteAssets::new(vec![offered_asset])?;
152 let recipient = NoteRecipient::new(serial_num, note_script, inputs);
153 let note = Note::new(assets, metadata, recipient);
154
155 let payback_assets = NoteAssets::new(vec![requested_asset])?;
157 let payback_note = NoteDetails::new(payback_assets, payback_recipient);
158
159 Ok((note, payback_note))
160}
161
162pub fn create_mint_note<R: FeltRng>(
189 faucet_id: AccountId,
190 sender: AccountId,
191 target_recipient: Word,
192 output_note_tag: Felt,
193 amount: Felt,
194 aux: Felt,
195 output_note_aux: Felt,
196 rng: &mut R,
197) -> Result<Note, NoteError> {
198 let note_script = WellKnownNote::MINT.script();
199 let serial_num = rng.draw_word();
200
201 let note_type = NoteType::Public;
203 let output_note_type = NoteType::Private;
205
206 let execution_hint = NoteExecutionHint::always();
207
208 let inputs = NoteInputs::new(vec![
209 target_recipient[0],
210 target_recipient[1],
211 target_recipient[2],
212 target_recipient[3],
213 execution_hint.into(),
214 output_note_type.into(),
215 output_note_aux,
216 output_note_tag,
217 amount,
218 ])?;
219
220 let tag = NoteTag::from_account_id(faucet_id);
221
222 let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
223 let assets = NoteAssets::new(vec![])?; let recipient = NoteRecipient::new(serial_num, note_script, inputs);
225
226 Ok(Note::new(assets, metadata, recipient))
227}
228
229pub fn create_burn_note<R: FeltRng>(
251 sender: AccountId,
252 faucet_id: AccountId,
253 fungible_asset: Asset,
254 aux: Felt,
255 rng: &mut R,
256) -> Result<Note, NoteError> {
257 let note_script = WellKnownNote::BURN.script();
258 let serial_num = rng.draw_word();
259
260 let note_type = NoteType::Public;
262 let execution_hint = NoteExecutionHint::always();
264
265 let inputs = NoteInputs::new(vec![])?;
266 let tag = NoteTag::from_account_id(faucet_id);
267
268 let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
269 let assets = NoteAssets::new(vec![fungible_asset])?; let recipient = NoteRecipient::new(serial_num, note_script, inputs);
271
272 Ok(Note::new(assets, metadata, recipient))
273}