light_token/instruction/
transfer.rs1use light_sdk_types::LIGHT_TOKEN_PROGRAM_ID;
2use solana_account_info::AccountInfo;
3use solana_cpi::{invoke, invoke_signed};
4use solana_instruction::{AccountMeta, Instruction};
5use solana_program_error::ProgramError;
6use solana_pubkey::Pubkey;
7
8pub struct Transfer {
26 pub source: Pubkey,
27 pub destination: Pubkey,
28 pub amount: u64,
29 pub authority: Pubkey,
30 pub fee_payer: Pubkey,
32}
33
34pub struct TransferCpi<'info> {
55 pub source: AccountInfo<'info>,
56 pub destination: AccountInfo<'info>,
57 pub amount: u64,
58 pub authority: AccountInfo<'info>,
59 pub system_program: AccountInfo<'info>,
60 pub fee_payer: AccountInfo<'info>,
62}
63
64impl<'info> TransferCpi<'info> {
65 pub fn instruction(&self) -> Result<Instruction, ProgramError> {
66 Transfer::from(self).instruction()
67 }
68
69 pub fn invoke(self) -> Result<(), ProgramError> {
70 let instruction = Transfer::from(&self).instruction()?;
71 let account_infos = [
72 self.source,
73 self.destination,
74 self.authority,
75 self.system_program,
76 self.fee_payer,
77 ];
78 invoke(&instruction, &account_infos)
79 }
80
81 pub fn invoke_signed(self, signer_seeds: &[&[&[u8]]]) -> Result<(), ProgramError> {
82 let instruction = Transfer::from(&self).instruction()?;
83 let account_infos = [
84 self.source,
85 self.destination,
86 self.authority,
87 self.system_program,
88 self.fee_payer,
89 ];
90 invoke_signed(&instruction, &account_infos, signer_seeds)
91 }
92}
93
94impl<'info> From<&TransferCpi<'info>> for Transfer {
95 fn from(account_infos: &TransferCpi<'info>) -> Self {
96 Self {
97 source: *account_infos.source.key,
98 destination: *account_infos.destination.key,
99 amount: account_infos.amount,
100 authority: *account_infos.authority.key,
101 fee_payer: *account_infos.fee_payer.key,
102 }
103 }
104}
105
106impl_with_top_up!(Transfer, TransferWithTopUp);
107
108impl Transfer {
109 fn build_instruction(self, max_top_up: Option<u16>) -> Result<Instruction, ProgramError> {
110 let accounts = vec![
111 AccountMeta::new(self.source, false),
112 AccountMeta::new(self.destination, false),
113 AccountMeta::new_readonly(self.authority, true),
114 AccountMeta::new_readonly(Pubkey::default(), false),
115 AccountMeta::new(self.fee_payer, true),
116 ];
117
118 let mut data = vec![3u8];
119 data.extend_from_slice(&self.amount.to_le_bytes());
120 if let Some(max_top_up) = max_top_up {
121 data.extend_from_slice(&max_top_up.to_le_bytes());
122 }
123
124 Ok(Instruction {
125 program_id: Pubkey::from(LIGHT_TOKEN_PROGRAM_ID),
126 accounts,
127 data,
128 })
129 }
130}