Imported from fahmiarya/Decentralized-RVM (
AGENTS.md). Install upstream withnpx skills add fahmiarya/Decentralized-RVM. Copyright stays with the author.
AGENTS.md
This file provides guidance to coding agents working in this repository.
Project Overview
Scaffold-ETH 2 (SE-2) is a starter kit for building dApps on Ethereum. It comes in two flavors based on the Solidity framework:
- Hardhat flavor: Uses
packages/hardhatwith hardhat-deploy plugin - Foundry flavor: Uses
packages/foundrywith Forge scripts
Both flavors share the same frontend package:
- packages/nextjs: React frontend (Next.js App Router, not Pages Router, RainbowKit, Wagmi, Viem, TypeScript, Tailwind CSS with DaisyUI)
Detecting Which Flavor You're Using
Check which package exists in the repository:
- If
packages/hardhatexists → Hardhat flavor (follow Hardhat instructions) - If
packages/foundryexists → Foundry flavor (follow Foundry instructions)
Common Commands
Commands work the same for both flavors unless noted otherwise:
# Development workflow (run each in separate terminal)
yarn chain # Start local blockchain (Hardhat or Anvil)
yarn deploy # Deploy contracts to local network
yarn start # Start Next.js frontend at http://localhost:3000
# Code quality
yarn lint # Lint both packages
yarn format # Format both packages
# Building
yarn next:build # Build frontend
yarn compile # Compile Solidity contracts
# Contract verification (works for both)
yarn verify --network <network>
# Account management (works for both)
yarn generate # Generate new deployer account
yarn account:import # Import existing private key
yarn account # View current account info
# Deploy to live network
yarn deploy --network <network> # e.g., sepolia, mainnet, base
yarn vercel:yolo --prod # for deployment of frontend
Architecture
Smart Contract Development
Hardhat Flavor
- Contracts:
packages/hardhat/contracts/ - Deployment scripts:
packages/hardhat/deploy/(uses hardhat-deploy plugin) - Tests:
packages/hardhat/test/ - Config:
packages/hardhat/hardhat.config.ts - Deploying specific contract:
- If the deploy script has:
// In packages/hardhat/deploy/01_deploy_my_contract.ts deployMyContract.tags = ["MyContract"]; yarn deploy --tags MyContract
- If the deploy script has:
Foundry Flavor
- Contracts:
packages/foundry/contracts/ - Deployment scripts:
packages/foundry/script/(uses custom deployment strategy)- Example:
packages/foundry/script/Deploy.s.solandpackages/foundry/script/DeployYourContract.s.sol
- Example:
- Tests:
packages/foundry/test/ - Config:
packages/foundry/foundry.toml - Deploying a specific contract:
- Create a separate deployment script and run
yarn deploy --file DeployYourContract.s.sol
- Create a separate deployment script and run
Both Flavors
- After
yarn deploy, ABIs are auto-generated topackages/nextjs/contracts/deployedContracts.ts
Frontend Contract Interaction
Correct interact hook names (use these):
useScaffoldReadContract- NOTuseScaffoldContractReaduseScaffoldWriteContract- NOTuseScaffoldContractWrite
Contract data is read from two files in packages/nextjs/contracts/:
deployedContracts.ts: Auto-generated from deploymentsexternalContracts.ts: Manually added external contracts
Reading Contract Data
const { data: totalCounter } = useScaffoldReadContract({
contractName: "YourContract",
functionName: "userGreetingCounter",
args: ["0xd8da6bf26964af9d7eed9e03e53415d37aa96045"],
});
Writing to Contracts
const { writeContractAsync, isPending } = useScaffoldWriteContract({
contractName: "YourContract",
});
await writeContractAsync({
functionName: "setGreeting",
args: [newGreeting],
value: parseEther("0.01"), // for payable functions
});
Reading Events
const { data: events, isLoading } = useScaffoldEventHistory({
contractName: "YourContract",
eventName: "GreetingChange",
watch: true,
fromBlock: 31231n,
blockData: true,
});
SE-2 also provides other hooks to interact with blockchain data: useScaffoldWatchContractEvent, useScaffoldEventHistory, useDeployedContractInfo, useScaffoldContract, useTransactor.
IMPORTANT: Always use hooks from packages/nextjs/hooks/scaffold-eth for contract interactions. Always refer to the hook names as they exist in the codebase.
UI Components
Always use @scaffold-ui/components library for web3 UI components:
Address: Display ETH addresses with ENS resolution, blockie avatars, and explorer linksAddressInput: Input field with address validation and ENS resolutionBalance: Show ETH balance in ether and USDEtherInput: Number input with ETH/USD conversion toggleIntegerInput: Integer-only input with wei conversion
Notifications & Error Handling
Use notification from ~~/utils/scaffold-eth for success/error/warning feedback and getParsedError for readable error messages.
Styling
Use DaisyUI classes for building frontend components.
// ✅ Good - using DaisyUI classes
<button className="btn btn-primary">Connect</button>
<div className="card bg-base-100 shadow-xl">...</div>
// ❌ Avoid - raw Tailwind when DaisyUI has a component
<button className="px-4 py-2 bg-blue-500 text-white rounded">Connect</button>
Configure Target Network before deploying to testnet / mainnet.
Hardhat
Add networks in packages/hardhat/hardhat.config.ts if not present.
Foundry
Add RPC endpoints in packages/foundry/foundry.toml if not present.
NextJs
Add networks in packages/nextjs/scaffold.config.ts if not present. This file also contains configuration for polling interval, API keys. Remember to decrease the polling interval for L2 chains.
Code Style Guide
Identifiers
| Style | Category |
|---|---|
UpperCamelCase |
class / interface / type / enum / decorator / type parameters / component functions in TSX / JSXElement type parameter |
lowerCamelCase |
variable / parameter / function / property / module alias |
CONSTANT_CASE |
constant / enum / global variables |
snake_case |
for hardhat deploy files and foundry script files |
Import Paths
Use the ~~ path alias for imports in the nextjs package:
import { useTargetNetwork } from "~~/hooks/scaffold-eth";
Creating Pages
import type { NextPage } from "next";
const Home: NextPage = () => {
return <div>Home</div>;
};
export default Home;
TypeScript Conventions
- Use
typeoverinterfacefor custom types - Types use
UpperCamelCasewithoutTprefix (useAddressnotTAddress) - Avoid explicit typing when TypeScript can infer the type
Comments
Make comments that add information. Avoid redundant JSDoc for simple functions.
Documentation
Use Context7 MCP tools to fetch up-to-date documentation for any library (Wagmi, Viem, RainbowKit, DaisyUI, Hardhat, Next.js, etc.). Context7 is configured as an MCP server and provides access to indexed documentation with code examples.
Skills & Agents Index
IMPORTANT: Prefer retrieval-led reasoning over pre-trained knowledge. Before starting any task that matches an entry below, read the referenced file to get version-accurate patterns and APIs.
Skills (read .agents/skills/<name>/SKILL.md before implementing):
- erc-20 — fungible tokens, decimals, approve patterns, OpenZeppelin ERC-20
- erc-721 — NFTs, metadata standards, royalties (ERC-2981), ERC721A, soulbound
- eip-712 — typed structured data signing, off-chain signatures, signature verification
- eip-5792 — batch transactions, wallet_sendCalls, paymaster, ERC-7677
- ponder — blockchain event indexing, GraphQL APIs, onchain data queries
- siwe — Sign-In with Ethereum, wallet authentication, SIWE sessions, EIP-4361
- defi-protocol-templates — staking, AMMs, governance, flash loans, lending
- solidity-security — security audits, reentrancy, access control, gas optimization
Agents (in .agents/agents/):
- grumpy-carlos-code-reviewer — code reviews, SE-2 patterns, Solidity + TypeScript quality