switchboard_solana/attestation_program/instructions/
function_init.rs

1use crate::prelude::*;
2
3#[derive(Accounts)]
4#[instruction(params:FunctionInitParams)]
5pub struct FunctionInit<'info> {
6    #[account(
7        mut,
8        signer,
9        owner = system_program.key(),
10        constraint = function.data_len() == 0 && function.lamports() == 0,
11    )]
12    pub function: AccountInfo<'info>,
13
14    /// CHECK: todo
15    #[account(mut)]
16    pub address_lookup_table: AccountInfo<'info>,
17
18    /// CHECK:
19    pub authority: AccountInfo<'info>,
20
21    pub attestation_queue: AccountInfo<'info>,
22
23    #[account(mut, signer)]
24    pub payer: AccountInfo<'info>,
25
26    /// CHECK: handle this manually because the PDA seed can vary
27    #[account(mut)]
28    pub escrow_wallet: AccountInfo<'info>,
29
30    #[account(signer)]
31    pub escrow_wallet_authority: Option<AccountInfo<'info>>,
32
33    /// CHECK: handle this manually because the PDA seed can vary
34    #[account(mut)]
35    pub escrow_token_wallet: AccountInfo<'info>,
36
37    #[account(address = anchor_spl::token::spl_token::native_mint::ID)]
38    pub mint: AccountInfo<'info>,
39    #[account(address = anchor_spl::token::ID)]
40    pub token_program: AccountInfo<'info>,
41    #[account(address = anchor_spl::associated_token::ID)]
42    pub associated_token_program: AccountInfo<'info>,
43    #[account(address = solana_program::system_program::ID)]
44    pub system_program: AccountInfo<'info>,
45
46    /// CHECK:
47    #[account(
48      constraint = address_lookup_program.executable,
49      address = solana_address_lookup_table_program::id(),
50    )]
51    pub address_lookup_program: AccountInfo<'info>,
52}
53
54#[derive(Clone, Default, AnchorSerialize, AnchorDeserialize)]
55pub struct FunctionInitParams {
56    // PDA fields
57    pub recent_slot: u64,
58    pub creator_seed: Option<[u8; 32]>,
59
60    // Metadata
61    pub name: Vec<u8>,
62    pub metadata: Vec<u8>,
63
64    // Container Config
65    pub container: Vec<u8>,
66    pub container_registry: Vec<u8>,
67    pub version: Vec<u8>,
68    pub mr_enclave: Option<[u8; 32]>,
69
70    // pub schedule: Vec<u8>,
71
72    // Request Config
73    pub requests_disabled: bool,
74    pub requests_require_authorization: bool,
75    pub requests_dev_fee: u64,
76
77    // Routines Config
78    pub routines_disabled: bool,
79    pub routines_require_authorization: bool,
80    pub routines_dev_fee: u64,
81}
82
83impl InstructionData for FunctionInitParams {}
84
85impl Discriminator for FunctionInitParams {
86    const DISCRIMINATOR: [u8; 8] = [0, 20, 30, 24, 100, 146, 13, 162];
87}
88
89impl Discriminator for FunctionInit<'_> {
90    const DISCRIMINATOR: [u8; 8] = [0, 20, 30, 24, 100, 146, 13, 162];
91}
92
93impl<'info> FunctionInit<'info> {
94    pub fn get_instruction(
95        &self,
96        program_id: Pubkey,
97        params: &FunctionInitParams,
98    ) -> anchor_lang::Result<Instruction> {
99        let accounts = self.to_account_metas(None);
100
101        let mut data: Vec<u8> = FunctionInit::discriminator().try_to_vec()?;
102        data.append(&mut params.try_to_vec()?);
103
104        let instruction = Instruction::new_with_bytes(program_id, &data, accounts);
105        Ok(instruction)
106    }
107
108    pub fn invoke(
109        &self,
110        program: AccountInfo<'info>,
111        params: &FunctionInitParams,
112    ) -> ProgramResult {
113        let instruction = self.get_instruction(*program.key, params)?;
114        let account_infos = self.to_account_infos();
115
116        invoke(&instruction, &account_infos[..])
117    }
118
119    pub fn invoke_signed(
120        &self,
121        program: AccountInfo<'info>,
122        params: &FunctionInitParams,
123        signer_seeds: &[&[&[u8]]],
124    ) -> ProgramResult {
125        let instruction = self.get_instruction(*program.key, params)?;
126        let account_infos = self.to_account_infos();
127
128        invoke_signed(&instruction, &account_infos[..], signer_seeds)
129    }
130
131    fn to_account_infos(&self) -> Vec<AccountInfo<'info>> {
132        let mut account_infos = Vec::new();
133        account_infos.extend(self.function.to_account_infos());
134        account_infos.extend(self.address_lookup_table.to_account_infos());
135        account_infos.extend(self.authority.to_account_infos());
136        account_infos.extend(self.attestation_queue.to_account_infos());
137        account_infos.extend(self.payer.to_account_infos());
138        account_infos.extend(self.escrow_wallet.to_account_infos());
139        account_infos.extend(self.escrow_wallet_authority.to_account_infos());
140        account_infos.extend(self.escrow_token_wallet.to_account_infos());
141        account_infos.extend(self.mint.to_account_infos());
142        account_infos.extend(self.token_program.to_account_infos());
143        account_infos.extend(self.associated_token_program.to_account_infos());
144        account_infos.extend(self.system_program.to_account_infos());
145        account_infos.extend(self.address_lookup_program.to_account_infos());
146        account_infos
147    }
148
149    #[allow(unused_variables)]
150    fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta> {
151        let mut account_metas = Vec::new();
152        account_metas.extend(self.function.to_account_metas(None));
153        account_metas.extend(self.address_lookup_table.to_account_metas(None));
154        account_metas.extend(self.authority.to_account_metas(None));
155        account_metas.extend(self.attestation_queue.to_account_metas(None));
156        account_metas.extend(self.payer.to_account_metas(Some(true)));
157        account_metas.extend(self.escrow_wallet.to_account_metas(None));
158        if let Some(escrow_wallet_authority) = &self.escrow_wallet_authority {
159            account_metas.extend(escrow_wallet_authority.to_account_metas(Some(true)));
160        } else {
161            account_metas.push(AccountMeta::new_readonly(
162                SWITCHBOARD_ATTESTATION_PROGRAM_ID,
163                false,
164            ));
165        }
166        account_metas.extend(self.escrow_token_wallet.to_account_metas(None));
167        account_metas.extend(self.mint.to_account_metas(None));
168        account_metas.extend(self.token_program.to_account_metas(None));
169        account_metas.extend(self.associated_token_program.to_account_metas(None));
170        account_metas.extend(self.system_program.to_account_metas(None));
171        account_metas.extend(self.address_lookup_program.to_account_metas(None));
172        account_metas
173    }
174}