switchboard_solana/attestation_program/instructions/
function_close.rs

1use crate::prelude::*;
2
3#[derive(Accounts)]
4#[instruction(params:FunctionCloseParams)]
5pub struct FunctionClose<'info> {
6    /// #[account(
7    ///     mut,
8    ///     close = sol_dest,
9    ///     seeds = [
10    ///         FUNCTION_SEED,
11    ///         function.load()?.creator_seed.as_ref(),
12    ///         &function.load()?.created_at_slot.to_le_bytes()
13    ///     ],
14    ///     bump = function.load()?.bump,
15    ///     has_one = authority @ SwitchboardError::InvalidAuthority,
16    ///     has_one = address_lookup_table,
17    ///     has_one = escrow_wallet,
18    /// )]
19    /// pub function: AccountLoader<'info, FunctionAccountData>,
20    #[account(mut)]
21    pub function: AccountInfo<'info>,
22
23    #[account(signer)]
24    pub authority: AccountInfo<'info>,
25
26    /// CHECK: handled in function has_one
27    #[account(
28        mut,
29        owner = address_lookup_program.key(),
30    )]
31    pub address_lookup_table: AccountInfo<'info>,
32
33    /// pub escrow_wallet: Box<Account<'info, SwitchboardWallet>>,
34    #[account(mut)]
35    pub escrow_wallet: AccountInfo<'info>, // SwitchboardWallet
36
37    /// CHECK:
38    pub sol_dest: AccountInfo<'info>,
39
40    /// #[account(
41    ///     mut,
42    ///     constraint = escrow_dest.is_native()
43    /// )]
44    /// pub escrow_dest: Box<Account<'info, TokenAccount>>,
45    #[account(mut)]
46    pub escrow_dest: AccountInfo<'info>,
47
48    /// pub token_program: Program<'info, Token>,
49    #[account(address = anchor_spl::token::ID)]
50    pub token_program: AccountInfo<'info>,
51
52    /// pub system_program: Program<'info, System>,
53    #[account(address = solana_program::system_program::ID)]
54    pub system_program: AccountInfo<'info>,
55
56    /// CHECK:
57    #[account(
58        constraint = address_lookup_program.executable,
59        address = solana_address_lookup_table_program::id(),
60    )]
61    pub address_lookup_program: AccountInfo<'info>,
62}
63
64#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
65pub struct FunctionCloseParams {}
66
67impl InstructionData for FunctionCloseParams {}
68
69impl Discriminator for FunctionCloseParams {
70    const DISCRIMINATOR: [u8; 8] = [94, 164, 174, 42, 156, 29, 244, 236];
71}
72
73impl Discriminator for FunctionClose<'_> {
74    const DISCRIMINATOR: [u8; 8] = [94, 164, 174, 42, 156, 29, 244, 236];
75}
76
77impl<'info> FunctionClose<'info> {
78    pub fn get_instruction(&self, program_id: Pubkey) -> anchor_lang::Result<Instruction> {
79        let accounts = self.to_account_metas(None);
80
81        let mut data: Vec<u8> = FunctionClose::discriminator().try_to_vec()?;
82        let params = FunctionCloseParams {};
83        data.append(&mut params.try_to_vec()?);
84
85        let instruction = Instruction::new_with_bytes(program_id, &data, accounts);
86        Ok(instruction)
87    }
88
89    pub fn invoke(&self, program: AccountInfo<'info>) -> ProgramResult {
90        let instruction = self.get_instruction(*program.key)?;
91        let account_infos = self.to_account_infos();
92
93        invoke(&instruction, &account_infos[..])
94    }
95
96    pub fn invoke_signed(
97        &self,
98        program: AccountInfo<'info>,
99        signer_seeds: &[&[&[u8]]],
100    ) -> ProgramResult {
101        let instruction = self.get_instruction(*program.key)?;
102        let account_infos = self.to_account_infos();
103
104        invoke_signed(&instruction, &account_infos[..], signer_seeds)
105    }
106
107    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
108        let mut account_infos = Vec::new();
109        account_infos.extend(self.function.to_account_infos());
110        account_infos.extend(self.authority.to_account_infos());
111        account_infos.extend(self.address_lookup_table.to_account_infos());
112        account_infos.extend(self.escrow_wallet.to_account_infos());
113        account_infos.extend(self.sol_dest.to_account_infos());
114        account_infos.extend(self.escrow_dest.to_account_infos());
115        account_infos.extend(self.token_program.to_account_infos());
116        account_infos.extend(self.system_program.to_account_infos());
117        account_infos.extend(self.address_lookup_program.to_account_infos());
118        account_infos
119    }
120
121    #[allow(unused_variables)]
122    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
123        let mut account_metas = Vec::new();
124        account_metas.extend(self.function.to_account_metas(None));
125        account_metas.extend(self.authority.to_account_metas(None));
126        account_metas.extend(self.address_lookup_table.to_account_metas(None));
127        account_metas.extend(self.escrow_wallet.to_account_metas(None));
128        account_metas.extend(self.sol_dest.to_account_metas(None));
129        account_metas.extend(self.escrow_dest.to_account_metas(None));
130        account_metas.extend(self.token_program.to_account_metas(None));
131        account_metas.extend(self.system_program.to_account_metas(None));
132        account_metas.extend(self.address_lookup_program.to_account_metas(None));
133        account_metas
134    }
135}