wagmi 使用教程 - Web3 React Hooks 库
简介
wagmi 是一个功能强大的 React Hooks 库,专门用于 Web3 开发。它提供了一套完整的工具来处理与区块链的交互,包括:
-
钱包连接管理
-
交易处理
-
智能合约读写
-
链上数据查询
本教程将介绍 wagmi 的基础用法和主要功能。
环境准备
在开始之前,确保你的开发环境已经安装了以下工具:
- Node.js (推荐 v20+)
- pnpm 或 yarn
- 代码编辑器 (推荐 VS Code)
首先安装必要的依赖:
pnpm install wagmi viem @tanstack/react-query
项目配置
1. Wagmi 配置
创建 wagmi 配置文件,设置链和钱包连接器:
// config.ts
import { http, createConfig } from "wagmi";
import { mainnet } from "wagmi/chains";
import { injected, metaMask, walletConnect } from "wagmi/connectors";
const projectId = "<WALLETCONNECT_PROJECT_ID>"; // WalletConnect项目ID
export const config = createConfig({
chains: [mainnet],
connectors: [injected(), walletConnect({ projectId }), metaMask()],
transports: {
[mainnet.id]: http(),
},
});
2. Provider 配置
// App.tsx
import { WagmiProvider } from "wagmi";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { config } from "./config";
const queryClient = new QueryClient();
function App() {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{/* 应用组件 */}
</QueryClientProvider>
</WagmiProvider>
);
}
基础功能实现
钱包连接
连接钱包是 Web3 应用的第一步。以下是一个基础的钱包连接组件:
// WalletConnect.tsx
import { useAccount, useConnect, useDisconnect } from "wagmi";
export function WalletConnect() {
const { address } = useAccount();
const { connectors, connect } = useConnect();
const { disconnect } = useDisconnect();
if (address)
return (
<div>
<div>已连接钱包: {address}</div>
<button onClick={() => disconnect()}>断开连接</button>
</div>
);
return (
<div>
{connectors.map((connector) => (
<button key={connector.uid} onClick={() => connect({ connector })}>
连接 {connector.name}
</button>
))}
</div>
);
}
发送交易
发送 ETH 交易的示例组件:
// SendTransaction.tsx
import { parseEther } from "viem";
import { useSendTransaction, useWaitForTransactionReceipt } from "wagmi";
export function SendTransaction() {
const { data: hash, isPending, sendTransaction } = useSendTransaction();
const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash,
});
async function submit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
const to = formData.get("address") as `0x${string}`;
const value = formData.get("value") as string;
sendTransaction({
to,
value: parseEther(value),
});
}
return (
<form onSubmit={submit}>
<input name="address" placeholder="接收地址" required />
<input name="value" placeholder="ETH数量" required />
<button disabled={isPending}>{isPending ? "确认中..." : "发送"}</button>
{hash && <div>交易哈希: {hash}</div>}
{isConfirming && <div>等待确认...</div>}
{isConfirmed && <div>交易已确认</div>}
</form>
);
}
合约交互
读取合约数据:
从智能合约读取数据的示例:
// ReadContract.tsx
import { useReadContract } from "wagmi";
const contractConfig = {
address: "0x...",
abi: [
{
name: "balanceOf",
type: "function",
inputs: [{ name: "owner", type: "address" }],
outputs: [{ type: "uint256" }],
},
],
} as const;
export function ReadContract() {
const { data: balance, isPending } = useReadContract({
...contractConfig,
functionName: "balanceOf",
args: ["0x..."], // 查询地址
});
if (isPending) return <div>加载中...</div>;
return <div>余额: {balance?.toString()}</div>;
}
写入合约:
调用合约写入方法的示例:
// WriteContract.tsx
import { useWriteContract, useWaitForTransactionReceipt } from "wagmi";
const contractConfig = {
address: "0x...",
abi: [
{
name: "mint",
type: "function",
inputs: [{ name: "tokenId", type: "uint256" }],
},
],
} as const;
export function WriteContract() {
const { data: hash, isPending, writeContract } = useWriteContract();
const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash,
});
async function mint(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData(e.target as HTMLFormElement);
const tokenId = formData.get("tokenId") as string;
writeContract({
...contractConfig,
functionName: "mint",
args: [BigInt(tokenId)],
});
}
return (
<form onSubmit={mint}>
<input name="tokenId" placeholder="Token ID" required />
<button disabled={isPending}>{isPending ? "确认中..." : "Mint"}</button>
{hash && <div>交易哈希: {hash}</div>}
{isConfirming && <div>等待确认...</div>}
{isConfirmed && <div>交易已确认</div>}
</form>
);
}
最佳实践
1. 错误处理
- 对所有可能的错误进行捕获和处理
- 为用户提供清晰的错误提示
- 实现适当的重试机制
2. 用户体验
- 添加加载状态提示
- 提供交易确认进度
- 实现友好的错误提示
- 添加适当的动画效果
3. 安全考虑
- 验证用户输入
- 使用安全的数据类型(如
BigInt)处理金额 - 实现交易确认提示
- 添加交易限额检查
4. 性能优化
- 使用 React Query 进行数据缓存
- 实现合理的重新请求策略
- 避免不必要的重渲染
进阶学习
- 多链支持
- ENS 集成
- 签名验证
- 交易历史记录
- Gas 优化
相关资源
希望这个教程能帮助你开始 Web3 前端开发之旅!如果有任何问题,欢迎继续提问。