Skip to content

Commit

Permalink
docs: Introduce top-level module
Browse files Browse the repository at this point in the history
  • Loading branch information
igamigo committed Jan 21, 2025
1 parent 0ce5fe7 commit 4be8932
Show file tree
Hide file tree
Showing 33 changed files with 523 additions and 78 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ jobs:
- name: make - test
run: make test

doc-tests:
name: doc-tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- uses: Swatinem/rust-cache@v2
with:
save-if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/next' }}
- name: Install rust
run: rustup update --no-self-update
- name: Run doc-tests
run: make test-docs

integration-tests:
name: integration-tests
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ test: ## Run tests
test-deps: ## Install dependencies for tests
CODEGEN=1 cargo install cargo-nextest

.PHONY: test-docs
test-docs: ## Run documentation tests
CODEGEN=1 cargo test --doc $(FEATURES_CLIENT)

# --- Integration testing -------------------------------------------------------------------------

.PHONY: integration-test
Expand Down
18 changes: 10 additions & 8 deletions crates/rust-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ miden-client = { version = "0.6" }

## Crate Features

- `concurrent`: used to enable concurrency during execution and proof generation. Disabled by default.
- `idxdb`: includes `WebStore`, an IdexedDB implementation of the `Store` trait. Disabled by default.
- `sqlite`: includes `SqliteStore`, a SQLite implementation of the `Store` trait. Disabled by default.
- `tonic`: includes `TonicRpcClient`, a Tonic client to communicate with Miden node. Disabled by default.
- `web-tonic`: includes `WebTonicRpcClient`, an Tonic client to communicate with the Miden node in the browser. Disabled by default.
- `testing`: useful feature that lowers PoW difficulty when enabled, meant to be used during development and not on production. Disabled by default.

To compile with `no_std`, disable default features via `--no-default-features` flag.
| Features | Description |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `concurrent` | Used to enable concurrency during execution and proof generation. **Disabled by default.** |
| `idxdb` | Includes `WebStore`, an IndexedDB implementation of the `Store` trait. **Disabled by default.** |
| `sqlite` | Includes `SqliteStore`, a SQLite implementation of the `Store` trait. This relies on the standard library. **Disabled by default.** |
| `tonic` | Includes `TonicRpcClient`, a Tonic client to communicate with Miden node. This relies on the standard library. **Disabled by default.** |
| `web-tonic` | Includes `WebTonicRpcClient`, a Tonic client to communicate with the Miden node in the browser. **Disabled by default.** |
| `testing` | Useful feature that lowers PoW difficulty when enabled, meant to be used during development and not in production. **Disabled by default.** |

Features `sqlite` and `idxdb` are mutually exclusive.

### Store and RpcClient implementations

Expand Down
66 changes: 63 additions & 3 deletions crates/rust-client/src/accounts.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,68 @@
//! The `accounts` module provides types and client APIs for managing accounts within the Miden
//! rollup network .
//! rollup network.
//!
//! Once accounts start being tracked by the client, their state will be
//! updated accordingly on every transaction, and validated against the rollup on every sync.
//! Once accounts start being tracked by the client, their state will be updated accordingly on
//! every transaction, and validated against the rollup on every sync.
//!
//! An account can store assets and define rules for manipulating them.
//!
//! # Overview
//!
//! This module exposes several key features:
//!
//! - **Account types:** Use the [`AccountBuilder`] to construct new accounts, specifying account
//! type, storage mode (public/private), and attaching necessary components (e.g., basic wallet or
//! fungible faucet).
//!
//! - **Account Tracking:** Accounts added via the client are persisted to the local store, where
//! their state (including nonce, balance, and metadata) is updated upon every synchronization
//! with the network.
//!
//! - **Data retrieval APIs:** The module also provides methods to fetch account-related data.
//!
//! # Example
//!
//! To add a new account to the client's store, you might use the [`Client::add_account`] method as
//! follows:
//!
//! ```rust
//! # use miden_client::accounts::{Account, AccountBuilder, AccountType, BasicWalletComponent};
//! # use miden_objects::accounts::{AuthSecretKey, AccountStorageMode};
//! # use miden_client::crypto::{FeltRng, SecretKey};
//! # async fn add_new_account_example(client: &mut miden_client::Client<impl FeltRng>) -> Result<(), miden_client::ClientError> {
//! let key_pair = SecretKey::with_rng(client.rng());
//! # let random_seed = Default::default();
//!
//! let (account, seed) = AccountBuilder::new(random_seed)
//! .account_type(AccountType::RegularAccountImmutableCode)
//! .storage_mode(AccountStorageMode::Private)
//! .with_component(BasicWalletComponent)
//! .build()?;
//!
//! // Add the account to the client. The account seed and authentication key are required for new accounts.
//! client.add_account(&account, Some(seed), &AuthSecretKey::RpoFalcon512(key_pair), false).await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Account composition
//!
//! An account consists of the following components:
//! - Account ID, which uniquely identifies the account and also defines basic properties of the
//! account.
//! - Account vault, which stores assets owned by the account.
//! - Account storage, which is a key-value map (both keys and values are words) used to store
//! arbitrary user-defined data.
//! - Account code, which is a set of Miden VM programs defining the public interface of the
//! account.
//! - Account nonce, a value which is incremented whenever account state is updated.
//!
//! Out of the above components account ID is always immutable (once defined it can never be
//! changed). Other components may be mutated throughout the lifetime of the account. However,
//! account state can be changed only by invoking one of account interface methods.
//!
//! For more details on account management and synchronization, refer to the Miden client
//! documentation.
use alloc::vec::Vec;

