Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

LiteSVM Tests

Pre-Alpha Disclaimer: This is an early pre-alpha release for exploring the SDK and starting development only. There is no real MPC signing — all signatures are generated by a single mock signer, not a distributed network. Do not submit any real transactions for signing or rely on any security guarantees. The dWallet keys, trust model, and signing protocol are not final; do not rely on any key material until mainnet. All interfaces, APIs, and data formats are subject to change without notice. The Solana program and all on-chain data will be wiped periodically and everything will be deleted when we transition to Ika Alpha 1. This software is provided “as is” without warranty of any kind; use is entirely at your own risk and dWallet Labs assumes no liability for any damages arising from its use.

Overview

LiteSVM provides in-process Solana runtime testing. Unlike Mollusk, LiteSVM can:

  • Deploy multiple programs
  • Test CPI calls (e.g., your program calling the dWallet program)
  • Process multiple transactions in sequence
  • Simulate the full transaction lifecycle

LiteSVM is ideal for testing the integration between your program and the dWallet program, including the CPI authority pattern and approve_message calls.

Setup

[dev-dependencies]
litesvm = "0.4"
solana-sdk = "2"

Basic Test Structure

#![allow(unused)]
fn main() {
use litesvm::LiteSVM;
use solana_sdk::{
    instruction::{AccountMeta, Instruction},
    pubkey::Pubkey,
    signature::Keypair,
    signer::Signer,
    transaction::Transaction,
};

#[test]
fn test_voting_with_cpi() {
    let mut svm = LiteSVM::new();

    // Deploy the dWallet program
    let dwallet_program_id = Pubkey::new_unique();
    svm.deploy_program(
        dwallet_program_id,
        include_bytes!("path/to/ika_dwallet_program.so"),
    );

    // Deploy the voting program
    let voting_program_id = Pubkey::new_unique();
    svm.deploy_program(
        voting_program_id,
        include_bytes!("path/to/ika_example_voting.so"),
    );

    // Fund accounts
    let payer = Keypair::new();
    svm.airdrop(&payer.pubkey(), 10_000_000_000).unwrap();

    // ... test transactions ...
}
}

Testing the CPI Path

The key advantage of LiteSVM over Mollusk is testing the quorum -> approve_message CPI path:

#![allow(unused)]
fn main() {
// Step 1: Initialize dWallet program state (mock the NOA setup)
// Step 2: Create a dWallet
// Step 3: Transfer authority to voting program CPI PDA
// Step 4: Create a proposal
// Step 5: Cast votes until quorum triggers approve_message CPI

// After the final vote, verify MessageApproval was created
let ma_data = svm.get_account(&message_approval_pda).unwrap().data;
assert_eq!(ma_data[0], 14); // MessageApproval discriminator
assert_eq!(ma_data[139], 0); // status = Pending
}

When to Use LiteSVM vs Mollusk

FeatureMolluskLiteSVM
SpeedFastestFast
CPI testingNoYes
Multi-programNoYes
Account persistenceNoYes
Transaction sequencingNoYes
Error granularityInstruction levelTransaction level

Use Mollusk for unit-testing individual instructions. Use LiteSVM when you need to test cross-program interactions or multi-step flows.

Tips

  • Pre-populate accounts via svm.set_account() to skip setup transactions
  • Use svm.get_account() to read account data after transactions
  • Deploy both the dWallet program and your program to test the full CPI flow
  • The CPI authority PDA derivation must use b"__ika_cpi_authority" as the seed