Skip to content

Conversation

@tractorss
Copy link
Contributor

@tractorss tractorss commented Jan 6, 2026

PR-Codex overview

This PR introduces enhancements primarily for local development environments, including configurations for the localhost network, improved deployment scripts, and new local-specific constants and functions. It also includes updates to various contracts and their deployment settings.

Detailed summary

  • Added mining configuration in hardhat.config.ts for block mining.
  • Updated subgraph scripts to remove core-university.
  • Introduced isLocalDeployment function in processEnvConsts.ts.
  • Added isLocalhost function to index.ts for network checks.
  • Changed deployment timeout based on network in 00-rng-chainlink.ts.
  • Modified Docker Compose to allow non-deterministic full-text search.
  • Updated getGraphqlUrl to handle the new local subgraph.
  • Enhanced ERC20 deployment logic to use a local contract variant.
  • Adjusted DEFAULT_CHAIN logic to select hardhat for local deployment.
  • Updated scripts in package.json for local deployment and population.
  • Added new PinakionV2Local contract for local testing.
  • Improved README with instructions for local setup and Blockscout usage.

The following files were skipped due to too many changes: contracts/deployments/hardhat.viem.ts

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • Documentation

    • Expanded local deployment flow with new setup steps and configuration guidance.
    • Added Docker Desktop requirements and updated deployment sequence.
    • Introduced local Blockscout explorer setup documentation.
  • New Features

    • Added support for local Hardhat network deployments.
  • Chores

    • Updated environment and network configurations for local deployments.

✏️ Tip: You can customize this high-level summary in your review settings.

@netlify
Copy link

netlify bot commented Jan 6, 2026

Deploy Preview for kleros-v2-neo failed. Why did it fail? →

Name Link
🔨 Latest commit 79dfe04
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-neo/deploys/695cffd68ffa9700086b8f54

@netlify
Copy link

netlify bot commented Jan 6, 2026

Deploy Preview for kleros-v2-testnet-devtools failed. Why did it fail? →

Name Link
🔨 Latest commit 79dfe04
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-testnet-devtools/deploys/695cffd6e5d130000853f501

@netlify
Copy link

netlify bot commented Jan 6, 2026

Deploy Preview for kleros-v2-testnet ready!

Name Link
🔨 Latest commit 79dfe04
🔍 Latest deploy log https://app.netlify.com/projects/kleros-v2-testnet/deploys/695cffd6abcf150008d387ba
😎 Deploy Preview https://deploy-preview-2212--kleros-v2-testnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

Walkthrough

This PR adds comprehensive local development support by introducing Hardhat localhost detection utilities, modifying deployment scripts with conditional behavior for local networks, creating a new PinakionV2Local token contract, converting wagmi config to async artifact generation, and updating web3 integration to route traffic through local Hardhat endpoints instead of production chains.

Changes

Cohort / File(s) Summary
Local Environment Detection & Utilities
contracts/deploy/utils/index.ts
New isLocalhost() utility function detects localhost deployments via network name or chainId 31337; used throughout deployment scripts and web config to conditionally apply local behavior.
Deployment Scripts (localhost behavior)
contracts/deploy/00-home-chain-arbitration.ts, contracts/deploy/00-rng-chainlink.ts, contracts/deploy/utils/deployTokens.ts
Updated scripts use isLocalhost() to treat local deployments as devnet-equivalent for timing parameters; conditionally deploy PinakionV2Local instead of TestERC20 on localhost; RNG fallback timeout reduced to 10s for localhost vs 30min for production.
Local Token Contract
contracts/src/token/mock/PinakionV2Local.sol
New ERC20 token contract with owner-only minting, increaseAllowance/decreaseAllowance overrides, and ETH/token recovery utilities for local testing.
Wagmi Artifact Configuration
contracts/wagmi.config.hardhat.ts, web/wagmi.config.ts
Converted contracts/wagmi.config.hardhat.ts to async config generation with multi-network artifact discovery and merging; updated web/wagmi.config.ts to include hardhat chain and support dynamic artifact loading with hardhatChainName parameter.
Local Build & Deployment Scripts
contracts/package.json, contracts/hardhat.config.ts, subgraph/scripts/all.sh
Added populate:local and updated start-local/deploy-local scripts with Resolver tag; enabled Hardhat auto-mining at 5s interval; removed core-university from subgraph build loop.
Web Configuration for Localhost
web/.env.local.public, web/src/consts/index.ts, web/src/consts/chains.ts, web/src/consts/processEnvConsts.ts, web/src/context/Web3Provider.tsx, web/src/utils/getGraphqlUrl.ts
Added isLocalDeployment predicate and HARDHAT_NODE_RPC constant; updated chain/transport resolution to use hardhat when local; modified subgraph URL lookup to include hardhat chain mapping.
Infrastructure & Documentation
services/graph-node/docker-compose.yml, README.md
Added Graph Node non-deterministic fulltext search flag; updated deployment flow documentation with localhost-specific steps (populate, viem bindings, Blockscout setup); noted ArbitrumSepolia as artifact source.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