Expand Down
102 changes: 100 additions & 2 deletions crates/rust-client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,102 @@
//! A no_std-compatible client library for interacting with the Miden rollup network.
//!
//! This crate provides a lightweight client that handles connections to Miden node, manages
//! accounts and their state, and facilitates executing, proving, and submitting transactions.
//!
//! For a protocol-level overview and guides for getting started, please visit the official
//! [Polygon Miden docs](https://docs.polygon.technology/miden/).
//!
//! ## Overview
//!
//! The library is organized into several key modules:
//!
//! - **Accounts:** Provides types, builders, and client APIs for managing accounts. Once accounts
//! are tracked by the client, their state is updated with every transaction and validated during
//! each sync.
//!
//! - **Notes:** Contains types and utilities for working with notes in the Miden client.
//!
//! - **RPC:** Facilitates communication with Miden node, exposing RPC methods for syncing state,
//! fetching block headers, and submitting transactions.
//!
//! - **Store:** Defines and implements the persistence layer for accounts, transactions, notes, and
//! other entities.
//!
//! - **Sync:** Provides functionality to synchronize the local state with the current state on the
//! Miden network.
//!
//! - **transactions:** Offers capabilities to build, execute, prove, and submit transactions.
//!
//! Additionally, the crate re-exports several utility modules:
//!
//! - **Assets:** Types and utilities for working with assets.
//! - **Auth:** Authentication-related types and functionalities.
//! - **Blocks:** Types for handling block headers.
//! - **Crypto:** Cryptographic types and utilities, including random number generators.
//! - **Utils:** Miscellaneous utilities for serialization and common operations.
//!
//! The library is designed to work in both `no_std` and `std` environments and is
//! configurable via Cargo features.
//!
//! ## Usage
//!
//! To use the Miden client library in your project, add it as a dependency in your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! miden-client = "0.6.0"
//! ```
//!
//! ## Example
//!
//! Below is a brief example illustrating how to instantiate the client:
//!
//! ```rust
//! use std::sync::Arc;
//!
//! use miden_client::{
//! crypto::RpoRandomCoin,
//! rpc::{Endpoint, TonicRpcClient},
//! store::{sqlite_store::SqliteStore, Store, StoreAuthenticator},
//! Client, Felt,
//! };
//! use miden_objects::crypto::rand::FeltRng;
//! use rand::Rng;
//!
//! # pub async fn create_test_client() -> Result<(), Box<dyn std::error::Error>> {
//! let client: Client<RpoRandomCoin> = {
//! // Create the SQLite store from the client configuration.
//! let sqlite_store = SqliteStore::new("path/to/store".try_into()?).await?;
//! let store = Arc::new(sqlite_store);
//!
//! // Generate a random seed for the RpoRandomCoin.
//! let mut rng = rand::thread_rng();
//! let coin_seed: [u64; 4] = rng.gen();
//!
//! // Initialize the random coin using the generated seed.
//! let rng = RpoRandomCoin::new(coin_seed.map(Felt::new));
//!
//! // Create a store authenticator with the store and random coin.
//! let authenticator = StoreAuthenticator::new_with_rng(store.clone(), rng);
//!
//! // Instantiate the client using a Tonic RPC client
//! let endpoint = Endpoint::new("https".into(), "localhost".into(), 57291);
//! Client::new(
//! Box::new(TonicRpcClient::new(endpoint, 10_000)),
//! rng,
//! store,
//! Arc::new(authenticator),
//! false, // Set to true for debug mode, if needed.
//! )
//! };
//!
//! # Ok(())
//! # }
//! ```
//!
//! For additional usage details, configuration options, and examples, consult the documentation for
//! each module.
#![no_std]

