Skip to main content
Version: 0.17 (unstable)

Miden Testnet 0.16.0

This guide covers all breaking changes you need to migrate an application to Miden 0.16.0. Like the 0.15 guide, it is intentionally user-facing: you do not need to know or care which internal crate (VM, protocol, client) a change came from. If you are:

  • building accounts, notes, or transactions
  • running a client, web client or React SDK
  • writing or compiling MASM
  • writing Rust smart contracts with the miden SDK
  • interacting with storage, auth, or RPCs

this document is for you. It folds together the breaking changes from the protocol crates (0.15.30.16.0), the VM crates (miden-vm, 0.230.29.2), miden-client (0.150.16.0), the Web SDK (@miden-sdk/* 0.150.16.0), and the miden Rust contract SDK / compiler (0.130.14).


Quick Upgrade

Try upgrading first — most projects can start with a dependency update:

Cargo.toml
# Replace these
miden-client = "0.15"
miden-client-sqlite-store = "0.15"
miden-protocol = "0.15.3"
miden-standards = "0.15.3"
miden-tx = "0.15.3"
miden-tx-batch-prover = "0.15.3"
miden-assembly = "0.23"
miden-core = "0.23"
miden-core-lib = "0.23"
miden-processor = "0.23"
miden-prover = "0.23"
miden-crypto = "0.25"

# With these
miden-client = "0.16.1"
miden-client-sqlite-store = "0.16.1"
miden-protocol = "0.16.1"
miden-standards = "0.16.1"
miden-tx = "0.16.1"
miden-tx-batch = "0.16.1" # renamed from miden-tx-batch-prover
miden-assembly = "0.29.2"
miden-core = "0.29.2"
miden-core-lib = "0.29.2"
miden-processor = "0.29.2"
miden-prover = "0.29.2"
miden-crypto = "0.29.2"
package.json (Web SDK)
{
"@miden-sdk/miden-sdk": "0.16.1",
"@miden-sdk/react": "0.16.0"
}

Then run:

cargo update && cargo build

If you encounter errors, continue reading for detailed migration steps.

The MAST wire format moved 0.0.30.0.4, the package format 4.0.06.0.0, and the .masl library format was removed entirely. Several commitment preimages changed as well. Re-assemble every package from source and re-sync into a fresh store.

Every pre-0.16 SQLite store is rejected — there is no migration path. Browser applications reset their IndexedDB store automatically. Separately, 0.16 clients seal (encrypt) transaction inputs before submission, so a 0.16 client cannot talk to an older node and vice versa.


This guide is for:

  • Rust client developers migrating from v0.15 → v0.16
  • Web SDK developers using the JavaScript/TypeScript SDK
  • Smart contract authors writing MASM or using protocol APIs
  • App developers using the protocol, standards, or client crates

If you're starting fresh on v0.16, you can skip this guide and go directly to the Get Started guide.


At a Glance

Big themes in 0.16:

ChangeSummary
Fees moved into the auth procedureThe kernel no longer burns the fee automatically. The auth procedure reads FeeConversionInfo from the transaction's auth args and emits a TX_FEE note. On a fee-charging chain, requests signed by AuthSingleSig/AuthMultisig must call TransactionRequestBuilder::fee_conversion_info(info, salt).
MASM gained an explicit module treeA .masm file is only included if its parent declares it with mod/pub mod — an undeclared file is silently dropped. use split into module imports and braced item imports, aliases moved from -> to as, and imports resolve globally.
Account updates became absoluteAccountDeltaAccountPatch for account updates (ExecutedTransaction, AccountUpdateDetails, client results). TransactionSummary::account_delta() deliberately stays relative.
Signed summaries bind their reference blockA summary now only authorizes an execution at the block it was derived at, so multisig and offline co-signing flows break silently — every party derives a different summary at its own sync height. Capture a ChainAnchor and have all of them execute against it. Nothing fails to compile.
Auth is no longer a special builder slotAccountBuilder::with_auth_component is gone; auth components pass through with_component(s) and are found by their @auth_script attribute. Keys are wrapped in a new Approver / ApproverSet. AuthMethod and AuthSingleSigAcl are removed.
Asset identity renamed one level downAssetVaultKeyAssetId, and the old AssetIdAssetClass. Because AssetId survives with a new meaning, careless renaming compiles and is wrong.
Library is gone; Package is the only artifactLibrary/KernelLibrary were deleted, link_*_library collapsed into link_package, *_from_dir became *_from_root, and .masl no longer exists. MAST 0.0.4 / package 6.0.0 are not backward compatible.
Notes use typed builders, and carry fewer assetsXNote::create(..)XNote::builder()…build()? + .into(). MAX_ASSETS_PER_NOTE dropped 64 → 16. Mint and burn scripts were unified across faucet kinds, changing their roots.
Debug decorators removeddebug.* and trace are gone from the language, replaced by miden::core::debug procedures — which, unlike the decorators, print unconditionally. The client and CLI debug-mode toggles were removed with them.
Commitment preimages changedECDSA public-key commitments, MMR peak commitments, and domain-separated empty-input hashes all changed value. Nothing fails to compile; stored values simply stop matching.
Store and node compatibility both breakEvery pre-0.16 SQLite store must be recreated, and transaction inputs are now sealed, so client and node must be upgraded together.

If you only skim a few sections, skim Transaction Changes, Account Changes, MASM Changes, and Client Changes.


Compatibility

ComponentRequiredTested With
Miden VM crates0.29+0.29.2
miden-crypto0.29+0.29.2
miden-protocol0.16+0.16.1
miden-standards0.16+0.16.1
miden-client0.16+0.16.1
Web SDK (@miden-sdk/*)0.16+0.16.0
miden contract SDK0.14+0.14.0
midenc compiler0.10+0.10.1
Rust (client / protocol)1.98.1+1.98.1
Rust (VM)1.96.1+1.96.1
Rust (contract SDK / compiler)1.99+1.99

The protocol and client crates are now published as stable v0.16 releases. The examples above pin the patch versions used to validate this snapshot.

Compiler v0.10.1 and the miden contract SDK still pin protocol 0.16.0-rc.4, while the client and node use stable protocol v0.16.1. They use the same VM 0.29 line, but the compiler sees an earlier protocol API snapshot. Its MSRV is also higher, at 1.99.


Migration Sections

Work through these sections in order for a complete migration:

SectionTopics
1. Imports & DependenciesCrate bumps, VM 0.23 → 0.29.2, MSRV 1.98.1, artifacts that must be rebuilt
2. Hashing & Crypto ChangesECDSA public-key commitments, MMR peaks binding the leaf count, empty domain-separated hashing
3. Account Changeswith_auth_component removed, Approver/ApproverSet, component name changes, AccountPatch
4. Note ChangesTyped note builders, MAX_ASSETS_PER_NOTE 64 → 16, unified mint/burn scripts
5. Assets, Vault & FaucetAssetVaultKeyAssetId, old AssetIdAssetClass, split faucet factories
6. Transaction ChangesFees paid by the auth procedure, sealed transaction inputs, TransactionSummary, ChainAnchor
7. Client ChangesStore recreation, node compatibility, chain-anchored execution, Rust/Web/React/CLI changes
8. MASM Changesmod declarations, new import syntax, debug decorators removed, protocol procedure moves
9. VM & Assembler ChangesLibraryPackage, MAST 0.0.4, ExecutionClaim, miden-project.toml
10. Rust Contract SDK & Compiler#[account_procedure], #[account(..)] generating traits, toolchain version skew

Final Checklist

Complete these steps to verify your migration:

  • Bump all Miden crate versions per section 1 and rename miden-tx-batch-prover to miden-tx-batch
  • Bump @miden-sdk/miden-sdk and @miden-sdk/react together; drop any miden-idxdb-store dependency
  • Update the toolchain to Rust 1.98.1 (1.99 if you also build Rust contracts)
  • Re-assemble every .masp from source and delete cached MastForest blobs; .masl no longer exists
  • Delete and recreate your local store, then re-sync — export private note files first
  • Upgrade your node together with your client — sealed and plaintext submissions are mutually incompatible
  • Add mod / pub mod declarations so every .masm file is reachable from your project root
  • Rewrite pub use a::b::c as pub use {c} from a::b, and use x->y as use x as y
  • Replace debug.* / trace decorators with miden::core::debug procedures, and strip them from production code
  • Declare fee conversion info on transactions if your chain charges a fee, and fund the paying account with the fee asset
  • Move auth components out of with_auth_component and wrap keys in Approver / ApproverSet
  • Rename AssetIdAssetClass first, then AssetVaultKeyAssetId
  • Replace account_delta() with account_patch() — but leave TransactionSummary::account_delta() alone
  • If you collect signatures over a summary across clients, capture a ChainAnchor and derive, verify, and execute the transaction against it
  • Rewrite XNote::create(..) calls as builders, and cap notes at 16 assets
  • Recompute stored ECDSA public-key commitments, MMR peak commitments, and empty domain-separated hashes
  • Replace Library/KernelLibrary with Package, and link_*_library with link_package
  • Add an explicit path to every [lib] and [[bin]] in miden-project.toml
  • Build an ExecutionClaim and call verify(proof, claim); discard proofs serialized under 0.15
  • CLI: rename send to transfer, --with-code to --inspect, and id to address in token_symbol_map.toml
  • CLI: re-check every call invocation — arguments are now counted in field elements
  • (If you write Rust contracts) mark component trait methods with #[account_procedure] and import the traits generated by #[account(..)]
  • Run cargo buildno errors
  • Run cargo testall tests pass

If your project builds and all tests pass, you've successfully migrated to v0.16.


Need Help?

  • Telegram: Build on Miden — technical discussion and support.
  • Forum: Miden discussions — longer-form questions and design discussion.
  • GitHub issues: file against the relevant repo — rust-sdk, web-sdk, protocol, miden-vm, or compiler.
  • Changelogs: the per-repo CHANGELOG.md files carry the full list of changes, including non-breaking features and fixes omitted from this guide.