light_program_test/program_test/
indexer.rs

1use async_trait::async_trait;
2use light_client::indexer::{
3    Address, AddressWithTree, BatchAddressUpdateIndexerResponse, CompressedAccount,
4    GetCompressedAccountsByOwnerConfig, GetCompressedTokenAccountsByOwnerOrDelegateOptions, Hash,
5    Indexer, IndexerError, IndexerRpcConfig, Items, ItemsWithCursor, MerkleProof,
6    MerkleProofWithContext, NewAddressProofWithContext, OwnerBalance, PaginatedOptions, Response,
7    RetryConfig, SignatureWithMetadata, TokenAccount, TokenBalance, ValidityProofWithContext,
8};
9use light_compressed_account::QueueType;
10use solana_sdk::pubkey::Pubkey;
11
12use crate::program_test::LightProgramTest;
13
14#[async_trait]
15impl Indexer for LightProgramTest {
16    async fn get_validity_proof(
17        &self,
18        hashes: Vec<Hash>,
19        new_addresses_with_trees: Vec<AddressWithTree>,
20        config: Option<IndexerRpcConfig>,
21    ) -> Result<Response<ValidityProofWithContext>, IndexerError> {
22        Ok(self
23            .indexer
24            .as_ref()
25            .ok_or(IndexerError::NotInitialized)?
26            .get_validity_proof(hashes, new_addresses_with_trees, config)
27            .await?)
28    }
29
30    async fn get_indexer_slot(&self, config: Option<RetryConfig>) -> Result<u64, IndexerError> {
31        Ok(self
32            .indexer
33            .as_ref()
34            .ok_or(IndexerError::NotInitialized)?
35            .get_indexer_slot(config)
36            .await?)
37    }
38
39    async fn get_multiple_compressed_account_proofs(
40        &self,
41        hashes: Vec<[u8; 32]>,
42        config: Option<IndexerRpcConfig>,
43    ) -> Result<Response<Items<MerkleProof>>, IndexerError> {
44        Ok(self
45            .indexer
46            .as_ref()
47            .ok_or(IndexerError::NotInitialized)?
48            .get_multiple_compressed_account_proofs(hashes, config)
49            .await?)
50    }
51
52    async fn get_compressed_accounts_by_owner(
53        &self,
54        owner: &Pubkey,
55        options: Option<GetCompressedAccountsByOwnerConfig>,
56        config: Option<IndexerRpcConfig>,
57    ) -> Result<Response<ItemsWithCursor<CompressedAccount>>, IndexerError> {
58        Ok(self
59            .indexer
60            .as_ref()
61            .ok_or(IndexerError::NotInitialized)?
62            .get_compressed_accounts_by_owner(owner, options, config)
63            .await?)
64    }
65
66    async fn get_compressed_account(
67        &self,
68        address: Address,
69        config: Option<IndexerRpcConfig>,
70    ) -> Result<Response<CompressedAccount>, IndexerError> {
71        Ok(self
72            .indexer
73            .as_ref()
74            .ok_or(IndexerError::NotInitialized)?
75            .get_compressed_account(address, config)
76            .await?)
77    }
78
79    async fn get_compressed_account_by_hash(
80        &self,
81        hash: Hash,
82        config: Option<IndexerRpcConfig>,
83    ) -> Result<Response<CompressedAccount>, IndexerError> {
84        Ok(self
85            .indexer
86            .as_ref()
87            .ok_or(IndexerError::NotInitialized)?
88            .get_compressed_account_by_hash(hash, config)
89            .await?)
90    }
91
92    async fn get_compressed_token_accounts_by_owner(
93        &self,
94        owner: &Pubkey,
95        options: Option<GetCompressedTokenAccountsByOwnerOrDelegateOptions>,
96        config: Option<IndexerRpcConfig>,
97    ) -> Result<Response<ItemsWithCursor<TokenAccount>>, IndexerError> {
98        Ok(self
99            .indexer
100            .as_ref()
101            .ok_or(IndexerError::NotInitialized)?
102            .get_compressed_token_accounts_by_owner(owner, options, config)
103            .await?)
104    }
105
106    async fn get_compressed_balance(
107        &self,
108        address: Option<Address>,
109        hash: Option<Hash>,
110        config: Option<IndexerRpcConfig>,
111    ) -> Result<Response<u64>, IndexerError> {
112        let indexer = self.indexer.as_ref().ok_or(IndexerError::NotInitialized)?;
113        Ok(Indexer::get_compressed_balance(indexer, address, hash, config).await?)
114    }
115
116    async fn get_compressed_token_account_balance(
117        &self,
118        address: Option<Address>,
119        hash: Option<Hash>,
120        config: Option<IndexerRpcConfig>,
121    ) -> Result<Response<u64>, IndexerError> {
122        Ok(self
123            .indexer
124            .as_ref()
125            .ok_or(IndexerError::NotInitialized)?
126            .get_compressed_token_account_balance(address, hash, config)
127            .await?)
128    }
129
130    async fn get_multiple_compressed_accounts(
131        &self,
132        addresses: Option<Vec<Address>>,
133        hashes: Option<Vec<Hash>>,
134        config: Option<IndexerRpcConfig>,
135    ) -> Result<Response<Items<CompressedAccount>>, IndexerError> {
136        Ok(self
137            .indexer
138            .as_ref()
139            .ok_or(IndexerError::NotInitialized)?
140            .get_multiple_compressed_accounts(addresses, hashes, config)
141            .await?)
142    }
143
144    async fn get_compressed_token_balances_by_owner_v2(
145        &self,
146        owner: &Pubkey,
147        options: Option<GetCompressedTokenAccountsByOwnerOrDelegateOptions>,
148        config: Option<IndexerRpcConfig>,
149    ) -> Result<Response<ItemsWithCursor<TokenBalance>>, IndexerError> {
150        Ok(self
151            .indexer
152            .as_ref()
153            .ok_or(IndexerError::NotInitialized)?
154            .get_compressed_token_balances_by_owner_v2(owner, options, config)
155            .await?)
156    }
157
158    async fn get_compression_signatures_for_account(
159        &self,
160        hash: Hash,
161        config: Option<IndexerRpcConfig>,
162    ) -> Result<Response<Items<SignatureWithMetadata>>, IndexerError> {
163        Ok(self
164            .indexer
165            .as_ref()
166            .ok_or(IndexerError::NotInitialized)?
167            .get_compression_signatures_for_account(hash, config)
168            .await?)
169    }
170
171    async fn get_multiple_new_address_proofs(
172        &self,
173        merkle_tree_pubkey: [u8; 32],
174        addresses: Vec<[u8; 32]>,
175        config: Option<IndexerRpcConfig>,
176    ) -> Result<Response<Items<NewAddressProofWithContext>>, IndexerError> {
177        Ok(self
178            .indexer
179            .as_ref()
180            .ok_or(IndexerError::NotInitialized)?
181            .get_multiple_new_address_proofs(merkle_tree_pubkey, addresses, config)
182            .await?)
183    }
184
185    async fn get_address_queue_with_proofs(
186        &mut self,
187        merkle_tree_pubkey: &Pubkey,
188        zkp_batch_size: u16,
189        start_offset: Option<u64>,
190        config: Option<IndexerRpcConfig>,
191    ) -> Result<Response<BatchAddressUpdateIndexerResponse>, IndexerError> {
192        Ok(self
193            .indexer
194            .as_mut()
195            .ok_or(IndexerError::NotInitialized)?
196            .get_address_queue_with_proofs(merkle_tree_pubkey, zkp_batch_size, start_offset, config)
197            .await?)
198    }
199
200    async fn get_queue_elements(
201        &mut self,
202        merkle_tree_pubkey: [u8; 32],
203        queue_type: QueueType,
204        num_elements: u16,
205        start_offset: Option<u64>,
206        config: Option<IndexerRpcConfig>,
207    ) -> Result<Response<Items<MerkleProofWithContext>>, IndexerError> {
208        Ok(self
209            .indexer
210            .as_mut()
211            .ok_or(IndexerError::NotInitialized)?
212            .get_queue_elements(
213                merkle_tree_pubkey,
214                queue_type,
215                num_elements,
216                start_offset,
217                config,
218            )
219            .await?)
220    }
221
222    async fn get_subtrees(
223        &self,
224        merkle_tree_pubkey: [u8; 32],
225        config: Option<IndexerRpcConfig>,
226    ) -> Result<Response<Items<[u8; 32]>>, IndexerError> {
227        Ok(self
228            .indexer
229            .as_ref()
230            .ok_or(IndexerError::NotInitialized)?
231            .get_subtrees(merkle_tree_pubkey, config)
232            .await?)
233    }
234
235    // New required trait methods
236    async fn get_compressed_balance_by_owner(
237        &self,
238        owner: &Pubkey,
239        config: Option<IndexerRpcConfig>,
240    ) -> Result<Response<u64>, IndexerError> {
241        Ok(self
242            .indexer
243            .as_ref()
244            .ok_or(IndexerError::NotInitialized)?
245            .get_compressed_balance_by_owner(owner, config)
246            .await?)
247    }
248
249    async fn get_compressed_mint_token_holders(
250        &self,
251        mint: &Pubkey,
252        options: Option<PaginatedOptions>,
253        config: Option<IndexerRpcConfig>,
254    ) -> Result<Response<ItemsWithCursor<OwnerBalance>>, IndexerError> {
255        Ok(self
256            .indexer
257            .as_ref()
258            .ok_or(IndexerError::NotInitialized)?
259            .get_compressed_mint_token_holders(mint, options, config)
260            .await?)
261    }
262
263    async fn get_compressed_token_accounts_by_delegate(
264        &self,
265        delegate: &Pubkey,
266        options: Option<GetCompressedTokenAccountsByOwnerOrDelegateOptions>,
267        config: Option<IndexerRpcConfig>,
268    ) -> Result<Response<ItemsWithCursor<TokenAccount>>, IndexerError> {
269        Ok(self
270            .indexer
271            .as_ref()
272            .ok_or(IndexerError::NotInitialized)?
273            .get_compressed_token_accounts_by_delegate(delegate, options, config)
274            .await?)
275    }
276
277    async fn get_compression_signatures_for_address(
278        &self,
279        address: &[u8; 32],
280        options: Option<PaginatedOptions>,
281        config: Option<IndexerRpcConfig>,
282    ) -> Result<Response<ItemsWithCursor<SignatureWithMetadata>>, IndexerError> {
283        Ok(self
284            .indexer
285            .as_ref()
286            .ok_or(IndexerError::NotInitialized)?
287            .get_compression_signatures_for_address(address, options, config)
288            .await?)
289    }
290
291    async fn get_compression_signatures_for_owner(
292        &self,
293        owner: &Pubkey,
294        options: Option<PaginatedOptions>,
295        config: Option<IndexerRpcConfig>,
296    ) -> Result<Response<ItemsWithCursor<SignatureWithMetadata>>, IndexerError> {
297        Ok(self
298            .indexer
299            .as_ref()
300            .ok_or(IndexerError::NotInitialized)?
301            .get_compression_signatures_for_owner(owner, options, config)
302            .await?)
303    }
304
305    async fn get_compression_signatures_for_token_owner(
306        &self,
307        owner: &Pubkey,
308        options: Option<PaginatedOptions>,
309        config: Option<IndexerRpcConfig>,
310    ) -> Result<Response<ItemsWithCursor<SignatureWithMetadata>>, IndexerError> {
311        Ok(self
312            .indexer
313            .as_ref()
314            .ok_or(IndexerError::NotInitialized)?
315            .get_compression_signatures_for_token_owner(owner, options, config)
316            .await?)
317    }
318
319    async fn get_indexer_health(&self, config: Option<RetryConfig>) -> Result<bool, IndexerError> {
320        Ok(self
321            .indexer
322            .as_ref()
323            .ok_or(IndexerError::NotInitialized)?
324            .get_indexer_health(config)
325            .await?)
326    }
327}