diff --git a/docs/pages/CRISP/introduction.mdx b/docs/pages/CRISP/introduction.mdx index 0f4bbc1b49..3523c12720 100644 --- a/docs/pages/CRISP/introduction.mdx +++ b/docs/pages/CRISP/introduction.mdx @@ -31,31 +31,37 @@ CRISP follows a modern Hardhat-based structure with clear separation of concerns ``` CRISP/ -|── client/ # React frontend application -|── server/ # Rust coordination server -|── program/ # RISC Zero computation program -├── contracts/ # Smart contracts (Solidity) -├── circuits/ # Noir circuits for ZK proofs -├── scripts/ # Development and utility scripts -├── enclave.config.yaml # Ciphernode configuration +├── client/ # React frontend application (Vite + @crisp-e3/sdk) +├── server/ # Rust coordination server & CLI +├── program/ # RISC Zero guest + prover control plane +├── packages/ +│ ├── crisp-contracts/ # Hardhat deployment + helpers +│ └── crisp-sdk/ # CRISP-specific TypeScript helpers to generate a ZK proof +├── crates/ # Rust libraries for the CLI + services +├── circuits/ # Noir circuits + verifiers (see [Noir Circuits](/noir-circuits)) +├── scripts/ # dev.sh, setup.sh, compile_circuits.sh, etc. +├── enclave.config.yaml # Ciphernodes + aggregator config +└── docker-compose.yaml # Optional multi-node deployment ``` --- ### **Client Application** (`/client`) -The client is a React application built with TypeScript that provides a voting interface: +The client is a React application built with TypeScript that provides a voting interface and reuses +the shared [CRISP SDK](/sdk): - Wallet connection with MetaMask and other wallets - Vote encryption using WebAssembly-based FHE encryption before submission -- Noir Zero-knowledge proof generation for vote validation +- Noir zero-knowledge proof generation for vote validation - Real-time updates on voting status and results --- ### **Coordination Server** (`/server`) -The server is a Rust-based coordination service that manages the E3 lifecycle: +The server is a Rust-based coordination service that manages the E3 lifecycle and drives the same +SDK from a privileged wallet: - Listens to blockchain events and coordinates protocol progression - Collects encrypted votes from the Smart Contract @@ -65,17 +71,16 @@ The server is a Rust-based coordination service that manages the E3 lifecycle: --- -### **ZK Program** (`/program`) +### **ZK Program + Noir Circuits** (`/program`, `/circuits`) -The core computation logic written in Rust for zkVM: - -- Performs computations on encrypted votes -- Counts votes without decrypting individual ballots -- Creates proofs of correct computation +- `program/`: Rust guest code compiled to the RISC Zero zkVM image that runs the CRISP tally logic +- `circuits/`: Noir circuits + SAFE/GRECO libraries used for membership proofs and encryption checks +- `scripts/compile_circuits.sh`: compiles Noir circuits, writes verification keys, and emits the + `CRISPVerifier.sol` contract used by `packages/crisp-contracts` --- -### **Smart Contracts** (`/contracts`) +### **Smart Contracts** (`/packages/crisp-contracts`) Solidity contracts implementing the E3 program interface: diff --git a/docs/pages/CRISP/running-e3.mdx b/docs/pages/CRISP/running-e3.mdx index 64e8001183..7b72f836a7 100644 --- a/docs/pages/CRISP/running-e3.mdx +++ b/docs/pages/CRISP/running-e3.mdx @@ -20,120 +20,124 @@ Please make sure you have followed the [CRISP Setup](/CRISP/setup) guide before -### Start Infrastructure +### Prep Once per Checkout -First, ensure you have the infrastructure running. If you haven't already, complete the setup: - -**Terminal 1: Start Anvil** - -```sh -anvil -``` - -**Terminal 2: Start Ciphernodes** +From the repo root run the bundled setup script (it installs dependencies, builds the CLI, prepares +env files, and compiles contracts): ```sh cd examples/CRISP -enclave nodes up -v +pnpm dev:setup ``` -Make sure contracts are deployed and ciphernodes are added to the registry as described in the setup -guide. - -### Start the Client Application +You only need to re-run this when dependencies change. -**Terminal 3: Client** +### Start Everything with One Command -Navigate to the client directory and start the React application: +The CRISP workspace ships with a supervisor that launches Hardhat, deploys contracts, boots +Ciphernodes, runs the RISC Zero program server, the Rust backend, and the React client. Start it in +the example root: ```sh -cd examples/CRISP/client -pnpm dev +pnpm dev:up ``` -The client application will start on `http://localhost:3000`. +Behind the scenes `scripts/dev.sh` calls `scripts/dev_services.sh`, which: -### Start the Server Application +- Spawns a Hardhat chain on `http://localhost:8545` +- Deploys contracts and registers five Ciphernodes against the local registry +- Runs `enclave program start --dev true` so proving happens instantly while developing +- Launches the Rust server with `cargo run --bin server` +- Starts the React client via `pnpm dev-static` -**Terminal 4: Server** +Keep this terminal open; logs from every service are multiplexed with `pnpm concurrently`. -Navigate to the server directory and start the backend server: - -```sh -cd examples/CRISP/server -cargo run --bin server -``` - -The server will start and begin listening for blockchain events. - -### Start the Program Server - -**Terminal 5: Program** - -Navigate to the program directory and start the program server: - -```sh -cd examples/CRISP/ -enclave program start -``` - -This runs the RISC Zero program server that handles secure computations. +### Initialize a New Voting Round -If you would like to run the program server in dev mode, you can run the following command: +Open a new terminal and launch the CLI from the example root: ```sh -cd examples/CRISP/ -enclave program start --dev true +pnpm cli ``` -In this case, Risc0 will not be used to generate proofs, and instead these will be mocked. +You can initialize a round using the interactive menu or directly via command-line flags: -### Initialize a New Voting Round +**Interactive Menu:** -**Terminal 6: CLI** +1. Select `Initialize new E3 round` +2. Enter the token contract address +3. Enter the balance threshold for the voting round -Navigate to the server directory and start the CLI: +**Command-Line (Direct):** -```sh -cd examples/CRISP/server -cargo run --bin cli +```bash +cargo run --bin cli init --token-address 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 --balance-threshold 1000 ``` -Follow these steps in the CLI: +**Command-line flags:** -1. Select `CRISP: Voting Protocol (ETH)` from the menu -2. Choose `Initialize new E3 round` to start a new voting round +- `--token-address`: ERC20 token address for voting eligibility +- `--balance-threshold`: Balance threshold for the voting round You should see output similar to: ```sh -[2024-10-22 11:56:11] [commands.rs:42] - Starting new CRISP round! -[2024-10-22 11:56:11] [commands.rs:46] - Enabling E3 Program... -[2024-10-22 11:56:11] [commands.rs:50] - E3 Program enabled. TxHash: 0xa391a4cd2dcc59f4bc6dd1f5ed1c78006dbba4556ea633f4b6a53e2271538682 -[2024-10-22 11:56:11] [commands.rs:74] - E3 request sent. TxHash: 0xe7998b9748e3526f6ca992c9bb498beabe4f387b02240a23d0f42a2386d3c305 +[2025-12-16 13:41:37] [commands.rs:77] - Starting new CRISP round with token address: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 and balance threshold: 1000000000000000000 +[2025-12-16 13:41:37] [commands.rs:90] - Enabling E3 Program with address: 0x67d269191c92Caf3cD7723F116c85e6E9bf55933 +[2025-12-16 13:41:37] [commands.rs:94] - E3 Program enabled. TxHash: 0xa391a4cd2dcc59f4bc6dd1f5ed1c78006dbba4556ea633f4b6a53e2271538682 +[2025-12-16 13:41:37] [commands.rs:118] - E3 request sent. TxHash: 0xe7998b9748e3526f6ca992c9bb498beabe4f387b02240a23d0f42a2386d3c305 ``` ### Set Up MetaMask -To interact with the client application, you need to configure MetaMask: +Whether you used `pnpm dev:up` or the manual flow below, you will interact with the Hardhat chain +running at `http://localhost:8545` (chain ID `31337`). Configure MetaMask once: -1. Open MetaMask in your browser -2. Add the Anvil private key to your wallet: +1. Import the Hardhat deployer key so you have funds available: ``` 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 ``` -3. Connect to the local Anvil network: - - Network Name: Anvil Local - - RPC URL: `http://localhost:8545` - - Chain ID: `31337` - - Currency Symbol: `ETH` +2. Add a custom network pointing to `http://localhost:8545` with symbol `ETH` and chain ID `31337`. +3. Connect your wallet to `http://localhost:3000` when the client asks. ### Submit Votes via Web Interface -1. Navigate to `http://localhost:3000` in your browser -2. Connect your MetaMask wallet -3. You should see the active voting round -4. Submit your vote by selecting your choice and confirming the transaction +1. Navigate to `http://localhost:3000` (started by `pnpm dev:up`) +2. Connect your MetaMask wallet when prompted +3. You should see the active voting round seeded by the CLI request +4. Cast a vote, approve the transaction, and wait for the confirmation toast + +### Manual Control (Optional) + +If you prefer to run each process in its own terminal (or need to customize flags), replicate what +`pnpm dev:up` does under the hood: + +1. **Hardhat chain + deploy contracts** + ```sh + pnpm -C packages/crisp-contracts hardhat node + # in another terminal + ./scripts/crisp_deploy.sh + ``` +2. **Ciphernodes & wallets** + ```sh + ./scripts/dev_cipher.sh ./.enclave/ready + ``` + This script wipes previous `.enclave` state, installs dev wallets, starts `enclave nodes up -v`, + and waits until all nodes are registered. +3. **Program server** + ```sh + ./scripts/dev_program.sh # add --dev true inside to skip proofs in dev + ``` +4. **Rust server** + ```sh + wait-on tcp:13151 && ./scripts/dev_server.sh + ``` +5. **React client** + ```sh + wait-on tcp:4000 && wait-on file:./.enclave/ready && ./scripts/dev_client.sh + ``` + +You can also let `./scripts/dev_services.sh` orchestrate steps 2–5 once Hardhat is up. ### Monitor the Process @@ -194,7 +198,8 @@ The CRISP voting process involves several key steps: - **Ensure all terminals remain open** during the voting process - **MetaMask connection issues**: Check that you're connected to the correct network (Chain ID: 31337) -- **Transaction failures**: Verify you have sufficient ETH balance from the Anvil faucet +- **Transaction failures**: Verify you have sufficient ETH balance from the Hardhat faucet (the + account with the imported deployer key starts funded) - **Server errors**: Monitor the server logs for detailed error messages - **Ciphernode issues**: Ensure all ciphernode processes are running and connected diff --git a/docs/pages/CRISP/setup.mdx b/docs/pages/CRISP/setup.mdx index 7d25f53d36..b41fe828e3 100644 --- a/docs/pages/CRISP/setup.mdx +++ b/docs/pages/CRISP/setup.mdx @@ -13,10 +13,12 @@ contracts, frontend applications, and secure computation components. The setup includes the following: -- **CRISP contracts**: Smart contracts located in the `contracts/` directory -- **Applications**: Frontend, server, and computation programs in the `apps/` directory -- **Ciphernodes**: Distributed nodes managed through the Enclave CLI -- **Development environment**: Hardhat + Foundry hybrid setup +- **CRISP contracts**: Smart contracts located in the `packages/crisp-contracts/` directory +- **Client**: React frontend application in the `client/` directory +- **Server**: Rust coordination server in the `server/` directory +- **Program**: RISC Zero computation program in the `program/` directory +- **Ciphernodes**: Distributed nodes managed through the Enclave CLI via `enclave.config.yaml` +- **Development environment**: Hardhat for contracts, Cargo for Rust components ## Prerequisites @@ -27,7 +29,9 @@ Before getting started, ensure you have installed: - [RiscZero](https://dev.risczero.com/api/zkvm/install) - [NodeJS](https://nodejs.org/en/download) - [pnpm](https://pnpm.io) -- [Metamask](https://metamask.io) +- [MetaMask](https://metamask.io) +- [Noir toolchain (`nargo`, `bb`)](https://noir-lang.org/docs/getting_started/installation) — + required when you recompile the circuits ### Install Node @@ -53,11 +57,12 @@ curl https://sh.rustup.rs -sSf | sh # Install Foundry curl -L https://foundry.paradigm.xyz | bash +foundryup ``` ### Install RISC Zero Toolchain -Next, install `rzup` for the `cargo-risczero` toolchain. +Install `rzup` for the `cargo-risczero` toolchain: ```sh # Install rzup @@ -67,81 +72,56 @@ curl -L https://risczero.com/install | bash rzup install cargo-risczero ``` -Verify the installation was successful by running: +Verify the installation: ```sh cargo risczero --version ``` -At this point, you should have all the tools required to develop and deploy an application with -[RISC Zero](https://www.risczero.com). - -## Environment - -You need to setup your environment variables for `client/` and `server/`. Just copy and paste the -`.env.default` as `.env` and overwrite with your values the following variables (you can leave the -others initialized with the default values). +## Quick Start -### Client +The simplest way to run CRISP is: ```bash -VITE_E3_PROGRAM_ADDRESS=0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44 # Default E3 program address from anvil -VITE_SEMAPHORE_ADDRESS=0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE -``` - -### Server +# Install dependencies and build everything +pnpm dev:setup -```bash -ENCLAVE_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" -CIPHERNODE_REGISTRY_ADDRESS="0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" -NAIVE_REGISTRY_FILTER_ADDRESS="0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" -E3_PROGRAM_ADDRESS="0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" # CRISPProgram Contract Address +# Start all services (Hardhat, contracts, ciphernodes, program server, coordination server, and UI) +pnpm dev:up ``` -These address will be displayed after successfully running the `pnpm dev:up` command in a log that -will look like the following: +`dev:up` runs `scripts/dev.sh`, which: -```bash -[DEPLOY] Script ran successfully. -[DEPLOY] -[DEPLOY] == Logs == -[DEPLOY] Deploying on ChainID 31337 -[DEPLOY] Using config profile: custom -[DEPLOY] Using MockRISC0Verifier -[DEPLOY] Deployed MockRISC0Verifier to 0x0B306BF915C4d645ff596e518fAf3F9669b97016 -[DEPLOY] Enclave Address: 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 -[DEPLOY] Verifier Address: 0x0B306BF915C4d645ff596e518fAf3F9669b97016 -[DEPLOY] Deployed SemaphoreNoirVerifier to 0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1 -[DEPLOY] Deployed Semaphore to 0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE -[DEPLOY] Deployed CRISPCheckerFactory to 0x68B1D87F95878fE05B998F19b66F4baba5De1aed -[DEPLOY] Deployed CRISPPolicyFactory to 0x3Aa5ebB10DC797CAC828524e59A333d0A371443c -[DEPLOY] Deployed HonkVerifier to 0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1 -[DEPLOY] Deployed CRISPProgram to 0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44 -[DEPLOY] Enabled E3 Program on Enclave -``` +1. Starts the Hardhat node in `packages/crisp-contracts` +2. Deploys all contracts (Enclave, CRISPProgram, verifiers, registries) via + `scripts/crisp_deploy.sh` +3. Starts ciphernodes using `enclave.config.yaml` via `scripts/dev_cipher.sh` +4. Launches the program server (RISC Zero) via `scripts/dev_program.sh` +5. Starts the coordination server (Rust) via `scripts/dev_server.sh` on port `4000` +6. Starts the React client via `scripts/dev_client.sh` on port `3000` -If you find any inconsistency with the addresses on the environment, you must update them and run -the script again (they must match). +All services run concurrently and will automatically restart if needed. -## Quick Start - -The fastest way to get CRISP running is using the scripts provided in the `scripts/` directory: +### Additional Commands ```bash -# Setup and build the development environment -pnpm dev:setup +# Recompile Noir circuits and generate verifiers +pnpm compile:circuit -# Start all services (Hardhat, Ciphernodes, Applications) -pnpm dev:up +# Open the interactive CLI to start voting rounds +pnpm cli + +# Run end-to-end tests +pnpm test:e2e ``` -This will start all CRISP components: +### Deployed Contract Addresses + +The contract addresses are automatically configured in `enclave.config.yaml` and the server `.env` +file. After running `pnpm dev:up`, the deployment logs will show the deployed contract addresses, +which are also saved in `packages/crisp-contracts/deployed_contracts.json`. -- Hardhat (local blockchain) -- Deploy all contracts -- Compile all ZK circuits -- Ciphernodes network -- CRISP applications (server, client) +### Using the Application Once everything is running, you can: @@ -155,226 +135,98 @@ Once everything is running, you can: 5. Open a new terminal, run `pnpm cli` and start a new E3 Round. 6. Refresh and interact with the round following the Client interface. -## Manual Start +## Configuration -If you prefer to set up CRISP manually or want to understand each component: +### Ciphernode Configuration -### Setting Up the project +The `enclave.config.yaml` file in the CRISP root directory configures the ciphernode network. By +default, it runs in development mode with fake proofs for fast local development: -1. Navigate to the root directory: - - ```sh - cd examples/CRISP - ``` - -2. Install dependencies: - - ```sh - pnpm install - ``` - -### Setting Up the Web App - -To set up the CRISP dApp in your local environment, follow these steps: - -1. Navigate to the `client` directory: - - ```sh - cd examples/CRISP/client - ``` - -2. Start the development server: - - ```sh - pnpm dev - ``` - -### Setting Up the CRISP Server - -Setting up the CRISP server involves several components, but this guide will walk you through each -step. - -### Step 1: Start a Local Testnet with Anvil - -```sh -anvil +```yaml +program: + dev: true # Uses fake proofs (fast for development) ``` -Keep Anvil running in the terminal, and open a new terminal for the next steps. - -### Step 2: Setting Up the Ciphernodes - -1. Clone the [Enclave Repo](https://github.com/gnosisguild/enclave): - - ```sh - git clone https://github.com/gnosisguild/enclave.git - ``` - -2. Navigate to the `enclave-contracts` directory: - - ```sh - cd enclave/packages/enclave-contracts - ``` - -3. Install dependencies: - - ```sh - pnpm install - ``` - -4. Delete any previous local deployment (if any): - - ```sh - rm -rf deployments/localhost/ - ``` - -5. Deploy the contracts on the local testnet: - - ```sh - pnpm deploy:mocks --network localhost - ``` - -After deployment, you will see the addresses for the following contracts: - -- Enclave -- Ciphernode Registry -- Naive Registry Filter -- Mock Input Validator -- Mock E3 Program -- Mock Decryption Verifier -- Mock Compute Provider - -Note down the first four addresses as they will be needed to configure `risc0`, `local_testnet` and -the `server`. - -### Step 3: Deploy the RISC Zero Contracts - -> Please note that this step is optional for development only. You can run the program server in dev -> mode which does not use Risc0. - -1. Navigate to the `CRISP/lib/risc0-ethereum` directory. - ---- - -**Faster Proving w/ Bonsai** - -The following steps are optional. You can config -[Bonsai](https://dev.risczero.com/api/generating-proofs/remote-proving) for faster proving. - -- Set up environment variables by creating a `.cargo` directory and `config.toml` file: - - ```sh - mkdir .cargo && cd .cargo && touch config.toml - ``` - -- Add the following configuration to `config.toml`: +### Boundless Configuration (Production Proving) + +For production-grade zero-knowledge proofs with [Boundless](https://docs.beboundless.xyz/), update +`enclave.config.yaml`: + +```yaml +program: + dev: false # Disable dev mode to use real proofs + risc0: + risc0_dev_mode: 0 # 0 = production (Boundless), 1 = dev mode + boundless: + rpc_url: 'https://sepolia.infura.io/v3/YOUR_KEY' # RPC endpoint + private_key: 'YOUR_PRIVATE_KEY' # Wallet with funds for proving + pinata_jwt: 'YOUR_PINATA_JWT' # Required for uploading programs to IPFS + program_url: 'https://gateway.pinata.cloud/ipfs/YOUR_CID' # Pre-uploaded program URL + onchain: true # true = onchain requests, false = offchain +``` - > **_Note:_** _This requires having access to a Bonsai API Key. To request an API key - > [complete the form here](https://bonsai.xyz/apply)._ +> **_Note:_** For production proving with Boundless, you need: +> +> - An RPC endpoint (e.g., Infura, Alchemy) with funds +> - A private key with sufficient ETH/tokens for proof generation +> - A Pinata JWT for uploading programs to IPFS (get one at [pinata.cloud](https://pinata.cloud)) +> - Pre-uploaded program URL to avoid uploading the ~40MB program at runtime - ```toml - [env] - BONSAI_API_KEY="your_api_key" - BONSAI_API_URL="your_api_url" - ``` +#### Uploading Your Program to IPFS ---- +When you make changes to the guest program in `program/`, you need to upload it to IPFS to get a +program URL: -2. In the `risc0/script` directory, update the `config.toml` with the deployed contract addresses. - The following configuration is based on default deployment addresses using local Anvil node: - - ```toml - [profile.custom] - chainId = 31337 - riscZeroVerifierAddress = "0x0000000000000000000000000000000000000000" - enclaveAddress = "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" - ``` +1. First, configure your Pinata JWT in `enclave.config.yaml` (as shown above) -3. Export the ETH_WALLET_PRIVATE_KEY environment variable (Anvil's default private key): +2. Build and upload your program: - ```sh - export ETH_WALLET_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + ```bash + # This compiles the guest program and uploads it to IPFS via Pinata + enclave program upload ``` -4. Deploy the contracts: +3. The command will output an IPFS hash like `QmXxx...`. Update your `enclave.config.yaml` with the + full URL: - ```sh - forge script --rpc-url http://localhost:8545 --broadcast script/Deploy.s.sol + ```yaml + program_url: 'https://gateway.pinata.cloud/ipfs/QmXxx...' ``` -Note down the `CRISPProgram` contract Address, which will be used as the E3 Program Address. +> **_Important:_** Every time you modify the guest program code in `program/`, you must rebuild and +> re-upload it to IPFS, then update the `program_url` in your configuration. This ensures Boundless +> uses your latest program version. -### Step 4: Set up Environment Variables +### Environment Variables -Create a `.env` file in the `server` directory with the following: +The `pnpm dev:setup` command automatically creates `.env` files for the server and client from the +`.env.example` templates. The server's `.env` file is automatically populated with contract +addresses after deployment. -```sh -# Private key for the enclave server -PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -ENCLAVE_SERVER_URL=http://0.0.0.0:4000 -HTTP_RPC_URL=http://127.0.0.1:8545 -PROGRAM_SERVER_URL=http://127.0.0.1:13151 -WS_RPC_URL=ws://127.0.0.1:8545 -CHAIN_ID=31337 - -# Cron-job API key to trigger new rounds -CRON_API_KEY=1234567890 - -# Based on Default Anvil Deployments (Only for testing) -ENCLAVE_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512" -CIPHERNODE_REGISTRY_ADDRESS="0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" -NAIVE_REGISTRY_FILTER_ADDRESS="0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9" -E3_PROGRAM_ADDRESS="0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44" # CRISPProgram Contract Address - -# E3 Config -E3_WINDOW_SIZE=40 -E3_THRESHOLD_MIN=1 -E3_THRESHOLD_MAX=2 -E3_DURATION=160 - -# E3 Compute Provider Config -E3_COMPUTE_PROVIDER_NAME="RISC0" -E3_COMPUTE_PROVIDER_PARALLEL=false -E3_COMPUTE_PROVIDER_BATCH_SIZE=4 # Must be a power of 2 -``` +## Running Individual Components -## Running Ciphernodes +While `pnpm dev:up` runs everything together, you can also run components separately: -To run three ciphernodes, use the following command inside the CRISP directory: +```bash +# Start only the Hardhat node +cd packages/crisp-contracts && pnpm hardhat node -```sh +# Start only the ciphernodes (requires Hardhat running) ./scripts/dev_cipher.sh -``` -This script will start the ciphernodes, add the ciphernodes to the registry on chain. +# Start only the program server (requires ciphernodes) +./scripts/dev_program.sh -## Running the CRISP Server +# Start only the coordination server (requires program server) +./scripts/dev_server.sh -To run the CRISP Server, open a new terminal and navigate to the `server` directory. Then, execute -the following command: +# Start only the client (requires coordination server) +./scripts/dev_client.sh -```sh -cargo run --bin server -``` - -## Interacting with CRISP via CLI - -Open a new terminal and navigate to the `server` directory. Then, execute the following command: - -```sh -cargo run --bin cli +# Run the CLI (requires all services) +pnpm cli ``` -Once the CLI client is running, you can interact with the CRISP voting protocol by following these -steps: - -1. Select `CRISP: Voting Protocol (ETH)` from the menu. - -2. To initiate a new CRISP round, choose the option `Initialize new CRISP round`. - -Ensure all services are running correctly and that components are communicating as expected before -starting a new CRISP round. - ## Next Steps Once you have completed the setup, you can proceed to [Running an E3 Program](/CRISP/running-e3) to diff --git a/docs/pages/_meta.json b/docs/pages/_meta.json index e694f486b8..b47d1ca34e 100644 --- a/docs/pages/_meta.json +++ b/docs/pages/_meta.json @@ -3,9 +3,9 @@ "display": "hidden", "title": "Home" }, - "-- Documentation": { + "-- Overview": { "type": "separator", - "title": "Documentation" + "title": "Overview" }, "introduction": { "title": "Introduction" @@ -19,12 +19,18 @@ "computation-flow": { "title": "E3 Computation Flow" }, + "use-cases": { + "title": "Use Cases" + }, "building-with-enclave": { "title": "Building with Enclave" }, - "-- TUTORIAL": { + "best-practices": { + "title": "Best Practices" + }, + "-- Getting Started": { "type": "separator", - "title": "Tutorial" + "title": "Getting Started" }, "installation": { "title": "Installation" @@ -35,41 +41,61 @@ "hello-world-tutorial": { "title": "Hello World" }, - "-- BUILD AN E3": { + "-- Tooling": { + "type": "separator", + "title": "Tooling" + }, + "project-template": { + "title": "Project Template" + }, + "sdk": { + "title": "Enclave SDK" + }, + "setting-up-server": { + "title": "Setting Up the Server" + }, + "noir-circuits": { + "title": "Noir Circuits" + }, + "-- Build an E3": { "type": "separator", - "title": "BUILD AN E3 Program" + "title": "Build an E3 Program" }, "getting-started": { "title": "Getting Started" }, - "compute-provider": { - "title": "Compute Provider Setup" - }, "write-secure-program": { "title": "Writing the Secure Process" }, "write-e3-contract": { "title": "Writing the E3 Program Contract" }, - "setting-up-server": { - "title": "Setting Up the Server" + "compute-provider": { + "title": "Compute Provider Setup" }, "putting-it-together": { "title": "Putting It All Together" }, + "-- Operations": { + "type": "separator", + "title": "Operations" + }, + "ciphernode-operators": { + "title": "Ciphernode Operators" + }, "build-e3": { "display": "hidden" }, - "-- USE CASES": { + "-- Examples": { "type": "separator", - "title": "USE CASES" + "title": "Examples" }, "CRISP": { "title": "CRISP" }, - "-- WHITE PAPER": { + "-- Reference": { "type": "separator", - "title": "WHITE PAPER" + "title": "Reference" }, "whitepaper": { "title": "White Paper" diff --git a/docs/pages/best-practices.mdx b/docs/pages/best-practices.mdx new file mode 100644 index 0000000000..0589457ae0 --- /dev/null +++ b/docs/pages/best-practices.mdx @@ -0,0 +1,65 @@ +--- +title: 'Best Practices' +--- + +# Design & Operations Best Practices + +Competitor docs such as Fhenix's "Key Considerations" and Ritual's architecture primers emphasize +clear guardrails for confidential compute. This guide distills the equivalent playbook for Enclave. + +## Parameter Strategy + +- **Thresholds**: Choose `threshold = [t, n]` so that `t` withstands your adversary model while `n` + matches available Ciphernodes. Higher thresholds improve collusion resistance but increase fees. +- **Timing Windows**: Ensure `startWindow` leaves enough time for committee selection (a few blocks) + and `duration` matches the longest credible compute time plus buffer. +- **Custom Params**: Use `customParams` in `E3RequestParams` to tag jurisdiction, use case, or + feature toggles without redeploying contracts. + +## Input Validation + +- **Push logic to validators**: Implement `IE3Program.validateInput` so ZK proofs and policy checks + happen before the Secure Process. This mirrors how CoFHE tutorials offload range proofs from the + heavy computation path. +- **Replay protection**: Include round identifiers or nullifiers inside inputs before you hash them + into the Lean IMT. +- **Access control**: Gate inputs via registries (e.g., DAO membership) or staking requirements to + keep spam out of the queue. + +## Secure Process & Compute Providers + +- **Determinism**: Reconstruct the on-chain Merkle root inside the Secure Process, then assert + equality prior to any heavy math. +- **Proof hooks**: When using RISC Zero or other verifiable CPs, keep witness blobs small and + reserve `computeProviderParams` for runtime toggles (precision, chunk size, etc.). +- **Failover**: Decide how your app reacts if `CiphertextOutputPublished` never arrives—e.g., allow + a guardian to cancel the round and refund deposits. + +## Key Material & Ciphernodes + +- **Key hygiene**: `dev:setup` wipes `.enclave` directories for you; mimic that behavior in + production by rotating committee keys when nodes churn. +- **Monitoring**: Subscribe to `E3Activated` and `PlaintextOutputPublished` events to ensure the + CiCo publishes keys and decryptions on schedule. +- **Operator docs**: Keep the [Ciphernode Operators](/ciphernode-operators) runbooks close to your + app documentation so node providers can mirror your expectations. + +## Observability & Tooling + +- **Structured logs**: Adopt the logging schema from the CRISP server (JSON with `e3_id` and phase) + so you can stitch together end-to-end traces. +- **Synthetic tests**: Reuse `pnpm dev:up` + Playwright to run rehearsal rounds on CI before + shipping new circuits or SDK releases. +- **Dashboarding**: Track request fees, committee saturation, and mean time from `request` to + `PlaintextOutputPublished` just like Ritual exposes node specialization metrics. + +## Deployment Checklist + +1. Run `pnpm dev:build` to preflight the entire stack. +2. Execute integration tests that cover `request → publishInput → publishCiphertextOutput` with mock + proofs. +3. Verify wallet funding for any automation (enclave CLI, Hardhat deployers). +4. Update onboarding docs (MetaMask, scripts) when RPC URLs or ports change. +5. Publish a postmortem template so incidents have consistent follow-up. + +Pair these practices with the [Use Cases](/use-cases) catalog to craft predictable launch plans. diff --git a/docs/pages/building-with-enclave.mdx b/docs/pages/building-with-enclave.mdx index ac40182aad..3ed67e64bc 100644 --- a/docs/pages/building-with-enclave.mdx +++ b/docs/pages/building-with-enclave.mdx @@ -41,24 +41,21 @@ contract Enclave { ### Request Flow -1. Users submits onchain request - -```solidity -function request( - address filter, - uint32[2] calldata threshold, - uint256[2] calldata startWindow, - uint256 duration, - IE3Program e3Program, - bytes memory e3ProgramParams, - bytes memory computeProviderParams -) external -``` - -2. Contract validates request parameters -3. E3 Program contract is set and used to get the Encryption scheme. -4. Request is submitted to the ciphernodeRegistry for committee selection. -5. `E3Requested` event is emitted +1. Users submit `E3RequestParams` containing thresholds, timing windows, program references, and + optional custom params. + + ```solidity + function request( + E3RequestParams calldata requestParams + ) external returns (uint256 e3Id, E3 memory e3); + ``` + +2. Contract validates the struct, estimates the fee, and stores an `E3` record seeded with a random + value derived from block entropy. +3. The E3 program's `validate` hook returns the encryption scheme ID and input validator contract, + which are persisted on the `E3` struct. +4. Committee selection is delegated to the `ciphernodeRegistry` via `requestCommittee`. +5. `E3Requested(e3Id, e3, e3Program)` is emitted with the full configuration payload for watchers. ## Committee and Ciphernode Management @@ -68,6 +65,8 @@ function request( from the global pool of available Ciphernodes. - Selected nodes coordinate to produce a shared public key with the requested threshold. - The public key is published to the Ciphernode Registry smart contract. +- For bonding, ticket economics, CLI commands, and operational responsibilities, see the + [Ciphernode Operators guide](/ciphernode-operators). ## E3 Activation @@ -94,7 +93,8 @@ function publishInput( ) external ``` -Inputs are accumulated incrementally into a Merkle tree. This allows you to: +Inputs can be accumulated incrementally into a Merkle tree (LazyIMT, or ultimately chosen by the +program implementation). This allows you to: 1. Use the published Merkle root as part of your E3 Program's Secure Process to ensure all published inputs are processed by the Compute Provider. @@ -136,14 +136,20 @@ to the E3's public key. It is also recommended to bundle in proofs to validate: ### Key Events +**Enclave Contract Events:** + ```solidity event E3Requested(uint256 indexed e3Id, address indexed requester, address e3ProgramAddress); -event InputSubmitted(uint256 indexed e3Id, address indexed sender, bytes32 inputHash); +event CiphertextOutputPublished(uint256 indexed e3Id, bytes ciphertextOutput); -event CiphertextOutputPublished(uint256 indexed e3Id, bytes32 ciphertextHash); +event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintextOutput); +``` -event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintext); +**Program Contract Events:** + +```solidity +event InputPublished(uint256 indexed e3Id, bytes data, uint256 inputHash, uint256 index); ``` ### Result Publication Flow @@ -161,19 +167,21 @@ event PlaintextOutputPublished(uint256 indexed e3Id, bytes plaintext); ```javascript const enclaveContract = new ethers.Contract(enclaveAddress, enclaveAbi, signer) -const tx = await enclaveContract.request( - filterAddress, - [thresholdMin, thresholdMax], - [startWindowStart, startWindowEnd], - duration, - e3ProgramAddress, +const requestParams = { + threshold: [3, 5], + startWindow: [startWindowStart, startWindowEnd], + duration: 3600, + e3Program: e3ProgramAddress, e3ProgramParams, computeProviderParams, - { value: computationFee }, -) + customParams: '0x', +} +const tx = await enclaveContract.request(requestParams) const receipt = await tx.wait() -const e3Id = receipt.events.find((e) => e.event === 'E3Requested').args.e3Id +const e3Id = receipt.logs + .map((log) => enclaveContract.interface.parseLog(log)) + .find((parsed) => parsed?.name === 'E3Requested')?.args?.e3Id ``` ### Monitoring Results @@ -219,21 +227,5 @@ the finality of the outcome and to appropriately handle re-orgs. ## Best Practices -1. **Request Management** - - Set appropriate thresholds - - Choose realistic time windows - -2. **Input Handling** - - Encrypt inputs properly - - Include necessary ZKPs - - Submit within time windows - -3. **Result Processing** - - Listen for all relevant events - - Implement timeout handling - - Verify result integrity - -4. **Error Handling** - - Handle contract reverts - - Implement retry logic - - Log errors appropriately +See the dedicated [Best Practices](/best-practices) guide for updated operational playbooks covering +parameter selection, validator design, compute provider trust, and observability. diff --git a/docs/pages/ciphernode-operators/_meta.json b/docs/pages/ciphernode-operators/_meta.json new file mode 100644 index 0000000000..45ca46dda4 --- /dev/null +++ b/docs/pages/ciphernode-operators/_meta.json @@ -0,0 +1,17 @@ +{ + "index": { + "title": "Overview" + }, + "running": { + "title": "Running a Ciphernode" + }, + "registration": { + "title": "Registration & Licensing" + }, + "tickets-and-sortition": { + "title": "Tickets & Sortition" + }, + "exits-and-slashing": { + "title": "Exits, Rewards & Slashing" + } +} diff --git a/docs/pages/ciphernode-operators/exits-and-slashing.mdx b/docs/pages/ciphernode-operators/exits-and-slashing.mdx new file mode 100644 index 0000000000..abedefcc4b --- /dev/null +++ b/docs/pages/ciphernode-operators/exits-and-slashing.mdx @@ -0,0 +1,212 @@ +--- +title: 'Exits, Rewards & Slashing' +description: 'Collect rewards, respond to slashing, and exit safely' +--- + +# Exits, Rewards & Slashing + +This guide covers the end-of-lifecycle operations: collecting rewards, handling slashing proposals, +and safely exiting the registry. + +## Rewards + +Rewards are distributed through `BondingRegistry.distributeRewards` after successful E3 completions. + +### How Rewards Work + +1. E3 completes successfully with plaintext output published +2. Reward distributor calls `distributeRewards` with the reward token +3. Committee members receive payouts based on participation +4. `RewardsDistributed` event is emitted + +### Monitoring Rewards + +Watch for reward events and ensure your wallet can receive the reward token: + +```bash +# Check your status including any pending rewards +enclave ciphernode status +``` + +> Keep your operator wallet funded with ETH for gas - claiming rewards through automation scripts +> still requires transaction fees. + +## Slashing + +Slashing penalizes operators who miss duties or behave maliciously. The `SlashingManager` contract +handles proposals, appeals, and execution. + +### Slashing Lifecycle + +```mermaid +flowchart LR + A[Violation Detected] --> B[SlashProposed] + B --> C{Appealable?} + C -->|Yes| D[Appeal Window] + D -->|Appeal Filed| E[Review] + D -->|No Appeal| F[Slash Executed] + C -->|No| F + E -->|Rejected| F + E -->|Accepted| G[Slash Cancelled] + F --> H[Penalties Applied] +``` + +### Slash Policy Structure + +Each slash reason has an associated policy: + +```solidity +struct SlashPolicy { + uint256 ticketPenalty; // Tickets to burn + uint256 licensePenalty; // ENCL to confiscate + bool requiresProof; // Whether evidence is needed + uint64 appealWindow; // Time to file appeal + bool appealable; // Whether appeals are allowed +} +``` + +### Responding to Slashing + +1. **Monitor for proposals**: Watch `SlashProposed` events targeting your address +2. **Review the policy**: Check if appeals are allowed and the window duration +3. **File appeal if applicable**: + ```bash + # Using cast (or implement in automation) + cast send $SLASHING "fileAppeal(uint256,string,string)" $E3_ID "reason" "evidence_uri" \ + --rpc-url $RPC --private-key $OPERATOR_KEY + ``` +4. **Track resolution**: Watch for finalization events + +### Slashing Penalties + +| Penalty Type | Effect | +| --------------- | ------------------------------------------------ | +| Ticket penalty | Burns ETK from your balance | +| License penalty | Confiscates ENCL from your bond | +| Ban | Prevents re-registration until governance clears | + +> Some policies skip the appeal process entirely. Always check the policy before assuming you can +> appeal. + +## Exit Process + +To safely exit the ciphernode registry: + +### Step 1: Deregister + +Request deregistration with your IMT proof siblings: + +```bash +enclave ciphernode deregister --proof 0x123...,0x456...,0x789... +``` + +> Save your sibling proof from the `CiphernodeAdded` event when you first register. You'll need it +> to deregister. + +### Step 2: Wait for Exit Delay + +Assets enter a queue with a delay period (7 days on Sepolia): + +| Asset | Behavior | +| ------- | ------------------------------------- | +| Tickets | Burned immediately, USDC enters queue | +| License | ENCL enters exit queue | + +Check your exit status: + +```bash +enclave ciphernode status +``` + +Look for "Exit pending" and "Pending exits" fields. + +### Step 3: Claim Exits + +After the delay period: + +```bash +# Claim all pending exits +enclave ciphernode license claim + +# Or specify maximum amounts +enclave ciphernode license claim --max-ticket 100 --max-license 50 +``` + +### Cancel Exit + +To cancel an exit and return to active status: + +```bash +enclave ciphernode register +``` + +This clears the exit queue and re-registers you in the registry. + +## CLI Commands Summary + +| Command | Description | +| ----------------------------------------- | ---------------------------------- | +| `enclave ciphernode status` | Check registration and exit status | +| `enclave ciphernode deregister --proof X` | Start exit process | +| `enclave ciphernode license claim` | Claim unlocked exits | +| `enclave ciphernode register` | Cancel exit and re-register | +| `enclave ciphernode deactivate` | Withdraw stakes to become inactive | + +## Monitoring Checklist + +| Check | Command / Event | +| --------------------- | ------------------------------------------- | +| Exit queue status | `enclave ciphernode status` | +| Pending exits amounts | `pendingExits(address)` on BondingRegistry | +| Exit unlock time | `exitUnlocksAt(address)` on BondingRegistry | +| Slash proposals | Watch `SlashProposed` events | +| Rewards distribution | Watch `RewardsDistributed` events | + +## Troubleshooting + +| Issue | Cause | Solution | +| --------------------------- | ------------------------------------ | ------------------------------------ | +| `ExitNotReady` on claim | Exit delay hasn't passed | Wait until `exitUnlocksAt` timestamp | +| Appeal rejected immediately | Policy doesn't allow appeals | Check `SlashPolicy.appealable` | +| `isActive` suddenly false | Slashing reduced stake below minimum | Add more tickets or license bond | +| Missed reward payouts | Deregistered or banned during E3 | Re-register before next request | + +## Post-Exit Cleanup + +After successfully claiming exits: + +1. **Wipe local secrets**: + + ```bash + enclave purge-all + ``` + +2. **Revoke access**: + - RPC credentials + - Firewall rules + - Any automation keys + +3. **Document for compliance**: + - Exit timestamp + - Final balances + - Reason for exit + +## Slashing Prevention + +To minimize slashing risk: + +1. **Stay online during active E3s** - Check for ongoing jobs before maintenance +2. **Monitor events** - Alert on `SlashProposed` targeting your address +3. **Archive logs** - You'll need evidence for appeals +4. **Verify `isActive` after changes** - Any stake modification could deactivate you + +## Summary + +| Phase | Key Actions | +| -------------- | ------------------------------------------- | +| **Active** | Monitor rewards, watch for slash proposals | +| **Slashing** | Review policy, file appeal if allowed, wait | +| **Exit Start** | Call deregister with proof | +| **Exit Wait** | Wait 7 days (check `exitUnlocksAt`) | +| **Exit Claim** | Claim tickets and license | +| **Post-Exit** | Purge secrets, revoke access, document | diff --git a/docs/pages/ciphernode-operators/index.mdx b/docs/pages/ciphernode-operators/index.mdx new file mode 100644 index 0000000000..51bee02927 --- /dev/null +++ b/docs/pages/ciphernode-operators/index.mdx @@ -0,0 +1,103 @@ +--- +title: 'Ciphernode Operators' +description: 'Overview of ciphernode operations, contracts, and lifecycle' +--- + +# Ciphernode Operators + +Ciphernodes are the distributed workers that power the Enclave network. They participate in +threshold cryptography to enable encrypted computations (E3s) while ensuring no single party can +access the underlying data. + +## What is a Ciphernode? + +A ciphernode is a node operator that: + +- **Generates key shares**: Creates PVSS (Publicly Verifiable Secret Sharing) key shares for each + committee +- **Publishes public keys**: Contributes to aggregated committee public keys used for encryption +- **Produces decryption shares**: Decrypts computation outputs when the threshold is met +- **Maintains availability**: Stays online and responsive to participate in sortition and committee + duties + +Ciphernodes earn rewards for successful participation and risk slashing for missed duties or +malicious behavior. + +## Contract Architecture + +The Enclave protocol uses several contracts that work together: + +| Contract | Purpose | +| ---------------------- | ------------------------------------------------------------------------------ | +| **Enclave** | Core coordinator that manages E3 requests and computation lifecycle | +| **CiphernodeRegistry** | Tracks registered operators and manages committee formation | +| **BondingRegistry** | Handles license bonds (ENCL) and ticket balances (ETK) | +| **SlashingManager** | Processes slashing proposals, appeals, and ban enforcement | +| **EnclaveToken** | ENCL token used for license bonding | +| **EnclaveTicketToken** | Non-transferable ETK token representing ticket balances (backed by stablecoin) | + +### Sepolia Contract Addresses + +| Contract | Address | Deploy block | +| -------------------- | -------------------------------------------- | ------------ | +| Enclave | `0x01E657C16192854E8d7D7055228C7D6532E345Be` | 9761354 | +| CiphernodeRegistry | `0x754490FF874f24fe36124006f9fE0bBaCADDd746` | 9761351 | +| BondingRegistry | `0xA8E7583955797F4C3827eC7bf20872C687bD6313` | 9761313 | +| SlashingManager | `0x2EA642a7431C0d4D958Ce69f0A10c64D49977127` | 9761309 | +| EnclaveTicketToken | `0xE375634734eC04E94c77907804F8DfF2A45EcFc5` | 9761309 | +| EnclaveToken (ENCL) | `0x8F079950F69FB1574B30737F4879F5BE620d3028` | 9761309 | +| MockUSDC (fee token) | `0x00b322ED68246EcD66069BBE4F2C5070d2973efE` | 9761309 | + +> Always verify addresses from `packages/enclave-contracts/deployed_contracts.json` or your +> deployment output. Addresses differ per network. + +## Operator Lifecycle + +A ciphernode moves through several states during its lifecycle: + +```mermaid +stateDiagram-v2 + [*] --> Unbonded + Unbonded --> Licensed: bondLicense(amount >= requiredBond) + Licensed --> Registered: registerOperator() + Registered --> Active: addTicketBalance(balance >= minBalance) + Active --> Inactive: removeTicketBalance() OR unbondLicense() + Inactive --> Active: addTicketBalance() OR bondLicense() + Active --> ExitPending: deregisterOperator() + Inactive --> ExitPending: deregisterOperator() + Registered --> ExitPending: deregisterOperator() + ExitPending --> [*]: claimExits() after exitDelay + ExitPending --> Registered: registerOperator() (cancels exit) +``` + +### State Descriptions + +| State | Description | +| --------------- | ---------------------------------------------------------------------- | +| **Unbonded** | No license bond deposited; cannot register | +| **Licensed** | ENCL bonded but not yet registered in the registry | +| **Registered** | In the registry but lacking minimum ticket balance | +| **Active** | Fully operational; eligible for committee selection via sortition | +| **Inactive** | Registered but below minimum requirements (tickets or license bond) | +| **ExitPending** | Deregistration requested; waiting for exit delay before claiming funds | + +## Requirements + +Before operating a ciphernode, ensure you have: + +| Requirement | Details | +| --------------- | ------------------------------------------------------------------------ | +| **ENCL Tokens** | At least `100 ENCL` for the license bond (check `licenseRequiredBond()`) | +| **Stablecoin** | USDC (or configured fee token) for tickets; minimum 1 ticket worth | +| **ETH** | Gas for transactions on your target network | +| **Hardware** | Linux/macOS, 4+ cores, 8GB+ RAM, stable internet with open UDP port | +| **Software** | Enclave CLI installed, WebSocket RPC endpoint | + +## Getting Started + +Follow these guides in order to become an active ciphernode operator: + +1. **[Running a Ciphernode](./running)** - Set up your node using DappNode, Enclave CLI, or Docker +2. **[Registration & Licensing](./registration)** - Bond your license, register, and add tickets +3. **[Tickets & Sortition](./tickets-and-sortition)** - Understand how committee selection works +4. **[Exits, Rewards & Slashing](./exits-and-slashing)** - Learn about rewards and exit procedures diff --git a/docs/pages/ciphernode-operators/registration.mdx b/docs/pages/ciphernode-operators/registration.mdx new file mode 100644 index 0000000000..7db315c51e --- /dev/null +++ b/docs/pages/ciphernode-operators/registration.mdx @@ -0,0 +1,230 @@ +--- +title: 'Registration & Licensing' +description: 'Bond your license, register as an operator, and add tickets' +--- + +# Registration & Licensing + +This guide walks you through the complete registration process to become an active ciphernode +operator. Make sure your node is already [running](./running) before proceeding. + +## Prerequisites + +Before registering, ensure your wallet has: + +| Token | Amount Required | Purpose | +| ----------------------- | ---------------------------------------- | ---------------------------- | +| **ENCL** | ≥ 100 ENCL (check `licenseRequiredBond`) | License bond collateral | +| **USDC** (or fee token) | ≥ 10 USDC per ticket (minimum 1 ticket) | Ticket balance for sortition | +| **ETH** | Sufficient for gas | Transaction fees | + +## Registration Steps + +### Step 1: Check Current Status + +First, verify your current on-chain status: + +```bash +enclave ciphernode status +``` + +Example output: + +``` +Ciphernode status on sepolia: + Address: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 + Registered: false + Active: false + Exit pending: false + Ticket balance: 0 (0 available) + License bond: 0 + Pending exits: tickets=0, license=0 + Requirements: minTickets=1, ticketPrice=10 EKT, licenseBond=100 ENCL +``` + +### Step 2: Bond Your License + +Bond ENCL tokens to meet the license requirement: + +```bash +enclave ciphernode license bond --amount 100 +``` + +This command: + +- Approves the BondingRegistry to spend your ENCL (if needed) +- Calls `bondLicense(100e18)` on the BondingRegistry contract + +> You can bond more than the minimum for a buffer against slashing. The active license floor is 80% +> of the required bond. + +### Step 3: Register as an Operator + +Register your address in the CiphernodeRegistry: + +```bash +enclave ciphernode register +``` + +After registration, your node will be added to the registry's Merkle tree and can participate in +committee formation once you have tickets. + +### Step 4: Add Ticket Balance + +Purchase tickets by depositing the underlying stablecoin: + +```bash +enclave ciphernode tickets buy --amount 100 +``` + +This deposits 100 USDC (or fee token units) and mints the equivalent in non-transferable ETK +(EnclaveTicketToken). + +The number of usable tickets is calculated as: + +``` +availableTickets = floor(ticketTokenBalance / ticketPrice) +``` + +With a ticket price of 10 USDC and a 100 USDC deposit, you get 10 available tickets. + +### Step 5: Verify Active Status + +Confirm your registration is complete: + +```bash +enclave ciphernode status +``` + +Expected output for an active operator: + +``` +Ciphernode status on sepolia: + Address: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 + Registered: true + Active: true + Exit pending: false + Ticket balance: 100 (10 available) + License bond: 100 + Pending exits: tickets=0, license=0 + Requirements: minTickets=1, ticketPrice=10 EKT, licenseBond=100 ENCL +``` + +## CLI Command Reference + +### License Commands + +```bash +# Bond ENCL tokens +enclave ciphernode license bond --amount + +# Unbond ENCL (moves to exit queue) +enclave ciphernode license unbond --amount + +# Claim unlocked exits +enclave ciphernode license claim +enclave ciphernode license claim --max-ticket 50 --max-license 100 +``` + +### Ticket Commands + +```bash +# Buy tickets (deposit stablecoin) +enclave ciphernode tickets buy --amount + +# Burn tickets (withdraw stablecoin) +enclave ciphernode tickets burn --amount +``` + +### Lifecycle Commands + +```bash +# Register as an operator +enclave ciphernode register + +# Deregister (requires IMT proof) +enclave ciphernode deregister --proof + +# Force activation check +enclave ciphernode activate + +# Deactivate by withdrawing stake +enclave ciphernode deactivate --tickets --license + +# Check status +enclave ciphernode status +``` + +### Multi-Chain Support + +Specify a chain when operating on multiple networks: + +```bash +enclave ciphernode status --chain mainnet +enclave ciphernode license bond --amount 100 --chain sepolia +``` + +The `--chain` parameter matches the `name` field in your config's `chains` array. + +## Economic Parameters + +Current Sepolia defaults (verify on-chain before depositing): + +| Parameter | Value | Description | +| --------------------- | -------------------- | ---------------------------------- | +| `ticketPrice` | 10,000,000 (10 USDC) | Cost per ticket in fee token units | +| `licenseRequiredBond` | 100 ENCL | Minimum ENCL to bond | +| `minTicketBalance` | 1 ticket | Minimum tickets to be active | +| `exitDelay` | 604,800s (7 days) | Wait time before claiming exits | + +Query these values on-chain: + +```bash +# Using cast (foundry) +cast call $BONDING "ticketPrice()" --rpc-url $RPC +cast call $BONDING "licenseRequiredBond()" --rpc-url $RPC +cast call $BONDING "minTicketBalance()" --rpc-url $RPC +cast call $BONDING "exitDelay()" --rpc-url $RPC +``` + +## Best Practices + +### Maintain Buffer Amounts + +- **License bond**: Keep 10-20% above the minimum to absorb potential slashing without losing active + status +- **Tickets**: Maintain extra tickets so you're not deactivated if one is consumed or slashed + +### Monitor Your Status + +Set up alerts for: + +- `isActive` changing to `false` +- `SlashProposed` events targeting your address +- Low ticket balance approaching minimum + +### Backup Your IMT Proof + +When you register, save the sibling nodes from the `CiphernodeAdded` event. You'll need these to +deregister: + +```bash +# Store the proof when you register +enclave ciphernode deregister --proof 0x123...,0x456...,0x789... +``` + +## Troubleshooting + +| Issue | Cause | Solution | +| ------------------------- | -------------------------------------- | ------------------------------------- | +| `isActive` is false | Below minimum license (80%) or tickets | Add more ENCL or tickets | +| Registration fails | Already registered or banned | Check `isRegistered()` and ban status | +| Ticket purchase fails | Insufficient stablecoin or allowance | Ensure balance and approve spending | +| "NodeNotEligible" in logs | Not registered before E3 request | Register before requests are made | + +## Next Steps + +Once registered and active: + +1. **[Tickets & Sortition](./tickets-and-sortition)** - Learn how committee selection works +2. **[Exits & Slashing](./exits-and-slashing)** - Understand rewards and exit procedures diff --git a/docs/pages/ciphernode-operators/running.mdx b/docs/pages/ciphernode-operators/running.mdx new file mode 100644 index 0000000000..8c828a63a5 --- /dev/null +++ b/docs/pages/ciphernode-operators/running.mdx @@ -0,0 +1,333 @@ +--- +title: 'Running a Ciphernode' +description: 'Three ways to run a ciphernode: DappNode, Enclave CLI, or Docker' +--- + +# Running a Ciphernode + +This guide covers three methods to run a ciphernode, from easiest to most flexible. Choose the +method that best fits your infrastructure. + +## Method 1: DappNode (Easiest) + +DappNode provides a user-friendly interface for running a ciphernode with minimal configuration. + +### Installation + +1. Open your DappNode UI (`http://my.dappnode`) +2. Search for **"Enclave Ciphernode"** and install the package +3. The setup wizard will prompt you for: + - `RPC_URL` - WebSocket RPC endpoint (e.g., `wss://ethereum-sepolia-rpc.publicnode.com`) + - `NETWORK` - Network name (e.g., `sepolia`, `mainnet`) + - Contract addresses and deploy blocks + - Node role (`ciphernode` or `aggregator`) + - Optional: encryption password, network key, private key + +4. Confirm and complete the installation +5. Check **Packages → enclave-ciphernode → Logs** to verify the node started + +### Configuration via Environment Variables + +| Variable | Description | Required | +| --------------------- | -------------------------------------------- | -------- | +| `RPC_URL` | WebSocket RPC endpoint | Yes | +| `NETWORK` | Network name (sepolia, mainnet, etc.) | No | +| `NODE_ROLE` | `ciphernode` or `aggregator` | No | +| `NODE_ADDRESS` | Your Ethereum address | No | +| `QUIC_PORT` | UDP port for P2P networking (default: 37173) | No | +| `ENCRYPTION_PASSWORD` | Password to encrypt local data | No | +| `NETWORK_PRIVATE_KEY` | libp2p network key (ed25519) | No | +| `PRIVATE_KEY` | Ethereum private key (for aggregator) | No | +| `PEERS` | Comma-separated peer multiaddresses | No | + +--- + +## Method 2: Enclave CLI (Recommended) + +The Enclave CLI provides the most control and is recommended for production deployments. + +### Install the CLI + +```bash +# Quick install +curl -fsSL https://raw.githubusercontent.com/gnosisguild/enclave/main/install | bash + +# Then install the CLI +enclaveup install +``` + +### Initialize Configuration + +```bash +enclave config-set \ + --rpc-url wss://ethereum-sepolia-rpc.publicnode.com \ + --eth-address 0xYourAddress +``` + +This creates `~/.config/enclave/enclave.config.yaml`. You'll be prompted for a password to encrypt +sensitive data. + +### Set Up Credentials + +```bash +# Set encryption password (encrypts local keystore) +enclave password set + +# Generate or set network keypair (for libp2p) +enclave net keypair generate +# Or import an existing key: +# enclave net keypair set --net-keypair 0x... + +# Set your wallet private key (for on-chain transactions) +enclave wallet set --private-key 0xYourPrivateKey +``` + +### Configure Your Node + +Edit `~/.config/enclave/enclave.config.yaml`: + +```yaml +node: + address: '0xYourAddress' + quic_port: 9091 + peers: + - '/dnsaddr/bootstrap.enclave.gg' + autonetkey: true + autopassword: true + +chains: + - name: sepolia + rpc_url: 'wss://ethereum-sepolia-rpc.publicnode.com' + contracts: + enclave: + address: '0x01E657C16192854E8d7D7055228C7D6532E345Be' + deploy_block: 9761354 + ciphernode_registry: + address: '0x754490FF874f24fe36124006f9fE0bBaCADDd746' + deploy_block: 9761351 + bonding_registry: + address: '0xA8E7583955797F4C3827eC7bf20872C687bD6313' + deploy_block: 9761313 +``` + +### Start Your Node + +```bash +# Start in foreground with verbose logging +enclave start -v + +# Or use the node supervisor for multiple nodes +enclave nodes up --detach +enclave nodes ps # Check status +enclave nodes logs cn1 # View logs +enclave nodes down # Stop all nodes +``` + +### CLI Commands Reference + +| Command | Description | +| ------------------------------ | -------------------------------------- | +| `enclave start` | Start the node in foreground | +| `enclave nodes up` | Start all configured nodes | +| `enclave nodes down` | Stop all nodes | +| `enclave nodes ps` | List running nodes | +| `enclave nodes status ` | Check specific node status | +| `enclave nodes restart ` | Restart a specific node | +| `enclave ciphernode status` | Show on-chain registration status | +| `enclave purge-all` | Wipe all local data (use with caution) | + +--- + +## Method 3: Docker + +For containerized deployments, you can run the ciphernode Docker image directly. + +### Pull the Image + +```bash +docker pull ghcr.io/gnosisguild/ciphernode:latest +``` + +### Create Configuration + +Create a `config.yaml` file: + +```yaml +node: + address: '0xYourAddress' + quic_port: 9091 + peers: + - '/dnsaddr/bootstrap.enclave.gg' + autonetkey: true + autopassword: true + +chains: + - name: sepolia + rpc_url: 'wss://ethereum-sepolia-rpc.publicnode.com' + contracts: + enclave: + address: '0x01E657C16192854E8d7D7055228C7D6532E345Be' + deploy_block: 9761354 + ciphernode_registry: + address: '0x754490FF874f24fe36124006f9fE0bBaCADDd746' + deploy_block: 9761351 + bonding_registry: + address: '0xA8E7583955797F4C3827eC7bf20872C687bD6313' + deploy_block: 9761313 +``` + +### Run the Container + +```bash +docker run -d \ + --name ciphernode \ + -v $(pwd)/config.yaml:/home/ciphernode/.config/enclave/config.yaml:ro \ + -v ciphernode-data:/home/ciphernode/.local/share/enclave \ + -p 9091:9091/udp \ + -e ENCRYPTION_PASSWORD=your_password \ + -e PRIVATE_KEY=0xYourPrivateKey \ + ghcr.io/gnosisguild/ciphernode:latest +``` + +### Docker Compose + +For a more manageable setup, use Docker Compose: + +```yaml +services: + ciphernode: + image: ghcr.io/gnosisguild/ciphernode:latest + restart: unless-stopped + volumes: + - ./config.yaml:/home/ciphernode/.config/enclave/config.yaml:ro + - ciphernode-data:/home/ciphernode/.local/share/enclave + ports: + - '9091:9091/udp' + environment: + ENCRYPTION_PASSWORD: ${ENCRYPTION_PASSWORD} + PRIVATE_KEY: ${PRIVATE_KEY} + +volumes: + ciphernode-data: +``` + +### View Logs + +```bash +docker logs -f ciphernode +``` + +--- + +## Configuration Reference + +### Node Configuration + +| Field | Description | Default | +| -------------- | ------------------------------------ | ------------------------ | +| `address` | Your Ethereum address | Required | +| `quic_port` | UDP port for QUIC/libp2p networking | `9091` | +| `peers` | Bootstrap peer multiaddresses | `[]` | +| `autonetkey` | Auto-generate network key if missing | `false` | +| `autopassword` | Auto-generate password if missing | `false` | +| `autowallet` | Auto-load wallet from environment | `false` | +| `data_dir` | Override data directory | `~/.local/share/enclave` | +| `config_dir` | Override config directory | `~/.config/enclave` | + +### Chain Configuration + +| Field | Description | Required | +| ----------- | ------------------------------------ | -------- | +| `name` | Chain identifier | Yes | +| `rpc_url` | WebSocket RPC endpoint | Yes | +| `contracts` | Contract addresses and deploy blocks | Yes | + +### Contract Addresses + +Each chain requires these contract addresses: + +| Contract | Description | +| --------------------- | ---------------------------------------- | +| `enclave` | Main Enclave coordinator | +| `ciphernode_registry` | Tracks registered operators | +| `bonding_registry` | Manages bonds and tickets | +| `fee_token` | Optional: stablecoin address for tickets | + +--- + +## Networking Requirements + +### Firewall Configuration + +Open the following ports: + +| Port | Protocol | Purpose | +| ------ | -------- | -------------------------- | +| `9091` | UDP | QUIC/libp2p P2P networking | + +### Bootstrap Peers + +Connect to the Enclave bootstrap network: + +```yaml +peers: + - '/dnsaddr/bootstrap.enclave.gg' +``` + +Or specify individual peers: + +```yaml +peers: + - '/dns4/node1.example.com/udp/9091/quic-v1' + - '/ip4/192.168.1.100/udp/9091/quic-v1' +``` + +--- + +## Data Directories + +| Directory | Contents | +| ------------------------------ | --------------------------------- | +| `~/.config/enclave/` | Configuration files, network keys | +| `~/.local/share/enclave/` | Databases, job data, keystores | +| `~/.local/share/enclave/jobs/` | Per-E3 secret shares and state | + +> Back up these directories regularly. The `jobs/` directory contains encrypted key shares for +> active E3s - losing this data while participating in a committee may result in slashing. + +--- + +## Monitoring + +### Log Levels + +Control verbosity with the `-v` flag: + +| Flag | Level | Description | +| ------ | ----- | ------------------------ | +| (none) | WARN | Warnings and errors only | +| `-v` | INFO | Normal operation logs | +| `-vv` | DEBUG | Detailed debug output | +| `-vvv` | TRACE | Full trace logging | + +### Key Events to Watch + +| Event | Meaning | +| --------------------------- | ------------------------------------ | +| `E3Requested` | New computation request detected | +| `TicketGenerated` | Your sortition ticket was calculated | +| `CiphernodeSelected` | You were selected for a committee | +| `KeyshareCreated` | Your key share was generated | +| `PublicKeyAggregated` | Committee public key is ready | +| `CiphertextOutputPublished` | Time to generate decryption share | +| `DecryptionshareCreated` | Your decryption share was published | +| `PlaintextAggregated` | Final result is available | + +--- + +## Next Steps + +Once your node is running: + +1. **[Register & License](./registration)** - Bond ENCL and register as an operator +2. **[Add Tickets](./tickets-and-sortition)** - Purchase tickets to participate in sortition diff --git a/docs/pages/ciphernode-operators/tickets-and-sortition.mdx b/docs/pages/ciphernode-operators/tickets-and-sortition.mdx new file mode 100644 index 0000000000..d0c06e3f37 --- /dev/null +++ b/docs/pages/ciphernode-operators/tickets-and-sortition.mdx @@ -0,0 +1,177 @@ +--- +title: 'Tickets & Sortition' +description: 'How ticket balances influence committee selection' +--- + +# Tickets & Sortition + +Tickets determine your probability of being selected for E3 committees. This guide explains the +ticket system and sortition algorithm. + +## Ticket Overview + +| Token | Purpose | Transferable | +| -------- | -------------------------------------------------- | ------------ | +| **ENCL** | License bond - required to register | Yes | +| **ETK** | Ticket token - determines committee selection odds | No | +| **USDC** | Underlying asset for tickets (fee token) | Yes | + +Tickets are priced in stablecoins and minted into non-transferable ETK balances: + +``` +availableTickets = floor(ticketTokenBalance / ticketPrice) +``` + +## Managing Tickets + +### Buy Tickets + +Deposit stablecoins to mint tickets: + +```bash +# Buy tickets worth 100 USDC +enclave ciphernode tickets buy --amount 100 +``` + +This: + +1. Approves the ticket contract to spend your USDC (if needed) +2. Deposits the stablecoin +3. Mints equivalent ETK to your balance + +### Burn Tickets + +Withdraw the underlying stablecoin: + +```bash +# Burn tickets and withdraw 50 USDC worth +enclave ciphernode tickets burn --amount 50 +``` + +> Burning tickets takes effect immediately. Dropping below the minimum ticket balance makes you +> inactive until you top up again. + +### Check Balance + +```bash +enclave ciphernode status +``` + +Look for the "Ticket balance" and "available" fields in the output. + +## Ticket Economics + +- **Committee probability scales linearly** with your available tickets relative to other operators +- **Doubling your tickets doubles your odds** (assuming peers stay constant) +- **Balances are snapshotted** at `requestBlock - 1` - adding tickets after a request won't help + that round +- **Idle tickets have opportunity cost** - rewards only accrue when you're selected and complete + duties + +### Rebalancing Tips + +- Add tickets **one or two requests ahead** of anticipated demand to avoid gas spikes +- Keep a **small buffer** so slashing or removals don't instantly deactivate you +- Monitor `ticketPrice()` and `minTicketBalance()` before automating deposits on multiple networks + +## Sortition Algorithm + +The sortition process selects committees deterministically based on a random seed: + +```mermaid +flowchart TD + A[E3Requested event] --> B[Snapshot balances at requestBlock - 1] + B --> C[Filter eligible operators] + C --> D[Calculate ticket scores] + D --> E[Submit winning tickets on-chain] + E --> F[Finalize committee after deadline] + F --> G[Generate and publish key shares] +``` + +### 1. Eligibility Check + +When `CommitteeRequested` fires, nodes check if they're eligible: + +- Registered and not banned +- `isActive` (bond + ticket minimums satisfied) +- No exit in progress + +### 2. Score Calculation + +For each ticket you hold, a score is calculated: + +``` +score = keccak256(seed, operator, ticketNumber) +``` + +The same inputs always produce the same scores, so all honest nodes converge on the same committee. + +### 3. Ticket Submission + +Operators submit their winning tickets during the submission window (300 seconds on Sepolia): + +```bash +# The CLI handles this automatically when running +submitTicket(e3Id, ticketNumber) +``` + +Each submission emits `TicketSubmitted(e3Id, operator, ticketNumber, score)`. + +### 4. Committee Finalization + +After the window closes and ≥ `threshold_m` tickets are present: + +1. Anyone can call `finalizeCommittee(e3Id)` +2. Registry emits `CommitteeFinalized` +3. Selected nodes generate and publish key shares +4. Aggregated public key is published via `publishCommittee` + +## Parameters + +| Parameter | Sepolia Value | Description | +| --------------------------- | ------------- | ----------------------------------- | +| `ticketPrice` | 10 USDC | Cost per ticket | +| `minTicketBalance` | 1 ticket | Minimum to be active | +| `sortitionSubmissionWindow` | 10 seconds | Time to submit winning tickets | +| `threshold_m` | Varies | Minimum operators needed for duties | +| `threshold_n` | Varies | Total committee size | + +## Monitoring + +### Events to Watch + +| Event | Meaning | +| -------------------- | ------------------------------------ | +| `CommitteeRequested` | New committee formation started | +| `TicketSubmitted` | A ticket was submitted for selection | +| `CommitteeFinalized` | Committee members confirmed | +| `CommitteePublished` | Aggregated public key ready | + +### Log Messages + +Watch your node logs for: + +- `sortition::submitted` - Successfully submitted tickets +- `sortition::missed` - Failed to submit in time +- `jobs::selected` - You were selected for a committee + +## Troubleshooting + +| Symptom | Possible Cause | Solution | +| ------------------------------- | ------------------------------------- | -------------------------------- | +| Never being selected | Low ticket count relative to peers | Add more tickets | +| `isActive` is false | Below minimum tickets or license bond | Top up tickets or rebond license | +| `SubmissionWindowClosed` errors | RPC latency or slow submission | Use faster RPC, check network | +| Committee missing your operator | Submission didn't succeed | Check logs, retry next round | + +## Best Practices + +1. **Stagger ticket top-ups** - Avoid last-minute gas competition +2. **Alert on missed submissions** - Human intervention before committee deadlines +3. **Batch networks separately** - Run separate CLI instances per chain +4. **Track governance changes** - `sortitionSubmissionWindow`, `ticketPrice`, and + `licenseRequiredBond` may change + +## Next Steps + +- **[Exits, Rewards & Slashing](./exits-and-slashing)** - Understand rewards and how to exit safely diff --git a/docs/pages/computation-flow.mdx b/docs/pages/computation-flow.mdx index 6015c5e4c7..97158ed990 100644 --- a/docs/pages/computation-flow.mdx +++ b/docs/pages/computation-flow.mdx @@ -11,31 +11,34 @@ Providers, or other network participant. ### Phase 1: Request -1. **Define the E3 Program**: The core FHE logic of your application must be written in a supported - FHE scheme. Currently, Enclave supports the [fhe.rs](https://github.com/gnosisguild/fhe.rs) - implementation of the BFV encryption scheme. -2. **Choose a Compute Provider**: Your E3 program will likely need to be written to explicitly - support your chosen Compute Provider. For our demo application, [CRISP](/CRISP/introduction), we - use [Risc Zero](https://www.risczero.com/) as our Compute Provider. -3. **Specify Parameters**: - - Set the threshold (t/n) for the Ciphernode Committee (CiCo), which defines the number of nodes - that must coordinate to decrypt the computation output. This can be user-defined or - pre-configured based on your application's needs. - - Provide any necessary parameters specific to the Compute Provider. - - Configure E3 Program parameters, including input submission deadlines and computation duration. -4. **Submit the Request**: Call `request` on the Enclave contract to publish the request and - initialize the E3. +1. **Define the E3 Program**: Author your Secure Process using the tooling described in + [Writing the Secure Process](/write-secure-program). Enclave currently ships first-party support + for the BFV scheme via [fhe.rs](https://github.com/gnosisguild/fhe.rs) and the SAFE library. +2. **Choose a Compute Provider**: Your program must align with the execution backend (e.g., + [RISC Zero](https://www.risczero.com/) for [CRISP](/CRISP/introduction) or a custom FHE + coprocessor). +3. **Assemble `E3RequestParams`**: + - `threshold`: the CiCo size/threshold tuple (t/n) used for decryption security + - `startWindow` and `duration`: governs when inputs open/close and how long execution may run + - `e3Program`, `e3ProgramParams`, `computeProviderParams`, and optional `customParams` +4. **Submit the Request**: Call `request` with the struct to publish the new computation. ```solidity function request( - address filter, - uint32[2] calldata threshold, - uint256[2] calldata startWindow, - uint256 duration, - IE3Program e3Program, - bytes memory e3ProgramParams, - bytes memory computeProviderParams - ) external returns (uint256 e3Id, E3 memory e3) + E3RequestParams calldata requestParams + ) external returns (uint256 e3Id, E3 memory e3); + ``` + + ```solidity + struct E3RequestParams { + uint32[2] threshold; + uint256[2] startWindow; + uint256 duration; + IE3Program e3Program; + bytes e3ProgramParams; + bytes computeProviderParams; + bytes customParams; + } ``` ### Phase 2: Node Selection diff --git a/docs/pages/compute-provider.mdx b/docs/pages/compute-provider.mdx index e2ee3c0479..0dd48b02a9 100644 --- a/docs/pages/compute-provider.mdx +++ b/docs/pages/compute-provider.mdx @@ -52,14 +52,17 @@ the [Writing the Secure Process](./write-secure-program.mdx) guide. ### Setup -In this guide, we'll go over setting up [RISC Zero](https://www.risczero.com/) as the CP. +In this guide, we'll go over setting up [RISC Zero](https://www.risczero.com/) with +[Boundless](https://docs.beboundless.xyz/) as the CP. -RISC Zero provides a [Foundry template](https://github.com/risc0/risc0-foundry-template) that can be -used to run the Secure Process and create a ZK proof. The template includes a basic program that can -be used to get started with the smart contract code to verify the proof. +Boundless provides a [Foundry template](https://github.com/boundless-xyz/boundless-foundry-template) +that can be used to run the Secure Process and create a ZK proof using RISC Zero's zkVM. The +template includes a basic program that can be used to get started with the smart contract code to +verify the proof. -Follow the instructions in the [Foundry template](https://github.com/risc0/risc0-foundry-template) -to setup RISC Zero. +Follow the instructions in the +[Boundless Foundry template](https://github.com/boundless-xyz/boundless-foundry-template) to setup +RISC Zero with Boundless. Ensure the following tools are installed: @@ -93,4 +96,20 @@ You can verify the installation was successful by running: cargo risczero --version ``` -Now you're ready to develop and deploy applications using RISC Zero as your CP. +Now you're ready to develop and deploy applications using RISC Zero with Boundless as your CP. + +### Boundless Configuration + +Boundless is a decentralized proving marketplace for RISC Zero programs. Instead of running proofs +locally, you can submit them to Boundless for faster, distributed proving. + +To use Boundless: + +1. Get access to an RPC endpoint (e.g., Infura, Alchemy) with funds +2. Obtain a private key with sufficient ETH/tokens for proof generation +3. (Optional) Get a Pinata JWT from [pinata.cloud](https://pinata.cloud) for uploading programs to + IPFS +4. Configure your `enclave.config.yaml` as shown in the + [CRISP setup guide](/CRISP/setup#boundless-configuration-production-proving) + +For more details, see the [Boundless documentation](https://docs.beboundless.xyz/). diff --git a/docs/pages/noir-circuits.mdx b/docs/pages/noir-circuits.mdx new file mode 100644 index 0000000000..3fb9424a49 --- /dev/null +++ b/docs/pages/noir-circuits.mdx @@ -0,0 +1,84 @@ +--- +title: 'Noir Circuits' +description: 'Build and reuse Noir circuits for Enclave programs' +--- + +# Noir Circuits & Libraries + +Enclave ships a dedicated Noir workspace under `circuits/` plus reusable libraries (SAFE sponge API, +polynomial utilities, Greco BFV proofs, etc.). Use these circuits as-is or vendor them into your own +E3 programs. + +## Workspace layout + +``` +circuits/ +├── Nargo.toml # workspace manifest +├── crates/ +│ └── libs/ +│ ├── safe/ # SAFE sponge implementation +│ ├── greco/ # ZK circuit for BFV ciphertext correctness proofs +│ └── polynomial/ # polynomial commitments utils +└── target/ # build artifacts (created by nargo) +``` + +Each library has its own `README.md` describing APIs and dependency stanza. Example (`safe`): + +```toml +[dependencies] +safe = { git = "https://github.com/gnosisguild/enclave", tag = "v0.1.5", directory = "circuits/crates/libs/safe" } +``` + +From `v0.1.6` onward the directory becomes `circuits/crates/libs/safe` (the `packages/` prefix was +removed). + +## Tooling requirements + +Install the Noir toolchain: + +```bash +curl -L https://noir-lang.org/install | bash # installs nargo + bb +nargo --version # 1.0.0-beta.11+ +bb --version # v0.87.0+ +``` + +## Formatting & compilation + +Run the helper scripts from the repo root or reproduce them in your project: + +```bash +./scripts/compile-circuits.sh # nargo fmt --check && nargo compile --workspace +./scripts/lint-circuits.sh # format check + warnings +./scripts/test-circuits.sh # run circuit unit tests (nargo test) when available +``` + +These scripts exit early (without failing the whole build) if `nargo` is not installed, which makes +CI happy when Noir is optional. + +## Exporting verifiers + +Projects such as CRISP compile Noir circuits into Solidity verifiers using `bb`: + +```bash +cd examples/CRISP +./scripts/compile_circuits.sh +``` + +The script performs: + +1. `nargo compile` for every circuit in the workspace +2. `bb write_vk` to emit the verification key (`circuits/target/vk`) +3. `bb write_solidity_verifier` to produce `CRISPVerifier.sol` +4. Copies the generated verifier into `packages/crisp-contracts/contracts/` + +Adapt the script for your own circuits and verifiers by changing the output path. + +## Integrating with E3 programs + +- Import the library from `Nargo.toml` or `program/Cargo.toml` +- Generate Solidity verifiers and move them into your contract package +- Reference the compiled artifacts when deploying via the template or CRISP scripts + +When adding new circuits, remember to update `package.json` scripts (e.g., `pnpm dev:all`) so they +call your compile script before spinning up the dev environment. This keeps your verifiers in sync +with the Noir source. diff --git a/docs/pages/project-template.mdx b/docs/pages/project-template.mdx new file mode 100644 index 0000000000..d3a199262c --- /dev/null +++ b/docs/pages/project-template.mdx @@ -0,0 +1,98 @@ +--- +title: 'Project Template' +description: 'What gets generated by `enclave init` and how to customize it' +--- + +# Default Project Template + +Running `enclave init ` 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 + +| Script | Purpose | +| ----------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| `pnpm dev:all` | Spins up Hardhat, deploys contracts, launches the RISC0 program server, coordination server, frontend, and ciphernodes. | +| `pnpm dev:evm` | Runs `hardhat node` on `http://localhost:8545`. | +| `pnpm dev:program` | Starts the RISC0 guest runner. Pass `--dev` to skip real proving. | +| `pnpm dev:server` | Boots the TypeScript coordination server with hot reload. | +| `pnpm dev:frontend` | Launches the Vite client on `http://localhost:3000`. | +| `pnpm dev:ciphernodes` | Calls the Enclave CLI to launch the nodes defined in `enclave.config.yaml`. | +| `pnpm compile` | Compiles Solidity contracts. | +| `pnpm test` | Runs Hardhat tests. | +| `pnpm test:integration` | Executes 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](/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`: + +```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. diff --git a/docs/pages/quick-start.mdx b/docs/pages/quick-start.mdx index a215514848..14a64ce372 100644 --- a/docs/pages/quick-start.mdx +++ b/docs/pages/quick-start.mdx @@ -105,7 +105,9 @@ Now that you have a working E3 program: 1. **Explore the code**: Check out `./program/src/lib.rs` to see the FHE computation 2. **Modify the computation**: Try changing the addition to multiplication 3. **Update the UI**: Customize the client in `./client/src/` -4. **Deploy**: Learn about production deployment +4. **Run real Ciphernodes**: Follow the [Ciphernode Operators guide](/ciphernode-operators) to bond + tokens, configure nodes, and join the shared network +5. **Deploy**: Learn about production deployment Ready to dive deeper? Continue with our [Hello World Tutorial](/hello-world-tutorial) for a step-by-step breakdown of building E3 programs from scratch. diff --git a/docs/pages/sdk.mdx b/docs/pages/sdk.mdx new file mode 100644 index 0000000000..92522ff639 --- /dev/null +++ b/docs/pages/sdk.mdx @@ -0,0 +1,170 @@ +--- +title: 'Enclave SDK' +description: 'Use the TypeScript + React SDKs to drive E3 programs from clients and services' +--- + +# Enclave SDK Overview + +The Enclave SDK (`@enclave-e3/sdk`) and React helpers (`@enclave-e3/react`) provide a +batteries-included client stack for requesting E3 computations, subscribing to protocol events, and +coordinating custom frontends or backend services. Both packages ship in this repository (see +`packages/enclave-sdk` and `packages/enclave-react`). + +## Installation + +```bash +pnpm add @enclave-e3/sdk # TypeScript SDK +pnpm add @enclave-e3/react # React hooks (optional) +``` + +For browser projects using WASM (encryption helpers, FHE keygen), configure Vite per the SDK README: + +```ts +// vite.config.ts +import wasm from 'vite-plugin-wasm' +import topLevelAwait from 'vite-plugin-top-level-await' + +export default defineConfig({ + optimizeDeps: { + exclude: ['@enclave-e3/wasm'], + }, + plugins: [wasm(), topLevelAwait()], +}) +``` + +## Core client + +```ts +import { EnclaveSDK, EnclaveEventType, RegistryEventType } from '@enclave-e3/sdk' +import { createPublicClient, createWalletClient, http, custom } from 'viem' + +const publicClient = createPublicClient({ transport: http(import.meta.env.VITE_RPC_URL) }) +const walletClient = createWalletClient({ transport: custom(window.ethereum) }) + +const sdk = new EnclaveSDK({ + publicClient, + walletClient, + contracts: { + enclave: import.meta.env.VITE_ENCLAVE_ADDRESS, + ciphernodeRegistry: import.meta.env.VITE_REGISTRY_ADDRESS, + }, + chainId: 11155111, +}) + +await sdk.initialize() +``` + +### Requesting computations + +```ts +const hash = await sdk.requestE3({ + threshold: [2, 3], + startWindow: [BigInt(Date.now()), BigInt(Date.now() + 5 * 60 * 1000)], + duration: BigInt(1800), + e3Program: '0x...', + e3ProgramParams: '0x', + computeProviderParams: '0x', + customParams: '0x', +}) +``` + +### Event subscriptions + +```ts +const e3Handler = (event) => { + console.log('New request', event.data) +} + +sdk.onEnclaveEvent(EnclaveEventType.E3_REQUESTED, e3Handler) + +sdk.onEnclaveEvent(RegistryEventType.COMMITTEE_REQUESTED, (event) => { + console.log('Committee requested', event.data) +}) + +// Later, remember to clean up +sdk.off(EnclaveEventType.E3_REQUESTED, e3Handler) +``` + +### React hook + +```tsx +import { useEnclaveSDK } from '@enclave-e3/react' + +export function Dashboard() { + const { isInitialized, requestE3, onEnclaveEvent, EnclaveEventType } = useEnclaveSDK({ + autoConnect: true, + contracts: { + enclave: import.meta.env.VITE_ENCLAVE_ADDRESS, + ciphernodeRegistry: import.meta.env.VITE_REGISTRY_ADDRESS, + }, + chainId: 31337, + }) + + useEffect(() => { + if (!isInitialized) return + const handle = (event) => console.log('Activated', event.data) + onEnclaveEvent(EnclaveEventType.E3_ACTIVATED, handle) + return () => off(EnclaveEventType.E3_ACTIVATED, handle) + }, [isInitialized]) + + return +} +``` + +## Configuration contract map + +Provide both the Enclave and CiphernodeRegistry addresses. The template exposes these via `.env` / +`enclave.config.yaml`. For multi-chain apps, instantiate multiple SDKs or call +`sdk.updateConfig({ contracts: { ... }, chainId })` whenever wallets switch networks. + +## Working with the template + +`enclave init` generates the default template (see [Project Template](/project-template)). The +client already wires `@enclave-e3/sdk` and `@enclave-e3/react`: + +- `client/src/sdk.ts` builds the shared SDK instance +- `client/src/hooks/useE3.ts` uses `useEnclaveSDK` to expose helper hooks throughout the UI +- `server/src/services/enclave.ts` instantiates the SDK with a server wallet using + `createWalletClient` + +When you add new contracts or E3 programs, update `client/.env` and `server/.env` with the new +addresses, then restart the dev server so the SDK reconnects. + +## Application-specific SDKs + +For complex E3 programs with specialized requirements, you may want to build an application-specific +SDK on top of or alongside the Enclave SDK. For example, +[CRISP](https://github.com/gnosisguild/enclave/tree/main/examples/CRISP) uses `@crisp-e3/sdk`, which +provides: + +- Zero-knowledge proof generation for votes using Noir circuits +- Merkle tree utilities for voter eligibility verification +- Vote encryption helpers using FHE +- Round management and token operations +- CRISP server interaction APIs + +If your E3 program requires specialized cryptographic operations, domain-specific logic, or +application-level abstractions beyond basic protocol interactions, consider building a dedicated SDK +that wraps or complements the core Enclave SDK. + +## Advanced usage + +- **Historical events**: `sdk.getHistoricalEvents(type, fromBlock, toBlock)` fetches logs without a + WebSocket provider; useful for CRON jobs or health checks. +- **Gas controls**: pass `gasLimit` to `requestE3`, `activateE3`, or `publishInput` if you want + fixed limits when interacting with Enclave on L2s. +- **Event polling**: `sdk.startEventPolling()` is handy in serverless environments where websockets + are unavailable. +- **Custom transports**: on the server, call `createWalletClient({ account, transport: http(rpc) })` + and load the private key from Vaults/KMS. + +## Troubleshooting + +| Symptom | Triage | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | +| `MISSING_PUBLIC_CLIENT` errors | Ensure `createPublicClient` uses an HTTP or WebSocket RPC reachable from the app. | +| `INVALID_ADDRESS` | Double-check contract addresses passed into the SDK match the current chain. | +| Hooks never initialize | Confirm `autoConnect` is true, wallet is connected, and React component is inside a provider that renders on the client. | +| No events arrive | Switch to a WebSocket RPC or call `sdk.startEventPolling()` so logs are polled over HTTP. | + +For additional API surface details see `packages/enclave-sdk/README.md` inside this repo. diff --git a/docs/pages/setting-up-server.mdx b/docs/pages/setting-up-server.mdx index cbbd12f783..ca90ffa313 100644 --- a/docs/pages/setting-up-server.mdx +++ b/docs/pages/setting-up-server.mdx @@ -29,16 +29,16 @@ The Enclave SDK handles much of this complexity for you, providing: ### Install the SDK -For TypeScript/JavaScript applications: +For TypeScript/JavaScript applications install the TypeScript SDK: ```bash -pnpm add @enclave-e3/contracts +pnpm add @enclave-e3/sdk ``` -For React applications: +For React applications add the hook helpers as well: ```bash -pnpm add @enclave-e3/contracts @enclave-e3/react +pnpm add @enclave-e3/sdk @enclave-e3/react ``` ### Basic TypeScript Client diff --git a/docs/pages/use-cases.mdx b/docs/pages/use-cases.mdx new file mode 100644 index 0000000000..238a14e24e --- /dev/null +++ b/docs/pages/use-cases.mdx @@ -0,0 +1,63 @@ +--- +title: 'Use Cases' +--- + +# Unlocking Enclave Use Cases + +Leading confidential-compute platforms such as Ritual, Fhenix, and Olas showcase their ecosystems by +highlighting concrete scenarios, personas, and playbooks. This page borrows that structure so you +can quickly map Enclave building blocks to the outcomes you need. + +## Confidential Governance (CRISP-style) + +- **Problem**: Public DAOs struggle to keep tallies, delegations, and vote rationales private during + sensitive decisions. +- **Pattern**: Use the CRISP template (client, Rust server, Noir circuits) with the Enclave SDK. +- **Flow**: DAO admins request an E3 round, contributors encrypt ballots in the browser, and + Ciphernodes publish a verifiable plaintext tally once the compute provider finishes. +- **Extras**: Plug Synpress or Playwright into the client for scripted voting drills. + +## Private Auctions & Matching Markets + +- **Problem**: Sealed-bid auctions or RFQ desks cannot run on public ledgers without leaking prices. +- **Pattern**: Model each bid as an input validated by account-specific ZKPs (range/whitelist) and + aggregate them off-chain using BFV-friendly arithmetic in your Secure Process. +- **Flow**: Traders submit encrypted bids, the compute provider selects the clearing price, and the + plaintext output unlocks settlement logic. +- **Extras**: Pair with Foundry scripts (similar to Fhenix's CoFHE quick starts) to simulate extreme + bidding volumes before mainnet. + +## AI Agent Coordination + +- **Problem**: Networks such as Ritual and Olas expose agent marketplaces; those agents still need a + privacy-preserving substrate for sensitive scoring, routing, or risk checks. +- **Pattern**: Treat each agent as a Data Provider, push policy enforcement into an + `IInputValidator`, and let Enclave host shared state transitions (e.g., allocating budget or + updating trust scores). +- **Flow**: Agents encrypt telemetry, the Secure Process derives rankings, and downstream contracts + or marketplaces read the published plaintext. +- **Extras**: Use `customParams` inside `E3RequestParams` to tag rounds per agent vertical (NFT + curation, wallet assistants, on-chain AI retrieval). + +## Identity, Compliance, and Scoring + +- **Problem**: Identity attestations or credit scores leak sensitive attributes when stored directly + on-chain. +- **Pattern**: Build circuits that validate proofs of residency, KYC, or AML results without + revealing raw data; only the computed risk vector is decrypted. +- **Flow**: Validators encrypt attestations, the Secure Process derives the minimal disclosure blob, + and downstream protocols pull the plaintext via `PlaintextOutputPublished`. +- **Extras**: Combine with `customParams` to pin jurisdictional policy, similar to how Fhenix + exposes "Key Considerations" per sector. + +## Solution Matrix + +| Scenario | Typical Inputs | Secure Process Focus | Output Consumers | +| ----------------------- | --------------------------- | ------------------------------------ | --------------------------------- | +| Confidential Governance | Wallet + ballot selections | Vote aggregation, quorum, randomness | DAO front-ends, multi-sigs | +| Private Auctions | Bid amount, bidder proofs | Price discovery, winner selection | Settlement contracts | +| AI Agent Coordination | Agent telemetry, task queue | Ranking, budget splits | Agent marketplaces, orchestrators | +| Identity / Compliance | Encrypted attestations | Risk flag derivation | On-chain registries, bridges | + +Next, explore the [Best Practices](/best-practices) and +[Putting It All Together](/putting-it-together) guides to tailor these patterns to your app. diff --git a/docs/pages/write-secure-program.mdx b/docs/pages/write-secure-program.mdx index 34b60cc5bd..2f8d8ea84d 100644 --- a/docs/pages/write-secure-program.mdx +++ b/docs/pages/write-secure-program.mdx @@ -39,7 +39,8 @@ impl ComputeProvider for Risc0Provider { type Output = Risc0Output; fn prove(&self, input: &ComputeInput) -> Self::Output { - // Implement proof generation using RISC Zero / SP1 or any other provider + // Implement proof generation using RISC Zero with Boundless / SP1 or any other provider + // See https://docs.beboundless.xyz/ for production proving // ... } } @@ -59,7 +60,7 @@ environment. Below are the key steps to implement it effectively: 4. **Focus on Computation**: Use the Compute Provider package to handle additional tasks like Merkle tree verification and proof verification, so you can focus on your computation logic. -**Example (Rust with RISC Zero):** +**Example (Rust with RISC Zero + Boundless):** ```rust use fhe::bfv::{BfvParameters, Ciphertext}; diff --git a/examples/CRISP/Readme.md b/examples/CRISP/Readme.md index 617ba1a100..44e0f6c3ae 100644 --- a/examples/CRISP/Readme.md +++ b/examples/CRISP/Readme.md @@ -204,37 +204,52 @@ After deployment, you will see the addresses for the following contracts: - CRISP Input Validator Factory - CRISP Program -#### Step 3: RISC0 Setup (Optional) - -> Please note that this step is optional for development only. You can run the program server in dev -> mode which does not use Risc0. The smart contracts would have already been deployed at the -> previous step. - ---- +#### Step 3: Configure Boundless (Optional) + +> Please note that this step is optional for development only. By default, the program server runs +> in dev mode which uses fake proofs for fast local development. + +For production-grade zero-knowledge proofs with [Boundless](https://docs.beboundless.xyz/), update +the `enclave.config.yaml` file in the CRISP root directory: + +```yaml +program: + dev: false # Disable dev mode to use real proofs + risc0: + risc0_dev_mode: 0 # 0 = production (Boundless), 1 = dev mode + boundless: + rpc_url: 'https://sepolia.infura.io/v3/YOUR_KEY' # RPC endpoint + private_key: 'YOUR_PRIVATE_KEY' # Wallet with funds for proving + pinata_jwt: 'YOUR_PINATA_JWT' # Required for uploading programs to IPFS + program_url: 'https://gateway.pinata.cloud/ipfs/YOUR_CID' # Pre-uploaded program URL + onchain: true # true = onchain requests, false = offchain +``` -**Faster Proving w/ Bonsai** +> **_Note:_** For production proving with Boundless, you need: +> +> - An RPC endpoint (e.g., Infura, Alchemy) with funds +> - A private key with sufficient ETH/tokens for proof generation +> - A Pinata JWT for uploading programs to IPFS (get one at [pinata.cloud](https://pinata.cloud)) +> - Pre-uploaded program URL to avoid uploading the ~40MB program at runtime -The following steps are optional. You can config -[Bonsai](https://dev.risczero.com/api/generating-proofs/remote-proving) for faster proving. +### Uploading Your Program to IPFS -- Set up environment variables by creating a `.cargo` directory and `config.toml` file: +When you make changes to the guest program in `program/`, you need to upload it to IPFS: - ```sh - mkdir .cargo && cd .cargo && touch config.toml - ``` +1. Build and upload your program: -- Add the following configuration to `config.toml`: + ```bash + enclave program upload + ``` - > **_Note:_** _This requires having access to a Bonsai API Key. To request an API key - > [complete the form here](https://bonsai.xyz/apply)._ +2. The command outputs an IPFS hash. Update `enclave.config.yaml` with the full URL: - ```toml - [env] - BONSAI_API_KEY="your_api_key" - BONSAI_API_URL="your_api_url" - ``` + ```yaml + program_url: 'https://gateway.pinata.cloud/ipfs/QmXxx...' + ``` ---- +> **_Important:_** Every time you modify the guest program, rebuild and re-upload it to IPFS, then +> update the `program_url` in your configuration. #### Step 4: Set up Environment Variables diff --git a/examples/CRISP/program/README.md b/examples/CRISP/program/README.md index eed946beb9..63abac4784 100644 --- a/examples/CRISP/program/README.md +++ b/examples/CRISP/program/README.md @@ -18,12 +18,12 @@ graph TD server --HTTP--> program end subgraph thirdparty["3rd PARTY"] - bonsai + boundless end client --"HTTP"--> server - program ---> bonsai + program ---> boundless - bonsai["bonsai (risc0)"] + boundless["boundless (risc0)"] server --"publishInput()"--> evm subgraph evm["EVM"] diff --git a/tests/integration/enclave.config.yaml b/tests/integration/enclave.config.yaml index 4a5481c3a1..629a1bd097 100644 --- a/tests/integration/enclave.config.yaml +++ b/tests/integration/enclave.config.yaml @@ -21,9 +21,13 @@ chains: program: dev: true # risc0: - # risc0_dev_mode: 1 # 0 = real groth16 proofs, 1 = fake proofs (dev mode) - # bonsai_api_key: xxxxxxxxxxxxxxxx - # bonsai_api_url: xxxxxxxxxxxxxxxx + # risc0_dev_mode: 0 # 0 = production (Boundless), 1 = dev mode (fake proofs) + # boundless: + # rpc_url: "https://sepolia.infura.io/v3/YOUR_KEY" + # private_key: "PRIVATE_KEY" # Use env vars for secrets + # pinata_jwt: "PINATA_JWT" # For uploading programs + # program_url: "https://gateway.pinata.cloud/ipfs/QmNMRAB7DW43JSmENfzGmD96G6sqaeBBNfTVrrq5WQae3D" # Pre-uploaded program + # onchain: true # true = onchain requests, false = offchain nodes: cn1: