light_compressed_pda/invoke/
sol_compression.rs1use crate::{
2 errors::CompressedPdaError,
3 sdk::accounts::{InvokeAccounts, SignerAccounts},
4 InstructionDataInvoke,
5};
6use aligned_sized::*;
7use anchor_lang::{
8 prelude::*,
9 solana_program::{account_info::AccountInfo, pubkey::Pubkey},
10 Bumps,
11};
12
13#[account]
14#[aligned_sized(anchor)]
15pub struct CompressedSolPda {}
16
17#[constant]
18pub const COMPRESSED_SOL_PDA_SEED: &[u8] = b"compressed_sol_pda";
19
20pub fn compression_lamports<
21 'a,
22 'b,
23 'c: 'info,
24 'info,
25 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
26>(
27 inputs: &'a InstructionDataInvoke,
28 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
29) -> Result<()> {
30 if inputs.is_compress {
31 compress_lamports(inputs, ctx)
32 } else if inputs.compression_lamports.is_some() {
33 decompress_lamports(inputs, ctx)
34 } else {
35 Ok(())
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_compression_recipient().as_ref() {
50 Some(compression_recipient) => compression_recipient.to_account_info(),
51 None => return err!(CompressedPdaError::DecompressRecipientUndefinedForDecompressSol),
52 };
53 let compressed_sol_pda = match ctx.accounts.get_compressed_sol_pda().as_ref() {
54 Some(compressed_sol_pda) => compressed_sol_pda.to_account_info(),
55 None => return err!(CompressedPdaError::CompressedSolPdaUndefinedForDecompressSol),
56 };
57 let lamports = match inputs.compression_lamports {
58 Some(lamports) => lamports,
59 None => return err!(CompressedPdaError::DeCompressLamportsUndefinedForDecompressSol),
60 };
61
62 transfer_lamports(&compressed_sol_pda, &recipient, lamports)?;
63
64 Ok(())
65}
66
67pub fn compress_lamports<
68 'a,
69 'b,
70 'c: 'info,
71 'info,
72 A: InvokeAccounts<'info> + SignerAccounts<'info> + Bumps,
73>(
74 inputs: &'a InstructionDataInvoke,
75 ctx: &'a Context<'a, 'b, 'c, 'info, A>,
76) -> Result<()> {
77 let recipient = match ctx.accounts.get_compressed_sol_pda().as_ref() {
78 Some(compressed_sol_pda) => compressed_sol_pda.to_account_info(),
79 None => return err!(CompressedPdaError::CompressedSolPdaUndefinedForCompressSol),
80 };
81 let lamports = match inputs.compression_lamports {
82 Some(lamports) => lamports,
83 None => return err!(CompressedPdaError::DeCompressLamportsUndefinedForCompressSol),
84 };
85
86 transfer_lamports_compress(
87 &ctx.accounts.get_authority().to_account_info(),
88 &recipient,
89 lamports,
90 )
91}
92
93pub fn transfer_lamports_compress<'info>(
94 from: &AccountInfo<'info>,
95 to: &AccountInfo<'info>,
96 lamports: u64,
97) -> Result<()> {
98 let instruction =
99 anchor_lang::solana_program::system_instruction::transfer(from.key, to.key, lamports);
100 anchor_lang::solana_program::program::invoke(&instruction, &[from.clone(), to.clone()])?;
101 Ok(())
102}
103
104pub fn transfer_lamports<'info>(
105 from: &AccountInfo<'info>,
106 to: &AccountInfo<'info>,
107 lamports: u64,
108) -> Result<()> {
109 let instruction =
110 anchor_lang::solana_program::system_instruction::transfer(from.key, to.key, lamports);
111 let (_, bump) =
112 anchor_lang::prelude::Pubkey::find_program_address(&[COMPRESSED_SOL_PDA_SEED], &crate::ID);
113 let bump = &[bump];
114 let seeds = &[&[COMPRESSED_SOL_PDA_SEED, bump][..]];
115 anchor_lang::solana_program::program::invoke_signed(
116 &instruction,
117 &[from.clone(), to.clone()],
118 seeds,
119 )?;
120 Ok(())
121}