jpskill.com
🛠️ 開発・MCP コミュニティ

Wagmi React フック

wagmi

ReactやNext.jsアプリでウォレット接続、コントラクトの読み書き、ブロックチェーンの状態管理を行う際に、EthereumやEVMブロックチェーンとの連携を可能にするためのSkillです。

📜 元の英語説明(参考)

React hooks for Ethereum and EVM blockchain interactions using Wagmi v3. Use when building React or Next.js apps with wallet connections, contract reads/writes, or blockchain state. Triggers on useAccount, useConnect, useContractRead, useContractWrite, WagmiProvider, ConnectKit, RainbowKit, or any React blockchain hooks. Do NOT use for Node scripts or non-React code (use viem skill instead).

🇯🇵 日本人クリエイター向け解説

一言でいうと

ReactやNext.jsアプリでウォレット接続、コントラクトの読み書き、ブロックチェーンの状態管理を行う際に、EthereumやEVMブロックチェーンとの連携を可能にするためのSkillです。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o wagmi.zip https://jpskill.com/download/5991.zip && unzip -o wagmi.zip && rm wagmi.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/5991.zip -OutFile "$d\wagmi.zip"; Expand-Archive "$d\wagmi.zip" -DestinationPath $d -Force; ri "$d\wagmi.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して wagmi.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → wagmi フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-17
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Wagmi スキル

バージョン: Wagmi 3.x | 公式ドキュメント | TypeScript 5.7.3+ が必要です

Wagmi は Ethereum 用の React フックを提供します。このスキルは、プロバイダーのセットアップ、フックの使用、および React 特有の落とし穴に対する正しいパターンを保証します。

クイックセットアップ (Wagmi v3)

1. 設定のセットアップ

// 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 パッケージに移動しました。

2. プロバイダーのセットアップ

// 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>
  )
}

コアフック

useAccount

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>
}

useConnect / useDisconnect / useConnectors

import { useAccount, useConnect, useDisconnect, useConnectors } from 'wagmi'

function ConnectButton() {
  // v3: useConnect() から取得する代わりに useConnectors() フックを使用します
  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>
  )
}

useReadContract (useContractRead を置き換えます)

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>Loading...</div>
  if (error) return <div>Error: {error.message}</div>

  return <div>Balance: {data?.toString()}</div>
}

useWriteContract (useContractWrite を置き換えます)

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>
  )
}

重要なパターン

ABI 型安全性 (重要)

// ✅ 正しい - 完全な型推論のための 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() フックを使用します (v3)
useSwitchChain からの chains (v2) useChains() フックを使用します (v3)
条件付きフック query: { enabled: bool } を使用します
QueryClientProvider がない Wagmi には TanStack Query が必要です
ハッシュを待機しない useWaitForTransactionReceipt を使用します
文字列の量 Bi を使用します

(原文がここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Wagmi Skill

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.

Quick Setup (Wagmi v3)

1. Config Setup

// 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/connectors package for better dependency control.

2. Provider Setup

// 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>
  )
}

Core Hooks

useAccount

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>
}

useConnect / useDisconnect / useConnectors

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>
  )
}

useReadContract (REPLACES useContractRead)

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>
}

useWriteContract (REPLACES useContractWrite)

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>
  )
}

Critical Patterns

ABI Type Safety (CRITICAL)

// ✅ 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`

Conditional Hook Calls (NEVER conditional)

// ❌ 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 },
  })
}

Stale Closure Prevention

// ❌ 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
    })
  }
}

Common Mistakes

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)

References

For detailed patterns, see: