Skip to content

feat: upgrade to hardhat v3 and configure repo#677

Merged
ctrlc03 merged 15 commits into
mainfrom
feat/hardhat-v3
Sep 11, 2025
Merged

feat: upgrade to hardhat v3 and configure repo#677
ctrlc03 merged 15 commits into
mainfrom
feat/hardhat-v3

Conversation

@ctrlc03

@ctrlc03 ctrlc03 commented Sep 5, 2025

Copy link
Copy Markdown
Collaborator

fix #663

  • Migrate to v3
  • Store addresses, block and args to a json file for later use
  • CRISP configured to use viem whereas enclave contracts use ethers

More details:

  • Remove dependency of hardhat-deploy in favour of using ignition and ethers. The new version of hardhat-deploy that works with hardhat v3 has several more external dependencies (as well as it being community maintained).
  • All deployments get stored to a json file categorized by the network they are deployed to. This prevents redeployment and allows us to save the arguments and addresses for later use (such as verification). A task to clean the file is added (utils:clean-deployments --chain $CHAIN )
  • We are using ethers in enclave and template but viem on CRISP - we should discuss which option is better for the future, both work fine
  • Tests (e2e and integration) cleanup localhost deployments and deployed_contracts.json (localhost only) to start fresh

Summary by CodeRabbit

  • New Features
    • One‑click enclave + mock deployment flow, deploy/save helpers, and new CLI tasks for ciphernode and E3 lifecycle (enable/activate/publish).
  • Refactor
    • Upgraded toolchain to Hardhat v3, ES module packaging, consolidated type outputs to ./types, and revamped build/deploy scripts.
  • Chores
    • CI simplified and Node bumped to 22; example env/config addresses updated; .gitignore adjusted.
  • Tests
    • Tests moved to ignition-driven deployments and Vitest for integration; large E2E tests simplified.

@vercel

vercel Bot commented Sep 5, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
crisp Ready Ready Preview Comment Sep 11, 2025 3:25pm
enclave-docs Ready Ready Preview Comment Sep 11, 2025 3:25pm

@coderabbitai

coderabbitai Bot commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Repository-wide migration to Hardhat v3 and Ignition: replaces hardhat-deploy scripts/fixtures with Ignition modules and deploy-and-save scripts, centralizes runtime deployments in deployed_contracts.json, updates CI (removes TypeChain steps, bumps Node), adjusts Docker/Rust entrypoint to read the single manifest, migrates tests/tasks/templates/CRISP to v3 tooling, and reorganizes packaging/exports for packages/enclave-contracts.

Changes

