Miden Multisig Client
High-level Rust SDK built on top of miden-client for private multisignature workflows on Miden. The crate wraps the on-chain multisig contracts plus Guardian coordination so you can:
- create multisig accounts, register them with a GUARDIAN, and keep state off-chain,
- propose, sign, and execute transactions with threshold enforcement,
- fall back to offline
SwitchGuardianworkflows when connectivity is limited, - export/import proposals as files for sharing using side channels,
How Private Multisigs & GUARDIAN Work
Miden multisig accounts store their authentication logic on-chain, but their state (signers, metadata, proposals) is kept private. GUARDIAN acts as a coordination server:
- A proposer pushes a delta (transaction plan) to Guardian. GUARDIAN tracks who signed and emits an ack signature once the threshold is met.
- Cosigners fetch pending deltas, verify details locally, sign the transaction summary, and push signatures back to GUARDIAN.
- Once ready, any cosigner builds the final transaction using all cosigner signatures + the GUARDIAN ack, executes it on-chain.
Installation
Add the crate to your workspace (already available in this repo). From another project:
[]
= { = "https://github.com/OpenZeppelin/guardian", = "miden-multisig-client" }
Quick Start
use Endpoint;
use ;
use ;
# async
Core Workflow Examples
Propose ➜ Sign ➜ Execute
use TransactionType;
use AccountId;
let recipient = from_hex?;
let faucet = from_hex?;
let tx = transfer;
// Proposer creates the delta on GUARDIAN
let proposal = client.propose_transaction.await?;
// Second cosigner lists available proposals and signs the matching one
let proposals = client.list_proposals.await?;
let to_sign = proposals
.iter
.find
.expect;
client.sign_proposal.await?;
// Once threshold is met, any cosigner can execute
client.execute_proposal.await?;
Fallback to Offline (if GUARDIAN unavailable)
If the GUARDIAN endpoint can’t be reached, the SDK can produce an offline proposal only for SwitchGuardian transactions:
use ;
let tx = switch_guardian;
match client.propose_with_fallback.await?
Fully Offline Signing and Execution
use TransactionType;
let tx = switch_guardian;
let mut exported = client.create_proposal_offline.await?;
// Cosigner signs locally
client.sign_imported_proposal.await?;
write?;
// Once enough signatures are collected offline:
client.execute_imported_proposal.await?;
Listing Notes
List all notes that are currently consumable by the loaded account:
let notes = client.list_consumable_notes.await?;
for note in notes
List notes from a specific faucet with a minimum amount filter:
use NoteFilter;
let faucet = from_hex?;
let filter = by_faucet_min_amount;
let spendable = client.list_consumable_notes_filtered.await?;
Demo CLI
Run the Terminal UI demo in examples/demo, which exercises the same APIs for account management, note listing, proposal signing, and offline export/import.
Contributions and bug reports are welcome!