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}