privacy protocol logo
Skip to Content
API Reference

API Reference

IPrivateDaoAdapter

The core interface for integrating private governance into your DAO.

import {IPrivateDaoAdapter} from "@privacy-protocol/cipher-contracts/src/DaoToolkit/interface/IPrivateDaoAdapter.sol";

ProposalConfig

struct ProposalConfig { uint8 ballotSize; // Number of voting options uint256 votingStart; // Timestamp when voting begins uint256 votingEnd; // Timestamp when voting ends bytes32 membershipRoot; // Merkle root for voter eligibility bool ended; // True after tally decryption bool exists; // True if proposal is initialized bool allowLiveReveal; // Whether encrypted tallies can be queried mid-vote }

Functions

propose

Creates a new proposal with encrypted tally slots.

function propose( uint256 _proposalId, uint8 _ballotSize, uint64 _votingPeriod, bool _allowLiveReveal, bytes32 _membershipRoot ) external returns (ProposalConfig memory proposal);
ParameterDescription
_proposalIdUnique proposal identifier (must not already exist)
_ballotSizeNumber of voting options (e.g., 3 for Against/For/Abstain)
_votingPeriodDuration in seconds
_allowLiveRevealIf true, encrypted tallies can be queried before voting ends
_membershipRootPoseidon2 Merkle root of member identity secrets

submitEncryptedVote

Submits a ZK-proven, FHE-encrypted vote.

function submitEncryptedVote( uint256 _proposalId, bytes32 _nullifierHash, bytes calldata _zkProof, bytes calldata voteData ) external;
ParameterDescription
_proposalIdThe proposal to vote on
_nullifierHashposeidon2(proposalId, identitySecret) — replay protection
_zkProofSerialized Honk SNARK proof bytes
voteDataABI-encoded (bytes32 encryptedVote, bytes voteProof)

Reverts if:

  • Proposal doesn’t exist or voting period has ended
  • Nullifier was already used (double vote)
  • ZK proof verification fails

endVoting

Finalizes a proposal and decrypts the tallies.

function endVoting( uint256 _proposalId, bytes calldata abiEncodedResults, bytes calldata decryptionProof ) external;
ParameterDescription
_proposalIdThe proposal to finalize
abiEncodedResultsKMS-provided plaintext results
decryptionProofKMS decryption proof

Reverts if: voting period hasn’t ended yet.

getRevealedTallies

Returns the decrypted vote counts after voting ends.

function getRevealedTallies( uint256 _proposalId ) external view returns (uint64[] memory tallies);

Returns an array of length ballotSize where each index corresponds to a voting option.

getCurrentEncryptedTallies

Returns encrypted tally handles during voting (if allowLiveReveal is enabled).

function getCurrentEncryptedTallies( uint256 _proposalId ) external view returns (bytes32[] memory currentEncryptedTallies);

getProposalById

Returns the configuration of a proposal.

function getProposalById( uint256 _proposalId ) external view returns (ProposalConfig memory proposal);

Events

EventParametersDescription
PDA__ProposalCreatedproposalId, ballotSize, votingPeriodNew proposal created
PDA__VoteSubmittedproposalIdEncrypted vote submitted
PDA__VotingEndedproposalIdVoting finalized and tallies decrypted
PDA__AggregateResultsRevealedproposalId, encryptedTalliesLive encrypted tallies returned
PDA__FinalResultsRevealedproposalId, revealedTalliesDecrypted final results

Errors

ErrorCause
PDA__ProposalAlreadyExistsProposal ID already in use
PDA__InvalidBallotSizeBallot size is 0 or too large
PDA__InvalidVotingPeriodVoting period is 0
PDA__VotingPeriodEndedAttempting to vote after deadline
PDA__VotingPeriodNotEndedAttempting to end voting too early
PDA__NullifierAlreadyUsedDouble vote detected
PDA__InvalidMembershipRootMembership root mismatch
PDA__InvalidVoteDataMalformed encrypted vote data
PDA__ResultsNotRevealedQuerying tallies before decryption
PDA__UnauthorizedCaller lacks permission

Proof generation types

VoteSubmissionProofRequest

type VoteSubmissionProofRequest = { proposalId: bigint | number | string; ballotSize: number; // 1–255 vote: number; // 0 to ballotSize - 1 memberIdentitySecrets: Array<bigint | number | string>; voterIndex: number; // Index in memberIdentitySecrets circuitPath?: string; // Path to compiled circuit JSON };

VoteSubmissionProofPayload

type VoteSubmissionProofPayload = { proof: string; // Hex-encoded Honk proof publicInputs: string[]; // 32-byte padded field elements proposalId: string; ballotSize: number; vote: number; voterIndex: number; identitySecret: string; membershipRoot: string; // bytes32 nullifierHash: string; // bytes32 leafIndex: number; siblingPath: string[]; // bytes32[] circuitInput: object; // Raw circuit inputs (for debugging) };

Utility functions (proofUtils)

FunctionSignatureDescription
buildMembershipTree(secrets: BigNumberishLike[]) => Promise<MembershipTree>Builds a Poseidon2 Merkle tree (height 32) from identity secrets
computeNullifier(proposalId, identitySecret) => Promise<bigint>Computes poseidon2(proposalId, identitySecret)
computeMembershipLeaf(identitySecret) => Promise<bigint>Computes poseidon2(identitySecret) leaf hash
poseidonHash(values: BigNumberishLike[]) => Promise<bigint>General-purpose Poseidon2 hash
poseidonPair(left, right) => Promise<bigint>Hash two field elements
toBytes32(value) => stringPad a value to 32-byte hex string
parseBigInt(value) => bigintParse string/number/bigint to bigint
Last updated on