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