Solana documentatieLiteSVMRustAanvullende Cratesanchor-litesvm

Snel starten

Installatie

Voeg de benodigde afhankelijkheden toe:

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

Wat is anchor-litesvm?

De anchor-litesvm crate biedt een vereenvoudigde syntaxis vergelijkbaar met anchor-client maar zonder RPC-overhead. Het bereikt een 78% codevermindering ten opzichte van raw LiteSVM, terwijl typeveiligheid met Anchor-typen behouden blijft.

AnchorContext

  • Productiecompatibele testcontext
  • Dezelfde API-patronen als anchor-client
  • Beheert LiteSVM-instantie, betaler en programma
  • Voer instructies uit zonder RPC-overhead

Programma-API - Vloeiende instructieopbouw - Typeveilige account- en argumentafhandeling - Vertrouwde anchor-client-syntaxis

Account-deserialisatie - Ophalen en deserialiseren van Anchor-accounts - Automatische discriminatorverwerking - Ondersteuning voor PDA's en aangepaste indelingen

Gebeurtenisverwerking

  • Verwerk gebeurtenissen uit transactielogboeken
  • Bevestig gebeurtenisemissie
  • Typeveilige gebeurtenisdeserialisatie

Snel voorbeeld

Met Anchor 1.0 gebruik je declare_program! om clienttypen te genereren vanuit de IDL van je programma. Deze macro maakt de modules client::accounts::* en client::args::* aan voor typeveilige instructieopbouw:

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) leest de IDL uit target/idl/my_program.json tijdens het compileren en genereert de modules client::accounts::* en client::args::*. Dit vereist dat je programma eerst is gebouwd.

Vergelijking: Raw LiteSVM vs anchor-litesvm

Vóór (Raw LiteSVM)

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();

Na (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();

Belangrijkste Componenten

AnchorLiteSVM Builder

MethodeBeschrijving
new()Maakt een nieuwe builder-instantie aan
with_payer(keypair)Stelt een aangepaste betaler keypair in
deploy_program(id, bytes)Voegt een programma toe om te implementeren
build()Bouwt de AnchorContext
build_with_program(id, bytes)Handige methode voor één enkel programma
build_with_programs(programs)Implementeert meerdere programma's

AnchorContext

MethodeBeschrijving
svmDirecte toegang tot de onderliggende LiteSVM instantie (openbaar veld)
program_idHet programma-ID (openbaar veld)
program()Geeft Program terug voor het bouwen van instructies
payer()Haal de betaler keypair op
execute_instruction(ix, signers)Voer een enkele instructie uit
execute_instructions(ixs, signers)Voer meerdere instructies uit in één transactie
send_and_confirm_transaction(&tx)Verstuur een ruwe transactie
get_account<T>(pubkey)Haal een Anchor-account op en deserialiseer het
get_account_unchecked<T>(pubkey)Ophalen zonder discriminatorcontrole
create_funded_account(lamports)Maak een nieuwe keypair aan en financier deze
airdrop(pubkey, lamports)Stort SOL bij op een adres
latest_blockhash()Haal de huidige blockhash op
account_exists(pubkey)Controleer of een account bestaat
deploy_program(id, bytes)Implementeer een extra programma (via ProgramTestExt)

Program

MethodeBeschrijving
accounts(accounts)Stel instructie-accounts in (elk ToAccountMetas type)
args(args)Stel instructieargumenten in (elk InstructionData type)
instruction()Bouw de uiteindelijke Instruction
id()Haal het programma-ID op

ctx.svm — TestHelpers & AssertionHelpers

ctx.svm is een publiek LiteSVM veld met TestHelpers en AssertionHelpers traits beschikbaar via litesvm-utils:

MethodeBeschrijving
ctx.svm.create_funded_account(lamports)Maak een keypair aan en financier het
ctx.svm.create_token_mint(authority, decimals)Maak een SPL-token mint aan
ctx.svm.create_associated_token_account(mint, owner)Maak een ATA aan
ctx.svm.mint_to(mint, token_account, authority, amount)Tokens minten
ctx.svm.get_pda(seeds, program_id)Leid een PDA-adres af
ctx.svm.get_pda_with_bump(seeds, program_id)Leid PDA af met bump seed
ctx.svm.assert_token_balance(token_account, expected)Controleer tokensaldo
ctx.svm.assert_account_closed(pubkey)Controleer of account gesloten is
ctx.svm.assert_sol_balance(pubkey, expected)Controleer SOL-saldo

Probleemoplossing

Veelvoorkomende fouten

FoutOorzaakOplossing
AccountNotFoundAccount bestaat nietZorg dat het account is aangemaakt voordat het wordt opgehaald
DiscriminatorMismatchVerkeerd accounttypeControleer of je de juiste accountstructuur gebruikt
DeserializationErrorOngeldige accountgegevensControleer of het account correct is geïnitialiseerd
No programs addedbuild() aangeroepen zonder deploy_program()Voeg minimaal één programma toe voordat je bouwt
Missing client typesdeclare_program! niet aangeroepenVoer eerst anchor build uit om de IDL te genereren, roep dan declare_program! aan

Is this page helpful?

© 2026 Solana Foundation. Alle rechten voorbehouden.