spl_token_interface/instruction.rs
1//! Instruction types.
2
3use pinocchio::{program_error::ProgramError, pubkey::Pubkey};
4
5use crate::error::TokenError;
6
7/// Instructions supported by the token program.
8#[repr(C)]
9#[derive(Clone, Debug, PartialEq)]
10pub enum TokenInstruction<'a> {
11 /// Initializes a new mint and optionally deposits all the newly minted
12 /// tokens in an account.
13 ///
14 /// The `InitializeMint` instruction requires no signers and MUST be
15 /// included within the same Transaction as the system program's
16 /// `CreateAccount` instruction that creates the account being initialized.
17 /// Otherwise another party can acquire ownership of the uninitialized
18 /// account.
19 ///
20 /// Accounts expected by this instruction:
21 ///
22 /// 0. `[writable]` The mint to initialize.
23 /// 1. `[]` Rent sysvar
24 InitializeMint {
25 /// Number of base 10 digits to the right of the decimal place.
26 decimals: u8,
27 /// The authority/multisignature to mint tokens.
28 mint_authority: Pubkey,
29 /// The freeze authority/multisignature of the mint.
30 freeze_authority: Option<Pubkey>,
31 },
32
33 /// Initializes a new account to hold tokens. If this account is associated
34 /// with the native mint then the token balance of the initialized account
35 /// will be equal to the amount of SOL in the account. If this account is
36 /// associated with another mint, that mint must be initialized before this
37 /// command can succeed.
38 ///
39 /// The `InitializeAccount` instruction requires no signers and MUST be
40 /// included within the same Transaction as the system program's
41 /// `CreateAccount` instruction that creates the account being initialized.
42 /// Otherwise another party can acquire ownership of the uninitialized
43 /// account.
44 ///
45 /// Accounts expected by this instruction:
46 ///
47 /// 0. `[writable]` The account to initialize.
48 /// 1. `[]` The mint this account will be associated with.
49 /// 2. `[]` The new account's owner/multisignature.
50 /// 3. `[]` Rent sysvar
51 InitializeAccount,
52
53 /// Initializes a multisignature account with N provided signers.
54 ///
55 /// Multisignature accounts can used in place of any single owner/delegate
56 /// accounts in any token instruction that require an owner/delegate to be
57 /// present. The variant field represents the number of signers (M)
58 /// required to validate this multisignature account.
59 ///
60 /// The `InitializeMultisig` instruction requires no signers and MUST be
61 /// included within the same Transaction as the system program's
62 /// `CreateAccount` instruction that creates the account being initialized.
63 /// Otherwise another party can acquire ownership of the uninitialized
64 /// account.
65 ///
66 /// Accounts expected by this instruction:
67 ///
68 /// 0. `[writable]` The multisignature account to initialize.
69 /// 1. `[]` Rent sysvar
70 /// 2. ..2+N. `[]` The signer accounts, must equal to N where 1 <= N <=
71 /// 11.
72 InitializeMultisig {
73 /// The number of signers (M) required to validate this multisignature
74 /// account.
75 m: u8,
76 },
77
78 /// Transfers tokens from one account to another either directly or via a
79 /// delegate. If this account is associated with the native mint then equal
80 /// amounts of SOL and Tokens will be transferred to the destination
81 /// account.
82 ///
83 /// Accounts expected by this instruction:
84 ///
85 /// * Single owner/delegate
86 /// 0. `[writable]` The source account.
87 /// 1. `[writable]` The destination account.
88 /// 2. `[signer]` The source account's owner/delegate.
89 ///
90 /// * Multisignature owner/delegate
91 /// 0. `[writable]` The source account.
92 /// 1. `[writable]` The destination account.
93 /// 2. `[]` The source account's multisignature owner/delegate.
94 /// 3. ..3+M `[signer]` M signer accounts.
95 Transfer {
96 /// The amount of tokens to transfer.
97 amount: u64,
98 },
99
100 /// Approves a delegate. A delegate is given the authority over tokens on
101 /// behalf of the source account's owner.
102 ///
103 /// Accounts expected by this instruction:
104 ///
105 /// * Single owner
106 /// 0. `[writable]` The source account.
107 /// 1. `[]` The delegate.
108 /// 2. `[signer]` The source account owner.
109 ///
110 /// * Multisignature owner
111 /// 0. `[writable]` The source account.
112 /// 1. `[]` The delegate.
113 /// 2. `[]` The source account's multisignature owner.
114 /// 3. ..3+M `[signer]` M signer accounts
115 Approve {
116 /// The amount of tokens the delegate is approved for.
117 amount: u64,
118 },
119
120 /// Revokes the delegate's authority.
121 ///
122 /// Accounts expected by this instruction:
123 ///
124 /// * Single owner
125 /// 0. `[writable]` The source account.
126 /// 1. `[signer]` The source account owner.
127 ///
128 /// * Multisignature owner
129 /// 0. `[writable]` The source account.
130 /// 1. `[]` The source account's multisignature owner.
131 /// 2. ..2+M `[signer]` M signer accounts
132 Revoke,
133
134 /// Sets a new authority of a mint or account.
135 ///
136 /// Accounts expected by this instruction:
137 ///
138 /// * Single authority
139 /// 0. `[writable]` The mint or account to change the authority of.
140 /// 1. `[signer]` The current authority of the mint or account.
141 ///
142 /// * Multisignature authority
143 /// 0. `[writable]` The mint or account to change the authority of.
144 /// 1. `[]` The mint's or account's current multisignature authority.
145 /// 2. ..2+M `[signer]` M signer accounts
146 SetAuthority {
147 /// The type of authority to update.
148 authority_type: AuthorityType,
149 /// The new authority
150 new_authority: Option<Pubkey>,
151 },
152
153 /// Mints new tokens to an account. The native mint does not support
154 /// minting.
155 ///
156 /// Accounts expected by this instruction:
157 ///
158 /// * Single authority
159 /// 0. `[writable]` The mint.
160 /// 1. `[writable]` The account to mint tokens to.
161 /// 2. `[signer]` The mint's minting authority.
162 ///
163 /// * Multisignature authority
164 /// 0. `[writable]` The mint.
165 /// 1. `[writable]` The account to mint tokens to.
166 /// 2. `[]` The mint's multisignature mint-tokens authority.
167 /// 3. ..3+M `[signer]` M signer accounts.
168 MintTo {
169 /// The amount of new tokens to mint.
170 amount: u64,
171 },
172
173 /// Burns tokens by removing them from an account. `Burn` does not support
174 /// accounts associated with the native mint, use `CloseAccount` instead.
175 ///
176 /// Accounts expected by this instruction:
177 ///
178 /// * Single owner/delegate
179 /// 0. `[writable]` The account to burn from.
180 /// 1. `[writable]` The token mint.
181 /// 2. `[signer]` The account's owner/delegate.
182 ///
183 /// * Multisignature owner/delegate
184 /// 0. `[writable]` The account to burn from.
185 /// 1. `[writable]` The token mint.
186 /// 2. `[]` The account's multisignature owner/delegate.
187 /// 3. ..3+M `[signer]` M signer accounts.
188 Burn {
189 /// The amount of tokens to burn.
190 amount: u64,
191 },
192
193 /// Close an account by transferring all its SOL to the destination account.
194 /// Non-native accounts may only be closed if its token amount is zero.
195 ///
196 /// Accounts expected by this instruction:
197 ///
198 /// * Single owner
199 /// 0. `[writable]` The account to close.
200 /// 1. `[writable]` The destination account.
201 /// 2. `[signer]` The account's owner.
202 ///
203 /// * Multisignature owner
204 /// 0. `[writable]` The account to close.
205 /// 1. `[writable]` The destination account.
206 /// 2. `[]` The account's multisignature owner.
207 /// 3. ..3+M `[signer]` M signer accounts.
208 CloseAccount,
209
210 /// Freeze an Initialized account using the Mint's freeze_authority (if
211 /// set).
212 ///
213 /// Accounts expected by this instruction:
214 ///
215 /// * Single owner
216 /// 0. `[writable]` The account to freeze.
217 /// 1. `[]` The token mint.
218 /// 2. `[signer]` The mint freeze authority.
219 ///
220 /// * Multisignature owner
221 /// 0. `[writable]` The account to freeze.
222 /// 1. `[]` The token mint.
223 /// 2. `[]` The mint's multisignature freeze authority.
224 /// 3. ..3+M `[signer]` M signer accounts.
225 FreezeAccount,
226
227 /// Thaw a Frozen account using the Mint's freeze_authority (if set).
228 ///
229 /// Accounts expected by this instruction:
230 ///
231 /// * Single owner
232 /// 0. `[writable]` The account to freeze.
233 /// 1. `[]` The token mint.
234 /// 2. `[signer]` The mint freeze authority.
235 ///
236 /// * Multisignature owner
237 /// 0. `[writable]` The account to freeze.
238 /// 1. `[]` The token mint.
239 /// 2. `[]` The mint's multisignature freeze authority.
240 /// 3. ..3+M `[signer]` M signer accounts.
241 ThawAccount,
242
243 /// Transfers tokens from one account to another either directly or via a
244 /// delegate. If this account is associated with the native mint then equal
245 /// amounts of SOL and Tokens will be transferred to the destination
246 /// account.
247 ///
248 /// This instruction differs from Transfer in that the token mint and
249 /// decimals value is checked by the caller. This may be useful when
250 /// creating transactions offline or within a hardware wallet.
251 ///
252 /// Accounts expected by this instruction:
253 ///
254 /// * Single owner/delegate
255 /// 0. `[writable]` The source account.
256 /// 1. `[]` The token mint.
257 /// 2. `[writable]` The destination account.
258 /// 3. `[signer]` The source account's owner/delegate.
259 ///
260 /// * Multisignature owner/delegate
261 /// 0. `[writable]` The source account.
262 /// 1. `[]` The token mint.
263 /// 2. `[writable]` The destination account.
264 /// 3. `[]` The source account's multisignature owner/delegate.
265 /// 4. ..4+M `[signer]` M signer accounts.
266 TransferChecked {
267 /// The amount of tokens to transfer.
268 amount: u64,
269 /// Expected number of base 10 digits to the right of the decimal place.
270 decimals: u8,
271 },
272
273 /// Approves a delegate. A delegate is given the authority over tokens on
274 /// behalf of the source account's owner.
275 ///
276 /// This instruction differs from Approve in that the token mint and
277 /// decimals value is checked by the caller. This may be useful when
278 /// creating transactions offline or within a hardware wallet.
279 ///
280 /// Accounts expected by this instruction:
281 ///
282 /// * Single owner
283 /// 0. `[writable]` The source account.
284 /// 1. `[]` The token mint.
285 /// 2. `[]` The delegate.
286 /// 3. `[signer]` The source account owner.
287 ///
288 /// * Multisignature owner
289 /// 0. `[writable]` The source account.
290 /// 1. `[]` The token mint.
291 /// 2. `[]` The delegate.
292 /// 3. `[]` The source account's multisignature owner.
293 /// 4. ..4+M `[signer]` M signer accounts
294 ApproveChecked {
295 /// The amount of tokens the delegate is approved for.
296 amount: u64,
297 /// Expected number of base 10 digits to the right of the decimal place.
298 decimals: u8,
299 },
300
301 /// Mints new tokens to an account. The native mint does not support
302 /// minting.
303 ///
304 /// This instruction differs from MintTo in that the decimals value is
305 /// checked by the caller. This may be useful when creating transactions
306 /// offline or within a hardware wallet.
307 ///
308 /// Accounts expected by this instruction:
309 ///
310 /// * Single authority
311 /// 0. `[writable]` The mint.
312 /// 1. `[writable]` The account to mint tokens to.
313 /// 2. `[signer]` The mint's minting authority.
314 ///
315 /// * Multisignature authority
316 /// 0. `[writable]` The mint.
317 /// 1. `[writable]` The account to mint tokens to.
318 /// 2. `[]` The mint's multisignature mint-tokens authority.
319 /// 3. ..3+M `[signer]` M signer accounts.
320 MintToChecked {
321 /// The amount of new tokens to mint.
322 amount: u64,
323 /// Expected number of base 10 digits to the right of the decimal place.
324 decimals: u8,
325 },
326
327 /// Burns tokens by removing them from an account. `BurnChecked` does not
328 /// support accounts associated with the native mint, use `CloseAccount`
329 /// instead.
330 ///
331 /// This instruction differs from Burn in that the decimals value is checked
332 /// by the caller. This may be useful when creating transactions offline or
333 /// within a hardware wallet.
334 ///
335 /// Accounts expected by this instruction:
336 ///
337 /// * Single owner/delegate
338 /// 0. `[writable]` The account to burn from.
339 /// 1. `[writable]` The token mint.
340 /// 2. `[signer]` The account's owner/delegate.
341 ///
342 /// * Multisignature owner/delegate
343 /// 0. `[writable]` The account to burn from.
344 /// 1. `[writable]` The token mint.
345 /// 2. `[]` The account's multisignature owner/delegate.
346 /// 3. ..3+M `[signer]` M signer accounts.
347 BurnChecked {
348 /// The amount of tokens to burn.
349 amount: u64,
350 /// Expected number of base 10 digits to the right of the decimal place.
351 decimals: u8,
352 },
353
354 /// Like InitializeAccount, but the owner pubkey is passed via instruction
355 /// data rather than the accounts list. This variant may be preferable
356 /// when using Cross Program Invocation from an instruction that does
357 /// not need the owner's `AccountInfo` otherwise.
358 ///
359 /// Accounts expected by this instruction:
360 ///
361 /// 0. `[writable]` The account to initialize.
362 /// 1. `[]` The mint this account will be associated with.
363 /// 3. `[]` Rent sysvar
364 InitializeAccount2 {
365 /// The new account's owner/multisignature.
366 owner: Pubkey,
367 },
368
369 /// Given a wrapped / native token account (a token account containing SOL)
370 /// updates its amount field based on the account's underlying `lamports`.
371 /// This is useful if a non-wrapped SOL account uses
372 /// `system_instruction::transfer` to move lamports to a wrapped token
373 /// account, and needs to have its token `amount` field updated.
374 ///
375 /// Accounts expected by this instruction:
376 ///
377 /// 0. `[writable]` The native token account to sync with its underlying
378 /// lamports.
379 SyncNative,
380
381 /// Like InitializeAccount2, but does not require the Rent sysvar to be
382 /// provided
383 ///
384 /// Accounts expected by this instruction:
385 ///
386 /// 0. `[writable]` The account to initialize.
387 /// 1. `[]` The mint this account will be associated with.
388 InitializeAccount3 {
389 /// The new account's owner/multisignature.
390 owner: Pubkey,
391 },
392
393 /// Like InitializeMultisig, but does not require the Rent sysvar to be
394 /// provided
395 ///
396 /// Accounts expected by this instruction:
397 ///
398 /// 0. `[writable]` The multisignature account to initialize.
399 /// 1. ..1+N. `[]` The signer accounts, must equal to N where 1 <= N <=
400 /// 11.
401 InitializeMultisig2 {
402 /// The number of signers (M) required to validate this multisignature
403 /// account.
404 m: u8,
405 },
406
407 /// Like [`InitializeMint`], but does not require the Rent sysvar to be
408 /// provided
409 ///
410 /// Accounts expected by this instruction:
411 ///
412 /// 0. `[writable]` The mint to initialize.
413 InitializeMint2 {
414 /// Number of base 10 digits to the right of the decimal place.
415 decimals: u8,
416 /// The authority/multisignature to mint tokens.
417 mint_authority: Pubkey,
418 /// The freeze authority/multisignature of the mint.
419 freeze_authority: Option<Pubkey>,
420 },
421
422 /// Gets the required size of an account for the given mint as a
423 /// little-endian `u64`.
424 ///
425 /// Return data can be fetched using `sol_get_return_data` and deserializing
426 /// the return data as a little-endian `u64`.
427 ///
428 /// Accounts expected by this instruction:
429 ///
430 /// 0. `[]` The mint to calculate for
431 GetAccountDataSize, // typically, there's also data, but this program ignores it
432
433 /// Initialize the Immutable Owner extension for the given token account
434 ///
435 /// Fails if the account has already been initialized, so must be called
436 /// before `InitializeAccount`.
437 ///
438 /// No-ops in this version of the program, but is included for compatibility
439 /// with the Associated Token Account program.
440 ///
441 /// Accounts expected by this instruction:
442 ///
443 /// 0. `[writable]` The account to initialize.
444 ///
445 /// Data expected by this instruction:
446 /// None
447 InitializeImmutableOwner,
448
449 /// Convert an Amount of tokens to a UiAmount `string`, using the given
450 /// mint. In this version of the program, the mint can only specify the
451 /// number of decimals.
452 ///
453 /// Fails on an invalid mint.
454 ///
455 /// Return data can be fetched using `sol_get_return_data` and deserialized
456 /// with `String::from_utf8`.
457 ///
458 /// Accounts expected by this instruction:
459 ///
460 /// 0. `[]` The mint to calculate for
461 AmountToUiAmount {
462 /// The amount of tokens to reformat.
463 amount: u64,
464 },
465
466 /// Convert a UiAmount of tokens to a little-endian `u64` raw Amount, using
467 /// the given mint. In this version of the program, the mint can only
468 /// specify the number of decimals.
469 ///
470 /// Return data can be fetched using `sol_get_return_data` and deserializing
471 /// the return data as a little-endian `u64`.
472 ///
473 /// Accounts expected by this instruction:
474 ///
475 /// 0. `[]` The mint to calculate for
476 UiAmountToAmount {
477 /// The ui_amount of tokens to reformat.
478 ui_amount: &'a str,
479 },
480 // Any new variants also need to be added to program-2022 `TokenInstruction`, so that the
481 // latter remains a superset of this instruction set. New variants also need to be added to
482 // token/js/src/instructions/types.ts to maintain @solana/spl-token compatibility
483}
484
485/// Specifies the authority type for `SetAuthority` instructions
486#[repr(u8)]
487#[derive(Clone, Debug, PartialEq)]
488pub enum AuthorityType {
489 /// Authority to mint new tokens
490 MintTokens,
491 /// Authority to freeze any account associated with the Mint
492 FreezeAccount,
493 /// Owner of a given token account
494 AccountOwner,
495 /// Authority to close a token account
496 CloseAccount,
497}
498
499impl AuthorityType {
500 pub fn into(&self) -> u8 {
501 match self {
502 AuthorityType::MintTokens => 0,
503 AuthorityType::FreezeAccount => 1,
504 AuthorityType::AccountOwner => 2,
505 AuthorityType::CloseAccount => 3,
506 }
507 }
508
509 pub fn from(index: u8) -> Result<Self, ProgramError> {
510 match index {
511 0 => Ok(AuthorityType::MintTokens),
512 1 => Ok(AuthorityType::FreezeAccount),
513 2 => Ok(AuthorityType::AccountOwner),
514 3 => Ok(AuthorityType::CloseAccount),
515 _ => Err(TokenError::InvalidInstruction.into()),
516 }
517 }
518}