Set up CRISP
This page shows how to build CRISP and run it on a local chain. It is for developers who want to run
the reference application or change it. At the end, the full CRISP stack runs on your computer and
the client is at http://localhost:3000.
CRISP lives in its own repository, theinterfold/CRISP (opens in a new tab). It
builds against one released version of the Interfold, which interfold-release.json names. You do
not need a clone of the Interfold repository. Run all pnpm commands on this page from the root of
the CRISP repository.
Prerequisites
| Tool | Version | Used by |
|---|---|---|
| Git | Any | Clone |
| Rust (opens in a new tab) | 1.91.1 (rust-toolchain.toml) | Server, CLI, program, and runner. Also the interfold CLI, on a platform with no release binary. |
| Node.js (opens in a new tab) | 22.x (CI uses NODE_VERSION: 22) | Client, SDK, contracts, and scripts |
| pnpm (opens in a new tab) | 10.7.1 (packageManager in package.json) | All JavaScript packages |
| Foundry (opens in a new tab) | Any | anvil, the local chain that scripts/dev.sh starts |
yq (opens in a new tab) | Any | scripts/dev_cipher.sh reads node addresses from the config |
nargo (opens in a new tab) | v1.0.0-beta.26 (NOIR_TOOLCHAIN in CI) | Circuit builds in pnpm dev:setup and pnpm compile:circuits |
bb (opens in a new tab) | 5.2.0 (crates/zk/prover/versions.json of the Interfold release) | Verification keys and generated verifiers |
| Python 3 | Any | scripts/compile_circuits.sh patches the generated verifiers |
| A browser wallet, for example MetaMask (opens in a new tab) | Any | The client |
cargo-openvm v2.0.2 | v2.0.2 | Only for real OpenVM proofs (CRISP_REAL_PROOFS=1) |
Install nargo with noirup -v v1.0.0-beta.26. Other nargo versions can fail to compile the
circuits. OpenVM is not necessary for local development, because the local scripts start the program
server in dev mode unless CRISP_REAL_PROOFS=1.
Build and start CRISP
Clone the repository
git clone https://github.com/theinterfold/CRISP.git
cd CRISPChoose a local profile
This step is optional. pnpm dev:setup copies the example file when crisp.dev.env does not exist.
cp crisp.dev.env.example crisp.dev.envThe default profile uses the insecure-64 BFV preset and skips DKG proof aggregation. See
Local profile for the two settings.
Build everything
pnpm dev:setupscripts/setup.sh does these tasks in sequence:
- Installs the dependencies (
pnpm install --frozen-lockfile). - Builds the CRISP SDK (
pnpm build:sdk). This step takes the circuits of the pinned Interfold release, compiles the CRISP circuits, and stages the circuit presets. - Compiles the CRISP contracts (
pnpm compile:contracts). - Copies
server/.env.exampletoserver/.envwhenserver/.envdoes not exist. Then it builds thecliandserverbinaries. - Writes the
E3_PARAM_SETthat matches the profile intoserver/.env. - Copies
client/.env.exampletoclient/.envwhenclient/.envdoes not exist. - Installs the
interfoldCLI of the pinned release into~/.cargo/bin(see Interfold release). - Runs
interfold program compile, only whenCRISP_REAL_PROOFS=1.
At the end, the script prints the active profile under the heading CRISP dev profile.
Check the interfold binary
which interfoldMake sure that the path is ~/.cargo/bin/interfold (or the bin folder of your CARGO_HOME). The
CRISP scripts run the first interfold on your PATH.
Start all services
pnpm dev:upscripts/dev.sh starts the services in this order. The ciphernodes, the program server, the CRISP
server, and the client start after the contract deployment is complete.
| Service | Started by | Port |
|---|---|---|
| Anvil (chain ID 31337) | scripts/dev.sh | 8545 |
| Local randomness helper | scripts/anvil-randomness.mjs | None |
| Contract deployment | scripts/crisp_deploy.sh | None |
Ciphernodes cn1 to cn5 | scripts/dev_cipher.sh (interfold nodes up) | QUIC 9201 to 9205. cn1 dashboard 8080 |
| Program server | scripts/dev_program.sh (interfold program start) | 13151 |
| CRISP server | scripts/dev_server.sh (cargo run --bin server) | 4000 |
| Client | scripts/dev_client.sh (pnpm dev-static) | 3000 |
When dev_cipher.sh has registered the ciphernodes, it prints CIPHERNODES HAVE BEEN ADDED. and
writes the file .interfold/ready. The client starts after port 4000 is open and that file exists.
The client is then available at http://localhost:3000.
Each pnpm dev:up starts from an empty state. Anvil starts a new chain, dev_cipher.sh deletes
.interfold/data and .interfold/config, and dev_server.sh deletes server/database. When you
press Ctrl+C, the cleanup in dev.sh stops every process whose command line contains anvil or
interfold start. This includes processes that CRISP did not start.
The program server listens on 0.0.0.0:13151 and does not authenticate callers. It is a
development service. It must not be reachable from production or untrusted networks.
What the deployment does
scripts/crisp_deploy.sh sets PRIVATE_KEY to the first Anvil account, USE_MOCKS=true, and
DEPLOY_INTERFOLD=true. Then it runs pnpm deploy:contracts --network localhost. The deployment
includes these contracts:
- The Interfold contracts, with mock BFV verifiers for the DKG. With
CRISP_SKIP_PROOF_AGGREGATION=false, the script setsENABLE_ZK_VERIFICATION=true, and the deployment uses the real BFV verifiers. For these verifiers, the script extracts the circuit archive of the pinned Interfold release and setsINTERFOLD_CIRCUITS_DIR(see below). CRISPProgram, the two generated Noir ballot verifiers, andSelfRegistry.MockOpenVmReceiptVerifier(withCRISP_UNPROVED_TEST=1, which the local scripts set unlessCRISP_REAL_PROOFS=1),MockVotingToken, andMockCrispDataAvailabilityVerifier. WithCRISP_REAL_PROOFS=1, the deployment instead deploys the OpenVM receipt verifier for the guest thatinterfold program compilebuilt. On Sepolia,CRISP_UNPROVED_TEST=1deploys the mock verifier only withALLOW_SEPOLIA_UNPROVED_COMPUTE=true. On any chain other than the local chain (chain ID 31337) and Sepolia, the deployment refusesCRISP_UNPROVED_TEST=1.
After the deployment, the script writes the new contract addresses into three files. You do not copy addresses by hand:
interfold.config.yaml: thecontractsof thelocalhostchain.server/.env:INTERFOLD_ADDRESS,E3_PROGRAM_ADDRESS,CIPHERNODE_REGISTRY_ADDRESS,FEE_TOKEN_ADDRESS,CRISP_VOTING_TOKEN, and the mock contract references.client/.env:VITE_CRISP_TOKEN.
The deployment records are in packages/crisp-contracts/deployed_contracts.json. For the addresses
of the public networks, see Contract addresses.
CRISP deploys the Interfold contracts with the scripts of the published @interfold/contracts
package, not with a clone of the Interfold repository. Outside the Interfold monorepo, the real BFV
verifiers (ENABLE_ZK_VERIFICATION=true) read the verification key hashes of the BFV aggregation
circuits from the directory that INTERFOLD_CIRCUITS_DIR names. This directory must hold the
circuits of the same release as the package, in the release layout
(<preset>/<committee>/default/...). scripts/crisp_deploy.sh sets the variable to
circuits/interfold/release, which node scripts/interfold-release.mjs circuits writes from the
release archive. When you run pnpm deploy:contracts yourself with ENABLE_ZK_VERIFICATION=true,
set INTERFOLD_CIRCUITS_DIR to that directory. The deployment stops with an error when the variable
is not set.
Configuration
| File | Created by | Purpose |
|---|---|---|
crisp.dev.env | Copied from crisp.dev.env.example by the scripts | Local profile: BFV preset and proof aggregation mode |
interfold.config.yaml | Tracked in Git. The deployment updates addresses. | Ciphernode chains, contracts, program mode, and nodes |
server/.env | Copied from server/.env.example by dev:setup | Settings for the CRISP server and the CLI |
client/.env | Copied from client/.env.example by dev:setup | Settings for the client |
.env | Copied by hand from .env.example | Keys for scripts/setup_testnet.sh only |
interfold-release.json | Tracked in Git | The Interfold release that CRISP builds against |
Interfold release
interfold-release.json names the Interfold version and the SHA-256 digest of each release asset
that CRISP downloads: the interfold CLI and the circuit archive. scripts/interfold-release.mjs
refuses an asset when its digest does not match. The other dependencies name the same release in
their own files:
Cargo.tomlandguest/Cargo.toml: the Rust crates (e3-*), as Cargo git dependencies on the release tag.circuits/lib/Nargo.tomlandcircuits/bin/*/Nargo.toml: the Noir libraryinterfold_lib, as a Nargo git dependency on the release tag.package.jsonandpackages/crisp-contracts/package.json: the npm packages@interfold/configand@interfold/contracts.
To move to another release, follow the steps in the Interfold dependency section (opens in a new tab) of the CRISP Readme.
Local profile
scripts/lib/dev_config.sh reads crisp.dev.env:
| Variable | Default | Values | Effect |
|---|---|---|---|
CRISP_BFV_PRESET | insecure-64 | insecure-64, secure-8192 | BFV preset. Sets E3_PARAM_SET in server/.env to 0 or 2. |
CRISP_SKIP_PROOF_AGGREGATION | true | true, false | true: mock verifiers and no recursive DKG proofs. false: real verifiers, recursive circuits, and full proof aggregation. |
After you change crisp.dev.env, run pnpm dev:setup again, then pnpm dev:up. The ciphernodes
refuse the skip setting unless the interfold binary has the test-only-skip-proof-aggregation
Cargo feature. pnpm dev:setup selects that feature from the profile. With
CRISP_SKIP_PROOF_AGGREGATION=false, DKG takes minutes for each committee, because the ciphernodes
make recursive proofs.
~/.cargo/bin/interfold is shared. A pnpm dev:setup in another project, for example
templates/default, replaces the binary that this profile installed. When the ciphernodes then
exit at startup, dev_cipher.sh stops and prints the node status table.
interfold.config.yaml
This file configures the local ciphernodes and the program server. The excerpt shows the local chain and the first two nodes. The deployment updates the contract addresses.
chains:
- name: localhost
enabled: true
rpc_url: ws://localhost:8545
ingestion_confirmations: 0
rpc_poll_interval_ms: 250
data_availability:
mode: mock_http
rpc_url: http://127.0.0.1:4000/availability
contracts:
# e3_program, interfold, ciphernode_registry, bonding_registry,
# slashing_manager, and fee_token: updated by the deployment
program:
dev: false
nodes:
cn1:
quic_port: 9201
ctrl_port: 50501
autonetkey: true
autopassword: true
dashboard_port: 8080
cn2:
quic_port: 9202
ctrl_port: 50502
autonetkey: true
autopassword: true
peers:
- /ip4/127.0.0.1/udp/9201/quic-v1- The file also has
mainnetandsepoliachains withenabled: false. The data-availability mode ofmainnetisavail. Onsepoliait ismock_http, because Avail Turing is down. - Nodes
cn3tocn5use QUIC ports 9203 to 9205 and control ports 50503 to 50505. Each node peers withcn1. scripts/lib/dev_config.shsetsE3_PROGRAM__DEV=trueunlessCRISP_REAL_PROOFS=1, sopnpm dev:upruns the development runner by default although the file setsprogram.dev: false.
For all node configuration keys, see Configuration.
Server settings
The CRISP server and the CLI read server/.env. Each value can also come from the process
environment (server/src/config.rs).
| Variable | Local value or default | Purpose |
|---|---|---|
PRIVATE_KEY | First Anvil account | Server key. The CLI uses it to request rounds. The server uses it to relay inputs, post census roots, and sign availability promises. |
INTERFOLD_SERVER_URL | http://127.0.0.1:4000 | URL of this server. Remote cron targets must use HTTPS. |
HTTP_RPC_URL, WS_RPC_URL, CHAIN_ID | http://127.0.0.1:8545, ws://127.0.0.1:8545, 31337 | Chain access. At startup, the server stops if CHAIN_ID is not the chain of HTTP_RPC_URL. |
PROGRAM_SERVER_URL | http://127.0.0.1:13151 | Program server that runs the computation |
INTERFOLD_ADDRESS, E3_PROGRAM_ADDRESS, CIPHERNODE_REGISTRY_ADDRESS, FEE_TOKEN_ADDRESS, CRISP_VOTING_TOKEN | Written by the deployment | Contract addresses |
E3_DURATION | 300 in the example file | Length of the input window in seconds. On Avail networks, it includes the finalization tail. |
VOTING_START_BUFFER_SECONDS | 20 in the example file. Default 120. | Time for the request transaction to be mined before the input window starts |
E3_PARAM_SET | 0 | 0 is insecure-64, 2 is secure-8192. Ethereum mainnet requires 2. |
E3_COMMITTEE_SIZE | 0 | 0 is minimum (N = 3, T = 1), 1 is micro (N = 9, T = 4), 2 is small (N = 19, T = 9) |
E3_COMPUTE_PROVIDER_NAME, E3_COMPUTE_PROVIDER_PARALLEL, E3_COMPUTE_PROVIDER_BATCH_SIZE | OpenVM, false, 4 | Compute provider parameters sent with the request. The batch size must be a power of 2. |
DATA_AVAILABILITY_MODE | mock | mock or avail. Without a value, the mode is mock for chain IDs 31337 and 1337 and avail for other chains. mock is allowed only on those two chains and on Sepolia with ALLOW_SEPOLIA_MOCK_DATA_AVAILABILITY=true. |
AVAIL_RPC_URL, AVAIL_BRIDGE_API_URL, AVAIL_APP_ID, AVAIL_SEED | Empty | Avail access and the funded Avail account that pays for submit_data |
AVAIL_PROOF_LEAD_SECONDS | 10800 | Minimum time before the input deadline when an Avail publication starts. In Avail mode, it must equal CRISPProgram.availabilityFinalizationWindow(). |
DATA_AVAILABILITY_MAX_PENDING_BYTES | 1073741824 (1 GiB) | Limit for bytes held by unfinished availability jobs |
CRON_API_KEY | Empty | Secret for POST /rounds/request and the cron client. When it is empty, the endpoint is disabled. |
MAINNET_RELAY, RELAY_MAX_INPUTS_PER_SLOT, RELAY_MAX_INPUTS_PER_ROUND | false, 3, not set | Input relay within per-slot and per-round limits. Mainnet relays only when MAINNET_RELAY is true, which also needs RELAY_MAX_INPUTS_PER_ROUND and RELAY_MIN_BALANCE_ETH. |
RELAY_MIN_BALANCE_ETH | Not set | Stop relaying below this ETH amount, which keeps funds for finalizeInput. Required outside mainnet and local chains (0 for no floor). Mainnet relay needs more than 0. |
ETHERSCAN_API_KEY | Empty | Token holder lookup on non-local chains |
INDEX_START_BLOCK, INDEX_CHUNK_SIZE, INDEX_CONTRACTS, INDEX_LOG_CONTRACTS | Not set | Indexer backfill and the contracts that the read-only /chain/* routes serve. An empty INDEX_CONTRACTS denies all /chain/* reads. |
The relay limits in the table apply to one server instance. All server instances use the same server
key, but each instance counts only its own relays. Thus, when more than one instance relays, a slot
or a round can receive the limit from each instance. To keep one limit for the server key, let one
instance relay and set RELAY_MAX_INPUTS_PER_SLOT to 0 on all other instances. Move the relay to
another instance only when no round is open. A ballot that a non-relaying instance receives uses the
voter's wallet. Also, only the instance that receives a ballot holds its job. Thus, send all client
requests to the relaying instance, for example with VITE_INTERFOLD_API. When a limit is reached,
the voter's wallet sends the input.
The server records its relays in database/server in its working directory, and its limits count
only these records. The server also records the time when this relay record starts. It writes that
time when it starts on a database without that time, for example a new database. A round that is
already open at that time uses the voter's wallet for all of its inputs, because the server cannot
count the relays that occurred before. Keep this directory when you replace or move the server.
The local PRIVATE_KEY is a public Anvil test key. Never use it on a live network. Funds sent to
its address on a live network can be lost.
Client settings
Vite reads client/.env when the client starts or builds.
| Variable | Local value | Purpose |
|---|---|---|
VITE_INTERFOLD_API | http://127.0.0.1:4000 | CRISP server URL |
VITE_CHAIN_ID | 31337 | Chain that the client asks the wallet to use |
VITE_RPC_URL | http://127.0.0.1:8545 | Chain RPC |
VITE_WALLETCONNECT_PROJECT_ID | Empty | WalletConnect. Without it, only injected wallets work. |
VITE_CRISP_TOKEN | Written by the deployment | Voting eligibility token (MockVotingToken locally) |
VITE_E3_REQUESTERS | First two Anvil accounts | Comma-separated requester addresses. The client shows rounds from these requesters. |
VITE_ENABLE_TEST_TOKEN_MINT | true | Shows the + Mint test tokens button on test networks. It is always off on mainnet. |
Real proofs with OpenVM
By default, the local scripts run the development runner, which makes no proof. To prove rounds with
OpenVM on your machine, build the workers and set the program section of interfold.config.yaml
(see Compute Provider):
program:
dev: false
openvm:
prover_bin: /opt/openvm/interfold-openvm-prover
prover_bin_cuda: /opt/openvm/interfold-openvm-prover-cuda # optional
backend: auto # a working GPU when there is one, the CPU otherwiseThen set CRISP_REAL_PROOFS=1 in crisp.dev.env and run pnpm dev:setup again. With it,
interfold program compile builds guest/ and its keys, the deployment deploys the receipt
verifier for that guest, and interfold program start serves real proofs. A changed program or
policy has a new receipt identity, so compile and deploy again after you change either.
Run single components
pnpm dev:up runs all services together. To run them one at a time, open a terminal for each
command and run the commands in this order from the root of the CRISP repository:
# 1. Local chain
anvil --host 0.0.0.0 --chain-id 31337 --block-time 1 --mnemonic 'test test test test test test test test test test test junk'
# 2. Fulfill randomness requests of the mock provider in a later block
node ./scripts/anvil-randomness.mjs
# 3. Deploy the contracts and sync the addresses
./scripts/crisp_deploy.sh
# 4. Start and register the ciphernodes. The argument is the ready file.
./scripts/dev_cipher.sh ./.interfold/ready
# 5. Program server (port 13151)
./scripts/dev_program.sh
# 6. CRISP server (port 4000)
./scripts/dev_server.sh
# 7. Client (port 3000)
./scripts/dev_client.shWithout step 2, the committee is not selected, because the mock randomness provider does not fulfill its own requests.
Scripts
These scripts are defined in package.json of the CRISP repository.
| Script | What it does |
|---|---|
pnpm dev:setup | Runs scripts/setup.sh: installs, builds, and creates the .env files |
pnpm dev:up | Runs scripts/dev.sh: starts the full local stack |
pnpm cli | Runs target/debug/cli with the arguments that you give |
pnpm compile:circuits | Compiles the Noir circuits and writes the verifiers to packages/crisp-contracts/contracts/verifiers |
pnpm compute:vk-hash <preset> | Prints the key hash that each fold circuit binds for one BFV preset. Run it after you change a ballot circuit or move to another Interfold release. |
pnpm build:runner-image | Builds the e3-support program runner image from runner/Dockerfile. With --push, it also pushes the image. |
pnpm openvm <task> | Runs a task of scripts/openvm.sh, for example service-build, service-start, fixture, or guest-parity |
pnpm compile:contracts | Compiles the CRISP contracts with Hardhat |
pnpm build:sdk, pnpm build:presets | Builds the SDK, or compiles and stages the circuit presets |
pnpm deploy:contracts, pnpm deploy:contracts:mock, pnpm deploy:contracts:full, pnpm deploy:contracts:full:mock | Deploys the CRISP contracts. mock sets USE_MOCKS=true, which mocks the token and data availability, not compute. full adds the Interfold contracts. |
pnpm ciphernode:add, pnpm ciphernode:add:self, pnpm ciphernode:mint:tokens | Hardhat tasks that register ciphernodes or mint tokens for them |
pnpm setup:testnet | Starts cn1 to cn5, mints tokens for them, and registers them on Sepolia with the keys in .env. Then it starts the program server and the CRISP server. |
pnpm publish:packages | Publishes the CRISP packages to npm (--channel prod or --channel testing) |
pnpm lint | Runs ESLint |
Run the tests
| Command | What it tests |
|---|---|
pnpm test:e2e (also pnpm test) | The full stack in a browser. See End-to-end test. |
pnpm test:contracts | All CRISP contract tests (Hardhat and Mocha) |
pnpm test:contracts:unit | Census modes, journal, input availability, input leaf, Interfold binding, SelfRegistry, and tally decoding |
pnpm test:contracts:input-tree, pnpm test:contracts:input-tree:poisoned-parent, pnpm test:contracts:input-tree:canonical | The end-to-end input tree test, in full or in parts |
pnpm test:contracts:ballots:program, pnpm test:contracts:ballots:census | Ballots against CRISPProgram, and ballots in an on-chain census round |
pnpm test:circuits | nargo test in circuits/lib |
pnpm test:sdk | SDK tests with Vitest. The script first stages the insecure-64 preset. |
End-to-end test
pnpm test:e2e runs scripts/test_e2e.sh. The script starts scripts/dev.sh, waits for port 3000
and the .interfold/ready file, and then runs Synpress and Playwright. The test does these steps:
- Requests a round with
target/debug/cli init. - Connects MetaMask to the client and waits for the committee key.
- Casts a vote and waits until
CRISPProgramrecords it. - Moves the Anvil time past the input deadline.
- Waits until the E3 stage is
Complete, then checks the result on theAll Pollspage.
Set CRISP_E2E_DURATION_SECS to change the input window of the test (default 300 seconds). Add
--ui (pnpm test:e2e --ui) to run the Synpress wallet setup without --headless. On Linux, the
script runs Playwright with xvfb-run. Run pnpm report to open the Playwright report.
Compact the server database
The CRISP server keeps its database in database/server below its working directory. In the
crisp-server image, the working directory is /, so the database is /database/server. sled
keeps old copies of changed pages on disk until it cleans its log. To recover that space, copy the
database while the server is stopped. The copy leaves out the old copies. It can still be up to
about three times the size of the current data, because sled writes pages again while it builds the
copy.
-
Stop the CRISP server.
-
In the server's working directory, run the
serverbinary withcompact-database. A source build puts the binary intarget/releaseortarget/debugbelow the root of the CRISP repository:server compact-database database/server database/server-compactWith the image, give the same arguments to the image and mount the volume that holds
/database:docker run --rm -v <volume>:/database <crisp-server image> compact-database /database/server /database/server-compact -
Move
database/serverto a backup location. -
Rename
database/server-compacttodatabase/server. -
Start the CRISP server.
-
When the server works correctly, run
syncon the host. -
Delete the backup.
The command builds the copy in the target path with .partial added, for example
database/server-compact.partial. It gives the copy the target name only when the copy is complete,
matches the database, and is on the disk. The command stops without a copy when the target directory
or the .partial directory exists, when the directory that holds the target does not exist, or when
the source directory holds no database. It also stops when the server holds the database, when the
copy does not match the database, or when the disk is full. After a failed command, delete the
.partial directory before you run the command again.
The operating system can keep the moves of steps 3 and 4 in memory for some time before it writes
them to the disk. The server reads from that memory, so a working server does not show that the disk
holds the copy. sync makes the operating system write that data to the disk.
Upgrade from a release that keeps ballots in the round record
At its first start, the server moves the ballots out of the round records. An older release cannot read the moved ballots. Before you upgrade:
- Stop the server and copy
database/server. - If the disk has little free space, compact the database. The first start writes each moved ballot again before it removes the old copy. The command also works on the database of an older release.
To go back to the older release, restore the copy, but only before the new release accepts a ballot.
The copy does not hold the availability jobs of later ballots, so their inputs would stay committed
but unpublished. After the new release accepts ballots, fix forward. In avail mode, you can also
go back when none of the availability jobs of the new release is pending: the older release reads
the published ballots again from Avail. In mock mode, the server can read a ballot only from its
database. The restored copy does not hold the ballots that the new release accepted, so those
ballots are lost.
Common setup errors
| Symptom | Cause | Fix |
|---|---|---|
dev_cipher.sh prints ERROR: only <n>/<m> ciphernodes stayed up | The interfold binary does not match the profile, or another node error. | Read the node output above the table. For a missing Cargo feature, run pnpm dev:setup again. |
Invalid CRISP_BFV_PRESET or Invalid CRISP_SKIP_PROOF_AGGREGATION | A value in crisp.dev.env is not allowed. | Use insecure-64 or secure-8192, and true or false. |
The server stops at startup with DATA_AVAILABILITY_MODE=mock is allowed only on local development chains | CHAIN_ID is not 31337 or 1337 and the mode is mock. | Set DATA_AVAILABILITY_MODE=avail and the Avail settings. On Sepolia, you can set ALLOW_SEPOLIA_MOCK_DATA_AVAILABILITY=true. |
The server stops at startup with Ethereum mainnet requires E3_PARAM_SET=2 (secure-8192) | CHAIN_ID=1 with E3_PARAM_SET=0. | Set E3_PARAM_SET=2. |
The server stops at startup with CHAIN_ID (…) does not match the chain of HTTP_RPC_URL (…) | HTTP_RPC_URL serves a different chain. | Use an RPC for the chain in CHAIN_ID, or correct CHAIN_ID. |
The server stops at startup with RELAY_MIN_BALANCE_ETH is required outside local chains… | RELAY_MIN_BALANCE_ETH is empty outside mainnet and local chains. | Set the balance that finalizeInput needs, or 0 to relay without a floor. |
interfold-release.mjs prints SHA-256 is <digest>, interfold-release.json pins <digest> | A downloaded release asset does not match its digest in interfold-release.json. | Download the asset again. When the digests still differ, correct the digest in interfold-release.json. |