Skip to main content

miden_base_sys/bindings/
input_note.rs

1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word};
5
6use super::types::{
7    AccountId, Asset, AttachmentLocation, NoteIdx, NoteMetadata, RawAccountId, Recipient,
8};
9
10const MAX_ATTACHMENTS_PER_NOTE: usize = 4;
11const MAX_ATTACHMENT_WORDS: usize = 256;
12
13#[allow(improper_ctypes)]
14unsafe extern "C" {
15    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
16    #[link_name = "miden::protocol::input_note::get_assets_info"]
17    fn extern_input_note_get_assets_info(note_index: Felt, ptr: *mut (Word, Felt));
18    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
19    #[link_name = "miden::protocol::input_note::get_assets"]
20    fn extern_input_note_get_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
21    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
22    #[link_name = "miden::protocol::input_note::get_recipient"]
23    fn extern_input_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
24    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
25    #[link_name = "miden::protocol::input_note::get_metadata"]
26    fn extern_input_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
27    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
28    #[link_name = "miden::protocol::input_note::get_sender"]
29    fn extern_input_note_get_sender(note_index: Felt, ptr: *mut RawAccountId);
30    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
31    #[link_name = "miden::protocol::input_note::get_storage_info"]
32    fn extern_input_note_get_storage_info(note_index: Felt, ptr: *mut (Word, Felt));
33    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
34    #[link_name = "miden::protocol::input_note::get_script_root"]
35    fn extern_input_note_get_script_root(note_index: Felt, ptr: *mut Word);
36    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
37    #[link_name = "miden::protocol::input_note::get_serial_number"]
38    fn extern_input_note_get_serial_number(note_index: Felt, ptr: *mut Word);
39    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
40    #[link_name = "miden::protocol::input_note::get_attachments_commitment"]
41    fn extern_input_note_get_attachments_commitment(note_index: Felt, ptr: *mut Word);
42    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
43    #[link_name = "miden::protocol::input_note::get_attachments_commitment_raw"]
44    fn extern_input_note_get_attachments_commitment_raw(
45        is_active_note: Felt,
46        note_index: Felt,
47        ptr: *mut Word,
48    );
49    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
50    #[link_name = "miden::protocol::input_note::write_attachment_commitments_to_memory"]
51    fn extern_input_note_write_attachment_commitments_to_memory(
52        dest_ptr: *mut Felt,
53        note_index: Felt,
54    ) -> usize;
55    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
56    #[link_name = "miden::protocol::input_note::write_attachment_to_memory"]
57    fn extern_input_note_write_attachment_to_memory(
58        dest_ptr: *mut Felt,
59        attachment_idx: Felt,
60        note_index: Felt,
61    ) -> usize;
62    #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
63    #[link_name = "miden::protocol::input_note::find_attachment"]
64    fn extern_input_note_find_attachment(
65        attachment_scheme: Felt,
66        note_index: Felt,
67        ptr: *mut AttachmentLocation,
68    );
69}
70
71/// Contains summary information about the assets stored in an input note.
72pub struct InputNoteAssetsInfo {
73    pub commitment: Word,
74    pub num_assets: Felt,
75}
76
77/// Contains summary information about the storage stored in an input note.
78pub struct InputNoteStorageInfo {
79    pub commitment: Word,
80    pub num_storage_items: Felt,
81}
82
83/// Returns the assets commitment and asset count for the input note at `note_index`.
84pub fn get_assets_info(note_index: NoteIdx) -> InputNoteAssetsInfo {
85    unsafe {
86        let mut ret_area = ::core::mem::MaybeUninit::<(Word, Felt)>::uninit();
87        extern_input_note_get_assets_info(note_index.inner, ret_area.as_mut_ptr());
88        let (commitment, num_assets) = ret_area.assume_init();
89        InputNoteAssetsInfo {
90            commitment,
91            num_assets,
92        }
93    }
94}
95
96/// Returns the assets contained in the input note at `note_index`.
97pub fn get_assets(note_index: NoteIdx) -> Vec<Asset> {
98    const MAX_ASSETS: usize = 256;
99    let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
100    let num_assets = unsafe {
101        let ptr = (assets.as_mut_ptr() as usize) / 4;
102        extern_input_note_get_assets(ptr as *mut Felt, note_index.inner)
103    };
104    unsafe {
105        assets.set_len(num_assets);
106    }
107    assets
108}
109
110/// Returns the recipient of the input note at `note_index`.
111pub fn get_recipient(note_index: NoteIdx) -> Recipient {
112    unsafe {
113        let mut ret_area = ::core::mem::MaybeUninit::<Recipient>::uninit();
114        extern_input_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
115        ret_area.assume_init()
116    }
117}
118
119/// Returns the attachment and metadata header of the input note at `note_index`.
120pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
121    unsafe {
122        let mut ret_area = ::core::mem::MaybeUninit::<NoteMetadata>::uninit();
123        extern_input_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
124        ret_area.assume_init()
125    }
126}
127
128/// Returns the sender of the input note at `note_index`.
129pub fn get_sender(note_index: NoteIdx) -> AccountId {
130    unsafe {
131        let mut ret_area = ::core::mem::MaybeUninit::<RawAccountId>::uninit();
132        extern_input_note_get_sender(note_index.inner, ret_area.as_mut_ptr());
133        ret_area.assume_init().into_account_id()
134    }
135}
136
137/// Returns the storage commitment and storage item count for the input note at `note_index`.
138pub fn get_storage_info(note_index: NoteIdx) -> InputNoteStorageInfo {
139    unsafe {
140        let mut ret_area = ::core::mem::MaybeUninit::<(Word, Felt)>::uninit();
141        extern_input_note_get_storage_info(note_index.inner, ret_area.as_mut_ptr());
142        let (commitment, num_storage_items) = ret_area.assume_init();
143        InputNoteStorageInfo {
144            commitment,
145            num_storage_items,
146        }
147    }
148}
149
150/// Returns the script root of the input note at `note_index`.
151pub fn get_script_root(note_index: NoteIdx) -> Word {
152    unsafe {
153        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
154        extern_input_note_get_script_root(note_index.inner, ret_area.as_mut_ptr());
155        ret_area.assume_init()
156    }
157}
158
159/// Returns the serial number of the input note at `note_index`.
160pub fn get_serial_number(note_index: NoteIdx) -> Word {
161    unsafe {
162        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
163        extern_input_note_get_serial_number(note_index.inner, ret_area.as_mut_ptr());
164        ret_area.assume_init()
165    }
166}
167
168/// Returns the commitment over all attachments of the input note at `note_index`.
169pub fn get_attachments_commitment(note_index: NoteIdx) -> Word {
170    unsafe {
171        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
172        extern_input_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
173        ret_area.assume_init()
174    }
175}
176
177/// Returns the attachment commitment using the protocol's shared active/indexed input-note path.
178pub fn get_attachments_commitment_raw(is_active_note: Felt, note_index: NoteIdx) -> Word {
179    unsafe {
180        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
181        extern_input_note_get_attachments_commitment_raw(
182            is_active_note,
183            note_index.inner,
184            ret_area.as_mut_ptr(),
185        );
186        ret_area.assume_init()
187    }
188}
189
190/// Writes attachment commitments to memory and returns them as protocol words.
191pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
192    let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
193    let num_attachments = unsafe {
194        let ptr = (commitments.as_mut_ptr() as usize) / 4;
195        extern_input_note_write_attachment_commitments_to_memory(ptr as *mut Felt, note_index.inner)
196    };
197    assert!(
198        num_attachments <= MAX_ATTACHMENTS_PER_NOTE,
199        "note cannot contain more than {MAX_ATTACHMENTS_PER_NOTE} attachments"
200    );
201    unsafe {
202        commitments.set_len(num_attachments);
203    }
204    commitments
205}
206
207/// Writes the selected input-note attachment to memory and returns it as protocol words.
208pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: Felt) -> Vec<Word> {
209    let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
210    let num_words = unsafe {
211        let ptr = (attachment.as_mut_ptr() as usize) / 4;
212        extern_input_note_write_attachment_to_memory(
213            ptr as *mut Felt,
214            attachment_idx,
215            note_index.inner,
216        )
217    };
218    assert!(
219        num_words <= MAX_ATTACHMENT_WORDS,
220        "note attachment cannot contain more than {MAX_ATTACHMENT_WORDS} words"
221    );
222    unsafe {
223        attachment.set_len(num_words);
224    }
225    attachment
226}
227
228/// Searches the input note metadata for `attachment_scheme`.
229pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> AttachmentLocation {
230    unsafe {
231        let mut ret_area = ::core::mem::MaybeUninit::<AttachmentLocation>::uninit();
232        extern_input_note_find_attachment(
233            attachment_scheme,
234            note_index.inner,
235            ret_area.as_mut_ptr(),
236        );
237        ret_area.assume_init()
238    }
239}