1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word};
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 = ::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.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 = ::core::mem::MaybeUninit::<Word>::uninit();
274 extern_output_note_get_attachments_commitment(note_index.inner, ret_area.as_mut_ptr());
275 ret_area.assume_init()
276 }
277}
278
279pub fn get_recipient(note_index: NoteIdx) -> Recipient {
281 unsafe {
282 let mut ret_area = ::core::mem::MaybeUninit::<Recipient>::uninit();
283 extern_output_note_get_recipient(note_index.inner, ret_area.as_mut_ptr());
284 ret_area.assume_init()
285 }
286}
287
288pub fn get_metadata(note_index: NoteIdx) -> NoteMetadata {
290 unsafe {
291 let mut ret_area = ::core::mem::MaybeUninit::<NoteMetadata>::uninit();
292 extern_output_note_get_metadata(note_index.inner, ret_area.as_mut_ptr());
293 ret_area.assume_init()
294 }
295}
296
297pub fn find_attachment(note_index: NoteIdx, attachment_scheme: Felt) -> AttachmentLocation {
299 unsafe {
300 let mut ret_area = ::core::mem::MaybeUninit::<AttachmentLocation>::uninit();
301 extern_output_note_find_attachment(
302 attachment_scheme,
303 note_index.inner,
304 ret_area.as_mut_ptr(),
305 );
306 ret_area.assume_init()
307 }
308}
309
310pub fn write_attachment_commitments_to_memory(note_index: NoteIdx) -> Vec<Word> {
312 let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
313 let num_attachments = unsafe {
314 let ptr = (commitments.as_mut_ptr() as usize) / 4;
315 extern_output_note_write_attachment_commitments_to_memory(
316 ptr as *mut Felt,
317 note_index.inner,
318 )
319 };
320 assert!(
321 num_attachments <= MAX_ATTACHMENTS_PER_NOTE,
322 "note cannot contain more than {MAX_ATTACHMENTS_PER_NOTE} attachments"
323 );
324 unsafe {
325 commitments.set_len(num_attachments);
326 }
327 commitments
328}
329
330pub fn write_attachment_to_memory(note_index: NoteIdx, attachment_idx: Felt) -> Vec<Word> {
332 let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
333 let num_words = unsafe {
334 let ptr = (attachment.as_mut_ptr() as usize) / 4;
335 extern_output_note_write_attachment_to_memory(
336 ptr as *mut Felt,
337 attachment_idx,
338 note_index.inner,
339 )
340 };
341 assert!(
342 num_words <= MAX_ATTACHMENT_WORDS,
343 "note attachment cannot contain more than {MAX_ATTACHMENT_WORDS} words"
344 );
345 unsafe {
346 attachment.set_len(num_words);
347 }
348 attachment
349}