Kurulum
Gerekli bağımlılıkları ekleyin:
cargo add --dev anchor-litesvm litesvm litesvm-utils
anchor-litesvm Nedir?
anchor-litesvm crate'i, RPC yükü olmaksızın anchor-client'a benzer
basitleştirilmiş bir sözdizimi sağlar. Ham LiteSVM'e kıyasla %78 kod
azaltımı sağlarken Anchor türleriyle tür güvenliğini korur.
AnchorContext
- Prodüksiyonla uyumlu test bağlamı
- anchor-client ile aynı API kalıpları
- LiteSVM örneği, ödeyici ve programı yönetir
- RPC yükü olmadan talimatları çalıştırır
Program API - Akıcı talimat oluşturma - Tür güvenli hesap ve argüman işleme - Tanıdık anchor-client sözdizimi
Hesap Serileştirme Çözme - Anchor hesaplarını getir ve serileştirmeyi çöz
- Otomatik ayrıştırıcı işleme - PDA'lar ve özel düzenler için destek
Olay Ayrıştırma
- İşlem günlüklerinden olayları ayrıştır
- Olay yayımını doğrula
- Tür güvenli olay serileştirme çözme
Hızlı Örnek
Anchor 1.0 ile, programınızın IDL'sinden istemci türleri oluşturmak için
declare_program! kullanın. Bu makro, tür güvenli talimat oluşturma için
client::accounts::* ve client::args::* modülleri oluşturur:
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 IDLanchor_lang::declare_program!(my_program);#[test]fn test_anchor_program() {// One-line setup — reads program keypair for the correct IDlet 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.svmlet user = ctx.svm.create_funded_account(10_000_000_000).unwrap();// Derive PDAlet 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 typeslet 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 chainctx.execute_instruction(ix, &[&user]).unwrap().assert_success();// Fetch and deserialize the accountlet account: my_program::MyAccount = ctx.get_account(&pda).unwrap();assert_eq!(account.name, "test");}
declare_program!(my_program), IDL'yi derleme zamanında
target/idl/my_program.json'dan okur ve client::accounts::* ile
client::args::* modüllerini oluşturur. Bu, önce programınızı derlemenizi
gerektirir.
Karşılaştırma: Ham LiteSVM ile anchor-litesvm
Önce (Ham 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 discriminatorlet 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 instructionlet 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 skiplet account_data = svm.get_account(&pda).unwrap().data;let account: UserAccount = UserAccount::try_deserialize(&mut &account_data[8..]).unwrap();
Sonra (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();
Temel Bileşenler
AnchorLiteSVM Builder
| Yöntem | Açıklama |
|---|---|
new() | Yeni bir builder örneği oluşturur |
with_payer(keypair) | Özel bir ödeyici keypair ayarlar |
deploy_program(id, bytes) | Dağıtılacak bir program ekler |
build() | AnchorContext'i oluşturur |
build_with_program(id, bytes) | Tek program için pratik yöntem |
build_with_programs(programs) | Birden fazla program dağıtır |
AnchorContext
| Yöntem | Açıklama |
|---|---|
svm | Altta yatan LiteSVM örneğine doğrudan erişim (genel alan) |
program_id | Program ID'si (genel alan) |
program() | Komut oluşturma için Program döndürür |
payer() | Ödeyici keypair'i alır |
execute_instruction(ix, signers) | Tek bir komutu yürütür |
execute_instructions(ixs, signers) | Birden fazla komutu tek işlemde yürütür |
send_and_confirm_transaction(&tx) | Ham bir işlem gönderir |
get_account<T>(pubkey) | Bir Anchor hesabını alır ve seri çözümler |
get_account_unchecked<T>(pubkey) | Ayırt edici kontrol olmadan alır |
create_funded_account(lamports) | Yeni bir keypair oluşturur ve fonlar |
airdrop(pubkey, lamports) | Bir adrese SOL airdrop yapar |
latest_blockhash() | Mevcut blockhash'i alır |
account_exists(pubkey) | Bir hesabın var olup olmadığını kontrol eder |
deploy_program(id, bytes) | Ek bir program dağıtır (ProgramTestExt aracılığıyla) |
Program
| Yöntem | Açıklama |
|---|---|
accounts(accounts) | Komut hesaplarını ayarlar (herhangi bir ToAccountMetas türü) |
args(args) | Komut argümanlarını ayarlar (herhangi bir InstructionData türü) |
instruction() | Son Instruction'i oluşturur |
id() | Program ID'sini alır |
ctx.svm — TestHelpers & AssertionHelpers
ctx.svm, TestHelpers ve AssertionHelpers özelliklerine sahip,
litesvm-utils aracılığıyla erişilebilen public bir LiteSVM alanıdır:
| Metot | Açıklama |
|---|---|
ctx.svm.create_funded_account(lamports) | Bir keypair oluştur ve fonla |
ctx.svm.create_token_mint(authority, decimals) | Bir SPL token mint'i oluştur |
ctx.svm.create_associated_token_account(mint, owner) | Bir ATA oluştur |
ctx.svm.mint_to(mint, token_account, authority, amount) | Token'ları mint et |
ctx.svm.get_pda(seeds, program_id) | Bir PDA adresi türet |
ctx.svm.get_pda_with_bump(seeds, program_id) | bump seed ile PDA türet |
ctx.svm.assert_token_balance(token_account, expected) | Token bakiyesini doğrula |
ctx.svm.assert_account_closed(pubkey) | Hesabın kapatıldığını doğrula |
ctx.svm.assert_sol_balance(pubkey, expected) | SOL bakiyesini doğrula |
Sorun Giderme
Yaygın Hatalar
| Hata | Neden | Çözüm |
|---|---|---|
AccountNotFound | Hesap mevcut değil | Hesabın getirilmeden önce oluşturulduğundan emin olun |
DiscriminatorMismatch | Yanlış hesap türü | Doğru hesap yapısını kullandığınızı doğrulayın |
DeserializationError | Geçersiz hesap verisi | Hesabın doğru şekilde başlatıldığını kontrol edin |
| No programs added | deploy_program() olmadan build() çağrıldı | Derleme öncesinde en az bir program ekleyin |
| Missing client types | declare_program! çağrılmadı | Önce IDL oluşturmak için anchor build çalıştırın, ardından declare_program! çağırın |
Is this page helpful?