#[macro_use]
Expand Down Expand Up @@ -104,8 +203,7 @@ use tracing::info;
/// Miden client is responsible for managing a set of accounts. Specifically, the client:
/// - Keeps track of the current and historical states of a set of accounts and related objects such
/// as notes and transactions.
/// - Connects to one or more Miden nodes to periodically sync with the current state of the
/// network.
/// - Connects to the Miden node to periodically sync with the current state of the network.
/// - Executes, proves, and submits transactions to the network as directed by the user.
pub struct Client<R: FeltRng> {
/// The client's store, which provides a way to write and read entities to provide persistence.
Expand Down
14 changes: 13 additions & 1 deletion crates/rust-client/src/notes/import.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
//! Provides note importing methods.
//!
//! This module allows users to import notes into the client's store.
//! Depending on the variant of [NoteFile] provided, the client will either fetch note details
//! from the network or create a new note record from supplied data. If a note already exists in
//! the store, it is updated with the new information. Additionally, the appropriate note tag
//! is tracked based on the imported note's metadata.
//!
//! For more specific information on how the process is performed, refer to the docs for
//! [Client::import_note()].
use alloc::string::ToString;

use miden_objects::{
Expand Down Expand Up @@ -29,6 +39,8 @@ impl<R: FeltRng> Client<R> {
/// - If the note file is a [NoteFile::NoteWithProof], the note is stored with the provided
/// inclusion proof and metadata. The block header data is only fetched from the node if the
/// note is committed in the past relative to the client.
///
/// An error is returned if an attempt is made to overwrite a note that is currently processing.
pub async fn import_note(&mut self, note_file: NoteFile) -> Result<NoteId, ClientError> {
let id = match &note_file {
NoteFile::NoteId(id) => *id,
Expand Down Expand Up @@ -77,7 +89,7 @@ impl<R: FeltRng> Client<R> {
/// passed via `previous_note` so it can be updated. The note information is fetched from the
/// node and stored in the client's store.
///
/// Errors:
/// # Errors:
/// - If the note doesn't exist on the node.
/// - If the note exists but is private.
async fn import_note_record_by_id(
Expand Down
59 changes: 58 additions & 1 deletion crates/rust-client/src/notes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,61 @@
//! Contains the Client APIs related to notes. Notes can contain assets and scripts that are
//! executed as part of transactions.
//!
//! This module enables the tracking, retrieval, and processing of notes.
//! It offers methods to query input and output notes from the store, check their consumability,
//! compile note scripts, and retrieve notes based on partial ID matching.
//!
//! ## Overview
//!
//! The module exposes APIs to:
//!
//! - Retrieve input notes and output notes.
//! - Determine the consumability of notes using the [NoteScreener].
//! - Compile note scripts from source code with `compile_note_script`.
//! - Retrieve an input note by a prefix of its ID using the helper function
//! [get_input_note_with_id_prefix].
//!
//! ## Example
//!
//! ```rust
//! use miden_client::{
//! Client,
//! notes,
//! notes::{get_input_note_with_id_prefix, NoteScreener},
//! store::NoteFilter,
//! crypto::FeltRng,
//! };
//! use miden_objects::accounts::AccountId;
//!
//! # async fn example(client: &Client<impl FeltRng>) -> Result<(), Box<dyn std::error::Error>> {
//! // Retrieve all committed input notes
//! let input_notes = client.get_input_notes(NoteFilter::Committed).await?;
//! println!("Found {} committed input notes.", input_notes.len());
//!
//! // Check consumability for a specific note
//! if let Some(note) = input_notes.first() {
//! let consumability = client.get_note_consumability(note.clone()).await?;
//! println!("Note consumability: {:?}", consumability);
//! }
//!
//! // Retrieve an input note by a partial ID match
//! let note_prefix = "0x70b7ec";
//! match get_input_note_with_id_prefix(client, note_prefix).await {
//! Ok(note) => println!("Found note with matching prefix: {}", note.id().to_hex()),
//! Err(err) => println!("Error retrieving note: {:?}", err),
//! }
//!
//! // Compile the note script
//! let script_src = "begin push.9 push.12 add end";
//! let note_script = client.compile_note_script(script_src)?;
//! println!("Compiled note script successfully.");
//!
//! # Ok(())
//! # }
//! ```
//!
//! For further details on the API and error handling, refer to the specific function and type
//! documentations in this module.
use alloc::{collections::BTreeSet, string::ToString, vec::Vec};

Expand Down Expand Up @@ -121,7 +177,8 @@ impl<R: FeltRng> Client<R> {
Ok(self.store.get_output_notes(NoteFilter::Unique(note_id)).await?.pop())
}

/// Compiles the provided program into a [NoteScript]
/// Compiles the provided program into a [NoteScript].
/// The assembler uses the debug mode if the client is using debug mode.
pub fn compile_note_script(&self, note_script: &str) -> Result<NoteScript, ClientError> {
let assembler = TransactionKernel::assembler().with_debug_mode(self.in_debug_mode);
NoteScript::compile(note_script, assembler).map_err(ClientError::NoteError)
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-client/src/rpc/generated/nostd/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub struct CheckNullifiersByPrefixRequest {
#[prost(uint32, repeated, tag = "2")]
pub nullifiers: ::prost::alloc::vec::Vec<u32>,
}
/// Get a list of proofs for given nullifier hashes, each proof as a sparse Merkle Tree.
/// Returns a nullifier proof for each of the requested nullifiers.
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CheckNullifiersRequest {
/// List of nullifiers to return proofs for.
Expand Down
Loading

0 comments on commit 4be8932

Please sign in to comment.