frontend-playbook
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseFrontend Playbook
前端操作手册
What You Probably Got Wrong
你可能搞错的几件事
"I'll use ." Wrong. gives you an empty local chain with no protocols, no tokens, no state. gives you a copy of real Base with Uniswap, Aave, USDC, real whale balances — everything. Always fork.
yarn chainyarn chainyarn fork --network base"I deployed to IPFS and it works." Did the CID change? If not, you deployed stale output. Did routes work? Without , every route except returns 404. Did you check the OG image? Without , it points to .
trailingSlash: true/NEXT_PUBLIC_PRODUCTION_URLlocalhost:3000"I'll set up the project manually." Don't. handles everything — Foundry, Next.js, RainbowKit, scaffold hooks. Never run or create Next.js projects from scratch.
npx create-eth@latestforge init“我要用。” 错了。会给你一个空的本地链,没有协议、没有代币、没有状态。会给你一个真实Base链的副本,包含Uniswap、Aave、USDC、真实的巨鲸余额——所有内容。始终使用fork模式。
yarn chainyarn chainyarn fork --network base“我部署到IPFS了,能正常运行。” CID有没有变化?如果没有,你部署的是旧的输出内容。路由能正常工作吗?如果没有设置,除了之外的所有路由都会返回404。你检查OG图片了吗?如果没有设置,它会指向。
trailingSlash: true/NEXT_PUBLIC_PRODUCTION_URLlocalhost:3000“我要手动搭建项目。” 别这么做。会处理所有事情——Foundry、Next.js、RainbowKit、scaffold钩子函数。永远不要手动运行或从零创建Next.js项目。
npx create-eth@latestforge initFork Mode Setup
Fork模式设置
Why Fork, Not Chain
为什么用Fork而不是Chain
yarn chain (WRONG) yarn fork --network base (CORRECT)
└─ Empty local chain └─ Fork of real Base mainnet
└─ No protocols └─ Uniswap, Aave, etc. available
└─ No tokens └─ Real USDC, WETH exist
└─ Testing in isolation └─ Test against REAL stateyarn chain (错误) yarn fork --network base (正确)
└─ 空的本地链 └─ 真实Base主网的副本
└─ 无任何协议 └─ 可使用Uniswap、Aave等协议
└─ 无代币 └─ 存在真实的USDC、WETH
└─ 孤立环境测试 └─ 针对真实状态进行测试Setup
搭建步骤
bash
npx create-eth@latest # Select: foundry, target chain, name
cd <project-name>
yarn install
yarn fork --network base # Terminal 1: fork of real Base
yarn deploy # Terminal 2: deploy contracts to fork
yarn start # Terminal 3: Next.js frontendbash
npx create-eth@latest # 选择:foundry、目标链、项目名称
cd <project-name>
yarn install
yarn fork --network base # 终端1:启动真实Base链的fork副本
yarn deploy # 终端2:将合约部署到fork链
yarn start # 终端3:启动Next.js前端Critical: Chain ID Gotcha
关键注意点:Chain ID陷阱
When using fork mode, the frontend target network MUST be (chain ID 31337), NOT the chain you're forking.
chains.foundryThe fork runs locally on Anvil with chain ID 31337. Even if you're forking Base:
typescript
// scaffold.config.ts during development
targetNetworks: [chains.foundry], // ✅ NOT chains.base!Only switch to when deploying contracts to the REAL network.
chains.base使用fork模式时,前端的目标网络必须是(Chain ID 31337),而不是你要fork的链。
chains.foundryFork链在本地Anvil上运行,Chain ID为31337。即使你fork的是Base链:
typescript
// 开发环境下的scaffold.config.ts
targetNetworks: [chains.foundry], // ✅ 不要用chains.base!只有在将合约部署到真实网络时,才切换为。
chains.baseEnable Block Mining
启用区块挖矿
bash
undefinedbash
undefinedIn a new terminal — REQUIRED for time-dependent logic
在新终端中执行——对于依赖时间的逻辑是必需的
cast rpc anvil_setIntervalMining 1
Without this, `block.timestamp` stays FROZEN. Any contract logic using timestamps (deadlines, expiry, vesting) will break silently.
**Make it permanent** by editing `packages/foundry/package.json` to add `--block-time 1` to the fork script.
---cast rpc anvil_setIntervalMining 1
如果不这么做,`block.timestamp`会保持冻结状态。任何使用时间戳的合约逻辑(截止时间、过期、归属)都会静默失效。
**永久设置**:编辑`packages/foundry/package.json`,在fork脚本中添加`--block-time 1`。
---Deploying to IPFS (Recommended)
部署到IPFS(推荐)
IPFS is the recommended deploy path for SE2. Avoids Vercel's memory limits entirely. Produces a fully decentralized static site.
IPFS是SE2推荐的部署路径,完全避免Vercel的内存限制,生成完全去中心化的静态站点。
Full Build Command
完整构建命令
bash
cd packages/nextjs
rm -rf .next out # ALWAYS clean first
NEXT_PUBLIC_PRODUCTION_URL="https://yourapp.yourname.eth.link" \
NODE_OPTIONS="--require ./polyfill-localstorage.cjs" \
NEXT_PUBLIC_IPFS_BUILD=true \
NEXT_PUBLIC_IGNORE_BUILD_ERROR=true \
yarn buildbash
cd packages/nextjs
rm -rf .next out # 始终先清理旧文件
NEXT_PUBLIC_PRODUCTION_URL="https://yourapp.yourname.eth.link" \
NODE_OPTIONS="--require ./polyfill-localstorage.cjs" \
NEXT_PUBLIC_IPFS_BUILD=true \
NEXT_PUBLIC_IGNORE_BUILD_ERROR=true \
yarn buildUpload to BuidlGuidl IPFS
上传到BuidlGuidl IPFS
yarn bgipfs upload out
yarn bgipfs upload out
Save the CID!
保存生成的CID!
undefinedundefinedNode 25+ localStorage Polyfill (REQUIRED)
Node 25+ localStorage 兼容补丁(必需)
Node.js 25+ ships a built-in object that's MISSING standard WebStorage API methods (, ). This breaks , RainbowKit, and any library that calls during static page generation.
localStoragegetItemsetItemnext-themeslocalStorage.getItem()Error you'll see:
TypeError: localStorage.getItem is not a function
Error occurred prerendering page "/_not-found"The fix: Create in :
polyfill-localstorage.cjspackages/nextjs/javascript
if (typeof globalThis.localStorage !== "undefined" &&
typeof globalThis.localStorage.getItem !== "function") {
const store = new Map();
globalThis.localStorage = {
getItem: (key) => store.get(key) ?? null,
setItem: (key, value) => store.set(key, String(value)),
removeItem: (key) => store.delete(key),
clear: () => store.clear(),
key: (index) => [...store.keys()][index] ?? null,
get length() { return store.size; },
};
}Why and not ? Next.js spawns a separate build worker process for prerendering. injects into EVERY Node process (including workers). polyfill only runs in the main process. doesn't run in the build worker. Only works.
--requireinstrumentation.ts--requirenext.config.tsinstrumentation.ts--requireNode.js 25+内置的对象缺少标准WebStorage API的方法(、)。这会导致、RainbowKit以及任何在静态页面生成期间调用的库失效。
localStoragegetItemsetItemnext-themeslocalStorage.getItem()你会遇到的错误:
TypeError: localStorage.getItem is not a function
Error occurred prerendering page "/_not-found"修复方法: 在目录下创建文件:
packages/nextjs/polyfill-localstorage.cjsjavascript
if (typeof globalThis.localStorage !== "undefined" &&
typeof globalThis.localStorage.getItem !== "function") {
const store = new Map();
globalThis.localStorage = {
getItem: (key) => store.get(key) ?? null,
setItem: (key, value) => store.set(key, String(value)),
removeItem: (key) => store.delete(key),
clear: () => store.clear(),
key: (index) => [...store.keys()][index] ?? null,
get length() { return store.size; },
};
}为什么用而不是? Next.js会为预渲染启动单独的构建工作进程。会注入到所有Node进程(包括工作进程)中。中的补丁仅在主进程中运行,不会在构建工作进程中运行。只有能生效。
--requireinstrumentation.ts--requirenext.config.tsinstrumentation.ts--requireIPFS Routing — Why Routes Break
IPFS路由——路由失效的原因
IPFS gateways serve static files. No server handles routing. Three things MUST be true:
1. in next.config.ts — generates static HTML files.
output: "export"2. (CRITICAL) — This is the #1 reason routes break:
trailingSlash: true- (default) → generates
trailingSlash: falsedebug.html - → generates
trailingSlash: truedebug/index.html - IPFS gateways resolve directories to automatically, but NOT bare filenames
index.html - Without trailing slash: → 404 ❌
/debug - With trailing slash: →
/debug→debug/✅debug/index.html
3. Pages must survive static prerendering — any page that crashes during (browser APIs at import time, localStorage) gets skipped silently → 404 on IPFS.
yarn buildThe complete IPFS-safe next.config.ts pattern:
typescript
const isIpfs = process.env.NEXT_PUBLIC_IPFS_BUILD === "true";
if (isIpfs) {
nextConfig.output = "export";
nextConfig.trailingSlash = true;
nextConfig.images = { unoptimized: true };
}SE2's block explorer pages use at import time and crash during static export. Rename to if not needed.
localStorageapp/blockexplorerapp/_blockexplorer-disabledIPFS网关仅提供静态文件服务,没有服务器处理路由。必须满足三个条件:
1. next.config.ts中设置 —— 生成静态HTML文件。
output: "export"2. 设置(至关重要) —— 这是路由失效的头号原因:
trailingSlash: true- (默认)→ 生成
trailingSlash: falsedebug.html - → 生成
trailingSlash: truedebug/index.html - IPFS网关会自动将目录解析为,但不会解析裸文件名
index.html - 没有尾部斜杠:→ 404 ❌
/debug - 有尾部斜杠:→
/debug→debug/✅debug/index.html
3. 页面必须能通过静态预渲染 —— 任何在期间崩溃的页面(导入时调用浏览器API、localStorage)会被静默跳过→在IPFS上返回404。
yarn build完整的IPFS兼容next.config.ts模板:
typescript
const isIpfs = process.env.NEXT_PUBLIC_IPFS_BUILD === "true";
if (isIpfs) {
nextConfig.output = "export";
nextConfig.trailingSlash = true;
nextConfig.images = { unoptimized: true };
}SE2的区块浏览器页面在导入时使用,会在静态导出时崩溃。如果不需要,将重命名为。
localStorageapp/blockexplorerapp/_blockexplorer-disabledStale Build Detection
陈旧构建检测
The #1 IPFS footgun: You edit code, then deploy the OLD build.
bash
undefinedIPFS的头号陷阱: 你修改了代码,但部署的是旧构建。
bash
undefinedMANDATORY after ANY code change:
任何代码变更后必须执行:
rm -rf .next out # 1. Delete old artifacts
rm -rf .next out # 1. 删除旧构建产物
... run full build command ... # 2. Rebuild from scratch
... 执行完整构建命令 ... # 2. 从头重新构建
grep -l "YOUR_STRING" out/_next/static/chunks/app/*.js # 3. Verify changes present
grep -l "YOUR_STRING" out/_next/static/chunks/app/*.js # 3. 验证变更已包含在内
Timestamp check:
时间戳检查:
stat -f '%Sm' app/page.tsx # Source modified time
stat -f '%Sm' out/ # Build output time
stat -f '%Sm' app/page.tsx # 源码修改时间
stat -f '%Sm' out/ # 构建输出时间
Source NEWER than out/ = STALE BUILD. Rebuild first!
源码时间晚于out/ = 陈旧构建。先重新构建!
**The CID is proof:** If the IPFS CID didn't change after a deploy, you deployed the same content. A real code change ALWAYS produces a new CID.
**CID是证明:** 如果部署后IPFS的CID没有变化,说明你部署的是相同内容。真正的代码变更必然会生成新的CID。Verify Routes After Deploy
部署后验证路由
bash
ls out/*/index.html # Each route has a directory + index.html
curl -s -o /dev/null -w "%{http_code}" -L "https://GATEWAY/ipfs/CID/debug/"bash
ls out/*/index.html # 每个路由都有对应的目录+index.html
curl -s -o /dev/null -w "%{http_code}" -L "https://GATEWAY/ipfs/CID/debug/"Should return 200, not 404
应返回200,而非404
---
---Deploying to Vercel (Alternative)
部署到Vercel(替代方案)
SE2 is a monorepo — Vercel needs special configuration.
SE2是一个单仓多包项目——Vercel需要特殊配置。
Configuration
配置步骤
- Root Directory:
packages/nextjs - Install Command:
cd ../.. && yarn install - Build Command: leave default ()
next build - Output Directory: leave default ()
.next
bash
undefined- 根目录:
packages/nextjs - 安装命令:
cd ../.. && yarn install - 构建命令: 保留默认值()
next build - 输出目录: 保留默认值()
.next
bash
undefinedVia API:
通过API配置:
curl -X PATCH "https://api.vercel.com/v9/projects/PROJECT_ID"
-H "Authorization: Bearer $VERCEL_TOKEN"
-H "Content-Type: application/json"
-d '{"rootDirectory": "packages/nextjs", "installCommand": "cd ../.. && yarn install"}'
-H "Authorization: Bearer $VERCEL_TOKEN"
-H "Content-Type: application/json"
-d '{"rootDirectory": "packages/nextjs", "installCommand": "cd ../.. && yarn install"}'
undefinedcurl -X PATCH "https://api.vercel.com/v9/projects/PROJECT_ID"
-H "Authorization: Bearer $VERCEL_TOKEN"
-H "Content-Type: application/json"
-d '{"rootDirectory": "packages/nextjs", "installCommand": "cd ../.. && yarn install"}'
-H "Authorization: Bearer $VERCEL_TOKEN"
-H "Content-Type: application/json"
-d '{"rootDirectory": "packages/nextjs", "installCommand": "cd ../.. && yarn install"}'
undefinedCommon Failures
常见失败情况
| Error | Cause | Fix |
|---|---|---|
| "No Next.js version detected" | Root Directory not set | Set to |
| "cd packages/nextjs: No such file" | Build command has | Clear it — root dir handles this |
| OOM / exit code 129 | SE2 monorepo exceeds 8GB | Use IPFS instead, or |
| 错误 | 原因 | 修复方法 |
|---|---|---|
| "No Next.js version detected" | 未设置根目录 | 设置为 |
| "cd packages/nextjs: No such file" | 构建命令包含 | 清空构建命令——根目录会处理路径 |
| OOM / exit code 129 | SE2单仓多包项目超过8GB内存限制 | 改用IPFS部署,或使用 |
Decision Tree
决策树
Want to deploy SE2?
├─ IPFS (recommended) → yarn ipfs / manual build + upload
│ └─ Fully decentralized, no memory limits, works with ENS
├─ Vercel → Set rootDirectory + installCommand
│ └─ Fast CDN, but centralized. May OOM on large projects
└─ vercel --prebuilt → Build locally, push artifacts to Vercel
└─ Best of both: local build power + Vercel CDN想要部署SE2?
├─ IPFS(推荐)→ yarn ipfs / 手动构建+上传
│ └─ 完全去中心化,无内存限制,兼容ENS
├─ Vercel → 设置rootDirectory + installCommand
│ └─ CDN速度快,但中心化。大型项目可能出现内存不足
└─ vercel --prebuilt → 本地构建,将产物推送到Vercel
└─ 兼顾两者优势:本地构建能力 + Vercel CDNENS Subdomain Setup
ENS子域名设置
Two mainnet transactions to point an ENS subdomain at your IPFS deployment.
需要两笔主网交易,将ENS子域名指向你的IPFS部署。
Transaction 1: Create Subdomain (new apps only)
交易1:创建子域名(仅适用于新应用)
- Open
https://app.ens.domains/yourname.eth - Go to "Subnames" tab → "New subname"
- Enter the label (e.g. ) → Next → Skip profile → Open Wallet → Confirm
myapp - If gas is stuck: switch MetaMask to Ethereum → Activity tab → "Speed up"
- 打开
https://app.ens.domains/yourname.eth - 进入“Subnames”标签页 → “New subname”
- 输入标签(例如)→ 下一步 → 跳过资料设置 → 打开钱包 → 确认交易
myapp - 如果gas卡住:将MetaMask切换到以太坊主网 → 活动标签页 → “加速”
Transaction 2: Set IPFS Content Hash
交易2:设置IPFS内容哈希
- Navigate to
https://app.ens.domains/myapp.yourname.eth - "Records" tab → "Edit Records" → "Other" tab
- Paste in Content Hash field:
ipfs://<CID> - Save → Open Wallet → Confirm in MetaMask
For updates to an existing app: skip Tx 1, only do Tx 2.
- 导航到
https://app.ens.domains/myapp.yourname.eth - “Records”标签页 → “Edit Records” → “Other”标签页
- 在Content Hash字段中粘贴:
ipfs://<CID> - 保存 → 打开钱包 → 在MetaMask中确认交易
对于现有应用的更新:跳过交易1,仅执行交易2。
Verify
验证
bash
undefinedbash
undefined1. Onchain content hash matches
1. 链上内容哈希匹配
RESOLVER=$(cast call 0x00000000000C2e074eC69A0dFb2997BA6C7d2e1e
"resolver(bytes32)(address)" $(cast namehash myapp.yourname.eth)
--rpc-url https://eth.llamarpc.com) cast call $RESOLVER "contenthash(bytes32)(bytes)"
$(cast namehash myapp.yourname.eth) --rpc-url https://eth.llamarpc.com
"resolver(bytes32)(address)" $(cast namehash myapp.yourname.eth)
--rpc-url https://eth.llamarpc.com) cast call $RESOLVER "contenthash(bytes32)(bytes)"
$(cast namehash myapp.yourname.eth) --rpc-url https://eth.llamarpc.com
RESOLVER=$(cast call 0x00000000000C2e074eC69A0dFb2997BA6C7d2e1e
"resolver(bytes32)(address)" $(cast namehash myapp.yourname.eth)
--rpc-url https://eth.llamarpc.com) cast call $RESOLVER "contenthash(bytes32)(bytes)"
$(cast namehash myapp.yourname.eth) --rpc-url https://eth.llamarpc.com
"resolver(bytes32)(address)" $(cast namehash myapp.yourname.eth)
--rpc-url https://eth.llamarpc.com) cast call $RESOLVER "contenthash(bytes32)(bytes)"
$(cast namehash myapp.yourname.eth) --rpc-url https://eth.llamarpc.com
2. Gateway responds (may take 5-15 min for cache)
2. 网关响应(缓存可能需要5-15分钟)
curl -s -o /dev/null -w "%{http_code}" -L "https://myapp.yourname.eth.link"
curl -s -o /dev/null -w "%{http_code}" -L "https://myapp.yourname.eth.link"
3. OG metadata correct (not localhost)
3. OG元数据正确(不是localhost)
curl -s -L "https://myapp.yourname.eth.link" | grep 'og:image'
**Use `.eth.link` NOT `.eth.limo`** — `.eth.link` works better on mobile.
---curl -s -L "https://myapp.yourname.eth.link" | grep 'og:image'
**使用`.eth.link`而不是`.eth.limo`** —— `.eth.link`在移动端的兼容性更好。
---Go to Production — Complete Checklist
上线生产环境——完整检查清单
When the user says "ship it", follow this EXACT sequence.
当用户说“发布”时,严格按照以下步骤执行。
Step 1: Final Code Review 🤖
步骤1:最终代码审查 🤖
- All feedback incorporated
- No duplicate h1, no raw addresses, no shared isLoading
- has
scaffold.config.tsandrpcOverridespollingInterval: 3000
- 所有反馈已处理
- 无重复h1标签、无裸地址、无共享的isLoading状态
- 中配置了
scaffold.config.ts和rpcOverridespollingInterval: 3000
Step 2: Choose Domain 👤
步骤2:选择域名 👤
Ask: "What subdomain do you want? e.g. → "
myapp.yourname.ethmyapp.yourname.eth.link询问:“你想要什么子域名?例如 → ”
myapp.yourname.ethmyapp.yourname.eth.linkStep 3: Generate OG Image + Fix Metadata 🤖
步骤3:生成OG图片 + 修复元数据 🤖
- Create 1200×630 PNG () — NOT the stock SE2 thumbnail
public/thumbnail.png - Set to the live domain
NEXT_PUBLIC_PRODUCTION_URL - Verify will resolve to an absolute production URL
og:image
- 创建1200×630的PNG图片()——不要使用SE2的默认缩略图
public/thumbnail.png - 将设置为正式域名
NEXT_PUBLIC_PRODUCTION_URL - 验证会解析为绝对的生产环境URL
og:image
Step 4: Clean Build + IPFS Deploy 🤖
步骤4:清理构建 + IPFS部署 🤖
bash
cd packages/nextjs && rm -rf .next out
NEXT_PUBLIC_PRODUCTION_URL="https://myapp.yourname.eth.link" \
NODE_OPTIONS="--require ./polyfill-localstorage.cjs" \
NEXT_PUBLIC_IPFS_BUILD=true NEXT_PUBLIC_IGNORE_BUILD_ERROR=true \
yarn buildbash
cd packages/nextjs && rm -rf .next out
NEXT_PUBLIC_PRODUCTION_URL="https://myapp.yourname.eth.link" \
NODE_OPTIONS="--require ./polyfill-localstorage.cjs" \
NEXT_PUBLIC_IPFS_BUILD=true NEXT_PUBLIC_IGNORE_BUILD_ERROR=true \
yarn buildVerify before uploading:
上传前验证:
ls out/*/index.html # Routes exist
grep 'og:image' out/index.html # Not localhost
stat -f '%Sm' app/page.tsx # Source older than out/
stat -f '%Sm' out/
yarn bgipfs upload out # Save the CID
undefinedls out/*/index.html # 路由存在
grep 'og:image' out/index.html # 不是localhost
stat -f '%Sm' app/page.tsx # 源码时间早于out/
stat -f '%Sm' out/
yarn bgipfs upload out # 保存CID
undefinedStep 5: Share for Approval 👤
步骤5:分享以获得批准 👤
Send: "Build ready for review: "
Wait for approval before touching ENS.
https://community.bgipfs.com/ipfs/<CID>发送:“构建已准备好审查:”
在触碰ENS之前等待批准。
https://community.bgipfs.com/ipfs/<CID>Step 6: Set ENS 🤖
步骤6:设置ENS 🤖
Create subdomain (if new) + set IPFS content hash. Two mainnet transactions.
创建子域名(如果是新应用)+ 设置IPFS内容哈希。两笔主网交易。
Step 7: Verify 🤖
步骤7:验证 🤖
- Content hash matches onchain
- gateway responds with 200
.eth.link - OG image loads correctly
- Routes work (, etc.)
/debug/
- 链上内容哈希匹配
- 网关返回200状态码
.eth.link - OG图片加载正常
- 路由可正常访问(等)
/debug/
Step 8: Report 👤
步骤8:汇报 👤
"Live at — ENS content hash confirmed onchain, unfurl metadata set."
https://myapp.yourname.eth.link“已上线:——ENS内容哈希已在链上确认,分享元数据已设置完成。”
https://myapp.yourname.eth.linkBuild Verification Process
构建验证流程
A build is NOT done when the code compiles. It's done when you've tested it like a real user.
构建完成的标志不是代码编译通过,而是你像真实用户一样完成了测试。
Phase 1: Code QA (Automated)
阶段1:代码QA(自动化)
- Scan files for raw address strings (should use
.tsx)<Address/> - Scan for shared state across multiple buttons
isLoading - Scan for missing props on transaction buttons
disabled - Verify RPC config and polling interval
- Verify OG metadata with absolute URLs
- Verify no public RPCs in any file
- 扫描文件中的裸地址字符串(应使用
.tsx组件)<Address/> - 扫描多个按钮之间共享的状态
isLoading - 扫描交易按钮上缺失的属性
disabled - 验证RPC配置和轮询间隔
- 验证OG元数据使用绝对URL
- 验证所有文件中没有使用公共RPC
Phase 2: Smart Contract Testing
阶段2:智能合约测试
bash
forge test # All tests pass
forge test --fuzz-runs 10000 # Fuzz testingTest edge cases: zero amounts, max amounts, unauthorized callers, reentrancy attempts.
bash
forge test # 所有测试通过
forge test --fuzz-runs 10000 # 模糊测试测试边缘情况:零金额、最大金额、未授权调用者、重入攻击尝试。
Phase 3: Browser Testing (THE REAL TEST)
阶段3:浏览器测试(真实测试)
Open the app and do a FULL walkthrough:
- Load the app — does it render correctly?
- Check page title — is it correct, not "Scaffold-ETH 2"?
- Connect wallet — does the connect flow work?
- Wrong network — connect on wrong chain, verify "Switch to Base" appears
- Switch network — click the switch button, verify it works
- Approve flow — verify approve button shows, click it, wait for tx, verify action button appears
- Main action — click primary action, verify loader, wait for tx, verify state updates
- Error handling — reject a transaction in wallet, verify UI recovers
- Address displays — all addresses showing ENS/blockies, not raw hex?
- Share URL — check OG unfurl (image, title, description)
打开应用并完成完整的流程测试:
- 加载应用 —— 渲染是否正常?
- 检查页面标题 —— 是否正确,不是“Scaffold-ETH 2”?
- 连接钱包 —— 连接流程是否正常?
- 错误网络 —— 连接到错误的链,验证是否显示“切换到Base链”提示
- 切换网络 —— 点击切换按钮,验证是否能正常切换
- 授权流程 —— 验证授权按钮显示,点击后等待交易完成,验证操作按钮出现
- 主操作 —— 点击主要操作按钮,验证加载状态,等待交易完成,验证状态更新
- 错误处理 —— 在钱包中拒绝交易,验证UI是否能恢复
- 地址显示 —— 所有地址是否显示ENS/区块头像,而不是原始十六进制字符串?
- 分享URL —— 检查OG预览(图片、标题、描述)
Phase 4: QA Sub-Agent (Complex Builds)
阶段4:QA子代理(复杂构建)
For bigger projects, spawn a sub-agent with fresh context. Give it the repo path and deployed URL. It reads all code against the UX rules, opens a browser, clicks through independently, and reports issues.
对于大型项目,启动一个带有全新上下文的子代理。提供仓库路径和部署URL。它会根据UX规则检查所有代码,打开浏览器独立完成流程测试,并报告问题。
Don't Do These
禁止操作
- ❌ — use
yarn chainyarn fork --network <chain> - ❌ — use
forge initnpx create-eth@latest - ❌ Manual Next.js setup — SE2 handles it
- ❌ Manual wallet connection — SE2 has RainbowKit pre-configured
- ❌ Edit — it's auto-generated by
deployedContracts.tsyarn deploy - ❌ Hardcode API keys in — use
scaffold.config.ts.env.local - ❌ Use in production — use Alchemy or similar
mainnet.base.org
- ❌ —— 使用
yarn chainyarn fork --network <chain> - ❌ —— 使用
forge initnpx create-eth@latest - ❌ 手动搭建Next.js项目 —— SE2会处理所有配置
- ❌ 手动实现钱包连接 —— SE2已预配置RainbowKit
- ❌ 编辑—— 它由
deployedContracts.ts自动生成yarn deploy - ❌ 在中硬编码API密钥 —— 使用
scaffold.config.ts.env.local - ❌ 生产环境使用—— 使用Alchemy或类似服务
mainnet.base.org
Resources
资源
- SE2 Docs: https://docs.scaffoldeth.io/
- UI Components: https://ui.scaffoldeth.io/
- SpeedRun Ethereum: https://speedrunethereum.com/
- ETH Tech Tree: https://www.ethtechtree.com
- BuidlGuidl IPFS: https://upload.bgipfs.com
- SE2文档: https://docs.scaffoldeth.io/
- UI组件: https://ui.scaffoldeth.io/
- SpeedRun Ethereum: https://speedrunethereum.com/
- ETH技术图谱: https://www.ethtechtree.com
- BuidlGuidl IPFS: https://upload.bgipfs.com