Skip to content

v0.18.1

Choose a tag to compare

@zeljkoX zeljkoX released this 12 Oct 16:59
42a04e4

Patch release on the Miden 0.17 line, covering everything since v0.18.0. It publishes the server image (ghcr.io/openzeppelin/guardian:v0.18.1), the Rust crates and the npm packages (dist-tag latest). Accounts and stored data carry over from v0.18.0: no reset, no database migration.

⚠️ SDK upgrade notes

  • Upgrade every cosigner of an account together. Proposals now record the block their summary binds as bound_block_num instead of a chain_anchor (#541). 0.18.1 clients accept proposals made by 0.18.0 clients, but 0.18.0 clients refuse proposals made by 0.18.1 clients, so a cosigner left on 0.18.0 cannot sign or execute them.
  • Removed APIs (#541). TypeScript: executeForSummary (use executeForSummaryAtTip), executeForSummaryAt, SummaryAnchorMismatchError, chainAnchorToBase64, chainAnchorFromBase64, chainAnchorBlockNum. Rust: the chain_anchor fields of ProposalMetadataPayload and ExportedMetadata, ProposalMetadata::chain_anchor_b64 and ProposalMetadata::chain_anchor(), ProposalPayload::with_chain_anchor, and MultisigError::SummaryAnchorMismatch. New: bound_block_num / boundBlockNum on the metadata types.
  • TypeScript: create*Proposal labels proposals with the account's next nonce (store nonce plus one, as the Rust SDK does) instead of Date.now() (#486). options.nonce still overrides it. Rows written with timestamp labels are not migrated; see Upgrading from 0.18.0 to 0.18.1 for how they order in /delta/since and the history.
  • TypeScript: execution refuses a proposal GUARDIAN pinned to a state the client does not hold (#486), before anything is pushed or executed, for every proposal type.
  • Miden patch pins. miden-protocol / miden-standards 0.17.1, miden-client 0.17.3, @miden-sdk/miden-sdk 0.17.3. The auth_tx procedure root is unchanged, so accounts carry over. A custom NodeRpcClient implementation must add is_invitation_code_valid. Browser clients that share a store name now share one IndexedDB connection: release a MidenClient with await client[Symbol.asyncDispose]() before deleting or reopening its store.
  • Note transport cursors. miden-client 0.17.3 keeps one transport cursor per note tag and does not carry the 0.17.0 cursor over, so a store upgraded from 0.18.0 re-reads transport history it already holds on its first syncs (imports dedupe). The recovery flow's transport drain gets past it in one call: it now keeps fetching until a fetch moves no tag's cursor.
  • Install pins. npm install @openzeppelin/miden-multisig-client@0.18.1 @miden-sdk/miden-sdk@0.17.3. Rust: miden-multisig-client = "=0.18.1" with miden-client = "=0.17.3".

Highlights

  • Miden account sessions with a delegated signer (#537). A wallet signs one session grant; a client-held P-256 key then signs session-eligible requests, so hardware and remote wallets stop prompting on every read and proposal request. Approvals over transaction summaries stay with the wallet. Rust: start_session / end_session / revoke_all_sessions; TypeScript: startSession / resumeSession / endSession / revokeAllSessions. See Session authentication.
  • Chained candidate queue (#486). An account can hold up to GUARDIAN_MAX_PENDING_CANDIDATES_PER_ACCOUNT in-flight candidates, so a wallet can push back-to-back transactions without waiting for each to canonicalize. Off by default.
  • Proposal approvals are verified (#526). Falcon, raw ECDSA and EIP-712 approvals are checked against the transaction summary and the signer's identity on PUT and POST /delta/proposal; POST accepts at most the proposer's own approval. Rejections use 400 invalid_proposal_signature.
  • Proposals bound to an older block can be created (#541, fixes #538). A request a dApp built at block N no longer fails with SummaryAnchorMismatchError once the proposer has synced past N.

Guardian operations

Required: deploy the v0.18.1 image. There is no database migration and no new required setting; the defaults keep v0.18.0 behaviour. Deploy the server before rolling out SDK features that need it: sessions only work against a v0.18.1 server.

Check after the upgrade:

  • Proposal signature verification (#526). A client that posts another cosigner's approval at proposal creation, or an approval that does not verify, now gets 400 invalid_proposal_signature. The repository's SDKs already comply; watch for this code from custom or third-party clients after the rollout. EIP-712 failures on PUT /delta/proposal used to return invalid_delta, and a signer mismatch authentication_failed.
  • Sessions are always on (#537). Optional GUARDIAN_SESSION_MAX_TTL_SECONDS caps a session's lifetime (default 28800, 8 h; it can only be shortened, and a value outside 361 to 28800 stops startup). With Postgres, sessions live in the existing auth_sessions table and survive restarts; the in-memory store loses them on restart and clients start a new session. GET /status advertises sessions.max_ttl_seconds. New error codes: 401 session_expired, 401 session_revoked, 403 wallet_signature_required.
  • Candidate queue (#486), opt-in. Leave GUARDIAN_MAX_PENDING_CANDIDATES_PER_ACCOUNT unset (default 1) until every TypeScript client runs 0.18.1: older TypeScript clients label proposals with timestamps and execute proposals pinned to states they do not hold, which can leave GUARDIAN behind the chain on a queueing server. Values 2 to 16 opt in; above 16 stops startup. On AWS, set the Terraform variable guardian_max_pending_candidates_per_account. GET /dashboard/info reports the effective max_pending_candidates_per_account.
  • Monitoring. Retained candidates gain the reason orphaned (a queued successor whose predecessor left the queue): new metric outcome, log event candidate_retained reason=orphaned, and dashboard status_reason. Update any alert or dashboard that matches on retained reasons.
  • Networks. Devnet runs node 0.17.0 and accepts these pins (checked 2026-10-12). Testnet still runs Miden 0.16 and stays on v0.17.0.

What's Changed

Full Changelog: v0.18.0...v0.18.1