solana_config_program/
config_instruction.rs

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