使用 wagmi + viem 工具链,在前端实现高质量的钱包连接模块,包括状态管理、自动连接、网络切换、多连接器支持等核心功能。
📚 作者:Henry 🧱 系列:《区块链钱包原理与前端集成实践》 · 第 3 篇 👨💻 受众:Web3 开发者 / 区块链学习者 👉 系列持续更新中,建议收藏专栏或关注作者

pnpm add wagmi viem @wagmi/core @walletconnect/ethereum
// lib/wagmi.ts
import { createConfig, configureChains } from 'wagmi'
import { mainnet, polygon } from 'wagmi/chains'
import { publicProvider } from 'wagmi/providers/public'
import { walletConnect } from 'wagmi/connectors'
import { injected } from 'wagmi/connectors'
const { chains, publicClient } = configureChains(
  [mainnet, polygon],
  [publicProvider()],
)
export const config = createConfig({
  autoConnect: true,
  publicClient,
  connectors: [
    injected(),
    walletConnect({
      projectId: 'YOUR_PROJECT_ID',
      showQrModal: true,
    }),
  ],
})
✅ 支持多链与多连接器切换,未来可集成 RainbowKit 或 Web3Modal UI。
// app/layout.tsx or _app.tsx
import { WagmiProvider } from 'wagmi'
import { config } from '@/lib/wagmi'
export default function App({ children }) {
  return (
    <WagmiProvider config={config}>
      {children}
    </WagmiProvider>
  )
}
// 基础连接按钮组件
'use client'
import {
  useConnect,
  useDisconnect,
  useAccount,
  useEnsName,
} from 'wagmi'
export function ConnectWalletButton() {
  const { connect, connectors } = useConnect()
  const { disconnect } = useDisconnect()
  const { address, isConnected } = useAccount()
  const { data: ensName } = useEnsName({ address })
  const connector = connectors[0] // 默认使用第一个连接器(如 Injected)
  return isConnected ? (
    <div>
      <p>已连接:{ensName ?? address}</p>
      <button onClick={() => disconnect()}>断开连接</button>
    </div>
  ) : (
    <button onClick={() => connect({ connector })}>
      连接钱包
    </button>
  )
}
在 createConfig 中设置:
// 自动连接配置
autoConnect: true
wagmi 会:
import { useAccount } from 'wagmi'
const { isConnected, address } = useAccount()
useEffect(() => {
  if (isConnected) {
    console.log('用户已连接地址:', address)
  }
}, [isConnected])
📌 可用于判断是否进入登录签名流程、是否展示资产信息等。
import { useNetwork, useSwitchChain } from 'wagmi'
const { chain } = useNetwork()
const { chains, switchChain } = useSwitchChain()
return (
  <selectvalue={chain?.id}
    onChange={(e) => switchChain({ chainId: Number(e.target.value) })}
  >
    {chains.map((c) => (
      <option key={c.id} value={c.id}>
        {c.name}
      </option>
    ))}
  </select>
)
chainUnsupported 标志推荐封装组件
| 组件名 | 功能描述 | 
|---|---|
WalletIdentityCard | 
展示地址 / ENS / 合约钱包标识 | 
ConnectWalletButton | 
钱包连接主入口,状态反馈 | 
ChainSwitcherDropdown | 
多链切换下拉框 | 
SignatureLoginGuard | 
登录保护封装,未连接不允许进入功能页 | 
UI 与 UX 提示建议
| 场景 | 提示设计 | 
|---|---|
| 未安装钱包 | 弹窗提示 + 下载链接 | 
| 正在连接中 | 加载动画 + 灰化按钮 | 
| 链不支持 | 高亮警告 + 切换链选项 | 
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!