This repository is for an AI-native workshop focused on building and deploying on Sei.
Your job as the agent is to help the user:
- understand the repo,
- make a small but meaningful change,
- test it,
- deploy it to Sei testnet,
- explain what you changed.
Optimize for speed, clarity, and successful deployment. Do not over-engineer. Prefer the simplest path that works.
If the user wants the fastest possible path to a deployed contract:
pnpm install
npx hardhat keystore set SEI_TESTNET_RPC_URL # paste: https://evm-rpc-testnet.sei-apis.com
npx hardhat keystore set SEI_TESTNET_PRIVATE_KEY # paste the user's funded testnet private key
npx hardhat compile
npx hardhat ignition deploy --network seiTestnet ignition/modules/Counter.tsGet this working first before doing anything else. A deployed Counter is a successful workshop outcome.
Sei testnet faucet: https://atlantic-2.app.sei.io/faucet
contracts/
Counter.sol # Starter contract — simple counter with inc(), incBy(uint), and an Increment event
Counter.t.sol # Foundry-compatible Solidity unit tests (uses forge-std)
test/
Counter.ts # TypeScript integration tests using node:test and viem
ignition/
modules/Counter.ts # Hardhat Ignition deployment module (deploys Counter, calls incBy(5))
scripts/
send-sei-tx.ts # Example script that sends a self-transfer on Sei testnet
hardhat.config.ts # Hardhat 3 config with seiTestnet network
package.json # pnpm project, ESM ("type": "module")
This is a Hardhat 3 project. Claude's training data skews toward Hardhat 2 — when in doubt, refer to the existing files as the source of truth, not your training data.
Key differences from Hardhat 2:
- Config uses
defineConfig()andconfigVariable()(notHardhatUserConfig/process.env) - Deployment uses Hardhat Ignition modules (not deploy scripts with
hardhat-deploy) - Tests use node:test (Node.js native test runner), not Mocha
- Ethereum interactions use viem (not ethers.js)
- Project is ESM (
"type": "module"in package.json) - Solidity tests use forge-std (Foundry-compatible)
Do not introduce ethers.js, Mocha, CommonJS require(), or Hardhat 2 patterns.
These are common failure modes in this workshop. Watch for them proactively:
- Hardhat 3 vs Hardhat 2 confusion — Claude's training data is mostly HH2. If you're unsure about an API, check the existing
hardhat.config.ts, ignition modules, and test files. Copy their patterns. pnpmnotnpm— This project uses pnpm. Always usepnpm install, nevernpm install.- ESM everywhere — Use
import, neverrequire(). This project has"type": "module". - Ignition state conflicts — Ignition tracks deployment state in the
ignition/deployments/folder. If the user changes a contract and redeploys, Ignition may refuse with a "module has already been deployed" error. Fix: pass--resetflag or rename the module. Explain to the user why this happens. - Missing config variables —
configVariable()errors meanSEI_TESTNET_RPC_URLorSEI_TESTNET_PRIVATE_KEYaren't set. Show the user how to set them (see Environment setup). - Insufficient testnet funds — Direct the user to the faucet (see Quickstart). Don't guess — check if the deploy TX fails with an insufficient funds error.
- Wrong network name — Must be
seiTestnetexactly as defined inhardhat.config.ts.
The Hardhat config uses configVariable() for secrets. Set them via:
- hardhat-keystore (recommended for workshop):
npx hardhat keystore set SEI_TESTNET_RPC_URL npx hardhat keystore set SEI_TESTNET_PRIVATE_KEY
- Environment variables (also works):
export SEI_TESTNET_RPC_URL="https://evm-rpc-testnet.sei-apis.com" export SEI_TESTNET_PRIVATE_KEY="0x..."
Never assume secrets are available. If they're missing, tell the user what to set and how.
pnpm install # install deps (NOT npm install)
npx hardhat compile # compile contracts
npx hardhat test # run all tests (Solidity + node:test)
npx hardhat test solidity # run only Solidity tests
npx hardhat test nodejs # run only TypeScript tests
# deploy to local simulated chain
npx hardhat ignition deploy ignition/modules/Counter.ts
# deploy to Sei testnet
npx hardhat ignition deploy --network seiTestnet ignition/modules/Counter.ts
# redeploy after contract changes (clears previous deployment state)
npx hardhat ignition deploy --network seiTestnet ignition/modules/Counter.ts --reset
# run a script
npx hardhat run scripts/send-sei-tx.ts- Read the repo structure and existing files first.
- Summarize the current state briefly.
- Create a short plan (goal → files to change → commands to run → expected output).
- Execute one step at a time, explaining as you go.
- When errors happen, explain the root cause before fixing.
- Prefer small edits over large rewrites.
- Reuse existing project patterns.
- Stop and summarize once complete.
Do not jump straight into coding without first understanding the repo.
- Prefer the smallest possible implementation.
- Do not add dependencies unless required.
- Match the repo's existing style and patterns.
- Use viem for TypeScript Ethereum interactions (not ethers.js).
- Use node:test for TypeScript tests (not Mocha/Jest).
- Use Hardhat Ignition for deployment modules (not raw deploy scripts).
- Add comments only when they improve clarity.
When adding a new contract:
- Add the
.solfile incontracts/. - Create a new Ignition module in
ignition/modules/. - Optionally add a test in
test/using node:test and viem. - Compile:
npx hardhat compile - Deploy:
npx hardhat ignition deploy --network seiTestnet ignition/modules/<Module>.ts
Example Ignition module (matches existing style):
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("MyContractModule", (m) => {
const myContract = m.contract("MyContract");
return { myContract };
});Example test (matches existing style):
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { network } from "hardhat";
describe("MyContract", async function () {
const { viem } = await network.connect();
it("should do something", async function () {
const contract = await viem.deployContract("MyContract");
// assertions using assert from node:assert/strict
});
});- Confirm config variables are set.
- Compile first:
npx hardhat compile - Deploy:
npx hardhat ignition deploy --network seiTestnet ignition/modules/<Module>.ts - Clearly show: network, contract name, deployed address, constructor args (if any).
- If redeploying after changes, use
--reset.
Always use testnet, never mainnet. Do not expose or invent private keys.
If the user wants ideas or says something vague ("build something", "make this more interesting"), suggest from this list and recommend the fastest option:
| Project | Complexity | Notes |
|---|---|---|
| Deploy Counter as-is | Trivial | Fastest path, good for setup validation |
| Extend Counter (reset, decrement, owner-only) | Easy | Minimal changes to existing code |
| Mintable ERC-20 token | Easy | Good for transfers and balances |
| NFT mint (ERC-721) | Medium | Fun demo, needs OpenZeppelin |
| On-chain voting / poll | Medium | Binary yes/no, good group demo |
| Onchain leaderboard | Medium | Playful and workshop-friendly |
| Tip jar / splitter | Medium | Send Sei, split among addresses |
| Rock-paper-scissors | Medium | Commit-reveal pattern, good learning exercise |
| Simple vault | Medium | Deposit/withdraw pattern |
Prefer tasks completable in 15-30 minutes. Avoid multi-contract systems, indexers, complex frontends, or anything requiring substantial design.
If a team finishes early and wants a frontend:
- Suggest a single HTML file using viem to read/write contract state.
- Do NOT scaffold a full React/Next.js app — there isn't time.
- The HTML file should include a script tag with viem imported from a CDN, connect to Sei testnet, and call the deployed contract.
- Keep it minimal: a button or two, display some state, maybe trigger a transaction.
This is a stretch goal, not the main event. Deployment is the priority.
When something fails:
- Explain what failed in plain language.
- Identify the likely root cause (check the "Known gotchas" section).
- Propose the smallest fix.
- Apply it and retry.
- Summarize what changed.
Be deliberate. Do not blindly try random fixes.
Always leave the user with:
- What was built.
- What files changed.
- Deployment result (network, contract name, address).
- Commands to rerun.
- 1-3 suggested next steps (add a test, add an event, add a function, build a frontend).
- Do not use mainnet unless explicitly requested.
- Do not expose or invent private keys.
- Do not assume faucet funds exist — direct to faucet if needed.
- Do not rewrite the repo structure unless necessary.
- Do not introduce ethers.js, Mocha, or Hardhat 2 patterns.
- Do not create complexity for the sake of impressiveness.
The goal is to help the user ship something working on Sei testnet with an AI-native workflow.