Problem
Current LP-0002 private multisig requires N+2 on-chain transactions (propose + N approve txs + execute). For coordinator-based workflows, this is inefficient — the coordinator should be able to collect ZK proofs off-chain and submit everything in a single transaction.
Repo: jimmy-claw/lez-multisig (jimmy/private-multisig-v2 branch)
Related: #87 (SPEL dry-run output format for coordinator interop)
Proposed Solution
Add a batch_execute instruction in lez-multisig that accepts all vote proofs inline:
#[instruction]
pub fn batch_execute(
multisig_state: AccountWithMetadata,
proposal_index: u64,
create_key: [u8; 32],
/// (vote_receipt, nullifier) pairs — collected off-chain from each member via `spel approve --dry-run`
approvals: Vec<(Vec<u32>, [u8; 32])>,
members: Vec<NullifierPublicKey>,
chained_call: ChainedCall,
) -> LezResult<()> {
// 1. Verify each (receipt, nullifier) pair against membership
// 2. Check nullifier uniqueness
// 3. Count approvals >= threshold
// 4. If met: fire ChainedCall
}
Coordinator Workflow
# Each member generates their proof blob (no on-chain submission)
spel approve --caller <private_key> --dry-run > member1_proof.txt
spel approve --caller <private_key> --dry-run > member2_proof.txt
# Coordinator collects files (out of band) and submits in one tx
spel batch_execute --approvals member1_proof.txt,member2_proof.txt ...
Design Notes
- Same vote circuit binary — each
(receipt, nullifier) verified independently
- NSKs never leave clients — coordinator only receives proof blobs
- Privacy guarantees identical to sequential
approve flow
approve kept for async/online voting
execute kept for stored-approvals case
Acceptance Criteria
Problem
Current LP-0002 private multisig requires N+2 on-chain transactions (propose + N approve txs + execute). For coordinator-based workflows, this is inefficient — the coordinator should be able to collect ZK proofs off-chain and submit everything in a single transaction.
Repo: jimmy-claw/lez-multisig (jimmy/private-multisig-v2 branch)
Related: #87 (SPEL dry-run output format for coordinator interop)
Proposed Solution
Add a
batch_executeinstruction in lez-multisig that accepts all vote proofs inline:Coordinator Workflow
Design Notes
(receipt, nullifier)verified independentlyapproveflowapprovekept for async/online votingexecutekept for stored-approvals caseAcceptance Criteria
batch_executeinstruction in lez-multisig#[lez_program]macro--dry-runoutput format is stable (docs: confirm #[pre_tx_hook] dry-run output format is stable for coordinator interop #87)