Cohort / File(s) Summary
CI workflows & Node
.github/workflows/ci.yml
Removed TypeChain generation steps across CI jobs; replaced one run with a prebuild step; changed TypeChain outputs used in artifact uploads; bumped Node.js setup where noted.
Rust Docker & entrypoint
crates/Dockerfile, crates/entrypoint/build.rs
Dockerfile now copies a single deployed_contracts.json; build.rs reads that JSON (networks→contracts→(address,blockNumber)) to generate CONTRACT_DEPLOYMENTS.
Monorepo scripts & root package
package.json, packages/enclave-sdk/package.json
Removed top-level TypeChain scripts, added evm:deploy/evm:clean, updated SDK prebuild to run enclave-contracts build.
enclave-contracts core: config & packaging
packages/enclave-contracts/hardhat.config.cts (removed), packages/enclave-contracts/hardhat.config.ts, packages/enclave-contracts/package.json, packages/enclave-contracts/tsconfig.json, packages/enclave-contracts/tsup.config.mjs (removed), .gitignore
Replaced old Hardhat config with v3 + Ignition config, set package "type":"module", changed exports to dist/scripts/types/ignition modules, emit types/outDir, removed old tsup config, ignore ignition deployments.
Ignition modules added
packages/enclave-contracts/ignition/modules/*
Added modules for Enclave, CiphernodeRegistry, NaiveRegistryFilter, PoseidonT3 and mock modules (MockComputeProvider, MockDecryptionVerifier, MockInputValidator, MockE3Program, mock variants).
Deployment registry & helpers
packages/enclave-contracts/deployed_contracts.json, packages/enclave-contracts/scripts/**, packages/enclave-contracts/scripts/utils.ts
Introduced deployed_contracts.json (manifest) and many deploy-and-save helpers (deployEnclave, deployMocks, deployAndSave* scripts) plus utilities to read/store/clean deployments.
Removed Hardhat-deploy artifacts & scripts
packages/enclave-contracts/deploy/*.ts (deleted), packages/enclave-contracts/deployments/sepolia/** (deleted)
Deleted legacy Hardhat-deploy scripts and Sepolia deployment/artifact snapshots; replaced by ignition + JSON registry approach.
Tasks: rewrite & new
packages/enclave-contracts/tasks/{ciphernode,enclave,utils}.ts, packages/enclave-contracts/tasks/accounts.ts (removed)
Rewrote tasks to option-based API, runtime resolution via readDeploymentArgs/ignition; added enclave tasks (enableE3, publish*, activateE3, requestCommittee) and ciphernode tasks; removed old accounts task; added utils:clean-deployments.
Tests: fixtures → Ignition
packages/enclave-contracts/test/**, packages/enclave-contracts/test/fixtures/* (removed)
Tests migrated to ignition-based deployments; fixtures removed; TypeChain factory usage adapted to ignition-deployed addresses; tests simplified/rewired.
Contracts & artifacts
packages/enclave-contracts/contracts/**, packages/enclave-contracts/artifacts/**
Minor Solidity doc/import fixes and a small redundant write removal; artifacts recompiled/updated to hh3-artifact-1 with added metadata and new bytecode for some contracts.
Examples (CRISP) & templates
examples/CRISP/**, templates/default/**
CRISP example migrated to Hardhat v3/viem and updated devDeps, tsconfigs, envs, simplified tests; templates modernized to ignition, Vitest, updated deploy templates and deployed_contracts.json template; minor RISC0 import fixes.
Integration/test scripts
tests/integration/{base.sh,persist.sh,fns.sh}, tests/integration/enclave.config.yaml
Integration helpers now run pnpm evm:clean and pnpm evm:deploy --network localhost before tests; updated addresses and cleanup/kill commands.
Misc SDK formatting & tsup aliases
packages/enclave-sdk/src/contract-client.ts, packages/enclave-sdk/tsup.config.js, templates/default/.gitignore
Minor formatting change, adjusted tsup alias paths for wasm init, unified TypeChain output ignore to /types.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev
  participant Script as deployEnclave.ts
  participant Ignition
  participant Enclave
  participant Registry as CiphernodeRegistry
  participant Filter as NaiveRegistryFilter
  opt withMocks
    participant Mocks
  end

  Dev->>Script: run()
  Script->>Ignition: deploy Enclave(params, owner, maxDuration, registry)
  Ignition-->>Enclave: deployed address
  Script->>Ignition: deploy CiphernodeRegistry(owner, enclave)
  Ignition-->>Registry: deployed address
  Script->>Ignition: deploy NaiveRegistryFilter(owner, registry)
  Ignition-->>Filter: deployed address
  Script->>Enclave: setCiphernodeRegistry(if needed)
  alt withMocks
    Script->>Ignition: deploy mock contracts
    Ignition-->>Mocks: mock addresses
    Script->>Enclave: setDecryptionVerifier / enableE3Program
  end
  Script-->>Dev: persist addresses to deployed_contracts.json
Loading
sequenceDiagram
  autonumber
  actor User
  participant Client
  participant NaiveRegistryFilter
  participant CiphernodeRegistry

  User->>Client: publishCommittee(e3Id, nodes, publicKey)
  Client->>NaiveRegistryFilter: publishCommittee(e3Id, nodes, publicKey)
  Note right of NaiveRegistryFilter: compute publicKey hash\nstore committee data
  NaiveRegistryFilter->>CiphernodeRegistry: publishCommittee(e3Id, abi.encode(nodes), publicKey)
  CiphernodeRegistry-->>NaiveRegistryFilter: tx ack
  NaiveRegistryFilter-->>Client: tx receipt
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • ryardley
  • 0xjei
  • hmzakhalid

Pre-merge checks (4 passed, 1 inconclusive)

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes Check ❓ Inconclusive Most edits align with the Hardhat v3 migration, but the PR also removes many sepolia deployment artifacts, deletes numerous test fixtures, and replaces a large end-to-end CRISP contract test with a minimal smoke test; these removals affect historical artifacts and test coverage and it is not explicit whether that reduction is intentional, so I cannot conclusively determine they are fully in-scope. Because those deletions impact reproducibility and regression surface, please confirm intent and rationale for removing artifacts/fixtures and for the large test simplification. Author should confirm and document that deleting the sepolia deployment artifacts, test fixtures, and the large contract test is intentional; if not intentional, restore or archive those files and re-run CI and integration tests to ensure coverage and reproducibility are preserved.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat: upgrade to hardhat v3 and configure repo" is concise and accurately summarizes the primary change—migrating the repository to Hardhat v3 and applying related repo configuration updates—and matches the scope and intent visible in the diff (configs, tasks, scripts, and tests). It is specific enough for history scanning and avoids noise.
Linked Issues Check ✅ Passed The changes implement the Hardhat v3 migration requested in linked issue [#663]: CRISP updates are present (examples/CRISP configs, deps, and tests) and the evm work includes ignition modules, new deployment scripts, rewritten tests, task implementations, deployment persistence (deployed_contracts.json and store/read utilities), and entrypoint/Dockerfile updates to consume that manifest, which together map to the issue checklist (CRISP, evm deployment, evm tests, tasks, entrypoint). The code-level changes shown in the diff directly address the listed objectives. I recommend running full CI and a local integration run to validate runtime behavior before merging.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

A rabbit taps the JSON log with care,
Ignition sparks and deployments scent the air.
Tasks hop tidy, modules line the way,
Types nestle safe inside the /types array.
Hardhat v3 blooms — we nibble, build, and play. 🐇✨

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/hardhat-v3

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Sep 8, 2025

Copy link
Copy Markdown
Contributor

License Header Check Failed

Some files are missing the required SPDX license header. Please add the following header to the beginning of all .js, .jsx, .nr, .rs, .sol, .ts, and .tsx files:

// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

You can run ./scripts/check-license-headers.sh --fix locally to automatically add missing headers, then commit the changes.

Or run ./scripts/check-license-headers.sh to see which files need headers.

@github-actions

github-actions Bot commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

License Header Check Failed

Some files are missing the required SPDX license header. Please add the following header to the beginning of all .js, .jsx, .nr, .rs, .sol, .ts, and .tsx files:

// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

You can run ./scripts/check-license-headers.sh --fix locally to automatically add missing headers, then commit the changes.

Or run ./scripts/check-license-headers.sh to see which files need headers.

@github-actions

github-actions Bot commented Sep 9, 2025

Copy link
Copy Markdown
Contributor

License Header Check Failed

Some files are missing the required SPDX license header. Please add the following header to the beginning of all .js, .jsx, .nr, .rs, .sol, .ts, and .tsx files:

// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

You can run ./scripts/check-license-headers.sh --fix locally to automatically add missing headers, then commit the changes.

Or run ./scripts/check-license-headers.sh to see which files need headers.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 49

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
packages/enclave-contracts/test/CiphernodeRegistry/NaiveRegistryFilter.spec.ts (6)

139-146: No-op assertion

expect(await registry.requestCommittee(...)) doesn’t assert anything. Either assert non-reversion or events.

-expect(
-  await registry.requestCommittee(
-    request.e3Id,
-    request.filter,
-    request.threshold,
-  ),
-);
+await expect(
+  registry.requestCommittee(
+    request.e3Id,
+    request.filter,
+    request.threshold,
+  ),
+).to.not.be.reverted;

161-167: Repeat: assert something meaningful

Same issue as above.

-expect(
-  await registry.requestCommittee(
-    request.e3Id,
-    request.filter,
-    request.threshold,
-  ),
-);
+await expect(
+  registry.requestCommittee(
+    request.e3Id,
+    request.filter,
+    request.threshold,
+  ),
+).to.not.be.reverted;

178-185: Repeat: assert something meaningful

Same fix.

-expect(
-  await registry.requestCommittee(
-    request.e3Id,
-    request.filter,
-    request.threshold,
-  ),
-);
+await expect(
+  registry.requestCommittee(
+    request.e3Id,
+    request.filter,
+    request.threshold,
+  ),
+).to.not.be.reverted;

195-201: Repeat: assert something meaningful

Same fix.

-expect(
-  await registry.requestCommittee(
-    request.e3Id,
-    request.filter,
-    request.threshold,
-  ),
-);
+await expect(
+  registry.requestCommittee(
+    request.e3Id,
+    request.filter,
+    request.threshold,
+  ),
+).to.not.be.reverted;

212-218: Repeat: assert something meaningful

Same fix.

-expect(
-  await registry.requestCommittee(
-    request.e3Id,
-    request.filter,
-    request.threshold,
-  ),
-);
+await expect(
+  registry.requestCommittee(
+    request.e3Id,
+    request.filter,
+    request.threshold,
+  ),
+).to.not.be.reverted;

256-261: No-op assertion on publishCommittee

The expect(...) doesn’t assert; just await the tx or assert events.

-expect(
-  await filter.publishCommittee(
-    request.e3Id,
-    [AddressOne, AddressTwo],
-    AddressThree,
-  ),
-);
+await filter.publishCommittee(
+  request.e3Id,
+  [AddressOne, AddressTwo],
+  AddressThree,
+);
🧹 Nitpick comments (56)
packages/enclave-sdk/src/contract-client.ts (1)

95-122: LGTM on the formatting; consider a tiny robustness tweak.

  • No functional changes detected in the simulate path; looks good.
  • Nit: prefer nullish coalescing for value to avoid boolean coercion semantics.

Apply this minimal diff:

-        value: value || BigInt(0),
+        value: value ?? 0n,
templates/default/server/index.ts (2)

301-312: Duplicate route registration for /sessions

The handler is registered twice; keep one to avoid accidental middleware/order surprises.

 app.post("/", handleWebhookRequest);
 app.get("/sessions", handleGetSessions);
 
 // This allows us to test interaction between server and program
 // TEST_MODE=1 pnpm dev:server
 if (process.env.TEST_MODE) {
   app.get("/test", handleTestInteraction);
 }
 
-app.get("/sessions", handleGetSessions);

141-163: Potential leak: currentlyActivating Map never cleared

After resolving, delete the entry to prevent unbounded growth across runs.

   if (!e3Sessions.has(sessionKey)) {
     const sdk = await createPrivateSDK();
     console.log("📡 Fetching E3 data from contract...");
 
     const e3 = await sdk.getE3(e3Id);
     console.log("✅ Received E3 data from contract.");
 
     e3Sessions.set(sessionKey, {
       e3Id,
       e3ProgramParams: e3.e3ProgramParams,
       expiration,
       inputs: [],
       isProcessing: false,
       isCompleted: false,
     });
     def.resolve();
+    currentlyActivating.delete(e3Id);
   }
packages/enclave-contracts/contracts/Enclave.sol (1)

170-178: Minor: avoid double map lookup

Use the cached variable for clarity and tiny gas/readability wins.

-        require(
-            decryptionVerifiers[encryptionSchemeId] !=
-                IDecryptionVerifier(address(0)),
-            InvalidEncryptionScheme(encryptionSchemeId)
-        );
+        require(
+            decryptionVerifier != IDecryptionVerifier(address(0)),
+            InvalidEncryptionScheme(encryptionSchemeId)
+        );
tests/integration/base.sh (1)

3-3: Add pipefail for safer bash erroring

Prevents hidden failures in piped commands.

-set -eu  # Exit immediately if a command exits with a non-zero status
+set -euo pipefail  # Exit on error, unset vars, and fail on pipeline errors
tests/integration/persist.sh (1)

3-3: Harden shell options

Match other scripts with pipefail for robustness.

-set -eu  # Exit immediately if a command exits with a non-zero status
+set -euo pipefail  # Exit on error, unset vars, and fail on pipeline errors
packages/enclave-sdk/package.json (1)

23-23: Prefer workspace-aware prebuild to avoid brittle cd paths

Use pnpm’s workspace flags so the script works regardless of where it’s invoked.

Apply:

-    "prebuild": "cd ../enclave-contracts && pnpm build && cd ../../crates/wasm && pnpm build",
+    "prebuild": "pnpm -w --filter @enclave-e3/contracts build && pnpm -w --filter @enclave-e3/wasm build",

Please confirm @enclave-e3/contracts’ build runs Hardhat compile (artifacts + types) so SDK consumers get everything they need.

.github/workflows/ci.yml (2)

351-351: Node 22: ensure toolchain support + unify setup-node versions

Hardhat v3 and Ignition should support Node 22, but please double-check locally/CI. Also, other jobs still use actions/setup-node@v3; consider standardizing on @v4 across the workflow for consistency.


535-547: Fail CI when SDK artifacts are missing

Uploading SDK artifacts with if-no-files-found: warn can hide regressions (e.g., missing types/artifacts after the v3 migration).

Apply:

       - name: "Upload SDK artifacts"
         uses: actions/upload-artifact@v4
         with:
           name: sdk-artifacts
           path: |
             packages/enclave-sdk/dist
             packages/enclave-contracts/dist
             packages/enclave-contracts/artifacts
             packages/enclave-contracts/cache
             packages/enclave-contracts/types
             crates/wasm/dist
-          retention-days: 1
-          if-no-files-found: warn
+          retention-days: 1
+          if-no-files-found: error
packages/enclave-contracts/ignition/modules/mockCiphernodeRegistryEmptyKey.ts (1)

7-7: Drop any-cast; rely on Ignition types

The module is already correctly typed by buildModule; the any cast and eslint disable are unnecessary.

Apply:

-/* eslint-disable @typescript-eslint/no-explicit-any */
 import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
 
 export default buildModule("MockCiphernodeRegistryEmptyKey", (m) => {
   const mockCiphernodeRegistryEmptyKey = m.contract(
     "MockCiphernodeRegistryEmptyKey",
   );
 
   return { mockCiphernodeRegistryEmptyKey };
-}) as any;
+});

Also applies to: 10-16

tests/integration/fns.sh (1)

55-57: Prefer graceful termination before SIGKILL

Try TERM first and fall back to KILL to avoid leaving temp files/locks.

Apply:

-    pkill -9 -f "target/debug/enclave" || true
-    pkill -9 -f "hardhat" || true
+    pkill -TERM -f "target/debug/enclave" || true
+    pkill -TERM -f "hardhat" || true
+    sleep 1
+    pkill -KILL -f "target/debug/enclave" || true
+    pkill -KILL -f "hardhat" || true
-  echo "Killing enclave"
-  pkill -9 -f "target/debug/enclave" || true
-  pkill -9 -f "enclave start" || true
-  pkill -9 -f "hardhat" || true
+  echo "Killing enclave"
+  pkill -TERM -f "target/debug/enclave" || true
+  pkill -TERM -f "enclave start" || true
+  pkill -TERM -f "hardhat" || true
+  sleep 1
+  pkill -KILL -f "target/debug/enclave" || true
+  pkill -KILL -f "enclave start" || true
+  pkill -KILL -f "hardhat" || true

Also applies to: 176-181

packages/enclave-contracts/tsconfig.json (2)

5-6: Confirm bundler resolution works with Hardhat v3/ts-node