Type: Feature🗿, Package: Web, Package: Contracts

Suggested reviewers

  • kemuru
  • alcercu
  • jaybuidl

Poem

🐰 Local chains spring to life with hardhat's gentle call,
Artifacts merge and wagmi dances through them all,
PinakionV2 hops in, localhost takes the stage,
Development blooms on a decentralized page! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Feat/testing implementation' is vague and generic, using non-descriptive terms that don't convey specific information about the substantial infrastructure and configuration changes implemented across contracts, web, and services. Consider a more descriptive title that captures the main objective, such as 'Add local Hardhat development environment support' or 'Support local blockchain testing with Hardhat integration'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

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

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 6, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI Agents
In @contracts/deploy/utils/deployTokens.ts:
- Around line 24-25: Fix the typo in the inline comment inside deployTokens.ts:
change "ERC20contract" to "ERC20 contract" in the comment that explains swapping
the local ERC20 implementation to one with increaseAllowance (refer to the
comment containing "increaseAllowance" in deployTokens.ts).

In @contracts/src/token/mock/PinakionV2Local.sol:
- Around line 25-34: The recoverTokens function incorrectly wraps
SafeERC20.safeTransfer (which returns void) in a require and uses .send for ETH;
remove the require and call the safeTransfer library call directly (e.g.,
token.safeTransfer(owner(), balance) or SafeERC20.safeTransfer(token, owner(),
balance) depending on imports), and replace
payable(owner()).send(address(this).balance) with a call pattern that bubbles
errors (e.g., (bool success, ) = payable(owner()).call{value:
address(this).balance}(""); require(success, "ETH transfer failed");) so
failures revert correctly; keep references to recoverTokens, token,
safeTransfer, and owner() when making the edits.

In @README.md:
- Around line 223-239: Fix the malformed link fragment and heading level:
replace the fragment text "#####shell-1---local-rpc-with-contracts-deployed"
used in the [hardhat node] link with a proper fragment starting with a single
hash (e.g., "#shell-1---local-rpc-with-contracts-deployed"), and change the
"#### Step 2: Start the Docker compose stack" heading to "### Step 2: Start the
Docker compose stack" so the heading hierarchy flows from "##" to "###"; also
ensure the localhost URL is written as <http://localhost> for consistency.

In @web/src/consts/processEnvConsts.ts:
- Line 23: The file exports an unused legacy function isLocalDeployment that
reads process.env.REACT_APP_DEPLOYMENT and duplicates behavior already
implemented in index.ts; either delete web/src/consts/processEnvConsts.ts
entirely, or move/merge the isLocalDeployment export into
web/src/consts/index.ts replacing process.env.REACT_APP_DEPLOYMENT with
import.meta.env.REACT_APP_DEPLOYMENT to match Vite usage, and remove any
duplicate exports so only the index.ts implementation remains.
🧹 Nitpick comments (5)
contracts/src/token/mock/PinakionV2Local.sol (1)

36-51: Add a comment explaining why increaseAllowance and decreaseAllowance are manually implemented.

These functions were removed from OpenZeppelin ERC20 in v5 as non-standard helpers, but your contract reimplements them. Adding a comment clarifying the rationale (compatibility with existing code, backwards compatibility, etc.) will help future maintainers understand the intent.

contracts/deploy/utils/index.ts (1)

31-32: Consider clarifying the comment.

The comment mentions the network name is "hardhat" when deployed while starting the node, but the code checks for network.name === "localhost". While the chainId check correctly handles both cases (covering "hardhat" name via the chainId), the comment could be clearer.

🔎 Suggested comment improvement
-// when deployed while starting node, the network name is "hardhat", the common factor for determining local node is chainId
+// The network name can be "localhost" or "hardhat" (when deployed while starting the node).
+// ChainId 31337 is the common factor for reliably detecting local Hardhat nodes.
 export const isLocalhost = (network: Network) => network.name === "localhost" || network.config.chainId === 31337;
contracts/deploy/utils/deployTokens.ts (1)

26-27: Consider extracting the repeated condition.

The condition ticker === "PNK" && isLocalhost(hre.network) is repeated on consecutive lines. While this works correctly, extracting it to a variable would improve maintainability.

🔎 Suggested refactor
-  const contractName = ticker === "PNK" && isLocalhost(hre.network) ? "PinakionV2Local" : "TestERC20";
-  const args = ticker === "PNK" && isLocalhost(hre.network) ? [] : [ticker, ticker];
+  const isPNKLocalDeployment = ticker === "PNK" && isLocalhost(hre.network);
+  const contractName = isPNKLocalDeployment ? "PinakionV2Local" : "TestERC20";
+  const args = isPNKLocalDeployment ? [] : [ticker, ticker];
web/src/context/Web3Provider.tsx (1)

