Skip to Content
Examples

Examples

Two ways to drive a running localnet: from the CLI with the bundled recipe scripts, or from application code with your usual client library pointed at the manifest’s endpoints. Boot the network first:

wharfnet up # or: wharfnet up --bare

From the CLI

Task-oriented shell recipes live in examples/. Each reads endpoints, accounts, and token addresses straight from .wharfnet/wharfnet.json (via jq), so nothing is hard-coded.

RecipeWhat it shows
evm/fund-and-transfer.sh Faucet an address, send an ERC-20 transfer, read balances
evm/snapshot-revert.sh Snapshot state, mutate it, roll back — the test-isolation pattern
evm/fork-and-impersonate.sh Fork mainnet, impersonate a whale, move real USDC with no key
solana/airdrop-and-tokens.sh Airdrop SOL, top up SPL tokens, read balances over JSON-RPC
starknet/fund-and-read.sh Fund the Cairo test tokens, read an ERC-20 balance
ci/github-actions.yml Boot the localnet in CI, run tests, tear down

From application code

Point your usual client at the endpoints from wharfnet status (or read them from .wharfnet/wharfnet.json). The chains behave like the real thing, so no wharfnet-specific SDK is needed.

import { createPublicClient, http } from 'viem' import { anvil } from 'viem/chains' // anvil-1's RPC, from `wharfnet status` const client = createPublicClient({ chain: anvil, transport: http('http://127.0.0.1:8545') }) // USDC is pre-deployed at a fixed address on every EVM chain const USDC = '0x5FbDB2315678afecb367f032d93F642f64180aa3' const abi = [{ name: 'balanceOf', type: 'function', stateMutability: 'view', inputs: [{ name: 'account', type: 'address' }], outputs: [{ type: 'uint256' }], }] as const const balance = await client.readContract({ address: USDC, abi, functionName: 'balanceOf', args: ['0x70997970C51812dc3A010C7d01b50e0d17dc79C8'], }) console.log('USDC balance (base units):', balance)

The dev accounts use Anvil’s standard test mnemonic, so their private keys are well-known — sign with them via createWalletClient for writes.

Need funded accounts or tokens at a specific address first? Use the faucetwharfnet faucet <chain> <address> <amount> tops up the native coin and every test token, with no private key.

In Rust tests — wharfnet::testkit

wharfnet is also a library. Add it as a dev-dependency and connect to a running localnet from an integration test — no hard-coded URLs or token addresses, all read from the manifest wharfnet up writes:

Cargo.toml
[dev-dependencies] wharfnet = "0.1.0" # pre-1.0 — pin the version you tested against
tests/localnet.rs
use wharfnet::testkit::Localnet; #[test] fn usdc_is_seeded_on_solana() { // Reads .wharfnet/wharfnet.json (run `wharfnet up` first, or in a CI step). let net = Localnet::connect().unwrap(); let sol = net.solana(); let rpc = sol.rpc_url(); // e.g. http://127.0.0.1:8899 let ws = sol.ws_url(); // Some("ws://127.0.0.1:8900") let usdc = sol.token("USDC"); // mint address + decimals let dev0 = sol.account(0); // funded dev account: address + private key assert_eq!(usdc.decimals, 6); // ... point solana-client / a signer built from dev0.private_key at `rpc`. let _ = (rpc, ws); }

net.evm(), net.starknet(), net.chain("anvil-2"), and net.chains() give the same typed handles for every chain. Missing chains/tokens panic with a clear message (a setup error in tests), or use the try_*/of_kind variants to handle them yourself.

The contract ABIs for the bundled test tokens are embedded too, so you can instantiate a token without fetching or hand-writing one — feed the JSON straight to viem/ethers/alloy (EVM) or starknet.js/starknet-rust (Starknet):

let evm = net.evm(); let abi_json = evm.token_abi("USDC"); // Some(&str) — the ERC-20 + mint ABI // net.starknet().token_abi("REB") → the rebasing-token Cairo ABI // Solana SPL tokens use the standard SPL Token program, so this is None.

The raw ABI constants are also available under wharfnet::abi (e.g. wharfnet::abi::evm::TEST_TOKEN, wharfnet::abi::starknet::REBASING_TOKEN).

Last updated on