#![cfg_attr(docsrs, feature(doc_cfg))]
#![no_std]
#[macro_use]
extern crate alloc;
use alloc::boxed::Box;
#[cfg(feature = "std")]
extern crate std;
pub mod account;
pub mod grpc_support;
pub mod keystore;
pub mod note;
pub mod note_transport;
pub mod rpc;
pub mod settings;
pub mod store;
pub mod sync;
pub mod transaction;
pub mod utils;
pub mod builder;
#[cfg(feature = "testing")]
mod test_utils;
pub mod errors;
pub use miden_protocol::utils::serde::{Deserializable, Serializable, SliceReader};
pub mod notes {
pub use miden_protocol::note::NoteFile;
}
pub mod assembly {
pub use miden_protocol::MastForest;
pub use miden_protocol::assembly::debuginfo::SourceManagerSync;
pub use miden_protocol::assembly::diagnostics::Report;
pub use miden_protocol::assembly::diagnostics::reporting::PrintDiagnostic;
pub use miden_protocol::assembly::mast::MastNodeExt;
pub use miden_protocol::assembly::{
Assembler,
DefaultSourceManager,
Library,
Module,
ModuleKind,
Path,
};
pub use miden_standards::code_builder::CodeBuilder;
}
pub mod asset {
pub use miden_protocol::account::delta::{
AccountStorageDelta,
AccountVaultDelta,
FungibleAssetDelta,
NonFungibleAssetDelta,
NonFungibleDeltaAction,
};
pub use miden_protocol::account::{
AccountStorageHeader,
StorageMapWitness,
StorageSlotContent,
StorageSlotHeader,
};
pub use miden_protocol::asset::{
Asset,
AssetVault,
AssetVaultKey,
AssetWitness,
FungibleAsset,
NonFungibleAsset,
NonFungibleAssetDetails,
PartialVault,
TokenSymbol,
};
}
pub mod auth {
pub use miden_protocol::account::auth::{
AuthScheme as AuthSchemeId,
AuthSecretKey,
PublicKey,
PublicKeyCommitment,
Signature,
};
pub use miden_standards::account::auth::{
AuthMultisig,
AuthMultisigConfig,
AuthSingleSig,
AuthSingleSigAcl,
AuthSingleSigAclConfig,
NoAuth,
};
pub use miden_tx::auth::{BasicAuthenticator, SigningInputs, TransactionAuthenticator};
pub use crate::account::component::AuthScheme;
pub const RPO_FALCON_SCHEME_ID: AuthSchemeId = AuthSchemeId::Falcon512Poseidon2;
pub const ECDSA_K256_KECCAK_SCHEME_ID: AuthSchemeId = AuthSchemeId::EcdsaK256Keccak;
}
pub mod block {
pub use miden_protocol::block::{BlockHeader, BlockNumber};
}
pub mod crypto {
pub mod rpo_falcon512 {
pub use miden_protocol::crypto::dsa::falcon512_poseidon2::{
PublicKey,
SecretKey,
Signature,
};
}
pub use miden_protocol::crypto::hash::blake::Blake3Digest;
pub use miden_protocol::crypto::hash::poseidon2::Poseidon2;
pub use miden_protocol::crypto::hash::rpo::Rpo256;
pub use miden_protocol::crypto::merkle::mmr::{
Forest,
InOrderIndex,
MmrDelta,
MmrPeaks,
MmrProof,
PartialMmr,
};
pub use miden_protocol::crypto::merkle::smt::{
LeafIndex,
SMT_DEPTH,
Smt,
SmtForest,
SmtLeaf,
SmtProof,
};
pub use miden_protocol::crypto::merkle::store::MerkleStore;
pub use miden_protocol::crypto::merkle::{
EmptySubtreeRoots,
MerkleError,
MerklePath,
MerkleTree,
NodeIndex,
SparseMerklePath,
};
pub use miden_protocol::crypto::rand::{FeltRng, RandomCoin};
}
pub mod address {
pub use miden_protocol::address::{
Address,
AddressId,
AddressInterface,
CustomNetworkId,
NetworkId,
RoutingParameters,
};
}
pub mod vm {
pub use miden_protocol::vm::{
AdviceInputs,
AdviceMap,
AttributeSet,
Package,
PackageExport,
PackageManifest,
ProcedureExport,
Program,
QualifiedProcedureName,
Section,
SectionId,
TargetType,
};
}
pub use async_trait::async_trait;
pub use errors::*;
use miden_protocol::assembly::SourceManagerSync;
pub use miden_protocol::{
EMPTY_WORD,
Felt,
MAX_TX_EXECUTION_CYCLES,
MIN_TX_EXECUTION_CYCLES,
ONE,
PrettyPrint,
Word,
ZERO,
};
pub use miden_remote_prover_client::RemoteTransactionProver;
pub use miden_tx::ExecutionOptions;
#[cfg(feature = "testing")]
pub mod testing {
pub use miden_protocol::testing::account_id;
pub use miden_standards::testing::note::NoteBuilder;
pub use miden_standards::testing::*;
pub use miden_testing::*;
pub use crate::test_utils::*;
}
use alloc::sync::Arc;
use miden_protocol::crypto::rand::FeltRng;
use miden_tx::auth::TransactionAuthenticator;
use rand::RngCore;
use rpc::NodeRpcClient;
use store::Store;
use crate::note_transport::NoteTransportClient;
use crate::transaction::TransactionProver;
pub struct Client<AUTH> {
store: Arc<dyn Store>,
rng: ClientRng,
rpc_api: Arc<dyn NodeRpcClient>,
tx_prover: Arc<dyn TransactionProver + Send + Sync>,
authenticator: Option<Arc<AUTH>>,
source_manager: Arc<dyn SourceManagerSync>,
exec_options: ExecutionOptions,
tx_discard_delta: Option<u32>,
max_block_number_delta: Option<u32>,
note_transport_api: Option<Arc<dyn NoteTransportClient>>,
}
impl<AUTH> Client<AUTH>
where
AUTH: builder::BuilderAuthenticator,
{
pub fn builder() -> builder::ClientBuilder<AUTH> {
builder::ClientBuilder::new()
}
}
impl<AUTH> Client<AUTH>
where
AUTH: TransactionAuthenticator,
{
pub fn in_debug_mode(&self) -> bool {
self.exec_options.enable_debugging()
}
pub fn code_builder(&self) -> assembly::CodeBuilder {
assembly::CodeBuilder::with_source_manager(self.source_manager.clone())
}
pub fn note_screener(&self) -> note::NoteScreener {
note::NoteScreener::new(self.store.clone(), self.rpc_api.clone())
}
pub fn rng(&mut self) -> &mut ClientRng {
&mut self.rng
}
pub fn prover(&self) -> Arc<dyn TransactionProver + Send + Sync> {
self.tx_prover.clone()
}
pub fn authenticator(&self) -> Option<&Arc<AUTH>> {
self.authenticator.as_ref()
}
pub fn source_manager(&self) -> Arc<dyn SourceManagerSync> {
self.source_manager.clone()
}
}
impl<AUTH> Client<AUTH> {
pub fn store_identifier(&self) -> &str {
self.store.identifier()
}
pub async fn check_note_tag_limit(&self) -> Result<(), ClientError> {
let limits = self.rpc_api.get_rpc_limits().await?;
if self.store.get_unique_note_tags().await?.len() >= limits.note_tags_limit as usize {
return Err(ClientError::NoteTagsLimitExceeded(limits.note_tags_limit));
}
Ok(())
}
pub async fn check_account_limit(&self) -> Result<(), ClientError> {
let limits = self.rpc_api.get_rpc_limits().await?;
if self.store.get_account_ids().await?.len() >= limits.account_ids_limit as usize {
return Err(ClientError::AccountsLimitExceeded(limits.account_ids_limit));
}
Ok(())
}
#[cfg(any(test, feature = "testing"))]
pub fn test_rpc_api(&mut self) -> &mut Arc<dyn NodeRpcClient> {
&mut self.rpc_api
}
#[cfg(any(test, feature = "testing"))]
pub fn test_store(&mut self) -> &mut Arc<dyn Store> {
&mut self.store
}
}
pub trait ClientFeltRng: FeltRng + Send + Sync {}
impl<T> ClientFeltRng for T where T: FeltRng + Send + Sync {}
pub type ClientRngBox = Box<dyn ClientFeltRng>;
pub struct ClientRng(ClientRngBox);
impl ClientRng {
pub fn new(rng: ClientRngBox) -> Self {
Self(rng)
}
pub fn inner_mut(&mut self) -> &mut ClientRngBox {
&mut self.0
}
}
impl RngCore for ClientRng {
fn next_u32(&mut self) -> u32 {
self.0.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.0.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.0.fill_bytes(dest);
}
}
impl FeltRng for ClientRng {
fn draw_element(&mut self) -> Felt {
self.0.draw_element()
}
fn draw_word(&mut self) -> Word {
self.0.draw_word()
}
}
#[derive(Debug, Clone, Copy)]
pub enum DebugMode {
Enabled,
Disabled,
}
impl From<DebugMode> for bool {
fn from(debug_mode: DebugMode) -> Self {
match debug_mode {
DebugMode::Enabled => true,
DebugMode::Disabled => false,
}
}
}
impl From<bool> for DebugMode {
fn from(debug_mode: bool) -> DebugMode {
if debug_mode {
DebugMode::Enabled
} else {
DebugMode::Disabled
}
}
}
#[cfg(test)]
mod tests {
use super::Client;
fn assert_send_sync<T: Send + Sync>() {}
#[test]
fn client_is_send_sync() {
assert_send_sync::<Client<()>>();
}
}