Contracts
What the on-chain pieces do. This page names methods; it does not list live contract IDs (those change on redeploy).
Live IDs: Deployments. How crate versions and redeploys relate: versioning.md on GitHub.
Registry (knot-registry)
The registry is a verifier, not a wallet. It stores groups and answers: did enough current members sign this message?
| Method | Plain meaning |
|---|---|
create_account | Create a group; returns its id (anyone may call) |
account | Read members and threshold |
verify_quorum | Check individual signatures; returns true/false |
verify_quorum_aggregate | Check one combined signature |
change_account | Replace members/threshold; delay 0 applies now, else wait |
set_timelock | Change this group's delay (quorum of current members) |
cancel_pending | Immediate cancel of a scheduled membership/delay change |
execute_pending | Apply a scheduled change after the wait |
next_account_id | Peek at the next id create will use |
For ordinary verify_quorum messages, you must stop replays (put a nonce or one-shot context in the message). change_account already folds the on-chain nonce into its own digest format.
Debug helpers such as diagnose_quorum are not on-chain - use the Lab. Shipping two WASM builds (with/without diagnostics) would mean testnet and mainnet were not the same bytecode. Source: knot-registry.
Proposals (knot-proposals)
This contract turns a signed intent into a real call:
- propose - open an action (target, function, args, deadline)
- approve - one member signs the recomputed digest
- finalize - once enough approvals exist, run the action
It asks the registry who the members are and what the threshold is. Digests come from knot-encoding (v3).
| Method | Plain meaning |
|---|---|
init_registry | Owner: point this contract at a registry (bumps epoch) |
set_proposal_ttl / set_tombstone | Owner ops |
propose | Open a proposal; returns its id |
approve | Add one member's approval |
finalize | Anyone may call once threshold is met; delay 0 runs now, else queues |
execute | Anyone may run a queued proposal after the wait |
cancel | Current members may cancel a queued proposal immediately |
prune | Anyone may reclaim old payload storage |
epoch / proposal_ttl / proposal / status | Reads |
Deploy order (v3): deploy registry, deploy proposals, then call init_registry. Signatures from the old v2 digest format do not work under v3.
Delay vs deadline: deadline is expiry ("by this block"). timelock_blocks on the registry account is a wait after quorum ("not before execute_at"). Cancel of a queued proposal or a pending membership change is immediate.
If your contract is the target of a finalize: check that the caller is the proposals contract (use abi::caller(), not public_sender). Do not open proposals that call owner-only admin methods on the proposals contract itself unless you mean to - finalize would look like the proposals contract calling itself.
Source: knot-proposals.
Shared encoding (knot-encoding)
Both contracts and the Lab share one crate so the signed bytes cannot drift. Domain labels (v3):
| What | Domain string |
|---|---|
| A proposal | nocturne.knot.multisig.proposal.v3 |
| Changing a group's members | nocturne.knot.multisig-registry.change_account.v3 |
Optional feature call-types holds shared argument/result types both contracts re-export.