Problem Statement
StarForge already models multisig accounts (utils/multisig.rs) and supports hardware wallet signing (utils/hardware_wallet.rs), but there is no orchestrated workflow tying them together for the case that matters most for treasury and protocol-governance safety: an M-of-N transaction where each signer operates on a separate, potentially air-gapped machine, and no single machine ever holds enough signing authority to submit alone. Today, coordinating this requires signers to manually copy XDR blobs around and hope they combine them correctly.
Proposed Solution
Add a starforge multisig ceremony command family that manages the full lifecycle of a multi-party signing session as portable, self-describing files:
starforge multisig ceremony start --source <G...> --op <...> --threshold 3 --signers <G1,G2,G3,G4> --output tx.ceremony — builds an unsigned transaction envelope plus a ceremony manifest (required signers, threshold, expiry ledger bound) into a single portable file.
starforge multisig ceremony sign --input tx.ceremony --wallet alice [--hardware] --output tx.ceremony — a signer (potentially on an air-gapped machine, potentially using a connected Ledger device) adds their signature to the ceremony file and records who signed and when, without requiring network access.
starforge multisig ceremony status --input tx.ceremony — reports collected vs. required signatures, which signers are outstanding, and time remaining before the transaction's time bounds expire.
starforge multisig ceremony submit --input tx.ceremony --network mainnet — verifies the threshold is met, assembles the final signed envelope, and submits it, refusing to submit if signatures are insufficient, from unauthorized signers, or if the ceremony file has been tampered with (integrity-checked via a manifest hash).
- Ceremony files are plain, diffable, git-friendly text (base64/JSON) so they can be passed via USB drive, QR code export/import, or a shared repository/PR for auditability.
Technical Scope
- New
src/utils/ceremony.rs: ceremony file format (versioned), manifest integrity hashing, signature collection/merge logic building on the existing multisig.rs primitives.
- New
src/commands/multisig_ceremony.rs (or an extension of the existing multisig command module) wiring the four subcommands.
- Reuse the existing hardware wallet signing path for the
--hardware flag rather than reimplementing device communication.
- Tamper detection: any modification to the unsigned transaction body after ceremony start must be rejected at
sign or submit time.
- Tests: threshold math edge cases (exactly at threshold, below threshold, duplicate signer submission), tamper-detection rejection, expiry handling, and round-trip serialization of ceremony files.
Acceptance Criteria
- A 3-of-5 ceremony can be completed by simulating three independent
sign invocations against the same file (no shared process state) and verified via status before submit.
- Attempting
submit with only 2 of 3 required signatures is rejected with a clear error.
- A ceremony file that has been edited to alter the transaction body after the first signature is rejected at the next
sign or submit step.
- Documentation walks through a full multi-machine ceremony example, including the air-gapped/USB-transfer use case.
Estimated Scope
Approximately 700 lines of new Rust across the ceremony engine, CLI wiring, and tests.
Problem Statement
StarForge already models multisig accounts (
utils/multisig.rs) and supports hardware wallet signing (utils/hardware_wallet.rs), but there is no orchestrated workflow tying them together for the case that matters most for treasury and protocol-governance safety: an M-of-N transaction where each signer operates on a separate, potentially air-gapped machine, and no single machine ever holds enough signing authority to submit alone. Today, coordinating this requires signers to manually copy XDR blobs around and hope they combine them correctly.Proposed Solution
Add a
starforge multisig ceremonycommand family that manages the full lifecycle of a multi-party signing session as portable, self-describing files:starforge multisig ceremony start --source <G...> --op <...> --threshold 3 --signers <G1,G2,G3,G4> --output tx.ceremony— builds an unsigned transaction envelope plus a ceremony manifest (required signers, threshold, expiry ledger bound) into a single portable file.starforge multisig ceremony sign --input tx.ceremony --wallet alice [--hardware] --output tx.ceremony— a signer (potentially on an air-gapped machine, potentially using a connected Ledger device) adds their signature to the ceremony file and records who signed and when, without requiring network access.starforge multisig ceremony status --input tx.ceremony— reports collected vs. required signatures, which signers are outstanding, and time remaining before the transaction's time bounds expire.starforge multisig ceremony submit --input tx.ceremony --network mainnet— verifies the threshold is met, assembles the final signed envelope, and submits it, refusing to submit if signatures are insufficient, from unauthorized signers, or if the ceremony file has been tampered with (integrity-checked via a manifest hash).Technical Scope
src/utils/ceremony.rs: ceremony file format (versioned), manifest integrity hashing, signature collection/merge logic building on the existingmultisig.rsprimitives.src/commands/multisig_ceremony.rs(or an extension of the existing multisig command module) wiring the four subcommands.--hardwareflag rather than reimplementing device communication.signorsubmittime.Acceptance Criteria
signinvocations against the same file (no shared process state) and verified viastatusbeforesubmit.submitwith only 2 of 3 required signatures is rejected with a clear error.signorsubmitstep.Estimated Scope
Approximately 700 lines of new Rust across the ceremony engine, CLI wiring, and tests.