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;
20use well_known_note::WellKnownNote;
21
22pub mod utils;
23pub mod well_known_note;
24
25pub fn create_p2id_note<R: FeltRng>(
39 sender: AccountId,
40 target: AccountId,
41 assets: Vec<Asset>,
42 note_type: NoteType,
43 aux: Felt,
44 rng: &mut R,
45) -> Result<Note, NoteError> {
46 let serial_num = rng.draw_word();
47 let recipient = utils::build_p2id_recipient(target, serial_num)?;
48
49 let tag = NoteTag::from_account_id(target);
50
51 let metadata = NoteMetadata::new(sender, note_type, tag, NoteExecutionHint::always(), aux)?;
52 let vault = NoteAssets::new(assets)?;
53
54 Ok(Note::new(vault, metadata, recipient))
55}
56
57pub fn create_p2ide_note<R: FeltRng>(
71 sender: AccountId,
72 target: AccountId,
73 assets: Vec<Asset>,
74 reclaim_height: Option<BlockNumber>,
75 timelock_height: Option<BlockNumber>,
76 note_type: NoteType,
77 aux: Felt,
78 rng: &mut R,
79) -> Result<Note, NoteError> {
80 let serial_num = rng.draw_word();
81 let recipient =
82 utils::build_p2ide_recipient(target, reclaim_height, timelock_height, serial_num)?;
83 let tag = NoteTag::from_account_id(target);
84
85 let execution_hint = match timelock_height {
86 Some(height) => NoteExecutionHint::after_block(height)?,
87 None => NoteExecutionHint::always(),
88 };
89
90 let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
91 let vault = NoteAssets::new(assets)?;
92
93 Ok(Note::new(vault, metadata, recipient))
94}
95
96pub fn create_swap_note<R: FeltRng>(
106 sender: AccountId,
107 offered_asset: Asset,
108 requested_asset: Asset,
109 swap_note_type: NoteType,
110 swap_note_aux: Felt,
111 payback_note_type: NoteType,
112 payback_note_aux: Felt,
113 rng: &mut R,
114) -> Result<(Note, NoteDetails), NoteError> {
115 if requested_asset == offered_asset {
116 return Err(NoteError::other("requested asset same as offered asset"));
117 }
118
119 let note_script = WellKnownNote::SWAP.script();
120
121 let payback_serial_num = rng.draw_word();
122 let payback_recipient = utils::build_p2id_recipient(sender, payback_serial_num)?;
123
124 let payback_recipient_word: Word = payback_recipient.digest();
125 let requested_asset_word: Word = requested_asset.into();
126 let payback_tag = NoteTag::from_account_id(sender);
127
128 let inputs = NoteInputs::new(vec![
129 requested_asset_word[0],
130 requested_asset_word[1],
131 requested_asset_word[2],
132 requested_asset_word[3],
133 payback_recipient_word[0],
134 payback_recipient_word[1],
135 payback_recipient_word[2],
136 payback_recipient_word[3],
137 NoteExecutionHint::always().into(),
138 payback_note_type.into(),
139 payback_note_aux,
140 payback_tag.into(),
141 ])?;
142
143 let tag = build_swap_tag(swap_note_type, &offered_asset, &requested_asset)?;
145 let serial_num = rng.draw_word();
146
147 let metadata =
149 NoteMetadata::new(sender, swap_note_type, tag, NoteExecutionHint::always(), swap_note_aux)?;
150 let assets = NoteAssets::new(vec![offered_asset])?;
151 let recipient = NoteRecipient::new(serial_num, note_script, inputs);
152 let note = Note::new(assets, metadata, recipient);
153
154 let payback_assets = NoteAssets::new(vec![requested_asset])?;
156 let payback_note = NoteDetails::new(payback_assets, payback_recipient);
157
158 Ok((note, payback_note))
159}