Skip to content

Quickstart

Prerequisites

Statecraft runs local EVM instances via Anvil (Foundry). withChain() and withFork() both start an Anvil runtime, so anvil must be available on your PATH. If you do not have Foundry installed yet:

curl -L https://foundry.paradigm.xyz | bash

Install

Choose a package manager:

bun add -D @st8craft/core viem @pimlico/alto

Create a minimal test

Create tests/quickstart.test.ts:

import { test, expect } from "vitest";
import { parseEther } from "viem";
import { scenario, withChain, withFundedWallet } from "@st8craft/core";
 
test(
  "funded wallet on local chain",
  scenario(
    withChain(),
    withFundedWallet({ balance: parseEther("1") }),
    async ({ publicClient, walletClient }) => {
      const balance = await publicClient.getBalance({
        address: walletClient.account!.address,
      });
 
      expect(balance).toBe(parseEther("1"));
    },
  ),
);

Run it

Run:

bunx vitest run tests/quickstart.test.ts

What happened (and what success looks like)

This test starts a fresh local Anvil chain, funds a scenario wallet with withFundedWallet, reads the wallet balance with publicClient.getBalance, and asserts it.

Success looks like a passing Vitest run for funded wallet on local chain.

Troubleshooting

  • anvil: command not found: install Foundry (which provides anvil), then restart your terminal so your PATH updates.
  • RPC URL is missing (fork setup): set VITE_RPC_URL (or replace process.env.VITE_RPC_URL! with your own env var) before running the fork example.
  • Fork block is not deterministic: keep blockNumber pinned as a bigint literal (for example 22_000_000n). Avoid passing a plain number.

Expected output

When it works, Vitest should exit with code 0 and show a passing test named funded wallet on local chain.

Next step: pinned fork state

When you want deterministic mainnet (or L2) state, set an RPC URL (for example VITE_RPC_URL), then replace withChain() with:

withFork({
  rpcUrl: process.env.VITE_RPC_URL!,
  blockNumber: 22_000_000n,
});

Keep blockNumber pinned to a bigint literal. Then continue with: