Surfpool: mainnet-fork test validator with RPC cheatcodes
Surfpool is solana-test-validator with Mainnet forking and cheatcodes — fork state instantly, manipulate accounts via RPC, run real protocols locally.
Surfpool is what solana-test-validator should have been. It's a local validator that can fork Mainnet state instantly, exposes RPC cheatcodes for manipulating accounts and time, and runs from a single binary with no setup. Now maintained under the Solana Foundation at solana-foundation/surfpool.
Install + run
curl -sL https://run.surfpool.run/ | bash
surfpool start
# Validator runs on http://localhost:8899
# Studio dashboard opens automatically at http://localhost:8488Mainnet forking
Clone any account, token balance, or program from Mainnet to your local network with one RPC call:
# Clone a single account from Mainnet
curl -X POST http://localhost:8899 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "surfnet_setAccount",
"params": [
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
{ "clone": "mainnet" }
]
}'
# Or fork all of Mainnet on startup
surfpool start --fork mainnetOnce cloned, the account behaves exactly as on Mainnet for the purposes of your local txs — same balance, same data, same owner. Modify it locally without touching Mainnet.
The cheatcode surface
Surfpool exposes a surfnet_* RPC family that gives you superpowers a real network would never allow:
surfnet_setAccount Overwrite any account's data + lamports + owner
surfnet_setTokenAccount Create a token account at any address
surfnet_setTokenBalance Set any wallet's token balance to anything
surfnet_setProgramData Replace a deployed program's bytecode
surfnet_timeTravel Jump forward N slots or epochs
surfnet_resetNetwork Reset everything back to a clean state
surfnet_simulateTransaction Like simulateTransaction but with state
overrides applied before execution
surfnet_subscribeAccountStream Real-time push for any account changeConcrete recipe: testing your liquidation logic against the actual mainnet USDC mint, with the user having $50k USDC and your protocol's vault pre-funded with collateral, all without depositing a single real dollar:
// 1. Fork USDC mint into local
await rpc.send("surfnet_setAccount", [
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
{ clone: "mainnet" },
])
// 2. Set the user's USDC balance to 50,000
await rpc.send("surfnet_setTokenBalance", [
userTokenAccount.toBase58(),
50_000_000_000, // 50k USDC (6 decimals)
])
// 3. Pre-fund your vault
await rpc.send("surfnet_setTokenBalance", [
vaultTokenAccount.toBase58(),
1_000_000_000_000,
])
// 4. Run your liquidation flow against real Mainnet program shapes
// All txs execute locally, no real funds at risk
const sig = await yourProtocol.liquidate(/* ... */)Comparison with the alternatives
Surfpool solana-test-validator LiteSVM
─────────────────────────────────────────────────────────────────────────────
Real validator process Yes Yes No (in-process)
Mainnet fork Yes (built in) No No
RPC cheatcodes Yes No N/A (direct API)
Setup time <5s 30s+ 0s (library)
Account-level speed ~real validator ~real validator microseconds
JSON-RPC compatible Yes Yes Limited
Use for Integration test Integration test Unit testWhen to reach for it
- Testing against real on-chain state. Your protocol depends on USDC's actual freeze authority, or Jupiter's actual program ID, or the exact lookup table Pyth uses — fork Mainnet and your tests see what production sees.
- Time-dependent logic. Vesting schedules, warmup periods, governance proposal deadlines — jump the clock via
surfnet_timeTravelinstead of mocking it. - Reproducing a Mainnet bug locally. Fork the exact slot the bug occurred at, set your wallet up identically, replay the failing transaction.
- Demo / development. Show off your protocol interacting with real liquidity, real tokens, real users without spending real SOL.
Studio dashboard
Surfpool ships a web UI at localhost:8488 showing live account state, recent transactions, program logs, and CU breakdowns. Particularly useful when you're iterating fast and want to see what changed after each tx without scraping explorer pages.
References
For anything past unit-tests, Surfpool is the right default local environment for Solana in 2026. LiteSVM stays the right tool for microsecond-fast unit tests; Surfpool is the integration-test environment where Mainnet's real state becomes accessible.