Cheatcodes

Cheatcodes são mutações de estado que contornam o fluxo normal de transações. Eles são executados instantaneamente sem consumir um blockhash ou pagar taxas, o que é exatamente o que você precisa para a configuração de testes.

Em Rust, os cheatcodes ficam em Surfnet::cheatcodes(). Em JS, são métodos diretamente na instância Surfnet.

Financiar SOL

fundSol / fund_sol define o saldo em lamport de qualquer conta, criando a conta se ela não existir.

use surfpool_sdk::{Pubkey, Surfnet};
let surfnet = Surfnet::start().await?;
let cheats = surfnet.cheatcodes();
let wallet = Pubkey::new_unique();
cheats.fund_sol(&wallet, 1_000_000_000)?;
// Fund several accounts in one call.
let bob = Pubkey::new_unique();
let carol = Pubkey::new_unique();
cheats.fund_sol_many(&[(&bob, 2_000_000_000), (&carol, 3_000_000_000)])?;

Financiar Tokens

fundToken / fund_token emite tokens para uma carteira calculando o token account associado, criando-o se necessário, e definindo o valor.

Mints Token-2022

Por padrão, fundToken usa o Token Program SPL clássico. Para mints Token-2022, passe o ID do programa Token-2022 (TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) como argumento final.

use surfpool_sdk::{Pubkey, Surfnet};
let surfnet = Surfnet::start().await?;
let cheats = surfnet.cheatcodes();
let wallet = Pubkey::new_unique();
let mint: Pubkey = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
.parse()
.unwrap();
// Classic SPL Token mint.
cheats.fund_token(&wallet, &mint, 5_000_000, None)?;
// Token-2022 mint — pass the program id explicitly.
let token_2022: Pubkey = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"
.parse()
.unwrap();
cheats.fund_token(&wallet, &mint, 5_000_000, Some(&token_2022))?;
// Fund many wallets with the same mint.
let mob = vec![Pubkey::new_unique(), Pubkey::new_unique()];
cheats.fund_token_many(&mob.iter().collect::<Vec<_>>(), &mint, 1_000_000, None)?;

Para derivar o ATA sem financiamento, use getAta / get_ata:

let ata = cheats.get_ata(&wallet, &mint, None);

Definir Estado Arbitrário de Conta

O método setAccount escreve lamports, proprietário e bytes de dados brutos para qualquer conta em uma única chamada. O SDK Rust também expõe um builder SetAccount para campos mais avançados como rent_epoch e executable.

use surfpool_sdk::cheatcodes::builders::SetAccount;
use surfpool_sdk::{Pubkey, Surfnet};
let surfnet = Surfnet::start().await?;
let cheats = surfnet.cheatcodes();
let address = Pubkey::new_unique();
let owner = Pubkey::new_unique();
// Direct method.
cheats.set_account(&address, 500_000, &[1, 2, 3], &owner)?;
// Builder when you need finer control.
cheats.execute(
SetAccount::new(address)
.lamports(500_000)
.owner(owner)
.data(vec![1, 2, 3])
.rent_epoch(0)
.executable(false),
)?;

Modificar Campos do Token Account

setTokenAccount atualiza os campos avançados de um token account existente — delegado, estado, autoridade de encerramento e valor delegado. Use quando fundToken sozinho não é suficiente.

use surfpool_sdk::cheatcodes::builders::SetTokenAccount;
use surfpool_sdk::{Pubkey, Surfnet};
let cheats = Surfnet::start().await?.cheatcodes();
let owner = Pubkey::new_unique();
let mint: Pubkey = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v".parse()?;
let delegate = Pubkey::new_unique();
cheats.execute(
SetTokenAccount::new(owner, mint)
.amount(2_000_000)
.delegate(delegate)
.delegated_amount(500_000)
.state("initialized"),
)?;
// Later: clear the delegation.
cheats.execute(SetTokenAccount::new(owner, mint).clear_delegate())?;

Redefinir Contas para o Estado Upstream

resetAccount descarta quaisquer mutações locais e busca novamente a conta no RPC upstream. Passe includeOwnedAccounts: true para também redefinir todas as contas pertencentes ao alvo — útil ao redefinir um programa e todos os seus PDAs.

Requer `remoteRpcUrl` para buscar novamente

Em uma Surfnet offline, resetAccount limpa a cópia local, mas não há upstream para buscar. Configure remoteRpcUrl na inicialização para que as redefinições restaurem o estado upstream.

use surfpool_sdk::cheatcodes::builders::ResetAccount;
use surfpool_sdk::{Pubkey, Surfnet};
let cheats = Surfnet::start().await?.cheatcodes();
let token_program: Pubkey = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA".parse()?;
cheats.execute(
ResetAccount::new(token_program).include_owned_accounts(true),
)?;

Transmitir Contas em Tempo Real

streamAccount registra uma conta para polling em segundo plano a partir do RPC upstream. A cópia local da Surfnet permanece sincronizada com a mainnet sem que o teste precise fazer polling explicitamente. Combine com includeOwnedAccounts para transmitir todos os PDAs pertencentes a um programa.

Requer `remoteRpcUrl`

streamAccount só funciona em uma Surfnet iniciada com remoteRpcUrl (ou remote_rpc_url em Rust). Sem um RPC upstream não há nada para transmitir e a chamada retornará um erro.

use surfpool_sdk::cheatcodes::builders::StreamAccount;
use surfpool_sdk::{Pubkey, Surfnet};
let cheats = Surfnet::builder()
.remote_rpc_url("https://api.mainnet-beta.solana.com")
.start()
.await?
.cheatcodes();
let oracle: Pubkey = "H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG".parse()?;
cheats.execute(StreamAccount::new(oracle).include_owned_accounts(false))?;

Construtores de Cheatcode (Rust)

O SDK Rust expõe builders tipados em surfpool_sdk::cheatcodes::builders para casos em que os métodos de conveniência não são suficientes. Cada builder implementa o trait CheatcodeBuilder e é executado via cheats.execute(builder).

BuilderConstructorCommon setters
SetAccountnew(address: Pubkey)lamports, data, owner, rent_epoch, executable
SetTokenAccountnew(owner: Pubkey, mint: Pubkey)amount, delegate, clear_delegate, state, delegated_amount, close_authority, clear_close_authority, token_program
ResetAccountnew(address: Pubkey)include_owned_accounts(bool)
StreamAccountnew(address: Pubkey)include_owned_accounts(bool)
DeployProgramnew(program_id: Pubkey), from_keypair_path(path)so_path, so_bytes, idl_path

Para a superfície JS completa, consulte Referência JS. Para a superfície Rust completa, consulte Referência Rust.

Is this page helpful?

Índice

Editar Página
© 2026 Fundação Solana. Todos os direitos reservados.