"module: ESNext" + "moduleResolution: bundler" can trip ts-node/Hardhat plugins. If you hit import resolution issues, switch to NodeNext.

-    "module": "ESNext",
-    "moduleResolution": "bundler",
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",

11-12: Avoid emitting declarations for tests/scripts/tasks

With declaration emit enabled and tests/scripts in "include", you'll fill dist/ with d.ts for non-publishable files. Prefer a dedicated build tsconfig.

Option A (keep current tsconfig for IDE, add build config):

// packages/enclave-contracts/tsconfig.build.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "noEmit": false,
    "emitDeclarationOnly": true,
    "outDir": "dist"
  },
  "include": ["src/**/*.ts", "types/**/*.ts"],
  "exclude": ["test", "tests", "scripts", "tasks", "ignition/modules"]
}

Run builds with: tsc -p tsconfig.build.json.

Also applies to: 14-21

templates/default/tsconfig.json (2)

17-18: Redundant test globs

Both test/** and tests/** are included. Keep one (prefer tests/**).

-    "test/**/*.ts",
-    "tests/**/*.ts",
+    "tests/**/*.ts",

5-6: Sanity-check bundler resolution for template consumers

If downstream users run Hardhat/ts-node directly, bundler resolution can be brittle. If issues arise, recommend NodeNext for broader compatibility.

-    "module": "ESNext",
-    "moduleResolution": "bundler",
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",
tests/integration/enclave.config.yaml (1)

5-7: De-duplicate sources of truth for addresses

Consider generating this from packages/enclave-contracts/deployed_contracts.json (or validating against it in CI) to avoid drift.

I can add a small script to sync/validate if you’d like.

examples/CRISP/client/.env.example (1)

4-5: Satisfy dotenv-linter: order keys and quote values

Sort keys and quote 0x values.

-VITE_ENCLAVE_API=http://127.0.0.1:4000
-VITE_TWITTER_SERVERLESS_API=
-VITE_WALLETCONNECT_PROJECT_ID=
-VITE_E3_PROGRAM_ADDRESS=0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1 # Default E3 program address from anvil
-VITE_SEMAPHORE_ADDRESS=0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE
+VITE_E3_PROGRAM_ADDRESS="0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" # Default E3 program address from anvil
+VITE_ENCLAVE_API=http://127.0.0.1:4000
+VITE_SEMAPHORE_ADDRESS="0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE"
+VITE_TWITTER_SERVERLESS_API=
+VITE_WALLETCONNECT_PROJECT_ID=
crates/Dockerfile (1)

35-35: Add fail-fast check for deployed_contracts.json in crates/Dockerfile

crates/entrypoint/build.rs references ../../packages/enclave-contracts/deployed_contracts.json (confirmed). Add a quick runtime check so Docker builds fail early if the file is missing/empty:

 COPY --from=evm-builder /build/packages/enclave-contracts/artifacts ../packages/enclave-contracts/artifacts
 COPY --from=evm-builder /build/packages/enclave-contracts/deployed_contracts.json ../packages/enclave-contracts/deployed_contracts.json
+RUN test -s ../packages/enclave-contracts/deployed_contracts.json || (echo "deployed_contracts.json missing or empty" >&2; exit 1)
examples/CRISP/server/.env.example (1)

14-16: Fix dotenv lint warnings (quotes/order) and keep addresses unquoted

Remove quotes to satisfy QuoteCharacter; optionally order keys before ENCLAVE_ADDRESS per linter.

Apply this diff:

-ENCLAVE_ADDRESS="0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512"
-CIPHERNODE_REGISTRY_ADDRESS="0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9"
-NAIVE_REGISTRY_FILTER_ADDRESS="0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9"
-E3_PROGRAM_ADDRESS="0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1" # CRISPProgram Contract Address
+E3_PROGRAM_ADDRESS=0x4ed7c70F96B99c776995fB64377f0d4aB3B0e1C1 # CRISPProgram Contract Address
+CIPHERNODE_REGISTRY_ADDRESS=0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
+NAIVE_REGISTRY_FILTER_ADDRESS=0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9
+ENCLAVE_ADDRESS=0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
packages/enclave-contracts/ignition/modules/naiveRegistryFilter.ts (2)

7-7: Drop unnecessary eslint disable

The explicit-any disable is only needed because of the cast below; removing both improves lint hygiene.

Apply this diff:

-/* eslint-disable @typescript-eslint/no-explicit-any */

10-20: Prefer typed module export; avoid as any

Ignition’s buildModule returns a properly typed definition; the cast is unnecessary. Keep the export typed and remove the cast.

Apply this diff:

-export default buildModule("NaiveRegistryFilter", (m) => {
+export default buildModule("NaiveRegistryFilter", (m) => {
@@
-  return { naiveRegistryFilter };
-}) as any;
+  return { naiveRegistryFilter };
+});

If TS complains, confirm @nomicfoundation/hardhat-ignition types are v3 and that tsconfig excludes ESM interop issues.

templates/default/scripts/dev_ciphernodes.sh (2)

9-13: Make cleanup resilient under set -e

pkill returns non‑zero when no match; with set -e that can abort cleanup mid‑way. Guard with || true.

-  pkill -9 -f "enclave start"
+  pkill -9 -f "enclave start" || true
   sleep 2
-  pkill enclave
+  pkill enclave || true

42-44: Quote addresses to avoid word-splitting/globbing

Not critical, but safer in bash.

-pnpm hardhat ciphernode:add --ciphernode-address $CN1 --network localhost
-pnpm hardhat ciphernode:add --ciphernode-address $CN2 --network localhost
-pnpm hardhat ciphernode:add --ciphernode-address $CN3 --network localhost
+pnpm hardhat ciphernode:add --ciphernode-address "$CN1" --network localhost
+pnpm hardhat ciphernode:add --ciphernode-address "$CN2" --network localhost
+pnpm hardhat ciphernode:add --ciphernode-address "$CN3" --network localhost
examples/CRISP/tests/crisp.contracts.test.ts (2)

201-203: Minor: unused variable

publicClient is assigned but not used.

-    const publicClient = await viemHardhat.getPublicClient();
+    await viemHardhat.getPublicClient(); // ensure client is instanced; value unused

90-104: Leaked dev private key in comments can trip Gitleaks

Even commented, the well-known Hardhat key triggers scanners. Either redact or add an allowlist rule scoped to localhost/dev paths.

I can propose a .gitleaks.toml snippet to allowlist the Hardhat default key only under examples/ and templates/.

Also applies to: 101-101

examples/CRISP/package.json (1)

