JS API Reference

The @solana/surfpool package exposes one class, Surfnet, plus the supporting types you need to call its methods type-safely. This page lists every exported symbol; for narrative usage, see the guides starting with Overview.

Package Exports

SymbolKindNotes
SurfnetclassRunning Surfnet instance with cheatcode methods
SurfnetConfigtypeArgument to Surfnet.startWithConfig
DeployOptionstypeArgument to Surfnet.deploy
SetTokenAccountUpdatetypeArgument to Surfnet.setTokenAccount
ResetAccountOptionstypeArgument to Surfnet.resetAccount
StreamAccountOptionstypeArgument to Surfnet.streamAccount
SolAccountFundingtypeElement of the array passed to Surfnet.fundSolMany
SimnetEventValuetypeElement returned by Surfnet.drainEvents
KeypairInfotypeReturned by Surfnet.newKeypair
ClockValuetypeField on SimnetEventValue
EpochInfoValuetypeReturned by time-travel helpers
ByteArrayLiketypeUint8Array | number[] — flexible byte input

Surfnet Class

Static Methods

class Surfnet {
static start(): Surfnet;
static startWithConfig(config: SurfnetConfig): Surfnet;
static newKeypair(): KeypairInfo;
}

Instance Properties

class Surfnet {
readonly rpcUrl: string; // http://127.0.0.1:<port>
readonly wsUrl: string; // ws://127.0.0.1:<port>
readonly payer: string; // base58 public key
readonly payerSecretKey: Uint8Array; // 64-byte private key
readonly instanceId: string;
}

Lifecycle

class Surfnet {
stop(): void; // idempotent; safe to call from `finally` / test teardown
}

SOL Cheatcodes

class Surfnet {
fundSol(address: string, lamports: number): void;
fundSolMany(accounts: SolAccountFunding[]): void;
setAccount(
address: string,
lamports: number,
data: Uint8Array,
owner: string
): void;
resetAccount(address: string, options?: ResetAccountOptions): void;
}

Token Cheatcodes

class Surfnet {
fundToken(
owner: string,
mint: string,
amount: number,
tokenProgram?: string
): void;
fundTokenMany(
owners: string[],
mint: string,
amount: number,
tokenProgram?: string
): void;
setTokenBalance(
owner: string,
mint: string,
amount: number,
tokenProgram?: string
): void;
setTokenAccount(
owner: string,
mint: string,
update: SetTokenAccountUpdate,
tokenProgram?: string
): void;
getAta(owner: string, mint: string, tokenProgram?: string): string;
}

Time Travel

class Surfnet {
timeTravelToSlot(slot: number): EpochInfoValue;
timeTravelToEpoch(epoch: number): EpochInfoValue;
timeTravelToTimestamp(timestampMs: number): EpochInfoValue;
}

Program Deployment

class Surfnet {
deployProgram(programName: string): string; // returns program id
deploy(options: DeployOptions): string; // returns program id
}

Streaming & Events

class Surfnet {
streamAccount(address: string, options?: StreamAccountOptions): void;
drainEvents(): SimnetEventValue[];
}

Config Types

SurfnetConfig

interface SurfnetConfig {
offline?: boolean; // default: true
remoteRpcUrl?: string; // setting this implies offline=false
blockProductionMode?: "manual" | "clock" | "transaction"; // default: "transaction"
slotTimeMs?: number; // default: 1
airdropSol?: number; // lamports; default: 10_000_000_000
airdropAddresses?: string[];
payerSecretKey?: ByteArrayLike;
enableFeatures?: string[]; // feature IDs (base58 or kebab name)
disableFeatures?: string[];
allFeatures?: boolean;
}

DeployOptions

interface DeployOptions {
programId: string; // base58 address
soPath?: string; // mutually exclusive with soBytes
soBytes?: ByteArrayLike;
idlPath?: string; // optional Anchor IDL JSON
}

SetTokenAccountUpdate

interface SetTokenAccountUpdate {
amount?: number;
delegate?: string; // base58 pubkey
clearDelegate?: boolean;
state?: string; // e.g. "initialized", "frozen"
delegatedAmount?: number;
closeAuthority?: string;
clearCloseAuthority?: boolean;
}

ResetAccountOptions

interface ResetAccountOptions {
includeOwnedAccounts?: boolean;
}

StreamAccountOptions

interface StreamAccountOptions {
includeOwnedAccounts?: boolean;
}

SolAccountFunding

interface SolAccountFunding {
address: string;
lamports: number;
}

KeypairInfo

interface KeypairInfo {
publicKey: string; // base58
secretKey: number[]; // 64 bytes
}

ByteArrayLike

type ByteArrayLike = Uint8Array | number[];

Where a method accepts ByteArrayLike, you can pass either a Uint8Array or a plain number array. The wrapper normalizes both into the format the native binding expects.

Event Types

SimnetEventValue

A flat object with a kind discriminator and optional fields. See Events for the variant catalog.

interface SimnetEventValue {
kind: string;
message?: string;
timestamp?: string;
initialTransactionCount?: number;
clock?: ClockValue;
epochInfo?: EpochInfoValue;
accountPubkey?: string;
clockCommand?: string;
slotIntervalMs?: number;
transactionSignature?: string;
logs?: string[];
computeUnitsConsumed?: number;
fee?: number;
errorMessage?: string;
tag?: string;
profileKey?: string;
profileSlot?: number;
runbookId?: string;
runbookErrors?: string[];
}

ClockValue

interface ClockValue {
slot: number;
epoch: number;
leaderScheduleEpoch: number;
unixTimestamp: number;
epochStartTimestamp: number;
}

EpochInfoValue

interface EpochInfoValue {
absoluteSlot: number;
slotIndex: number;
slotsInEpoch: number;
epoch: number;
blockHeight: number;
transactionCount?: number;
}

Errors

Every method throws a standard Error whose message wraps the underlying Rust SurfnetError. Inspect error.message to discriminate between cases.

try {
surfnet.deploy({ programId, soPath: "missing.so" });
} catch (err) {
// err.message starts with "Cheatcode:" / "Startup:" / etc.
console.error(err);
}

Native Module Footprint

The package depends on platform-specific native binaries published as optionalDependencies:

TriplePackage
aarch64-apple-darwin@solana/surfpool-darwin-arm64
x86_64-apple-darwin@solana/surfpool-darwin-x64
x86_64-unknown-linux-gnu@solana/surfpool-linux-x64-gnu

If none of the platform packages installs on your machine, Surfnet.start() throws at first call with a clear "native module not found" error. See Installation for the support matrix and troubleshooting.

Is this page helpful?

© 2026 Solana Foundation. All rights reserved.