solana_config_program/
config_instruction.rs

1use {
2    crate::{id, ConfigKeys, ConfigState},
3    solana_instruction::{AccountMeta, Instruction},
4    solana_pubkey::Pubkey,
5    solana_system_interface::instruction as system_instruction,
6};
7
8fn initialize_account<T: ConfigState>(config_pubkey: &Pubkey) -> Instruction {
9    let account_metas = vec![AccountMeta::new(*config_pubkey, true)];
10    let account_data = (ConfigKeys { keys: vec![] }, T::default());
11    Instruction::new_with_bincode(id(), &account_data, account_metas)
12}
13
14/// Create a new, empty configuration account
15pub fn create_account<T: ConfigState>(
16    from_account_pubkey: &Pubkey,
17    config_account_pubkey: &Pubkey,
18    lamports: u64,
19    keys: Vec<(Pubkey, bool)>,
20) -> Vec<Instruction> {
21    let space = T::max_space() + ConfigKeys::serialized_size(keys);
22    vec![
23        system_instruction::create_account(
24            from_account_pubkey,
25            config_account_pubkey,
26            lamports,
27            space,
28            &id(),
29        ),
30        initialize_account::<T>(config_account_pubkey),
31    ]
32}
33
34/// Store new data in a configuration account
35pub fn store<T: ConfigState>(
36    config_account_pubkey: &Pubkey,
37    is_config_signer: bool,
38    keys: Vec<(Pubkey, bool)>,
39    data: &T,
40) -> Instruction {
41    let mut account_metas = vec![AccountMeta::new(*config_account_pubkey, is_config_signer)];
42    for (signer_pubkey, _) in keys.iter().filter(|(_, is_signer)| *is_signer) {
43        if signer_pubkey != config_account_pubkey {
44            account_metas.push(AccountMeta::new(*signer_pubkey, true));
45        }
46    }
47    let account_data = (ConfigKeys { keys }, data);
48    Instruction::new_with_bincode(id(), &account_data, account_metas)
49}