spl_managed_token/
instruction.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2use shank::ShankInstruction;
3use solana_program::{
4    instruction::{AccountMeta, Instruction},
5    program_error::ProgramError,
6    pubkey::Pubkey,
7    system_program,
8};
9use spl_associated_token_account::get_associated_token_address;
10
11use crate::get_authority;
12
13#[derive(Debug, Clone, ShankInstruction, BorshSerialize, BorshDeserialize)]
14#[rustfmt::skip]
15pub enum ManagedTokenInstruction {
16
17    #[account(0, writable, signer, name = "mint")]
18    #[account(1, writable, signer, name = "payer")]
19    #[account(2, name = "upstream_authority")]
20    #[account(3, name = "system_program", desc = "System program")]
21    #[account(4, name = "token_program", desc = "Token program")]
22    InitializeMint {
23        decimals: u8,
24    },
25
26    #[account(0, writable, name = "account")]
27    #[account(1, name = "owner")]
28    #[account(2, writable, signer, name = "payer")]
29    #[account(3, signer, name = "upstream_authority")]
30    #[account(4, name = "freeze_authority")]
31    #[account(5, name = "mint")]
32    #[account(6, name = "system_program", desc = "System program")]
33    #[account(
34        7,
35        name = "associated_token_program",
36        desc = "Associated Token program"
37    )]
38    #[account(8, name = "token_program", desc = "Token program")]
39    InitializeAccount,
40
41    #[account(0, writable, name = "src_account")]
42    #[account(1, writable, name = "dst_account")]
43    #[account(2, name = "mint")]
44    #[account(3, signer, name = "owner")]
45    #[account(4, signer, name = "upstream_authority")]
46    #[account(5, name = "freeze_authority")]
47    #[account(6, name = "token_program", desc = "Token program")]
48    Transfer { amount: u64 },
49
50    #[account(0, writable, name = "mint")]
51    #[account(1, writable, name = "account")]
52    #[account(2, signer, name = "upstream_authority")]
53    #[account(3, name = "freeze_authority")]
54    #[account(4, name = "token_program", desc = "Token program")]
55    MintTo { amount: u64 },
56
57    #[account(0, writable, name = "mint")]
58    #[account(1, writable, name = "account")]
59    #[account(2, signer, name = "owner")]
60    #[account(3, signer, name = "upstream_authority")]
61    #[account(4, name = "freeze_authority")]
62    #[account(5, name = "token_program", desc = "Token program")]
63    Burn { amount: u64 },
64
65    #[account(0, writable, name = "account")]
66    #[account(1, writable, name = "destination")]
67    #[account(2, name = "mint")]
68    #[account(3, signer, name = "owner")]
69    #[account(4, signer, name = "upstream_authority")]
70    #[account(5, name = "freeze_authority")]
71    #[account(6, name = "token_program", desc = "Token program")]
72    CloseAccount,
73
74    #[account(0, name = "mint")]
75    #[account(1, writable, name = "account")]
76    #[account(2, signer, name = "owner")]
77    #[account(3, signer, name = "upstream_authority")]
78    #[account(4, name = "delegate")]
79    #[account(5, name = "freeze_authority")]
80    #[account(6, name = "token_program", desc = "Token program")]
81    Approve { amount: u64 },
82
83    #[account(0, name = "mint")]
84    #[account(1, writable, name = "account")]
85    #[account(2, signer, name = "owner")]
86    #[account(3, signer, name = "upstream_authority")]
87    #[account(4, name = "freeze_authority")]
88    #[account(5, name = "token_program", desc = "Token program")]
89    Revoke,
90}
91
92pub fn create_initialize_mint_instruction(
93    mint: &Pubkey,
94    payer: &Pubkey,
95    upstream_authority: &Pubkey,
96    decimals: u8,
97) -> Result<Instruction, ProgramError> {
98    Ok(Instruction {
99        program_id: crate::id(),
100        accounts: vec![
101            AccountMeta::new(*mint, true),
102            AccountMeta::new(*payer, true),
103            AccountMeta::new_readonly(*upstream_authority, false),
104            AccountMeta::new_readonly(system_program::id(), false),
105            AccountMeta::new_readonly(spl_token::id(), false),
106        ],
107        data: ManagedTokenInstruction::InitializeMint { decimals }.try_to_vec()?,
108    })
109}
110
111pub fn create_initialize_account_instruction(
112    mint: &Pubkey,
113    owner: &Pubkey,
114    payer: &Pubkey,
115    upstream_authority: &Pubkey,
116) -> Result<Instruction, ProgramError> {
117    let account = get_associated_token_address(owner, mint);
118    let (freeze_authority, _) = get_authority(upstream_authority);
119    Ok(Instruction {
120        program_id: crate::id(),
121        accounts: vec![
122            AccountMeta::new(account, false),
123            AccountMeta::new_readonly(*owner, false),
124            AccountMeta::new(*payer, true),
125            AccountMeta::new_readonly(*upstream_authority, true),
126            AccountMeta::new_readonly(freeze_authority, false),
127            AccountMeta::new_readonly(*mint, false),
128            AccountMeta::new_readonly(system_program::id(), false),
129            AccountMeta::new_readonly(spl_associated_token_account::id(), false),
130            AccountMeta::new_readonly(spl_token::id(), false),
131        ],
132        data: ManagedTokenInstruction::InitializeAccount.try_to_vec()?,
133    })
134}
135
136pub fn create_mint_to_instruction(
137    mint: &Pubkey,
138    owner: &Pubkey,
139    upstream_authority: &Pubkey,
140    amount: u64,
141) -> Result<Instruction, ProgramError> {
142    let account = get_associated_token_address(owner, mint);
143    let (authority, _) = get_authority(upstream_authority);
144    Ok(Instruction {
145        program_id: crate::id(),
146        accounts: vec![
147            AccountMeta::new(*mint, false),
148            AccountMeta::new(account, false),
149            AccountMeta::new_readonly(*upstream_authority, true),
150            AccountMeta::new_readonly(authority, false),
151            AccountMeta::new_readonly(spl_token::id(), false),
152        ],
153        data: ManagedTokenInstruction::MintTo { amount }.try_to_vec()?,
154    })
155}
156
157pub fn create_transfer_instruction(
158    src: &Pubkey,
159    dst: &Pubkey,
160    mint: &Pubkey,
161    upstream_authority: &Pubkey,
162    amount: u64,
163) -> Result<Instruction, ProgramError> {
164    let src_account = get_associated_token_address(src, mint);
165    let dst_account = get_associated_token_address(dst, mint);
166    let (freeze_authority, _) = get_authority(upstream_authority);
167    Ok(Instruction {
168        program_id: crate::id(),
169        accounts: vec![
170            AccountMeta::new(src_account, false),
171            AccountMeta::new(dst_account, false),
172            AccountMeta::new_readonly(*mint, false),
173            AccountMeta::new_readonly(*src, true),
174            AccountMeta::new_readonly(*upstream_authority, true),
175            AccountMeta::new_readonly(freeze_authority, false),
176            AccountMeta::new_readonly(spl_token::id(), false),
177        ],
178        data: ManagedTokenInstruction::Transfer { amount }.try_to_vec()?,
179    })
180}
181
182pub fn create_transfer_with_delegate_instruction(
183    src: &Pubkey,
184    dst: &Pubkey,
185    delegate: &Pubkey,
186    mint: &Pubkey,
187    upstream_authority: &Pubkey,
188    amount: u64,
189) -> Result<Instruction, ProgramError> {
190    let src_account = get_associated_token_address(src, mint);
191    let dst_account = get_associated_token_address(dst, mint);
192    let (freeze_authority, _) = get_authority(upstream_authority);
193    Ok(Instruction {
194        program_id: crate::id(),
195        accounts: vec![
196            AccountMeta::new(src_account, false),
197            AccountMeta::new(dst_account, false),
198            AccountMeta::new_readonly(*mint, false),
199            AccountMeta::new_readonly(*delegate, true),
200            AccountMeta::new_readonly(*upstream_authority, true),
201            AccountMeta::new_readonly(freeze_authority, false),
202            AccountMeta::new_readonly(spl_token::id(), false),
203        ],
204        data: ManagedTokenInstruction::Transfer { amount }.try_to_vec()?,
205    })
206}
207
208pub fn create_burn_instruction(
209    mint: &Pubkey,
210    owner: &Pubkey,
211    upstream_authority: &Pubkey,
212    amount: u64,
213) -> Result<Instruction, ProgramError> {
214    let account = get_associated_token_address(owner, mint);
215    let (freeze_authority, _) = get_authority(upstream_authority);
216    Ok(Instruction {
217        program_id: crate::id(),
218        accounts: vec![
219            AccountMeta::new(*mint, false),
220            AccountMeta::new(account, false),
221            AccountMeta::new_readonly(*owner, true),
222            AccountMeta::new_readonly(*upstream_authority, true),
223            AccountMeta::new_readonly(freeze_authority, false),
224            AccountMeta::new_readonly(spl_token::id(), false),
225        ],
226        data: ManagedTokenInstruction::Burn { amount }.try_to_vec()?,
227    })
228}
229
230pub fn create_close_account_instruction(
231    mint: &Pubkey,
232    owner: &Pubkey,
233    upstream_authority: &Pubkey,
234) -> Result<Instruction, ProgramError> {
235    let account = get_associated_token_address(owner, mint);
236    let (freeze_authority, _) = get_authority(upstream_authority);
237    Ok(Instruction {
238        program_id: crate::id(),
239        accounts: vec![
240            AccountMeta::new(account, false),
241            AccountMeta::new(*owner, false),
242            AccountMeta::new_readonly(*mint, false),
243            AccountMeta::new_readonly(*owner, true),
244            AccountMeta::new_readonly(*upstream_authority, true),
245            AccountMeta::new_readonly(freeze_authority, false),
246            AccountMeta::new_readonly(spl_token::id(), false),
247        ],
248        data: ManagedTokenInstruction::CloseAccount.try_to_vec()?,
249    })
250}
251
252pub fn create_approve_instruction(
253    mint: &Pubkey,
254    owner: &Pubkey,
255    delegate: &Pubkey,
256    upstream_authority: &Pubkey,
257    amount: u64,
258) -> Result<Instruction, ProgramError> {
259    let (freeze_authority, _) = get_authority(upstream_authority);
260    let account = get_associated_token_address(owner, mint);
261    Ok(Instruction {
262        program_id: crate::id(),
263        accounts: vec![
264            AccountMeta::new_readonly(*mint, false),
265            AccountMeta::new(account, false),
266            AccountMeta::new_readonly(*owner, true),
267            AccountMeta::new_readonly(*upstream_authority, true),
268            AccountMeta::new_readonly(*delegate, false),
269            AccountMeta::new_readonly(freeze_authority, false),
270            AccountMeta::new_readonly(spl_token::id(), false),
271        ],
272        data: ManagedTokenInstruction::Approve { amount }.try_to_vec()?,
273    })
274}
275
276pub fn create_revoke_instruction(
277    mint: &Pubkey,
278    owner: &Pubkey,
279    upstream_authority: &Pubkey,
280) -> Result<Instruction, ProgramError> {
281    let (freeze_authority, _) = get_authority(upstream_authority);
282    let account = get_associated_token_address(owner, mint);
283    Ok(Instruction {
284        program_id: crate::id(),
285        accounts: vec![
286            AccountMeta::new_readonly(*mint, false),
287            AccountMeta::new(account, false),
288            AccountMeta::new_readonly(*owner, true),
289            AccountMeta::new_readonly(*upstream_authority, true),
290            AccountMeta::new_readonly(freeze_authority, false),
291            AccountMeta::new_readonly(spl_token::id(), false),
292        ],
293        data: ManagedTokenInstruction::Revoke.try_to_vec()?,
294    })
295}