web3-frontend

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Web3 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
undefined
python
undefined

Invoke this skill for Web3 frontend development

调用该技能进行Web3前端开发

Skill("web3-frontend", topic="wallet", framework="react")
undefined
Skill("web3-frontend", topic="wallet", framework="react")
undefined

Topics 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-query
tsx
// 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-query
tsx
// 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

常见开发模式

PatternUse CaseHook
Connect walletUser auth
useAccount
Read dataDisplay balances
useReadContract
Write txMint, transfer
useWriteContract
Wait for txConfirm state
useWaitForTransactionReceipt
Sign messageAuth, permit
useSignMessage
模式使用场景Hook
连接钱包用户认证
useAccount
读取数据展示余额
useReadContract
写入交易铸造、转账
useWriteContract
等待交易确认状态同步
useWaitForTransactionReceipt
消息签名认证、授权
useSignMessage

Common Pitfalls

常见陷阱

PitfallIssueSolution
Hydration errorSSR mismatchUse
dynamic
with
ssr: false
BigInt serializationJSON.stringifyCustom serializer
Stale dataCache issuesUse
refetchInterval
陷阱问题解决方案
水合错误SSR不匹配使用
dynamic
并设置
ssr: false
BigInt序列化JSON.stringify报错自定义序列化器
数据过期缓存问题使用
refetchInterval

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-development
    ,
    solidity-development
  • 关联Agent
    05-web3-frontend
  • 相关技能
    ethereum-development
    ,
    solidity-development

Version History

版本历史

VersionDateChanges
2.0.02025-01Production-grade with wagmi v2, viem
1.0.02024-12Initial release
版本日期更新内容
2.0.02025-01适配wagmi v2与viem的生产级版本
1.0.02024-12初始版本