Private DAO governance · Stellar

Vote in the shadows.
Execute in the light.

Every ballot is one of thousands of identical marks — none traceable to a voter. The tally stays sealed until close, then a bounded agent executes the result on-chain.

Live on Stellar testnet

The anonymity set — your vote is one of these.
No one can tell which.
  1. 01 / SEAL

    A sealed vote

    A zero-knowledge proof casts your weighted vote — identity, weight and direction never revealed.

  2. 02 / HOLD

    A timelocked tally

    Every ballot is encrypted to a future drand round. The count is unreadable until close — no whale can watch.

  3. 03 / REVEAL

    Open & execute

    At the deadline the seal breaks, the tally is revealed on-chain, and a bounded agent carries out the result.

Build with it · TypeScript SDK

Not a one-off demo —
a drop-in SDK for your app.

ShadowKit is four ESM packages plus deployed Soroban contracts. Generate a real sealed zero-knowledge ballot, timelock the tally, and let a policy-bounded agent execute the result — from your own code, in the browser or a Cloudflare Worker.

  • @shadowkit/zk-prover
  • @shadowkit/snapshot-tool
  • @shadowkit/tally-reveal
  • @shadowkit/shared
your-app.ts
import { generateVoteProof } from "@shadowkit/zk-prover";

// one call → a REAL Groth16 proof + a timelock-sealed ballot
const { proof, publicSignals, sealedCiphertext } =
  await generateVoteProof(voteInput, { wasmPath, zkeyPath }, deadline);

// cast on YOUR GovVault — identity, weight & direction stay private
await govVault.cast_vote({
  id, proof,
  pub_signals: publicSignals,
  sealed_ciphertext: sealedCiphertext,
});

See it live

Deployed & live

No mock. No replay.
Every demo runs on these contracts.