Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@
</picture>
</div>

### TL;DR
## 🌊 Overview

`surfpool` is to Solana what `anvil` is to Ethereum: a blazing fast ⚡️ in-memory testnet that has the ability to point-fork Solana mainnet instantly.
Surfpool is your drop-in replacement for `solana-test-validator` (local validator), designed for builders who want to work with real mainnet state — without downloading the entire chain.

## Introduction
But Surfpool goes further: it introduces Infrastructure as Code for Solana, empowering developers to define, deploy, and operate both on-chain and off-chain infrastructure declaratively and reproducibly.

Surfpool provides a blazing-fast, developer-friendly simulation of Solana Mainnet that runs seamlessly on your local machine. It eliminates the need for high-performance hardware while maintaining an authentic testing environment.
It’s built local-first and offline-ready, so you can spin up networks on your laptop — and then promote the exact same setup to the cloud when it’s showtime.

Whether you're developing, debugging, or educating yourself on Solana, Surfpool gives you an instant, self-contained network that dynamically fetches missing Mainnet data as needed—no more manual account setups.

## Surfpool in action: 101 Series
## Surfpool in action: 101 Series

<a href="https://www.youtube.com/playlist?list=PL0FMgRjJMRzO1FdunpMS-aUS4GNkgyr3T">
<picture>
Expand All @@ -25,17 +23,28 @@ Whether you're developing, debugging, or educating yourself on Solana, Surfpool
</picture>
</a>

## Features
## 💡 Key Features

- Fast & Lightweight – Runs smoothly on any machine without heavy system requirements.
### 🪄 Drop-in replacement for solana-test-validator
Spin up local networks that mirror mainnet state instantly — no 2 TB snapshots, no heavy setup (yes, even runs on a Raspberry Pi 🍓).
Surfpool has been battle-tested by hundreds of developers with existing Solana tools — including `solana-cli`, `anchor`, and `Kit` — so you can plug it into your workflow without changing a thing.

- Dynamic Account Fetching – Automatically retrieves necessary Mainnet accounts during transaction execution.
### 🧩 IDL-to-SQL
Transform your on-chain IDL into a fully queryable SQL schema.
Surfpool’s IDL-to-SQL engine bridges programs and databases — automatically generating tables and syncing chain data to local SQLite/Postgres for instant indexing and analytics.

- Anchor Integration – Detects Anchor projects and deploys programs automatically.
### 🛡️ Infrastructure as Code (IaC) for Web3
Define your stack once — then deploy and tweak it thousands of times before mainnet, with minimal friction.
Inspired by Terraform, Surfpool’s IaC makes your setup reproducible by design:
your local environment is optimized for speed and feedback, while production is optimized for safety and scales gracefully.

- Educational & Debug-Friendly – Provides clear insights into transaction execution and state changes.
### 🎮 Cheatcodes for Builders
Simulate, debug, and replay transactions — all without touching mainnet.
Includes Stream Oracles, Universal Faucet, Transaction Inspector, and Time Travel for fast, fearless experimentation.

- Easy Installation – Available via Homebrew, Snap, and direct binaries.
### ☁️ Surfpool Studio → Surfpool Cloud
Surfpool Studio is your local dashboard to visualize, inspect, and manage your networks in real time.
Surfpool Cloud extends that same experience to the cloud — letting you index mainnet data and run large-scale simulations with the same developer experience. It’s serverless, backend-as-a-service, and built for analytics at scale.

## Installation

