Skip to main content

miden_base_sys/bindings/
output_note.rs

1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word};
5
6use super::types::{Asset, NoteIdx, NoteMetadata, NoteType, Recipient, Tag};
7
8#[allow(improper_ctypes)]
9unsafe extern "C" {
10    #[link_name = "miden::protocol::output_note::create"]
11    pub fn extern_output_note_create(
12        tag: Tag,
13        note_type: NoteType,
14        recipient_f0: Felt,
15        recipient_f1: Felt,
16        recipient_f2: Felt,
17        recipient_f3: Felt,
18    ) -> NoteIdx;
19
20    #[link_name = "miden::protocol::output_note::add_asset"]
21    pub fn extern_output_note_add_asset(
22        asset_f0: Felt,
23        asset_f1: Felt,
24        asset_f2: Felt,
25        asset_f3: Felt,
26        note_idx: NoteIdx,
27    );
28
29    #[link_name = "miden::protocol::output_note::get_assets_info"]
30    pub fn extern_output_note_get_assets_info(note_index: Felt, ptr: *mut (Word, Felt));
31
32    #[link_name = "miden::protocol::output_note::get_assets"]
33    pub fn extern_output_note_get_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
34
35    #[link_name = "miden::protocol::output_note::get_recipient"]
36    pub fn extern_output_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
37
38    #[link_name = "miden::protocol::output_note::get_metadata"]
39    pub fn extern_output_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
40
41    #[link_name = "miden::protocol::output_note::set_attachment"]
42    pub fn extern_output_note_set_attachment(
43        note_idx: NoteIdx,
44        attachment_scheme: Felt,
45        attachment_kind: Felt,
46        attachment_f0: Felt,
47        attachment_f1: Felt,
48        attachment_f2: Felt,
49        attachment_f3: Felt,
50    );
51
52    #[link_name = "miden::protocol::output_note::set_word_attachment"]
53    pub fn extern_output_note_set_word_attachment(
54        note_idx: NoteIdx,
55        attachment_scheme: Felt,
56        attachment_f0: Felt,
57        attachment_f1: Felt,
58        attachment_f2: Felt,
59        attachment_f3: Felt,
60    );
61
62    #[link_name = "miden::protocol::output_note::set_array_attachment"]
63    pub fn extern_output_note_set_array_attachment(
64        note_idx: NoteIdx,
65        attachment_scheme: Felt,
66        attachment_f0: Felt,
67        attachment_f1: Felt,
68        attachment_f2: Felt,
69        attachment_f3: Felt,
70    );
71}
72
73/// Creates a new output note and returns its index.
74///
75/// # Examples
76///
77/// Create a note and add a single asset to it:
78///
79/// ```rust,ignore
80/// // before using `Vec`/`vec!`.
81/// extern crate alloc;
82///
83/// use miden::{felt, output_note, Asset, Digest, NoteType, Recipient, Tag, Word};
84///
85/// // Values used to derive the note recipient.
86/// let serial_num = Word::from_u64_unchecked(1, 2, 3, 4);
87/// let note_script_root = Digest::from_word(Word::from_u64_unchecked(0, 0, 0, 0));
88///
89/// // Note inputs are hashed via `hash_elements`.
90/// let inputs = alloc::vec![felt!(0); 2];
91/// let recipient = Recipient::compute(serial_num, note_script_root, inputs);
92///
93/// let tag = Tag::from(felt!(0));
94/// let note_type = NoteType::from(felt!(1)); // public note type (0b01)
95///
96/// let note_idx = output_note::create(tag, note_type, recipient);
97/// output_note::add_asset(Asset::new([felt!(0), felt!(0), felt!(0), felt!(1)]), note_idx);
98/// ```
99pub fn create(tag: Tag, note_type: NoteType, recipient: Recipient) -> NoteIdx {
100    unsafe {
101        extern_output_note_create(
102            tag,
103            note_type,
104            recipient.inner[3],
105            recipient.inner[2],
106            recipient.inner[1],
107            recipient.inner[0],
108        )
109    }
110}
111
112/// Sets the attachment of the output note specified by `note_idx`.
113pub fn set_attachment(
114    note_idx: NoteIdx,
115    attachment_scheme: Felt,
116    attachment_kind: Felt,
117    attachment: Word,
118) {
119    unsafe {
120        extern_output_note_set_attachment(
121            note_idx,
122            attachment_scheme,
123            attachment_kind,
124            attachment[3],
125            attachment[2],
126            attachment[1],
127            attachment[0],
128        );
129    }
130}
131
132/// Sets the attachment of the output note specified by `note_idx` to the provided word.
133pub fn set_word_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
134    unsafe {
135        extern_output_note_set_word_attachment(
136            note_idx,
137            attachment_scheme,
138            attachment[3],
139            attachment[2],
140            attachment[1],
141            attachment[0],
142        );
143    }
144}
145
146/// Sets the attachment of the output note specified by `note_idx` to the provided commitment.
147///
148/// The advice map must contain an entry for the attachment elements committed to by `attachment`.
149pub fn set_array_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
150    unsafe {
151        extern_output_note_set_array_attachment(
152            note_idx,
153            attachment_scheme,
154            attachment[3],
155            attachment[2],
156            attachment[1],
157            attachment[0],
158        );
159    }
160}
161
162/// Adds the asset to the output note specified by `note_idx`.
163///
164/// # Examples
165///
166/// ```rust,ignore
167/// use miden::{felt, output_note, Asset, NoteIdx};
168///
169/// // `note_idx` is returned by `output_note::create(...)`.
170/// let note_idx: NoteIdx = /* ... */
171///
172/// let asset = Asset::new([felt!(0), felt!(0), felt!(0), felt!(1)]);
173/// output_note::add_asset(asset, note_idx);
174/// ```
175pub fn add_asset(asset: Asset, note_idx: NoteIdx) {
176    unsafe {
177        extern_output_note_add_asset(
178            asset.inner[3],
179            asset.inner[2],
180            asset.inner[1],
181            asset.inner[0],
182            note_idx,
183        );
184    }
185}
186
187/// Contains summary information about the assets of an output note.
188pub struct OutputNoteAssetsInfo {
189    pub commitment: Word,
190    pub num_assets: Felt,
191}
192
193/// Retrieves the assets commitment and asset count for the output note at `note_index`.
194pub fn get_assets_info(note_index: NoteIdx) -> OutputNoteAssetsInfo {
195    unsafe {
196        let mut ret_area = ::core::mem::MaybeUninit::<(Word, Felt)>::uninit();
197        extern_output_note_get_assets_info(note_index.inner, ret_area.as_mut_ptr());
198        let (commitment, num_assets) = ret_area.assume_init();
199        OutputNoteAssetsInfo {
200            commitment: commitment.reverse(),
201            num_assets,
202        }
203    }
204}
205
206/// Returns the assets contained in the output note at `note_index`.
207pub fn get_assets(note_index: NoteIdx) -> Vec<Asset> {
208    const MAX_ASSETS: usize = 256;
209    let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
210    let num_assets = unsafe {
211        let ptr = (assets.as_mut_ptr() as usize) / 4;
212        extern_output_note_get_assets(ptr as *mut Felt, note_index.inner)
213    };
214    unsafe {
215        assets.set_len(num_assets);
216    }
217    assets
218}
219
220/// Returns the recipient of the output note at `note_index`.
221pub fn get_recipient(note_index: NoteIdx) -> Recipient {
222    unsafe {
223        let mut ret_area = ::core::mem::MaybeUninit::<Recipient>::uninit();
224        extern_output_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
225        let recipient = ret_area.assume_init();
226        Recipient {
227            inner: recipient.inner.reverse(),
228        }
229    }
230}
231
232/// Returns the attachment and metadata header of the output note at `note_index`.
233pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
234    unsafe {
235        let mut ret_area = ::core::mem::MaybeUninit::<NoteMetadata>::uninit();
236        extern_output_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
237        ret_area.assume_init().reverse()
238    }
239}