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