light_program_test/lib.rs
1//! # Light Program Test
2//!
3//! A fast local test environment for Solana programs using compressed accounts and tokens.
4//!
5//! ## Features
6//! - Fast in-memory indexer and SVM via [LiteSVM](https://github.com/LiteSVM/LiteSVM)
7//! - Supports custom programs
8//! - Built-in prover
9//!
10//! **Use `light-program-test` when:**
11//! - You need fast test execution
12//! - You write unit/integration tests for your program or client code
13//!
14//! **Use `solana-test-validator` when:**
15//! - You need RPC methods or external tools that are incompatible with LiteSVM
16//! - Testing against real validator behavior
17//!
18//! ## Configuration Options
19//!
20//! ### `with_prover: bool`
21//! - `true`: Starts a prover server in the background for generating validity proofs
22//! - `false`: Runs without prover (faster for tests that don't need proofs, or repeated test runs to reduce startup time)
23//!
24//! ### `additional_programs: Option<Vec<(&str, Pubkey)>>`
25//! - Specify custom programs to deploy alongside the default Light Protocol programs
26//! - Format: `vec![("program_name", program_id)]`
27//! - Programs are loaded from built artifacts
28//!
29//! ## Prerequisites
30//!
31//! 1. **ZK Compression CLI**: Required to start the prover server and download Light Protocol programs
32//! ```bash
33//! npm i -g @lightprotocol/zk-compression-cli
34//! ```
35//! - If programs are missing after CLI installation, run `light test-validator` once to download them
36//!
37//! 2. **Build programs**: Run `cargo test-sbf` to build program binaries and set the required
38//! environment variables for locating program artifacts
39//!
40//! ## Prover Server
41//!
42//! The prover server runs on port 3001 when enabled. To manually stop it:
43//! ```bash
44//! # Find the process ID
45//! lsof -i:3001
46//! # Kill the process
47//! kill <pid>
48//! ```
49//!
50//! ## Examples
51//!
52//! ### V1 Trees
53//! ```rust
54//! use light_program_test::{LightProgramTest, ProgramTestConfig};
55//! use solana_sdk::signer::Signer;
56//!
57//! #[tokio::test]
58//! async fn test_v1_compressed_account() {
59//! // Initialize with v1 trees
60//! let config = ProgramTestConfig::default();
61//! let mut rpc = LightProgramTest::new(config).await.unwrap();
62//!
63//! let payer = Keypair::new();
64//!
65//! // Get v1 tree info
66//! let address_tree_info = rpc.get_address_tree_v1();
67//! let state_tree_info = rpc.get_random_state_tree_info();
68//!
69//! // Airdrop for testing
70//! rpc.airdrop_lamports(&payer.pubkey(), 1_000_000_000).await.unwrap();
71//!
72//! // Query compressed accounts using Indexer trait
73//! let accounts = rpc.indexer().unwrap()
74//! .get_compressed_accounts_by_owner(&payer.pubkey())
75//! .await
76//! .unwrap();
77//!
78//! println!("Found {} compressed accounts", accounts.len());
79//! }
80//! ```
81//!
82//! ### V2 Trees
83//! ```rust
84//! use light_program_test::{LightProgramTest, ProgramTestConfig};
85//! use solana_sdk::signer::Signer;
86//!
87//! #[tokio::test]
88//! async fn test_v2_compressed_account() {
89//! // Initialize with v2 batched trees and custom program
90//! let config = ProgramTestConfig::new_v2(
91//! true, // with_prover
92//! Some(vec![("my_program", my_program::ID)])
93//! );
94//! let mut rpc = LightProgramTest::new(config).await.unwrap();
95//!
96//! let payer = Keypair::new();
97//!
98//! // Get v2 tree pubkeys
99//! let address_tree_info = rpc.get_address_tree_v2();
100//! let state_tree_info = rpc.get_random_state_tree_info();
101//!
102//!
103//! rpc.airdrop_lamports(&payer.pubkey(), 1_000_000_000).await.unwrap();
104//!
105//! // Query using Indexer trait methods
106//! let accounts = rpc.indexer().unwrap()
107//! .get_compressed_accounts_by_owner(&payer.pubkey())
108//! .await
109//! .unwrap();
110//!
111//! println!("Found {} compressed accounts with v2 trees", accounts.len());
112//! }
113//! ```
114
115pub mod accounts;
116pub mod indexer;
117pub mod program_test;
118pub mod utils;
119
120pub use light_client::{
121 indexer::{AddressWithTree, Indexer},
122 rpc::{Rpc, RpcError},
123};
124pub use program_test::{config::ProgramTestConfig, LightProgramTest};