53-56: Potential undefined access in defaultTransport websocket fallback.

chain.rpcUrls.default?.webSocket?.[0] may be undefined for chains that don't provide a default WebSocket URL. While webSocket(undefined) is handled gracefully by viem (it becomes a no-op in the fallback), consider making the fallback more explicit or adding a comment explaining this behavior.

🔎 Optional: Make undefined handling explicit
 const defaultTransport = (chain: AppKitNetwork) =>
-  fallback([http(chain.rpcUrls.default?.http?.[0]), webSocket(chain.rpcUrls.default?.webSocket?.[0])]);
+  fallback([
+    http(chain.rpcUrls.default?.http?.[0]),
+    // WebSocket may not be available for all chains; fallback handles undefined gracefully
+    ...(chain.rpcUrls.default?.webSocket?.[0] ? [webSocket(chain.rpcUrls.default.webSocket[0])] : []),
+  ]);
contracts/wagmi.config.hardhat.ts (1)

2-2: Same import assertion syntax note as web/wagmi.config.ts.

Biome flags the assert { type: "json" } syntax. Consider updating to with { type: "json" } for consistency if your TypeScript/bundler versions support import attributes.

🔎 Proposed update to import attributes syntax
-import IHomeGateway from "./artifacts/src/gateway/interfaces/IHomeGateway.sol/IHomeGateway.json" assert { type: "json" };
+import IHomeGateway from "./artifacts/src/gateway/interfaces/IHomeGateway.sol/IHomeGateway.json" with { type: "json" };
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46da5a2 and 79dfe04.

📒 Files selected for processing (19)
  • README.md
  • contracts/deploy/00-home-chain-arbitration.ts
  • contracts/deploy/00-rng-chainlink.ts
  • contracts/deploy/utils/deployTokens.ts
  • contracts/deploy/utils/index.ts
  • contracts/deployments/hardhat.viem.ts
  • contracts/hardhat.config.ts
  • contracts/package.json
  • contracts/src/token/mock/PinakionV2Local.sol
  • contracts/wagmi.config.hardhat.ts
  • services/graph-node/docker-compose.yml
  • subgraph/scripts/all.sh
  • web/.env.local.public
  • web/src/consts/chains.ts
  • web/src/consts/index.ts
  • web/src/consts/processEnvConsts.ts
  • web/src/context/Web3Provider.tsx
  • web/src/utils/getGraphqlUrl.ts
  • web/wagmi.config.ts
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2024-11-19T05:31:48.701Z
Learnt from: Harman-singh-waraich
Repo: kleros/kleros-v2 PR: 1744
File: web/src/hooks/useGenesisBlock.ts:9-31
Timestamp: 2024-11-19T05:31:48.701Z
Learning: In `useGenesisBlock.ts`, within the `useEffect` hook, the conditions (`isKlerosUniversity`, `isKlerosNeo`, `isTestnetDeployment`) are mutually exclusive, so multiple imports won't execute simultaneously, and race conditions are not a concern.

Applied to files:

  • contracts/deploy/00-home-chain-arbitration.ts
  • contracts/deploy/utils/index.ts
  • web/src/consts/processEnvConsts.ts
  • web/src/consts/index.ts
  • contracts/deploy/00-rng-chainlink.ts
📚 Learning: 2024-10-14T13:58:25.708Z
Learnt from: Harman-singh-waraich
Repo: kleros/kleros-v2 PR: 1703
File: web/src/hooks/queries/usePopulatedDisputeData.ts:58-61
Timestamp: 2024-10-14T13:58:25.708Z
Learning: In `web/src/hooks/queries/usePopulatedDisputeData.ts`, the query and subsequent logic only execute when `disputeData.dispute?.arbitrableChainId` and `disputeData.dispute?.externalDisputeId` are defined, so `initialContext` properties based on these values are safe to use without additional null checks.

Applied to files:

  • web/src/utils/getGraphqlUrl.ts
📚 Learning: 2024-10-15T16:18:32.543Z
Learnt from: Harman-singh-waraich
Repo: kleros/kleros-v2 PR: 1687
File: web/src/context/AtlasProvider.tsx:225-244
Timestamp: 2024-10-15T16:18:32.543Z
Learning: In `web/src/context/AtlasProvider.tsx`, the `atlasUri` variable comes from environment variables and does not change, so it does not need to be included in dependency arrays.

Applied to files:

  • web/.env.local.public
  • web/src/consts/index.ts
📚 Learning: 2024-10-22T09:38:20.093Z
Learnt from: Harman-singh-waraich
Repo: kleros/kleros-v2 PR: 1703
File: kleros-sdk/src/dataMappings/utils/actionTypes.ts:1-1
Timestamp: 2024-10-22T09:38:20.093Z
Learning: In the TypeScript file `kleros-sdk/src/dataMappings/utils/actionTypes.ts`, the `Abi` type is parsed later in the action functions, so importing `Abi` from `viem` in this file is unnecessary.

