From 40baa5ad2fa2e650970fb7abd01928319dfed21b Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Fri, 24 Jan 2025 19:00:52 -0300 Subject: [PATCH 1/7] feat: Use AccountComponentTemplate --- CHANGELOG.md | 3 +- Cargo.lock | 8 +- bin/miden-cli/src/commands/account.rs | 8 +- bin/miden-cli/src/commands/init.rs | 6 +- bin/miden-cli/src/commands/new_account.rs | 157 ++++++++++++++++-- bin/miden-cli/src/errors.rs | 11 +- bin/miden-cli/src/lib.rs | 1 - bin/miden-cli/src/tests.rs | 8 +- crates/rust-client/build.rs | 13 +- crates/rust-client/src/account.rs | 24 ++- .../src/rpc/generated/nostd/account.rs | 4 +- .../src/rpc/generated/nostd/note.rs | 4 +- .../src/rpc/generated/nostd/responses.rs | 2 +- .../src/rpc/generated/std/account.rs | 4 +- .../rust-client/src/rpc/generated/std/note.rs | 4 +- .../src/rpc/generated/std/responses.rs | 2 +- .../states/consumed_authenticated_local.rs | 1 + crates/web-client/src/new_account.rs | 24 ++- docs/library.md | 8 +- tests/integration/common.rs | 12 +- 20 files changed, 226 insertions(+), 78 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a241f80..0ace82c2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,9 +18,10 @@ * Created functions for creating standard notes and note scripts easily on the web client (#686). * [BREAKING] Renamed plural modules to singular (#687). * [BREAKING] Made `idxdb` only usable on WASM targets (#685). -* Added fixed seed option for web client generation (#688) +* Added fixed seed option for web client generation (#688). * [BREAKING] Updated `init` command in the CLI to receive a `--network` flag (#690). * Improved CLI error messages (#682). +* Added account creation from component templates (#680). ### Fixes diff --git a/Cargo.lock b/Cargo.lock index 456091ca5..f34c617ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2962,9 +2962,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f14b5c02a137632f68194ec657ecb92304138948e8957c932127eb1b58c23be" +checksum = "b812699e0c4f813b872b373a4471717d9eb550da14b311058a4d9cf4173cbca6" dependencies = [ "dissimilar", "glob", @@ -2993,9 +2993,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243" [[package]] name = "unicode-linebreak" diff --git a/bin/miden-cli/src/commands/account.rs b/bin/miden-cli/src/commands/account.rs index cd37635e0..543009df2 100644 --- a/bin/miden-cli/src/commands/account.rs +++ b/bin/miden-cli/src/commands/account.rs @@ -188,12 +188,8 @@ pub async fn show_account( println!("Storage: \n"); - let mut table = create_dynamic_table(&[ - "Item Slot Index", - "Item Slot Type", - "Value Arity", - "Value/Commitment", - ]); + let mut table = + create_dynamic_table(&["Item Slot Index", "Item Slot Type", "Value/Commitment"]); for (idx, entry) in account_storage.slots().iter().enumerate() { let item = account_storage diff --git a/bin/miden-cli/src/commands/init.rs b/bin/miden-cli/src/commands/init.rs index d70cc9617..d85cf6e12 100644 --- a/bin/miden-cli/src/commands/init.rs +++ b/bin/miden-cli/src/commands/init.rs @@ -102,7 +102,7 @@ impl InitCmd { }; let config_as_toml_string = toml::to_string_pretty(&cli_config).map_err(|err| { - CliError::Config("Failed to serialize config".to_string().into(), err.to_string()) + CliError::Config("failed to serialize config".to_string().into(), err.to_string()) })?; let mut file_handle = File::options() @@ -110,11 +110,11 @@ impl InitCmd { .create_new(true) .open(&config_file_path) .map_err(|err| { - CliError::Config("Failed to create config file".to_string().into(), err.to_string()) + CliError::Config("failed to create config file".to_string().into(), err.to_string()) })?; file_handle.write(config_as_toml_string.as_bytes()).map_err(|err| { - CliError::Config("Failed to write config file".to_string().into(), err.to_string()) + CliError::Config("failed to write config file".to_string().into(), err.to_string()) })?; println!("Config file successfully created at: {:?}", config_file_path); diff --git a/bin/miden-cli/src/commands/new_account.rs b/bin/miden-cli/src/commands/new_account.rs index 2709697eb..20a061d19 100644 --- a/bin/miden-cli/src/commands/new_account.rs +++ b/bin/miden-cli/src/commands/new_account.rs @@ -1,14 +1,21 @@ +use std::{collections::BTreeMap, fs, io::Write, path::PathBuf}; + use clap::{Parser, ValueEnum}; use miden_client::{ account::{ - AccountBuilder, AccountStorageMode, AccountType, BasicFungibleFaucetComponent, - BasicWalletComponent, RpoFalcon512Component, + component::{ + AccountComponent, AccountComponentTemplate, BasicFungibleFaucet, BasicWallet, + InitStorageData, MapRepresentation, PlaceholderType, RpoFalcon512, StorageValue, + }, + AccountBuilder, AccountStorageMode, AccountType, }, assets::TokenSymbol, auth::AuthSecretKey, crypto::{FeltRng, SecretKey}, - Client, Felt, + utils::Deserializable, + Client, Felt, Word, }; +use miden_lib::utils::parse_hex_string_as_word; use crate::{ commands::account::maybe_set_default_account, errors::CliError, utils::load_config_file, @@ -30,6 +37,81 @@ impl From for AccountStorageMode { } } +/// Helper function to process extra component templates. +/// It reads user input for each placeholder in a component template. +// TODO: this could take a TOML file with key-values +fn process_component_templates( + extra_components: &[AccountComponentTemplate], +) -> Result, CliError> { + let mut account_components = vec![]; + for component_template in extra_components { + let mut init_storage_data = BTreeMap::new(); + for (placeholder_key, placeholder_type) in + component_template.metadata().get_unique_storage_placeholders() + { + print!( + "Enter hex value for placeholder '{}' (type: {}): ", + placeholder_key, placeholder_type + ); + std::io::stdout().flush()?; + + let mut input_value = String::new(); + std::io::stdin().read_line(&mut input_value)?; + let input_value = input_value.trim(); + + match placeholder_type { + PlaceholderType::Felt => { + let value = input_value + .strip_prefix("0x") + .ok_or("error parsing input: Missing 0x prefix".to_string()) + .map(|hex| { + u64::from_str_radix(hex, 16).map_err(|e| { + CliError::Parse(e.into(), "failed to parse hex from input".into()) + }) + }) + .map_err(|e| { + CliError::Parse(e.into(), "failed to parse hex from input".into()) + })??; + + init_storage_data + .insert(placeholder_key.clone(), StorageValue::Felt(Felt::new(value))); + }, + PlaceholderType::Map => { + // TODO: Test this case further + let map: MapRepresentation = toml::from_str(input_value).map_err(|e| { + CliError::Parse(e.into(), "failed to parse map from input".into()) + })?; + let map = map.try_build_map(&Default::default()).map_err(|e| { + CliError::Parse(e.into(), "failed to parse map from input".into()) + })?; + + init_storage_data.insert(placeholder_key.clone(), StorageValue::Map(map)); + }, + PlaceholderType::Word => { + let word: Word = parse_hex_string_as_word(input_value).map_err(|e| { + CliError::Parse(e.into(), "failed to parse hex from input".into()) + })?; + + init_storage_data.insert(placeholder_key.clone(), StorageValue::Word(word)); + }, + } + } + let component = AccountComponent::from_template( + component_template, + &InitStorageData::new(init_storage_data), + ) + .map_err(|e| CliError::Account(e, "error instantiating component from template".into()))? + .with_supports_all_types(); + + account_components.push(component); + } + + Ok(account_components) +} + +// NEW FAUCET +// ================================================================================================ + #[derive(Debug, Parser, Clone)] /// Create a new faucet account. pub struct NewFaucetCmd { @@ -47,6 +129,9 @@ pub struct NewFaucetCmd { decimals: Option, #[clap(short, long)] max_supply: Option, + #[clap(short, long)] + /// List of additional component template files to include. + template_files: Vec, } impl NewFaucetCmd { @@ -62,6 +147,18 @@ impl NewFaucetCmd { )); } + let mut extra_components = Vec::new(); + for path in &self.template_files { + let bytes = fs::read(path)?; + let template = AccountComponentTemplate::read_from_bytes(&bytes).map_err(|e| { + CliError::AccountComponentError( + Box::new(e), + "failed to read account component template".into(), + ) + })?; + extra_components.push(template); + } + let decimals = self.decimals.expect("decimals must be provided"); let token_symbol = self.token_symbol.clone().expect("token symbol must be provided"); @@ -78,18 +175,23 @@ impl NewFaucetCmd { let anchor_block = client.get_latest_epoch_block().await?; - let (new_account, seed) = AccountBuilder::new(init_seed) + let mut builder = AccountBuilder::new(init_seed) .anchor((&anchor_block).try_into().expect("anchor block should be valid")) .account_type(AccountType::FungibleFaucet) .storage_mode(self.storage_mode.into()) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component( - BasicFungibleFaucetComponent::new(symbol, decimals, max_supply).map_err(|err| { - CliError::Account(err, "Failed to create a faucet".to_string()) - })?, - ) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicFungibleFaucet::new(symbol, decimals, max_supply).map_err( + |err| CliError::Account(err, "failed to create a faucet component".to_string()), + )?); + + //add any extra component templates + for component in process_component_templates(&extra_components)? { + builder = builder.with_component(component); + } + + let (new_account, seed) = builder .build() - .map_err(|err| CliError::Account(err, "Failed to create a faucet".to_string()))?; + .map_err(|err| CliError::Account(err, "error building account".into()))?; client .add_account(&new_account, Some(seed), &AuthSecretKey::RpoFalcon512(key_pair), false) @@ -105,6 +207,9 @@ impl NewFaucetCmd { } } +// NEW WALLET +// ================================================================================================ + #[derive(Debug, Parser, Clone)] /// Create a new wallet account. pub struct NewWalletCmd { @@ -114,10 +219,25 @@ pub struct NewWalletCmd { #[clap(short, long)] /// Defines if the account code is mutable (by default it isn't mutable). pub mutable: bool, + #[clap(short, long)] + /// Optional list of additional component package files to include. + pub template_files: Vec, } impl NewWalletCmd { pub async fn execute(&self, mut client: Client) -> Result<(), CliError> { + let mut extra_components = Vec::new(); + for path in &self.template_files { + let bytes = fs::read(path)?; + let template = AccountComponentTemplate::read_from_bytes(&bytes).map_err(|e| { + CliError::AccountComponentError( + Box::new(e), + "failed to read account component template".into(), + ) + })?; + extra_components.push(template); + } + let key_pair = SecretKey::with_rng(client.rng()); let mut init_seed = [0u8; 32]; @@ -131,14 +251,21 @@ impl NewWalletCmd { let anchor_block = client.get_latest_epoch_block().await?; - let (new_account, seed) = AccountBuilder::new(init_seed) + let mut builder = AccountBuilder::new(init_seed) .anchor((&anchor_block).try_into().expect("anchor block should be valid")) .account_type(account_type) .storage_mode(self.storage_mode.into()) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicWalletComponent) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicWallet); + + //add any extra component templates + for component in process_component_templates(&extra_components)? { + builder = builder.with_component(component); + } + + let (new_account, seed) = builder .build() - .map_err(|err| CliError::Account(err, "Failed to create a wallet".to_string()))?; + .map_err(|err| CliError::Account(err, "failed to create a wallet".to_string()))?; client .add_account(&new_account, Some(seed), &AuthSecretKey::RpoFalcon512(key_pair), false) diff --git a/bin/miden-cli/src/errors.rs b/bin/miden-cli/src/errors.rs index 72e3dbe06..523e5421a 100644 --- a/bin/miden-cli/src/errors.rs +++ b/bin/miden-cli/src/errors.rs @@ -5,11 +5,16 @@ use miden_objects::{AccountError, AccountIdError, AssetError}; use miette::Diagnostic; use thiserror::Error; +type SourceError = Box; + #[derive(Debug, Diagnostic, Error)] pub enum CliError { #[error("account error: {1}")] #[diagnostic(code(cli::account_error))] Account(#[source] AccountError, String), + #[error("account component error: {1}")] + #[diagnostic(code(cli::account_error))] + AccountComponentError(#[source] SourceError, String), #[error("account id error: {1}")] #[diagnostic(code(cli::accountid_error), help("Check the account ID format."))] AccountId(#[source] AccountIdError, String), @@ -24,7 +29,7 @@ pub enum CliError { code(cli::config_error), help("Check if the configuration file exists and is well-formed.") )] - Config(#[source] Box, String), + Config(#[source] SourceError, String), #[error("export error: {0}")] #[diagnostic(code(cli::export_error), help("Check the ID."))] Export(String), @@ -45,10 +50,10 @@ pub enum CliError { MissingFlag(String), #[error("parse error: {1}")] #[diagnostic(code(cli::parse_error), help("Check the inputs."))] - Parse(#[source] Box, String), + Parse(#[source] SourceError, String), #[error("transaction error: {1}")] #[diagnostic(code(cli::transaction_error))] - Transaction(#[source] Box, String), + Transaction(#[source] SourceError, String), } impl From for String { diff --git a/bin/miden-cli/src/lib.rs b/bin/miden-cli/src/lib.rs index bd46225e8..e3ab36269 100644 --- a/bin/miden-cli/src/lib.rs +++ b/bin/miden-cli/src/lib.rs @@ -93,7 +93,6 @@ impl Cli { // Define whether we want to use the executor's debug mode based on the env var and // the flag override - let in_debug_mode = match env::var("MIDEN_DEBUG") { Ok(value) if value.to_lowercase() == "true" => true, _ => self.debug, diff --git a/bin/miden-cli/src/tests.rs b/bin/miden-cli/src/tests.rs index 3c12f6a8a..3b29e84ba 100644 --- a/bin/miden-cli/src/tests.rs +++ b/bin/miden-cli/src/tests.rs @@ -10,8 +10,8 @@ use config::RpcConfig; use miden_client::{ self, account::{ - AccountBuilder, AccountId, AccountStorageMode, AccountType, BasicWalletComponent, - RpoFalcon512Component, + component::{BasicWallet, RpoFalcon512}, + AccountBuilder, AccountId, AccountStorageMode, AccountType, }, auth::AuthSecretKey, crypto::{FeltRng, RpoRandomCoin, SecretKey}, @@ -124,8 +124,8 @@ async fn test_mint_with_untracked_account() { .anchor((&anchor_block).try_into().unwrap()) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(AccountStorageMode::Private) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicWalletComponent) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicWallet) .build() .unwrap(); diff --git a/crates/rust-client/build.rs b/crates/rust-client/build.rs index 43107019d..856db03e0 100644 --- a/crates/rust-client/build.rs +++ b/crates/rust-client/build.rs @@ -13,13 +13,24 @@ use prost::Message; const STD_PROTO_OUT_DIR: &str = "src/rpc/generated/std"; const NO_STD_PROTO_OUT_DIR: &str = "src/rpc/generated/nostd"; +/// Defines whether the build script should generate files in `/src`. +/// The docs.rs build pipeline has a read-only filesystem, so we have to avoid writing to `src`, +/// otherwise the docs will fail to build there. Note that writing to `OUT_DIR` is fine. +const BUILD_GENERATED_FILES_IN_SRC: bool = option_env!("BUILD_GENERATED_FILES_IN_SRC").is_some(); + fn main() -> miette::Result<()> { + println!("cargo::rerun-if-env-changed=BUILD_GENERATED_FILES_IN_SRC"); + let out_dir = env::var("OUT_DIR").expect("OUT_DIR should be set"); let dest_path = PathBuf::from(out_dir); + if !BUILD_GENERATED_FILES_IN_SRC { + return Ok(()); + } + // updates the generated files from protobuf. Only do so when this is not docs.rs building the // documentation. - if env::var("DOCS_RS").is_err() && env::var("CODEGEN").unwrap_or("0".to_string()) == "1" { + if env::var("CODEGEN").unwrap_or("0".to_string()) == "1" { write_proto(&dest_path).unwrap(); compile_tonic_client_proto(&dest_path)?; replace_no_std_types(); diff --git a/crates/rust-client/src/account.rs b/crates/rust-client/src/account.rs index e0b540e13..bec03e307 100644 --- a/crates/rust-client/src/account.rs +++ b/crates/rust-client/src/account.rs @@ -6,14 +6,9 @@ use alloc::vec::Vec; -pub use miden_lib::account::{ - auth::RpoFalcon512 as RpoFalcon512Component, - faucets::BasicFungibleFaucet as BasicFungibleFaucetComponent, - wallets::BasicWallet as BasicWalletComponent, -}; pub use miden_objects::account::{ Account, AccountBuilder, AccountCode, AccountData, AccountHeader, AccountId, AccountStorage, - AccountStorageMode, AccountType, StorageSlot, StorageSlotType, + AccountStorageMode, AccountType, StorageSlot, }; use miden_objects::{account::AuthSecretKey, crypto::rand::FeltRng, Digest, Word}; @@ -23,6 +18,23 @@ use crate::{ ClientError, }; +// RE-EXPORTS +// ================================================================================================ + +pub mod component { + pub use miden_lib::account::{ + auth::RpoFalcon512, faucets::BasicFungibleFaucet, wallets::BasicWallet, + }; + pub use miden_objects::account::{ + AccountComponent, AccountComponentMetadata, AccountComponentTemplate, FeltRepresentation, + InitStorageData, MapRepresentation, PlaceholderType, StorageEntry, StoragePlaceholder, + StorageSlotType, StorageValue, WordRepresentation, + }; +} + +// CLIENT METHODS +// ================================================================================================ + impl Client { // ACCOUNT CREATION // -------------------------------------------------------------------------------------------- diff --git a/crates/rust-client/src/rpc/generated/nostd/account.rs b/crates/rust-client/src/rpc/generated/nostd/account.rs index a2683eb0d..eb4a9c022 100644 --- a/crates/rust-client/src/rpc/generated/nostd/account.rs +++ b/crates/rust-client/src/rpc/generated/nostd/account.rs @@ -7,7 +7,7 @@ #[prost(skip_debug)] pub struct AccountId { /// 15 bytes (120 bits) encoded using \[winter_utils::Serializable\] implementation for - /// \[miden_objects::accounts::account_id::AccountId\]. + /// \[miden_objects::account::account_id::AccountId\]. #[prost(bytes = "vec", tag = "1")] pub id: ::prost::alloc::vec::Vec, } @@ -31,7 +31,7 @@ pub struct AccountInfo { #[prost(message, optional, tag = "1")] pub summary: ::core::option::Option, /// Account details encoded using \[winter_utils::Serializable\] implementation for - /// \[miden_objects::accounts::Account\]. + /// \[miden_objects::account::Account\]. #[prost(bytes = "vec", optional, tag = "2")] pub details: ::core::option::Option<::prost::alloc::vec::Vec>, } diff --git a/crates/rust-client/src/rpc/generated/nostd/note.rs b/crates/rust-client/src/rpc/generated/nostd/note.rs index b64565915..77a9bae41 100644 --- a/crates/rust-client/src/rpc/generated/nostd/note.rs +++ b/crates/rust-client/src/rpc/generated/nostd/note.rs @@ -10,12 +10,12 @@ pub struct NoteMetadata { pub note_type: u32, /// A value which can be used by the recipient(s) to identify notes intended for them. /// - /// See `miden_objects::notes::note_tag` for more info. + /// See `miden_objects::note::note_tag` for more info. #[prost(fixed32, tag = "3")] pub tag: u32, /// Specifies when a note is ready to be consumed. /// - /// See `miden_objects::notes::execution_hint` for more info. + /// See `miden_objects::note::execution_hint` for more info. #[prost(fixed64, tag = "4")] pub execution_hint: u64, /// An arbitrary user-defined value. diff --git a/crates/rust-client/src/rpc/generated/nostd/responses.rs b/crates/rust-client/src/rpc/generated/nostd/responses.rs index ee222ce8e..5b526ae67 100644 --- a/crates/rust-client/src/rpc/generated/nostd/responses.rs +++ b/crates/rust-client/src/rpc/generated/nostd/responses.rs @@ -204,7 +204,7 @@ pub struct GetBlockByNumberResponse { #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetAccountStateDeltaResponse { /// The calculated account delta encoded using \[winter_utils::Serializable\] implementation - /// for \[miden_objects::accounts::delta::AccountDelta\]. + /// for \[miden_objects::account::delta::AccountDelta\]. #[prost(bytes = "vec", optional, tag = "1")] pub delta: ::core::option::Option<::prost::alloc::vec::Vec>, } diff --git a/crates/rust-client/src/rpc/generated/std/account.rs b/crates/rust-client/src/rpc/generated/std/account.rs index a2683eb0d..eb4a9c022 100644 --- a/crates/rust-client/src/rpc/generated/std/account.rs +++ b/crates/rust-client/src/rpc/generated/std/account.rs @@ -7,7 +7,7 @@ #[prost(skip_debug)] pub struct AccountId { /// 15 bytes (120 bits) encoded using \[winter_utils::Serializable\] implementation for - /// \[miden_objects::accounts::account_id::AccountId\]. + /// \[miden_objects::account::account_id::AccountId\]. #[prost(bytes = "vec", tag = "1")] pub id: ::prost::alloc::vec::Vec, } @@ -31,7 +31,7 @@ pub struct AccountInfo { #[prost(message, optional, tag = "1")] pub summary: ::core::option::Option, /// Account details encoded using \[winter_utils::Serializable\] implementation for - /// \[miden_objects::accounts::Account\]. + /// \[miden_objects::account::Account\]. #[prost(bytes = "vec", optional, tag = "2")] pub details: ::core::option::Option<::prost::alloc::vec::Vec>, } diff --git a/crates/rust-client/src/rpc/generated/std/note.rs b/crates/rust-client/src/rpc/generated/std/note.rs index b64565915..77a9bae41 100644 --- a/crates/rust-client/src/rpc/generated/std/note.rs +++ b/crates/rust-client/src/rpc/generated/std/note.rs @@ -10,12 +10,12 @@ pub struct NoteMetadata { pub note_type: u32, /// A value which can be used by the recipient(s) to identify notes intended for them. /// - /// See `miden_objects::notes::note_tag` for more info. + /// See `miden_objects::note::note_tag` for more info. #[prost(fixed32, tag = "3")] pub tag: u32, /// Specifies when a note is ready to be consumed. /// - /// See `miden_objects::notes::execution_hint` for more info. + /// See `miden_objects::note::execution_hint` for more info. #[prost(fixed64, tag = "4")] pub execution_hint: u64, /// An arbitrary user-defined value. diff --git a/crates/rust-client/src/rpc/generated/std/responses.rs b/crates/rust-client/src/rpc/generated/std/responses.rs index ee222ce8e..5b526ae67 100644 --- a/crates/rust-client/src/rpc/generated/std/responses.rs +++ b/crates/rust-client/src/rpc/generated/std/responses.rs @@ -204,7 +204,7 @@ pub struct GetBlockByNumberResponse { #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetAccountStateDeltaResponse { /// The calculated account delta encoded using \[winter_utils::Serializable\] implementation - /// for \[miden_objects::accounts::delta::AccountDelta\]. + /// for \[miden_objects::account::delta::AccountDelta\]. #[prost(bytes = "vec", optional, tag = "1")] pub delta: ::core::option::Option<::prost::alloc::vec::Vec>, } diff --git a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs index f8d9e3ae5..bdc540678 100644 --- a/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs +++ b/crates/rust-client/src/store/note_record/input_note_record/states/consumed_authenticated_local.rs @@ -10,6 +10,7 @@ use miden_objects::{ use super::{InputNoteState, NoteStateHandler, NoteSubmissionData}; use crate::store::NoteRecordError; +/// Information related to notes in the [InputNoteState::ConsumedAuthenticatedLocal] state. #[derive(Clone, Debug, PartialEq)] pub struct ConsumedAuthenticatedLocalNoteState { /// Metadata associated with the note, including sender, note type, tag and other additional diff --git a/crates/web-client/src/new_account.rs b/crates/web-client/src/new_account.rs index 36de9ab20..4a907d1ea 100644 --- a/crates/web-client/src/new_account.rs +++ b/crates/web-client/src/new_account.rs @@ -1,7 +1,7 @@ use miden_client::{ account::{ - AccountBuilder, AccountType, BasicFungibleFaucetComponent, BasicWalletComponent, - RpoFalcon512Component, + component::{BasicFungibleFaucet, BasicWallet, RpoFalcon512}, + AccountBuilder, AccountType, }, auth::AuthSecretKey, crypto::SecretKey, @@ -38,8 +38,8 @@ impl WebClient { .anchor((&anchor_block).try_into().unwrap()) .account_type(account_type) .storage_mode(storage_mode.into()) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicWalletComponent) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicWallet) .build() { Ok(result) => result, @@ -98,16 +98,12 @@ impl WebClient { .anchor((&anchor_block).try_into().unwrap()) .account_type(AccountType::FungibleFaucet) .storage_mode(storage_mode.into()) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component( - BasicFungibleFaucetComponent::new(symbol, decimals, max_supply).map_err( - |err| { - JsValue::from_str( - format!("Failed to create new faucet: {}", err).as_str(), - ) - }, - )?, - ) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicFungibleFaucet::new(symbol, decimals, max_supply).map_err( + |err| { + JsValue::from_str(format!("Failed to create new faucet: {}", err).as_str()) + }, + )?) .build() { Ok(result) => result, diff --git a/docs/library.md b/docs/library.md index 18094528d..ac6ca8b0e 100644 --- a/docs/library.md +++ b/docs/library.md @@ -61,8 +61,8 @@ let (new_account, seed) = AccountBuilder::new(init_seed) // Seed should be rando .anchor((&anchor_block).try_into().unwrap()) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(AccountStorageMode::Private) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicWalletComponent) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicWallet) .build()?; client.add_account(&new_account, Some(seed), &AuthSecretKey::RpoFalcon512(key_pair), false).await?; @@ -79,8 +79,8 @@ let (new_account, seed) = AccountBuilder::new(init_seed) // Seed should be rando .anchor((&anchor_block).try_into().unwrap()) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(AccountStorageMode::Public) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicWalletComponent) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicWallet) .build()?; client.add_account(&new_account, Some(seed), &AuthSecretKey::RpoFalcon512(key_pair), false).await?; diff --git a/tests/integration/common.rs b/tests/integration/common.rs index 4e7fdc763..0467776a0 100644 --- a/tests/integration/common.rs +++ b/tests/integration/common.rs @@ -2,8 +2,8 @@ use std::{env::temp_dir, path::PathBuf, sync::Arc, time::Duration}; use miden_client::{ account::{ - AccountBuilder, AccountType, BasicFungibleFaucetComponent, BasicWalletComponent, - RpoFalcon512Component, + component::{BasicFungibleFaucet, BasicWallet, RpoFalcon512}, + AccountBuilder, AccountType, }, auth::AuthSecretKey, crypto::FeltRng, @@ -106,8 +106,8 @@ pub async fn insert_new_wallet( .anchor((&anchor_block).try_into().unwrap()) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(storage_mode) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicWalletComponent) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicWallet) .build() .unwrap(); @@ -138,8 +138,8 @@ pub async fn insert_new_fungible_faucet( .anchor((&anchor_block).try_into().unwrap()) .account_type(AccountType::FungibleFaucet) .storage_mode(storage_mode) - .with_component(RpoFalcon512Component::new(key_pair.public_key())) - .with_component(BasicFungibleFaucetComponent::new(symbol, 10, max_supply).unwrap()) + .with_component(RpoFalcon512::new(key_pair.public_key())) + .with_component(BasicFungibleFaucet::new(symbol, 10, max_supply).unwrap()) .build() .unwrap(); From ffc82edcc153daa0b2bc1a6039ab1e65ed4389e3 Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Fri, 24 Jan 2025 19:01:12 -0300 Subject: [PATCH 2/7] chore: Cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f34c617ed..c58762246 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1511,9 +1511,9 @@ dependencies = [ [[package]] name = "miden-objects" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7532561ba51c1edcdc510e4e4a097357d49a2b6ea899d9982176dc5608bfd32e" +checksum = "4622f71888d4641577d145dd561165824b9b9293fd0be2306326f11bcf39e67d" dependencies = [ "getrandom", "miden-assembly", From a0cb3f81e3c760839be94a3f41f2ca09b7f995b9 Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Sun, 26 Jan 2025 00:12:51 -0300 Subject: [PATCH 3/7] reviews: Docs above attribues, roll back env var name --- bin/miden-cli/src/commands/new_account.rs | 21 +++++++++-------- crates/rust-client/build.rs | 28 ++++++++--------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/bin/miden-cli/src/commands/new_account.rs b/bin/miden-cli/src/commands/new_account.rs index 20a061d19..adaa11772 100644 --- a/bin/miden-cli/src/commands/new_account.rs +++ b/bin/miden-cli/src/commands/new_account.rs @@ -115,23 +115,24 @@ fn process_component_templates( #[derive(Debug, Parser, Clone)] /// Create a new faucet account. pub struct NewFaucetCmd { - #[clap(value_enum, short, long, default_value_t = CliAccountStorageMode::Private)] /// Storage mode of the account. + #[clap(value_enum, short, long, default_value_t = CliAccountStorageMode::Private)] storage_mode: CliAccountStorageMode, - #[clap(short, long)] /// Defines if the account assets are non-fungible (by default it is fungible). - non_fungible: bool, #[clap(short, long)] + non_fungible: bool, /// Token symbol of the faucet. - token_symbol: Option, #[clap(short, long)] + token_symbol: Option, /// Decimals of the faucet. + #[clap(short, long)] decimals: Option, + /// Maximum amount of assets that the fungible faucet can distribute. #[clap(short, long)] max_supply: Option, + /// Optional list of files specifying addional components to add to the account. #[clap(short, long)] - /// List of additional component template files to include. - template_files: Vec, + extra_components: Vec, } impl NewFaucetCmd { @@ -213,15 +214,15 @@ impl NewFaucetCmd { #[derive(Debug, Parser, Clone)] /// Create a new wallet account. pub struct NewWalletCmd { - #[clap(value_enum, short, long, default_value_t = CliAccountStorageMode::Private)] /// Storage mode of the account. + #[clap(value_enum, short, long, default_value_t = CliAccountStorageMode::Private)] pub storage_mode: CliAccountStorageMode, - #[clap(short, long)] /// Defines if the account code is mutable (by default it isn't mutable). + #[clap(short, long)] pub mutable: bool, + /// Optional list of files specifying addional components to add to the account. #[clap(short, long)] - /// Optional list of additional component package files to include. - pub template_files: Vec, + pub extra_components: Vec, } impl NewWalletCmd { diff --git a/crates/rust-client/build.rs b/crates/rust-client/build.rs index 856db03e0..3aabbd29a 100644 --- a/crates/rust-client/build.rs +++ b/crates/rust-client/build.rs @@ -7,7 +7,7 @@ use std::{ use miden_lib::note::scripts::{p2id, p2idr, swap}; use miden_rpc_proto::write_proto; -use miette::IntoDiagnostic; +use miette::{Error, IntoDiagnostic}; use prost::Message; const STD_PROTO_OUT_DIR: &str = "src/rpc/generated/std"; @@ -16,30 +16,22 @@ const NO_STD_PROTO_OUT_DIR: &str = "src/rpc/generated/nostd"; /// Defines whether the build script should generate files in `/src`. /// The docs.rs build pipeline has a read-only filesystem, so we have to avoid writing to `src`, /// otherwise the docs will fail to build there. Note that writing to `OUT_DIR` is fine. -const BUILD_GENERATED_FILES_IN_SRC: bool = option_env!("BUILD_GENERATED_FILES_IN_SRC").is_some(); +const CODEGEN: bool = option_env!("CODEGEN").is_some(); fn main() -> miette::Result<()> { - println!("cargo::rerun-if-env-changed=BUILD_GENERATED_FILES_IN_SRC"); - - let out_dir = env::var("OUT_DIR").expect("OUT_DIR should be set"); - let dest_path = PathBuf::from(out_dir); - - if !BUILD_GENERATED_FILES_IN_SRC { + println!("cargo::rerun-if-env-changed=CODEGEN"); + if !CODEGEN { return Ok(()); } - // updates the generated files from protobuf. Only do so when this is not docs.rs building the - // documentation. - if env::var("CODEGEN").unwrap_or("0".to_string()) == "1" { - write_proto(&dest_path).unwrap(); - compile_tonic_client_proto(&dest_path)?; - replace_no_std_types(); - generate_known_script_roots().unwrap(); - } + let out_dir = env::var("OUT_DIR").expect("OUT_DIR should be set"); + let dest_path = PathBuf::from(out_dir); - Ok(()) + write_proto(&dest_path).map_err(miette::Report::msg)?; + compile_tonic_client_proto(&dest_path)?; + replace_no_std_types(); + generate_known_script_roots().into_diagnostic() } - // NODE RPC CLIENT PROTO CODEGEN // =============================================================================================== From 09f8baef2a7fdfe127c72f1afa050c387a21f3cc Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Sun, 26 Jan 2025 00:52:00 -0300 Subject: [PATCH 4/7] reviews: fix rename --- bin/miden-cli/src/commands/new_account.rs | 4 ++-- crates/rust-client/build.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/miden-cli/src/commands/new_account.rs b/bin/miden-cli/src/commands/new_account.rs index adaa11772..67246d898 100644 --- a/bin/miden-cli/src/commands/new_account.rs +++ b/bin/miden-cli/src/commands/new_account.rs @@ -149,7 +149,7 @@ impl NewFaucetCmd { } let mut extra_components = Vec::new(); - for path in &self.template_files { + for path in &self.extra_components { let bytes = fs::read(path)?; let template = AccountComponentTemplate::read_from_bytes(&bytes).map_err(|e| { CliError::AccountComponentError( @@ -228,7 +228,7 @@ pub struct NewWalletCmd { impl NewWalletCmd { pub async fn execute(&self, mut client: Client) -> Result<(), CliError> { let mut extra_components = Vec::new(); - for path in &self.template_files { + for path in &self.extra_components { let bytes = fs::read(path)?; let template = AccountComponentTemplate::read_from_bytes(&bytes).map_err(|e| { CliError::AccountComponentError( diff --git a/crates/rust-client/build.rs b/crates/rust-client/build.rs index 3aabbd29a..ad3187c35 100644 --- a/crates/rust-client/build.rs +++ b/crates/rust-client/build.rs @@ -7,7 +7,7 @@ use std::{ use miden_lib::note::scripts::{p2id, p2idr, swap}; use miden_rpc_proto::write_proto; -use miette::{Error, IntoDiagnostic}; +use miette::IntoDiagnostic; use prost::Message; const STD_PROTO_OUT_DIR: &str = "src/rpc/generated/std"; From af86bd79b3c3937cf6df6f7324ba5a1eedb2bddf Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Mon, 27 Jan 2025 09:48:01 -0300 Subject: [PATCH 5/7] docs: Move doc comments above attributes --- bin/miden-cli/src/commands/new_account.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/miden-cli/src/commands/new_account.rs b/bin/miden-cli/src/commands/new_account.rs index 67246d898..85893a898 100644 --- a/bin/miden-cli/src/commands/new_account.rs +++ b/bin/miden-cli/src/commands/new_account.rs @@ -112,8 +112,8 @@ fn process_component_templates( // NEW FAUCET // ================================================================================================ -#[derive(Debug, Parser, Clone)] /// Create a new faucet account. +#[derive(Debug, Parser, Clone)] pub struct NewFaucetCmd { /// Storage mode of the account. #[clap(value_enum, short, long, default_value_t = CliAccountStorageMode::Private)] @@ -211,8 +211,8 @@ impl NewFaucetCmd { // NEW WALLET // ================================================================================================ -#[derive(Debug, Parser, Clone)] /// Create a new wallet account. +#[derive(Debug, Parser, Clone)] pub struct NewWalletCmd { /// Storage mode of the account. #[clap(value_enum, short, long, default_value_t = CliAccountStorageMode::Private)] From 8abcdc1ee0faf091ea0c0fece42bb72df45a8a2d Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Mon, 27 Jan 2025 10:05:15 -0300 Subject: [PATCH 6/7] doc tests: Fix import --- crates/rust-client/src/account.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rust-client/src/account.rs b/crates/rust-client/src/account.rs index 58650febd..e06a1ae16 100644 --- a/crates/rust-client/src/account.rs +++ b/crates/rust-client/src/account.rs @@ -11,7 +11,7 @@ //! follows: //! //! ```rust -//! # use miden_client::account::{Account, AccountBuilder, AccountType, BasicWalletComponent}; +//! # use miden_client::account::{Account, AccountBuilder, AccountType, component::BasicWallet}; //! # use miden_objects::account::{AuthSecretKey, AccountStorageMode}; //! # use miden_client::crypto::{FeltRng, SecretKey}; //! # async fn add_new_account_example( @@ -23,7 +23,7 @@ //! let (account, seed) = AccountBuilder::new(random_seed) //! .account_type(AccountType::RegularAccountImmutableCode) //! .storage_mode(AccountStorageMode::Private) -//! .with_component(BasicWalletComponent) +//! .with_component(BasicWallet) //! .build()?; //! //! // Add the account to the client. The account seed and authentication key are required From ce5c46ae1dc2a61555ed5ef52c8cd13f5d499cd7 Mon Sep 17 00:00:00 2001 From: Ignacio Amigo Date: Mon, 27 Jan 2025 10:07:38 -0300 Subject: [PATCH 7/7] docs: Improve examples --- docs/cli-reference.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 29a5873f4..f8805043a 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -96,7 +96,7 @@ After creating an account with the `new-wallet` command, it is automatically sto Creates a new faucet account. This command has three optional flags: -- `--storage-mode `: Used to select the storage mode of the account (private if not specified). It may receive "private" or "public". +- `--storage-mode `: Used to select the storage mode of the account (private if not specified). It may receive "private" or "public". - `--non-fungible`: Makes the faucet asset non-fungible (it's fungible by default). - `--extra_components `: Allows to pass a list of account component template files which can be added to the account. If the templates contain placeholders, the CLI will prompt the user to enter the required data for instantiating storage appropriately. @@ -105,16 +105,16 @@ After creating an account with the `new-faucet` command, it is automatically sto #### Examples ```bash -# Example: Create a new wallet with default settings (private storage, immutable, no extra components) +# Create a new wallet with default settings (private storage, immutable, no extra components) miden new-wallet -# Example: Create a new wallet with public storage and a mutable code +# Create a new wallet with public storage and a mutable code miden new-wallet --storage-mode public --mutable -# Example: Create a new wallet that includes extra components from local templates +# Create a new wallet that includes extra components from local templates miden new-wallet --extra-components template1,template2 -# Example: Create a fungible faucet +# Create a fungible faucet miden new-faucet --token-symbol TST --decimals 10 --max-supply 100000 --storage-mode private ```