web3-frontend
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWeb3 Frontend Skill
Web3前端开发技能
Master Web3 frontend development with wallet integration, modern libraries (viem/wagmi), and production dApp patterns.
精通Web3前端开发,涵盖钱包集成、现代库(viem/wagmi)以及生产级dApp开发模式。
Quick Start
快速开始
python
undefinedpython
undefinedInvoke this skill for Web3 frontend development
调用该技能进行Web3前端开发
Skill("web3-frontend", topic="wallet", framework="react")
undefinedSkill("web3-frontend", topic="wallet", framework="react")
undefinedTopics Covered
涵盖主题
1. Wallet Integration
1. 钱包集成
Connect users to Web3:
- RainbowKit: Beautiful wallet modal
- WalletConnect: Mobile support
- Account Abstraction: ERC-4337
- Multi-chain: Network switching
将用户连接到Web3:
- RainbowKit:美观的钱包弹窗
- WalletConnect:移动端支持
- Account Abstraction:ERC-4337标准
- Multi-chain:网络切换
2. Transaction Management
2. 交易管理
Handle blockchain interactions:
- Write Operations: Contract writes
- State Tracking: Pending, confirmed
- Gas Estimation: Fee display
- Error Handling: User-friendly messages
处理区块链交互:
- Write Operations:合约写入
- State Tracking:交易待处理、已确认状态追踪
- Gas Estimation:手续费展示
- Error Handling:用户友好的错误提示
3. Signing & Auth
3. 签名与认证
Verify user identity:
- EIP-712: Typed data signing
- SIWE: Sign-In with Ethereum
- Permit: Gasless approvals
- Message Signing: Personal sign
验证用户身份:
- EIP-712:类型化数据签名
- SIWE:以太坊登录
- Permit:无Gas费授权
- Message Signing:个人消息签名
4. React Hooks
4. React Hooks
Modern patterns with wagmi:
- useAccount: Connection state
- useWriteContract: Transactions
- useReadContract: Data fetching
- useWaitForTransactionReceipt: Confirmations
基于wagmi的现代开发模式:
- useAccount:连接状态管理
- useWriteContract:交易处理
- useReadContract:数据获取
- useWaitForTransactionReceipt:交易确认等待
Code Examples
代码示例
Connect Wallet
连接钱包
tsx
'use client';
import { ConnectButton } from '@rainbow-me/rainbowkit';
import { useAccount } from 'wagmi';
export function WalletConnect() {
const { address, isConnected } = useAccount();
return (
<div>
<ConnectButton />
{isConnected && <p>Connected: {address}</p>}
</div>
);
}tsx
'use client';
import { ConnectButton } from '@rainbow-me/rainbowkit';
import { useAccount } from 'wagmi';
export function WalletConnect() {
const { address, isConnected } = useAccount();
return (
<div>
<ConnectButton />
{isConnected && <p>已连接:{address}</p>}
</div>
);
}Write Contract
合约写入
tsx
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
import { parseEther } from 'viem';
export function MintButton() {
const { writeContract, data: hash, isPending } = useWriteContract();
const { isLoading, isSuccess } = useWaitForTransactionReceipt({ hash });
const mint = () => {
writeContract({
address: '0x...',
abi: [...],
functionName: 'mint',
args: [1n],
value: parseEther('0.08'),
});
};
return (
<button onClick={mint} disabled={isPending || isLoading}>
{isPending ? 'Confirm in wallet...' :
isLoading ? 'Minting...' :
isSuccess ? 'Minted!' : 'Mint NFT'}
</button>
);
}tsx
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi';
import { parseEther } from 'viem';
export function MintButton() {
const { writeContract, data: hash, isPending } = useWriteContract();
const { isLoading, isSuccess } = useWaitForTransactionReceipt({ hash });
const mint = () => {
writeContract({
address: '0x...',
abi: [...],
functionName: 'mint',
args: [1n],
value: parseEther('0.08'),
});
};
return (
<button onClick={mint} disabled={isPending || isLoading}>
{isPending ? '请在钱包中确认...' :
isLoading ? '铸造中...' :
isSuccess ? '铸造完成!' : '铸造NFT'}
</button>
);
}Sign Typed Data (EIP-712)
类型化数据签名(EIP-712)
tsx
import { useSignTypedData } from 'wagmi';
const DOMAIN = {
name: 'My App',
version: '1',
chainId: 1,
verifyingContract: '0x...',
};
export function useSignOrder() {
const { signTypedDataAsync } = useSignTypedData();
const sign = async (order: Order) => {
return await signTypedDataAsync({
domain: DOMAIN,
types: { Order: [...] },
primaryType: 'Order',
message: order,
});
};
return { sign };
}tsx
import { useSignTypedData } from 'wagmi';
const DOMAIN = {
name: 'My App',
version: '1',
chainId: 1,
verifyingContract: '0x...',
};
export function useSignOrder() {
const { signTypedDataAsync } = useSignTypedData();
const sign = async (order: Order) => {
return await signTypedDataAsync({
domain: DOMAIN,
types: { Order: [...] },
primaryType: 'Order',
message: order,
});
};
return { sign };
}Error Handling
错误处理
typescript
export function parseError(error: unknown): string {
const msg = error instanceof Error ? error.message : String(error);
if (msg.includes('user rejected')) return 'Transaction cancelled';
if (msg.includes('insufficient funds')) return 'Insufficient balance';
if (msg.includes('execution reverted')) {
const reason = msg.match(/reason="([^"]+)"/)?.[1];
return reason || 'Transaction would fail';
}
return 'Transaction failed';
}typescript
export function parseError(error: unknown): string {
const msg = error instanceof Error ? error.message : String(error);
if (msg.includes('user rejected')) return '交易已取消';
if (msg.includes('insufficient funds')) return '余额不足';
if (msg.includes('execution reverted')) {
const reason = msg.match(/reason="([^"]+)"/)?.[1];
return reason || '交易将失败';
}
return '交易失败';
}Package Setup
包安装
bash
npm install wagmi viem @rainbow-me/rainbowkit @tanstack/react-querytsx
// providers/Web3.tsx
import { WagmiProvider } from 'wagmi';
import { RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { config } from './config';
const queryClient = new QueryClient();
export function Web3Provider({ children }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>{children}</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}bash
npm install wagmi viem @rainbow-me/rainbowkit @tanstack/react-querytsx
// providers/Web3.tsx
import { WagmiProvider } from 'wagmi';
import { RainbowKitProvider } from '@rainbow-me/rainbowkit';
import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
import { config } from './config';
const queryClient = new QueryClient();
export function Web3Provider({ children }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
<RainbowKitProvider>{children}</RainbowKitProvider>
</QueryClientProvider>
</WagmiProvider>
);
}Common Patterns
常见开发模式
| Pattern | Use Case | Hook |
|---|---|---|
| Connect wallet | User auth | |
| Read data | Display balances | |
| Write tx | Mint, transfer | |
| Wait for tx | Confirm state | |
| Sign message | Auth, permit | |
| 模式 | 使用场景 | Hook |
|---|---|---|
| 连接钱包 | 用户认证 | |
| 读取数据 | 展示余额 | |
| 写入交易 | 铸造、转账 | |
| 等待交易确认 | 状态同步 | |
| 消息签名 | 认证、授权 | |
Common Pitfalls
常见陷阱
| Pitfall | Issue | Solution |
|---|---|---|
| Hydration error | SSR mismatch | Use |
| BigInt serialization | JSON.stringify | Custom serializer |
| Stale data | Cache issues | Use |
| 陷阱 | 问题 | 解决方案 |
|---|---|---|
| 水合错误 | SSR不匹配 | 使用 |
| BigInt序列化 | JSON.stringify报错 | 自定义序列化器 |
| 数据过期 | 缓存问题 | 使用 |
Troubleshooting
问题排查
"Wallet not connecting"
"钱包无法连接"
tsx
// Ensure client-side only
import dynamic from 'next/dynamic';
const ConnectButton = dynamic(
() => import('./ConnectButton'),
{ ssr: false }
);tsx
// 确保仅在客户端渲染
import dynamic from 'next/dynamic';
const ConnectButton = dynamic(
() => import('./ConnectButton'),
{ ssr: false }
);"Transaction pending forever"
"交易一直处于待处理状态"
Check gas settings or speed up:
typescript
await wallet.sendTransaction({
...tx,
maxFeePerGas: tx.maxFeePerGas * 120n / 100n,
});检查Gas设置或加速交易:
typescript
await wallet.sendTransaction({
...tx,
maxFeePerGas: tx.maxFeePerGas * 120n / 100n,
});Security Checklist
安全检查清单
- Never expose private keys
- Validate contract addresses
- Sanitize user inputs
- Use proper error boundaries
- Implement CSP headers
- 绝不暴露私钥
- 验证合约地址
- 过滤用户输入
- 使用正确的错误边界
- 配置CSP头部
Cross-References
交叉引用
- Bonded Agent:
05-web3-frontend - Related Skills: ,
ethereum-developmentsolidity-development
- 关联Agent:
05-web3-frontend - 相关技能:,
ethereum-developmentsolidity-development
Version History
版本历史
| Version | Date | Changes |
|---|---|---|
| 2.0.0 | 2025-01 | Production-grade with wagmi v2, viem |
| 1.0.0 | 2024-12 | Initial release |
| 版本 | 日期 | 更新内容 |
|---|---|---|
| 2.0.0 | 2025-01 | 适配wagmi v2与viem的生产级版本 |
| 1.0.0 | 2024-12 | 初始版本 |