Applied to files:

  • web/wagmi.config.ts
📚 Learning: 2025-09-03T22:48:32.972Z
Learnt from: jaybuidl
Repo: kleros/kleros-v2 PR: 0
File: :0-0
Timestamp: 2025-09-03T22:48:32.972Z
Learning: In the Kleros v2 codebase, the team prioritizes gas optimization over strict CEI pattern compliance when dealing with trusted contracts. For penalty execution logic, they prefer batching storage writes (`round.pnkPenalties`) rather than updating incrementally after each penalty calculation to save gas costs, as the risk is extremely low between trusted contracts.

Applied to files:

  • contracts/src/token/mock/PinakionV2Local.sol
🧬 Code graph analysis (6)
contracts/deploy/00-home-chain-arbitration.ts (1)
contracts/deploy/utils/index.ts (2)
  • isDevnet (30-30)
  • isLocalhost (32-32)
web/src/consts/processEnvConsts.ts (1)
web/src/consts/index.ts (1)
  • isLocalDeployment (33-33)
web/src/consts/index.ts (1)
web/src/consts/processEnvConsts.ts (1)
  • isLocalDeployment (23-23)
contracts/deploy/00-rng-chainlink.ts (1)
contracts/deploy/utils/index.ts (1)
  • isLocalhost (32-32)
web/src/context/Web3Provider.tsx (3)
contracts/deploy/utils/index.ts (1)
  • isLocalhost (32-32)
web/src/consts/index.ts (2)
  • isLocalDeployment (33-33)
  • HARDHAT_NODE_RPC (53-53)
web/src/consts/processEnvConsts.ts (1)
  • isLocalDeployment (23-23)
web/src/consts/chains.ts (2)
web/src/consts/processEnvConsts.ts (3)
  • DEFAULT_CHAIN (32-32)
  • isLocalDeployment (23-23)
  • isProductionDeployment (22-22)
web/src/consts/index.ts (2)
  • isLocalDeployment (33-33)
  • isProductionDeployment (31-31)
🪛 Biome (2.1.2)
web/wagmi.config.ts

[error] 12-12: Expected a semicolon or an implicit semicolon after a statement, but found none

An explicit or implicit semicolon is expected here...

...Which is required to end this statement

(parse)


[error] 12-12: Expected a semicolon or an implicit semicolon after a statement, but found none

An explicit or implicit semicolon is expected here...

...Which is required to end this statement

(parse)

contracts/wagmi.config.hardhat.ts

[error] 2-2: Expected a semicolon or an implicit semicolon after a statement, but found none

An explicit or implicit semicolon is expected here...

...Which is required to end this statement

(parse)


[error] 2-2: Expected a semicolon or an implicit semicolon after a statement, but found none

An explicit or implicit semicolon is expected here...

...Which is required to end this statement

(parse)

🪛 dotenv-linter (4.0.0)
web/.env.local.public

[warning] 3-3: [UnorderedKey] The REACT_APP_CORE_SUBGRAPH key should go before the REACT_APP_DEPLOYMENT key

(UnorderedKey)

🪛 markdownlint-cli2 (0.18.1)
README.md

113-113: Dollar signs used before commands without showing output

(MD014, commands-show-output)


225-225: Link fragments should be valid

(MD051, link-fragments)


227-227: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)


239-239: Bare URL used

(MD034, no-bare-urls)

⏰ 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). (16)
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Redirect rules - kleros-v2-testnet
  • GitHub Check: Redirect rules - kleros-v2-testnet-devtools
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-testnet
  • GitHub Check: Header rules - kleros-v2-testnet-devtools
  • GitHub Check: Pages changed - kleros-v2-testnet
  • GitHub Check: Pages changed - kleros-v2-testnet
  • GitHub Check: Pages changed - kleros-v2-testnet-devtools
  • GitHub Check: Redirect rules - kleros-v2-neo
  • GitHub Check: Header rules - kleros-v2-neo
  • GitHub Check: Pages changed - kleros-v2-neo
  • GitHub Check: Analyze (javascript)
  • GitHub Check: hardhat-tests
  • GitHub Check: SonarCloud
  • GitHub Check: Mend Security Check
🔇 Additional comments (27)
contracts/hardhat.config.ts (1)

60-63: LGTM!

The mining configuration with auto: true and a 5-second interval provides predictable block times for local development and testing. This is a standard pattern for simulating realistic block production while maintaining fast feedback loops.

services/graph-node/docker-compose.yml (2)

26-26: Acknowledge local-only configuration for non-deterministic fulltext search.

Enabling GRAPH_ALLOW_NON_DETERMINISTIC_FULLTEXT_SEARCH is appropriate for local development but should never be used in production as it can cause inconsistent query results across Graph Node instances. This is acceptable since this docker-compose is for local development only.


38-38: LGTM!

The postgres command reformatting is a non-functional change that improves readability.

contracts/package.json (2)

63-65: LGTM!

