light_program_test/program_test/
indexer.rs

1use async_trait::async_trait;
2use light_client::indexer::{
3    Address, AddressWithTree, CompressedAccount, CompressedTokenAccount,
4    GetCompressedAccountsByOwnerConfig, GetCompressedTokenAccountsByOwnerOrDelegateOptions, Hash,
5    Indexer, IndexerError, IndexerRpcConfig, Items, ItemsWithCursor, MerkleProof,
6    NewAddressProofWithContext, OwnerBalance, PaginatedOptions, QueueElementsResult,
7    QueueElementsV2Options, Response, RetryConfig, SignatureWithMetadata, TokenBalance,
8    ValidityProofWithContext,
9};
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<Option<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<Option<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<CompressedTokenAccount>>, 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<Option<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_queue_elements(
186        &mut self,
187        merkle_tree_pubkey: [u8; 32],
188        options: QueueElementsV2Options,
189        config: Option<IndexerRpcConfig>,
190    ) -> Result<Response<QueueElementsResult>, IndexerError> {
191        Ok(self
192            .indexer
193            .as_mut()
194            .ok_or(IndexerError::NotInitialized)?
195            .get_queue_elements(merkle_tree_pubkey, options, config)
196            .await?)
197    }
198
199    async fn get_queue_info(
200        &self,
201        config: Option<IndexerRpcConfig>,
202    ) -> Result<Response<light_client::indexer::QueueInfoResult>, IndexerError> {
203        Ok(self
204            .indexer
205            .as_ref()
206            .ok_or(IndexerError::NotInitialized)?
207            .get_queue_info(config)
208            .await?)
209    }
210
211    async fn get_subtrees(
212        &self,
213        merkle_tree_pubkey: [u8; 32],
214        config: Option<IndexerRpcConfig>,
215    ) -> Result<Response<Items<[u8; 32]>>, IndexerError> {
216        Ok(self
217            .indexer
218            .as_ref()
219            .ok_or(IndexerError::NotInitialized)?
220            .get_subtrees(merkle_tree_pubkey, config)
221            .await?)
222    }
223
224    // New required trait methods
225    async fn get_compressed_balance_by_owner(
226        &self,
227        owner: &Pubkey,
228        config: Option<IndexerRpcConfig>,
229    ) -> Result<Response<u64>, IndexerError> {
230        Ok(self
231            .indexer
232            .as_ref()
233            .ok_or(IndexerError::NotInitialized)?
234            .get_compressed_balance_by_owner(owner, config)
235            .await?)
236    }
237
238    async fn get_compressed_mint_token_holders(
239        &self,
240        mint: &Pubkey,
241        options: Option<PaginatedOptions>,
242        config: Option<IndexerRpcConfig>,
243    ) -> Result<Response<ItemsWithCursor<OwnerBalance>>, IndexerError> {
244        Ok(self
245            .indexer
246            .as_ref()
247            .ok_or(IndexerError::NotInitialized)?
248            .get_compressed_mint_token_holders(mint, options, config)
249            .await?)
250    }
251
252    async fn get_compressed_token_accounts_by_delegate(
253        &self,
254        delegate: &Pubkey,
255        options: Option<GetCompressedTokenAccountsByOwnerOrDelegateOptions>,
256        config: Option<IndexerRpcConfig>,
257    ) -> Result<Response<ItemsWithCursor<CompressedTokenAccount>>, IndexerError> {
258        Ok(self
259            .indexer
260            .as_ref()
261            .ok_or(IndexerError::NotInitialized)?
262            .get_compressed_token_accounts_by_delegate(delegate, options, config)
263            .await?)
264    }
265
266    async fn get_compression_signatures_for_address(
267        &self,
268        address: &[u8; 32],
269        options: Option<PaginatedOptions>,
270        config: Option<IndexerRpcConfig>,
271    ) -> Result<Response<ItemsWithCursor<SignatureWithMetadata>>, IndexerError> {
272        Ok(self
273            .indexer
274            .as_ref()
275            .ok_or(IndexerError::NotInitialized)?
276            .get_compression_signatures_for_address(address, options, config)
277            .await?)
278    }
279
280    async fn get_compression_signatures_for_owner(
281        &self,
282        owner: &Pubkey,
283        options: Option<PaginatedOptions>,
284        config: Option<IndexerRpcConfig>,
285    ) -> Result<Response<ItemsWithCursor<SignatureWithMetadata>>, IndexerError> {
286        Ok(self
287            .indexer
288            .as_ref()
289            .ok_or(IndexerError::NotInitialized)?
290            .get_compression_signatures_for_owner(owner, options, config)
291            .await?)
292    }
293
294    async fn get_compression_signatures_for_token_owner(
295        &self,
296        owner: &Pubkey,
297        options: Option<PaginatedOptions>,
298        config: Option<IndexerRpcConfig>,
299    ) -> Result<Response<ItemsWithCursor<SignatureWithMetadata>>, IndexerError> {
300        Ok(self
301            .indexer
302            .as_ref()
303            .ok_or(IndexerError::NotInitialized)?
304            .get_compression_signatures_for_token_owner(owner, options, config)
305            .await?)
306    }
307
308    async fn get_indexer_health(&self, config: Option<RetryConfig>) -> Result<bool, IndexerError> {
309        Ok(self
310            .indexer
311            .as_ref()
312            .ok_or(IndexerError::NotInitialized)?
313            .get_indexer_health(config)
314            .await?)
315    }
316}