Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Introduce top-level module docs for Rust client crate #683

Merged
merged 20 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/test.yml
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
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
5 changes: 3 additions & 2 deletions 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)
bobbinth marked this conversation as resolved.
Show resolved Hide resolved

# --- 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.** |
bobbinth marked this conversation as resolved.
Show resolved Hide resolved

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

### Store and RpcClient implementations

Expand Down
49 changes: 46 additions & 3 deletions crates/rust-client/src/account.rs
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,8 +1,51 @@
//! The `accounts` module provides types and client APIs for managing accounts within the Miden
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//! 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.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! # 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.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! # 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::account::{Account, AccountBuilder, AccountType, BasicWalletComponent};
//! # use miden_objects::account::{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(())
//! # }
//! ```
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! For more details on accounts, refer to the [Account] documentation.

use alloc::vec::Vec;

Expand Down
102 changes: 100 additions & 2 deletions crates/rust-client/src/lib.rs
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
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.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! This crate provides a lightweight client that handles connections to the 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/).
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ## 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.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! - **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"
//! ```
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ## 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 a 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/note/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.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
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
58 changes: 57 additions & 1 deletion crates/rust-client/src/note/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
//! 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,
//! note::{get_input_note_with_id_prefix, NoteScreener},
//! store::NoteFilter,
//! crypto::FeltRng,
//! };
//! use miden_objects::account::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 more details on the API and error handling, see the documentation for the specific functions
//! and types in this module.

use alloc::{collections::BTreeSet, string::ToString, vec::Vec};

Expand Down Expand Up @@ -126,7 +181,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.
bobbinth marked this conversation as resolved.
Show resolved Hide resolved
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
4 changes: 2 additions & 2 deletions crates/rust-client/src/rpc/generated/nostd/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>,
}
Expand All @@ -31,7 +31,7 @@ pub struct AccountInfo {
#[prost(message, optional, tag = "1")]
pub summary: ::core::option::Option<AccountSummary>,
/// 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<u8>>,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rust-client/src/rpc/generated/nostd/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion crates/rust-client/src/rpc/generated/nostd/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>>,
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rust-client/src/rpc/generated/std/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>,
}
Expand All @@ -31,7 +31,7 @@ pub struct AccountInfo {
#[prost(message, optional, tag = "1")]
pub summary: ::core::option::Option<AccountSummary>,
/// 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<u8>>,
}
Expand Down
Loading
Loading