32-60: Verify plugin mix and remove stale deps

  • You depend on both hardhat-toolbox and hardhat-toolbox-viem plus hardhat-ethers; ensure you aren’t loading conflicting plugins in hardhat.config.ts. If CRISP is Viem-only, you likely don’t need hardhat-ethers via toolbox.
  • hardhat-deploy remains but the PR states it’s removed; drop if unused.
   "devDependencies": {
     "@enclave-e3/config": "^0.0.10-test",
     "@nomicfoundation/hardhat-ethers": "^3.0.0",
     "@nomicfoundation/hardhat-toolbox": "^5.0.0",
     "@nomicfoundation/hardhat-ignition": "^3.0.0",
     "@nomicfoundation/hardhat-toolbox-viem": "^5.0.0",
@@
-    "hardhat-deploy": "^0.12.4",

If you keep both toolboxes, ensure only one is imported in hardhat.config.ts to avoid duplicate plugin side-effects.

packages/enclave-contracts/ignition/modules/enclave.ts (2)

18-26: Constructor arg shape: avoid wrapping params in an array

If the Enclave constructor expects bytes (as implied by upstream encoding), pass params directly, not [params].

-  const enclave = m.contract(
-    "Enclave",
-    [owner, registry, maxDuration, [params]],
+  const enclave = m.contract(
+    "Enclave",
+    [owner, registry, maxDuration, params],
     {
       libraries: {
         PoseidonT3: poseidonT3,
       },
     },
   );

28-29: Drop as any

Ignition’s buildModule returns a typed module; avoid as any to keep type-safety.

packages/enclave-contracts/scripts/deployAndSave/mockDecryptionVerifier.ts (1)

22-23: Persist chainId and harden network reads

  • Prefer storing chainId alongside name to avoid collisions and improve portability.
  • Make blockNumber non-null.
-  const chain = (await signer.provider?.getNetwork())?.name ?? "localhost";
+  const net = await signer.provider!.getNetwork();
+  const chain = net.name ?? "localhost";
+  const chainId = Number(net.chainId);
@@
-  const blockNumber = await signer.provider?.getBlockNumber();
+  const blockNumber = await signer.provider!.getBlockNumber();
@@
   storeDeploymentArgs(
     {
-      blockNumber,
+      blockNumber,
       address: decryptionVerifierAddress,
+      chainId,
     },
     "MockDecryptionVerifier",
     chain,
   );

Also applies to: 32-41

packages/enclave-contracts/scripts/deployAndSave/mockProgram.ts (1)

26-29: Also store chainId for portability

Mirroring other scripts, persist chainId in the stored args.

-  const chain = (await signer.provider?.getNetwork())?.name ?? "localhost";
+  const net = await signer.provider!.getNetwork();
+  const chain = net.name ?? "localhost";
+  const chainId = Number(net.chainId);
@@
   storeDeploymentArgs(
     {
       constructorArgs: { mockInputValidator },
-      blockNumber,
+      blockNumber,
       address: e3ProgramAddress,
+      chainId,
     },
     "MockE3Program",
     chain,
   );

Also applies to: 55-63

packages/enclave-contracts/scripts/deployAndSave/mockInputValidator.ts (1)

27-37: Capture chainId and avoid nullable reads

Add chainId and make blockNumber non-null.

-  const chain = (await signer.provider?.getNetwork())?.name ?? "localhost";
-  const blockNumber = await signer.provider?.getBlockNumber();
+  const net = await signer.provider!.getNetwork();
+  const chain = net.name ?? "localhost";
+  const chainId = Number(net.chainId);
+  const blockNumber = await signer.provider!.getBlockNumber();
@@
   storeDeploymentArgs(
     {
       blockNumber,
       address: inputValidatorAddress,
+      chainId,
     },
     "MockInputValidator",
     chain,
   );
templates/default/scripts/deploy-local.ts (1)

34-35: Exit with non-zero code on failure

Ensure CI fails if deployment fails.

-main().catch(console.error);
+main().catch((err) => {
+  console.error(err);
+  process.exit(1);
+});
crates/entrypoint/build.rs (1)

65-65: Use the computed absolute path in rerun-if-changed to avoid path drift.

The hard-coded relative path can desync from deployments_path.

-    println!("cargo:rerun-if-changed=../../packages/enclave-contracts/deployed_contracts.json");
+    println!("cargo:rerun-if-changed={}", deployments_path.display());
packages/enclave-contracts/scripts/deployEnclave.ts (1)

78-109: Centralize encryptionSchemeId derivation.

Hard-coding "fhe.rs:BFV" risks divergence. Expose a shared helper/constant (e.g., in the SDK) and reuse here.

templates/default/tests/integration.spec.ts (2)

262-265: Decode the plaintext as a full BigInt, not a single byte.

Parsing only parsed[0] is fragile. Use viem’s fromHex to compare the full value.

-  const parsed = hexToUint8Array(plaintextEvent.data.plaintextOutput);
-
-  expect(BigInt(parsed[0])).toBe(num1 + num2);
+  import { fromHex } from "viem";
+  const out = fromHex(plaintextEvent.data.plaintextOutput, { to: "bigint" });
+  expect(out).toBe(num1 + num2);

35-39: Deduplicate helpers: use viem’s hexToBytes instead of custom hex parser.

You already import hexToBytes; the local hexToUint8Array is redundant.

-function hexToUint8Array(hexString: string) {
-  const hex = hexString.startsWith("0x") ? hexString.slice(2) : hexString;
-  const m = hex.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? [];
-  return new Uint8Array(m);
-}
+// Use viem.hexToBytes where needed
packages/enclave-contracts/hardhat.config.ts (1)

117-123: Ganache accounts config differs from others; intentional?

Elsewhere you resolve accounts from PRIVATE_KEY/MNEMONIC with configVariable. Here you hardcode mnemonic only. If that’s intentional for local dev, ignore; otherwise align with the shared logic.

templates/default/deployed_contracts.json (1)

1-67: Template looks coherent; consider embedding constructor args everywhere you can.

You already include constructorArgs for major contracts; adding them for ImageID/InputValidator/MyProgram (if applicable) improves reproducibility and later verification. Low-priority.

packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (2)

66-68: Minor: property shorthand

Tidy up constructorArgs.

-        ciphernodeRegistryAddress: ciphernodeRegistryAddress,
+        ciphernodeRegistryAddress,

40-44: Optional: verify on-chain code before reconnecting

Before connecting to a cached address, consider validating code is present (not "0x") to avoid stale/corrupt entries.

I can provide a small helper to fetch and assert bytecode if you want.

packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1)

59-68: Optional: type-safety on params/maxDuration

If Enclave expects bytes/uint values, prefer stricter types (e.g., Hex string branded type or bigint) to prevent accidental non-hex strings reaching ignition.

I can align the types to the module’s expected parameter shapes if you share the EnclaveModule signature.

packages/enclave-contracts/scripts/deployMocks.ts (1)

20-24: Fix JSDoc: remove nonexistent parameter.

The function takes no args; the @param enclaveAddress line is misleading.

 /**
  * Deploys the mock contracts and returns the addresses.
- * @param enclaveAddress - The address of the enclave contract.
  * @returns The addresses of the mock contracts.
  */
packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1)

40-47: Optional: validate addresses before reuse.

Consider checking code at preDeployedArgs.address to avoid connecting to a dead address after a chain reset.

Happy to add a lightweight getCode(address) check and warn/skip if it's 0x.

templates/default/deploy/default.ts (1)

42-52: Minor cleanup: avoid repeated awaits of addresses.

Cache addresses to reduce RPC calls and improve readability.

-  storeDeploymentArgs({
-    address: await e3Program.getAddress(),
-    constructorArgs: {
-      enclave: await enclave.getAddress(),
-      verifier: await verifier.getAddress(),
-      programId,
-      inputValidator: await inputValidator.getAddress(),
-    },
-  }, "MyProgram", chain);
+  const [enclaveAddr, verifierAddr, inputValidatorAddr, e3ProgramAddr] =
+    await Promise.all([
+      enclave.getAddress(),
+      verifier.getAddress(),
+      inputValidator.getAddress(),
+      e3Program.getAddress(),
+    ]);
+
+  storeDeploymentArgs({
+    address: e3ProgramAddr,
+    constructorArgs: {
+      enclave: enclaveAddr,
+      verifier: verifierAddr,
+      programId,
+      inputValidator: inputValidatorAddr,
+    },
+  }, "MyProgram", chain);
packages/enclave-contracts/scripts/utils.ts (2)

9-9: Consider making the deployment file path configurable.

The hardcoded path to deployed_contracts.json at the root may not be flexible enough for different environments or configurations.

Consider using an environment variable with a default fallback:

-const deploymentsFile = path.join("deployed_contracts.json");
+const deploymentsFile = path.join(
+  process.env.DEPLOYMENTS_FILE || "deployed_contracts.json"
+);

106-111: Consider atomic file operations for concurrent safety.

The deployment file operations are not atomic, which could lead to data corruption if multiple processes try to write simultaneously.

Consider implementing file locking or using atomic write operations (e.g., write to a temp file and rename) to prevent race conditions during concurrent deployments. Libraries like write-file-atomic could help ensure data integrity.

packages/enclave-contracts/test/CiphernodeRegistry/CiphernodeRegistryOwnable.spec.ts (1)

22-23: Consider moving top-level await into test setup.

Using top-level await for network connection could cause issues in certain test environments or when running tests in parallel.

Consider moving the network connection into the setup function or a before hook:

-const { ethers, networkHelpers, ignition } = await network.connect();
-const { loadFixture } = networkHelpers;
+let ethers: any, networkHelpers: any, ignition: any, loadFixture: any;
+
+before(async function () {
+  const connection = await network.connect();
+  ethers = connection.ethers;
+  networkHelpers = connection.networkHelpers;
+  ignition = connection.ignition;
+  loadFixture = networkHelpers.loadFixture;
+});
packages/enclave-contracts/tasks/ciphernode.ts (1)

20-33: Consider adding success/failure feedback for deployments.

The tasks don't provide clear feedback about whether the deployment was reused or newly created.

Consider enhancing the logging to indicate deployment status:

       const { ciphernodeRegistry } =
         await deployAndSaveCiphernodeRegistryOwnable({ hre });
+      console.log(`Using CiphernodeRegistry at: ${await ciphernodeRegistry.getAddress()}`);

       const tx = await ciphernodeRegistry.addCiphernode(ciphernodeAddress);
       await tx.wait();
       console.log(`Ciphernode ${ciphernodeAddress} registered`);
examples/CRISP/hardhat.config.ts (1)

87-95: API key environment variables not validated

The API keys are passed as empty strings when environment variables are not set, which might cause issues with block explorer verification.

Consider adding validation or warnings for missing API keys:

-    arbitrum: getChainConfig("arbitrum-mainnet", process.env.ARBISCAN_API_KEY || ""),
+    arbitrum: getChainConfig("arbitrum-mainnet", process.env.ARBISCAN_API_KEY || (() => {
+      console.warn("Warning: ARBISCAN_API_KEY not set");
+      return "";
+    })()),
packages/enclave-contracts/tasks/enclave.ts (1)

320-324: Consider validating file existence before reading

The file read operations don't check if the file exists before attempting to read it, which could cause unhelpful error messages.

       if (dataFile) {
+        if (!fs.existsSync(dataFile)) {
+          throw new Error(`File not found: ${dataFile}`);
+        }
         const file = fs.readFileSync(dataFile);
         dataToSend = file.toString();
       }
packages/enclave-contracts/test/Enclave.spec.ts (2)

29-55: Consider extracting test constants to a shared module.

These test constants (encryption scheme IDs, E3 program parameters, data/proof values) could be extracted to a shared test utilities module to promote reusability across test files and reduce duplication.

Consider creating a test utilities module:

// test/utils/constants.ts
export const TEST_CONSTANTS = {
  THIRTY_DAYS_IN_SECONDS: 60 * 60 * 24 * 30,
  ENCRYPTION_SCHEME_ID: "0x2c2a814a0495f913a3a312fc4771e37552bc14f8a2d4075a08122d356f0849c6",
  // ... other constants
};

export const TEST_E3_PARAMS = {
  polynomial_degree: ethers.toBigInt(2048),
  plaintext_modulus: ethers.toBigInt(1032193),
  moduli: [ethers.toBigInt("18014398492704769")]
};

194-196: Redundant from parameter in connect call.

When using connect() with a signer, the from parameter in the transaction options is redundant as the signer's address is already used.

-      await expect(
-        enclave
-          .connect(notTheOwner)
-          .setMaxDuration(1, { from: await notTheOwner.getAddress() }),
-      )
+      await expect(
+        enclave
+          .connect(notTheOwner)
+          .setMaxDuration(1),
+      )
templates/default/hardhat.config.ts (4)

20-23: Consider validating environment variables.

While using configVariable is good practice, consider adding validation or fallback values for critical configuration to prevent runtime failures.

const mnemonic = configVariable("MNEMONIC");
const privateKey = configVariable("PRIVATE_KEY");
const infuraApiKey = configVariable("INFURA_API_KEY");

