Skip to main content
Version: 0.12

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";

// Initialize client
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";

// Initialize client
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.