light_merkle_tree_program/verifier_invoked_instructions/
spl_transfer.rs1use anchor_lang::prelude::*;
2use anchor_spl::token::{Token, TokenAccount, Transfer};
3
4use crate::{utils::constants::TOKEN_AUTHORITY_SEED, RegisteredVerifier};
5#[derive(Accounts)]
6pub struct UnshieldSpl<'info> {
7 #[account(mut, seeds=[__program_id.to_bytes().as_ref()],bump,seeds::program=registered_verifier_pda.pubkey)]
9 pub authority: Signer<'info>,
10 #[account(mut)]
12 pub merkle_tree_token: Account<'info, TokenAccount>,
13 #[account(mut)]
15 pub recipient: Account<'info, TokenAccount>,
16 pub token_program: Program<'info, Token>,
17 #[account(mut, seeds=[TOKEN_AUTHORITY_SEED], bump)]
19 pub token_authority: AccountInfo<'info>,
20 #[account(seeds=[®istered_verifier_pda.pubkey.to_bytes()], bump)]
21 pub registered_verifier_pda: Account<'info, RegisteredVerifier>,
22}
23
24pub fn process_spl_transfer<'info>(
25 ctx: Context<'_, '_, '_, 'info, UnshieldSpl<'info>>,
26 amount: u64,
27) -> Result<()> {
28 let (_, bump) =
29 anchor_lang::prelude::Pubkey::find_program_address(&[TOKEN_AUTHORITY_SEED], ctx.program_id);
30 let bump = &[bump][..];
31 let seeds = &[&[TOKEN_AUTHORITY_SEED, bump][..]];
32 let accounts = Transfer {
33 from: ctx.accounts.merkle_tree_token.to_account_info(),
34 to: ctx.accounts.recipient.to_account_info(),
35 authority: ctx.accounts.token_authority.to_account_info(),
36 };
37 let cpi_ctx = CpiContext::new_with_signer(
38 ctx.accounts.token_program.to_account_info(),
39 accounts,
40 seeds,
41 );
42 anchor_spl::token::transfer(cpi_ctx, amount)
43}