// Add validation
if (!mnemonic && !privateKey) {
  console.warn("Warning: Neither MNEMONIC nor PRIVATE_KEY is set. Some network operations may fail.");
}

95-100: Hardcoded salt in create2 configuration.

Using a zero salt for CREATE2 deployments removes the benefit of deterministic addresses across chains. Consider using a more meaningful salt or making it configurable.

ignition: {
  strategyConfig: {
    create2: {
      salt: process.env.CREATE2_SALT || ethers.id("enclave-v3-migration"),
    }
  }
},

137-148: Consider version management for imported contracts.

The npmFilesToBuild list hardcodes specific contract paths. Consider documenting the versioning strategy for these dependencies to ensure compatibility.

Would you like me to create a configuration file that tracks contract dependency versions and their compatibility matrix?


51-62: Accounts union is valid — prefer using ConfigurationVariable[] instead of the single-element tuple

Hardhat accepts either an array of configuration variables (private keys) or an HD-wallet object; the current union is acceptable, but change the type from [ConfigurationVariable] to ConfigurationVariable[] to allow multiple keys and better match Hardhat's accounts shape. (hardhat.org)

Location: templates/default/hardhat.config.ts (lines 51–62)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc330c6 and 4cc5089.

⛔ Files ignored due to path filters (2)
  • packages/enclave-contracts/test/fixtures/pubkey.bin is excluded by !**/*.bin
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (94)
  • .github/workflows/ci.yml (3 hunks)
  • crates/Dockerfile (1 hunks)
  • crates/entrypoint/build.rs (3 hunks)
  • examples/CRISP/client/.env.example (1 hunks)
  • examples/CRISP/enclave.config.yaml (1 hunks)
  • examples/CRISP/hardhat.config.ts (3 hunks)
  • examples/CRISP/package.json (1 hunks)
  • examples/CRISP/server/.env.example (1 hunks)
  • examples/CRISP/tests/CRISPProgram.t.sol (0 hunks)
  • examples/CRISP/tests/crisp.contracts.test.ts (1 hunks)
  • examples/CRISP/tsconfig.json (1 hunks)
  • package.json (1 hunks)
  • packages/enclave-contracts/.gitignore (1 hunks)
  • packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json (2 hunks)
  • packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json (2 hunks)
  • packages/enclave-contracts/artifacts/contracts/registry/NaiveRegistryFilter.sol/NaiveRegistryFilter.json (2 hunks)
  • packages/enclave-contracts/contracts/Enclave.sol (2 hunks)
  • packages/enclave-contracts/contracts/interfaces/IEnclave.sol (1 hunks)
  • packages/enclave-contracts/contracts/registry/NaiveRegistryFilter.sol (1 hunks)
  • packages/enclave-contracts/contracts/test/MockE3Program.sol (0 hunks)
  • packages/enclave-contracts/deploy/enclave.ts (0 hunks)
  • packages/enclave-contracts/deploy/mocks.ts (0 hunks)
  • packages/enclave-contracts/deployed_contracts.json (1 hunks)
  • packages/enclave-contracts/deployments/sepolia/.chainId (0 hunks)
  • packages/enclave-contracts/deployments/sepolia/MockComputeProvider.json (0 hunks)
  • packages/enclave-contracts/deployments/sepolia/MockDecryptionVerifier.json (0 hunks)
  • packages/enclave-contracts/deployments/sepolia/MockE3Program.json (0 hunks)
  • packages/enclave-contracts/deployments/sepolia/MockInputValidator.json (0 hunks)
  • packages/enclave-contracts/deployments/sepolia/NaiveRegistryFilter.json (0 hunks)
  • packages/enclave-contracts/deployments/sepolia/solcInputs/f32a0aa4ee06fa210859a817cc9dafc5.json (0 hunks)
  • packages/enclave-contracts/hardhat.config.cts (0 hunks)
  • packages/enclave-contracts/hardhat.config.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/ciphernodeRegistry.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/enclave.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockCiphernodeRegistry.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockCiphernodeRegistryEmptyKey.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockComputeProvider.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockDecryptionVerifier.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockE3Program.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockInputValidator.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/naiveRegistryFilter.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/poseidonT3.ts (1 hunks)
  • packages/enclave-contracts/package.json (2 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockComputeProvider.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockDecryptionVerifier.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockInputValidator.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockProgram.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployEnclave.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployMocks.ts (1 hunks)
  • packages/enclave-contracts/scripts/run.ts (1 hunks)
  • packages/enclave-contracts/scripts/utils.ts (1 hunks)
  • packages/enclave-contracts/tasks/accounts.ts (0 hunks)
  • packages/enclave-contracts/tasks/ciphernode.ts (1 hunks)
  • packages/enclave-contracts/tasks/enclave.ts (1 hunks)
  • packages/enclave-contracts/tasks/utils.ts (1 hunks)
  • packages/enclave-contracts/test/CiphernodeRegistry/CiphernodeRegistryOwnable.spec.ts (5 hunks)
  • packages/enclave-contracts/test/CiphernodeRegistry/NaiveRegistryFilter.spec.ts (4 hunks)
  • packages/enclave-contracts/test/Enclave.spec.ts (20 hunks)
  • packages/enclave-contracts/test/fixtures/CiphernodeRegistryOwnable.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/Enclave.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/MockCiphernodeRegistry.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/MockComputeProvider.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/MockDecryptionVerifier.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/MockE3Program.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/MockInputValidator.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/NaiveRegistryFilter.fixture.ts (0 hunks)
  • packages/enclave-contracts/test/fixtures/PoseidonT3.fixture.ts (0 hunks)
  • packages/enclave-contracts/tsconfig.json (1 hunks)
  • packages/enclave-contracts/tsup.config.mjs (0 hunks)
  • packages/enclave-sdk/package.json (1 hunks)
  • packages/enclave-sdk/src/contract-client.ts (1 hunks)
  • packages/enclave-sdk/tsup.config.js (2 hunks)
  • templates/default/.gitignore (1 hunks)
  • templates/default/contracts/Mocks/MockRISC0Verifier.sol (1 hunks)
  • templates/default/contracts/MyProgram.sol (1 hunks)
  • templates/default/deploy/default.ts (1 hunks)
  • templates/default/deploy/enclave.ts (0 hunks)
  • templates/default/deployed_contracts.json (1 hunks)
  • templates/default/enclave.config.yaml (1 hunks)
  • templates/default/hardhat.config.ts (1 hunks)
  • templates/default/package.json (2 hunks)
  • templates/default/scripts/deploy-local.ts (1 hunks)
  • templates/default/scripts/dev_ciphernodes.sh (2 hunks)
  • templates/default/scripts/test_integration.sh (1 hunks)
  • templates/default/server/index.ts (1 hunks)
  • templates/default/tests/integration.spec.ts (4 hunks)
  • templates/default/tsconfig.json (1 hunks)
  • tests/integration/base.sh (1 hunks)
  • tests/integration/enclave.config.yaml (1 hunks)
  • tests/integration/fns.sh (3 hunks)
  • tests/integration/persist.sh (1 hunks)
💤 Files with no reviewable changes (24)
  • packages/enclave-contracts/test/fixtures/NaiveRegistryFilter.fixture.ts
  • packages/enclave-contracts/deployments/sepolia/MockE3Program.json
  • packages/enclave-contracts/deployments/sepolia/MockComputeProvider.json
  • packages/enclave-contracts/test/fixtures/CiphernodeRegistryOwnable.fixture.ts
  • packages/enclave-contracts/test/fixtures/MockInputValidator.fixture.ts
  • packages/enclave-contracts/tsup.config.mjs
  • packages/enclave-contracts/test/fixtures/MockE3Program.fixture.ts
  • templates/default/deploy/enclave.ts
  • packages/enclave-contracts/hardhat.config.cts
  • packages/enclave-contracts/test/fixtures/PoseidonT3.fixture.ts
  • packages/enclave-contracts/deployments/sepolia/MockInputValidator.json
  • packages/enclave-contracts/deploy/enclave.ts
  • packages/enclave-contracts/deploy/mocks.ts
  • packages/enclave-contracts/deployments/sepolia/.chainId
  • packages/enclave-contracts/tasks/accounts.ts
  • packages/enclave-contracts/test/fixtures/MockDecryptionVerifier.fixture.ts
  • packages/enclave-contracts/deployments/sepolia/NaiveRegistryFilter.json
  • packages/enclave-contracts/test/fixtures/MockComputeProvider.fixture.ts
  • packages/enclave-contracts/test/fixtures/Enclave.fixture.ts
  • packages/enclave-contracts/contracts/test/MockE3Program.sol
  • packages/enclave-contracts/test/fixtures/MockCiphernodeRegistry.fixture.ts
  • examples/CRISP/tests/CRISPProgram.t.sol
  • packages/enclave-contracts/deployments/sepolia/MockDecryptionVerifier.json
  • packages/enclave-contracts/deployments/sepolia/solcInputs/f32a0aa4ee06fa210859a817cc9dafc5.json
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2024-11-25T09:47:48.863Z
Learnt from: ryardley
PR: gnosisguild/enclave#184
File: packages/ciphernode/net/tests/entrypoint.sh:4-8
Timestamp: 2024-11-25T09:47:48.863Z
Learning: When reviewing test scripts like `packages/ciphernode/net/tests/entrypoint.sh`, avoid suggesting additional error handling and cleanup for `iptables` commands, as it may not be necessary.

Applied to files:

  • templates/default/scripts/dev_ciphernodes.sh
📚 Learning: 2024-09-26T04:12:09.345Z
Learnt from: ryardley
PR: gnosisguild/enclave#107
File: tests/basic_integration/test.sh:103-114
Timestamp: 2024-09-26T04:12:09.345Z
Learning: In `tests/basic_integration/test.sh`, the user prefers not to refactor the ciphernode addition section to reduce duplication.

Applied to files:

  • templates/default/scripts/dev_ciphernodes.sh
  • tests/integration/base.sh
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
PR: gnosisguild/enclave#107
File: tests/basic_integration/test.sh:81-83
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `tests/basic_integration/test.sh`, it's acceptable to wait indefinitely for the EVM node to start without a timeout, as it's unlikely to fail here.

Applied to files:

  • templates/default/tests/integration.spec.ts
  • tests/integration/base.sh
📚 Learning: 2024-11-05T06:56:49.157Z
Learnt from: ryardley
PR: gnosisguild/enclave#173
File: packages/ciphernode/enclave_node/src/aggregator.rs:0-0
Timestamp: 2024-11-05T06:56:49.157Z
Learning: `RegistryFilterSol` does not have a reader and does not require a repository reader or deploy block when calling `RegistryFilterSol::attach` in `packages/ciphernode/enclave_node/src/aggregator.rs`.

Applied to files:

  • packages/enclave-contracts/contracts/registry/NaiveRegistryFilter.sol
🧬 Code graph analysis (20)
packages/enclave-contracts/ignition/modules/enclave.ts (1)
crates/events/src/enclave_event/compute_request/trbfv.rs (1)
  • params (59-63)
packages/enclave-contracts/scripts/deployAndSave/mockInputValidator.ts (1)
packages/enclave-contracts/scripts/utils.ts (1)
  • storeDeploymentArgs (34-62)
packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (1)
packages/enclave-contracts/scripts/utils.ts (2)
  • readDeploymentArgs (70-78)
  • storeDeploymentArgs (34-62)
packages/enclave-contracts/tasks/ciphernode.ts (1)
packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1)
  • deployAndSaveCiphernodeRegistryOwnable (29-86)
packages/enclave-contracts/hardhat.config.ts (3)
packages/enclave-contracts/tasks/ciphernode.ts (3)
  • ciphernodeAdd (11-33)
  • ciphernodeRemove (35-68)
  • ciphernodeSiblings (70-102)
packages/enclave-contracts/tasks/enclave.ts (7)
  • requestCommittee (13-184)
  • publishPlaintext (406-474)
  • publishCiphertext (336-404)
  • publishInput (289-334)
  • activateE3 (258-287)
  • publishCommittee (211-256)
  • enableE3 (186-209)
packages/enclave-contracts/tasks/utils.ts (1)
  • cleanDeploymentsTask (11-26)
packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1)
packages/enclave-contracts/scripts/utils.ts (2)
  • readDeploymentArgs (70-78)
  • storeDeploymentArgs (34-62)
templates/default/deploy/default.ts (1)
packages/enclave-contracts/scripts/utils.ts (2)
  • readDeploymentArgs (70-78)
  • storeDeploymentArgs (34-62)
packages/enclave-contracts/scripts/deployAndSave/mockProgram.ts (1)
packages/enclave-contracts/scripts/utils.ts (2)
  • readDeploymentArgs (70-78)
  • storeDeploymentArgs (34-62)
packages/enclave-contracts/tasks/utils.ts (1)
packages/enclave-contracts/scripts/utils.ts (1)
  • cleanDeployments (101-111)
packages/enclave-contracts/scripts/deployAndSave/mockDecryptionVerifier.ts (1)
packages/enclave-contracts/scripts/utils.ts (1)
  • storeDeploymentArgs (34-62)
packages/enclave-contracts/scripts/deployMocks.ts (4)
packages/enclave-contracts/scripts/deployAndSave/mockComputeProvider.ts (1)
  • deployAndSaveMockComputeProvider (15-48)
packages/enclave-contracts/scripts/deployAndSave/mockDecryptionVerifier.ts (1)
  • deployAndSaveMockDecryptionVerifier (15-49)
packages/enclave-contracts/scripts/deployAndSave/mockInputValidator.ts (1)
  • deployAndSaveMockInputValidator (15-45)
packages/enclave-contracts/scripts/deployAndSave/mockProgram.ts (1)
  • deployAndSaveMockProgram (20-71)
templates/default/hardhat.config.ts (2)
packages/enclave-contracts/tasks/ciphernode.ts (1)
  • ciphernodeAdd (11-33)
packages/enclave-contracts/tasks/utils.ts (1)
  • cleanDeploymentsTask (11-26)
templates/default/tests/integration.spec.ts (1)
packages/enclave-sdk/src/utils.ts (5)
  • DEFAULT_E3_CONFIG (86-92)
  • calculateStartWindow (141-146)
  • encodeBfvParams (98-123)
  • encodeComputeProviderParams (128-136)
  • DEFAULT_COMPUTE_PROVIDER_PARAMS (79-83)
packages/enclave-contracts/scripts/run.ts (1)
packages/enclave-contracts/scripts/deployEnclave.ts (1)
  • deployEnclave (16-109)
crates/entrypoint/build.rs (1)
crates/config/src/contract.rs (1)
  • deploy_block (28-34)
packages/enclave-contracts/scripts/deployEnclave.ts (4)
packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1)
  • deployAndSaveEnclave (28-88)
packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1)
  • deployAndSaveCiphernodeRegistryOwnable (29-86)
packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (1)
  • deployAndSaveNaiveRegistryFilter (21-82)
packages/enclave-contracts/scripts/deployMocks.ts (1)
  • deployMocks (25-60)
packages/enclave-contracts/scripts/deployAndSave/mockComputeProvider.ts (1)
packages/enclave-contracts/scripts/utils.ts (1)
  • storeDeploymentArgs (34-62)
templates/default/scripts/deploy-local.ts (2)
packages/enclave-contracts/scripts/deployEnclave.ts (1)
  • deployEnclave (16-109)
templates/default/deploy/default.ts (1)
  • deployTemplate (11-59)
packages/enclave-contracts/tasks/enclave.ts (3)
packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1)
  • deployAndSaveEnclave (28-88)
packages/enclave-contracts/scripts/utils.ts (1)
  • readDeploymentArgs (70-78)
packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (1)
  • deployAndSaveNaiveRegistryFilter (21-82)
packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1)
packages/enclave-contracts/scripts/utils.ts (2)
  • readDeploymentArgs (70-78)
  • storeDeploymentArgs (34-62)
🪛 dotenv-linter (3.3.0)
examples/CRISP/client/.env.example

[warning] 4-4: [UnorderedKey] The VITE_E3_PROGRAM_ADDRESS key should go before the VITE_ENCLAVE_API key

(UnorderedKey)


[warning] 4-4: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)


[warning] 5-5: [UnorderedKey] The VITE_SEMAPHORE_ADDRESS key should go before the VITE_TWITTER_SERVERLESS_API key

(UnorderedKey)

examples/CRISP/server/.env.example

[warning] 14-14: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 14-14: [UnorderedKey] The CIPHERNODE_REGISTRY_ADDRESS key should go before the ENCLAVE_ADDRESS key

(UnorderedKey)


[warning] 15-15: [QuoteCharacter] The value has quote characters (', ")

(QuoteCharacter)


[warning] 16-16: [UnorderedKey] The E3_PROGRAM_ADDRESS key should go before the ENCLAVE_ADDRESS key

(UnorderedKey)

🪛 Gitleaks (8.27.2)
examples/CRISP/tests/crisp.contracts.test.ts

[high] 101-101: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Shellcheck (0.10.0)
tests/integration/fns.sh

[warning] 24-24: ENCLAVE_CONTRACT appears unused. Verify use (or export if used externally).

(SC2034)


[warning] 25-25: REGISTRY_CONTRACT appears unused. Verify use (or export if used externally).

(SC2034)


[warning] 26-26: REGISTRY_FILTER_CONTRACT appears unused. Verify use (or export if used externally).

(SC2034)


[warning] 27-27: INPUT_VALIDATOR_CONTRACT appears unused. Verify use (or export if used externally).

(SC2034)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: crisp_e2e

Comment thread crates/entrypoint/build.rs Outdated
Comment thread crates/entrypoint/build.rs
Comment thread examples/CRISP/hardhat.config.ts
Comment thread examples/CRISP/tests/crisp.contracts.test.ts
Comment thread examples/CRISP/tsconfig.json Outdated
Comment thread templates/default/package.json
Comment thread templates/default/scripts/deploy-local.ts
Comment thread templates/default/tests/integration.spec.ts
Comment thread templates/default/tsconfig.json
Comment thread tests/integration/fns.sh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review continued from previous batch...

Comment thread packages/enclave-contracts/package.json Outdated
Comment thread packages/enclave-contracts/tasks/enclave.ts
Comment thread packages/enclave-contracts/tasks/enclave.ts Outdated
Comment thread packages/enclave-contracts/tasks/enclave.ts Outdated
Comment thread packages/enclave-contracts/tasks/enclave.ts
Comment thread packages/enclave-contracts/test/Enclave.spec.ts
Comment thread packages/enclave-contracts/test/Enclave.spec.ts
Comment thread packages/enclave-contracts/test/Enclave.spec.ts
Comment thread packages/enclave-contracts/test/Enclave.spec.ts

@cedoor cedoor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 👍🏽

Comment thread packages/enclave-contracts/contracts/Enclave.sol Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (8)
packages/enclave-contracts/tsconfig.json (1)

21-21: Keep custom ambient declarations included (repeat from prior review)

Excluding "types" can hide local .d.ts augmentations (e.g., custom matchers/util globals). Unless intentionally unused, remove it from exclude (or explicitly include types/**/*.ts).

