light_system_program/invoke/
sol_compression.rs1use account_compression::utils::transfer_lamports::transfer_lamports_cpi;
2use aligned_sized::*;
3use anchor_lang::{
4 prelude::*,
5 solana_program::{account_info::AccountInfo, pubkey::Pubkey},
6 Bumps,
7};
8
9use crate::{
10 errors::SystemProgramError,
11 sdk::accounts::{InvokeAccounts, SignerAccounts},
12 InstructionDataInvoke,
13};
14
15#[account]
16#[aligned_sized(anchor)]
17pub struct CompressedSolPda {}
18
19#[constant]
20pub const SOL_POOL_PDA_SEED: &[u8] = b"sol_pool_pda";
21
22pub fn compress_or_decompress_lamports<
23 'a,
24 'b,
25 'c: 'info,
26 'info,
27 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
28>(
29 inputs: &'a InstructionDataInvoke,
30 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
31) -> Result<()> {
32 if inputs.is_compress {
33 compress_lamports(inputs, ctx)
34 } else {
35 decompress_lamports(inputs, ctx)
36 }
37}
38
39pub fn decompress_lamports<
40 'a,
41 'b,
42 'c: 'info,
43 'info,
44 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
45>(
46 inputs: &'a InstructionDataInvoke,
47 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
48) -> Result<()> {
49 let recipient = match ctx.accounts.get_decompression_recipient().as_ref() {
50 Some(decompression_recipient) => decompression_recipient.to_account_info(),
51 None => return err!(SystemProgramError::DecompressRecipientUndefinedForDecompressSol),
52 };
53 let sol_pool_pda = match ctx.accounts.get_sol_pool_pda().as_ref() {
54 Some(sol_pool_pda) => sol_pool_pda.to_account_info(),
55 None => return err!(SystemProgramError::CompressedSolPdaUndefinedForDecompressSol),
56 };
57 let lamports = match inputs.compress_or_decompress_lamports {
58 Some(lamports) => lamports,
59 None => return err!(SystemProgramError::DeCompressLamportsUndefinedForDecompressSol),
60 };
61
62 transfer_lamports(&sol_pool_pda, &recipient, lamports)
63}
64
65pub fn compress_lamports<
66 'a,
67 'b,
68 'c: 'info,
69 'info,
70 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
71>(
72 inputs: &'a InstructionDataInvoke,
73 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
74) -> Result<()> {
75 let recipient = match ctx.accounts.get_sol_pool_pda().as_ref() {
76 Some(sol_pool_pda) => sol_pool_pda.to_account_info(),
77 None => return err!(SystemProgramError::CompressedSolPdaUndefinedForCompressSol),
78 };
79 let lamports = match inputs.compress_or_decompress_lamports {
80 Some(lamports) => lamports,
81 None => return err!(SystemProgramError::DeCompressLamportsUndefinedForCompressSol),
82 };
83
84 transfer_lamports_cpi(
85 &ctx.accounts.get_fee_payer().to_account_info(),
86 &recipient,
87 lamports,
88 )
89}
90
91pub fn transfer_lamports<'info>(
92 from: &AccountInfo<'info>,
93 to: &AccountInfo<'info>,
94 lamports: u64,
95) -> Result<()> {
96 let instruction =
97 anchor_lang::solana_program::system_instruction::transfer(from.key, to.key, lamports);
98 let (_, bump) =
99 anchor_lang::prelude::Pubkey::find_program_address(&[SOL_POOL_PDA_SEED], &crate::ID);
100 let bump = &[bump];
101 let seeds = &[&[SOL_POOL_PDA_SEED, bump][..]];
102 anchor_lang::solana_program::program::invoke_signed(
103 &instruction,
104 &[from.clone(), to.clone()],
105 seeds,
106 )?;
107 Ok(())
108}