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::{Asset, NoteIdx, NoteMetadata, NoteType, RawAttachmentLocation, Recipient, Tag},
10};
11
12#[allow(improper_ctypes)]
13unsafe extern "C" {
14 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
15 #[link_name = "miden::protocol::output_note::create"]
16 pub fn extern_output_note_create(
17 tag: Tag,
18 note_type: NoteType,
19 recipient_f0: Felt,
20 recipient_f1: Felt,
21 recipient_f2: Felt,
22 recipient_f3: Felt,
23 ) -> NoteIdx;
24 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
25 #[link_name = "miden::protocol::output_note::add_asset"]
26 pub fn extern_output_note_add_asset(
27 asset_key_f0: Felt,
28 asset_key_f1: Felt,
29 asset_key_f2: Felt,
30 asset_key_f3: Felt,
31 asset_value_f0: Felt,
32 asset_value_f1: Felt,
33 asset_value_f2: Felt,
34 asset_value_f3: Felt,
35 note_idx: NoteIdx,
36 );
37 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
38 #[link_name = "miden::protocol::output_note::get_assets_info"]
39 pub fn extern_output_note_get_assets_info(note_index: Felt, ptr: *mut (Word, Felt));
40 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
41 #[link_name = "miden::protocol::output_note::get_assets"]
42 pub fn extern_output_note_get_assets(dest_ptr: *mut Felt, note_index: Felt) -> usize;
43 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
44 #[link_name = "miden::protocol::output_note::get_attachments_commitment"]
45 pub fn extern_output_note_get_attachments_commitment(note_index: Felt, ptr: *mut Word);
46 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
47 #[link_name = "miden::protocol::output_note::get_recipient"]
48 pub fn extern_output_note_get_recipient(note_index: Felt, ptr: *mut Recipient);
49 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
50 #[link_name = "miden::protocol::output_note::get_metadata"]
51 pub fn extern_output_note_get_metadata(note_index: Felt, ptr: *mut NoteMetadata);
52 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
53 #[link_name = "miden::protocol::output_note::add_word_attachment"]
54 pub fn extern_output_note_add_word_attachment(
55 attachment_scheme: Felt,
56 attachment_f0: Felt,
57 attachment_f1: Felt,
58 attachment_f2: Felt,
59 attachment_f3: Felt,
60 note_idx: NoteIdx,
61 );
62 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
63 #[link_name = "miden::protocol::output_note::add_attachment"]
64 pub fn extern_output_note_add_attachment(
65 attachment_scheme: Felt,
66 attachment_f0: Felt,
67 attachment_f1: Felt,
68 attachment_f2: Felt,
69 attachment_f3: Felt,
70 note_idx: NoteIdx,
71 );
72 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
73 #[link_name = "miden::protocol::output_note::add_attachment_from_memory"]
74 pub fn extern_output_note_add_attachment_from_memory(
75 attachment_scheme: Felt,
76 num_words: usize,
77 attachment_ptr: *const Felt,
78 note_idx: NoteIdx,
79 );
80 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
81 #[link_name = "miden::protocol::output_note::find_attachment"]
82 pub(crate) fn extern_output_note_find_attachment(
83 attachment_scheme: Felt,
84 note_index: Felt,
85 ptr: *mut RawAttachmentLocation,
86 );
87 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
88 #[link_name = "miden::protocol::output_note::write_attachment_commitments_to_memory"]
89 pub fn extern_output_note_write_attachment_commitments_to_memory(
90 dest_ptr: *mut Felt,
91 note_index: Felt,
92 ) -> usize;
93 #[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
94 #[link_name = "miden::protocol::output_note::write_attachment_to_memory"]
95 pub fn extern_output_note_write_attachment_to_memory(
96 dest_ptr: *mut Felt,
97 attachment_idx: Felt,
98 note_index: Felt,
99 ) -> usize;
100}
101
102pub fn create(tag: Tag, note_type: NoteType, recipient: Recipient) -> NoteIdx {
134 unsafe {
135 extern_output_note_create(
136 tag,
137 note_type,
138 recipient.inner[0],
139 recipient.inner[1],
140 recipient.inner[2],
141 recipient.inner[3],
142 )
143 }
144}
145
146pub fn add_word_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
148 unsafe {
149 extern_output_note_add_word_attachment(
150 attachment_scheme,
151 attachment[0],
152 attachment[1],
153 attachment[2],
154 attachment[3],
155 note_idx,
156 );
157 }
158}
159
160pub fn add_attachment(note_idx: NoteIdx, attachment_scheme: Felt, attachment: Word) {
164 unsafe {
165 extern_output_note_add_attachment(
166 attachment_scheme,
167 attachment[0],
168 attachment[1],
169 attachment[2],
170 attachment[3],
171 note_idx,
172 );
173 }
174}
175
176pub fn add_attachment_from_memory(note_idx: NoteIdx, attachment_scheme: Felt, attachment: &[Word]) {
181 assert!(!attachment.is_empty(), "note attachment cannot be empty");
182 assert_attachment_word_count(attachment.len());
183 let ptr = (attachment.as_ptr().addr() / 4) as u32;
184
185 unsafe {
186 extern_output_note_add_attachment_from_memory(
187 attachment_scheme,
188 attachment.len(),
189 ptr as *const Felt,
190 note_idx,
191 );
192 }
193}
194
195pub fn add_asset(asset: Asset, note_idx: NoteIdx) {
212 unsafe {
213 extern_output_note_add_asset(
214 asset.key[0],
215 asset.key[1],
216 asset.key[2],
217 asset.key[3],
218 asset.value[0],
219 asset.value[1],
220 asset.value[2],
221 asset.value[3],
222 note_idx,
223 );
224 }
225}
226
227pub struct OutputNoteAssetsInfo {
229 pub commitment: Word,
230 pub num_assets: u32,
231}
232
233pub fn get_assets_info(note_index: NoteIdx) -> OutputNoteAssetsInfo {
235 unsafe {
236 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<(Word, Felt)>::uninit());
237 extern_output_note_get_assets_info(note_index.inner, ret_area.as_mut_ptr());
238 let (commitment, num_assets) = ret_area.into_inner().assume_init();
239 OutputNoteAssetsInfo {
240 commitment,
241 num_assets: num_assets.as_canonical_u64() as u32,
243 }
244 }
245}
246
247pub fn get_assets(note_index: NoteIdx) -> Vec<Asset> {
249 const MAX_ASSETS: usize = 256;
250 let mut assets: Vec<Asset> = Vec::with_capacity(MAX_ASSETS);
251 let num_assets = unsafe {
252 let ptr = (assets.as_mut_ptr() as usize) / 4;
253 extern_output_note_get_assets(ptr as *mut Felt, note_index.inner)
254 };
255 unsafe {
256 assets.set_len(num_assets);
257 }
258 assets
259}
260
261pub fn get_attachments_commitment(note_index: NoteIdx) -> Word {
263 unsafe {
264 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
265 extern_output_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
266 ret_area.into_inner().assume_init()
267 }
268}
269
270pub fn get_recipient(note_index: NoteIdx) -> Recipient {
272 unsafe {
273 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
274 extern_output_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
275 ret_area.into_inner().assume_init()
276 }
277}
278
279pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
281 unsafe {
282 let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteMetadata>::uninit());
283 extern_output_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
284 ret_area.into_inner().assume_init()
285 }
286}
287
288pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> Option<u32> {
290 unsafe {
291 let mut ret_area =
292 WordAligned::new(::core::mem::MaybeUninit::<RawAttachmentLocation>::uninit());
293 extern_output_note_find_attachment(
294 attachment_scheme,
295 note_index.inner,
296 ret_area.as_mut_ptr(),
297 );
298 ret_area.into_inner().assume_init().into_attachment_index()
299 }
300}
301
302pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
304 let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
305 let num_attachments = unsafe {
306 let ptr = (commitments.as_mut_ptr() as usize) / 4;
307 extern_output_note_write_attachment_commitments_to_memory(
308 ptr as *mut Felt,
309 note_index.inner,
310 )
311 };
312 assert_attachment_count(num_attachments);
313 unsafe {
314 commitments.set_len(num_attachments);
315 }
316 commitments
317}
318
319pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: u32) -> Vec<Word> {
321 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
322 let num_words = unsafe {
323 let ptr = (attachment.as_mut_ptr() as usize) / 4;
324 extern_output_note_write_attachment_to_memory(
325 ptr as *mut Felt,
326 Felt::from_u32(attachment_idx),
327 note_index.inner,
328 )
329 };
330 assert_attachment_word_count(num_words);
331 unsafe {
332 attachment.set_len(num_words);
333 }
334 attachment
335}