1use alloc::vec::Vec;
2
3use miden_objects::{
4 Felt, NoteError, Word,
5 account::AccountId,
6 asset::Asset,
7 block::BlockNumber,
8 crypto::rand::FeltRng,
9 note::{
10 Note, NoteAssets, NoteDetails, NoteExecutionHint, NoteInputs, NoteMetadata, NoteRecipient,
11 NoteTag, NoteType,
12 },
13};
14use utils::build_swap_tag;
15use well_known_note::WellKnownNote;
16
17pub mod utils;
18pub mod well_known_note;
19
20pub fn create_p2id_note<R: FeltRng>(
34 sender: AccountId,
35 target: AccountId,
36 assets: Vec<Asset>,
37 note_type: NoteType,
38 aux: Felt,
39 rng: &mut R,
40) -> Result<Note, NoteError> {
41 let serial_num = rng.draw_word();
42 let recipient = utils::build_p2id_recipient(target, serial_num)?;
43
44 let tag = NoteTag::from_account_id(target);
45
46 let metadata = NoteMetadata::new(sender, note_type, tag, NoteExecutionHint::always(), aux)?;
47 let vault = NoteAssets::new(assets)?;
48
49 Ok(Note::new(vault, metadata, recipient))
50}
51
52pub fn create_p2ide_note<R: FeltRng>(
66 sender: AccountId,
67 target: AccountId,
68 assets: Vec<Asset>,
69 reclaim_height: Option<BlockNumber>,
70 timelock_height: Option<BlockNumber>,
71 note_type: NoteType,
72 aux: Felt,
73 rng: &mut R,
74) -> Result<Note, NoteError> {
75 let serial_num = rng.draw_word();
76 let recipient =
77 utils::build_p2ide_recipient(target, reclaim_height, timelock_height, serial_num)?;
78 let tag = NoteTag::from_account_id(target);
79
80 let execution_hint = match timelock_height {
81 Some(height) => NoteExecutionHint::after_block(height)?,
82 None => NoteExecutionHint::always(),
83 };
84
85 let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
86 let vault = NoteAssets::new(assets)?;
87
88 Ok(Note::new(vault, metadata, recipient))
89}
90
91pub fn create_swap_note<R: FeltRng>(
101 sender: AccountId,
102 offered_asset: Asset,
103 requested_asset: Asset,
104 note_type: NoteType,
105 aux: Felt,
106 rng: &mut R,
107) -> Result<(Note, NoteDetails), NoteError> {
108 let note_script = WellKnownNote::SWAP.script();
109
110 let payback_serial_num = rng.draw_word();
111 let payback_recipient = utils::build_p2id_recipient(sender, payback_serial_num)?;
112
113 let payback_recipient_word: Word = payback_recipient.digest().into();
114 let requested_asset_word: Word = requested_asset.into();
115 let payback_tag = NoteTag::from_account_id(sender);
116
117 let inputs = NoteInputs::new(vec![
118 payback_recipient_word[0],
119 payback_recipient_word[1],
120 payback_recipient_word[2],
121 payback_recipient_word[3],
122 requested_asset_word[0],
123 requested_asset_word[1],
124 requested_asset_word[2],
125 requested_asset_word[3],
126 payback_tag.as_u32().into(),
127 NoteExecutionHint::always().into(),
128 ])?;
129
130 let tag = build_swap_tag(note_type, &offered_asset, &requested_asset)?;
132 let serial_num = rng.draw_word();
133
134 let metadata = NoteMetadata::new(sender, note_type, tag, NoteExecutionHint::always(), aux)?;
136 let assets = NoteAssets::new(vec![offered_asset])?;
137 let recipient = NoteRecipient::new(serial_num, note_script, inputs);
138 let note = Note::new(assets, metadata, recipient);
139
140 let payback_assets = NoteAssets::new(vec![requested_asset])?;
142 let payback_note = NoteDetails::new(payback_assets, payback_recipient);
143
144 Ok((note, payback_note))
145}