buddy_link/cpi/
transfer_reward.rs

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    /// CHECK: The buddylink program
14    #[account(executable, address = BL_PROGRAM_ID)]
15    pub buddy_link_program: AccountInfo<'info>,
16
17    /// CHECK: Authority of the account sending the funds.
18    #[account(mut, signer)]
19    pub authority: AccountInfo<'info>,
20
21    /// CHECK: System Program
22    #[account(executable, address = solana_program::system_program::ID)]
23    pub system_program: Option<AccountInfo<'info>>,
24
25    /// CHECK: Mint
26    #[account()]
27    pub mint: Option<AccountInfo<'info>>,
28    /// CHECK: Token program
29    #[account(executable, address = Token::id())]
30    pub token_program: Option<AccountInfo<'info>>,
31
32    /// CHECK: Account sending the funds.
33    #[account(mut)]
34    pub from_token_account: Option<AccountInfo<'info>>,
35    /*
36    Remaining accounts with be the referrer treasuries paired with referrer_member for sol or token accounts for spl
37     */
38}
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    /// CHECK: The buddylink program
84    #[account(executable, address = BL_PROGRAM_ID)]
85    pub buddy_link_program: AccountInfo<'info>,
86
87    /// CHECK: Authority of the account sending the funds.
88    #[account(mut, signer)]
89    pub authority: AccountInfo<'info>,
90
91    /// CHECK: Mint
92    #[account()]
93    pub mint: AccountInfo<'info>,
94    /// CHECK: Token program
95    #[account(executable, address = Token::id())]
96    pub token_program: AccountInfo<'info>,
97
98    /// CHECK: Account sending the funds.
99    #[account(mut)]
100    pub from_token_account: AccountInfo<'info>,
101    /// CHECK: Account receiving the funds (buddy link owned).
102    #[account(mut)]
103    pub referrer_token_account: AccountInfo<'info>,
104
105    /// CHECK: Referrer member (account of the referrer within your organization).
106    #[account(mut)]
107    pub referrer_member: AccountInfo<'info>,
108    /// CHECK: Referrer treasury (treasury that owns the referrer member ).
109    #[account(mut)]
110    pub referrer_treasury: AccountInfo<'info>,
111    /// CHECK: Referrer treasury for reward (treasury that is linked to the current mint, could be the same as above).
112    #[account(mut)]
113    pub referrer_treasury_for_reward: AccountInfo<'info>,
114
115    /// CHECK: Buddy Link Profile of the referee.
116    #[account()]
117    pub referee_buddy_profile: AccountInfo<'info>,
118    /// CHECK: Buddy Link Paid buddy of the referee (could be the same as above).
119    #[account()]
120    pub referee_buddy: AccountInfo<'info>,
121    /// CHECK: Referee treasury (is owned by above).
122    #[account(mut)]
123    pub referee_treasury: AccountInfo<'info>,
124    /// CHECK: Referee member (account of the referee within your organization).
125    #[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    /// CHECK: The buddylink program
173    #[account(executable, address = BL_PROGRAM_ID)]
174    pub buddy_link_program: AccountInfo<'info>,
175
176    /// CHECK: Authority of the account sending the funds.
177    #[account(mut, signer)]
178    pub authority: AccountInfo<'info>,
179
180    /// CHECK: Mint
181    #[account()]
182    pub mint: AccountInfo<'info>,
183    /// CHECK: Token program
184    #[account(executable, address = Token::id())]
185    pub token_program: AccountInfo<'info>,
186
187    /// CHECK: Account sending the funds.
188    #[account(mut)]
189    pub from_token_account: AccountInfo<'info>,
190    /// CHECK: Account receiving the funds (buddy link owned).
191    #[account(mut)]
192    pub referrer_token_account: AccountInfo<'info>,
193
194    /// CHECK: Referrer member (account of the referrer within your organization) (None if don't want on-chain analytics).
195    #[account(mut)]
196    pub referrer_member: Option<AccountInfo<'info>>,
197    /// CHECK: Referrer treasury (treasury that owns the referrer member ).
198    #[account(mut)]
199    pub referrer_treasury: AccountInfo<'info>,
200    /// CHECK: Referrer treasury for reward (treasury that is linked to the current mint, could be the same as above).
201    #[account(mut)]
202    pub referrer_treasury_for_reward: AccountInfo<'info>,
203
204    /// CHECK: Referee member (account of the referee within your organization).
205    #[account(mut)]
206    pub referee_member: AccountInfo<'info>,
207
208    /// CHECK: Global referrer treasury (treasury of the global referrer of current referee) (None if user doesn't have global referrer).
209    #[account(mut)]
210    pub buddy_global_referrer_treasury: Option<AccountInfo<'info>>,
211    /// CHECK: Global referrer token account linked to the above account.
212    #[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    /// CHECK: The buddylink program
266    #[account(executable, address = BL_PROGRAM_ID)]
267    pub buddy_link_program: AccountInfo<'info>,
268
269    /// CHECK: Authority of the account sending the funds.
270    #[account(mut, signer)]
271    pub authority: AccountInfo<'info>,
272
273    /// CHECK: System Program - Only used if sending SOL, None if sending SPL.
274    #[account(executable, address = solana_program::system_program::ID)]
275    pub system_program: Option<AccountInfo<'info>>,
276
277    /// CHECK: Mint, None if sending SOL.
278    #[account()]
279    pub mint: Option<AccountInfo<'info>>,
280    /// CHECK: Token program, None if sending SOL.
281    #[account(executable, address = Token::id())]
282    pub token_program: Option<AccountInfo<'info>>,
283
284    /// CHECK: From token account - None if sending SOL (will send from authority), else is Token Account
285    #[account(mut)]
286    pub from_token_account: Option<AccountInfo<'info>>,
287    /// CHECK: Referrer token account - None if receiving SOL (will send to treasury), else is Token Account
288    #[account(mut)]
289    pub referrer_token_account: Option<AccountInfo<'info>>,
290
291    /// CHECK: Global referrer treasury (treasury of the global referrer of current referee).
292    #[account(mut)]
293    pub global_referrer_treasury: AccountInfo<'info>,
294    /// CHECK: Global referrer treasury for reward (treasury of the global referrer of current referee that is linked to the current mint, could be same as ).
295    #[account(mut)]
296    pub global_referrer_treasury_for_reward: AccountInfo<'info>,
297
298    /// CHECK: Buddy Link Profile of the referee.
299    #[account()]
300    pub referee_buddy_profile: AccountInfo<'info>,
301    /// CHECK: Buddy Link Paid buddy of the referee (could be the same as above).
302    #[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}