1use borsh::BorshDeserialize;
9use borsh::BorshSerialize;
10use solana_program::pubkey::Pubkey;
11
12pub struct TransferWithSeed {
14 pub funding_account: solana_program::pubkey::Pubkey,
16 pub base: solana_program::pubkey::Pubkey,
18 pub recipient_account: solana_program::pubkey::Pubkey,
20}
21
22impl TransferWithSeed {
23 pub fn instruction(
24 &self,
25 args: TransferWithSeedInstructionArgs,
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: TransferWithSeedInstructionArgs,
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.funding_account,
38 false,
39 ));
40 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
41 self.base, true,
42 ));
43 accounts.push(solana_program::instruction::AccountMeta::new(
44 self.recipient_account,
45 false,
46 ));
47 accounts.extend_from_slice(remaining_accounts);
48 let mut data = TransferWithSeedInstructionData::new().try_to_vec().unwrap();
49 let mut args = args.try_to_vec().unwrap();
50 data.append(&mut args);
51
52 solana_program::instruction::Instruction {
53 program_id: crate::SYSTEM_PROGRAM_ID,
54 accounts,
55 data,
56 }
57 }
58}
59
60#[derive(BorshDeserialize, BorshSerialize)]
61struct TransferWithSeedInstructionData {
62 discriminator: u32,
63}
64
65impl TransferWithSeedInstructionData {
66 fn new() -> Self {
67 Self { discriminator: 11 }
68 }
69}
70
71#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
72#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
73pub struct TransferWithSeedInstructionArgs {
74 pub lamports: u64,
75 pub from_seed: String,
76 pub from_owner: Pubkey,
77}
78
79#[derive(Default)]
87pub struct TransferWithSeedBuilder {
88 funding_account: Option<solana_program::pubkey::Pubkey>,
89 base: Option<solana_program::pubkey::Pubkey>,
90 recipient_account: Option<solana_program::pubkey::Pubkey>,
91 lamports: Option<u64>,
92 from_seed: Option<String>,
93 from_owner: Option<Pubkey>,
94 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
95}
96
97impl TransferWithSeedBuilder {
98 pub fn new() -> Self {
99 Self::default()
100 }
101 #[inline(always)]
103 pub fn funding_account(
104 &mut self,
105 funding_account: solana_program::pubkey::Pubkey,
106 ) -> &mut Self {
107 self.funding_account = Some(funding_account);
108 self
109 }
110 #[inline(always)]
112 pub fn base(&mut self, base: solana_program::pubkey::Pubkey) -> &mut Self {
113 self.base = Some(base);
114 self
115 }
116 #[inline(always)]
118 pub fn recipient_account(
119 &mut self,
120 recipient_account: solana_program::pubkey::Pubkey,
121 ) -> &mut Self {
122 self.recipient_account = Some(recipient_account);
123 self
124 }
125 #[inline(always)]
126 pub fn lamports(&mut self, lamports: u64) -> &mut Self {
127 self.lamports = Some(lamports);
128 self
129 }
130 #[inline(always)]
131 pub fn from_seed(&mut self, from_seed: String) -> &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 = TransferWithSeed {
161 funding_account: self.funding_account.expect("funding_account is not set"),
162 base: self.base.expect("base is not set"),
163 recipient_account: self
164 .recipient_account
165 .expect("recipient_account is not set"),
166 };
167 let args = TransferWithSeedInstructionArgs {
168 lamports: self.lamports.clone().expect("lamports is not set"),
169 from_seed: self.from_seed.clone().expect("from_seed is not set"),
170 from_owner: self.from_owner.clone().expect("from_owner is not set"),
171 };
172
173 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
174 }
175}
176
177pub struct TransferWithSeedCpiAccounts<'a, 'b> {
179 pub funding_account: &'b solana_program::account_info::AccountInfo<'a>,
181 pub base: &'b solana_program::account_info::AccountInfo<'a>,
183 pub recipient_account: &'b solana_program::account_info::AccountInfo<'a>,
185}
186
187pub struct TransferWithSeedCpi<'a, 'b> {
189 pub __program: &'b solana_program::account_info::AccountInfo<'a>,
191 pub funding_account: &'b solana_program::account_info::AccountInfo<'a>,
193 pub base: &'b solana_program::account_info::AccountInfo<'a>,
195 pub recipient_account: &'b solana_program::account_info::AccountInfo<'a>,
197 pub __args: TransferWithSeedInstructionArgs,
199}
200
201impl<'a, 'b> TransferWithSeedCpi<'a, 'b> {
202 pub fn new(
203 program: &'b solana_program::account_info::AccountInfo<'a>,
204 accounts: TransferWithSeedCpiAccounts<'a, 'b>,
205 args: TransferWithSeedInstructionArgs,
206 ) -> Self {
207 Self {
208 __program: program,
209 funding_account: accounts.funding_account,
210 base: accounts.base,
211 recipient_account: accounts.recipient_account,
212 __args: args,
213 }
214 }
215 #[inline(always)]
216 pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult {
217 self.invoke_signed_with_remaining_accounts(&[], &[])
218 }
219 #[inline(always)]
220 pub fn invoke_with_remaining_accounts(
221 &self,
222 remaining_accounts: &[(
223 &'b solana_program::account_info::AccountInfo<'a>,
224 bool,
225 bool,
226 )],
227 ) -> solana_program::entrypoint::ProgramResult {
228 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
229 }
230 #[inline(always)]
231 pub fn invoke_signed(
232 &self,
233 signers_seeds: &[&[&[u8]]],
234 ) -> solana_program::entrypoint::ProgramResult {
235 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
236 }
237 #[allow(clippy::clone_on_copy)]
238 #[allow(clippy::vec_init_then_push)]
239 pub fn invoke_signed_with_remaining_accounts(
240 &self,
241 signers_seeds: &[&[&[u8]]],
242 remaining_accounts: &[(
243 &'b solana_program::account_info::AccountInfo<'a>,
244 bool,
245 bool,
246 )],
247 ) -> solana_program::entrypoint::ProgramResult {
248 let mut accounts = Vec::with_capacity(3 + remaining_accounts.len());
249 accounts.push(solana_program::instruction::AccountMeta::new(
250 *self.funding_account.key,
251 false,
252 ));
253 accounts.push(solana_program::instruction::AccountMeta::new_readonly(
254 *self.base.key,
255 true,
256 ));
257 accounts.push(solana_program::instruction::AccountMeta::new(
258 *self.recipient_account.key,
259 false,
260 ));
261 remaining_accounts.iter().for_each(|remaining_account| {
262 accounts.push(solana_program::instruction::AccountMeta {
263 pubkey: *remaining_account.0.key,
264 is_signer: remaining_account.1,
265 is_writable: remaining_account.2,
266 })
267 });
268 let mut data = TransferWithSeedInstructionData::new().try_to_vec().unwrap();
269 let mut args = self.__args.try_to_vec().unwrap();
270 data.append(&mut args);
271
272 let instruction = solana_program::instruction::Instruction {
273 program_id: crate::SYSTEM_PROGRAM_ID,
274 accounts,
275 data,
276 };
277 let mut account_infos = Vec::with_capacity(3 + 1 + remaining_accounts.len());
278 account_infos.push(self.__program.clone());
279 account_infos.push(self.funding_account.clone());
280 account_infos.push(self.base.clone());
281 account_infos.push(self.recipient_account.clone());
282 remaining_accounts
283 .iter()
284 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
285
286 if signers_seeds.is_empty() {
287 solana_program::program::invoke(&instruction, &account_infos)
288 } else {
289 solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds)
290 }
291 }
292}
293
294pub struct TransferWithSeedCpiBuilder<'a, 'b> {
302 instruction: Box<TransferWithSeedCpiBuilderInstruction<'a, 'b>>,
303}
304
305impl<'a, 'b> TransferWithSeedCpiBuilder<'a, 'b> {
306 pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self {
307 let instruction = Box::new(TransferWithSeedCpiBuilderInstruction {
308 __program: program,
309 funding_account: None,
310 base: None,
311 recipient_account: None,
312 lamports: None,
313 from_seed: None,
314 from_owner: None,
315 __remaining_accounts: Vec::new(),
316 });
317 Self { instruction }
318 }
319 #[inline(always)]
321 pub fn funding_account(
322 &mut self,
323 funding_account: &'b solana_program::account_info::AccountInfo<'a>,
324 ) -> &mut Self {
325 self.instruction.funding_account = Some(funding_account);
326 self
327 }
328 #[inline(always)]
330 pub fn base(&mut self, base: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self {
331 self.instruction.base = Some(base);
332 self
333 }
334 #[inline(always)]
336 pub fn recipient_account(
337 &mut self,
338 recipient_account: &'b solana_program::account_info::AccountInfo<'a>,
339 ) -> &mut Self {
340 self.instruction.recipient_account = Some(recipient_account);
341 self
342 }
343 #[inline(always)]
344 pub fn lamports(&mut self, lamports: u64) -> &mut Self {
345 self.instruction.lamports = Some(lamports);
346 self
347 }
348 #[inline(always)]
349 pub fn from_seed(&mut self, from_seed: String) -> &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 = TransferWithSeedInstructionArgs {
400 lamports: self
401 .instruction
402 .lamports
403 .clone()
404 .expect("lamports is not set"),
405 from_seed: self
406 .instruction
407 .from_seed
408 .clone()
409 .expect("from_seed is not set"),
410 from_owner: self
411 .instruction
412 .from_owner
413 .clone()
414 .expect("from_owner is not set"),
415 };
416 let instruction = TransferWithSeedCpi {
417 __program: self.instruction.__program,
418
419 funding_account: self
420 .instruction
421 .funding_account
422 .expect("funding_account is not set"),
423
424 base: self.instruction.base.expect("base is not set"),
425
426 recipient_account: self
427 .instruction
428 .recipient_account
429 .expect("recipient_account is not set"),
430 __args: args,
431 };
432 instruction.invoke_signed_with_remaining_accounts(
433 signers_seeds,
434 &self.instruction.__remaining_accounts,
435 )
436 }
437}
438
439struct TransferWithSeedCpiBuilderInstruction<'a, 'b> {
440 __program: &'b solana_program::account_info::AccountInfo<'a>,
441 funding_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
442 base: Option<&'b solana_program::account_info::AccountInfo<'a>>,
443 recipient_account: Option<&'b solana_program::account_info::AccountInfo<'a>>,
444 lamports: Option<u64>,
445 from_seed: Option<String>,
446 from_owner: Option<Pubkey>,
447 __remaining_accounts: Vec<(
449 &'b solana_program::account_info::AccountInfo<'a>,
450 bool,
451 bool,
452 )>,
453}