use anchor_litesvm::{AnchorLiteSVM, TestHelpers, AssertionHelpers, tuple_args};
use solana_sdk::signature::Signer;
use solana_program::pubkey::Pubkey;
use borsh::BorshSerialize;
#[derive(BorshSerialize)]
#[allow(dead_code)]
struct TransferArgs {
amount: u64,
}
fn main() {
println!("=== Code Comparison: Traditional vs anchor-litesvm ===\n");
traditional_approach();
println!("\n{}\n", "=".repeat(60));
using_anchor_litesvm();
println!("\n=== Results ===");
println!("Traditional approach: ~50 lines for basic test");
println!("With anchor-litesvm: ~10 lines for same test");
println!("Code reduction: 80%");
}
fn traditional_approach() {
println!("TRADITIONAL APPROACH (Raw LiteSVM):");
println!("------------------------------------\n");
println!("// Setup - requires manual initialization");
println!("let mut svm = LiteSVM::new();");
println!("let program_bytes = include_bytes!(\"../target/deploy/program.so\");");
println!("svm.add_program(program_id, program_bytes);");
println!();
println!("// Account creation - manual transaction building");
println!("let maker = Keypair::new();");
println!("svm.airdrop(&maker.pubkey(), 10_000_000_000)?;");
println!();
println!("// Token mint creation - multiple instructions");
println!("let mint = Keypair::new();");
println!("let rent = svm.minimum_balance_for_rent_exemption(82);");
println!("let create_account_ix = system_instruction::create_account(...);");
println!("let init_mint_ix = spl_token::instruction::initialize_mint(...);");
println!("let tx = Transaction::new_signed_with_payer(&[create_account_ix, init_mint_ix], ...);");
println!("svm.send_transaction(tx)?;");
println!();
println!("// Instruction building - manual discriminator");
println!("use sha2::{{Digest, Sha256}};");
println!("let mut hasher = Sha256::new();");
println!("hasher.update(b\"global:transfer\");");
println!("let hash = hasher.finalize();");
println!("let mut discriminator = [0u8; 8];");
println!("discriminator.copy_from_slice(&hash[..8]);");
println!();
println!("// Manual data serialization");
println!("let mut instruction_data = discriminator.to_vec();");
println!("instruction_data.extend_from_slice(&amount.to_le_bytes());");
println!();
println!("// Manual account meta setup");
println!("let accounts = vec![");
println!(" AccountMeta::new(from_account, true),");
println!(" AccountMeta::new(to_account, false),");
println!(" AccountMeta::new_readonly(authority, true),");
println!(" // ... more accounts");
println!("];");
println!();
println!("// Transaction execution");
println!("let ix = Instruction {{ program_id, accounts, data: instruction_data }};");
println!("let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash);");
println!("let result = svm.send_transaction(tx)?;");
println!();
println!("// Manual assertions");
println!("let account = svm.get_account(&token_account)?;");
println!("let token_data = unpack_token_account(&account.data)?;");
println!("assert_eq!(token_data.amount, expected_amount);");
}
fn using_anchor_litesvm() {
println!("WITH ANCHOR-LITESVM:");
println!("--------------------\n");
println!("// One-line setup!");
println!("let mut ctx = AnchorLiteSVM::build_with_program(program_id, program_bytes);");
println!();
println!("// Simple account creation");
println!("let maker = ctx.create_funded_account(10_000_000_000)?;");
println!("let mint = ctx.create_token_mint(&maker, 9)?;");
println!("let ata = ctx.create_token_account(&maker, &mint.pubkey(), Some((1_000_000, &maker)))?;");
println!();
println!("// Fluent instruction building with automatic discriminator");
println!("let result = ctx.instruction_builder(\"transfer\")");
println!(" .signer(\"from\", &from_account)");
println!(" .account_mut(\"to\", to_account)");
println!(" .account(\"authority\", authority.pubkey())");
println!(" .token_program()");
println!(" .args(tuple_args((amount,))) // No struct needed!");
println!(" .execute(&mut ctx, &[&from_account])?;");
println!();
println!("// Clean assertions");
println!("result.assert_success();");
println!("ctx.assert_token_balance(&token_account, expected_amount);");
}
#[allow(dead_code)]
fn example_complete_test() {
let program_id = Pubkey::new_unique();
let program_bytes = vec![];
let mut ctx = AnchorLiteSVM::build_with_program(program_id, &program_bytes);
let maker = ctx.create_funded_account(10_000_000_000).unwrap();
let taker = ctx.create_funded_account(10_000_000_000).unwrap();
let mint_a = ctx.create_token_mint(&maker, 9).unwrap();
let _mint_b = ctx.create_token_mint(&taker, 9).unwrap();
let maker_ata = ctx.create_token_account(
&maker,
&mint_a.pubkey(),
Some((1_000_000_000, &maker))
).unwrap();
ctx.instruction_builder("transfer")
.signer("sender", &maker)
.account_mut("from", maker_ata)
.account_mut("to", taker.pubkey())
.account("mint", mint_a.pubkey())
.token_program()
.args(tuple_args((500_000_000u64,))) .execute(&mut ctx, &[&maker])
.unwrap()
.assert_success();
ctx.assert_token_balance(&maker_ata, 500_000_000);
}
#[allow(dead_code)]
fn example_error_handling() {
let program_id = Pubkey::new_unique();
let program_bytes = vec![];
let mut ctx = AnchorLiteSVM::build_with_program(program_id, &program_bytes);
let account = ctx.create_funded_account(1_000_000_000).unwrap();
let result = ctx.instruction_builder("risky_operation")
.signer("user", &account)
.account_mut("target", Pubkey::new_unique())
.args(tuple_args(()))
.execute(&mut ctx, &[&account]);
match result {
Ok(tx_result) => {
println!("Transaction succeeded!");
if tx_result.has_log("Success") {
println!("Found success message in logs");
}
println!("Used {} compute units", tx_result.compute_units());
}
Err(e) => {
println!("Transaction failed: {:?}", e);
}
}
}
#[allow(dead_code)]
fn example_multiple_programs() {
use anchor_litesvm::AnchorLiteSVM;
let program1_id = Pubkey::new_unique();
let program2_id = Pubkey::new_unique();
let program1_bytes = vec![];
let program2_bytes = vec![];
let mut ctx = AnchorLiteSVM::new()
.deploy_program(program1_id, &program1_bytes)
.deploy_program(program2_id, &program2_bytes)
.with_primary_program(program1_id)
.build();
let user = ctx.create_funded_account(10_000_000_000).unwrap();
ctx.instruction_builder("initialize")
.signer("user", &user)
.account_mut("state", Pubkey::new_unique())
.system_program()
.args(tuple_args(()))
.execute(&mut ctx, &[&user])
.unwrap()
.assert_success();
}