wagmi by 0xsardius/onchain-typescript-skills
npx skills add https://github.com/0xsardius/onchain-typescript-skills --skill wagmi版本: Wagmi 3.x | 官方文档 | 需要 TypeScript 5.7.3+
Wagmi 为以太坊提供了 React Hooks。此技能确保在提供者设置、Hooks 使用以及 React 特定陷阱方面采用正确的模式。
// config.ts
import { http, createConfig } from 'wagmi'
import { mainnet, polygon, arbitrum } from 'wagmi/chains'
// v3: 单独安装连接器: npm i @wagmi/connectors
import { injected, coinbaseWallet, walletConnect } from '@wagmi/connectors'
export const config = createConfig({
chains: [mainnet, polygon, arbitrum],
connectors: [
injected(),
coinbaseWallet({ appName: 'My App' }),
walletConnect({ projectId: 'YOUR_PROJECT_ID' }),
],
transports: {
[mainnet.id]: http('https://eth-mainnet.g.alchemy.com/v2/KEY'),
[polygon.id]: http('https://polygon-mainnet.g.alchemy.com/v2/KEY'),
[arbitrum.id]: http('https://arb-mainnet.g.alchemy.com/v2/KEY'),
},
})
v3 注意: 连接器现在位于
@wagmi/connectors包中,以便更好地控制依赖关系。
// providers.tsx
'use client' // Next.js App Router 必需
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './config'
const queryClient = new QueryClient()
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</WagmiProvider>
)
}
Version: Wagmi 3.x | Official Docs | Requires TypeScript 5.7.3+
Wagmi provides React hooks for Ethereum. This skill ensures correct patterns for provider setup, hooks usage, and React-specific pitfalls.
// config.ts
import { http, createConfig } from 'wagmi'
import { mainnet, polygon, arbitrum } from 'wagmi/chains'
// v3: Install connectors separately: npm i @wagmi/connectors
import { injected, coinbaseWallet, walletConnect } from '@wagmi/connectors'
export const config = createConfig({
chains: [mainnet, polygon, arbitrum],
connectors: [
injected(),
coinbaseWallet({ appName: 'My App' }),
walletConnect({ projectId: 'YOUR_PROJECT_ID' }),
],
transports: {
[mainnet.id]: http('https://eth-mainnet.g.alchemy.com/v2/KEY'),
[polygon.id]: http('https://polygon-mainnet.g.alchemy.com/v2/KEY'),
[arbitrum.id]: http('https://arb-mainnet.g.alchemy.com/v2/KEY'),
},
})
v3 Note: Connectors are now in
@wagmi/connectorspackage for better dependency control.
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
import { useAccount } from 'wagmi'
function Profile() {
const { address, isConnected, isConnecting, chain } = useAccount()
if (isConnecting) return <div>连接中...</div>
if (!isConnected) return <div>未连接</div>
return <div>已连接: {address} 于 {chain?.name}</div>
}
import { useAccount, useConnect, useDisconnect, useConnectors } from 'wagmi'
function ConnectButton() {
// v3: 使用 useConnectors() hook 替代从 useConnect() 获取
const connectors = useConnectors()
const { connect, isPending } = useConnect()
const { disconnect } = useDisconnect()
const { isConnected } = useAccount()
if (isConnected) {
return <button onClick={() => disconnect()}>断开连接</button>
}
return (
<div>
{connectors.map((connector) => (
<button
key={connector.id}
onClick={() => connect({ connector })}
disabled={isPending}
>
{connector.name}
</button>
))}
</div>
)
}
import { useReadContract } from 'wagmi'
function Balance() {
const { data, isLoading, error, refetch } = useReadContract({
address: '0x...',
abi, // 使用 `as const` 以获得类型安全
functionName: 'balanceOf',
args: ['0x...'],
})
if (isLoading) return <div>加载中...</div>
if (error) return <div>错误: {error.message}</div>
return <div>余额: {data?.toString()}</div>
}
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
function Transfer() {
const { data: hash, writeContract, isPending, error } = useWriteContract()
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
hash,
})
async function handleTransfer() {
writeContract({
address: '0x...',
abi,
functionName: 'transfer',
args: ['0x...', 1000n],
})
}
return (
<div>
<button onClick={handleTransfer} disabled={isPending}>
{isPending ? '确认中...' : '转账'}
</button>
{isConfirming && <div>等待确认...</div>}
{isSuccess && <div>交易已确认!</div>}
{error && <div>错误: {error.message}</div>}
</div>
)
}
// ✅ 正确 - 使用 as const 以获得完整的类型推断
const abi = [
{
name: 'transfer',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
outputs: [{ name: '', type: 'bool' }],
},
] as const
// ❌ 错误 - 没有类型推断
const abi = [{ ... }] // 缺少 `as const`
// ❌ 错误 - 违反 Hooks 规则
function BadComponent({ shouldFetch }) {
if (shouldFetch) {
const { data } = useReadContract({ ... })
}
}
// ✅ 正确 - 使用 enabled 选项
function GoodComponent({ shouldFetch }) {
const { data } = useReadContract({
...params,
query: { enabled: shouldFetch },
})
}
// ❌ 错误 - 捕获了过时的值
function BadComponent() {
const [amount, setAmount] = useState(0n)
const { writeContract } = useWriteContract()
// 这会捕获渲染时的 `amount`!
const handleClick = () => {
writeContract({
...params,
args: [amount], // 可能是过时的!
})
}
}
// ✅ 正确 - 传递最新的值
function GoodComponent() {
const [amount, setAmount] = useState(0n)
const { writeContract } = useWriteContract()
const handleClick = () => {
writeContract({
...params,
args: [amount], // 从闭包中获取最新值
})
}
}
| 错误 | 修复方法 |
|---|---|
| useContractRead (v1) | 使用 useReadContract |
| useContractWrite (v1) | 使用 useWriteContract |
从 useConnect 获取 connectors (v2) | 使用 useConnectors() hook (v3) |
从 useSwitchChain 获取 chains (v2) | 使用 useChains() hook (v3) |
| 条件性 hooks | 使用 query: { enabled: bool } |
| 缺少 QueryClientProvider | Wagmi 需要 TanStack Query |
| 未等待 hash | 使用 useWaitForTransactionReceipt |
| 字符串金额 | 使用 BigInt: 1000n |
连接器来自 wagmi/connectors | 使用 @wagmi/connectors 包 (v3) |
有关详细模式,请参阅:
references/hooks-guide.md - 完整的 hooks 参考references/react-patterns.md - React 特定模式和 SSR每周安装量
86
代码仓库
首次出现
2026年1月23日
安全审计
安装于
opencode79
gemini-cli78
cursor77
codex77
github-copilot73
amp71
// providers.tsx
'use client' // Required for Next.js App Router
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from './config'
const queryClient = new QueryClient()
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</WagmiProvider>
)
}
import { useAccount } from 'wagmi'
function Profile() {
const { address, isConnected, isConnecting, chain } = useAccount()
if (isConnecting) return <div>Connecting...</div>
if (!isConnected) return <div>Not connected</div>
return <div>Connected: {address} on {chain?.name}</div>
}
import { useAccount, useConnect, useDisconnect, useConnectors } from 'wagmi'
function ConnectButton() {
// v3: Use useConnectors() hook instead of getting from useConnect()
const connectors = useConnectors()
const { connect, isPending } = useConnect()
const { disconnect } = useDisconnect()
const { isConnected } = useAccount()
if (isConnected) {
return <button onClick={() => disconnect()}>Disconnect</button>
}
return (
<div>
{connectors.map((connector) => (
<button
key={connector.id}
onClick={() => connect({ connector })}
disabled={isPending}
>
{connector.name}
</button>
))}
</div>
)
}
import { useReadContract } from 'wagmi'
function Balance() {
const { data, isLoading, error, refetch } = useReadContract({
address: '0x...',
abi, // Use `as const` for type safety
functionName: 'balanceOf',
args: ['0x...'],
})
if (isLoading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>Balance: {data?.toString()}</div>
}
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
function Transfer() {
const { data: hash, writeContract, isPending, error } = useWriteContract()
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({
hash,
})
async function handleTransfer() {
writeContract({
address: '0x...',
abi,
functionName: 'transfer',
args: ['0x...', 1000n],
})
}
return (
<div>
<button onClick={handleTransfer} disabled={isPending}>
{isPending ? 'Confirming...' : 'Transfer'}
</button>
{isConfirming && <div>Waiting for confirmation...</div>}
{isSuccess && <div>Transaction confirmed!</div>}
{error && <div>Error: {error.message}</div>}
</div>
)
}
// ✅ CORRECT - as const for full type inference
const abi = [
{
name: 'transfer',
type: 'function',
stateMutability: 'nonpayable',
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' },
],
outputs: [{ name: '', type: 'bool' }],
},
] as const
// ❌ WRONG - no type inference
const abi = [{ ... }] // Missing `as const`
// ❌ WRONG - Violates Rules of Hooks
function BadComponent({ shouldFetch }) {
if (shouldFetch) {
const { data } = useReadContract({ ... })
}
}
// ✅ CORRECT - Use enabled option
function GoodComponent({ shouldFetch }) {
const { data } = useReadContract({
...params,
query: { enabled: shouldFetch },
})
}
// ❌ WRONG - Captures stale values
function BadComponent() {
const [amount, setAmount] = useState(0n)
const { writeContract } = useWriteContract()
// This captures `amount` at render time!
const handleClick = () => {
writeContract({
...params,
args: [amount], // May be stale!
})
}
}
// ✅ CORRECT - Pass fresh values
function GoodComponent() {
const [amount, setAmount] = useState(0n)
const { writeContract } = useWriteContract()
const handleClick = () => {
writeContract({
...params,
args: [amount], // Fresh from closure
})
}
}
| Mistake | Fix |
|---|---|
| useContractRead (v1) | Use useReadContract |
| useContractWrite (v1) | Use useWriteContract |
connectors from useConnect (v2) | Use useConnectors() hook (v3) |
chains from useSwitchChain (v2) | Use useChains() hook (v3) |
| Conditional hooks | Use query: { enabled: bool } |
| Missing QueryClientProvider | Wagmi requires TanStack Query |
| Not awaiting hash | Use useWaitForTransactionReceipt |
| String amounts | Use BigInt: 1000n |
Connectors from wagmi/connectors | Use @wagmi/connectors package (v3) |
For detailed patterns, see:
references/hooks-guide.md - Complete hooks referencereferences/react-patterns.md - React-specific patterns and SSRWeekly Installs
86
Repository
First Seen
Jan 23, 2026
Security Audits
Installed on
opencode79
gemini-cli78
cursor77
codex77
github-copilot73
amp71
Solidity 智能合约安全指南:防范重入攻击、溢出漏洞与访问控制
7,900 周安装