extern crate alloc;
use alloc::vec::Vec;
use miden_stdlib_sys::{Felt, Word, WordAligned};
use super::{
AccountId, Asset, MAX_ATTACHMENT_WORDS, MAX_ATTACHMENTS_PER_NOTE, NoteId, NoteMetadata,
RawAccountId, RawCommitmentWithCount, RawFoundIndex, Recipient, assert_attachment_count,
assert_attachment_word_count,
};
#[allow(improper_ctypes)]
unsafe extern "C" {
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_storage"]
fn extern_note_get_storage(ptr: *mut Felt) -> usize;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_initial_assets"]
fn extern_note_get_initial_assets(ptr: *mut Felt) -> usize;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_sender"]
fn extern_note_get_sender(ptr: *mut RawAccountId);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_recipient"]
fn extern_note_get_recipient(ptr: *mut Recipient);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_script_root"]
fn extern_note_get_script_root(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_serial_number"]
fn extern_note_get_serial_number(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_metadata"]
fn extern_note_get_metadata(ptr: *mut NoteMetadata);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::is_public"]
fn extern_note_is_public() -> Felt;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::is_private"]
fn extern_note_is_private() -> Felt;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_attachments_commitment"]
fn extern_note_get_attachments_commitment(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::write_attachment_commitments_to_memory"]
fn extern_note_write_attachment_commitments_to_memory(dest_ptr: *mut Felt) -> usize;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::write_attachment_to_memory"]
fn extern_note_write_attachment_to_memory(dest_ptr: *mut Felt, attachment_idx: Felt) -> usize;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::find_attachment"]
fn extern_note_find_attachment(attachment_scheme: Felt, ptr: *mut RawFoundIndex);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_initial_assets_info"]
fn extern_active_note_get_initial_assets_info(ptr: *mut RawCommitmentWithCount);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_initial_num_assets"]
fn extern_active_note_get_initial_num_assets() -> Felt;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_asset"]
fn extern_active_note_get_asset(asset_index: Felt, ptr: *mut Asset);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::remove_asset"]
fn extern_active_note_remove_asset(
asset_id_0: Felt,
asset_id_1: Felt,
asset_id_2: Felt,
asset_id_3: Felt,
asset_value_0: Felt,
asset_value_1: Felt,
asset_value_2: Felt,
asset_value_3: Felt,
ptr: *mut Word,
);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_note_id"]
fn extern_active_note_get_note_id(ptr: *mut NoteId);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_note::get_storage_info"]
fn extern_active_note_get_storage_info(ptr: *mut RawCommitmentWithCount);
}
pub struct ActiveNoteAssetsInfo {
pub commitment: Word,
pub num_assets: u32,
}
pub struct ActiveNoteStorageInfo {
pub commitment: Word,
pub num_storage_items: u32,
}
pub fn get_storage() -> Vec<Felt> {
const MAX_INPUTS: usize = 1024;
let mut inputs: Vec<Felt> = Vec::with_capacity(MAX_INPUTS);
let num_inputs = unsafe {
let ptr = (inputs.as_mut_ptr() as usize) / 4;
extern_note_get_storage(ptr as *mut Felt)
};
unsafe {
inputs.set_len(num_inputs);
}
inputs
}
pub fn get_initial_assets() -> Vec<Asset> {
const MAX_INPUTS: usize = 256;
let mut inputs: Vec<Asset> = Vec::with_capacity(MAX_INPUTS);
let num_inputs = unsafe {
let ptr = (inputs.as_mut_ptr() as usize) / 4;
extern_note_get_initial_assets(ptr as *mut Felt)
};
unsafe {
inputs.set_len(num_inputs);
}
inputs
}
pub fn get_sender() -> AccountId {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawAccountId>::uninit());
extern_note_get_sender(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init().into_account_id()
}
}
pub fn get_recipient() -> Recipient {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Recipient>::uninit());
extern_note_get_recipient(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn get_script_root() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_note_get_script_root(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn get_serial_number() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_note_get_serial_number(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn get_metadata() -> NoteMetadata {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteMetadata>::uninit());
extern_note_get_metadata(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
#[inline]
pub fn is_public() -> bool {
unsafe { extern_note_is_public() != Felt::new(0).unwrap() }
}
#[inline]
pub fn is_private() -> bool {
unsafe { extern_note_is_private() != Felt::new(0).unwrap() }
}
pub fn get_attachments_commitment() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_note_get_attachments_commitment(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn write_attachment_commitments_to_memory() -> Vec<Word> {
let mut commitments: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENTS_PER_NOTE);
let num_attachments = unsafe {
let ptr = (commitments.as_mut_ptr() as usize) / 4;
extern_note_write_attachment_commitments_to_memory(ptr as *mut Felt)
};
assert_attachment_count(num_attachments);
unsafe {
commitments.set_len(num_attachments);
}
commitments
}
pub fn write_attachment_to_memory(attachment_idx: u32) -> Vec<Word> {
let mut attachment: Vec<Word> = Vec::with_capacity(MAX_ATTACHMENT_WORDS);
let num_words = unsafe {
let ptr = (attachment.as_mut_ptr() as usize) / 4;
extern_note_write_attachment_to_memory(ptr as *mut Felt, Felt::from_u32(attachment_idx))
};
assert_attachment_word_count(num_words);
unsafe {
attachment.set_len(num_words);
}
attachment
}
pub fn find_attachment(attachment_scheme: Felt) -> Option<u32> {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawFoundIndex>::uninit());
extern_note_find_attachment(attachment_scheme, ret_area.as_mut_ptr());
ret_area.into_inner().assume_init().into_attachment_index()
}
}
pub fn get_initial_assets_info() -> ActiveNoteAssetsInfo {
unsafe {
let mut ret_area =
WordAligned::new(::core::mem::MaybeUninit::<RawCommitmentWithCount>::uninit());
extern_active_note_get_initial_assets_info(ret_area.as_mut_ptr());
let raw = ret_area.into_inner().assume_init();
ActiveNoteAssetsInfo {
commitment: raw.commitment,
num_assets: raw.num_items(),
}
}
}
#[inline]
pub fn get_initial_num_assets() -> u32 {
let count = unsafe { extern_active_note_get_initial_num_assets() };
count.as_canonical_u64() as u32
}
pub fn get_asset(asset_index: u32) -> Asset {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Asset>::uninit());
extern_active_note_get_asset(Felt::from_u32(asset_index), ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn remove_asset(asset: Asset) -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
let id = asset.id.inner;
extern_active_note_remove_asset(
id[0],
id[1],
id[2],
id[3],
asset.value[0],
asset.value[1],
asset.value[2],
asset.value[3],
ret_area.as_mut_ptr(),
);
ret_area.into_inner().assume_init()
}
}
pub fn get_note_id() -> NoteId {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<NoteId>::uninit());
extern_active_note_get_note_id(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn get_storage_info() -> ActiveNoteStorageInfo {
unsafe {
let mut ret_area =
WordAligned::new(::core::mem::MaybeUninit::<RawCommitmentWithCount>::uninit());
extern_active_note_get_storage_info(ret_area.as_mut_ptr());
let raw = ret_area.into_inner().assume_init();
ActiveNoteStorageInfo {
commitment: raw.commitment,
num_storage_items: raw.num_items(),
}
}
}
pub trait ActiveNote {
#[inline]
fn get_initial_assets(&self) -> Vec<Asset> {
get_initial_assets()
}
#[inline]
fn get_sender(&self) -> AccountId {
get_sender()
}
#[inline]
fn get_recipient(&self) -> Recipient {
get_recipient()
}
#[inline]
fn get_script_root(&self) -> Word {
get_script_root()
}
#[inline]
fn get_serial_number(&self) -> Word {
get_serial_number()
}
#[inline]
fn get_metadata(&self) -> NoteMetadata {
get_metadata()
}
#[inline]
fn is_public(&self) -> bool {
is_public()
}
#[inline]
fn is_private(&self) -> bool {
is_private()
}
#[inline]
fn get_attachments_commitment(&self) -> Word {
get_attachments_commitment()
}
#[inline]
fn write_attachment_commitments_to_memory(&self) -> Vec<Word> {
write_attachment_commitments_to_memory()
}
#[inline]
fn write_attachment_to_memory(&self, attachment_idx: u32) -> Vec<Word> {
write_attachment_to_memory(attachment_idx)
}
#[inline]
fn find_attachment(&self, attachment_scheme: Felt) -> Option<u32> {
find_attachment(attachment_scheme)
}
#[inline]
fn get_initial_assets_info(&self) -> ActiveNoteAssetsInfo {
get_initial_assets_info()
}
#[inline]
fn get_initial_num_assets(&self) -> u32 {
get_initial_num_assets()
}
#[inline]
fn get_asset(&self, asset_index: u32) -> Asset {
get_asset(asset_index)
}
#[inline]
fn get_note_id(&self) -> NoteId {
get_note_id()
}
#[inline]
fn get_storage_info(&self) -> ActiveNoteStorageInfo {
get_storage_info()
}
#[inline]
fn remove_asset(&mut self, asset: Asset) -> Word {
remove_asset(asset)
}
}