light_client/interface/
initialize_config.rs

1//! Helper for initializing config with sensible defaults.
2
3#[cfg(feature = "anchor")]
4use anchor_lang::{AnchorDeserialize, AnchorSerialize};
5#[cfg(not(feature = "anchor"))]
6use borsh::{BorshDeserialize as AnchorDeserialize, BorshSerialize as AnchorSerialize};
7use light_sdk::interface::config::LightConfig;
8use solana_instruction::{AccountMeta, Instruction};
9use solana_pubkey::Pubkey;
10
11/// Default address tree v2 pubkey.
12pub const ADDRESS_TREE_V2: Pubkey =
13    solana_pubkey::pubkey!("amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx");
14
15/// Default write top-up value (5000 lamports).
16pub const DEFAULT_INIT_WRITE_TOP_UP: u32 = 5_000;
17
18/// Instruction data format matching anchor-generated `initialize_compression_config`.
19#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
20pub struct InitializeCompressionConfigAnchorData {
21    pub write_top_up: u32,
22    pub rent_sponsor: Pubkey,
23    pub compression_authority: Pubkey,
24    pub rent_config: light_compressible::rent::RentConfig,
25    pub address_space: Vec<Pubkey>,
26}
27
28/// Builder for `initialize_compression_config` instruction with sensible defaults.
29pub struct InitializeRentFreeConfig {
30    program_id: Pubkey,
31    fee_payer: Pubkey,
32    program_data_pda: Pubkey,
33    authority: Option<Pubkey>,
34    rent_sponsor: Pubkey,
35    compression_authority: Pubkey,
36    rent_config: light_compressible::rent::RentConfig,
37    write_top_up: u32,
38    address_space: Vec<Pubkey>,
39    config_bump: u8,
40}
41
42impl InitializeRentFreeConfig {
43    pub fn new(
44        program_id: &Pubkey,
45        fee_payer: &Pubkey,
46        program_data_pda: &Pubkey,
47        rent_sponsor: Pubkey,
48        compression_authority: Pubkey,
49    ) -> Self {
50        Self {
51            program_id: *program_id,
52            fee_payer: *fee_payer,
53            program_data_pda: *program_data_pda,
54            authority: None,
55            rent_sponsor,
56            compression_authority,
57            rent_config: light_compressible::rent::RentConfig::default(),
58            write_top_up: DEFAULT_INIT_WRITE_TOP_UP,
59            address_space: vec![ADDRESS_TREE_V2],
60            config_bump: 0,
61        }
62    }
63
64    pub fn authority(mut self, authority: Pubkey) -> Self {
65        self.authority = Some(authority);
66        self
67    }
68
69    pub fn rent_config(mut self, rent_config: light_compressible::rent::RentConfig) -> Self {
70        self.rent_config = rent_config;
71        self
72    }
73
74    pub fn write_top_up(mut self, write_top_up: u32) -> Self {
75        self.write_top_up = write_top_up;
76        self
77    }
78
79    pub fn address_space(mut self, address_space: Vec<Pubkey>) -> Self {
80        self.address_space = address_space;
81        self
82    }
83
84    pub fn config_bump(mut self, config_bump: u8) -> Self {
85        self.config_bump = config_bump;
86        self
87    }
88
89    pub fn build(self) -> (Instruction, Pubkey) {
90        let authority = self.authority.unwrap_or(self.fee_payer);
91        let (config_pda, _) = LightConfig::derive_pda(&self.program_id, self.config_bump);
92
93        let accounts = vec![
94            AccountMeta::new(self.fee_payer, true), // payer
95            AccountMeta::new(config_pda, false),    // config
96            AccountMeta::new_readonly(self.program_data_pda, false), // program_data
97            AccountMeta::new_readonly(authority, true), // authority
98            AccountMeta::new_readonly(
99                solana_pubkey::pubkey!("11111111111111111111111111111111"),
100                false,
101            ), // system_program
102        ];
103
104        let instruction_data = InitializeCompressionConfigAnchorData {
105            write_top_up: self.write_top_up,
106            rent_sponsor: self.rent_sponsor,
107            compression_authority: self.compression_authority,
108            rent_config: self.rent_config,
109            address_space: self.address_space,
110        };
111
112        // Anchor discriminator for "initialize_compression_config"
113        // SHA256("global:initialize_compression_config")[..8]
114        const DISCRIMINATOR: [u8; 8] = [133, 228, 12, 169, 56, 76, 222, 61];
115
116        let serialized_data = instruction_data
117            .try_to_vec()
118            .expect("Failed to serialize instruction data");
119
120        let mut data = Vec::with_capacity(DISCRIMINATOR.len() + serialized_data.len());
121        data.extend_from_slice(&DISCRIMINATOR);
122        data.extend_from_slice(&serialized_data);
123
124        let instruction = Instruction {
125            program_id: self.program_id,
126            accounts,
127            data,
128        };
129
130        (instruction, config_pda)
131    }
132}