Adding the Resolver tag to both start-local and deploy-local scripts ensures consistent local deployment of resolver contracts alongside arbitration components.


70-70: LGTM!

The populate:local script provides a convenient way to seed local development with courts and policy registry data from v2_devnet, streamlining the local setup workflow.

web/.env.local.public (1)

2-5: LGTM!

The environment variable updates correctly configure the web app for local development, pointing to local Graph Node endpoints and setting the deployment mode to localhost. This aligns with the broader local development infrastructure changes in this PR.

subgraph/scripts/all.sh (1)

13-13: The removal of core-university from the batch loop is intentional and safe.

The core-university subgraph remains fully functional with dedicated npm scripts in package.json (lines 24-32), including update, codegen, build, test, deploy, and rebuild commands. The change to all.sh is a deliberate scope reduction for the batch automation script, allowing developers to run core and drt subgraphs together while invoking core-university commands individually when needed. This does not break any workflows.

contracts/deploy/00-rng-chainlink.ts (2)

3-3: LGTM!

The addition of isLocalhost to the import aligns with the local development support introduced across the deployment scripts.


79-79: LGTM!

The conditional timeout logic is well-designed: 10 seconds for local development (appropriate for the 5-second Hardhat mining interval) and 30 minutes for production networks.

web/src/utils/getGraphqlUrl.ts (2)

1-1: LGTM!

The addition of hardhat to the wagmi/chains import enables local development support.


13-14: LGTM!

The hardhat chain mapping follows the same pattern as other chains, using an environment variable with an appropriate fallback message.

contracts/deploy/00-home-chain-arbitration.ts (2)

6-6: LGTM!

The addition of isLocalhost to the imports enables localhost detection for devnet-equivalent behavior.


50-52: LGTM!

Treating localhost as devnet-equivalent for timing constants is appropriate. The shorter minStakingTime (180s vs 1800s) and maxFreezingTime (600s vs 1800s) enable faster testing cycles during local development.

contracts/deploy/utils/deployTokens.ts (2)

4-4: LGTM!

The addition of isLocalhost to the imports follows the existing pattern.


28-33: LGTM!

The conditional contract deployment correctly uses PinakionV2Local for PNK on localhost and TestERC20 otherwise, with appropriate constructor arguments for each case.

web/src/consts/chains.ts (2)

14-18: LGTM - Local deployment chain selection is correctly prioritized.

The ternary chain correctly checks isLocalDeployment() first, then falls back to the production/testnet logic. This ensures local development uses Hardhat while preserving existing behavior for other environments.


21-27: The code correctly handles the chain/transport mismatch for local deployments. While QUERY_CHAINS includes gnosis/gnosisChiado and mainnet regardless of deployment type, the createAppKit configuration uses allowUnsupportedChain: true (line 110 of Web3Provider.tsx) which gracefully allows chains without corresponding transports. Additionally, mainnet is included in the localhost transport for ENS resolution. Since gnosis/gnosisChiado are read-only query chains not needed during local development, no changes are required.

web/src/consts/index.ts (2)

52-53: LGTM - Standard Hardhat RPC endpoint.

The HARDHAT_NODE_RPC constant uses the default Hardhat network address. This is the standard endpoint for local Hardhat nodes.


33-33: The isLocalDeployment function in index.ts is the only active version—processEnvConsts.ts is not imported anywhere in the codebase.

The concern about duplication is partially valid, but processEnvConsts.ts (using process.env) appears to be unused or legacy code. Only the import.meta.env version in index.ts is actively imported and used by chains.ts and Web3Provider.tsx. Consider clarifying whether processEnvConsts.ts should be maintained or removed.

Likely an incorrect or invalid review comment.

web/src/context/Web3Provider.tsx (2)

67-71: LGTM - Local transport correctly includes mainnet for ENS resolution.

The local transport configuration properly includes both the Hardhat node and mainnet (via Alchemy) to support ENS resolution during local development.


98-108: LGTM - SDK and AppKit configuration consistently updated for local deployment.

Both configureSDK and createAppKit use the same isLocalhost check to select the appropriate chain and transport, maintaining consistency across the Web3 stack.

README.md (1)

110-123: LGTM - Clear instructions for local data population and artifact generation.

The new section clearly documents the required steps after local deployment, including the court population and wagmi/viem bindings regeneration.

web/wagmi.config.ts (3)

92-96: LGTM - Localhost deployment case correctly configured.

The new localhost case properly sets viemNetwork to "hardhat", hardhatNetwork to "localhost", and uses hardhatViem for the arbitrator contracts, maintaining consistency with the artifact directory structure.


20-20: Good design: Optional hardhatChainName parameter enables flexible artifact resolution.

The readArtifacts function now accepts an optional hardhatChainName to decouple the viem chain name from the Hardhat deployment directory name. This elegantly handles cases like localhost/hardhat mapping.

Also applies to: 51-51


12-16: The assert { type: "json" } syntax is the standard ES2022 import assertions syntax and is fully supported by TypeScript 5.6.3 with module set to ESNext. This same syntax is used consistently across 7 files in the project (web/wagmi.config.ts, web-devtools/wagmi.config.ts, web/scripts/gitInfo.js, and multiple wagmi config files). While TypeScript 5.5+ nominally prefers with { type: "json" } for forward compatibility, assert remains valid and functional. The suggestion to update only this one file creates an inconsistency with the rest of the codebase and is not a functional requirement.

contracts/wagmi.config.hardhat.ts (2)

5-27: LGTM - Async config with multi-network artifact discovery.

The async getConfig function properly:

  1. Reads artifacts from localhost, gnosisChiado, and sepolia networks
  2. Logs discovered artifacts for debugging visibility
  3. Merges artifacts across networks using the helper
  4. Includes IHomeGateway in the final output

The comment on line 10 about network renaming breaking other scripts is a useful note for future maintainers.


3-3: No action required. The wagmiHelpers module exists at contracts/scripts/wagmiHelpers.ts and properly exports all three required functions: getAbi (line 11), readArtifacts (line 15), and merge (line 45).

Comment on lines +24 to +25
// locally the ERC20contract lacks `increaseAllowance` function,
// so we swap it with an updated contract to allow local development
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix typo in comment.

The comment contains a typo: "ERC20contract" should be "ERC20 contract".

🔎 Proposed fix
-  // locally the ERC20contract lacks `increaseAllowance` function,
+  // locally the ERC20 contract lacks `increaseAllowance` function,
   // so we swap it with an updated contract to allow local development
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// locally the ERC20contract lacks `increaseAllowance` function,
// so we swap it with an updated contract to allow local development
// locally the ERC20 contract lacks `increaseAllowance` function,
// so we swap it with an updated contract to allow local development
🤖 Prompt for AI Agents
In @contracts/deploy/utils/deployTokens.ts around lines 24 - 25, Fix the typo in
the inline comment inside deployTokens.ts: change "ERC20contract" to "ERC20
contract" in the comment that explains swapping the local ERC20 implementation
to one with increaseAllowance (refer to the comment containing
"increaseAllowance" in deployTokens.ts).

