1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10use kaigan::types::U64PrefixString;
11use solana_program::pubkey::Pubkey;
12
13pub struct CreateAccountWithSeed {
15 pub payer: solana_program::pubkey::Pubkey,
16
17 pub new_account: solana_program::pubkey::Pubkey,
18
19 pub base_account: solana_program::pubkey::Pubkey,
20}
21
22impl CreateAccountWithSeed {
23 pub fn instruction(
24 &self,
25 args: CreateAccountWithSeedInstructionArgs,
26 ) -> solana_program::instruction::Instruction {
27 self.instruction_with_remaining_accounts(args, &[])
28 }
29 #[allow(clippy::vec_init_then_push)]
30 pub fn instruction_with_remaining_accounts(
31 &self,
32 args: CreateAccountWithSeedInstructionArgs,
33 remaining_accounts: &[solana_program::instruction::AccountMeta],
34 ) -> solana_program::instruction::Instruction {
35 let mut accounts = Vec::with_capacity(3 + remaining_accounts.len());
36 accounts.push(solana_program::instruction::AccountMeta::new(
37 self.payer, true,
38 ));
39 accounts.push(solana_program::instruction::AccountMeta::new(
40 self.new_account,
41 false,
42 ));
43 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
44 self.base_account,
45 true,
46 ));
47 accounts.extend_from_slice(remaining_accounts);
48 let mut data = CreateAccountWithSeedInstructionData::new()
49 .try_to_vec()
50 .unwrap();
51 let mut args = args.try_to_vec().unwrap();
52 data.append(&mut args);
53
54 solana_program::instruction::Instruction {
55 program_id: crate::SYSTEM_ID,
56 accounts,
57 data,
58 }
59 }
60}
61
62#[derive(BorshDeserialize, BorshSerialize)]
63pub struct CreateAccountWithSeedInstructionData {
64 discriminator: u32,
65}
66
67impl CreateAccountWithSeedInstructionData {
68 pub fn new() -> Self {
69 Self { discriminator: 3 }
70 }
71}
72
73impl Default for CreateAccountWithSeedInstructionData {
74 fn default() -> Self {
75 Self::new()
76 }
77}
78
79#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
80#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
81pub struct CreateAccountWithSeedInstructionArgs {
82 pub base: Pubkey,
83 pub seed: U64PrefixString,
84 pub amount: u64,
85 pub space: u64,
86 pub program_address: Pubkey,
87}
88
89#[derive(Clone, Debug, Default)]
97pub struct CreateAccountWithSeedBuilder {
98 payer: Option<solana_program::pubkey::Pubkey>,
99 new_account: Option<solana_program::pubkey::Pubkey>,
100 base_account: Option<solana_program::pubkey::Pubkey>,
101 base: Option<Pubkey>,
102 seed: Option<U64PrefixString>,
103 amount: Option<u64>,
104 space: Option<u64>,
105 program_address: Option<Pubkey>,
106 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
107}
108
109impl CreateAccountWithSeedBuilder {
110 pub fn new() -> Self {
111 Self::default()
112 }
113 #[inline(always)]
114 pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self {
115 self.payer = Some(payer);
116 self
117 }
118 #[inline(always)]
119 pub fn new_account(&mut self, new_account: solana_program::pubkey::Pubkey) -> &mut Self {
120 self.new_account = Some(new_account);
121 self
122 }
123 #[inline(always)]
124 pub fn base_account(&mut self, base_account: solana_program::pubkey::Pubkey) -> &mut Self {
125 self.base_account = Some(base_account);
126 self
127 }
128 #[inline(always)]
129 pub fn base(&mut self, base: Pubkey) -> &mut Self {
130 self.base = Some(base);
131 self
132 }
133 #[inline(always)]
134 pub fn seed(&mut self, seed: U64PrefixString) -> &mut Self {
135 self.seed = Some(seed);
136 self
137 }
138 #[inline(always)]
139 pub fn amount(&mut self, amount: u64) -> &mut Self {
140 self.amount = Some(amount);
141 self
142 }
143 #[inline(always)]
144 pub fn space(&mut self, space: u64) -> &mut Self {
145 self.space = Some(space);
146 self
147 }
148 #[inline(always)]
149 pub fn program_address(&mut self, program_address: Pubkey) -> &mut Self {
150 self.program_address = Some(program_address);
151 self
152 }
153 #[inline(always)]
155 pub fn add_remaining_account(
156 &mut self,
157 account: solana_program::instruction::AccountMeta,
158 ) -> &mut Self {
159 self.__remaining_accounts.push(account);
160 self
161 }
162 #[inline(always)]
164 pub fn add_remaining_accounts(
165 &mut self,
166 accounts: &[solana_program::instruction::AccountMeta],
167 ) -> &mut Self {
168 self.__remaining_accounts.extend_from_slice(accounts);
169 self
170 }
171 #[allow(clippy::clone_on_copy)]
172 pub fn instruction(&self) -> solana_program::instruction::Instruction {
173 let accounts = CreateAccountWithSeed {
174 payer: self.payer.expect("payer is not set"),
175 new_account: self.new_account.expect("new_account is not set"),
176 base_account: self.base_account.expect("base_account is not set"),
177 };
178 let args = CreateAccountWithSeedInstructionArgs {
179 base: self.base.clone().expect("base is not set"),
180 seed: self.seed.clone().expect("seed is not set"),
181 amount: self.amount.clone().expect("amount is not set"),
182 space: self.space.clone().expect("space is not set"),
183 program_address: self
184 .program_address
185 .clone()
186 .expect("program_address is not set"),
187 };
188
189 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
190 }
191}
192
193pub struct CreateAccountWithSeedCpiAccounts<'a, 'b> {
195 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
196
197 pub new_account: &'b solana_program::account_info::AccountInfo<'a>,
198
199 pub base_account: &'b solana_program::account_info::AccountInfo<'a>,
200}
201
202pub struct CreateAccountWithSeedCpi<'a, 'b> {
204 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
206
207 pub payer: &'b solana_program::account_info::AccountInfo<'a>,
208
209 pub new_account: &'b solana_program::account_info::AccountInfo<'a>,
210
211 pub base_account: &'b solana_program::account_info::AccountInfo<'a>,
212 pub __args: CreateAccountWithSeedInstructionArgs,
214}
215
216impl<'a, 'b> CreateAccountWithSeedCpi<'a, 'b> {
217 pub fn new(
218 program: &'b solana_program::account_info::AccountInfo<'a>,
219 accounts: CreateAccountWithSeedCpiAccounts<'a, 'b>,
220 args: CreateAccountWithSeedInstructionArgs,
221 ) -> Self {
222 Self {
223 __program: program,
224 payer: accounts.payer,
225 new_account: accounts.new_account,
226 base_account: accounts.base_account,
227 __args: args,
228 }
229 }
230 #[inline(always)]
231 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
232 self.invoke_signed_with_remaining_accounts(&[], &[])
233 }
234 #[inline(always)]
235 pub fn invoke_with_remaining_accounts(
236 &self,
237 remaining_accounts: &[(
238 &'b solana_program::account_info::AccountInfo<'a>,
239 bool,
240 bool,
241 )],
242 ) -> solana_program::entrypoint::ProgramResult {
243 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
244 }
245 #[inline(always)]
246 pub fn invoke_signed(
247 &self,
248 signers_seeds: &[&[&[u8]]],
249 ) -> solana_program::entrypoint::ProgramResult {
250 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
251 }
252 #[allow(clippy::clone_on_copy)]
253 #[allow(clippy::vec_init_then_push)]
254 pub fn invoke_signed_with_remaining_accounts(
255 &self,
256 signers_seeds: &[&[&[u8]]],
257 remaining_accounts: &[(
258 &'b solana_program::account_info::AccountInfo<'a>,
259 bool,
260 bool,
261 )],
262 ) -> solana_program::entrypoint::ProgramResult {
263 let mut accounts = Vec::with_capacity(3 + remaining_accounts.len());
264 accounts.push(solana_program::instruction::AccountMeta::new(
265 *self.payer.key,
266 true,
267 ));
268 accounts.push(solana_program::instruction::AccountMeta::new(
269 *self.new_account.key,
270 false,
271 ));
272 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
273 *self.base_account.key,
274 true,
275 ));
276 remaining_accounts.iter().for_each(|remaining_account| {
277 accounts.push(solana_program::instruction::AccountMeta {
278 pubkey: *remaining_account.0.key,
279 is_signer: remaining_account.1,
280 is_writable: remaining_account.2,
281 })
282 });
283 let mut data = CreateAccountWithSeedInstructionData::new()
284 .try_to_vec()
285 .unwrap();
286 let mut args = self.__args.try_to_vec().unwrap();
287 data.append(&mut args);
288
289 let instruction = solana_program::instruction::Instruction {
290 program_id: crate::SYSTEM_ID,
291 accounts,
292 data,
293 };
294 let mut account_infos = Vec::with_capacity(3 + 1 + remaining_accounts.len());
295 account_infos.push(self.__program.clone());
296 account_infos.push(self.payer.clone());
297 account_infos.push(self.new_account.clone());
298 account_infos.push(self.base_account.clone());
299 remaining_accounts
300 .iter()
301 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
302
303 if signers_seeds.is_empty() {
304 solana_program::program::invoke(&instruction, &account_infos)
305 } else {
306 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
307 }
308 }
309}
310
311#[derive(Clone, Debug)]
319pub struct CreateAccountWithSeedCpiBuilder<'a, 'b> {
320 instruction: Box<CreateAccountWithSeedCpiBuilderInstruction<'a, 'b>>,
321}
322
323impl<'a, 'b> CreateAccountWithSeedCpiBuilder<'a, 'b> {
324 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
325 let instruction = Box::new(CreateAccountWithSeedCpiBuilderInstruction {
326 __program: program,
327 payer: None,
328 new_account: None,
329 base_account: None,
330 base: None,
331 seed: None,
332 amount: None,
333 space: None,
334 program_address: None,
335 __remaining_accounts: Vec::new(),
336 });
337 Self { instruction }
338 }
339 #[inline(always)]
340 pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
341 self.instruction.payer = Some(payer);
342 self
343 }
344 #[inline(always)]
345 pub fn new_account(
346 &mut self,
347 new_account: &'b solana_program::account_info::AccountInfo<'a>,
348 ) -> &mut Self {
349 self.instruction.new_account = Some(new_account);
350 self
351 }
352 #[inline(always)]
353 pub fn base_account(
354 &mut self,
355 base_account: &'b solana_program::account_info::AccountInfo<'a>,
356 ) -> &mut Self {
357 self.instruction.base_account = Some(base_account);
358 self
359 }
360 #[inline(always)]
361 pub fn base(&mut self, base: Pubkey) -> &mut Self {
362 self.instruction.base = Some(base);
363 self
364 }
365 #[inline(always)]
366 pub fn seed(&mut self, seed: U64PrefixString) -> &mut Self {
367 self.instruction.seed = Some(seed);
368 self
369 }
370 #[inline(always)]
371 pub fn amount(&mut self, amount: u64) -> &mut Self {
372 self.instruction.amount = Some(amount);
373 self
374 }
375 #[inline(always)]
376 pub fn space(&mut self, space: u64) -> &mut Self {
377 self.instruction.space = Some(space);
378 self
379 }
380 #[inline(always)]
381 pub fn program_address(&mut self, program_address: Pubkey) -> &mut Self {
382 self.instruction.program_address = Some(program_address);
383 self
384 }
385 #[inline(always)]
387 pub fn add_remaining_account(
388 &mut self,
389 account: &'b solana_program::account_info::AccountInfo<'a>,
390 is_writable: bool,
391 is_signer: bool,
392 ) -> &mut Self {
393 self.instruction
394 .__remaining_accounts
395 .push((account, is_writable, is_signer));
396 self
397 }
398 #[inline(always)]
403 pub fn add_remaining_accounts(
404 &mut self,
405 accounts: &[(
406 &'b solana_program::account_info::AccountInfo<'a>,
407 bool,
408 bool,
409 )],
410 ) -> &mut Self {
411 self.instruction
412 .__remaining_accounts
413 .extend_from_slice(accounts);
414 self
415 }
416 #[inline(always)]
417 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
418 self.invoke_signed(&[])
419 }
420 #[allow(clippy::clone_on_copy)]
421 #[allow(clippy::vec_init_then_push)]
422 pub fn invoke_signed(
423 &self,
424 signers_seeds: &[&[&[u8]]],
425 ) -> solana_program::entrypoint::ProgramResult {
426 let args = CreateAccountWithSeedInstructionArgs {
427 base: self.instruction.base.clone().expect("base is not set"),
428 seed: self.instruction.seed.clone().expect("seed is not set"),
429 amount: self.instruction.amount.clone().expect("amount is not set"),
430 space: self.instruction.space.clone().expect("space is not set"),
431 program_address: self
432 .instruction
433 .program_address
434 .clone()
435 .expect("program_address is not set"),
436 };
437 let instruction = CreateAccountWithSeedCpi {
438 __program: self.instruction.__program,
439
440 payer: self.instruction.payer.expect("payer is not set"),
441
442 new_account: self
443 .instruction
444 .new_account
445 .expect("new_account is not set"),
446
447 base_account: self
448 .instruction
449 .base_account
450 .expect("base_account is not set"),
451 __args: args,
452 };
453 instruction.invoke_signed_with_remaining_accounts(
454 signers_seeds,
455 &self.instruction.__remaining_accounts,
456 )
457 }
458}
459
460#[derive(Clone, Debug)]
461struct CreateAccountWithSeedCpiBuilderInstruction<'a, 'b> {
462 __program: &'b solana_program::account_info::AccountInfo<'a>,
463 payer: Option<&'b solana_program::account_info::AccountInfo<'a>>,
464 new_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
465 base_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
466 base: Option<Pubkey>,
467 seed: Option<U64PrefixString>,
468 amount: Option<u64>,
469 space: Option<u64>,
470 program_address: Option<Pubkey>,
471 __remaining_accounts: Vec<(
473 &'b solana_program::account_info::AccountInfo<'a>,
474 bool,
475 bool,
476 )>,
477}