Expand All @@ -54,7 +63,6 @@ brew reinstall surfpool
# While this is being resolved, Linux users should install from source
```


Install from source:

```console
Expand Down
13 changes: 8 additions & 5 deletions crates/cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use solana_pubkey::Pubkey;
use solana_signer::{EncodableKey, Signer};
use surfpool_mcp::McpOptions;
use surfpool_types::{
CHANGE_TO_DEFAULT_STUDIO_PORT_ONCE_SUPERVISOR_MERGED, DEFAULT_NETWORK_HOST, DEFAULT_RPC_PORT,
DEFAULT_SLOT_TIME_MS, DEFAULT_WS_PORT, RpcConfig, SimnetConfig, SimnetEvent, StudioConfig,
SubgraphConfig, SurfpoolConfig,
BlockProductionMode, CHANGE_TO_DEFAULT_STUDIO_PORT_ONCE_SUPERVISOR_MERGED,
DEFAULT_NETWORK_HOST, DEFAULT_RPC_PORT, DEFAULT_SLOT_TIME_MS, DEFAULT_WS_PORT, RpcConfig,
SimnetConfig, SimnetEvent, StudioConfig, SubgraphConfig, SurfpoolConfig,
};
use txtx_cloud::LoginCommand;
use txtx_core::manifest::WorkspaceManifest;
Expand Down Expand Up @@ -151,6 +151,9 @@ pub struct StartSimnet {
/// Set the slot time (eg. surfpool start --slot-time 400)
#[arg(long = "slot-time", short = 't', default_value_t = DEFAULT_SLOT_TIME_MS)]
pub slot_time: u64,
/// Set the block production mode (eg. surfpool start --block-production-mode transaction)
#[arg(long = "block-production-mode", short = 'b', default_value_t = BlockProductionMode::Clock)]
pub block_production_mode: BlockProductionMode,
/// Set a datasource RPC URL (cannot be used with --network). Can also be set via SURFPOOL_DATASOURCE_RPC_URL. (eg. surfpool start --rpc-url https://api.mainnet-beta.solana.com)
#[arg(long = "rpc-url", short = 'u', conflicts_with = "network", default_value = DEFAULT_RPC_URL)]
pub rpc_url: Option<String>,
Expand All @@ -166,7 +169,7 @@ pub struct StartSimnet {
/// Disable auto deployments (eg. surfpool start --no-deploy)
#[clap(long = "no-deploy", default_value = "false")]
pub no_deploy: bool,
/// List of runbooks-id to run (eg. surfpool start --runbook runbook-1 --runbook runbook-2)
/// List of runbooks-id to run (eg. surfpool start --runbook runbook-1 --runbook runbook-2)
#[arg(long = "runbook", short = 'r', default_value = DEFAULT_RUNBOOK)]
pub runbooks: Vec<String>,
/// Skip prompts for generating runbooks, and assume "yes" for all (eg. surfpool start -y)
Expand Down Expand Up @@ -338,7 +341,7 @@ impl StartSimnet {
SimnetConfig {
remote_rpc_url,
slot_time: self.slot_time,
block_production_mode: surfpool_types::BlockProductionMode::Clock,
block_production_mode: self.block_production_mode.clone(),
airdrop_addresses,
airdrop_token_amount: self.airdrop_token_amount,
expiry: None,
Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/runloops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ pub async fn start_block_production_runloop(
if let Err(e) = svm_locker.process_transaction(&remote_client_with_commitment, transaction, status_tx, skip_preflight, sigverify).await {
let _ = svm_locker.simnet_events_tx().send(SimnetEvent::error(format!("Failed to process transaction: {}", e)));
}
if block_production_mode.eq(&BlockProductionMode::Transaction) {
do_produce_block = true;
}
}
SimnetCommand::Terminate(_) => {
let _ = svm_locker.simnet_events_tx().send(SimnetEvent::Aborted("Terminated due to inactivity.".to_string()));
Expand Down
26 changes: 26 additions & 0 deletions crates/types/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,32 @@ pub enum BlockProductionMode {
Manual,
}

impl fmt::Display for BlockProductionMode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BlockProductionMode::Clock => write!(f, "clock"),
BlockProductionMode::Transaction => write!(f, "transaction"),
BlockProductionMode::Manual => write!(f, "manual"),
}
}
}

impl FromStr for BlockProductionMode {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"clock" => Ok(BlockProductionMode::Clock),
"transaction" => Ok(BlockProductionMode::Transaction),
"manual" => Ok(BlockProductionMode::Manual),
_ => Err(format!(
"Invalid block production mode: {}. Valid values are: clock, transaction, manual",
s
)),
}
}
}

#[derive(Debug)]
pub enum SubgraphEvent {
EndpointReady,
Expand Down
Binary file modified doc/assets/surfpool-github-hero-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified doc/assets/surfpool-github-hero-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/assets/surfpool-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.