miden_base_sys/bindings/
active_note.rs

1extern crate alloc;
2use alloc::vec::Vec;
3
4use miden_stdlib_sys::{Felt, Word};
5
6use super::{AccountId, Asset, Recipient};
7
8#[allow(improper_ctypes)]
9unsafe extern "C" {
10    #[link_name = "miden::active_note::get_inputs"]
11    pub fn extern_note_get_inputs(ptr: *mut Felt) -> usize;
12    #[link_name = "miden::active_note::get_assets"]
13    pub fn extern_note_get_assets(ptr: *mut Felt) -> usize;
14    #[link_name = "miden::active_note::get_sender"]
15    pub fn extern_note_get_sender(ptr: *mut AccountId);
16    #[link_name = "miden::active_note::get_recipient"]
17    pub fn extern_note_get_recipient(ptr: *mut Recipient);
18    #[link_name = "miden::active_note::get_script_root"]
19    pub fn extern_note_get_script_root(ptr: *mut Word);
20    #[link_name = "miden::active_note::get_serial_number"]
21    pub fn extern_note_get_serial_number(ptr: *mut Word);
22    #[link_name = "miden::active_note::get_metadata"]
23    pub fn extern_note_get_metadata(ptr: *mut Word);
24    #[link_name = "miden::active_note::add_assets_to_account"]
25    pub fn extern_note_add_assets_to_account();
26}
27
28/// Get the inputs of the currently executing note.
29pub fn get_inputs() -> Vec<Felt> {
30    const MAX_INPUTS: usize = 256;
31    let mut inputs: Vec<Felt> = Vec::with_capacity(MAX_INPUTS);
32    let num_inputs = unsafe {
33        // Ensure the pointer is a valid Miden pointer
34        //
35        // NOTE: This relies on the fact that BumpAlloc makes all allocations
36        // minimally word-aligned. Each word consists of 4 elements of 4 bytes.
37        // Since Miden VM is field element-addressable, to get a Miden address from a Rust address,
38        // we divide it by 4 to get the address in field elements.
39        let ptr = (inputs.as_mut_ptr() as usize) / 4;
40        // The MASM for this function is here:
41        // https://github.com/0xMiden/miden-base/blob/3cbe8d59dcf4ccc9c380b7c8417ac6178fc6b86a/miden-lib/asm/miden/note.masm#L69-L102
42        // #! Writes the inputs of the currently execute note into memory starting at the specified
43        // address. #!
44        // #! Inputs: [dest_ptr]
45        // #! Outputs: [num_inputs, dest_ptr]
46        // #!
47        // #! - dest_ptr is the memory address to write the inputs.
48        // Compiler generated adapter code at call site will drop the returned dest_ptr
49        // and return the number of inputs
50        extern_note_get_inputs(ptr as *mut Felt)
51    };
52    unsafe {
53        inputs.set_len(num_inputs);
54    }
55    inputs
56}
57
58/// Get the assets of the currently executing note.
59pub fn get_assets() -> Vec<Asset> {
60    const MAX_INPUTS: usize = 256;
61    let mut inputs: Vec<Asset> = Vec::with_capacity(MAX_INPUTS);
62    let num_inputs = unsafe {
63        let ptr = (inputs.as_mut_ptr() as usize) / 4;
64        extern_note_get_assets(ptr as *mut Felt)
65    };
66    unsafe {
67        inputs.set_len(num_inputs);
68    }
69    inputs
70}
71
72/// Returns the sender [`AccountId`] of the note that is currently executing.
73pub fn get_sender() -> AccountId {
74    unsafe {
75        let mut ret_area = ::core::mem::MaybeUninit::<AccountId>::uninit();
76        extern_note_get_sender(ret_area.as_mut_ptr());
77        ret_area.assume_init()
78    }
79}
80
81/// Returns the recipient of the note that is currently executing.
82pub fn get_recipient() -> Recipient {
83    unsafe {
84        let mut ret_area = ::core::mem::MaybeUninit::<Recipient>::uninit();
85        extern_note_get_recipient(ret_area.as_mut_ptr());
86        let mut recipient = ret_area.assume_init();
87        recipient.inner = recipient.inner.reverse();
88        recipient
89    }
90}
91
92/// Returns the script root of the currently executing note.
93pub fn get_script_root() -> Word {
94    unsafe {
95        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
96        extern_note_get_script_root(ret_area.as_mut_ptr());
97        ret_area.assume_init().reverse()
98    }
99}
100
101/// Returns the serial number of the currently executing note.
102pub fn get_serial_number() -> Word {
103    unsafe {
104        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
105        extern_note_get_serial_number(ret_area.as_mut_ptr());
106        ret_area.assume_init().reverse()
107    }
108}
109
110/// Returns the metadata of the note that is currently executing.
111pub fn get_metadata() -> Word {
112    unsafe {
113        let mut ret_area = ::core::mem::MaybeUninit::<Word>::uninit();
114        extern_note_get_metadata(ret_area.as_mut_ptr());
115        ret_area.assume_init().reverse()
116    }
117}
118
119/// Moves all assets from the active note into the active account vault.
120#[inline]
121pub fn add_assets_to_account() {
122    unsafe { extern_note_add_assets_to_account() }
123}