Project Template

Default Project Template

Running enclave init <project-name> clones the templates/default workspace into your directory and adds a tailor-made enclave.config.yaml. The goal is to give you a full-stack, reproducible playground for building and testing E3 programs without copying the entire monorepo.

Layout

my-first-e3/
├── contracts/          # Hardhat workspace with Enclave adapters + your E3 program contracts
├── program/            # RISC Zero guest code
├── server/             # TypeScript coordination server
├── client/             # React + Vite frontend wired to @enclave-e3/sdk
├── deploy/             # Deployment scripts
├── scripts/            # Helper scripts (start dev stack, ciphernodes, etc.)
├── tests/              # Integration + contract tests
├── enclave.config.yaml # Node + chain config consumed by the CLI
├── package.json        # Dev orchestrator scripts
└── .enclave/           # cached CLI state (ignored by git)

Each workspace shares the same pnpm root so dependencies stay in sync.

Commands

ScriptPurpose
pnpm dev:allSpins up Hardhat, deploys contracts, launches the RISC0 program server, coordination server, frontend, and ciphernodes.
pnpm dev:evmRuns hardhat node on http://localhost:8545.
pnpm dev:programStarts the RISC0 guest runner. Pass --dev to skip real proving.
pnpm dev:serverBoots the TypeScript coordination server with hot reload.
pnpm dev:frontendLaunches the Vite client on http://localhost:3000.
pnpm dev:ciphernodesCalls the Enclave CLI to launch the nodes defined in enclave.config.yaml.
pnpm compileCompiles Solidity contracts.
pnpm testRuns Hardhat tests.
pnpm test:integrationExecutes the end-to-end flow in tests/.

Before dev:all runs, the predev:all hook calls enclave program compile so the latest zkVM image is ready; skip this by exporting SKIP_PROGRAM_COMPILE=1.

Environment files

  • client/.env: contains VITE_ variables for contract addresses, RPC URLs, and optional feature flags.
  • server/.env: holds the operator wallet key (never commit), RPC endpoints, and cron API tokens.
  • enclave.config.yaml: describes your Ciphernodes and aggregator profile. The default file mirrors the template you saw earlier in this repo.

Integrating the SDK

The template already wires the Enclave SDK:

  • client/src/sdk.ts exports a singleton EnclaveSDK
  • client/src/hooks/useE3.ts wraps useEnclaveSDK
  • server/src/services/enclave.ts instantiates a wallet-backed SDK for automation

Update the .env files after every redeploy so the SDK listens to the correct contracts.

Noir circuits & Nargo

Although the template ships with a simple addition circuit, you can plug in Noir circuits by pointing to this repo's shared libraries (circuits/crates/libs/*). Add dependencies in your program/Cargo.toml or your Noir workspace's Nargo.toml:

[dependencies]
safe = { git = "https://github.com/gnosisguild/enclave", tag = "v0.1.5", directory = "circuits/crates/libs/safe" }

Use the helper scripts in the root repo (scripts/compile-circuits.sh, scripts/lint-circuits.sh) as a reference for formatting and compiling Noir workspaces via nargo and bb. Integrate similar scripts in my-first-e3/scripts/ if your application publishes verifiers alongside the template contracts.

Customizing Ciphernodes

enclave.config.yaml includes multiple node profiles (cn1, cn2, cn3, ag). Update the addresses, peers, and QUIC ports to match your deployment. For production, replace autonetkey/autopassword with explicit secrets and run enclave nodes up --detach from a systemd service or container entrypoint.

Common tweaks

  • Alternate compute providers: edit server/src/providers to switch between RISC Zero dev-mode vs real proving, or wire in a custom prover.
  • Program parameters: server/src/config/e3.ts defines the default thresholds and time windows used when calling sdk.requestE3. Adjust them to match your chain's latency.
  • Frontend UI: client/src/components/ResultCard.tsx renders decrypted outputs—extend it with your own domain logic.

The template is intentionally opinionated so you can delete what you do not need while still referencing a complete working stack.