jpskill.com
💼 ビジネス コミュニティ

viem

Viem は、EthereumやEVM互換ブロックチェーンとの低レベルなやり取りをTypeScriptで記述する際に、コントラクト操作やトランザクション署名などを効率的に行うSkill。

📜 元の英語説明(参考)

TypeScript patterns for low-level EVM blockchain interactions using Viem. Use when writing Node scripts, CLI tools, or backend services that read/write to Ethereum or EVM chains. Triggers on contract interactions, wallet operations, transaction signing, event watching, ABI encoding, or any non-React blockchain TypeScript code. Do NOT use for React/Next.js apps with hooks (use wagmi skill instead).

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

一言でいうと

Viem は、EthereumやEVM互換ブロックチェーンとの低レベルなやり取りをTypeScriptで記述する際に、コントラクト操作やトランザクション署名などを効率的に行うSkill。

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

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

🎯 この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-17
同梱ファイル
1

📖 Skill本文(日本語訳)

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

Viem スキル

バージョン: Viem 2.x | 公式ドキュメント

Viem は、Ethereum 向けの最新の TypeScript インターフェースです。このスキルは、コントラクトのインタラクション、クライアントのセットアップ、および型安全性のための正しいパターンを保証します。

クイックリファレンス

import { createPublicClient, createWalletClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'

重要なパターン

1. クライアントのセットアップ

Public Client (読み取り専用操作):

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'),
})

Wallet Client (書き込み操作):

const account = privateKeyToAccount('0x...')
const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'),
})

2. ABI の型安全性 (重要)

完全な型推論を得るために、ABI には常に as const を使用してください。

// ✅ 正しい - 完全な型安全性
const abi = [
  {
    name: 'balanceOf',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: 'owner', type: 'address' }],
    outputs: [{ name: '', type: 'uint256' }],
  },
] as const

// ❌ 間違い - 型推論なし
const abi = [{ name: 'balanceOf', ... }] // `as const` が欠落

3. コントラクト読み取りパターン

const balance = await publicClient.readContract({
  address: '0x...', // コントラクトアドレス
  abi,
  functionName: 'balanceOf',
  args: ['0x...'], // `as const` を使用すると引数は完全に型付けされます
})

4. コントラクト書き込みパターン (最初にシミュレート!)

エラーを早期に検出するために、書き込みの前に必ずシミュレートしてください。

// ステップ 1: シミュレート
const { request } = await publicClient.simulateContract({
  account,
  address: '0x...',
  abi,
  functionName: 'transfer',
  args: ['0x...', 1000000n], // uint256 には BigInt を使用
})

// ステップ 2: 実行
const hash = await walletClient.writeContract(request)

// ステップ 3: レシートを待機
const receipt = await publicClient.waitForTransactionReceipt({ hash })

5. イベント監視

const unwatch = publicClient.watchContractEvent({
  address: '0x...',
  abi,
  eventName: 'Transfer',
  onLogs: (logs) => {
    for (const log of logs) {
      console.log(log.args.from, log.args.to, log.args.value)
    }
  },
})

// クリーンアップ
unwatch()

6. バッチ読み取りのための Multicall

const results = await publicClient.multicall({
  contracts: [
    { address: '0x...', abi, functionName: 'balanceOf', args: ['0x...'] },
    { address: '0x...', abi, functionName: 'totalSupply' },
  ],
})
// results[0].result, results[1].result

よくある間違い

間違い 修正
ABI に as const がない 型推論のために as const を追加する
金額に Number を使用している BigInt リテラルを使用する: 1000000n
シミュレートせずに書き込んでいる 常に最初に simulateContract を実行する
ガスをハードコーディングしている viem に見積もらせるか、gas: await publicClient.estimateGas(...) を使用する
レシートを待機していない 確認のために waitForTransactionReceipt を使用する

チェーン設定

import { mainnet, polygon, arbitrum, optimism, base } from 'viem/chains'

// カスタムチェーン
const customChain = {
  id: 123,
  name: 'My Chain',
  nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
  rpcUrls: {
    default: { http: ['https://rpc.mychain.com'] },
  },
}

エラー処理

import { BaseError, ContractFunctionRevertedError } from 'viem'

