Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,9 @@ if echo "$staged_files" | grep -q "^web-devtools/"; then
yarn workspace @kleros/kleros-v2-web-devtools check-types
fi

#Check if any file is in the web directory and if so, check types
if echo "$staged_files" | grep -q "^web/"; then
yarn workspace @kleros/kleros-v2-web check-types
fi

yarn lint-staged
52 changes: 52 additions & 0 deletions eslint-config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# @kleros/kleros-v2-eslint-config

Shared ESLint configuration to be used across the Kleros v2 monorepo.

## Usage

Workspaces that don't need custom rules can use the default config with a one-line `eslint.config.mjs`:

```js
export { default } from "@kleros/kleros-v2-eslint-config/flat.config.mjs";
```

## Flat-config migration shim

ESLint 9 requires the flat config format (`eslint.config.*`) and no longer reads legacy `.eslintrc` files automatically. `flat.config.mjs` uses `FlatCompat` to translate the legacy `.eslintrc.js` into a flat config, so the existing rules continue to apply.

## What's in the config

### Parser & environments

- **Parser:** `@typescript-eslint/parser`
- **`parserOptions.ecmaVersion`:** `2020`
- **Environments enabled:** `browser`, `node`, `es6`, `es2020`, `mocha`

### Extended configs

- `eslint:recommended` — ESLint's built-in baseline rules
- `plugin:@typescript-eslint/recommended` — TypeScript-aware rules
- `plugin:prettier/recommended` — runs Prettier as an ESLint rule and disables conflicting style rules
- `plugin:import/recommended` — import/export hygiene

### Plugins

`@typescript-eslint`, `prettier`, `import`, `n` (Node).

### Custom rule overrides

| Rule | Setting | Why |
| ------------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `no-unused-vars` | `off` | Replaced by the TS-aware variant. |
| `@typescript-eslint/no-unused-vars` | `error`, with `varsIgnorePattern` / `argsIgnorePattern` | Prefix a name with `_` (e.g. `_unused`, `_1`) or use an `ignored` / `Ignored` suffix to deliberately silence the rule for intentional placeholders. |
| `prettier/prettier` | `error` | Formatting violations fail lint. |
| `import/no-unresolved` | `error`, `commonjs: true` | Catches imports that won't resolve at runtime, including CJS `require` paths. |
| `n/no-unsupported-features/es-syntax` | `error`, `ignores: ["modules"]` | Flags ES syntax not supported by the configured Node target, but allows ES modules. |
| `n/no-missing-import` | `off` | Resolution is handled by `import/no-unresolved` + the TS resolver. |

### Resolver settings

Imports are resolved via:

- `eslint-import-resolver-typescript` (uses each workspace's `tsconfig.json`)
- Node resolver, with extensions `.js`, `.jsx`, `.ts`, `.tsx`
2 changes: 2 additions & 0 deletions kleros-sdk/src/types/reality-eth-lib.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//Declaration for @reality.eth/reality-eth-lib, which ships no TypeScript types and causes "noImplicitAny" errors.
//Remove this shim whenever the library exports types or is not needed.
declare module "@reality.eth/reality-eth-lib/formatters/question.js";
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@
"build:web:ci": "yarn workspaces focus @kleros/kleros-v2-web && yarn workspaces foreach -Ap --include kleros-app --include contracts run build && yarn workspace @kleros/kleros-v2-web build-netlify",
"build:web-devtools:ci": "yarn workspaces focus @kleros/kleros-v2-web-devtools && yarn workspaces foreach -Ap --include contracts run build && yarn workspace @kleros/kleros-v2-web-devtools build-netlify",
"build:contract-docs": "forge doc --build --out contracts/dist",
"start:contract-docs": "forge doc --serve"
"start:contract-docs": "forge doc --serve",
"check-types": "yarn workspaces foreach -A -v run check-types"
},
"alias": {
"process": "process/browser.js",
Expand Down
6 changes: 6 additions & 0 deletions web/.lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"*.{js,jsx,ts,tsx}": [
"eslint --fix --no-error-on-unmatched-pattern",
"prettier --write --no-error-on-unmatched-pattern"
]
}
14 changes: 13 additions & 1 deletion web/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const compat = new FlatCompat({

export default [
{
ignores: ["src/assets"],
ignores: ["src/assets", "src/hooks/contracts/generated.ts", "src/graphql/**/*"],
},
...fixupConfigRules(
compat.extends(
Expand Down Expand Up @@ -105,6 +105,18 @@ export default [
"security/detect-object-injection": "off",
"security/detect-non-literal-fs-filename": "off",

"no-restricted-imports": [
"error",
{
patterns: [
{
group: ["~*", "~/*"],
message: "Do not import using the '~' prefix.",
},
],
},
],

"import/extensions": [
"error",
"ignorePackages",
Expand Down
2 changes: 1 addition & 1 deletion web/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ declare global {

declare module "styled-components" {
type Theme = typeof lightTheme;
//eslint-disable-next-line @typescript-eslint/no-empty-interface
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface DefaultTheme extends Theme {}
}

Expand Down
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"build-mainnet": "scripts/runEnv.sh mainnet 'yarn generate && vite build'",
"build-netlify": "scripts/generateBuildInfo.sh && yarn generate && vite build",
"check-style": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
"check-types": "tsc --noEmit",
"check-types": "tsc --noEmit --declaration false",
"generate": "yarn generate:gql && yarn generate:hooks",
"generate:gql": "graphql-codegen --require tsconfig-paths/register",
"generate:hooks": "NODE_NO_WARNINGS=1 wagmi generate"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ export const argentinaConsumerProtectionCommitBuilder = defineCommitBuilder({
deps.storeCommitData(key, { choice, salt });

const commit = hashVote(choice, salt);
const chainKey = chain.id as keyof typeof disputeKitGatedArgentinaConsumerProtectionAddress;

return {
account,
address: disputeKitGatedArgentinaConsumerProtectionAddress[chain.id],
address: disputeKitGatedArgentinaConsumerProtectionAddress[chainKey],
abi: disputeKitGatedArgentinaConsumerProtectionAbi,
functionName: "castCommit",
args: [disputeId, voteIds, commit],
Expand Down
4 changes: 3 additions & 1 deletion web/src/actions/commit/builders/classic.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export const classicCommitBuilder = defineCommitBuilder({
deps.storeCommitData(key, { choice, salt });

const commit = hashVote(choice, salt);
const chainKey = chain.id as keyof typeof disputeKitClassicAddress;

return {
account,
address: disputeKitClassicAddress[chain.id],
address: disputeKitClassicAddress[chainKey],
abi: disputeKitClassicAbi,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
functionName: "castCommit",
args: [disputeId, voteIds, commit],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export const classicUniversityCommitBuilder = defineCommitBuilder({
deps.storeCommitData(key, { choice, salt });

const commit = hashVote(choice, salt);
const chainKey = chain.id as keyof typeof disputeKitClassicUniversityAddress;

return {
account,
address: disputeKitClassicUniversityAddress[chain.id],
address: disputeKitClassicUniversityAddress[chainKey],
abi: disputeKitClassicUniversityAbi,
functionName: "castCommit",
args: [disputeId, voteIds, commit],
Expand Down
4 changes: 3 additions & 1 deletion web/src/actions/commit/builders/gated.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ export const gatedCommitBuilder = defineCommitBuilder({
deps.storeCommitData(key, { choice, salt });

const commit = hashVote(choice, salt);
const chainKey = chain.id as keyof typeof disputeKitGatedAddress;

return {
account,
address: disputeKitGatedAddress[chain.id],
address: disputeKitGatedAddress[chainKey],
abi: disputeKitGatedAbi,
functionName: "castCommit",
args: [disputeId, voteIds, commit],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/commit/builders/gatedShutter.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ export const gatedShutterCommitBuilder = defineCommitBuilder({

const choiceCommit = hashVote(choice, salt);
const justificationCommit = hashJustification(salt, justification);
const chainKey = chain.id as keyof typeof disputeKitGatedShutterAddress;

return {
account,
address: disputeKitGatedShutterAddress[chain.id],
address: disputeKitGatedShutterAddress[chainKey],
abi: disputeKitGatedShutterAbi,
Comment thread
kyrers marked this conversation as resolved.
functionName: "castCommitShutter",
args: [disputeId, voteIds, choiceCommit, justificationCommit, identity as Hex, encryptedCommitment],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/commit/builders/shutter.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ export const shutterCommitBuilder = defineCommitBuilder({

const choiceCommit = hashVote(choice, BigInt(salt));
const justificationCommit = hashJustification(BigInt(salt), justification);
const chainKey = chain.id as keyof typeof disputeKitShutterAddress;

return {
account,
address: disputeKitShutterAddress[chain.id],
address: disputeKitShutterAddress[chainKey],
abi: disputeKitShutterAbi,
functionName: "castCommitShutter",
args: [disputeId, voteIds, choiceCommit, justificationCommit, identity as Hex, encryptedCommitment],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ export const argentinaConsumerProtectionFundAppealBuilder = defineFundAppealBuil
build: async (params: ArgentinaConsumerProtectionFundAppealParams, context) => {
const { disputeId, choice, fundAmount } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedArgentinaConsumerProtectionAddress;

return {
account,
address: disputeKitGatedArgentinaConsumerProtectionAddress[chain.id],
address: disputeKitGatedArgentinaConsumerProtectionAddress[chainKey],
abi: disputeKitGatedArgentinaConsumerProtectionAbi,
functionName: "fundAppeal",
args: [disputeId, choice],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/fundAppeal/builders/classic.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const classicFundAppealBuilder = defineFundAppealBuilder({
build: async (params: ClassicFundAppealParams, context) => {
const { disputeId, choice, fundAmount } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitClassicAddress;

return {
account,
address: disputeKitClassicAddress[chain.id],
address: disputeKitClassicAddress[chainKey],
Comment thread
kyrers marked this conversation as resolved.
abi: disputeKitClassicAbi,
functionName: "fundAppeal",
args: [disputeId, choice],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const classicUniversityFundAppealBuilder = defineFundAppealBuilder({
build: async (params: ClassicUniversityFundAppealParams, context) => {
const { disputeId, choice, fundAmount } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitClassicUniversityAddress;

return {
account,
address: disputeKitClassicUniversityAddress[chain.id],
address: disputeKitClassicUniversityAddress[chainKey],
Comment thread
kyrers marked this conversation as resolved.
abi: disputeKitClassicUniversityAbi,
functionName: "fundAppeal",
args: [disputeId, choice],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/fundAppeal/builders/gated.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const gatedFundAppealBuilder = defineFundAppealBuilder({
build: async (params: GatedFundAppealParams, context) => {
const { disputeId, choice, fundAmount } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedAddress;

return {
account,
address: disputeKitGatedAddress[chain.id],
address: disputeKitGatedAddress[chainKey],
abi: disputeKitGatedAbi,
functionName: "fundAppeal",
args: [disputeId, choice],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const gatedShutterFundAppealBuilder = defineFundAppealBuilder({
build: async (params: GatedShutterFundAppealParams, context) => {
const { disputeId, choice, fundAmount } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedShutterAddress;

return {
account,
address: disputeKitGatedShutterAddress[chain.id],
address: disputeKitGatedShutterAddress[chainKey],
abi: disputeKitGatedShutterAbi,
functionName: "fundAppeal",
args: [disputeId, choice],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/fundAppeal/builders/shutter.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const shutterFundAppealBuilder = defineFundAppealBuilder({
build: async (params: ShutterFundAppealParams, context) => {
const { disputeId, choice, fundAmount } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitShutterAddress;

return {
account,
address: disputeKitShutterAddress[chain.id],
address: disputeKitShutterAddress[chainKey],
abi: disputeKitShutterAbi,
functionName: "fundAppeal",
args: [disputeId, choice],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ export const argentinaConsumerProtectionRevealBuilder = defineRevealBuilder({
build: async (params: ArgentinaConsumerProtectionRevealParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedArgentinaConsumerProtectionAddress;

return {
account,
address: disputeKitGatedArgentinaConsumerProtectionAddress[chain.id],
address: disputeKitGatedArgentinaConsumerProtectionAddress[chainKey],
abi: disputeKitGatedArgentinaConsumerProtectionAbi,
functionName: "castVote",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/reveal/builders/classic.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const classicRevealBuilder = defineRevealBuilder({
build: async (params: ClassicRevealParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitClassicAddress;

return {
account,
address: disputeKitClassicAddress[chain.id],
address: disputeKitClassicAddress[chainKey],
Comment thread
kyrers marked this conversation as resolved.
abi: disputeKitClassicAbi,
functionName: "castVote",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const classicUniversityRevealBuilder = defineRevealBuilder({
build: async (params: ClassicUniversityRevealParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitClassicUniversityAddress;

return {
account,
address: disputeKitClassicUniversityAddress[chain.id],
address: disputeKitClassicUniversityAddress[chainKey],
Comment thread
kyrers marked this conversation as resolved.
abi: disputeKitClassicUniversityAbi,
functionName: "castVote",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/reveal/builders/gated.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const gatedRevealBuilder = defineRevealBuilder({
build: async (params: GatedRevealParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedAddress;

return {
account,
address: disputeKitGatedAddress[chain.id],
address: disputeKitGatedAddress[chainKey],
abi: disputeKitGatedAbi,
functionName: "castVote",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/reveal/builders/gatedShutter.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const gatedShutterRevealBuilder = defineRevealBuilder({
build: async (params: GatedShutterRevealParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedShutterAddress;

return {
account,
address: disputeKitGatedShutterAddress[chain.id],
address: disputeKitGatedShutterAddress[chainKey],
abi: disputeKitGatedShutterAbi,
functionName: "castVoteShutter",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/reveal/builders/shutter.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const shutterRevealBuilder = defineRevealBuilder({
build: async (params: ShutterRevealParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitShutterAddress;

return {
account,
address: disputeKitShutterAddress[chain.id],
address: disputeKitShutterAddress[chainKey],
abi: disputeKitShutterAbi,
functionName: "castVoteShutter",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
2 changes: 1 addition & 1 deletion web/src/actions/reveal/helpers/bruteForceChoice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { hashVote } from "utils/crypto/hashVote";
import { bruteForceChoice } from "./bruteForceChoice";

describe("bruteForceChoice", () => {
const createCommit = (choice: bigint, salt: `0x${string}`): string => hashVote(choice, BigInt(salt));
const createCommit = (choice: bigint, salt: `0x${string}`) => hashVote(choice, BigInt(salt));

const mockAnswers: Answer[] = [
{ id: "0x0", title: "Refuse To Arbitrate", description: "RTA" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ export const argentinaConsumerProtectionVoteBuilder = defineVoteBuilder({
build: async (params: ArgentinaConsumerProtectionVoteParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitGatedArgentinaConsumerProtectionAddress;

return {
account,
address: disputeKitGatedArgentinaConsumerProtectionAddress[chain.id],
address: disputeKitGatedArgentinaConsumerProtectionAddress[chainKey],
Comment thread
kyrers marked this conversation as resolved.
abi: disputeKitGatedArgentinaConsumerProtectionAbi,
functionName: "castVote",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
3 changes: 2 additions & 1 deletion web/src/actions/vote/builders/classic.builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ export const classicVoteBuilder = defineVoteBuilder({
build: async (params: ClassicVoteParams, context) => {
const { disputeId, voteIds, choice, salt, justification } = params;
const { chain, account } = context;
const chainKey = chain.id as keyof typeof disputeKitClassicAddress;

return {
account,
address: disputeKitClassicAddress[chain.id],
address: disputeKitClassicAddress[chainKey],
abi: disputeKitClassicAbi,
functionName: "castVote",
args: [disputeId, voteIds, choice, salt, justification],
Expand Down
Loading
Loading