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}