Accounts
Miden's account model is fundamentally different from traditional blockchains. Let's explore how to create and manage accounts programmatically.
Understanding Miden Accounts
Before diving into account creation, it's essential to understand what makes Miden accounts unique compared to traditional blockchain addresses.
What Makes Miden Accounts Special:
- Smart Contract Wallets: Every account is a programmable smart contract that can hold assets and execute custom logic
- Modular Design: Accounts are composed of reusable components (authentication, wallet functionality, etc.)
- Privacy Levels: Choose between public or private storage modes
Miden accounts differ from traditional blockchain addresses in fundamental ways.
Account Architecture:
- Every account is a smart contract with programmable logic
- Accounts can store assets (fungible and non-fungible tokens) in their vault
- Each account has storage slots for custom data
- Accounts are composed of modular components for different functionalities
Storage Modes:
- Public: All state visible onchain (transparent operations)
- Private: Only commitments onchain, full state held privately
Account Structure
Every Miden account contains these core components:
- Vault: Secure asset storage
- Storage: Key-value data store (up to 255 slots)
- Code: Smart contract logic
- Nonce: Anti-replay counter
- Components: Modular functionality (authentication, wallet, etc.)
Account Struct
pub struct MidenAccount {
/// Immutable, 120-bit ID encoding type, storage mode and version.
pub id: [u8; 15],
/// Determines mutability of the account (immutable, mutable).
pub account_type: AccountType,
/// Storage placement preference (public/private).
pub storage_mode: StorageMode,
/// Root commitment of the account CODE (MAST root).
pub code_commitment: [u8; 32],
/// Root commitment of the account STORAGE (slots / maps).
/// Think of this as the "root hash" of the Account's storage merkle tree.
pub storage_commitment: [u8; 32],
/// Vault commitment. For compact headers we keep only an optional aggregate commitment.
/// Indexers can materialize a richer view (e.g., list of assets) offchain.
pub vault_commitment: Option<[u8; 32]>,
/// Monotonically increasing counter; must increment exactly once when state changes.
pub nonce: u64,
/// Merged set of account components that defined this account's interface and storage.
/// Accounts are composed by merging components (e.g. wallet component + an auth component).
pub components: Vec<ComponentDescriptor>,
/// Authentication procedure metadata (e.g. "RpoFalcon512").
pub authentication: AuthenticationDescriptor,
}
Account Types:
pub enum AccountType {
// Faucet that can issue fungible assets
FungibleFaucet = 2,
// Faucet that can issue non-fungible assets
NonFungibleFaucet = 3,
// Regular account with immutable code
RegularAccountImmutableCode = 0,
/// Regular account with updateable code
RegularAccountUpdatableCode = 1,
}
Storage Modes:
pub enum StorageMode {
/// State stored onchain and publicly readable.
Public,
/// Only a commitment is onchain; full state is held privately by the owner.
Private,
}
Set Up Development Environment
To run the code examples in this guide, you'll need to set up a development environment for either Rust or TypeScript.
Rust Environment
Create a new Miden Rust project:
miden new my-project
cd my-project/integration/
For each code example, create a new binary file:
touch src/bin/demo.rs
Copy the Rust code example into the file, then run:
cargo run --bin demo --release
TypeScript Environment
Create a new Miden frontend project:
yarn create-miden-app
cd miden-app/
For each code example, create a demo file:
touch src/lib/demo.ts
Copy the TypeScript code into the file, then import and call the demo() function in your App.tsx. Run the project:
yarn dev
# or
npm run dev
For detailed frontend setup guidance, see the Web Client tutorial.
Creating Accounts Programmatically
Let's start by creating accounts using the Miden client libraries:
import { WebClient, AccountStorageMode } from "@demox-labs/miden-sdk";
export async function demo() {
// Initialize client to connect with the Miden Testnet.
// NOTE: The client is our entry point to the Miden network.
// All interactions with the network go through the client.
const nodeEndpoint = "https://rpc.testnet.miden.io:443";
const client = await WebClient.createClient(nodeEndpoint);
await client.syncState();
// Create new wallet account
const account = await client.newWallet(
AccountStorageMode.public(), // Public: account state is visible onchain
true // Mutable: account code can be upgraded later
);
console.log("Account ID:", account.id().toString());
console.log(
"No Assets in Vault:",
account.vault().fungibleAssets().length === 0
);
}
Expected output
Account ID: 0x94733054a40d1610178320cc0c8060
No Assets in Vault: true
Creating a Token Faucet
Before we can work with tokens, we need a source of tokens. Let's create a fungible token faucet:
import { WebClient, AccountStorageMode } from "@demox-labs/miden-sdk";
export async function demo() {
// Initialize client to connect with the Miden Testnet.
// NOTE: The client is our entry point to the Miden network.
// All interactions with the network go through the client.
const nodeEndpoint = "https://rpc.testnet.miden.io:443";
const client = await WebClient.createClient(nodeEndpoint);
await client.syncState();
const symbol = "TEST";
const decimals = 8;
const initialSupply = BigInt(10_000_000 * 10 ** decimals);
const faucet = await client.newFaucet(
AccountStorageMode.public(),
false,
symbol,
decimals,
initialSupply
);
console.log("Faucet account ID:", faucet.id().toString());
}
Expected output
Faucet account ID: 0xde0ba31282f7522046d3d4af40722b
Key Takeaways
Account Types:
- Regular Accounts: Standard smart contract wallets that can hold assets and execute custom logic
- Faucet Accounts: Specialized accounts with minting permissions for tokens
Storage Modes:
- Public: Account state is fully transparent and visible onchain
- Private: Only cryptographic commitments are stored onchain, with full state maintained privately
Modular Components:
- BasicWallet: Provides asset management functionality
- BasicFungibleFaucet: Enables token minting capabilities
- AuthRpoFalcon512: Handles cryptographic authentication
Now that you understand how to create accounts and faucets, you're ready to learn about Miden's unique transaction model. Continue to Notes & Transactions to explore how assets move between accounts using notes.