npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kiwa-lab/dapp

v2.0.0

Published

Headless E2E test fixture for dApps on anvil forks (Playwright + viem). Renamed from @kiwa-lab/core in v1.0.

Readme

@kiwa-lab/dapp

🇬🇧 English🇯🇵 日本語

Headless E2E test fixture for dApps on anvil forks (Playwright + viem).

@kiwa-lab/dapp is the runtime fixture used by kiwa's Playwright-based dApp E2E layer. It injects window.ethereum into the test page, starts an anvil-backed wallet fixture, handles the core EIP-1193 flows directly, and forwards the rest of the JSON-RPC surface to anvil.

You can use this package in two ways: (a) let Claude generate Playwright tests via /kiwa-play, or (b) import the fixture directly (import { dappE2eTest as test } from "@kiwa-lab/dapp") and write the tests by hand. See kiwa README for the full 3-path picture (contract test via @kiwa-lab/forge + dApp e2e via @kiwa-lab/dapp + manual write).

Installation

pnpm add -D @kiwa-lab/dapp @playwright/test viem

Bonus — Claude Code plugin

If you use Claude Code, install the kiwa skill chain in one command to get /kiwa:kiwa-play (Playwright e2e generation), /kiwa:kiwa-design, /kiwa:kiwa-forge, /kiwa:kiwa-hardhat, /kiwa:kiwa-vitest, /kiwa:kiwa-api, /kiwa:kiwa-review across every dApp project. (The /kiwa:kiwa-test one-shot orchestrator requires examples/ and is kiwa-monorepo-only.)

# In Claude Code:
/plugin marketplace add cardene777/kiwa
/plugin install kiwa@kiwa-marketplace
/reload-plugins

Plugin skills are namespaced by plugin name (/kiwa:kiwa-design, not /kiwa-design). See kiwa README — Option A for the full skill list.

Quickstart

import { expect } from "@playwright/test";
import { dappE2eTest as test } from "@kiwa-lab/dapp";

test("window.ethereum is injected", async ({ page, dappE2e }) => {
  await page.goto("/");

  const chainId = await page.evaluate(() => {
    return (window as any).ethereum.request({ method: "eth_chainId" });
  });

  await dappE2e.waitForRpcIdle();
  expect(chainId).toBe("0x7a69");
});

Features

  • Playwright fixture preset (dappE2eTest) that injects window.ethereum
  • anvil lifecycle integration for isolated test runs
  • 9 EIP-1193 JSON-RPC methods handled directly, with all other methods forwarded to anvil
  • 4 EIP-1193 events triggerable from tests
  • transaction broadcast helper for eth_sendTransaction
  • approval-mode helpers for deterministic reject-flow testing
  • EIP-6963 multi-wallet injection and smart-account support
  • vitest helper (setupTestEnv / withAnvil) that boots a real anvil with --load-state for unit / integration tests
  • anvil pool (createAnvilPool) with anvil_reset-backed 0 ms borrow / release for parallel test suites
  • tunable transport timeout / retry on sendTransaction for fail-fast error-path tests

Vitest helper (mock + real anvil with state load)

@kiwa-lab/dapp ships a vitest helper that lets the same test file run in either mock mode (no anvil process, default) or real anvil mode with a pre-built state file. The state file is produced once via kiwa anvil seed, then every test boots anvil with --load-state — equivalent to pasting the entire chain in one shot.

import { setupTestEnv } from "@kiwa-lab/dapp";

// mock mode (default): no anvil process, viem mock transport
const env = await setupTestEnv();

// clean anvil: spawns anvil on a free port, chainId 31337
const env = await setupTestEnv({ anvil: true });

// anvil with pre-built state: instant setup, no per-test deploy
const env = await setupTestEnv({
  anvil: { loadState: "tests/fixtures/state.json", chainId: 31337 },
});

await env.stop(); // call in afterAll

Generate the state file once with the CLI seed command:

# tests/seed.ts uses process.env.ANVIL_RPC_URL to deploy + setup
pnpm exec kiwa anvil seed tests/seed.ts --out tests/fixtures/state.json

The seed script runs against a one-shot anvil; on exit, anvil's --dump-state writes the full chain state to the output path. Subsequent test runs read it back via loadState and reach a ready chain in ~300 ms without replaying any transactions.

Anvil pool (v0.2.0+)

For test suites that need real anvil across many cases, createAnvilPool pre-spawns N instances and lets each test borrow/release one. Releasing runs anvil_reset so the next borrower sees a clean chain — borrow + release is ~0 ms after the pool warms up.

import { createAnvilPool, setupTestEnv, type AnvilPool } from "@kiwa-lab/dapp";

let pool: AnvilPool;
beforeAll(async () => {
  pool = await createAnvilPool({ size: 4 });
});
afterAll(async () => {
  await pool.stopAll();
});

it("borrows from pool", async () => {
  const env = await setupTestEnv({ pool }); // borrow + lease
  // ...
  await env.stop(); // releases back, anvil_reset is invoked
});

setupTestEnv cannot accept anvil and pool together — the call throws if both are passed. Polling/spawn was tuned in v0.2.0 so a fresh setupTestEnv({ anvil: true }) returns in ~32 ms (down from 107 ms).

Transport tuning for sendTransaction (v0.2.0+)

TxBroadcastCtx accepts optional transportTimeoutMs (default 5000) and transportRetryCount (default 0). Tests that exercise transport-error paths (e.g. invalid port → ECONNREFUSED) can shrink the wait from viem's 10s default to 200 ms:

await sendTransaction(
  { privateKey, chainId: 31337, anvilPort: brokenPort, transportTimeoutMs: 200, transportRetryCount: 0 },
  params,
); // rejects with code -32603 within ~200ms

Direct RPC Methods

@kiwa-lab/dapp handles these methods directly:

  • eth_requestAccounts
  • eth_accounts
  • eth_chainId
  • net_version
  • personal_sign
  • eth_signTypedData_v4
  • wallet_switchEthereumChain
  • wallet_addEthereumChain
  • eth_sendTransaction

Common read methods such as eth_call, eth_getBalance, eth_blockNumber, and eth_estimateGas are forwarded to anvil.

EIP-1193 Events

The injected provider supports these events:

  • accountsChanged
  • chainChanged
  • connect
  • disconnect

From tests, you can drive them with dappE2e.triggerEvent() or use higher-level helpers such as connect(), disconnect(), switchChain(), and waitForRpcIdle().

Related

Author

cardeneGitHub / X

License

MIT