Skip to main content
Version: 0.14

Mutation hooks

Mutation hooks own the full transaction lifecycle — execute, prove, submit — and serialize under the Web SDK's concurrency lock so two components can't corrupt the WASM state.

Two result-shape families show up across this page:

Transaction-producing hooks (useSend, useMultiSend, useMint, useConsume, useSwap, useTransaction):

{
[action]: (options) => Promise<Result>; // send, sendMany, mint, ...
result: Result | null;
isLoading: boolean;
stage: TransactionStage;
error: Error | null;
reset: () => void;
}

Account-creation hooks (useCreateWallet, useCreateFaucet, useImportAccount) don't go through the prove/submit pipeline, so they expose isCreating / isImporting instead of isLoading + stage:

{
createWallet: (opts?) => Promise<Account>;
wallet: Account | null;
isCreating: boolean; // or `isImporting` for useImportAccount
error: Error | null;
reset: () => void;
}

Polling helpers (useWaitForCommit, useWaitForNotes) are simpler still — they expose just the action. Per-hook exact shapes are called out below.

See setup for the TransactionStage progression.

useCreateWallet

Creates a new wallet account. Returns the Account object.

import { useCreateWallet, AuthScheme } from "@miden-sdk/react";

function NewWalletButton() {
const { createWallet, wallet, isCreating, error } = useCreateWallet();

const handleCreate = async () => {
const account = await createWallet({
storageMode: "private", // "private" | "public" | "network" (default private)
mutable: true, // default true — updatable code
authScheme: AuthScheme.AuthRpoFalcon512, // default
});
console.log("Created:", account.bech32id());
};

return (
<button onClick={handleCreate} disabled={isCreating}>Create wallet</button>
);
}

CreateWalletOptions (all optional):

FieldDefaultDescription
storageMode"private""private" / "public" / "network"
mutabletrueWhether code can be updated after deployment
authSchemeAuthScheme.AuthRpoFalcon512Signing scheme
initSeedrandom32-byte seed for deterministic account-ID derivation

useCreateFaucet

Creates a fungible-token faucet.

import { useCreateFaucet } from "@miden-sdk/react";

function NewFaucetButton() {
const { createFaucet, faucet, isCreating } = useCreateFaucet();

const handleCreate = async () => {
const created = await createFaucet({
tokenSymbol: "TEST",
decimals: 8, // default 8
maxSupply: 10_000_000n, // number | bigint
storageMode: "public", // default "private"; public allows FPI reads
});
console.log("Faucet:", created.bech32id());
};

return (
<button onClick={handleCreate} disabled={isCreating}>Create faucet</button>
);
}

CreateFaucetOptions:

FieldDefaultDescription
tokenSymbolrequiredDisplay symbol (e.g. "USDC")
maxSupplyrequiredbigint | number
decimals8Token decimals
storageMode"private"Public faucets are discoverable/readable on-chain
authSchemeAuthScheme.AuthRpoFalcon512Signing scheme

useSend

Sends tokens from one account to another.

import { useSend } from "@miden-sdk/react";

function SendForm({ from, to, usdcFaucetId }: Props) {
const { send, isLoading, stage, error } = useSend();

const handleSend = async () => {
const { txId, note } = await send({
from,
to,
assetId: usdcFaucetId,
amount: 100n,
noteType: "private", // default "private"
});
console.log("Transaction:", txId);
};

return (
<button onClick={handleSend} disabled={isLoading}>
{isLoading ? `${stage}` : "Send"}
</button>
);
}

SendOptions:

FieldRequiredDescription
fromyesSender AccountRef
toyesRecipient AccountRef
assetIdyesToken faucet AccountRef
amountunless sendAllbigint | number
noteType"private" / "public" (default "private")
recallHeightBlock height after which sender can reclaim the note
timelockHeightBlock height after which recipient can consume the note
attachmentbigint[] | Uint8Array | number[] — payload attached to the note
skipSyncSkip the pre-send auto-sync (default false)
sendAllDrain full balance of assetId — when true, amount is ignored
returnNoteReturn the Note object in the result (for out-of-band delivery, QR codes, etc.)

SendResult: { txId: string; note: Note | null }. note is non-null only when returnNote: true.

useMultiSend

