Skip to main content
Version: 0.11 (stable)

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:

>_ Terminal
miden new my-project
cd my-project/integration/

For each code example, create a new binary file:

>_ Terminal
touch src/bin/demo.rs

Copy the Rust code example into the file, then run:

>_ Terminal
cargo run --bin demo --release

TypeScript Environment

Create a new Miden frontend project:

>_ Terminal
yarn create-miden-app
cd miden-app/

For each code example, create a demo file:

>_ Terminal
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:

>_ Terminal
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:

src/lib/account.ts
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:

src/lib/faucet.ts
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.