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 Asset, NoteId, NoteIdx, NoteMetadata, NoteType, RawCommitmentWithCount, RawFoundIndex,
11 Recipient, Tag,
12 },
13};
14
15#[allow(improper_ctypes)]
16unsafe extern "C" {
17 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
18 #[link_name = "miden::protocol::output_note::create"]
19 pub fn extern_output_note_create(
20 tag: Tag,
21 note_type: NoteType,
22 recipient_f0: Felt,
23 recipient_f1: Felt,
24 recipient_f2: Felt,
25 recipient_f3: Felt,
26 ) -> NoteIdx;
27 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
28 #[link_name = "miden::protocol::output_note::add_asset"]
29 pub fn extern_output_note_add_asset(
30 asset_id_f0: Felt,
31 asset_id_f1: Felt,
32 asset_id_f2: Felt,
33 asset_id_f3: Felt,
34 asset_value_f0: Felt,
35 asset_value_f1: Felt,
36 asset_value_f2: Felt,
37 asset_value_f3: Felt,
38 note_idx: NoteIdx,
39 );
40 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
41 #[link_name = "miden::protocol::output_note::get_assets_info"]
42 pub(crate) fn extern_output_note_get_assets_info(
43 note_index: Felt,
44 ptr: *mut RawCommitmentWithCount,
45 );
46 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
47 #[link_name = "miden::protocol::output_note::get_assets"]
48 pub fn extern_output_note_get_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
49 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
50 #[link_name = "miden::protocol::output_note::get_attachments_commitment"]
51 pub fn extern_output_note_get_attachments_commitment(note_index: Felt, ptr: *mut Word);
52 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
53 #[link_name = "miden::protocol::output_note::get_recipient"]
54 pub fn extern_output_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
55 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
56 #[link_name = "miden::protocol::output_note::get_metadata"]
57 pub fn extern_output_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
58 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
59 #[link_name = "miden::protocol::output_note::add_word_attachment"]
60 pub fn extern_output_note_add_word_attachment(
61 attachment_scheme: Felt,
62 attachment_f0: Felt,
63 attachment_f1: Felt,
64 attachment_f2: Felt,
65 attachment_f3: Felt,
66 note_idx: NoteIdx,
67 );
68 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
69 #[link_name = "miden::protocol::output_note::add_attachment"]
70 pub fn extern_output_note_add_attachment(
71 attachment_scheme: Felt,
72 attachment_f0: Felt,
73 attachment_f1: Felt,
74 attachment_f2: Felt,
75 attachment_f3: Felt,
76 note_idx: NoteIdx,
77 );
78 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
79 #[link_name = "miden::protocol::output_note::add_attachment_from_memory"]
80 pub fn extern_output_note_add_attachment_from_memory(
81 attachment_scheme: Felt,
82 num_words: usize,
83 attachment_ptr: *const Felt,
84 note_idx: NoteIdx,
85 );
86 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
87 #[link_name = "miden::protocol::output_note::find_attachment"]
88 pub(crate) fn extern_output_note_find_attachment(
89 attachment_scheme: Felt,
90 note_index: Felt,
91 ptr: *mut RawFoundIndex,
92 );
93 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
94 #[link_name = "miden::protocol::output_note::write_attachment_commitments_to_memory"]
95 pub fn extern_output_note_write_attachment_commitments_to_memory(
96 dest_ptr: *mut Felt,
97 note_index: Felt,
98 ) -> usize;
99 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
100 #[link_name = "miden::protocol::output_note::write_attachment_to_memory"]
101 pub fn extern_output_note_write_attachment_to_memory(
102 dest_ptr: *mut Felt,
103 attachment_idx: Felt,
104 note_index: Felt,
105 ) -> usize;
106 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
107 #[link_name = "miden::protocol::output_note::compute_note_id"]
108 fn extern_output_note_compute_note_id(note_idx: Felt, ptr: *mut NoteId);
109 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
110 #[link_name = "miden::protocol::output_note::seal"]
111 fn extern_output_note_seal(note_index: Felt);
112 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
113 #[link_name = "miden::protocol::output_note::is_sealed"]
114 fn extern_output_note_is_sealed(note_index: Felt) -> Felt;
115}
116
117pub fn create(tag: Tag, note_type: NoteType, recipient: Recipient) -> NoteIdx {
149 unsafe {
150 extern_output_note_create(
151 tag,
152 note_type,
153 recipient.inner[0],
154 recipient.inner[1],
155 recipient.inner[2],
156 recipient.inner[3],
157 )
158 }
159}
160
161pub fn add_word_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
163 unsafe {
164 extern_output_note_add_word_attachment(
165 attachment_scheme,
166 attachment[0],
167 attachment[1],
168 attachment[2],
169 attachment[3],
170 note_idx,
171 );
172 }
173}
174
175pub fn add_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
179 unsafe {
180 extern_output_note_add_attachment(
181 attachment_scheme,
182 attachment[0],
183 attachment[1],
184 attachment[2],
185 attachment[3],
186 note_idx,
187 );
188 }
189}
190
191pub fn add_attachment_from_memory(note_idx: NoteIdx, attachment_scheme: Felt, attachment: &[Word]) {
196 assert!(!attachment.is_empty(), "note attachment cannot be empty");
197 assert_attachment_word_count(attachment.len());
198 let ptr = (attachment.as_ptr().addr() / 4) as u32;
199
200 unsafe {
201 extern_output_note_add_attachment_from_memory(
202 attachment_scheme,
203 attachment.len(),
204 ptr as *const Felt,
205 note_idx,
206 );
207 }
208}
209
210pub fn add_asset(asset: Asset, note_idx: NoteIdx) {
227 let id = asset.id.inner;
228 unsafe {
229 extern_output_note_add_asset(
230 id[0],
231 id[1],
232 id[2],
233 id[3],
234 asset.value[0],
235 asset.value[1],
236 asset.value[2],
237 asset.value[3],
238 note_idx,
239 );
240 }
241}
242
243pub fn seal(note_index: NoteIdx) {
253 unsafe { extern_output_note_seal(note_index.inner) }
254}
255
256pub fn is_sealed(note_index: NoteIdx) -> bool {
263 unsafe { extern_output_note_is_sealed(note_index.inner) != Felt::new(0).unwrap() }
264}
265
266pub struct OutputNoteAssetsInfo {
268 pub commitment: Word,
269 pub num_assets: u32,
270}
271
272pub fn get_assets_info(note_index: NoteIdx) -> OutputNoteAssetsInfo {
274 unsafe {
275 let mut ret_area =
276 WordAligned::new(::core::mem::MaybeUninit::<RawCommitmentWithCount>::uninit());
277 extern_output_note_get_assets_info(note_index.inner, ret_area.as_mut_ptr());
278 let raw = ret_area.into_inner().assume_init();
279 OutputNoteAssetsInfo {
280 commitment: raw.commitment,
281 num_assets: raw.num_items(),
282 }
283 }
284}
285
286pub fn get_assets(note_index: NoteIdx) -> Vec<Asset> {
288 const MAX_ASSETS: usize = 256;
289 let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
290 let num_assets = unsafe {
291 let ptr = (assets.as_mut_ptr() as usize) / 4;
292 extern_output_note_get_assets(ptr as *mut Felt, note_index.inner)
293 };
294 unsafe {
295 assets.set_len(num_assets);
296 }
297 assets
298}
299
300pub fn get_attachments_commitment(note_index: NoteIdx) -> Word {
302 unsafe {
303 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
304 extern_output_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
305 ret_area.into_inner().assume_init()
306 }
307}
308
309pub fn get_recipient(note_index: NoteIdx) -> Recipient {
311 unsafe {
312 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
313 extern_output_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
314 ret_area.into_inner().assume_init()
315 }
316}
317
318pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
320 unsafe {
321 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteMetadata>::uninit());
322 extern_output_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
323 ret_area.into_inner().assume_init()
324 }
325}
326
327pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> Option<u32> {
329 unsafe {
330 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawFoundIndex>::uninit());
331 extern_output_note_find_attachment(
332 attachment_scheme,
333 note_index.inner,
334 ret_area.as_mut_ptr(),
335 );
336 ret_area.into_inner().assume_init().into_attachment_index()
337 }
338}
339
340pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
344 let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
345 let num_attachments = unsafe {
346 let ptr = (commitments.as_mut_ptr() as usize) / 4;
347 extern_output_note_write_attachment_commitments_to_memory(
348 ptr as *mut Felt,
349 note_index.inner,
350 )
351 };
352 assert_attachment_count(num_attachments);
353 unsafe {
354 commitments.set_len(num_attachments);
355 }
356 commitments
357}
358
359pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: u32) -> Vec<Word> {
364 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
365 let num_words = unsafe {
366 let ptr = (attachment.as_mut_ptr() as usize) / 4;
367 extern_output_note_write_attachment_to_memory(
368 ptr as *mut Felt,
369 Felt::from_u32(attachment_idx),
370 note_index.inner,
371 )
372 };
373 assert_attachment_word_count(num_words);
374 unsafe {
375 attachment.set_len(num_words);
376 }
377 attachment
378}
379
380pub fn compute_note_id(note_index: NoteIdx) -> NoteId {
389 unsafe {
390 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteId>::uninit());
391 extern_output_note_compute_note_id(note_index.inner, ret_area.as_mut_ptr());
392 ret_area.into_inner().assume_init()
393 }
394}