light_program_test/forester/
claim_forester.rs

1use light_client::{
2    indexer::Indexer,
3    rpc::{Rpc, RpcError},
4};
5use light_compressible::config::CompressibleConfig;
6use solana_sdk::{
7    pubkey::Pubkey,
8    signature::{Keypair, Signature},
9    signer::Signer,
10};
11
12use crate::registry_sdk::{
13    build_claim_instruction, get_forester_epoch_pda_from_authority, REGISTRY_PROGRAM_ID,
14};
15
16/// Claim rent from compressible token accounts via the registry program
17///
18/// This function invokes the registry program's claim instruction,
19/// which then CPIs to the compressed token program with the correct compression_authority PDA signer.
20///
21/// # Arguments
22/// * `rpc` - RPC client with indexer capabilities
23/// * `token_accounts` - List of compressible token accounts to claim rent from
24/// * `authority` - Authority that can execute the claim
25/// * `payer` - Transaction fee payer
26///
27/// # Returns
28/// `Result<Signature, RpcError>` - Transaction signature
29pub async fn claim_forester<R: Rpc + Indexer>(
30    rpc: &mut R,
31    token_accounts: &[Pubkey],
32    authority: &Keypair,
33    payer: &Keypair,
34) -> Result<Signature, RpcError> {
35    // Compressed token program ID
36    let compressed_token_program_id =
37        Pubkey::from_str_const("cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m");
38
39    let current_epoch = 0;
40
41    // Derive registered forester PDA for the current epoch
42    let (registered_forester_pda, _) =
43        get_forester_epoch_pda_from_authority(&authority.pubkey(), current_epoch);
44    let config = CompressibleConfig::light_token_v1(Default::default(), Default::default());
45    let compressible_config = CompressibleConfig::derive_v1_config_pda(&REGISTRY_PROGRAM_ID).0;
46    let rent_sponsor = config.rent_sponsor;
47    let compression_authority = config.compression_authority;
48
49    // Build the claim instruction using local SDK
50    let claim_ix = build_claim_instruction(
51        authority.pubkey(),
52        registered_forester_pda,
53        rent_sponsor,
54        compression_authority,
55        compressible_config,
56        compressed_token_program_id,
57        token_accounts,
58    );
59
60    // Prepare signers
61    let mut signers = vec![payer];
62    if authority.pubkey() != payer.pubkey() {
63        signers.push(authority);
64    }
65
66    // Send transaction
67    rpc.create_and_send_transaction(&[claim_ix], &payer.pubkey(), &signers)
68        .await
69}