mcpField
V
viem-v2

viem-v2

github.com/blockmatic開発1220 回インストール5 週間前に更新
リポジトリ

viem-v2 について

viem-v2は、TypeScript/JavaScriptアプリにEVMブロックチェーンを統合するためのガイドで、クライアント、トランスポート、チェーン、読み取り、書き込みを扱います。スクリプト、バックエンド、フロントエンドの開発者向けに、viemとwagmiの使い分けも説明します。

主な機能

  1. 01PublicClientとWalletClientの利用
  2. 02HTTP、WebSocket、カスタムトランスポート
  3. 03チェーンデータとコントラクトの読み取り
  4. 04トランザクション送信とメッセージ署名
  5. 05アドレス、単位変換、ハッシュのユーティリティ

活用シーン

  1. 01Node.jsスクリプトやバックエンドでのチェーンデータ取得
  2. 02リアルタイムのブロックチェーンイベント監視
  3. 03トランザクション送信やコントラクト書き込み
  4. 04アドレスや署名関連入力の検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/blockmatic/basilic-skills --skill viem-v2

インストール後、Claude Code で/viem-v2を入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
accounts-and-keys.md
clients-and-transports.md
contract-patterns.md
reading-data.md
wagmi-react.md
writing-transactions.md

詳細

viem 統合

viem を使用して、TypeScript/JavaScript アプリケーションに EVM ブロックチェーンを統合します。

ウォレット UI: React のウォレット接続とフックについては、wagmi-v3 を参照してください。まだウォレット UI がないアプリに wagmi を追加しないでください。バックエンド、スクリプト、アドレス/署名の検証には viem を直接使用します。

クイック判断ガイド

構築するもの使用するもの
Node.js スクリプト/バックエンドhttp トランスポートを使った viem
React/Next.js フロントエンドviem を基盤とする wagmi フック
リアルタイムイベント監視webSocket トランスポートを使った viem
ブラウザーウォレット統合wagmi または viem のカスタムトランスポート

インストール

# Core library
npm install viem

# For React apps, also install wagmi
npm install wagmi viem @tanstack/react-query

基本概念

クライアント

viem には 2 種類のクライアントがあります。

クライアント用途使用例
PublicClient読み取り専用の操作残高の取得、コントラクトの読み取り、ログの取得
WalletClient書き込み操作トランザクションの送信、メッセージへの署名
トランスポート
トランスポート使用場面
http()標準的な RPC 呼び出し(最も一般的)
webSocket()リアルタイムイベントのサブスクリプション
custom()ブラウザーウォレット(window.ethereum)
チェーン

viem には 50 以上のチェーン定義が含まれています。viem/chains からインポートします。

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

入力値の検証ルール

ユーザーが指定した値を生成した TypeScript コードに埋め込む前に、必ず次の検証を行ってください。

  • Ethereum アドレス:^0x[a-fA-F0-9]{40}$ に一致する必要があります。検証には viem の isAddress() を使用してください。
  • チェーン ID:viem がサポートするチェーン定義に含まれている必要があります。
  • 秘密鍵:ハードコードしてはいけません。必ず process.env.PRIVATE_KEY を使用し、実行時に検証してください。
  • RPC URL:https:// または wss:// プロトコルのみを使用してください。
  • ABI 入力:エンコードする前に、型が想定される Solidity 型と一致することを検証してください。

クイックスタートの例

残高の読み取り
import { createPublicClient, http, formatEther } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({
  chain: mainnet,
  transport: http(),
});

const balance = await client.getBalance({
  address: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045',
});

console.log(`Balance: ${formatEther(balance)} ETH`);
コントラクトの読み取り
import { createPublicClient, http, parseAbi } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({
  chain: mainnet,
  transport: http(),
});

const abi = parseAbi([
  'function balanceOf(address) view returns (uint256)',
  'function decimals() view returns (uint8)',
]);

const balance = await client.readContract({
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
  abi,
  functionName: 'balanceOf',
  args: ['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'],
});
トランザクションの送信
import { createWalletClient, http, parseEther } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const client = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
});

const hash = await client.sendTransaction({
  to: '0x...',
  value: parseEther('0.1'),
});

console.log(`Transaction hash: ${hash}`);
コントラクトへの書き込み
import { createWalletClient, createPublicClient, http, parseAbi, parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);

const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
});

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(),
});

const abi = parseAbi(['function transfer(address to, uint256 amount) returns (bool)']);

// Simulate first to catch errors
const { request } = await publicClient.simulateContract({
  address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  abi,
  functionName: 'transfer',
  args: ['0x...', parseUnits('100', 6)],
  account,
});

// Execute the transaction
const hash = await walletClient.writeContract(request);

// Wait for confirmation
const receipt = await publicClient.waitForTransactionReceipt({ hash });
console.log(`Confirmed in block ${receipt.blockNumber}`);

リファレンスドキュメント

各トピックの詳しい説明については、次を参照してください。

トピックリファレンスファイル
クライアントの設定、トランスポート、チェーンクライアントとトランスポート
ブロックチェーンデータの読み取りデータの読み取り
トランザクションの送信トランザクションの書き込み
秘密鍵、HD ウォレットアカウントと鍵
ABI の処理、マルチコールコントラクトのパターン
React/wagmi フックWagmi React

関連プラグイン

viem の基本に慣れたら、uniswap-trading プラグインで Uniswap のスワップを包括的に統合できます。

  • Uniswap Trading API の統合
  • Universal Router SDK の使用
  • トークンスワップの実装

次のコマンドでインストールします:claude plugin add @uniswap/uniswap-trading


共通ユーティリティ

単位変換
import { parseEther, formatEther, parseUnits, formatUnits } from 'viem';

// ETH
parseEther('1.5'); // 1500000000000000000n (wei)
formatEther(1500000000000000000n); // "1.5"

// Tokens (e.g., USDC with 6 decimals)
parseUnits('100', 6); // 100000000n
formatUnits(100000000n, 6); // "100"
アドレスユーティリティ
import { getAddress, isAddress } from 'viem';

isAddress('0x...'); // true/false
getAddress('0x...'); // checksummed address
ハッシュ化
import { keccak256, toHex } from 'viem';

keccak256(toHex('hello')); // 0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8

エラー処理

viem は型付きエラーをスローするため、捕捉して処理できます。

import { ContractFunctionExecutionError, InsufficientFundsError } from 'viem'

try {
  await client.writeContract(...)
} catch (error) {
  if (error instanceof ContractFunctionExecutionError) {
    console.error('Contract call failed:', error.shortMessage)
  }
  if (error instanceof InsufficientFundsError) {
    console.error('Not enough ETH for gas')
  }
}

関連項目

  • React のウォレット UI → wagmi-v3(viem を基盤としています)
  • Ethereum のハッシュ化(セレクター、トピック、EIP-712)→ nodejs-keccak256-v1
  • 非 EVM チェーン → solana-v1

Resources

コメント