miden-base-sys 0.14.0-rc.1

Miden rollup Rust bingings and MASM library
Documentation
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;
}

/// Returns the account ID of the active account.
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()
    }
}

/// Returns the nonce of the active account.
#[inline]
pub fn get_nonce() -> Nonce {
    Nonce {
        inner: unsafe { extern_active_account_get_nonce() },
    }
}

/// Computes and returns the commitment of the current account data.
#[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()
    }
}

/// Returns the code commitment of the active account.
#[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()
    }
}

/// Computes the latest storage commitment of the active account.
#[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()
    }
}

/// Returns the current value stored under the specified `asset_key` in the active account vault.
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()
    }
}

/// Returns `true` if the active account vault currently contains an asset with the specified asset
/// id.
#[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()
    }
}

/// Returns the current vault root of the active account.
#[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()
    }
}

/// Returns the number of procedures exported by the active account.
#[inline]
pub fn get_num_procedures() -> u32 {
    // The transaction kernel guarantees procedure counts fit in a u32.
    let count = unsafe { extern_active_account_get_num_procedures() };
    count.as_canonical_u64() as u32
}

/// Returns the procedure root for the procedure at `index`.
#[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()
    }
}

/// Returns `true` if the procedure identified by `proc_root` exists on the active account.
#[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()
    }
}

/// Trait that provides active account operations for components.
///
/// This trait is automatically implemented for the storage struct marked with the
/// `#[component_storage]` macro.
///
/// A `#[account(...)]` component method that shares a name with one of these built-ins does not
/// shadow it: both live on traits, so the call is disambiguated with
/// `<Wallet as ActiveAccount>::get_id(account)` or `<Wallet as Interface>::get_id(account)`.
pub trait ActiveAccount {
    /// Guard hook invoked by every active-account operation before it runs.
    ///
    /// The default implementation is a no-op. Types that can also represent a *foreign* account
    /// (for example the struct generated by the `#[account(...)]` macro) override this to reject
    /// calls made on a foreign binding, because the active-account operations always target the
    /// transaction's active account rather than the foreign one.
    #[doc(hidden)]
    #[inline]
    fn __assert_active_account(&self) {}

    /// Returns the account ID of the active account.
    #[inline]
    fn get_id(&self) -> AccountId {
        self.__assert_active_account();
        get_id()
    }

    /// Returns the nonce of the active account.
    #[inline]
    fn get_nonce(&self) -> Nonce {
        self.__assert_active_account();
        get_nonce()
    }

    /// Computes and returns the commitment of the current account data.
    #[inline]
    fn compute_commitment(&self) -> Word {
        self.__assert_active_account();
        compute_commitment()
    }

    /// Returns the code commitment of the active account.
    #[inline]
    fn get_code_commitment(&self) -> Word {
        self.__assert_active_account();
        get_code_commitment()
    }

    /// Computes the latest storage commitment of the active account.
    #[inline]
    fn compute_storage_commitment(&self) -> Word {
        self.__assert_active_account();
        compute_storage_commitment()
    }

    /// Returns the current value stored under the specified `asset_key` in the active account
    /// vault.
    #[inline]
    fn get_asset(&self, asset_key: Word) -> Word {
        self.__assert_active_account();
        get_asset(asset_key)
    }

    /// Returns `true` if the active account vault currently contains an asset with the specified
    /// asset id.
    #[inline]
    fn has_asset(&self, asset_id: Word) -> bool {
        self.__assert_active_account();
        has_asset(asset_id)
    }

    /// Returns the current vault root of the active account.
    #[inline]
    fn get_vault_root(&self) -> Word {
        self.__assert_active_account();
        get_vault_root()
    }

    /// Returns the number of procedures exported by the active account.
    #[inline]
    fn get_num_procedures(&self) -> u32 {
        self.__assert_active_account();
        get_num_procedures()
    }

    /// Returns the procedure root for the procedure at `index`.
    #[inline]
    fn get_procedure_root(&self, index: u32) -> Word {
        self.__assert_active_account();
        get_procedure_root(index)
    }

    /// Returns `true` if the procedure identified by `proc_root` exists on the active account.
    #[inline]
    fn has_procedure(&self, proc_root: Word) -> bool {
        self.__assert_active_account();
        has_procedure(proc_root)
    }
}

/// Marker trait for account API wrapper types.
///
/// The `#[note]` and `#[tx_script]` macros instantiate their entrypoint account parameter
/// through this trait, so that parameter must be a type implementing it. The `ActiveAccount`
/// supertrait guarantees that parameter is usable as the transaction's active account and keeps
/// unrelated `Default` types from satisfying the bound. The `#[account(...)]` macro implements
/// both automatically; it is not a sealed capability boundary, so manual implementations are
/// possible but normally unnecessary.
#[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 {
    /// Creates a binding to the transaction's active account.
    ///
    /// This is the account the transaction executes against, as opposed to a foreign account
    /// reached through FPI (created with `new`).
    #[inline(always)]
    fn active() -> Self {
        Self::default()
    }
}

/// Exposes which account a generated `#[account(...)]` wrapper binds to.
///
/// The component traits generated by `#[account(...)]` dispatch every call between the
/// transaction's active account and a foreign account reached through FPI. They read the binding
/// target through this trait — a supertrait of each generated component trait — so the dispatch
/// works without access to the wrapper's private `foreign_account_id` field.
///
/// This is an internal dispatch hook implemented by the `#[account(...)]` macro; it is not meant to
/// be implemented or called directly.
#[doc(hidden)]
pub trait AccountBinding {
    /// Returns `Some(id)` when the wrapper targets a foreign account reached through FPI, or `None`
    /// when it targets the transaction's active account.
    fn foreign_account_id(&self) -> Option<AccountId>;
}