-  "exclude": ["node_modules", "dist", "types"]
+  "exclude": ["node_modules", "dist"]
crates/entrypoint/build.rs (2)

39-57: Address the duplicate key collision issue from previous review.

The code still generates PHF map keys using only contract_name, which will cause collisions if multiple networks are added to the JSON manifest in the future. While currently only Sepolia exists, this creates technical debt.

Apply this diff to prefix keys with network name:

-    if let Some(networks) = json.as_object() {
+    if let Some(networks) = json.as_object() {
-        if let Some(sepolia_data) = networks.get("sepolia") {
+        for (network_name, network_data) in networks {
-            if let Some(contracts) = sepolia_data.as_object() {
+            if let Some(contracts) = network_data.as_object() {
                 for (contract_name, contract_data) in contracts {
                     // Extract address and block number from the contract data
                     if let (Some(address), Some(deploy_block)) = (
                         contract_data["address"].as_str(),
                         contract_data["blockNumber"].as_u64(),
                     ) {
                         contract_info.push_str(&format!(
-                            "    \"{}\" => ContractInfo {{\n        address: \"{}\",\n        deploy_block: {},\n    }},\n",
-                            contract_name, address, deploy_block
+                            "    \"{}:{}\" => ContractInfo {{\n        address: \"{}\",\n        deploy_block: {},\n    }},\n",
+                            network_name, contract_name, address, deploy_block
                         ));
                     }
                 }
             }
         }
-    }

45-53: Add error handling for malformed JSON entries.

The code silently skips contracts with missing address or blockNumber fields, making debugging difficult if the JSON is malformed.

Apply this diff to fail fast with clear error messages:

                     if let (Some(address), Some(deploy_block)) = (
                         contract_data["address"].as_str(),
                         contract_data["blockNumber"].as_u64(),
                     ) {
                         contract_info.push_str(&format!(
                             "    \"{}\" => ContractInfo {{\n        address: \"{}\",\n        deploy_block: {},\n    }},\n",
                             contract_name, address, deploy_block
                         ));
+                    } else {
+                        panic!(
+                            "deployed_contracts.json: missing address or blockNumber for '{}'",
+                            contract_name
+                        );
                     }
templates/default/deploy/default.ts (1)

15-17: Chain resolution may be undefined - fallback to localhost.

As noted in learnings, hre.globalOptions.network can be undefined in some contexts. The current implementation doesn't handle this case, which could lead to undefined behavior when accessing deployment arguments.

Apply this fix to ensure robust chain resolution:

-  const chain = hre.globalOptions.network;
+  const chain = hre.globalOptions.network ?? "localhost";
packages/enclave-contracts/tasks/ciphernode.ts (4)

15-19: Remove invalid ZeroAddress default for required ciphernode parameter.

Using ZeroAddress as the default value will cause the task to fail when executed without arguments, as registering the zero address is typically invalid.

Remove the default value to make the parameter required:

   .addOption({
     name: "ciphernodeAddress",
     description: "address of ciphernode to register",
-    defaultValue: ZeroAddress,
   })

39-48: Fix inconsistent default values for remove task parameters.

The siblings parameter expects a comma-separated list but defaults to an empty string, while ciphernodeAddress defaults to ZeroAddress which is invalid.

Update both parameters to be required:

   .addOption({
     name: "ciphernodeAddress",
     description: "address of ciphernode to remove",
-    defaultValue: ZeroAddress,
   })
   .addOption({
     name: "siblings",
     description: "comma separated siblings from tree proof",
-    defaultValue: "",
   })

57-57: Add robust error handling for siblings parsing.

The current implementation will throw a cryptic error if the siblings input is malformed or contains invalid values.

Add validation and error handling:

-      const siblingsArray = siblings.split(",").map((s: string) => BigInt(s));
+      const siblingsArray = siblings
+        .split(",")
+        .filter(s => s.trim() !== "")
+        .map((s: string) => {
+          const trimmed = s.trim();
+          try {
+            return BigInt(trimmed);
+          } catch (error) {
+            throw new Error(`Invalid sibling value: "${trimmed}" - must be a valid integer`);
+          }
+        });

74-84: Fix incorrect default value for ciphernodeAddresses parameter.

Using ZeroAddress as default for a comma-separated list parameter is semantically incorrect and will cause parsing errors.

Make both parameters required:

   .addOption({
     name: "ciphernodeAddress",
     description: "address of ciphernode to get siblings for",
-    defaultValue: ZeroAddress,
   })
   .addOption({
     name: "ciphernodeAddresses",
     description:
       "comma separated addresses of ciphernodes in the order they were added to the registry",
-    defaultValue: ZeroAddress,
   })
🧹 Nitpick comments (10)
packages/enclave-contracts/tsconfig.json (6)

5-6: Prefer NodeNext modules/resolution for Hardhat/Node tooling

Hardhat, scripts, tasks, and Ignition modules run in Node. module: "ESNext" with moduleResolution: "bundler" can break Node/ts-node/tsx resolution and package "exports" condition handling. Recommend NodeNext for both.

-    "module": "ESNext",
-    "moduleResolution": "bundler",
+    "module": "NodeNext",
+    "moduleResolution": "NodeNext",

3-4: Align lib and target to avoid typing-runtime mismatches

You’re targeting ES2022 but typing against ES2023 APIs. Either bump target or drop lib back to ES2022. If CI/engines use Node ≥18/20 and you rely on ES2023 APIs, bump target.

Option A (bump target):

-    "lib": ["es2023"],
-    "target": "ES2022",
+    "lib": ["es2023"],
+    "target": "ES2023",

Option B (conservative libs):

-    "lib": ["es2023"],
+    "lib": ["es2022"],

10-12: Avoid emitting declarations for tests/scripts/tasks; split configs or disable emit

Current config will emit .d.ts/.js for tests, tasks, ignition, and hardhat.config into dist. Typically we type-check these without emit and let Hardhat/tsx transpile at runtime. Suggest disabling emit here, and (if needed) create a separate build tsconfig for any publishable library code.

Minimal change (no emit):

-    "outDir": "dist",
-    "declaration": true,
-    "declarationMap": true
+    "noEmit": true

Or split configs:

  • tsconfig.json (tools): "noEmit": true, module/moduleResolution: "NodeNext".
  • tsconfig.build.json (library/artifacts packaging): emits with outDir, declaration, excludes tests/scripts/tasks/hardhat config.

2-13: Enable JSON imports if code imports deployment manifests

You mention reading/writing deployed_contracts.json. If imported in TS, add resolveJsonModule.

   "compilerOptions": {
+    "resolveJsonModule": true,

2-13: Pin ambient types for cleaner tool/test DX

To avoid pulling every @types/* and to get globals for Hardhat/Mocha/Chai, explicitly set types. Adjust if using Vitest instead of Mocha.

   "compilerOptions": {
+    "types": ["node", "mocha", "chai", "hardhat"],

14-20: Optional: isolate tools from tests in includes

Grouping tools (hardhat.config.ts, scripts/**/*.ts, tasks/**/*.ts, ignition/modules/**/*.ts) and tests under one tsconfig can make editor/tsserver slower. Consider a dedicated tsconfig.tools.json (referenced by IDE) and keep tests in the main tsconfig (or vice versa).

packages/enclave-contracts/tasks/enclave.ts (3)

11-11: Consider caching deployment imports and results

The deployment functions are dynamically imported and executed in every task action. This could lead to unnecessary file reads and potential performance issues if the same tasks are run multiple times in a session.

Consider moving the imports to the module level or implementing a caching mechanism to avoid repeated deployments when the configuration hasn't changed:

// At module level
let deploymentCache: Record<string, any> = {};

// In task actions
if (!deploymentCache.enclave) {
  const { deployAndSaveEnclave } = await import(
    "../scripts/deployAndSave/enclave"
  );
  deploymentCache.enclave = await deployAndSaveEnclave({ hre });
}
const { enclave } = deploymentCache.enclave;

Also applies to: 86-88, 195-197, 235-237, 280-282, 320-322, 379-381, 449-451


327-331: Add validation for empty file content

The tasks read files but don't validate if the content is empty or if the file exists, which could lead to confusing behavior.

Add validation for file content:

       if (dataFile) {
+        if (!fs.existsSync(dataFile)) {
+          throw new Error(`Data file not found: ${dataFile}`);
+        }
         const file = fs.readFileSync(dataFile);
+        if (file.length === 0) {
+          throw new Error(`Data file is empty: ${dataFile}`);
+        }
         dataToSend = file.toString();
       }

Also applies to: 387-390, 455-460, 462-467


175-175: Consider making ETH value configurable

The ETH value sent with the enclave.request transaction is hardcoded to 1 ETH. This might not be appropriate for all networks or use cases.

Consider adding an option for the ETH value:

+  .addOption({
+    name: "value",
+    description: "ETH value to send with the request (in wei)",
+    defaultValue: "1000000000000000000",
+    type: ArgumentType.STRING,
+  })
   .setAction(async () => ({
     default: async (
       {
         // ... existing parameters
+        value,
       },
       hre,
     ) => {
       // ... existing code
       const tx = await enclave.request(
         {
           // ... existing parameters
         },
-        { value: "1000000000000000000" },
+        { value },
       );
templates/default/hardhat.config.ts (1)

70-74: Block explorer configuration may be incomplete

The block explorer configuration only includes apiUrl but other networks might require additional configuration like url for the explorer web interface.

Consider adding the explorer URL for completeness:

     blockExplorers: {
       etherscan: {
         apiUrl,
+        url: getBlockExplorerUrl(chain),
       },
     },

And add a helper function:

function getBlockExplorerUrl(chain: keyof typeof chainIds): string {
  const explorers: Record<string, string> = {
    "arbitrum-mainnet": "https://arbiscan.io",
    "avalanche": "https://snowtrace.io",
    "bsc": "https://bscscan.com",
    // ... other networks
  };
  return explorers[chain] || `https://${chain}.etherscan.io`;
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4cc5089 and f45f0e2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (25)
  • crates/entrypoint/build.rs (3 hunks)
  • examples/CRISP/tsconfig.json (1 hunks)
  • packages/enclave-contracts/.gitignore (1 hunks)
  • packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json (2 hunks)
  • packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json (2 hunks)
  • packages/enclave-contracts/artifacts/contracts/registry/NaiveRegistryFilter.sol/NaiveRegistryFilter.json (2 hunks)
  • packages/enclave-contracts/contracts/Enclave.sol (1 hunks)
  • packages/enclave-contracts/deployed_contracts.json (1 hunks)
  • packages/enclave-contracts/hardhat.config.ts (1 hunks)
  • packages/enclave-contracts/ignition/modules/mockE3Program.ts (1 hunks)
  • packages/enclave-contracts/package.json (2 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockComputeProvider.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockDecryptionVerifier.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockInputValidator.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/mockProgram.ts (1 hunks)
  • packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (1 hunks)
  • packages/enclave-contracts/scripts/run.ts (1 hunks)
  • packages/enclave-contracts/scripts/utils.ts (1 hunks)
  • packages/enclave-contracts/tasks/ciphernode.ts (1 hunks)
  • packages/enclave-contracts/tasks/enclave.ts (1 hunks)
  • packages/enclave-contracts/tsconfig.json (1 hunks)
  • templates/default/deploy/default.ts (1 hunks)
  • templates/default/hardhat.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (15)
  • packages/enclave-contracts/scripts/deployAndSave/mockProgram.ts
  • packages/enclave-contracts/scripts/deployAndSave/mockInputValidator.ts
  • packages/enclave-contracts/.gitignore
  • packages/enclave-contracts/scripts/utils.ts
  • packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json
  • packages/enclave-contracts/scripts/run.ts
  • packages/enclave-contracts/scripts/deployAndSave/mockDecryptionVerifier.ts
  • packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts
  • packages/enclave-contracts/ignition/modules/mockE3Program.ts
  • packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json
  • packages/enclave-contracts/hardhat.config.ts
  • packages/enclave-contracts/scripts/deployAndSave/mockComputeProvider.ts
  • examples/CRISP/tsconfig.json
  • packages/enclave-contracts/scripts/deployAndSave/enclave.ts
  • packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-09-11T13:09:03.764Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#677
File: packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts:30-31
Timestamp: 2025-09-11T13:09:03.764Z
Learning: In Hardhat v3 deployment scripts, use `(await signer.provider?.getNetwork())?.name ?? "localhost"` instead of `hre.globalOptions.network` to reliably get the network name, as `hre.globalOptions.network` can be undefined in some contexts.

Applied to files:

  • templates/default/deploy/default.ts
📚 Learning: 2025-09-11T13:09:03.764Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#677
File: packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts:30-31
Timestamp: 2025-09-11T13:09:03.764Z
Learning: In Hardhat v3, hre.network.name is not available anymore. Use hre.globalOptions.network to get the network name instead.

Applied to files:

  • templates/default/deploy/default.ts
📚 Learning: 2025-09-11T13:02:56.305Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#677
File: packages/enclave-contracts/scripts/deployAndSave/mockComputeProvider.ts:6-6
Timestamp: 2025-09-11T13:02:56.305Z
Learning: In Hardhat v3, the import path "hardhat/types/hre" may be valid for importing HardhatRuntimeEnvironment, unlike in Hardhat v2 where the standard path was "hardhat/types".

Applied to files:

  • packages/enclave-contracts/package.json
📚 Learning: 2025-09-11T13:21:30.996Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#677
File: packages/enclave-contracts/tasks/utils.ts:7-8
Timestamp: 2025-09-11T13:21:30.996Z
Learning: In Hardhat v3, the task API syntax has changed significantly from v2. The new syntax uses:
- `.addOption({ name, description, defaultValue, type })` instead of `.addOptionalParam()`
- `.setAction(async () => ({ default: (args, hre) => { ... } }))` instead of direct `.setAction((args, hre) => { ... })`
- `.build()` is required to finalize task definitions
- `ArgumentType.STRING` is used for option types instead of `types.string`

Applied to files:

  • templates/default/hardhat.config.ts
  • packages/enclave-contracts/tasks/enclave.ts
  • packages/enclave-contracts/tasks/ciphernode.ts
🧬 Code graph analysis (5)
crates/entrypoint/build.rs (1)
crates/config/src/contract.rs (1)
  • deploy_block (28-34)
templates/default/deploy/default.ts (1)
packages/enclave-contracts/scripts/utils.ts (2)
  • readDeploymentArgs (74-88)
  • storeDeploymentArgs (34-66)
templates/default/hardhat.config.ts (2)
packages/enclave-contracts/tasks/ciphernode.ts (1)
  • ciphernodeAdd (11-33)
packages/enclave-contracts/tasks/utils.ts (1)
  • cleanDeploymentsTask (11-26)
packages/enclave-contracts/tasks/enclave.ts (3)
packages/enclave-contracts/scripts/deployAndSave/enclave.ts (1)
  • deployAndSaveEnclave (28-91)
packages/enclave-contracts/scripts/utils.ts (1)
  • readDeploymentArgs (74-88)
packages/enclave-contracts/scripts/deployAndSave/naiveRegistryFilter.ts (1)
  • deployAndSaveNaiveRegistryFilter (21-87)
packages/enclave-contracts/tasks/ciphernode.ts (1)
packages/enclave-contracts/scripts/deployAndSave/ciphernodeRegistryOwnable.ts (1)
  • deployAndSaveCiphernodeRegistryOwnable (29-91)
🔇 Additional comments (12)
packages/enclave-contracts/artifacts/contracts/registry/NaiveRegistryFilter.sol/NaiveRegistryFilter.json (3)

302-303: Recompiled bytecode — re-check verification and determinism.

  • Bytecode changed; update Etherscan/Blockscout verification artifacts/paths.
  • Confirm a single solc version and identical optimizer/metadata settings across all builds; scan found multiple hardhat.config.* "solidity"/"optimizer" blocks and the build-info solc-version query returned no results — verify/unify configs and regenerate deterministic build.

2-2: Verify external tooling supports Hardhat v3 artifacts ("hh3-artifact-1")

rg returned only artifact JSON hits (no ts/js/sh files in this repo appear to hard-code the old artifact format). Matches: packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json (lines 219–222), packages/enclave-contracts/artifacts/contracts/interfaces/IEnclave.sol/IEnclave.json (lines 704–707), packages/enclave-contracts/artifacts/contracts/registry/NaiveRegistryFilter.sol/NaiveRegistryFilter.json (lines 305–308). Verify external CI/deploy/verify/packaging scripts that consume artifacts accept "_format": "hh3-artifact-1" and the hh3 layout (buildInfoId / inputSourceName / immutableReferences / deployedLinkReferences).


305-309: Verify tooling that depends on artifact source paths; prefer buildInfoId

  • Artifacts include buildInfoId and both sourceName (repo-relative) and inputSourceName (prefixed with "project/…"). Example: packages/enclave-contracts/artifacts/contracts/interfaces/ICiphernodeRegistry.sol/ICiphernodeRegistry.json shows inputSourceName="project/contracts/interfaces/ICiphernodeRegistry.sol" and a buildInfoId.
  • Quick scan under packages found no JS/TS references to artifacts.readArtifactSync, artifact.sourceName, or readArtifactSync; if any tooling relies on artifact paths, update it to use buildInfoId instead.
packages/enclave-contracts/contracts/Enclave.sol (1)

173-173: Whitespace-only change - no functional impact.

This is a cosmetic formatting change that adds a blank line for better code readability. The change aligns with the broader code reformatting efforts in this PR's migration to Hardhat v3.

packages/enclave-contracts/deployed_contracts.json (1)

1-30: LGTM! Centralized deployment manifest provides clear structure.

The JSON structure is well-organized with proper nesting (network -> contract -> metadata). The contract entries include all necessary deployment information (address, blockNumber, and constructorArgs), and the constructor arguments properly reference each other (e.g., CiphernodeRegistry references Enclave address, NaiveRegistryFilter references CiphernodeRegistry address).

crates/entrypoint/build.rs (3)

25-25: LGTM! Path correctly updated to use centralized manifest.

The change from a deployments directory structure to a single deployed_contracts.json file aligns with the PR objective to consolidate deployment metadata.


35-37: LGTM! JSON parsing approach is appropriate.

The switch from directory traversal to JSON parsing is clean and matches the new centralized manifest approach.


65-65: LGTM! Build dependency correctly updated.

The rerun trigger properly points to the new centralized manifest file instead of the old deployments directory.

templates/default/deploy/default.ts (1)

11-63: LGTM! Successful migration to Hardhat v3 with proper deployment flow.

The deployment implementation correctly:

  • Awaits all deployments before contract interactions
  • Uses the new ESM export pattern
  • Properly stores deployment arguments for reuse
  • Handles chain-specific deployments
packages/enclave-contracts/package.json (1)

6-6: LGTM! Correct migration to ES modules.

Adding "type": "module" aligns with Hardhat v3's modern ESM-first approach and is consistent with the PR's migration goals.

templates/default/hardhat.config.ts (2)

54-62: LGTM! Clean implementation of account configuration

The account configuration logic properly handles both private key and mnemonic scenarios with appropriate fallbacks.


130-141: LGTM! Well-organized Solidity configuration

The npmFilesToBuild approach provides clear visibility of external dependencies and the contracts being compiled. The optimizer settings are appropriate for production deployments.

Comment thread packages/enclave-contracts/package.json
Comment thread packages/enclave-contracts/tasks/ciphernode.ts
Comment thread packages/enclave-contracts/tasks/enclave.ts
Comment thread packages/enclave-contracts/tasks/enclave.ts
Comment thread templates/default/hardhat.config.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Configure hardhat v3 across the monorepo (crisp and evm)

2 participants