1use crate::constants::BL_PROGRAM_ID;
2use crate::instruction;
3use crate::instruction::{GeneralTransferRewardArgs, TransferUncheckedLocalSharedRewardArgs};
4use crate::utils::{get_account_info_or_default, get_key_or_none};
5use anchor_lang::prelude::*;
6use anchor_lang::{Accounts, Key, ToAccountInfo};
7use anchor_spl::token::{Token};
8use solana_program::entrypoint::ProgramResult;
9use solana_program::program::invoke_signed;
10
11#[derive(Accounts)]
12pub struct TransferRewardUncheckedMultiple<'info> {
13 #[account(executable, address = BL_PROGRAM_ID)]
15 pub buddy_link_program: AccountInfo<'info>,
16
17 #[account(mut, signer)]
19 pub authority: AccountInfo<'info>,
20
21 #[account(executable, address = solana_program::system_program::ID)]
23 pub system_program: Option<AccountInfo<'info>>,
24
25 #[account()]
27 pub mint: Option<AccountInfo<'info>>,
28 #[account(executable, address = Token::id())]
30 pub token_program: Option<AccountInfo<'info>>,
31
32 #[account(mut)]
34 pub from_token_account: Option<AccountInfo<'info>>,
35 }
39
40pub fn transfer_unchecked_local_shared_reward<'info>(
41 ctx: CpiContext<'_, '_, '_, 'info, TransferRewardUncheckedMultiple<'info>>,
42 total_amount: u64,
43 shares_in_bps: Vec<u16>,
44 members_included: bool,
45 transfer_signer_seeds: &[&[&[u8]]],
46) -> ProgramResult {
47 let remaining_accounts_key: Vec<Pubkey> =
48 ctx.remaining_accounts.iter().map(|x| x.key()).collect();
49
50 let default_account_info = ctx.accounts.buddy_link_program.to_account_info();
51
52 let instruction = instruction::transfer_unchecked_local_shared_reward(
53 ctx.accounts.authority.key(),
54 Some(
55 get_account_info_or_default(&ctx.accounts.system_program, &default_account_info).key(),
56 ),
57 get_key_or_none(&ctx.accounts.mint),
58 Some(get_account_info_or_default(&ctx.accounts.token_program, &default_account_info).key()),
59 get_key_or_none(&ctx.accounts.from_token_account),
60 &remaining_accounts_key,
61 &TransferUncheckedLocalSharedRewardArgs {
62 total_amount,
63 shares_in_bps,
64 members_included,
65 },
66 );
67
68 let mut account_infos = vec![
69 ctx.accounts.authority.to_account_info(),
70 get_account_info_or_default(&ctx.accounts.system_program, &default_account_info),
71 get_account_info_or_default(&ctx.accounts.mint, &default_account_info),
72 get_account_info_or_default(&ctx.accounts.token_program, &default_account_info),
73 get_account_info_or_default(&ctx.accounts.from_token_account, &default_account_info),
74 ];
75
76 account_infos.extend_from_slice(&ctx.remaining_accounts);
77
78 invoke_signed(&instruction, &account_infos, transfer_signer_seeds)
79}
80
81#[derive(Accounts)]
82pub struct TransferSecureLocalReward<'info> {
83 #[account(executable, address = BL_PROGRAM_ID)]
85 pub buddy_link_program: AccountInfo<'info>,
86
87 #[account(mut, signer)]
89 pub authority: AccountInfo<'info>,
90
91 #[account()]
93 pub mint: AccountInfo<'info>,
94 #[account(executable, address = Token::id())]
96 pub token_program: AccountInfo<'info>,
97
98 #[account(mut)]
100 pub from_token_account: AccountInfo<'info>,
101 #[account(mut)]
103 pub referrer_token_account: AccountInfo<'info>,
104
105 #[account(mut)]
107 pub referrer_member: AccountInfo<'info>,
108 #[account(mut)]
110 pub referrer_treasury: AccountInfo<'info>,
111 #[account(mut)]
113 pub referrer_treasury_for_reward: AccountInfo<'info>,
114
115 #[account()]
117 pub referee_buddy_profile: AccountInfo<'info>,
118 #[account()]
120 pub referee_buddy: AccountInfo<'info>,
121 #[account(mut)]
123 pub referee_treasury: AccountInfo<'info>,
124 #[account(mut)]
126 pub referee_member: AccountInfo<'info>,
127}
128
129pub fn transfer_secure_local_reward<'info>(
130 ctx: CpiContext<'_, '_, '_, 'info, TransferSecureLocalReward<'info>>,
131 amount: u64,
132 transfer_signer_seeds: &[&[&[u8]]],
133) -> ProgramResult {
134 let instruction = instruction::transfer_secure_local_reward(
135 ctx.accounts.authority.key(),
136 ctx.accounts.mint.key(),
137 ctx.accounts.token_program.key(),
138 ctx.accounts.from_token_account.key(),
139 ctx.accounts.referrer_token_account.key(),
140 ctx.accounts.referrer_member.key(),
141 ctx.accounts.referrer_treasury.key(),
142 ctx.accounts.referrer_treasury_for_reward.key(),
143 ctx.accounts.referee_buddy_profile.key(),
144 ctx.accounts.referee_buddy.key(),
145 ctx.accounts.referee_treasury.key(),
146 ctx.accounts.referee_member.key(),
147 &GeneralTransferRewardArgs { amount },
148 );
149
150 invoke_signed(
151 &instruction,
152 &[
153 ctx.accounts.authority.to_account_info(),
154 ctx.accounts.mint.to_account_info(),
155 ctx.accounts.token_program.to_account_info(),
156 ctx.accounts.from_token_account.to_account_info(),
157 ctx.accounts.referrer_member.to_account_info(),
158 ctx.accounts.referrer_treasury.to_account_info(),
159 ctx.accounts.referrer_treasury_for_reward.to_account_info(),
160 ctx.accounts.referee_buddy_profile.to_account_info(),
161 ctx.accounts.referee_buddy.to_account_info(),
162 ctx.accounts.referee_treasury.to_account_info(),
163 ctx.accounts.referee_member.to_account_info(),
164 ctx.accounts.referrer_token_account.to_account_info(),
165 ],
166 transfer_signer_seeds,
167 )
168}
169
170#[derive(Accounts)]
171pub struct TransferCheckedGlobalReward<'info> {
172 #[account(executable, address = BL_PROGRAM_ID)]
174 pub buddy_link_program: AccountInfo<'info>,
175
176 #[account(mut, signer)]
178 pub authority: AccountInfo<'info>,
179
180 #[account()]
182 pub mint: AccountInfo<'info>,
183 #[account(executable, address = Token::id())]
185 pub token_program: AccountInfo<'info>,
186
187 #[account(mut)]
189 pub from_token_account: AccountInfo<'info>,
190 #[account(mut)]
192 pub referrer_token_account: AccountInfo<'info>,
193
194 #[account(mut)]
196 pub referrer_member: Option<AccountInfo<'info>>,
197 #[account(mut)]
199 pub referrer_treasury: AccountInfo<'info>,
200 #[account(mut)]
202 pub referrer_treasury_for_reward: AccountInfo<'info>,
203
204 #[account(mut)]
206 pub referee_member: AccountInfo<'info>,
207
208 #[account(mut)]
210 pub buddy_global_referrer_treasury: Option<AccountInfo<'info>>,
211 #[account(mut)]
213 pub buddy_global_referrer_token_account: Option<AccountInfo<'info>>,
214}
215
216pub fn transfer_checked_global_reward<'info>(
217 ctx: CpiContext<'_, '_, '_, 'info, TransferCheckedGlobalReward<'info>>,
218 amount: u64,
219 transfer_signer_seeds: &[&[&[u8]]],
220) -> ProgramResult {
221 let instruction = instruction::transfer_checked_global_reward(
222 ctx.accounts.authority.key(),
223 ctx.accounts.mint.key(),
224 ctx.accounts.token_program.key(),
225 ctx.accounts.from_token_account.key(),
226 ctx.accounts.referrer_token_account.key(),
227 get_key_or_none(&ctx.accounts.referrer_member),
228 ctx.accounts.referrer_treasury.key(),
229 ctx.accounts.referrer_treasury_for_reward.key(),
230 ctx.accounts.referee_member.key(),
231 get_key_or_none(&ctx.accounts.buddy_global_referrer_treasury),
232 get_key_or_none(&ctx.accounts.buddy_global_referrer_token_account),
233 &GeneralTransferRewardArgs { amount },
234 );
235
236 let default_account_info = ctx.accounts.buddy_link_program.to_account_info();
237
238 invoke_signed(
239 &instruction,
240 &[
241 ctx.accounts.authority.to_account_info(),
242 get_account_info_or_default(
243 &ctx.accounts.buddy_global_referrer_treasury,
244 &default_account_info,
245 ),
246 get_account_info_or_default(
247 &ctx.accounts.buddy_global_referrer_token_account,
248 &default_account_info,
249 ),
250 ctx.accounts.referee_member.to_account_info(),
251 ctx.accounts.referrer_treasury.to_account_info(),
252 ctx.accounts.referrer_treasury_for_reward.to_account_info(),
253 ctx.accounts.referee_member.to_account_info(),
254 ctx.accounts.mint.to_account_info(),
255 ctx.accounts.token_program.to_account_info(),
256 ctx.accounts.from_token_account.to_account_info(),
257 ctx.accounts.referrer_token_account.to_account_info(),
258 ],
259 transfer_signer_seeds,
260 )
261}
262
263#[derive(Accounts)]
264pub struct TransferCheckedGlobalOnlyReward<'info> {
265 #[account(executable, address = BL_PROGRAM_ID)]
267 pub buddy_link_program: AccountInfo<'info>,
268
269 #[account(mut, signer)]
271 pub authority: AccountInfo<'info>,
272
273 #[account(executable, address = solana_program::system_program::ID)]
275 pub system_program: Option<AccountInfo<'info>>,
276
277 #[account()]
279 pub mint: Option<AccountInfo<'info>>,
280 #[account(executable, address = Token::id())]
282 pub token_program: Option<AccountInfo<'info>>,
283
284 #[account(mut)]
286 pub from_token_account: Option<AccountInfo<'info>>,
287 #[account(mut)]
289 pub referrer_token_account: Option<AccountInfo<'info>>,
290
291 #[account(mut)]
293 pub global_referrer_treasury: AccountInfo<'info>,
294 #[account(mut)]
296 pub global_referrer_treasury_for_reward: AccountInfo<'info>,
297
298 #[account()]
300 pub referee_buddy_profile: AccountInfo<'info>,
301 #[account()]
303 pub referee_buddy: AccountInfo<'info>,
304}
305
306pub fn transfer_checked_global_only_reward<'info>(
307 ctx: CpiContext<'_, '_, '_, 'info, TransferCheckedGlobalOnlyReward<'info>>,
308 amount: u64,
309 transfer_signer_seeds: &[&[&[u8]]],
310) -> ProgramResult {
311 let default_account_info = ctx.accounts.buddy_link_program.to_account_info();
312
313 let instruction = instruction::transfer_checked_global_only_reward(
314 ctx.accounts.authority.key(),
315 Some(
316 get_account_info_or_default(&ctx.accounts.system_program, &default_account_info).key(),
317 ),
318 get_key_or_none(&ctx.accounts.mint),
319 Some(get_account_info_or_default(&ctx.accounts.token_program, &default_account_info).key()),
320 get_key_or_none(&ctx.accounts.from_token_account),
321 get_key_or_none(&ctx.accounts.referrer_token_account),
322 ctx.accounts.global_referrer_treasury.key(),
323 ctx.accounts.global_referrer_treasury_for_reward.key(),
324 ctx.accounts.referee_buddy_profile.key(),
325 ctx.accounts.referee_buddy.key(),
326 &GeneralTransferRewardArgs { amount },
327 );
328
329 invoke_signed(
330 &instruction,
331 &[
332 ctx.accounts.authority.to_account_info(),
333 ctx.accounts.global_referrer_treasury.to_account_info(),
334 ctx.accounts
335 .global_referrer_treasury_for_reward
336 .to_account_info(),
337 ctx.accounts.referee_buddy_profile.to_account_info(),
338 ctx.accounts.referee_buddy.to_account_info(),
339 get_account_info_or_default(&ctx.accounts.system_program, &default_account_info),
340 get_account_info_or_default(&ctx.accounts.mint, &default_account_info),
341 get_account_info_or_default(&ctx.accounts.token_program, &default_account_info),
342 get_account_info_or_default(
343 &ctx.accounts.referrer_token_account,
344 &default_account_info,
345 ),
346 get_account_info_or_default(&ctx.accounts.from_token_account, &default_account_info),
347 ],
348 transfer_signer_seeds,
349 )
350}