use miden_stdlib_sys::{Felt, Word, WordAligned};
use super::types::{AccountId, Nonce, RawAccountId};
#[allow(improper_ctypes)]
unsafe extern "C" {
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_id"]
fn extern_active_account_get_id(ptr: *mut RawAccountId);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_nonce"]
fn extern_active_account_get_nonce() -> Felt;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::compute_commitment"]
fn extern_active_account_compute_commitment(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_code_commitment"]
fn extern_active_account_get_code_commitment(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::compute_storage_commitment"]
fn extern_active_account_compute_storage_commitment(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_asset"]
fn extern_active_account_get_asset(
asset_key_0: Felt,
asset_key_1: Felt,
asset_key_2: Felt,
asset_key_3: Felt,
ptr: *mut Word,
);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::has_asset"]
fn extern_active_account_has_asset(
asset_id_0: Felt,
asset_id_1: Felt,
asset_id_2: Felt,
asset_id_3: Felt,
) -> Felt;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_vault_root"]
fn extern_active_account_get_vault_root(ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_num_procedures"]
fn extern_active_account_get_num_procedures() -> Felt;
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::get_procedure_root"]
fn extern_active_account_get_procedure_root(index: Felt, ptr: *mut Word);
#[cfg_attr(target_family = "wasm", linkage = "extern_weak")]
#[link_name = "miden::protocol::active_account::has_procedure"]
fn extern_active_account_has_procedure(
proc_root_0: Felt,
proc_root_1: Felt,
proc_root_2: Felt,
proc_root_3: Felt,
) -> Felt;
}
pub fn get_id() -> AccountId {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<RawAccountId>::uninit());
extern_active_account_get_id(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init().into_account_id()
}
}
#[inline]
pub fn get_nonce() -> Nonce {
Nonce {
inner: unsafe { extern_active_account_get_nonce() },
}
}
#[inline]
pub fn compute_commitment() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_active_account_compute_commitment(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
#[inline]
pub fn get_code_commitment() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_active_account_get_code_commitment(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
#[inline]
pub fn compute_storage_commitment() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_active_account_compute_storage_commitment(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
pub fn get_asset(asset_key: Word) -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_active_account_get_asset(
asset_key[0],
asset_key[1],
asset_key[2],
asset_key[3],
ret_area.as_mut_ptr(),
);
ret_area.into_inner().assume_init()
}
}
#[inline]
pub fn has_asset(asset_id: Word) -> bool {
unsafe {
extern_active_account_has_asset(asset_id[0], asset_id[1], asset_id[2], asset_id[3])
!= Felt::new(0).unwrap()
}
}
#[inline]
pub fn get_vault_root() -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_active_account_get_vault_root(ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
#[inline]
pub fn get_num_procedures() -> u32 {
let count = unsafe { extern_active_account_get_num_procedures() };
count.as_canonical_u64() as u32
}
#[inline]
pub fn get_procedure_root(index: u32) -> Word {
unsafe {
let mut ret_area = WordAligned::new(::core::mem::MaybeUninit::<Word>::uninit());
extern_active_account_get_procedure_root(Felt::from_u32(index), ret_area.as_mut_ptr());
ret_area.into_inner().assume_init()
}
}
#[inline]
pub fn has_procedure(proc_root: Word) -> bool {
unsafe {
extern_active_account_has_procedure(proc_root[0], proc_root[1], proc_root[2], proc_root[3])
!= Felt::new(0).unwrap()
}
}
pub trait ActiveAccount {
#[doc(hidden)]
#[inline]
fn __assert_active_account(&self) {}
#[inline]
fn get_id(&self) -> AccountId {
self.__assert_active_account();
get_id()
}
#[inline]
fn get_nonce(&self) -> Nonce {
self.__assert_active_account();
get_nonce()
}
#[inline]
fn compute_commitment(&self) -> Word {
self.__assert_active_account();
compute_commitment()
}
#[inline]
fn get_code_commitment(&self) -> Word {
self.__assert_active_account();
get_code_commitment()
}
#[inline]
fn compute_storage_commitment(&self) -> Word {
self.__assert_active_account();
compute_storage_commitment()
}
#[inline]
fn get_asset(&self, asset_key: Word) -> Word {
self.__assert_active_account();
get_asset(asset_key)
}
#[inline]
fn has_asset(&self, asset_id: Word) -> bool {
self.__assert_active_account();
has_asset(asset_id)
}
#[inline]
fn get_vault_root(&self) -> Word {
self.__assert_active_account();
get_vault_root()
}
#[inline]
fn get_num_procedures(&self) -> u32 {
self.__assert_active_account();
get_num_procedures()
}
#[inline]
fn get_procedure_root(&self, index: u32) -> Word {
self.__assert_active_account();
get_procedure_root(index)
}
#[inline]
fn has_procedure(&self, proc_root: Word) -> bool {
self.__assert_active_account();
has_procedure(proc_root)
}
}
#[diagnostic::on_unimplemented(
message = "`{Self}` is not an account wrapper generated by `#[account(...)]`",
note = "define a struct with `#[account(...)]` and use it as the entrypoint account parameter"
)]
pub trait AccountWrapper: ActiveAccount + Default {
#[inline(always)]
fn active() -> Self {
Self::default()
}
}
#[doc(hidden)]
pub trait AccountBinding {
fn foreign_account_id(&self) -> Option<AccountId>;
}