1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word, WordAligned};
5
6use super::types::{Asset, AttachmentLocation, NoteIdx, NoteMetadata, NoteType, Recipient, Tag};
7
8const MAX_ATTACHMENTS_PER_NOTE: usize = 4;
9const MAX_ATTACHMENT_WORDS: usize = 256;
10
11#[allow(improper_ctypes)]
12unsafe extern "C" {
13 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
14 #[link_name = "miden::protocol::output_note::create"]
15 pub fn extern_output_note_create(
16 tag: Tag,
17 note_type: NoteType,
18 recipient_f0: Felt,
19 recipient_f1: Felt,
20 recipient_f2: Felt,
21 recipient_f3: Felt,
22 ) -> NoteIdx;
23 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
24 #[link_name = "miden::protocol::output_note::add_asset"]
25 pub fn extern_output_note_add_asset(
26 asset_key_f0: Felt,
27 asset_key_f1: Felt,
28 asset_key_f2: Felt,
29 asset_key_f3: Felt,
30 asset_value_f0: Felt,
31 asset_value_f1: Felt,
32 asset_value_f2: Felt,
33 asset_value_f3: Felt,
34 note_idx: NoteIdx,
35 );
36 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
37 #[link_name = "miden::protocol::output_note::get_assets_info"]
38 pub fn extern_output_note_get_assets_info(note_index: Felt, ptr: *mut (Word, Felt));
39 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
40 #[link_name = "miden::protocol::output_note::get_assets"]
41 pub fn extern_output_note_get_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
42 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
43 #[link_name = "miden::protocol::output_note::get_attachments_commitment"]
44 pub fn extern_output_note_get_attachments_commitment(note_index: Felt, ptr: *mut Word);
45 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
46 #[link_name = "miden::protocol::output_note::get_recipient"]
47 pub fn extern_output_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
48 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
49 #[link_name = "miden::protocol::output_note::get_metadata"]
50 pub fn extern_output_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
51 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
52 #[link_name = "miden::protocol::output_note::add_word_attachment"]
53 pub fn extern_output_note_add_word_attachment(
54 attachment_scheme: Felt,
55 attachment_f0: Felt,
56 attachment_f1: Felt,
57 attachment_f2: Felt,
58 attachment_f3: Felt,
59 note_idx: NoteIdx,
60 );
61 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
62 #[link_name = "miden::protocol::output_note::add_attachment"]
63 pub fn extern_output_note_add_attachment(
64 attachment_scheme: Felt,
65 attachment_f0: Felt,
66 attachment_f1: Felt,
67 attachment_f2: Felt,
68 attachment_f3: Felt,
69 note_idx: NoteIdx,
70 );
71 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
72 #[link_name = "miden::protocol::output_note::add_attachment_from_memory"]
73 pub fn extern_output_note_add_attachment_from_memory(
74 attachment_scheme: Felt,
75 num_words: usize,
76 attachment_ptr: *const Felt,
77 note_idx: NoteIdx,
78 );
79 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
80 #[link_name = "miden::protocol::output_note::find_attachment"]
81 pub fn extern_output_note_find_attachment(
82 attachment_scheme: Felt,
83 note_index: Felt,
84 ptr: *mut AttachmentLocation,
85 );
86 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
87 #[link_name = "miden::protocol::output_note::write_attachment_commitments_to_memory"]
88 pub fn extern_output_note_write_attachment_commitments_to_memory(
89 dest_ptr: *mut Felt,
90 note_index: Felt,
91 ) -> usize;
92 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
93 #[link_name = "miden::protocol::output_note::write_attachment_to_memory"]
94 pub fn extern_output_note_write_attachment_to_memory(
95 dest_ptr: *mut Felt,
96 attachment_idx: Felt,
97 note_index: Felt,
98 ) -> usize;
99}
100
101pub fn create(tag: Tag, note_type: NoteType, recipient: Recipient) -> NoteIdx {
133 unsafe {
134 extern_output_note_create(
135 tag,
136 note_type,
137 recipient.inner[0],
138 recipient.inner[1],
139 recipient.inner[2],
140 recipient.inner[3],
141 )
142 }
143}
144
145pub fn add_word_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
147 unsafe {
148 extern_output_note_add_word_attachment(
149 attachment_scheme,
150 attachment[0],
151 attachment[1],
152 attachment[2],
153 attachment[3],
154 note_idx,
155 );
156 }
157}
158
159pub fn set_word_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
161 add_word_attachment(note_idx, attachment_scheme, attachment);
162}
163
164pub fn add_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
168 unsafe {
169 extern_output_note_add_attachment(
170 attachment_scheme,
171 attachment[0],
172 attachment[1],
173 attachment[2],
174 attachment[3],
175 note_idx,
176 );
177 }
178}
179
180pub fn set_array_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
184 add_attachment(note_idx, attachment_scheme, attachment);
185}
186
187pub fn add_attachment_from_memory(note_idx: NoteIdx, attachment_scheme: Felt, attachment: &[Word]) {
189 let ptr = if attachment.is_empty() {
190 0
191 } else {
192 (attachment.as_ptr().addr() / 4) as u32
193 };
194
195 unsafe {
196 extern_output_note_add_attachment_from_memory(
197 attachment_scheme,
198 attachment.len(),
199 ptr as *const Felt,
200 note_idx,
201 );
202 }
203}
204
205pub fn add_asset(asset: Asset, note_idx: NoteIdx) {
222 unsafe {
223 extern_output_note_add_asset(
224 asset.key[0],
225 asset.key[1],
226 asset.key[2],
227 asset.key[3],
228 asset.value[0],
229 asset.value[1],
230 asset.value[2],
231 asset.value[3],
232 note_idx,
233 );
234 }
235}
236
237pub struct OutputNoteAssetsInfo {
239 pub commitment: Word,
240 pub num_assets: Felt,
241}
242
243pub fn get_assets_info(note_index: NoteIdx) -> OutputNoteAssetsInfo {
245 unsafe {
246 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<(Word, Felt)>::uninit());
247 extern_output_note_get_assets_info(note_index.inner, ret_area.as_mut_ptr());
248 let (commitment, num_assets) = ret_area.into_inner().assume_init();
249 OutputNoteAssetsInfo {
250 commitment,
251 num_assets,
252 }
253 }
254}
255
256pub fn get_assets(note_index: NoteIdx) -> Vec<Asset> {
258 const MAX_ASSETS: usize = 256;
259 let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
260 let num_assets = unsafe {
261 let ptr = (assets.as_mut_ptr() as usize) / 4;
262 extern_output_note_get_assets(ptr as *mut Felt, note_index.inner)
263 };
264 unsafe {
265 assets.set_len(num_assets);
266 }
267 assets
268}
269
270pub fn get_attachments_commitment(note_index: NoteIdx) -> Word {
272 unsafe {
273 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
274 extern_output_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
275 ret_area.into_inner().assume_init()
276 }
277}
278
279pub fn get_recipient(note_index: NoteIdx) -> Recipient {
281 unsafe {
282 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
283 extern_output_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
284 ret_area.into_inner().assume_init()
285 }
286}
287
288pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
290 unsafe {
291 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteMetadata>::uninit());
292 extern_output_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
293 ret_area.into_inner().assume_init()
294 }
295}
296
297pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> AttachmentLocation {
299 unsafe {
300 let mut ret_area =
301 WordAligned::new(::core::mem::MaybeUninit::<AttachmentLocation>::uninit());
302 extern_output_note_find_attachment(
303 attachment_scheme,
304 note_index.inner,
305 ret_area.as_mut_ptr(),
306 );
307 ret_area.into_inner().assume_init()
308 }
309}
310
311pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
313 let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
314 let num_attachments = unsafe {
315 let ptr = (commitments.as_mut_ptr() as usize) / 4;
316 extern_output_note_write_attachment_commitments_to_memory(
317 ptr as *mut Felt,
318 note_index.inner,
319 )
320 };
321 assert!(
322 num_attachments <= MAX_ATTACHMENTS_PER_NOTE,
323 "note cannot contain more than {MAX_ATTACHMENTS_PER_NOTE} attachments"
324 );
325 unsafe {
326 commitments.set_len(num_attachments);
327 }
328 commitments
329}
330
331pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: Felt) -> Vec<Word> {
333 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
334 let num_words = unsafe {
335 let ptr = (attachment.as_mut_ptr() as usize) / 4;
336 extern_output_note_write_attachment_to_memory(
337 ptr as *mut Felt,
338 attachment_idx,
339 note_index.inner,
340 )
341 };
342 assert!(
343 num_words <= MAX_ATTACHMENT_WORDS,
344 "note attachment cannot contain more than {MAX_ATTACHMENT_WORDS} words"
345 );
346 unsafe {
347 attachment.set_len(num_words);
348 }
349 attachment
350}