算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
wagmi【设计与创意】wagmi is a set of React hooks for Ethereum, built on viem, for connecting wallets, reading contracts, sending transactions and switching chains. Use it when a user asks to connect wallets in React, read blockchain data in components, send transactions from a frontend, upgrade wagmi v2 to v3, or build a Web3 user interface in React or Next.js.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
wagmi provides React hooks for Ethereum: wallet connection, contract reads and writes, transaction signing and chain switching. It is built on viem (the TypeScript Ethereum library) and TanStack Query, so every read hook returns query state (data, isLoading, refetch) and every write hook is a mutation.
Version checked: wagmi 3.7 (peer deps: viem 2.x, react >= 18, @tanstack/react-query >= 5, typescript >= 5.9.3). If a project is on wagmi 2, useAccount, connect, writeContract and useConnect().connectors still work there; v3 renames them (see Guidelines) and keeps the old names as deprecated aliases for now.
npm install wagmi viem@2.x @tanstack/react-query
npm install @walletconnect/ethereum-provider # only if you use the walletConnect connector
In wagmi 3, connector SDKs are optional peer dependencies: install the one your connector needs (walletConnect needs @walletconnect/ethereum-provider, coinbaseWallet needs @coinbase/wallet-sdk, metaMask needs @metamask/connect-evm, safe needs the Safe apps packages). injected() needs nothing.
// lib/wagmi.ts
import { createConfig, http, cookieStorage, createStorage } from 'wagmi'
import { mainnet, base, arbitrum } from 'wagmi/chains'
import { injected, walletConnect } from 'wagmi/connectors'
export const config = createConfig({
chains: [mainnet, base, arbitrum],
connectors: [
injected(),
walletConnect({ projectId: process.env.NEXT_PUBLIC_WC_PROJECT_ID! }),
],
ssr: true, // Next.js: avoid hydration mismatch
storage: createStorage({ storage: cookieStorage }),
transports: {
[mainnet.id]: http(process.env.NEXT_PUBLIC_MAINNET_RPC_URL),
[base.id]: http(process.env.NEXT_PUBLIC_BASE_RPC_URL),
[arbitrum.id]: http(process.env.NEXT_PUBLIC_ARBITRUM_RPC_URL),
},
})
declare module 'wagmi' {
interface Register { config: typeof config } // makes hooks infer your chains
}
http() with no URL uses the chain's public RPC, which is rate limited; put a provider URL in an env var for production. The WalletConnect project id comes from the Reown dashboard.
// app/providers.tsx
'use client'
import { useState, type ReactNode } from 'react'
import { WagmiProvider } from 'wagmi'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { config } from '@/lib/wagmi'
export function Providers({ children }: { children: ReactNode }) {
const [queryClient] = useState(() => new QueryClient())
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</WagmiProvider>
)
}
'use client'
import { useConnection, useConnect, useConnectors, useDisconnect } from 'wagmi'
export function ConnectButton() {
const { address, isConnected } = useConnection() // v2: useAccount()
const { mutate: connect } = useConnect() // v2: const { connect } = useConnect()
const connectors = useConnectors() // v2: useConnect().connectors
const { mutate: disconnect } = useDisconnect()
if (isConnected) {
return (
<div>
<p>{address?.slice(0, 6)}...{address?.slice(-4)}</p>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
)
}
return (
<div>
{connectors.map((connector) => (
<button key={connector.uid} onClick={() => connect({ connector })}>
Connect {connector.name}
</button>
))}
</div>
)
}
'use client'
import { useReadContract, useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
import { erc20Abi, parseUnits, formatUnits, type Address } from 'viem'
const USDC_BASE: Address = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
export function UsdcBalance({ owner }: { owner: Address }) {
const { data: balance, isLoading } = useReadContract({
address: USDC_BASE,
abi: erc20Abi,
functionName: 'balanceOf',
args: [owner],
chainId: 8453,
})
if (isLoading) return <p>Loading…</p>
return <p>USDC: {balance !== undefined ? formatUnits(balance, 6) : '—'}</p>
}
export function SendUsdc({ to, amount }: { to: Address; amount: string }) {
const { mutate: writeContract, data: hash, isPending, error } = useWriteContract()
const { isLoading: confirming, isSuccess } = useWaitForTransactionReceipt({ hash })
return (
<>
<button
disabled={isPending || confirming}
onClick={() =>
writeContract({
address: USDC_BASE,
abi: erc20Abi,
functionName: 'transfer',
args: [to, parseUnits(amount, 6)],
chainId: 8453,
})
}
>
{isPending ? 'Confirm in wallet…' : confirming ? 'Confirming…' : isSuccess ? 'Sent' : 'Send USDC'}
</button>
{error && <p role="alert">{error.message}</p>}
</>
)
}
useSimulateContract before writeContract catches reverts before the wallet prompt. Use useWatchContractEvent for live logs and useSwitchChain to move the wallet to the right network.
User request: "Add a Connect Wallet button to my Next.js 15 app with MetaMask and WalletConnect, and show the ETH balance."
Install the packages from Step 1, create lib/wagmi.ts and app/providers.tsx, wrap app/layout.tsx children in <Providers>, and render ConnectButton. For the balance, const { address } = useConnection(); const { data } = useBalance({ address }) then show data?.formatted-style output with formatUnits(data.value, data.decimals). Result: the button lists "Connect Injected" and "Connect WalletConnect"; after connecting it shows 0x71C7…976F and the balance, with no hydration warning thanks to ssr: true and cookie storage.
User request: "We are on wagmi 2.x, bump it to 3 and fix the build."
Run npm install wagmi@3 viem@2 @tanstack/react-query@5 and raise typescript to 5.9.3 or newer. Install the connector SDKs your config uses. Rename useAccount to useConnection, useAccountEffect to useConnectionEffect, useSwitchAccount to useSwitchConnection; change const { connect } = useConnect() to const { mutate: connect } = useConnect() (same for writeContract, disconnect, switchChain), and replace useConnect().connectors with useConnectors() and useSwitchChain().chains with useChains(). Run npx tsc --noEmit; deprecated names still compile but are flagged.
chainId to hooks, and offer useSwitchChain when the wallet is on another chain.NEXT_PUBLIC_* values are public.bigint in token units: use parseUnits and formatUnits with the token's decimals (USDC has 6, not 18).as const (or comes from viem's exported ABIs or @wagmi/cli codegen).type Address from viem and type addresses as 0x${string}.createPublicClient) for server-side reads; hooks need a client component.