1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word, WordAligned};
5
6use super::{
7 MAX_ATTACHMENT_WORDS, MAX_ATTACHMENTS_PER_NOTE, assert_attachment_count,
8 assert_attachment_word_count,
9 types::{
10 AccountId, Asset, NoteId, NoteIdx, NoteMetadata, RawAccountId, RawCommitmentWithCount,
11 RawFoundIndex, Recipient,
12 },
13};
14
15#[allow(improper_ctypes)]
16unsafe extern "C" {
17 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
18 #[link_name = "miden::protocol::input_note::get_initial_assets_info"]
19 fn extern_input_note_get_initial_assets_info(
20 note_index: Felt,
21 ptr: *mut RawCommitmentWithCount,
22 );
23 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
24 #[link_name = "miden::protocol::input_note::get_initial_assets"]
25 fn extern_input_note_get_initial_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
26 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
27 #[link_name = "miden::protocol::input_note::get_recipient"]
28 fn extern_input_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
29 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
30 #[link_name = "miden::protocol::input_note::get_metadata"]
31 fn extern_input_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
32 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
33 #[link_name = "miden::protocol::input_note::get_sender"]
34 fn extern_input_note_get_sender(note_index: Felt, ptr: *mut RawAccountId);
35 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
36 #[link_name = "miden::protocol::input_note::get_storage_info"]
37 fn extern_input_note_get_storage_info(note_index: Felt, ptr: *mut RawCommitmentWithCount);
38 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
39 #[link_name = "miden::protocol::input_note::get_script_root"]
40 fn extern_input_note_get_script_root(note_index: Felt, ptr: *mut Word);
41 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
42 #[link_name = "miden::protocol::input_note::get_serial_number"]
43 fn extern_input_note_get_serial_number(note_index: Felt, ptr: *mut Word);
44 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
45 #[link_name = "miden::protocol::input_note::get_attachments_commitment"]
46 fn extern_input_note_get_attachments_commitment(note_index: Felt, ptr: *mut Word);
47 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
48 #[link_name = "miden::protocol::input_note::write_attachment_commitments_to_memory"]
49 fn extern_input_note_write_attachment_commitments_to_memory(
50 dest_ptr: *mut Felt,
51 note_index: Felt,
52 ) -> usize;
53 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
54 #[link_name = "miden::protocol::input_note::write_attachment_to_memory"]
55 fn extern_input_note_write_attachment_to_memory(
56 dest_ptr: *mut Felt,
57 attachment_idx: Felt,
58 note_index: Felt,
59 ) -> usize;
60 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
61 #[link_name = "miden::protocol::input_note::find_attachment"]
62 fn extern_input_note_find_attachment(
63 attachment_scheme: Felt,
64 note_index: Felt,
65 ptr: *mut RawFoundIndex,
66 );
67 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
68 #[link_name = "miden::protocol::input_note::get_initial_num_assets"]
69 fn extern_input_note_get_initial_num_assets(note_index: Felt) -> Felt;
70 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
71 #[link_name = "miden::protocol::input_note::get_asset"]
72 fn extern_input_note_get_asset(asset_index: Felt, note_index: Felt, ptr: *mut Asset);
73 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
74 #[link_name = "miden::protocol::input_note::remove_asset"]
75 fn extern_input_note_remove_asset(
76 asset_id_0: Felt,
77 asset_id_1: Felt,
78 asset_id_2: Felt,
79 asset_id_3: Felt,
80 asset_value_0: Felt,
81 asset_value_1: Felt,
82 asset_value_2: Felt,
83 asset_value_3: Felt,
84 note_index: Felt,
85 ptr: *mut Word,
86 );
87 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
88 #[link_name = "miden::protocol::input_note::get_note_id"]
89 fn extern_input_note_get_note_id(note_index: Felt, ptr: *mut NoteId);
90 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
91 #[link_name = "miden::protocol::input_note::find_note"]
92 fn extern_input_note_find_note(
93 note_id_0: Felt,
94 note_id_1: Felt,
95 note_id_2: Felt,
96 note_id_3: Felt,
97 ptr: *mut RawFoundIndex,
98 );
99}
100
101pub struct InputNoteAssetsInfo {
103 pub commitment: Word,
104 pub num_assets: u32,
105}
106
107pub struct InputNoteStorageInfo {
109 pub commitment: Word,
110 pub num_storage_items: u32,
111}
112
113pub fn get_initial_assets_info(note_index: NoteIdx) -> InputNoteAssetsInfo {
117 unsafe {
118 let mut ret_area =
119 WordAligned::new(::core::mem::MaybeUninit::<RawCommitmentWithCount>::uninit());
120 extern_input_note_get_initial_assets_info(note_index.inner, ret_area.as_mut_ptr());
121 let raw = ret_area.into_inner().assume_init();
122 InputNoteAssetsInfo {
123 commitment: raw.commitment,
124 num_assets: raw.num_items(),
125 }
126 }
127}
128
129pub fn get_initial_assets(note_index: NoteIdx) -> Vec<Asset> {
133 const MAX_ASSETS: usize = 256;
134 let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
135 let num_assets = unsafe {
136 let ptr = (assets.as_mut_ptr() as usize) / 4;
137 extern_input_note_get_initial_assets(ptr as *mut Felt, note_index.inner)
138 };
139 unsafe {
140 assets.set_len(num_assets);
141 }
142 assets
143}
144
145pub fn get_recipient(note_index: NoteIdx) -> Recipient {
147 unsafe {
148 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
149 extern_input_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
150 ret_area.into_inner().assume_init()
151 }
152}
153
154pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
156 unsafe {
157 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteMetadata>::uninit());
158 extern_input_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
159 ret_area.into_inner().assume_init()
160 }
161}
162
163pub fn get_sender(note_index: NoteIdx) -> AccountId {
165 unsafe {
166 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawAccountId>::uninit());
167 extern_input_note_get_sender(note_index.inner, ret_area.as_mut_ptr());
168 ret_area.into_inner().assume_init().into_account_id()
169 }
170}
171
172pub fn get_storage_info(note_index: NoteIdx) -> InputNoteStorageInfo {
174 unsafe {
175 let mut ret_area =
176 WordAligned::new(::core::mem::MaybeUninit::<RawCommitmentWithCount>::uninit());
177 extern_input_note_get_storage_info(note_index.inner, ret_area.as_mut_ptr());
178 let raw = ret_area.into_inner().assume_init();
179 InputNoteStorageInfo {
180 commitment: raw.commitment,
181 num_storage_items: raw.num_items(),
182 }
183 }
184}
185
186pub fn get_script_root(note_index: NoteIdx) -> Word {
188 unsafe {
189 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
190 extern_input_note_get_script_root(note_index.inner, ret_area.as_mut_ptr());
191 ret_area.into_inner().assume_init()
192 }
193}
194
195pub fn get_serial_number(note_index: NoteIdx) -> Word {
197 unsafe {
198 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
199 extern_input_note_get_serial_number(note_index.inner, ret_area.as_mut_ptr());
200 ret_area.into_inner().assume_init()
201 }
202}
203
204pub fn get_attachments_commitment(note_index: NoteIdx) -> Word {
206 unsafe {
207 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
208 extern_input_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
209 ret_area.into_inner().assume_init()
210 }
211}
212
213pub fn get_attachments_commitment_raw(is_active_note: Felt, note_index: NoteIdx) -> Word {
220 assert!(
221 is_active_note == Felt::from_u32(0) || is_active_note == Felt::from_u32(1),
222 "is_active_note must be zero or one"
223 );
224 if is_active_note == Felt::from_u32(1) {
225 super::active_note::get_attachments_commitment()
226 } else {
227 get_attachments_commitment(note_index)
228 }
229}
230
231pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
235 let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
236 let num_attachments = unsafe {
237 let ptr = (commitments.as_mut_ptr() as usize) / 4;
238 extern_input_note_write_attachment_commitments_to_memory(ptr as *mut Felt, note_index.inner)
239 };
240 assert_attachment_count(num_attachments);
241 unsafe {
242 commitments.set_len(num_attachments);
243 }
244 commitments
245}
246
247pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: u32) -> Vec<Word> {
251 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
252 let num_words = unsafe {
253 let ptr = (attachment.as_mut_ptr() as usize) / 4;
254 extern_input_note_write_attachment_to_memory(
255 ptr as *mut Felt,
256 Felt::from_u32(attachment_idx),
257 note_index.inner,
258 )
259 };
260 assert_attachment_word_count(num_words);
261 unsafe {
262 attachment.set_len(num_words);
263 }
264 attachment
265}
266
267pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> Option<u32> {
269 unsafe {
270 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawFoundIndex>::uninit());
271 extern_input_note_find_attachment(
272 attachment_scheme,
273 note_index.inner,
274 ret_area.as_mut_ptr(),
275 );
276 ret_area.into_inner().assume_init().into_attachment_index()
277 }
278}
279
280#[inline]
284pub fn get_initial_num_assets(note_index: NoteIdx) -> u32 {
285 let count = unsafe { extern_input_note_get_initial_num_assets(note_index.inner) };
287 count.as_canonical_u64() as u32
288}
289
290pub fn get_asset(note_index: NoteIdx, asset_index: u32) -> Asset {
299 unsafe {
300 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Asset>::uninit());
301 extern_input_note_get_asset(
302 Felt::from_u32(asset_index),
303 note_index.inner,
304 ret_area.as_mut_ptr(),
305 );
306 ret_area.into_inner().assume_init()
307 }
308}
309
310pub fn remove_asset(note_index: NoteIdx, asset: Asset) -> Word {
321 unsafe {
322 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
323 let id = asset.id.inner;
324 extern_input_note_remove_asset(
325 id[0],
326 id[1],
327 id[2],
328 id[3],
329 asset.value[0],
330 asset.value[1],
331 asset.value[2],
332 asset.value[3],
333 note_index.inner,
334 ret_area.as_mut_ptr(),
335 );
336 ret_area.into_inner().assume_init()
337 }
338}
339
340pub fn get_note_id(note_index: NoteIdx) -> NoteId {
342 unsafe {
343 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteId>::uninit());
344 extern_input_note_get_note_id(note_index.inner, ret_area.as_mut_ptr());
345 ret_area.into_inner().assume_init()
346 }
347}
348
349pub fn find_note(note_id: NoteId) -> Option<NoteIdx> {
357 unsafe {
358 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawFoundIndex>::uninit());
359 let id = note_id.inner;
360 extern_input_note_find_note(id[0], id[1], id[2], id[3], ret_area.as_mut_ptr());
361 ret_area.into_inner().assume_init().into_note_index()
362 }
363}