1use crate::account_view::AccountView;
7use crate::address::Address;
8use crate::instruction::{CpiAccount, Signer};
9use crate::ProgramResult;
10
11pub const TOKEN_PROGRAM_ID: Address =
13 crate::address!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
14
15pub struct Transfer<'a> {
19 pub from: &'a AccountView<'a>,
20 pub to: &'a AccountView<'a>,
21 pub authority: &'a AccountView<'a>,
22 pub amount: u64,
23}
24
25impl Transfer<'_> {
26 #[inline]
27 pub fn invoke(&self) -> ProgramResult {
28 self.invoke_signed(&[])
29 }
30
31 #[inline]
32 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
33 let mut data = [0u8; 9];
34 data[0] = 3;
35 data[1..9].copy_from_slice(&self.amount.to_le_bytes());
36
37 let accounts = [
38 CpiAccount::from(self.from),
39 CpiAccount::from(self.to),
40 CpiAccount::from(self.authority),
41 ];
42
43 invoke_token(&data, &accounts, 0b011, 0b100, signers)
44 }
45}
46
47pub struct MintTo<'a> {
51 pub mint: &'a AccountView<'a>,
52 pub account: &'a AccountView<'a>,
53 pub mint_authority: &'a AccountView<'a>,
54 pub amount: u64,
55}
56
57impl MintTo<'_> {
58 #[inline]
59 pub fn invoke(&self) -> ProgramResult {
60 self.invoke_signed(&[])
61 }
62
63 #[inline]
64 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
65 let mut data = [0u8; 9];
66 data[0] = 7;
67 data[1..9].copy_from_slice(&self.amount.to_le_bytes());
68
69 let accounts = [
70 CpiAccount::from(self.mint),
71 CpiAccount::from(self.account),
72 CpiAccount::from(self.mint_authority),
73 ];
74
75 invoke_token(&data, &accounts, 0b011, 0b100, signers)
76 }
77}
78
79pub struct Burn<'a> {
83 pub account: &'a AccountView<'a>,
84 pub mint: &'a AccountView<'a>,
85 pub authority: &'a AccountView<'a>,
86 pub amount: u64,
87}
88
89impl Burn<'_> {
90 #[inline]
91 pub fn invoke(&self) -> ProgramResult {
92 self.invoke_signed(&[])
93 }
94
95 #[inline]
96 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
97 let mut data = [0u8; 9];
98 data[0] = 8;
99 data[1..9].copy_from_slice(&self.amount.to_le_bytes());
100
101 let accounts = [
102 CpiAccount::from(self.account),
103 CpiAccount::from(self.mint),
104 CpiAccount::from(self.authority),
105 ];
106
107 invoke_token(&data, &accounts, 0b011, 0b100, signers)
108 }
109}
110
111pub struct CloseAccount<'a> {
115 pub account: &'a AccountView<'a>,
116 pub destination: &'a AccountView<'a>,
117 pub authority: &'a AccountView<'a>,
118}
119
120impl CloseAccount<'_> {
121 #[inline]
122 pub fn invoke(&self) -> ProgramResult {
123 self.invoke_signed(&[])
124 }
125
126 #[inline]
127 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
128 let data = [9u8];
129
130 let accounts = [
131 CpiAccount::from(self.account),
132 CpiAccount::from(self.destination),
133 CpiAccount::from(self.authority),
134 ];
135
136 invoke_token(&data, &accounts, 0b011, 0b100, signers)
137 }
138}
139
140pub struct Approve<'a> {
144 pub source: &'a AccountView<'a>,
145 pub delegate: &'a AccountView<'a>,
146 pub authority: &'a AccountView<'a>,
147 pub amount: u64,
148}
149
150impl Approve<'_> {
151 #[inline]
152 pub fn invoke(&self) -> ProgramResult {
153 self.invoke_signed(&[])
154 }
155
156 #[inline]
157 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
158 let mut data = [0u8; 9];
159 data[0] = 4;
160 data[1..9].copy_from_slice(&self.amount.to_le_bytes());
161
162 let accounts = [
163 CpiAccount::from(self.source),
164 CpiAccount::from(self.delegate),
165 CpiAccount::from(self.authority),
166 ];
167
168 invoke_token(&data, &accounts, 0b001, 0b100, signers)
169 }
170}
171
172pub struct Revoke<'a> {
176 pub source: &'a AccountView<'a>,
177 pub authority: &'a AccountView<'a>,
178}
179
180impl Revoke<'_> {
181 #[inline]
182 pub fn invoke(&self) -> ProgramResult {
183 self.invoke_signed(&[])
184 }
185
186 #[inline]
187 pub fn invoke_signed(&self, signers: &[Signer<'_, '_>]) -> ProgramResult {
188 let data = [5u8];
189
190 let accounts = [
191 CpiAccount::from(self.source),
192 CpiAccount::from(self.authority),
193 ];
194
195 invoke_token(&data, &accounts, 0b01, 0b10, signers)
196 }
197}
198
199#[inline]
202fn invoke_token<'a, const ACCOUNTS: usize>(
203 data: &[u8],
204 accounts: &[CpiAccount<'a>; ACCOUNTS],
205 writable_mask: usize,
206 signer_mask: usize,
207 signers: &[Signer<'_, '_>],
208) -> ProgramResult {
209 crate::cpi::invoke_specialized_signed(
210 &TOKEN_PROGRAM_ID,
211 data,
212 accounts,
213 writable_mask,
214 signer_mask,
215 signers,
216 )
217}
218
219pub mod instructions {
221 pub use super::{Approve, Burn, CloseAccount, MintTo, Revoke, Transfer};
222}