Documentação SolanaLiteSVMRustCaixas Adicionaisanchor-litesvm

Início Rápido

Instalação

Adicione as dependências necessárias:

cargo add --dev anchor-litesvm litesvm litesvm-utils

O que é anchor-litesvm?

O crate anchor-litesvm oferece uma sintaxe simplificada semelhante ao anchor-client, mas sem a sobrecarga de RPC. Obtém uma redução de 78% no código em comparação com o LiteSVM puro, mantendo a segurança de tipos com os tipos do Anchor.

AnchorContext

  • Contexto de teste compatível com produção
  • Mesmos padrões de API que o anchor-client
  • Gerencia instância LiteSVM, pagador e programa
  • Execute instruções sem sobrecarga de RPC

API do Programa - Construção fluente de instruções - Manipulação de contas e argumentos com segurança de tipos - Sintaxe familiar do anchor-client

Desserialização de Contas - Busque e desserialize contas Anchor - Tratamento automático de discriminadores - Suporte para PDAs e layouts personalizados

Análise de Eventos

  • Analise eventos a partir de logs de transações
  • Verifique a emissão de eventos
  • Desserialização de eventos com segurança de tipos

Exemplo Rápido

Com o Anchor 1.0, use declare_program! para gerar tipos de cliente a partir do IDL do seu programa. Esta macro cria os módulos client::accounts::* e client::args::* para a construção de instruções com segurança de tipos:

use anchor_litesvm::AnchorLiteSVM;
use anchor_litesvm::{AssertionHelpers, TestHelpers};
use anchor_lang::system_program;
use solana_sdk::signature::{read_keypair_file, Signer};
// Generate client types from your program's IDL
anchor_lang::declare_program!(my_program);
#[test]
fn test_anchor_program() {
// One-line setup — reads program keypair for the correct ID
let program_keypair = read_keypair_file("target/deploy/my_program-keypair.json").unwrap();
let mut ctx = AnchorLiteSVM::build_with_program(
program_keypair.pubkey(),
include_bytes!("../target/deploy/my_program.so"),
);
// Create a funded account via TestHelpers on ctx.svm
let user = ctx.svm.create_funded_account(10_000_000_000).unwrap();
// Derive PDA
let seed: u64 = 42;
let pda = ctx.svm.get_pda(
&[b"user", user.pubkey().as_ref(), &seed.to_le_bytes()],
&program_keypair.pubkey(),
);
// Build instruction using generated client types
let ix = ctx.program()
.accounts(my_program::client::accounts::Initialize {
user: user.pubkey(),
user_account: pda,
system_program: system_program::ID,
})
.args(my_program::client::args::Initialize {
seed,
name: "test".to_string(),
})
.instruction()
.unwrap();
// Execute and assert in one chain
ctx.execute_instruction(ix, &[&user])
.unwrap()
.assert_success();
// Fetch and deserialize the account
let account: my_program::MyAccount = ctx.get_account(&pda).unwrap();
assert_eq!(account.name, "test");
}

declare_program!(my_program) lê o IDL de target/idl/my_program.json em tempo de compilação e gera os módulos client::accounts::* e client::args::*. Isso requer que seu programa seja compilado primeiro.

Comparação: LiteSVM Bruto vs anchor-litesvm

Antes (LiteSVM Bruto)

use litesvm::LiteSVM;
use solana_keypair::Keypair;
use solana_signer::Signer;
use solana_program::instruction::{AccountMeta, Instruction};
use solana_message::Message;
use solana_transaction::Transaction;
let mut svm = LiteSVM::new();
svm.add_program(program_id, program_bytes).unwrap();
let payer = Keypair::new();
svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();
// Manually compute 8-byte discriminator
let discriminator = {
let mut hasher = sha2::Sha256::new();
hasher.update(b"global:initialize");
let result = hasher.finalize();
result[..8].to_vec()
};
// Manually serialize args and build instruction
let mut data = discriminator;
data.extend_from_slice(&borsh::to_vec(&args).unwrap());
let accounts = vec![
AccountMeta::new(user.pubkey(), true),
AccountMeta::new(user_pda, false),
AccountMeta::new_readonly(system_program::id(), false),
];
let ix = Instruction::new_with_bytes(program_id, &data, accounts);
let tx = Transaction::new_signed_with_payer(
&[ix],
Some(&payer.pubkey()),
&[&payer],
svm.latest_blockhash(),
);
svm.send_transaction(tx).unwrap();
// Manually deserialize with discriminator skip
let account_data = svm.get_account(&pda).unwrap().data;
let account: UserAccount = UserAccount::try_deserialize(
&mut &account_data[8..]
).unwrap();

