From a927d591c6a220d75ef1e5c9527c39909921ff5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A2u=20Cao?= Date: Sat, 25 Jul 2026 17:32:49 +0200 Subject: [PATCH] Add AGENTS.md --- AGENTS.md | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c420597 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,112 @@ +# AGENTS.md + +Guidance for AI agents working on this repository. + +## Project overview + +`@kredits/contracts` — Solidity smart contracts and a JavaScript (ethers v5) +wrapper for [Kosmos Kredits](https://wiki.kosmos.org/Kredits), a contribution +tracking DAO running on EVM chains (primarily RSK). Contributors earn kredits +for contributions; kredits are withdrawable as ERC20 tokens. All contracts are +upgradeable via OpenZeppelin hardhat-upgrades proxies. + +## Tech stack + +- Solidity ^0.8.0 (compiler 0.8.2), OpenZeppelin upgradeable contracts +- Hardhat (with @openzeppelin/hardhat-upgrades, hardhat-deploy, hardhat-waffle) +- JavaScript (CommonJS), ethers v5, ipfs-http-client +- Tests: mocha + chai + @nomicfoundation/hardhat-chai-matchers +- Lint: solhint (contracts), eslint (JS) + +## Repository layout + +- `contracts/` — Solidity smart contracts (see "Contracts" below) +- `lib/` — published JavaScript API wrapper (entry: `lib/kredits.js`) + - `lib/contracts/` — one wrapper class per contract, extending `Base`/`Record` + - `lib/serializers/` — IPFS JSON serializers (contributor, contribution) + - `lib/utils/` — ipfs, pagination, validator, preflight, deprecate, format-kredits + - `lib/abis/` — committed ABI JSON (regenerated by `npm run build:json`) + - `lib/addresses.json` — chainId → deployed contract addresses +- `scripts/` — hardhat CLI helpers (create-proxy, seeds, add-/list-*, build-json, + upgrade-example, import/, export/) +- `test/contracts/` — mocha tests (Contributor.js, Contribution.js) +- `config/seeds.js` — demo seed data +- `hardhat.config.js` — networks: hardhat (1337), rinkeby, rsk (RSK testnet); + injects `hre.kredits` (an initialized `Kredits` instance) + +## Contracts + +All in `contracts/`, all `Initializable` (OpenZeppelin upgradeable): + +- `Contributor.sol` — contributor registry (account + IPFS profile hash). + Core team = contributor IDs 1–6 (hardcoded). `withdraw()` mints tokens for + confirmed, not-yet-withdrawn kredits. +- `Contribution.sol` — contribution records (ERC721-like ownership). Veto + period ~40320 blocks (~7 days @ 15s blocks). `add()` → veto window → confirmed. +- `Reimbursement.sol` — expense reimbursements, same veto pattern. +- `Token.sol` — ERC20 "Kredits" (symbol KS, 0 decimals). `mintFor` callable only + by the Contributor contract. + +Contracts are independent and reference each other by address (set via +`setContributorContract`, `setContributionContract`, `setTokenContract`). +Wiring happens in `scripts/create-proxy.js`. + +## Common commands + +Bootstrap a local dev environment: +``` +npm install +npm run devchain # hardhat node --network hardhat (separate terminal) +npm run bootstrap # build + deploy proxies + seeds (uses localhost) +``` + +Other: +``` +npm run build # compile contracts + regenerate lib/abis +npm run deploy:dao # deploy upgradeable proxies (scripts/create-proxy.js) +npm run seeds # seed demo data +npm run fund # send devchain ETH to an address +npm test # hardhat test (requires devchain running) +npm run lint:contracts # solhint +npm run lint:wrapper # eslint lib/ +``` + +Run a hardhat script: `hardhat run scripts/.js --network localhost` +(or `--network rsk` for RSK testnet). Use `DEPLOY_KEY=` to override the +deploy account. + +## Conventions + +### JavaScript (eslint: `lib/`, scripts/, test/) +- CommonJS (`require`/`module.exports`) +- 2-space indentation; semicolons required +- Trailing commas in multiline arrays/objects (not in imports/exports) +- Space before named function parens: `function foo () {}`, `async () => {}` +- Async wrappers use `.then()` chains in older code; new code may use async/await + +### Solidity (solhint: default + recommended) +- `pragma solidity ^0.8.0;` +- Upgradeable pattern: `import Initializable`, use `initialize()` (and + `reinitializer(n)` for upgrades) — never use constructors for state init +- Interfaces declared inline (e.g. `ContributorInterface`) for cross-contract calls +- Core-only / deployer-only / contributors-only modifiers guard privileged calls + +### Upgradeable contract changes +- Do not use constructors to initialize state (use `initialize`/`reinitializer`) +- Do not change the order/types of existing storage variables (storage layout!) +- New storage vars go at the end of the contract +- See `scripts/upgrade-example.js` and `scripts/create-proxy.js` + +## Tests + +Mocha + hardhat-waffle + chai-matchers. `test/contracts/` only covers +Contributor and Contribution today. When changing contract code, add/adapt +tests there. Requires a running devchain (`npm run devchain`) for `npm test`. + +## Networks & deployment + +- `hardhat` (chainId 1337) — local devchain +- `rsk` (RSK testnet, https://rsk-testnet.kosmos.org) — primary test deployment +- `rinkeby` — legacy, configured but deprecated +- Deployed addresses are tracked per chainId in `lib/addresses.json` and must be + committed when deployment changes (see `npm run version` script)