|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Agent playbook for `dkg-evm-module`. |
| 4 | +Use this when building, testing, linting, and editing code in this repository. |
| 5 | + |
| 6 | +## Project snapshot |
| 7 | + |
| 8 | +- Stack: Hardhat + TypeScript + Solidity. |
| 9 | +- Package manager: `npm`. |
| 10 | +- CI Node version: `20.x`. |
| 11 | +- Solidity target: `^0.8.20`. |
| 12 | +- Core directories: |
| 13 | + - `contracts/` Solidity sources. |
| 14 | + - `deploy/` hardhat-deploy scripts (`NNN_name.ts`). |
| 15 | + - `test/unit/` and `test/integration/`. |
| 16 | + - `tasks/`, `scripts/`, `utils/`, `deployments/`, `abi/`. |
| 17 | + |
| 18 | +## Setup and environment |
| 19 | + |
| 20 | +- Install deps with `npm ci` (preferred) or `npm install`. |
| 21 | +- Required env var patterns (see `.env.example`): |
| 22 | + - `RPC_<NETWORK>` |
| 23 | + - `EVM_PRIVATE_KEY_<NETWORK>` (or mnemonic) |
| 24 | + - `MNEMONIC_<NETWORK>` or fallback `MNEMONIC` |
| 25 | + - `ACCOUNT_WITH_NEURO_URI_<NETWORK>` for Neuro funding tasks |
| 26 | +- Common networks in config include `hardhat`, `localhost`, `neuroweb_*`, `gnosis_*`, `base_*`. |
| 27 | + |
| 28 | +## Build, lint, and test commands |
| 29 | + |
| 30 | +### Build and generation |
| 31 | + |
| 32 | +- `npm run clean` — clear Hardhat cache/artifacts. |
| 33 | +- `npm run compile` — compile using `hardhat.node.config.ts`. |
| 34 | +- `npm run compile:size` — contract size report. |
| 35 | +- `npm run typechain` — regenerate `typechain/`. |
| 36 | +- `npm run export-abi` — regenerate `abi/*.json`. |
| 37 | + |
| 38 | +### Formatting and linting |
| 39 | + |
| 40 | +- `npm run format` / `npm run format:fix`. |
| 41 | +- `npm run lint` / `npm run lint:fix`. |
| 42 | +- `npm run lint:sol` / `npm run lint:sol:fix`. |
| 43 | +- `npm run lint:ts` / `npm run lint:ts:fix`. |
| 44 | + |
| 45 | +### Test suite commands |
| 46 | + |
| 47 | +- `npm run test` runs `test/scripts/run-tests-with-summary.sh`. |
| 48 | + - This script executes each `*.test.ts` file and does not accept file arguments. |
| 49 | +- `npm run test:unit` uses `--grep '@unit'`. |
| 50 | +- `npm run test:integration` uses `--grep '@integration'`. |
| 51 | + - Only a subset of integration tests are tagged; this command is partial. |
| 52 | +- `npm run test:parallel` for parallel test execution. |
| 53 | +- `npm run test:trace` / `npm run test:fulltrace` for traces. |
| 54 | +- `npm run test:gas`, `test:gas:trace`, `test:gas:fulltrace` for gas reporting. |
| 55 | +- `npm run coverage` for solidity-coverage. |
| 56 | + |
| 57 | +### Single test file (recommended local loop) |
| 58 | + |
| 59 | +- Use Hardhat directly: |
| 60 | + - `npx hardhat test test/unit/Ask.test.ts --network hardhat` |
| 61 | + - `npx hardhat test test/integration/StakingRewards.test.ts --network hardhat` |
| 62 | + |
| 63 | +### Single test case |
| 64 | + |
| 65 | +- Filter with Mocha grep: |
| 66 | + - `npx hardhat test test/unit/Ask.test.ts --network hardhat --grep "stake=0"` |
| 67 | + - `npx hardhat test --network hardhat --grep "Operator Fee Management"` |
| 68 | + |
| 69 | +## CI and hooks expectations |
| 70 | + |
| 71 | +- PR CI runs: `npx hardhat typechain`, `npm run lint`, `npm run format`, `npm run test`. |
| 72 | +- CI checks `package-lock.json` presence and dependency-lock sync. |
| 73 | +- Pre-commit hook runs `npx lint-staged`. |
| 74 | +- `lint-staged` applies Prettier, ESLint, and Solhint on staged files. |
| 75 | + |
| 76 | +## TypeScript style guide |
| 77 | + |
| 78 | +- TS runs in strict mode (`"strict": true`): keep all new code type-safe. |
| 79 | +- Prefer `type` aliases over `interface` (`@typescript-eslint/consistent-type-definitions`). |
| 80 | +- Avoid `any`; if unavoidable, keep it narrow and justified. |
| 81 | +- Prefer explicit return types for exported helpers. |
| 82 | +- Prefer `async/await` over chained `.then()`. |
| 83 | +- For state-changing tx calls in scripts/tests, `await tx.wait()` before assertions. |
| 84 | +- Use `bigint` for on-chain numeric values and `ethers.parseUnits`/`parseEther`. |
| 85 | +- Prefer `const`; use `let` only when reassignment is required. |
| 86 | + |
| 87 | +### TS imports and structure |
| 88 | + |
| 89 | +- Follow ESLint `import/order`: |
| 90 | + - group order: builtin, external, internal, sibling/parent/index, object, type. |
| 91 | + - alphabetize within groups, case-insensitive. |
| 92 | + - keep blank lines between groups. |
| 93 | +- Keep relative import paths consistent with surrounding files. |
| 94 | +- Prefer named imports; keep default exports only where existing patterns require them. |
| 95 | + |
| 96 | +### TS naming |
| 97 | + |
| 98 | +- `camelCase`: functions and variables. |
| 99 | +- `PascalCase`: types/classes; contract instances in tests often follow contract names. |
| 100 | +- Deploy script filenames: `NNN_descriptive_name.ts`. |
| 101 | +- Task/script filenames: snake_case (current repository pattern). |
| 102 | + |
| 103 | +## Solidity style guide |
| 104 | + |
| 105 | +- Standard order: SPDX, pragma, imports, declarations. |
| 106 | +- Use named imports: `import {Foo} from "./Foo.sol";`. |
| 107 | +- Naming conventions: |
| 108 | + - Contracts: `PascalCase` |
| 109 | + - Interfaces: `I*` |
| 110 | + - Libraries: `*Lib` |
| 111 | + - Storage contracts: `*Storage` |
| 112 | +- Keep existing narrowed integer widths (`uint72`, `uint96`, etc.) when domain-specific. |
| 113 | +- Private constants commonly use `_UPPER_SNAKE_CASE`. |
| 114 | +- Use existing access-control patterns (`onlyHub`, `onlyContracts`, `onlyOwner...`). |
| 115 | + |
| 116 | +### Solidity errors, events, gas patterns |
| 117 | + |
| 118 | +- Prefer custom errors (often defined in `*Lib`) for new logic. |
| 119 | +- String-based `require(...)` exists in legacy paths; avoid adding new string reverts unless needed for compatibility. |
| 120 | +- Emit events for state and admin mutations. |
| 121 | +- Bubble low-level call revert data when appropriate (see `Hub.forwardCall`). |
| 122 | +- Cache repeated storage/contract reads in locals. |
| 123 | +- Use unchecked loop increments where safe: |
| 124 | + - `for (uint256 i; i < arr.length; ) { ... unchecked { i++; } }` |
| 125 | +- Preserve optimizer/viaIR assumptions; do not change compiler settings casually. |
| 126 | + |
| 127 | +## Testing conventions |
| 128 | + |
| 129 | +- Framework: Mocha + Chai + `@nomicfoundation/hardhat-chai-matchers`. |
| 130 | +- Heavy fixture usage is standard: |
| 131 | + - `await hre.deployments.fixture([...])` |
| 132 | + - `await loadFixture(...)` |
| 133 | +- Many tests call `hre.helpers.resetDeploymentsJson()` in `beforeEach`. |
| 134 | +- Prefer precise revert checks: |
| 135 | + - `revertedWithCustomError(...)` for custom errors |
| 136 | + - `revertedWith(...)` for string-revert paths |
| 137 | +- Test files should be named `*.test.ts`. |
| 138 | +- Add `@unit`/`@integration` tags in `describe()` when you want grep-based scripts to include suites. |
| 139 | + |
| 140 | +## Deploy, task, and script conventions |
| 141 | + |
| 142 | +- Deploy scripts should export `const func: DeployFunction = async (...) => {}` and `export default func`. |
| 143 | +- Set `func.tags` and `func.dependencies` consistently. |
| 144 | +- Prefer `hre.helpers.deploy(...)` for deployments and Hub wiring. |
| 145 | +- Non-development deployments are staged and persisted via helper-managed arrays and `deployments/*_contracts.json`. |
| 146 | +- Scripts should use `main().then(...).catch(...)` and exit non-zero on failure. |
| 147 | + |
| 148 | +## Generated artifacts and tracked outputs |
| 149 | + |
| 150 | +- Do not hand-edit generated outputs unless explicitly required: |
| 151 | + - `abi/*.json`, `typechain/`, `artifacts/`, `cache/`, `coverage/` |
| 152 | +- Treat `deployments/*.json` as operational state; update through scripts/helpers, not ad-hoc edits. |
| 153 | +- Keep `package-lock.json` present and synchronized with dependency updates. |
| 154 | + |
| 155 | +## Cursor and Copilot rules |
| 156 | + |
| 157 | +- Checked rule paths: |
| 158 | + - `.cursorrules` |
| 159 | + - `.cursor/rules/` |
| 160 | + - `.github/copilot-instructions.md` |
| 161 | +- No Cursor or Copilot instruction files currently exist in this repository. |
| 162 | +- If these files are added later, treat them as high-priority repository instructions. |
0 commit comments