Depois (anchor-litesvm)

use anchor_litesvm::AnchorLiteSVM;
anchor_lang::declare_program!(my_program);
let mut ctx = AnchorLiteSVM::build_with_program(program_id, program_bytes);
let user = ctx.svm.create_funded_account(10_000_000_000).unwrap();
let ix = ctx.program()
.accounts(my_program::client::accounts::Initialize {
user: user.pubkey(),
user_account: user_pda,
system_program: anchor_lang::system_program::ID,
})
.args(my_program::client::args::Initialize { name: "test".to_string() })
.instruction()
.unwrap();
ctx.execute_instruction(ix, &[&user]).unwrap().assert_success();
let account: my_program::UserAccount = ctx.get_account(&user_pda).unwrap();

Componentes Principais

Construtor AnchorLiteSVM

MétodoDescrição
new()Cria uma nova instância do construtor
with_payer(keypair)Define um keypair de pagador personalizado
deploy_program(id, bytes)Adiciona um programa para implantar
build()Constrói o AnchorContext
build_with_program(id, bytes)Conveniência para programa único
build_with_programs(programs)Implanta múltiplos programas

AnchorContext

MétodoDescrição
svmAcesso direto à instância subjacente de LiteSVM (campo público)
program_idO ID do programa (campo público)
program()Retorna Program para construção de instruções
payer()Obtém o keypair do pagador
execute_instruction(ix, signers)Executa uma única instrução
execute_instructions(ixs, signers)Executa múltiplas instruções em uma transação
send_and_confirm_transaction(&tx)Envia uma transação bruta
get_account<T>(pubkey)Busca e desserializa uma conta Anchor
get_account_unchecked<T>(pubkey)Busca sem verificação de discriminador
create_funded_account(lamports)Cria e financia um novo keypair
airdrop(pubkey, lamports)Faz airdrop de SOL para um endereço
latest_blockhash()Obtém o blockhash atual
account_exists(pubkey)Verifica se uma conta existe
deploy_program(id, bytes)Implanta um programa adicional (via ProgramTestExt)

Programa

MétodoDescrição
accounts(accounts)Define contas de instrução (qualquer tipo ToAccountMetas)
args(args)Define argumentos de instrução (qualquer tipo InstructionData)
instruction()Constrói a Instruction final
id()Obtém o ID do programa

ctx.svm — TestHelpers & AssertionHelpers

ctx.svm é um campo público LiteSVM com as traits TestHelpers e AssertionHelpers disponíveis via litesvm-utils:

MétodoDescrição
ctx.svm.create_funded_account(lamports)Criar e financiar um keypair
ctx.svm.create_token_mint(authority, decimals)Criar um token mint SPL
ctx.svm.create_associated_token_account(mint, owner)Criar uma ATA
ctx.svm.mint_to(mint, token_account, authority, amount)Cunhar tokens
ctx.svm.get_pda(seeds, program_id)Derivar um endereço PDA
ctx.svm.get_pda_with_bump(seeds, program_id)Derivar PDA com bump seed
ctx.svm.assert_token_balance(token_account, expected)Verificar saldo de tokens
ctx.svm.assert_account_closed(pubkey)Verificar se a conta foi encerrada
ctx.svm.assert_sol_balance(pubkey, expected)Verificar saldo de SOL

Solução de Problemas

Erros Comuns

ErroCausaSolução
AccountNotFoundA conta não existeCertifique-se de que a conta foi criada antes de buscá-la
DiscriminatorMismatchTipo de conta incorretoVerifique se está usando a struct de conta correta
DeserializationErrorDados de conta inválidosVerifique se a conta foi inicializada corretamente
Nenhum programa adicionadoChamou build() sem deploy_program()Adicione pelo menos um programa antes de compilar
Tipos de cliente ausentesdeclare_program! não foi chamadoExecute anchor build primeiro para gerar o IDL, depois chame declare_program!

Is this page helpful?

© 2026 Fundação Solana. Todos os direitos reservados.