mcpField
H
hardhat-toolbox-viem

hardhat-toolbox-viem

github.com/nomicfoundation開発256 回インストール2 週間前に更新
リポジトリ

hardhat-toolbox-viem について

viem を使う Hardhat プロジェクト向けのスキルです。TypeScript でコントラクトテストを書く開発者を対象に、型付きの操作と Ethereum 固有のアサーションを扱います。

主な機能

  1. 01型付き viem クライアント
  2. 02型付きコントラクトのデプロイと取得
  3. 03フィクスチャを使ったデプロイ
  4. 04Ethereum のリバートとイベント検証

活用シーン

  1. 01Hardhat テストでのコントラクトデプロイ
  2. 02リバートとイベントの検証
  3. 03型安全なコントラクト操作の作成

インストール

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

$npx skills add https://github.com/nomicfoundation/hardhat-skills --skill hardhat-toolbox-viem

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

詳細

Hardhat toolbox:viem

このスキルは、コアの hardhat スキルを基盤としています。テストの構成、network.create() の形式、networkHelpers、フィクスチャ、型チェックのワークフローについては、まずそちらを読み込んでください。以下の内容はすべて、network.create() が返す接続を基準としています。

import { network } from "hardhat";
import { describe, it } from "node:test";
import assert from "node:assert/strict";

describe("Counter", async function () {
  const { viem, networkHelpers } = await network.create();
  // ...
});

viem:クライアントとコントラクトとのやり取り

// Clients
const publicClient = await viem.getPublicClient();
const [owner, alice, bob] = await viem.getWalletClients(); // default accounts
const testClient = await viem.getTestClient(); // dev-only operations

// Deploy a contract, returns a fully typed instance
const counter = await viem.deployContract("Counter");

// Read state (return type inferred from ABI)
const value = await counter.read.x();

// Write transactions. Args and options are type-checked against the ABI at
// compile time; passing wrong types, wrong argument counts, or `value` on a
// non-payable function is a TypeScript error
await counter.write.inc();
await counter.write.inc({ account: alice.account }); // different sender
await counter.write.incBy([3n]); // with args
await counter.write.deposit({ value: 10n ** 18n }); // no parameters and payable

// Attach to an already-deployed contract
const existing = await viem.getContractAt("Counter", "0xabc...");

コントラクトとのやり取りに walletClient.writeContract を使うのは避けてください。ABI による型付けがなく、誤った引数がそのまま通ってしまいます。代わりに、viem.deployContract または viem.getContractAt が返す型付きのインスタンスを使ってください。

loadFixture のセットアップ関数内では(周辺のパターンについては hardhat スキルを参照)、viem.deployContract が標準的なデプロイ手順です。

async function deployCounter() {
  const counter = await viem.deployContract("Counter");
  return { counter };
}

const { counter } = await networkHelpers.loadFixture(deployCounter);

viem.assertions:Ethereum 固有のアサーション

コントラクト固有のチェックには viem.assertions を使ってください。最初の引数には、await していないトランザクションの Promise を渡します。

// Reverts
await viem.assertions.revert(counter.write.inc({ account: banned }));
await viem.assertions.revertWith(
  counter.write.inc({ account: banned }),
  "Not authorized",
);
await viem.assertions.revertWithCustomError(
  counter.write.inc({ account: banned }),
  counter,
  "Unauthorized",
);
await viem.assertions.revertWithCustomErrorWithArgs(
  counter.write.inc({ account: banned }),
  counter,
  "Unauthorized",
  [banned],
);

// Events
await viem.assertions.emit(counter.write.inc(), counter, "Increment");
await viem.assertions.emitWithArgs(counter.write.inc(), counter, "Increment", [
  1n,
]);

// ETH balance changes (positive = received, negative = spent, before gas)
await viem.assertions.balancesHaveChanged(game.write.claim(), {
  [winner]: PRIZE,
  [loser]: -STAKE,
});

*WithArgs マッチャー(revertWithCustomErrorWithArgs と emitWithArgs)では、具体的な値とともに、任意の引数位置で (value) => boolean の述語を指定できます。また、気にしない引数位置に使える anyValue ヘルパーもプラグインに含まれています。

import { anyValue } from "@nomicfoundation/hardhat-toolbox-viem/predicates";

// Inline predicate at any arg position. Useful for ranges or computed conditions.
await viem.assertions.revertWithCustomErrorWithArgs(
  contract.write.failing(),
  contract,
  "BadValue",
  [(n: bigint) => n > 100n, "another error arg"],
);
await viem.assertions.emitWithArgs(
  counter.write.incBy([3n]),
  counter,
  "Increment",
  [(by: bigint) => by >= 1n],
);

// `anyValue` matches anything — handy for fields you don't care about.
await viem.assertions.revertWithCustomErrorWithArgs(
  contract.write.failing(),
  contract,
  "BadValue",
  [anyValue, "another error arg"],
);

通常の TypeScript のアサーション(等価性、配列、型)には node:assert/strict を使ってください。

コメント