@cdr-kit/contracts/Conditions/MultiSigCondition

MultiSigCondition

N-of-M read gate with two parallel approval paths: off-chain EIP-712 sigs (gas-free; buyer collects + submits at read time) OR Safe-style on-chain approve() (signers pay gas; dashboards read chain truth). First-of-kind in the CDR ecosystem.
address = 0x3A0Cf72f167A2c1f5a7A5025eb36219f28C20FCd

Config shape

PropTypeDefaultDescription
signersrequiredaddress[]Allowed signers. MUST be sorted strictly ascending (agent helper auto-sorts).
thresholdrequireduint16Minimum sigs required (1 ≤ threshold ≤ signers.length).

EIP-712 Approval

  • Domain: cdr-kit:MultiSigCondition, version 1, chainId 1315, verifyingContract = condition address.
  • Type: Approval(uint32 uuid, address caller, uint64 epoch, uint64 deadline).
  • caller binding prevents sig replay against a different reader; epoch rotation invalidates in-flight sigs.

On-chain approve() — the Safe-style path

For dashboards that prefer chain-truth over off-chain sig collection, signers call approve(uuid) on-chain. Each approval costs ~50k gas. currentApprovalsCount(uuid) returns the count for the active epoch — read it directly in your UI via useMultiSigStatus.

Storage shape (epoch-scoped, so rotation auto-invalidates): hasApproved[uuid][epoch][signer] + approvalsCount[uuid][epoch]. Emits Approved(uuid, signer, epoch) for indexers.

rotateSigners()

Creator-only. Validates the new signer set + threshold, bumps epoch — invalidates BOTH off-chain sigs (signed against the old epoch) AND on-chain approvals (the count under the old epoch key no longer matters since reads check the new epoch). Use this to remove a compromised signer immediately.

Limitations

EIP-1271 (Safe / contract-wallet signers) not supported in 0.5 — ecrecover handles EOAs only. Workaround: have a Safe-owned EOA sign on behalf and register that EOA.