1use fogo_sessions_sdk::session::is_session;
2use fogo_sessions_sdk::token::PROGRAM_SIGNER_SEED;
3use spl_token::instruction::close_account;
4use solana_program::program::invoke_signed as solana_invoke_signed;
5use solana_program::account_info::AccountInfo;
6use solana_program::program_error::ProgramError;
7use solana_program::pubkey::Pubkey;
8use steel::*;
9use crate::ID;
10
11pub fn validate_program_signer(program_signer_info: &AccountInfo) -> Result<u8, ProgramError> {
12 let (program_signer_pda, bump) = Pubkey::find_program_address(
13 &[PROGRAM_SIGNER_SEED],
14 &ID,
15 );
16 if program_signer_info.key != &program_signer_pda {
17 return Err(ProgramError::InvalidArgument);
18 }
19 Ok(bump)
20}
21
22pub fn validate_session(signer_info: &AccountInfo) -> Result<(), ProgramError> {
23 if !is_session(signer_info) {
24 return Err(ProgramError::InvalidAccountData);
25 }
26 Ok(())
27}
28
29pub fn transfer_wrapped_sol_and_unwrap<'a>(
30 signer_info: &'a AccountInfo<'a>,
31 program_signer_info: &'a AccountInfo<'a>,
32 _payer_info: &'a AccountInfo<'a>,
33 amount: u64,
34 user_wrapped_sol_info: &'a AccountInfo<'a>,
35 destination_wrapped_sol_info: &'a AccountInfo<'a>,
36 destination_pda_info: &'a AccountInfo<'a>,
37 mint_info: &'a AccountInfo<'a>,
38 token_program: &'a AccountInfo<'a>,
39 destination_seeds: &[&[u8]],
40) -> Result<(), ProgramError> {
41 let bump = validate_program_signer(program_signer_info)?;
42
43 let transfer_ix = fogo_sessions_sdk::token::instruction::transfer_checked(
44 token_program.key,
45 user_wrapped_sol_info.key,
46 mint_info.key,
47 destination_wrapped_sol_info.key,
48 signer_info.key,
49 Some(program_signer_info.key),
50 amount,
51 9,
52 )?;
53
54 solana_invoke_signed(
55 &transfer_ix,
56 &[
57 user_wrapped_sol_info.clone(),
58 mint_info.clone(),
59 destination_wrapped_sol_info.clone(),
60 signer_info.clone(),
61 token_program.clone(),
62 program_signer_info.clone(),
63 ],
64 &[&[PROGRAM_SIGNER_SEED, &[bump]]],
65 )?;
66
67 let close_ix = close_account(
68 token_program.key,
69 destination_wrapped_sol_info.key,
70 destination_pda_info.key,
71 destination_pda_info.key,
72 &[],
73 )?;
74
75 invoke_signed(
76 &close_ix,
77 &[
78 destination_wrapped_sol_info.clone(),
79 destination_pda_info.clone(),
80 destination_pda_info.clone(),
81 token_program.clone(),
82 ],
83 &ID,
84 destination_seeds,
85 )?;
86
87 Ok(())
88}
89
90pub fn transfer_wrapped_sol<'a>(
91 signer_info: &'a AccountInfo<'a>,
92 program_signer_info: &'a AccountInfo<'a>,
93 amount: u64,
94 user_wrapped_sol_info: &'a AccountInfo<'a>,
95 destination_wrapped_sol_info: &'a AccountInfo<'a>,
96 mint_info: &'a AccountInfo<'a>,
97 token_program: &'a AccountInfo<'a>,
98) -> Result<(), ProgramError> {
99 let bump = validate_program_signer(program_signer_info)?;
100
101 let transfer_ix = fogo_sessions_sdk::token::instruction::transfer_checked(
102 token_program.key,
103 user_wrapped_sol_info.key,
104 mint_info.key,
105 destination_wrapped_sol_info.key,
106 signer_info.key,
107 Some(program_signer_info.key),
108 amount,
109 9,
110 )?;
111
112 solana_invoke_signed(
113 &transfer_ix,
114 &[
115 user_wrapped_sol_info.clone(),
116 mint_info.clone(),
117 destination_wrapped_sol_info.clone(),
118 signer_info.clone(),
119 token_program.clone(),
120 program_signer_info.clone(),
121 ],
122 &[&[PROGRAM_SIGNER_SEED, &[bump]]],
123 )?;
124
125 Ok(())
126}
127
128pub fn transfer_token_with_program_signer<'a>(
129 token_program: &'a AccountInfo<'a>,
130 sender_info: &'a AccountInfo<'a>,
131 mint_info: &'a AccountInfo<'a>,
132 destination_info: &'a AccountInfo<'a>,
133 signer_info: &'a AccountInfo<'a>,
134 program_signer_info: &'a AccountInfo<'a>,
135 amount: u64,
136) -> Result<(), ProgramError> {
137 let bump = validate_program_signer(program_signer_info)?;
138
139 let transfer_ix = fogo_sessions_sdk::token::instruction::transfer_checked(
140 token_program.key,
141 sender_info.key,
142 mint_info.key,
143 destination_info.key,
144 signer_info.key,
145 Some(program_signer_info.key),
146 amount,
147 11,
148 )?;
149
150 solana_invoke_signed(
151 &transfer_ix,
152 &[
153 sender_info.clone(),
154 mint_info.clone(),
155 destination_info.clone(),
156 signer_info.clone(),
157 token_program.clone(),
158 program_signer_info.clone(),
159 ],
160 &[&[PROGRAM_SIGNER_SEED, &[bump]]],
161 )?;
162
163 Ok(())
164}