Batches multiple recipients into one transaction. All outputs must share the same sender and asset. The action function is named sendMany.

import { useMultiSend } from "@miden-sdk/react";

const { sendMany, isLoading } = useMultiSend();

await sendMany({
from: senderAccountId,
assetId: faucetId,
recipients: [
{ to: recipient1, amount: 500n, noteType: "private" },
{ to: recipient2, amount: 300n },
],
noteType: "private", // default for recipients that don't override
});

MultiSendOptions:

FieldDescription
from, assetIdSingle sender + single faucet for the whole batch
recipientsMultiSendRecipient[] — each { to, amount, noteType?, attachment? }
noteTypeDefault for recipients that don't specify one (default "private")
skipSyncSkip pre-send auto-sync

useMint

Mints tokens from a faucet you control into a recipient account.

import { useMint } from "@miden-sdk/react";

const { mint, isLoading, stage } = useMint();

const result = await mint({
targetAccountId: recipient,
faucetId: myFaucet,
amount: 10_000n,
noteType: "private", // default "private"
});
console.log("Mint tx:", result.transactionId);

MintOptions:

FieldDescription
targetAccountIdRecipient AccountRef
faucetIdFaucet AccountRef (must be owned by the caller)
amountbigint | number
noteType"private" / "public" (default "private")

Returns TransactionResult: { transactionId: string }.

useConsume

Claims one or more notes into an account.

import { useConsume } from "@miden-sdk/react";

const { consume, isLoading } = useConsume();

await consume({
accountId: myAccountId,
notes: [noteIdHex1, noteIdHex2], // hex IDs, NoteId objects, InputNoteRecord, or Note
});

ConsumeOptions:

FieldDescription
accountIdAccount consuming the notes
notes(string | NoteId | InputNoteRecord | Note)[] — mix-and-match accepted

useSwap

Atomic swap between two assets.

import { useSwap } from "@miden-sdk/react";

const { swap, isLoading } = useSwap();

await swap({
accountId: myWallet,
offeredFaucetId: usdcFaucet,
offeredAmount: 100n,
requestedFaucetId: dagFaucet,
requestedAmount: 200n,
noteType: "public", // default "private"
paybackNoteType: "private", // default "private"
});

useImportAccount

Imports an account by ID (fetches from network), by previously-exported file, or by seed.

import { useImportAccount, AuthScheme } from "@miden-sdk/react";

const { importAccount, account, isImporting, error } = useImportAccount();

// By ID — public accounts only
const imported = await importAccount({
type: "id",
accountId: "mtst1qy35...",
});

// By seed — public accounts only
await importAccount({
type: "seed",
seed: initSeed, // Uint8Array
mutable: true, // default true
authScheme: AuthScheme.AuthRpoFalcon512,
});

// By file — works for both public and private accounts
await importAccount({
type: "file",
file: accountFileBytes, // AccountFile | Uint8Array | ArrayBuffer
});

The type discriminant is required. For private accounts, use the "file" variant — private account state isn't reconstructible from a seed alone.

useWaitForCommit / useWaitForNotes

Polling helpers for transaction confirmation and note inbox arrivals. Both are minimal hooks — they only expose the action function.

useWaitForCommit

Signature: waitForCommit(txId, options?)txId is positional (hex string or TransactionId), options are merged with defaults.

import { useWaitForCommit } from "@miden-sdk/react";

const { waitForCommit } = useWaitForCommit();
await waitForCommit(result.txId, {
timeoutMs: 30_000, // default 10_000
intervalMs: 1_000, // default 1_000
});

useWaitForNotes

Exposes waitForConsumableNotes(options) and returns the matching ConsumableNoteRecord[] when the threshold is reached.

import { useWaitForNotes } from "@miden-sdk/react";

const { waitForConsumableNotes } = useWaitForNotes();

const notes = await waitForConsumableNotes({
accountId: recipient,
minCount: 1, // default 1
timeoutMs: 30_000,
});

Both reject on timeout — wrap them in try/catch when you want a graceful fallback.

Next

  • Advanced — custom scripts, MASM compilation, session accounts, store import/export.
  • Signers — external wallets (Para, Turnkey, MidenFi) and custom signers.
  • Recipes — realistic patterns + link-outs to Philipp's full wallet tutorial.