Skip to content

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?

MethodPlain meaning
create_accountCreate a group; returns its id (anyone may call)
accountRead members and threshold
verify_quorumCheck individual signatures; returns true/false
verify_quorum_aggregateCheck one combined signature
change_accountReplace members/threshold; delay 0 applies now, else wait
set_timelockChange this group's delay (quorum of current members)
cancel_pendingImmediate cancel of a scheduled membership/delay change
execute_pendingApply a scheduled change after the wait
next_account_idPeek 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:

  1. propose - open an action (target, function, args, deadline)
  2. approve - one member signs the recomputed digest
  3. 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).

MethodPlain meaning
init_registryOwner: point this contract at a registry (bumps epoch)
set_proposal_ttl / set_tombstoneOwner ops
proposeOpen a proposal; returns its id
approveAdd one member's approval
finalizeAnyone may call once threshold is met; delay 0 runs now, else queues
executeAnyone may run a queued proposal after the wait
cancelCurrent members may cancel a queued proposal immediately
pruneAnyone may reclaim old payload storage
epoch / proposal_ttl / proposal / statusReads

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):

WhatDomain string
A proposalnocturne.knot.multisig.proposal.v3
Changing a group's membersnocturne.knot.multisig-registry.change_account.v3

Optional feature call-types holds shared argument/result types both contracts re-export.