SolanaドキュメントLiteSVMRust追加クレートanchor-litesvm

クイックスタート

インストール

必要な依存関係を追加します:

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

anchor-litesvm とは?

anchor-litesvm クレートは、RPCのオーバーヘッドなしに anchor-client に似た簡略化された構文を提供します。Anchor の型で型安全性を維持しながら、生の LiteSVM と比較して コードを78%削減します。

AnchorContext

  • 本番環境対応のテストコンテキスト
  • anchor-client と同じ API パターン
  • LiteSVM インスタンス、ペイヤー、プログラムを管理
  • RPC オーバーヘッドなしで instructions を実行

プログラム API - 流れるようなインストラクション構築 - 型安全なアカウントと引数の処理 - 使い慣れた anchor-client の構文

アカウントのデシリアライズ - Anchor アカウントの取得とデシリアライズ - ディスクリミネーターの自動処理 - PDA およびカスタムレイアウトのサポート

イベントのパース

  • トランザクションログからイベントをパース
  • イベント発行のアサート
  • 型安全なイベントのデシリアライズ

クイックサンプル

Anchor 1.0 では、declare_program! を使用してプログラムの IDL からクライアント型を生成します。このマクロは、型安全な instructions 構築のための client::accounts::* および client::args::* モジュールを作成します:

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) はコンパイル時に target/idl/my_program.json から IDL を読み込み、client::accounts::* および client::args::* モジュールを生成します。これにはプログラムを事前にビルドする必要があります。

比較:Raw LiteSVM と anchor-litesvm

変更前(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();

変更後(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();

主要コンポーネント

AnchorLiteSVM ビルダー

メソッド説明
new()新しいビルダーインスタンスを作成
with_payer(keypair)カスタムペイヤー keypair を設定
deploy_program(id, bytes)デプロイするプログラムを追加
build()AnchorContext をビルド
build_with_program(id, bytes)単一プログラム向けの便利メソッド
build_with_programs(programs)複数プログラムをデプロイ

AnchorContext

メソッド説明
svm基盤となる LiteSVM インスタンスへの直接アクセス(パブリックフィールド)
program_idプログラム ID(パブリックフィールド)
program()instructions ビルド用の Program を返す
payer()ペイヤー Keypair を取得
execute_instruction(ix, signers)単一の instruction を実行
execute_instructions(ixs, signers)1 つのトランザクションで複数の instructions を実行
send_and_confirm_transaction(&tx)生のトランザクションを送信
get_account<T>(pubkey)Anchor アカウントをフェッチしてデシリアライズ
get_account_unchecked<T>(pubkey)ディスクリミネーターチェックなしでフェッチ
create_funded_account(lamports)新しい keypair を作成してSOLをエアドロップ
airdrop(pubkey, lamports)アドレスに SOL をエアドロップ
latest_blockhash()現在のブロックハッシュを取得
account_exists(pubkey)アカウントの存在を確認
deploy_program(id, bytes)追加プログラムをデプロイ(ProgramTestExt 経由)

Program

メソッド説明
accounts(accounts)instruction アカウントを設定(任意の ToAccountMetas 型)
args(args)instruction 引数を設定(任意の InstructionData 型)
instruction()最終的な Instruction をビルド
id()プログラム ID を取得

ctx.svm — TestHelpers と AssertionHelpers

ctx.svm は、LiteSVM の public フィールドであり、litesvm-utils を通じて TestHelpers および AssertionHelpers トレイトが利用可能です:

メソッド説明
ctx.svm.create_funded_account(lamports)keypair を作成して資金を追加
ctx.svm.create_token_mint(authority, decimals)SPL トークンミントを作成
ctx.svm.create_associated_token_account(mint, owner)ATA を作成
ctx.svm.mint_to(mint, token_account, authority, amount)トークンをミント
ctx.svm.get_pda(seeds, program_id)PDA アドレスを導出
ctx.svm.get_pda_with_bump(seeds, program_id)bump seed を使用して PDA を導出
ctx.svm.assert_token_balance(token_account, expected)トークン残高をアサート
ctx.svm.assert_account_closed(pubkey)アカウントがクローズされたことをアサート
ctx.svm.assert_sol_balance(pubkey, expected)SOL 残高をアサート

トラブルシューティング

よくあるエラー

エラー原因解決策
AccountNotFoundアカウントが存在しないフェッチ前にアカウントが作成されていることを確認してください
DiscriminatorMismatchアカウントの種類が異なる正しいアカウント構造体を使用しているか確認してください
DeserializationErrorアカウントデータが無効アカウントが正しく初期化されているか確認してください
No programs addeddeploy_program() なしで build() を呼び出したビルド前に少なくとも1つのプログラムを追加してください
Missing client typesdeclare_program! が呼び出されていないまず anchor build を実行して IDL を生成し、その後 declare_program! を呼び出してください

Is this page helpful?

© 2026 Solana Foundation. 無断転載を禁じます。