1use account_compression::processor::initialize_address_merkle_tree::Pubkey;
2use anchor_lang::solana_program::system_instruction;
3use light_client::{
4 indexer::Indexer,
5 rpc::{Rpc, RpcError},
6};
7use solana_sdk::{signature::Signer, transaction::Transaction};
8use tokio::time::sleep;
9use tracing::{debug, error};
10
11use crate::error::ForesterUtilsError;
12
13pub async fn airdrop_lamports<R: Rpc>(
14 rpc: &mut R,
15 destination_pubkey: &Pubkey,
16 lamports: u64,
17) -> Result<(), RpcError> {
18 let transfer_instruction =
19 system_instruction::transfer(&rpc.get_payer().pubkey(), destination_pubkey, lamports);
20 let latest_blockhash = rpc.get_latest_blockhash().await?;
21 let transaction = Transaction::new_signed_with_payer(
22 &[transfer_instruction],
23 Some(&rpc.get_payer().pubkey()),
24 &vec![&rpc.get_payer()],
25 latest_blockhash.0,
26 );
27 rpc.process_transaction_with_context(transaction).await?;
28 Ok(())
29}
30
31pub async fn wait_for_indexer<R: Rpc, I: Indexer>(
32 rpc: &mut R,
33 indexer: &I,
34) -> Result<(), ForesterUtilsError> {
35 let rpc_slot = rpc
36 .get_slot()
37 .await
38 .map_err(|_| ForesterUtilsError::Rpc("Failed to get rpc slot".into()))?;
39
40 let indexer_slot = indexer.get_indexer_slot(None).await;
41
42 let mut indexer_slot = match indexer_slot {
43 Ok(slot) => slot,
44 Err(e) => {
45 error!("failed to get indexer slot from indexer: {:?}", e);
46 return Err(ForesterUtilsError::Indexer(
47 "Failed to get indexer slot".into(),
48 ));
49 }
50 };
51
52 let max_attempts = 20;
53 let mut attempts = 0;
54
55 while rpc_slot > indexer_slot {
56 if attempts >= max_attempts {
57 return Err(ForesterUtilsError::Indexer(
58 "Maximum attempts reached waiting for indexer to catch up".into(),
59 ));
60 }
61
62 debug!(
63 "waiting for indexer to catch up, rpc_slot: {}, indexer_slot: {}",
64 rpc_slot, indexer_slot
65 );
66
67 tokio::task::yield_now().await;
68 sleep(std::time::Duration::from_millis(500)).await;
69 indexer_slot = indexer.get_indexer_slot(None).await.map_err(|e| {
70 error!("failed to get indexer slot from indexer: {:?}", e);
71 ForesterUtilsError::Indexer("Failed to get indexer slot".into())
72 })?;
73
74 attempts += 1;
75 }
76 Ok(())
77}