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