Comment on lines +25 to +34
function recoverTokens(address _token) public onlyOwner {
if (_token == address(0)) {
require(payable(owner()).send(address(this).balance), "Transfer failed");
return;
}

IERC20 token = IERC20(_token);
uint balance = token.balanceOf(address(this));
require(token.safeTransfer(payable(owner()), balance), "Token transfer failed");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: safeTransfer returns void, not bool—this will always revert.

SafeERC20.safeTransfer does not return a boolean; it reverts on failure. The require statement on line 33 will always fail because the return value is void (treated as false).

Additionally, using .send() on line 27 is risky as it only forwards 2300 gas, which may fail for contracts with complex receive/fallback functions.

🔎 Proposed fix
     function recoverTokens(address _token) public onlyOwner {
         if (_token == address(0)) {
-            require(payable(owner()).send(address(this).balance), "Transfer failed");
+            (bool success, ) = payable(owner()).call{value: address(this).balance}("");
+            require(success, "Transfer failed");
             return;
         }

         IERC20 token = IERC20(_token);
         uint balance = token.balanceOf(address(this));
-        require(token.safeTransfer(payable(owner()), balance), "Token transfer failed");
+        token.safeTransfer(owner(), balance);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function recoverTokens(address _token) public onlyOwner {
if (_token == address(0)) {
require(payable(owner()).send(address(this).balance), "Transfer failed");
return;
}
IERC20 token = IERC20(_token);
uint balance = token.balanceOf(address(this));
require(token.safeTransfer(payable(owner()), balance), "Token transfer failed");
}
function recoverTokens(address _token) public onlyOwner {
if (_token == address(0)) {
(bool success, ) = payable(owner()).call{value: address(this).balance}("");
require(success, "Transfer failed");
return;
}
IERC20 token = IERC20(_token);
uint balance = token.balanceOf(address(this));
token.safeTransfer(owner(), balance);
}
🤖 Prompt for AI Agents
In @contracts/src/token/mock/PinakionV2Local.sol around lines 25 - 34, The
recoverTokens function incorrectly wraps SafeERC20.safeTransfer (which returns
void) in a require and uses .send for ETH; remove the require and call the
safeTransfer library call directly (e.g., token.safeTransfer(owner(), balance)
or SafeERC20.safeTransfer(token, owner(), balance) depending on imports), and
replace payable(owner()).send(address(this).balance) with a call pattern that
bubbles errors (e.g., (bool success, ) = payable(owner()).call{value:
address(this).balance}(""); require(success, "ETH transfer failed");) so
failures revert correctly; keep references to recoverTokens, token,
safeTransfer, and owner() when making the edits.

Comment on lines +223 to +239
## Run a local Blockscout explorer to inspect transactions on hardhat (Optional)

Make sure [hardhat node](#####shell-1---local-rpc-with-contracts-deployed) is running.

#### Step 1 - Clone [blockscout](https://github.com/blockscout/blockscout/blob/master/docker-compose/README.md) repo

```bash
git clone https://github.com/blockscout/blockscout.git
```

#### Step 2: Start the Docker compose stack

```bash
docker-compose -f hardhat-network.yml up -d
```

This should run a Blockscout locally at http://localhost.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix heading hierarchy and link fragment.

Static analysis flagged two issues:

  1. Line 225: The link fragment #####shell-1---local-rpc-with-contracts-deployed appears malformed (uses 5 hashes instead of matching the actual heading format)
  2. Line 227: Heading jumps from ## (h2) directly to #### (h4), skipping h3
🔎 Proposed fixes
 ## Run a local Blockscout explorer to inspect transactions on hardhat (Optional)

-Make sure [hardhat node](#####shell-1---local-rpc-with-contracts-deployed) is running.
+Make sure [hardhat node](#shell-1---local-rpc-with-contracts-deployed) is running.

-#### Step 1 - Clone [blockscout](https://github.com/blockscout/blockscout/blob/master/docker-compose/README.md) repo
+### Step 1 - Clone [blockscout](https://github.com/blockscout/blockscout/blob/master/docker-compose/README.md) repo

 ```bash
 git clone https://github.com/blockscout/blockscout.git

-#### Step 2: Start the Docker compose stack
+### Step 2: Start the Docker compose stack

docker-compose -f hardhat-network.yml up -d

-This should run a Blockscout locally at http://localhost.
+This should run a Blockscout locally at http://localhost.

</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
## Run a local Blockscout explorer to inspect transactions on hardhat (Optional)

Make sure [hardhat node](#shell-1---local-rpc-with-contracts-deployed) is running.

### Step 1 - Clone [blockscout](https://github.com/blockscout/blockscout/blob/master/docker-compose/README.md) repo

🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

225-225: Link fragments should be valid

(MD051, link-fragments)


227-227: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)


239-239: Bare URL used

(MD034, no-bare-urls)

🤖 Prompt for AI Agents
In @README.md around lines 223 - 239, Fix the malformed link fragment and
heading level: replace the fragment text
"#####shell-1---local-rpc-with-contracts-deployed" used in the [hardhat node]
link with a proper fragment starting with a single hash (e.g.,
"#shell-1---local-rpc-with-contracts-deployed"), and change the "#### Step 2:
Start the Docker compose stack" heading to "### Step 2: Start the Docker compose
stack" so the heading hierarchy flows from "##" to "###"; also ensure the
localhost URL is written as <http://localhost> for consistency.

export const ETH_SIGNATURE_REGEX = /^0x([a-fA-F0-9]{130})+$|^0x$/;

export const isProductionDeployment = () => process.env.REACT_APP_DEPLOYMENT === "mainnet";
export const isLocalDeployment = () => process.env.REACT_APP_DEPLOYMENT === "localhost";
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the exact code at the specified locations
echo "=== processEnvConsts.ts (around line 23) ==="
head -30 web/src/consts/processEnvConsts.ts | cat -n

echo -e "\n=== index.ts (around line 32) ==="
head -40 web/src/consts/index.ts | cat -n

Repository: kleros/kleros-v2

Length of output: 4064


🏁 Script executed:

#!/bin/bash
# Check for vite configuration
echo "=== Vite config files ==="
find . -maxdepth 2 -name "vite.config.*" -o -name "vite.config.ts" -o -name "vite.config.js"

echo -e "\n=== package.json dev dependencies (checking for vite) ==="
cat package.json | jq '.devDependencies | keys[] | select(contains("vite"))'

Repository: kleros/kleros-v2

Length of output: 193


🏁 Script executed:

#!/bin/bash
# Analyze the full distribution of env variable patterns
echo "=== process.env usage in web/src ==="
rg -c "process\.env\." web/src --type=ts --type=tsx -g '!*.test.*' | wc -l
rg "process\.env\." web/src --type=ts --type=tsx -g '!*.test.*' | head -15

echo -e "\n=== import.meta.env usage in web/src ==="
rg -c "import\.meta\.env\." web/src --type=ts --type=tsx -g '!*.test.*' | wc -l
rg "import\.meta\.env\." web/src --type=ts --type=tsx -g '!*.test.*' | head -15

Repository: kleros/kleros-v2

Length of output: 271


🏁 Script executed:

#!/bin/bash
# Check imports of both files to see which is actively used
echo "=== Imports of processEnvConsts.ts ==="
rg "from.*processEnvConsts" web/src -A 2 -B 2

echo -e "\n=== Imports of consts/index.ts ==="
rg 'from.*["\']consts["\']' web/src -A 2 -B 2 | head -40

echo -e "\n=== Check for explicit index imports ==="
rg 'from.*consts/index' web/src

Repository: kleros/kleros-v2

Length of output: 220


🏁 Script executed:

#!/bin/bash
# Check if there are any comments or documentation about these files
echo "=== File headers/comments in processEnvConsts.ts ==="
head -5 web/src/consts/processEnvConsts.ts

echo -e "\n=== File headers/comments in index.ts ==="
head -5 web/src/consts/index.ts

echo -e "\n=== Check if processEnvConsts.ts is exported from index.ts ==="
rg "processEnvConsts" web/src/consts/

Repository: kleros/kleros-v2

Length of output: 648


🏁 Script executed:

#!/bin/bash
# Check imports more carefully with proper escaping
echo "=== Imports of processEnvConsts.ts ==="
rg "processEnvConsts" web/src

echo -e "\n=== All imports from consts (index.ts) ==="
rg "from ['\"]consts['\"]" web/src | head -30

Repository: kleros/kleros-v2

Length of output: 142


🏁 Script executed:

#!/bin/bash
# Check tsconfig or any references to consts module resolution
echo "=== tsconfig.json references ==="
cat web/tsconfig.json | grep -A 5 -B 5 "paths\|baseUrl" || echo "No special path config found"

echo -e "\n=== Check web directory structure ==="
ls -la web/src/consts/

Repository: kleros/kleros-v2

Length of output: 1172


🏁 Script executed:

#!/bin/bash
# Check if processEnvConsts is referenced from index.ts or exported
echo "=== Complete index.ts file ==="
cat web/src/consts/index.ts

echo -e "\n=== Check tsconfig paths more carefully ==="
cat web/tsconfig.json | jq '.compilerOptions.paths'

Repository: kleros/kleros-v2

Length of output: 3163


🏁 Script executed:

#!/bin/bash
# Check if there are any direct imports of consts files in the entire web directory
echo "=== Direct imports from consts/ ==="
rg "from ['\"].*consts/" web/src | head -20

echo -e "\n=== Imports from consts without explicit file ==="
rg "from ['\"]consts['\"]" web/src | head -20

Repository: kleros/kleros-v2

Length of output: 2045


🏁 Script executed:

#!/bin/bash
# Check git history of processEnvConsts to understand its purpose
echo "=== Check if processEnvConsts.ts is referenced in comments or README ==="
rg "processEnvConsts" web/ --type=md --type=txt

echo -e "\n=== Check all files in consts directory to see if any re-export from processEnvConsts ==="
grep -r "processEnvConsts" web/src/consts/

echo -e "\n=== See if there are any TypeScript declaration files that might reference it ==="
find web/src -name "*.d.ts" -exec grep -l "processEnvConsts" {} \;

Repository: kleros/kleros-v2

Length of output: 306


🏁 Script executed:

#!/bin/bash
# Double-check by looking for any dynamic imports or string references
echo "=== Search for any string references to processEnvConsts ==="
rg "processEnvConsts" web/

echo -e "\n=== Check if it's exported from barrel files ==="
grep -n "export.*from.*processEnvConsts" web/src/consts/*

Repository: kleros/kleros-v2

Length of output: 170


🏁 Script executed:

#!/bin/bash
# Final check: see if processEnvConsts.ts is actually being used in any build configs or if it's truly dead code
echo "=== Check vite.config.js for any special handling ==="
cat web/vite.config.js

echo -e "\n=== Check if there are any glob imports or dynamic requires ==="
rg "processEnvConsts|consts/\*" web/src --type=ts --type=tsx

Repository: kleros/kleros-v2

Length of output: 1497


Remove or consolidate processEnvConsts.ts — it's unused dead code.

This file is not imported anywhere in the codebase and duplicates functionality already present in web/src/consts/index.ts. Additionally, it uses process.env.REACT_APP_DEPLOYMENT which is the legacy pattern; the active file (index.ts) correctly uses import.meta.env.REACT_APP_DEPLOYMENT for Vite. Either delete processEnvConsts.ts or consolidate the duplicate exports into index.ts.

🤖 Prompt for AI Agents
In @web/src/consts/processEnvConsts.ts at line 23, The file exports an unused
legacy function isLocalDeployment that reads process.env.REACT_APP_DEPLOYMENT
and duplicates behavior already implemented in index.ts; either delete
web/src/consts/processEnvConsts.ts entirely, or move/merge the isLocalDeployment
export into web/src/consts/index.ts replacing process.env.REACT_APP_DEPLOYMENT
with import.meta.env.REACT_APP_DEPLOYMENT to match Vite usage, and remove any
duplicate exports so only the index.ts implementation remains.

@jaybuidl jaybuidl added Type: Toolchain ⚒️ Build tools configuration, CI/CD Package: Web Court web frontend Package: Contracts Court smart contracts Package: Subgraph Court subgraph labels Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Package: Contracts Court smart contracts Package: Subgraph Court subgraph Package: Web Court web frontend Type: Toolchain ⚒️ Build tools configuration, CI/CD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants