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
midenSDK - interacting with storage, auth, or RPCs
this document is for you. It folds together the breaking changes from the protocol crates (0.15.3 → 0.16.0), the VM crates (miden-vm, 0.23 → 0.29.2), miden-client (0.15 → 0.16.0), the Web SDK (@miden-sdk/* 0.15 → 0.16.0), and the miden Rust contract SDK / compiler (0.13 → 0.14).
Quick Upgrade
Try upgrading first — most projects can start with a dependency update:
# 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"
{
"@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.3 → 0.0.4, the package format 4.0.0 → 6.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:
| Change | Summary |
|---|---|
| Fees moved into the auth procedure | The 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 tree | A .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 absolute | AccountDelta → AccountPatch for account updates (ExecutedTransaction, AccountUpdateDetails, client results). TransactionSummary::account_delta() deliberately stays relative. |
| Signed summaries bind their reference block | A 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 slot | AccountBuilder::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 down | AssetVaultKey → AssetId, and the old AssetId → AssetClass. Because AssetId survives with a new meaning, careless renaming compiles and is wrong. |
Library is gone; Package is the only artifact | Library/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 assets | XNote::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 removed | debug.* 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 changed | ECDSA 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 break | Every 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
| Component | Required | Tested With |
|---|---|---|
| Miden VM crates | 0.29+ | 0.29.2 |
| miden-crypto | 0.29+ | 0.29.2 |
| miden-protocol | 0.16+ | 0.16.1 |
| miden-standards | 0.16+ | 0.16.1 |
| miden-client | 0.16+ | 0.16.1 |
Web SDK (@miden-sdk/*) | 0.16+ | 0.16.0 |
miden contract SDK | 0.14+ | 0.14.0 |
midenc compiler | 0.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:
| Section | Topics |
|---|---|
| 1. Imports & Dependencies | Crate bumps, VM 0.23 → 0.29.2, MSRV 1.98.1, artifacts that must be rebuilt |
| 2. Hashing & Crypto Changes | ECDSA public-key commitments, MMR peaks binding the leaf count, empty domain-separated hashing |
| 3. Account Changes | with_auth_component removed, Approver/ApproverSet, component name changes, AccountPatch |
| 4. Note Changes | Typed note builders, MAX_ASSETS_PER_NOTE 64 → 16, unified mint/burn scripts |
| 5. Assets, Vault & Faucet | AssetVaultKey → AssetId, old AssetId → AssetClass, split faucet factories |
| 6. Transaction Changes | Fees paid by the auth procedure, sealed transaction inputs, TransactionSummary, ChainAnchor |
| 7. Client Changes | Store recreation, node compatibility, chain-anchored execution, Rust/Web/React/CLI changes |
| 8. MASM Changes | mod declarations, new import syntax, debug decorators removed, protocol procedure moves |
| 9. VM & Assembler Changes | Library → Package, 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-provertomiden-tx-batch - Bump
@miden-sdk/miden-sdkand@miden-sdk/reacttogether; drop anymiden-idxdb-storedependency - Update the toolchain to Rust 1.98.1 (1.99 if you also build Rust contracts)
- Re-assemble every
.maspfrom source and delete cachedMastForestblobs;.maslno 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 moddeclarations so every.masmfile is reachable from your project root - Rewrite
pub use a::b::caspub use {c} from a::b, anduse x->yasuse x as y - Replace
debug.*/tracedecorators withmiden::core::debugprocedures, 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_componentand wrap keys inApprover/ApproverSet - Rename
AssetId→AssetClassfirst, thenAssetVaultKey→AssetId - Replace
account_delta()withaccount_patch()— but leaveTransactionSummary::account_delta()alone - If you collect signatures over a summary across clients, capture a
ChainAnchorand 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/KernelLibrarywithPackage, andlink_*_librarywithlink_package - Add an explicit
pathto every[lib]and[[bin]]inmiden-project.toml - Build an
ExecutionClaimand callverify(proof, claim); discard proofs serialized under 0.15 - CLI: rename
sendtotransfer,--with-codeto--inspect, andidtoaddressintoken_symbol_map.toml - CLI: re-check every
callinvocation — 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 build— no errors - Run
cargo test— all 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, orcompiler. - Changelogs: the per-repo
CHANGELOG.mdfiles carry the full list of changes, including non-breaking features and fixes omitted from this guide.