try {
  await publicClient.simulateContract({ ... })
} catch (err) {
  if (err instanceof BaseError) {
    const revertError = err.walk(e => e instanceof ContractFunctionRevertedError)
    if (revertError instanceof ContractFunctionRevertedError) {
      const errorName = revertError.data?.errorName
      // 特定のリバート理由を処理
    }
  }
}

参照

詳細なパターンについては、以下を参照してください。

  • references/contract-patterns.md - 高度なコントラクトインタラクションパターン
  • references/common-errors.md - エラー処理とデバッグガイド
  • Viem Documentation - 公式ドキュメント
  • Viem GitHub - ソースとリリース
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Viem Skill

Version: Viem 2.x | Official Docs

Viem is the modern TypeScript interface for Ethereum. This skill ensures correct patterns for contract interactions, client setup, and type safety.

Quick Reference

import { createPublicClient, createWalletClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'

Critical Patterns

1. Client Setup

Public Client (read-only operations):

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'),
})

Wallet Client (write operations):

const account = privateKeyToAccount('0x...')
const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY'),
})

2. ABI Type Safety (CRITICAL)

Always use as const for ABIs to get full type inference:

// ✅ CORRECT - Full type safety
const abi = [
  {
    name: 'balanceOf',
    type: 'function',
    stateMutability: 'view',
    inputs: [{ name: 'owner', type: 'address' }],
    outputs: [{ name: '', type: 'uint256' }],
  },
] as const

// ❌ WRONG - No type inference
const abi = [{ name: 'balanceOf', ... }] // Missing `as const`

3. Contract Read Pattern

const balance = await publicClient.readContract({
  address: '0x...', // Contract address
  abi,
  functionName: 'balanceOf',
  args: ['0x...'], // Args are fully typed when using `as const`
})

4. Contract Write Pattern (Simulate First!)

Always simulate before writing to catch errors early:

// Step 1: Simulate
const { request } = await publicClient.simulateContract({
  account,
  address: '0x...',
  abi,
  functionName: 'transfer',
  args: ['0x...', 1000000n], // Use BigInt for uint256
})

// Step 2: Execute
const hash = await walletClient.writeContract(request)

// Step 3: Wait for receipt
const receipt = await publicClient.waitForTransactionReceipt({ hash })

5. Event Watching

const unwatch = publicClient.watchContractEvent({
  address: '0x...',
  abi,
  eventName: 'Transfer',
  onLogs: (logs) => {
    for (const log of logs) {
      console.log(log.args.from, log.args.to, log.args.value)
    }
  },
})

// Clean up
unwatch()

6. Multicall for Batch Reads

const results = await publicClient.multicall({
  contracts: [
    { address: '0x...', abi, functionName: 'balanceOf', args: ['0x...'] },
    { address: '0x...', abi, functionName: 'totalSupply' },
  ],
})
// results[0].result, results[1].result

Common Mistakes

Mistake Fix
Missing as const on ABI Add as const for type inference
Using Number for amounts Use BigInt literals: 1000000n
Writing without simulate Always simulateContract first
Hardcoding gas Let viem estimate, or use gas: await publicClient.estimateGas(...)
Not awaiting receipts Use waitForTransactionReceipt for confirmation

Chain Configuration

import { mainnet, polygon, arbitrum, optimism, base } from 'viem/chains'

// Custom chain
const customChain = {
  id: 123,
  name: 'My Chain',
  nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 },
  rpcUrls: {
    default: { http: ['https://rpc.mychain.com'] },
  },
}

Error Handling

import { BaseError, ContractFunctionRevertedError } from 'viem'

try {
  await publicClient.simulateContract({ ... })
} catch (err) {
  if (err instanceof BaseError) {
    const revertError = err.walk(e => e instanceof ContractFunctionRevertedError)
    if (revertError instanceof ContractFunctionRevertedError) {
      const errorName = revertError.data?.errorName
      // Handle specific revert reason
    }
  }
}

References

For detailed patterns, see:

  • references/contract-patterns.md - Advanced contract interaction patterns
  • references/common-errors.md - Error handling and debugging guide
  • Viem Documentation - Official docs
  • Viem GitHub - Source and releases