-
Notifications
You must be signed in to change notification settings - Fork 3
Description
RFC: Unified Private State Manager (PSM) Architecture for Multisig Accounts
Status: Proposal
Type: Architecture Overhaul
Summary
This proposal outlines the strategic integration of the Private State Manager (PSM) into the Miden Multisig infrastructure.
Current State: The existing MultiSig repository serves as a functional Proof of Concept (PoC) with a custom backend coordinator.
Goal: Elevate the Miden Multisig to a Production-Grade application by implementing a Unified State Architecture where the PSM becomes the single source of truth for both Public and Private accounts.
Current Architecture (PoC)
The current system relies on a monolithic Backend Coordinator to manage the lifecycle of multisig accounts. It acts as the central authority for state, public key storage, and transaction orchestration.
1. Component Overview & Diagram
graph TD
User((User))
subgraph Client [Browser Client]
UI[React UI]
LocalKeys[Local Key Storage]
end
subgraph Backend [Coordinator Service]
API[REST API]
DB[(PostgreSQL)]
Engine[Multisig Engine]
end
Node[Miden Node]
User -->|Interacts| UI
UI -->|1. Register Account| API
UI -->|2. Fetch Notes| API
UI -->|3. Propose Tx| API
UI -->|4. Sign Tx| LocalKeys
UI -->|5. Submit Sig| API
API -->|Read/Write| DB
API -->|Query Notes| Node
Engine -->|Poll Ready Tx| DB
Engine -->|6. Prove & Submit| Node
- Backend Coordinator: Exposes a REST API. It stores account metadata, signer public keys, and pending transactions in a PostgreSQL database.
- Multisig Engine: A background worker component that monitors completed proposals, generates recursive proofs for the transaction execution, and submits them to the Miden Node.
- Frontend: A Next.js application where users connect their wallets, view accounts, and sign transactions.
2. Detailed Workflows
A. Account Registration
- Siloed State: Each account is created as an independent actor.
- Process: A user defines the signers (public keys) and the signature threshold.
- Storage: The Coordinator stores this configuration in its database. It does not deploy the account on-chain immediately in all cases, but tracks the expected state (Account ID, Nonce, Code Hash).
sequenceDiagram
participant User
participant Frontend
participant Coordinator
participant DB
User->>Frontend: Enter Signer PubKeys & Threshold
Frontend->>Coordinator: POST /accounts (Register)
Coordinator->>DB: Store Account Metadata
Coordinator->>DB: Store Signer PubKey Commits
DB-->>Coordinator: Success
Coordinator-->>Frontend: Account ID
Frontend-->>User: Registration Complete
B. Transaction Lifecycle
The transaction flow is split into Proposal, Signing, and Execution.
-
Proposal:
- The user selects assets to send or notes to consume.
- Fetch Notes: The Frontend requests "consumable notes" from the Coordinator. The Coordinator queries the Miden Node to find notes owned by the account.
- Local Execution: The Frontend downloads the current account state and executes the transaction locally in the browser (using Miden WASM) to generate a Transaction Summary.
- Submission: The Frontend submits the Transaction Payload (script, inputs) and the Transaction Summary to the Coordinator.
-
Signing:
- Other signers log in and fetch
pendingtransactions from the API. - They validate the
Transaction Summarylocally. - They sign the summary using their private key (currently managed via browser wallet or local storage).
- Signatures are uploaded to the Coordinator.
- Other signers log in and fetch
-
Execution & Proving:
- The Coordinator checks if the gathered signatures meet the threshold.
- If valid, the Multisig Engine picks up the job.
- It re-executes the transaction to generate the final Zero-Knowledge Proof.
- It submits the proven transaction to the Miden Network.
sequenceDiagram
participant Creator
participant Signer
participant Frontend
participant Coordinator
participant Engine
participant Node
Note over Creator, Node: 1. Proposal Phase
Creator->>Frontend: Select Assets/Notes to Spend
Frontend->>Coordinator: GET /notes (Fetch Consumable)
Coordinator->>Node: Sync/Fetch Notes
Node-->>Coordinator: Notes Data
Coordinator-->>Frontend: Available Notes
Creator->>Frontend: Draft Transaction
Frontend->>Frontend: Execute Transaction (Generate Summary)
Frontend->>Coordinator: POST /transactions (Proposal + Payload + Summary)
Coordinator->>Coordinator: Validate Proposal
Coordinator-->>Frontend: Proposal Created
Note over Creator, Node: 2. Signing Phase
Signer->>Frontend: View Pending Transactions
Frontend->>Coordinator: GET /transactions/pending
Coordinator-->>Frontend: List of Proposals
Signer->>Frontend: Approve & Sign
Frontend->>Frontend: Sign(Transaction Summary)
Frontend->>Coordinator: POST /signatures
Coordinator->>Coordinator: Verify Signature
Coordinator-->>Frontend: Signature Accepted
Note over Creator, Node: 3. Execution Phase
Coordinator->>Engine: Check Threshold Met?
Engine->>Engine: Yes -> Initiate Execution
Engine->>Engine: Generate Proof (Recursive)
Engine->>Node: Submit Proven Transaction
Node-->>Engine: Transaction Included
Engine->>Coordinator: Update Account State
3. Limitations of Current Architecture
- Privacy: Since the Coordinator orchestrates everything, it knows every transaction, sender, and recipient. This violates the requirements for Private Multisig accounts.
- Scalability: The Coordinator handles note discovery, state storage, and proof generation via a single
Clientinstance. This monolithic design is hard to scale. - State Drift: If a user gathers signatures for a transaction outside of the Coordinator (e.g., via CLI), the Coordinator's database becomes out of sync, breaking the application.
Proposed Unified Architecture
We will replace the state management role of the Coordinator with the PSM. All accounts, regardless of privacy setting, will register with the PSM.
1. Justification & Production-Grade Benefits
Moving to a PSM-centric architecture addresses the critical limitations of the PoC and provides a robust foundation for production:
- Unified State Management: By treating the PSM as the single source of truth for all multisig accounts (both Public and Private), we eliminate the need for maintaining separate backends. The core logic remains consistent; only the data visibility changes.
- Enhanced Privacy (Private by Default Capable): The PSM is designed to store "opaque blobs" (deltas). This is impossible with the current Coordinator model.
- Client-Side Scalability: In the proposed architecture, state transitions and proofs are calculated on the client side (or by a specialized prover service decoupled from storage). The PSM merely validates signatures and sequences updates. This prevents the backend from becoming a computation bottleneck during high transaction volumes.
- Resilience & Offline-First: Clients maintain a local cache of the state (via IndexedDB). They can verify the entire history of an account independently by replaying the delta chain fetched from the PSM. If the PSM acts maliciously (e.g., withholding data), clients can detect the fork or inconsistency immediately, and decide to elect a new PSM.
2. System Components
graph TD
User((User))
subgraph Frontend [Miden Multisig Frontend]
UI[Dashboard UI]
subgraph SDK [Revamped Frontend SDK]
StateManager[State Manager]
WalletBridge[Wallet Adapter Bridge]
SyncService[Delta Sync Service]
end
LocalStorage[(IndexedDB / Local Storage)]
end
subgraph PSM [Private State Manager]
PSM_API[API Gateway]
DeltaStore[(Delta Store)]
NoteIndexer[Note Indexer Service]
end
BrowserExt[Miden Wallet Extension]
MidenNode[Miden Node]
%% User Interaction
User -->|Interacts| UI
UI -->|Calls| SDK
%% SDK Internals
StateManager -->|Persist State| LocalStorage
SyncService -->|Fetch Deltas| PSM_API
WalletBridge -->|Sign Requests| BrowserExt
%% PSM Internals
PSM_API -->|Store/Get| DeltaStore
NoteIndexer -->|Scrape Notes| MidenNode
PSM_API -->|Query Notes| NoteIndexer
%% Connections
SDK -.->|HTTP / gRPC| PSM_API
3. Detailed Workflows: Unified Account Registration
Registration is the entry point for all users. The revamped flow allows users to choose their privacy model upfront, but the underlying mechanism remains consistent: generating an initial state (Genesis Delta) and registering it with the PSM.
Detailed Registration Steps:
- Selection: The user selects "Create New Account" and chooses "Public" or "Private".
- Configuration: User inputs signer public keys (typically gathering them offline or via a sharing link) and sets the threshold (e.g., 2-of-3).
- Genesis State Creation: The Frontend SDK locally constructs the
Accountstruct (including code, storage, and vault). It then generates the Genesis Delta, which represents the transition from "nothing" to "initial state". - Submission: The SDK submits the
(AccountID, SignedGenesisDelta)to the PSM. - Indexing: The PSM validates the initial signature, stores the delta, and begins monitoring the blockchain for notes sent to this
AccountID.
sequenceDiagram
participant User
participant Frontend
participant SDK
participant PSM
User->>Frontend: "Create Account" (Select Private/Public)
Frontend->>User: Request Signer Keys & Threshold
User->>Frontend: Provide Config
Frontend->>SDK: initializeAccount(config)
SDK->>SDK: Generate Account Code & Storage
SDK->>SDK: Create Genesis Delta
alt Private Account
SDK->>SDK: Serialize Delta
end
SDK->>PSM: registerAccount(delta, initialSig)
PSM->>PSM: Validate Signature
PSM->>PSM: Store Genesis Delta
PSM-->>SDK: Registration Success
SDK->>Frontend: Account Ready
Frontend-->>User: Show Dashboard
4. Detailed Workflows: Transaction Lifecycle
This unified flow handles both account types. The key difference is that for Private accounts, the PSM cannot validate the transaction logic, only the update authority (signatures).
sequenceDiagram
participant User
participant UI as Frontend UI
participant SDK as Frontend SDK
participant Wallet as Wallet Extension
participant PSM as Private State Manager
Note over User, PSM: 1. Transaction Proposal Phase
User->>UI: Select "Send Assets"
UI->>SDK: prepareTransaction(recipient, amount)
SDK->>PSM: fetchAccountDeltas() (Sync)
PSM-->>SDK: Latest Deltas
SDK->>SDK: Calculate New State (Client-Side)
SDK->>SDK: Generate Delta Proposal
alt Private Account
SDK->>SDK: Delta (Shared Key)
else Public Account
SDK->>SDK: Delta
end
SDK->>PSM: submitProposal(deltaPayload)
PSM-->>UI: Proposal ID Confirmed
Note over User, PSM: 2. Signing Phase (Multi-User)
User->>UI: Click "Sign Proposal"
UI->>SDK: signProposal(proposalId)
SDK->>PSM: fetchProposal(proposalId)
PSM-->>SDK: Delta + Metadata
SDK->>Wallet: requestSignature(deltaHash)
Wallet-->>User: Prompt Approval
User->>Wallet: Approve
Wallet-->>SDK: Signature (Rpo256)
SDK->>PSM: submitSignature(proposalId, signature)
Note over User, PSM: 3. Execution Phase
PSM->>PSM: Check Threshold Met?
PSM->>PSM: Canonicalize Delta (Append to Chain)
Note over User, PSM: 4. Sync Phase
SDK->>PSM: Poll for new Head
PSM-->>SDK: New Canonical Delta
SDK->>UI: Update Balance
Implementation Path
Phase 1: PSM Backend Enhancements (Rust)
- Note Indexer: Implement a service in PSM that scans the Miden blockchain (or connects to a node) to find notes effectively owned by registered accounts.
- Metadata Support: Extend the proposals API to accept and serve JSON metadata linked to proposal IDs.
Phase 2: Revamped Frontend SDK (TypeScript)
- Package Creation: Initialize
miden-multisig-web-client. - Wallet Bridge: Implement
WalletSignerutilizingmiden-wallet-adapterand wallet extension proves and submits to network. - Unified Strategy:
PublicStrategyandPrivateStrategy
Phase 3: Unified "Create Account" Flow (UI)
- Onboarding Screen:
- Radio Button: "Public" vs "Private".
- Dashboard:
- Single dashboard view that adapts based on the loaded account type.
Phase 4: Production Hardening
- Delta Verification: Ensure the PSM enforces basic validity checks (signatures, sequence numbers) even for private accounts.
- Backup & Recovery: Mechanisms for users to back up their shared keys (for private accounts).
The above points were also discussed offline at Hacker Den Dubai 2026 with @MCarlomagno and @VAIBHAVJINDAL3012.