extern crate proc_macro; use proc_macro::TokenStream; use quote::ToTokens; use syn::parse_macro_input; /// Implements an [`Accounts`](./trait.Accounts.html) deserializer on the given /// struct. Can provide further functionality through the use of attributes. /// /// # Table of Contents /// - [Instruction Attribute](#instruction-attribute) /// - [Constraints](#constraints) /// /// # Instruction Attribute /// /// You can access the instruction's arguments with the /// `#[instruction(..)]` attribute. You have to list them /// in the same order as in the instruction but you can /// omit all arguments after the last one you need. /// /// # Example /// /// ```ignore /// ... /// pub fn initialize(ctx: Context, bump: u8, authority: Pubkey, data: u64) -> anchor_lang::Result<()> { /// ... /// Ok(()) /// } /// ... /// #[derive(Accounts)] /// #[instruction(bump: u8)] /// pub struct Initialize<'info> { /// ... /// } /// ``` /// /// # Constraints /// /// There are different types of constraints that can be applied with the `#[account(..)]` attribute. /// /// Attributes may reference other data structures. When `` is used in the tables below, an arbitrary expression /// may be passed in as long as it evaluates to a value of the expected type, e.g. `owner = token_program.key()`. If `target_account` /// used, the `target_account` must exist in the struct and the `.key()` is implicit, e.g. `payer = authority`. /// /// - [Normal Constraints](#normal-constraints) /// - [SPL Constraints](#spl-constraints) /// # Normal Constraints /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ///
AttributeDescription
/// #[account(signer)]

#[account(signer @ <custom_error>)] ///
/// Checks the given account signed the transaction.
/// Custom errors are supported via @.
/// Consider using the Signer type if you would only have this constraint on the account.

/// Example: ///

/// #[account(signer)]
/// pub authority: AccountInfo<'info>,
/// #[account(signer @ MyError::MyErrorCode)]
/// pub payer: AccountInfo<'info>
///                 
///
/// #[account(mut)]

#[account(mut @ <custom_error>)] ///
/// Checks the given account is mutable.
/// Makes anchor persist any state changes.
/// Custom errors are supported via @.

/// Example: ///

/// #[account(mut)]
/// pub data_account: Account<'info, MyData>,
/// #[account(mut @ MyError::MyErrorCode)]
/// pub data_account_two: Account<'info, MyData>
///                 
///
/// #[account(init, payer = <target_account>, space = <num_bytes>)] /// /// Creates the account via a CPI to the system program and /// initializes it (sets its account discriminator).
/// Marks the account as mutable and is mutually exclusive with mut.
/// Makes the account rent exempt unless skipped with rent_exempt = skip.

/// Use #[account(zero)] for accounts larger than 10 Kibibyte.

/// init has to be used with additional constraints: ///
    ///
  • /// Requires the payer constraint to also be on the account. /// The payer account pays for the /// account creation. ///
  • ///
  • /// Requires the system program to exist on the struct /// and be called system_program. ///
  • ///
  • /// Requires that the space constraint is specified. /// When using the space constraint, one must remember to add 8 to it /// which is the size of the account discriminator. This only has to be done /// for accounts owned by anchor programs.
    /// The given space number is the size of the account in bytes, so accounts that hold /// a variable number of items such as a Vec should allocate sufficient space for all items that may /// be added to the data structure because account size is fixed. /// Check out the space reference /// and the borsh library /// (which anchor uses under the hood for serialization) specification to learn how much /// space different data structures require. ///
  • ///
    /// Example: ///
    /// #[account]
    /// pub struct MyData {
    ///     pub data: u64
    /// }
    
    /// #[derive(Accounts)]
    /// pub struct Initialize<'info> {
    ///     #[account(init, payer = payer, space = 8 + 8)]
    ///     pub data_account_two: Account<'info, MyData>,
    ///     #[account(mut)]
    ///     pub payer: Signer<'info>,
    ///     pub system_program: Program<'info, System>,
    /// }
    ///                 
    ///
/// init can be combined with other constraints (at the same time): ///
    ///
  • /// By default init sets the owner field of the created account to the /// currently executing program. Add the owner constraint to specify a /// different program owner. ///
  • ///
  • /// Use the seeds constraint together with bumpto create PDAs.
    /// init uses find_program_address to calculate the pda so the /// bump value can be left empty.
    /// However, if you want to use the bump in your instruction, /// you can pass it in as instruction data and set the bump value like shown in the example, /// using the instruction_data attribute. /// Anchor will then check that the bump returned by find_program_address equals /// the bump in the instruction data.
    /// seeds::program cannot be used together with init because the creation of an /// account requires its signature which for PDAs only the currently executing program can provide. ///
  • ///
/// Example: ///
/// #[derive(Accounts)]
/// #[instruction(bump: u8)]
/// pub struct Initialize<'info> {
///     #[account(
///         init, payer = payer, space = 8 + 8
///         seeds = [b"example_seed"], bump = bump
///     )]
///     pub pda_data_account: Account<'info, MyData>,
///     #[account(
///         init, payer = payer,
///         space = 8 + 8, owner = other_program.key()
///     )]
///     pub account_for_other_program: AccountInfo<'info>,
///     #[account(
///         init, payer = payer, space = 8 + 8,
///         owner = other_program.key(),
///         seeds = [b"other_seed"], bump
///     )]
///     pub pda_for_other_program: AccountInfo<'info>,
///     #[account(mut)]
///     pub payer: Signer<'info>,
///     pub system_program: Program<'info, System>,
///     pub other_program: Program<'info, OtherProgram>
/// }
///                 
///
/// #[account(init_if_needed, payer = <target_account>)]

/// #[account(init_if_needed, payer = <target_account>, space = <num_bytes>)] ///
/// Exact same functionality as the init constraint but only runs if the account does not exist yet.
/// If the account does exist, it still checks whether the given init constraints are correct, /// e.g. that the account has the expected amount of space and, if it's a PDA, the correct seeds etc.

/// This feature should be used with care and is therefore behind a feature flag. /// You can enable it by importing anchor-lang with the init-if-needed cargo feature.
/// When using init_if_needed, you need to make sure you properly protect yourself /// against re-initialization attacks. You need to include checks in your code that check /// that the initialized account cannot be reset to its initial settings after the first time it was /// initialized (unless that it what you want).
/// Because of the possibility of re-initialization attacks and the general guideline that instructions /// should avoid having multiple execution flows (which is important so they remain easy to understand), /// consider breaking up your instruction into two instructions - one for initializing and one for using /// the account - unless you have a good reason not to do so. ///

/// Example: ///
/// #[account]
/// #[derive(Default)]
/// pub struct MyData {
///     pub data: u64
/// }

/// #[account]
/// pub struct OtherData {
///     pub data: u64
/// }

/// #[derive(Accounts)]
/// pub struct Initialize<'info> {
///     #[account(init_if_needed, payer = payer)]
///     pub data_account: Account<'info, MyData>,
///     #[account(init_if_needed, payer = payer, space = 8 + 8)]
///     pub data_account_two: Account<'info, OtherData>,
///     #[account(mut)]
///     pub payer: Signer<'info>,
///     pub system_program: Program<'info, System>
/// }
///                 
///
/// #[account(seeds = <seeds>, bump)]

/// #[account(seeds = <seeds>, bump, seeds::program = <expr>)]

/// #[account(seeds = <seeds>, bump = <expr>)]

/// #[account(seeds = <seeds>, bump = <expr>, seeds::program = <expr>)]

///
/// Checks that given account is a PDA derived from the currently executing program, /// the seeds, and if provided, the bump. If not provided, anchor uses the canonical /// bump.
/// Add seeds::program = <expr> to derive the PDA from a different /// program than the currently executing one.
/// This constraint behaves slightly differently when used with init. /// See its description. ///

/// Example: ///

/// #[derive(Accounts)]
/// #[instruction(first_bump: u8, second_bump: u8)]
/// pub struct Example {
///     #[account(seeds = [b"example_seed"], bump)]
///     pub canonical_pda: AccountInfo<'info>,
///     #[account(
///         seeds = [b"example_seed"],
///         bump,
///         seeds::program = other_program.key()
///     )]
///     pub canonical_pda_two: AccountInfo<'info>,
///     #[account(seeds = [b"other_seed"], bump = first_bump)]
///     pub arbitrary_pda: AccountInfo<'info>
///     #[account(
///         seeds = [b"other_seed"],
///         bump = second_bump,
///         seeds::program = other_program.key()
///     )]
///     pub arbitrary_pda_two: AccountInfo<'info>,
///     pub other_program: Program<'info, OtherProgram>
/// }
///                 
///
/// #[account(has_one = <target_account>)]

/// #[account(has_one = <target_account> @ <custom_error>)] ///
/// Checks the target_account field on the account matches the /// key of the target_account field in the Accounts struct.
/// Custom errors are supported via @.

/// Example: ///

/// #[account(mut, has_one = authority)]
/// pub data: Account<'info, MyData>,
/// pub authority: Signer<'info>
///                 
/// In this example has_one checks that data.authority = authority.key() ///
/// #[account(address = <expr>)]

/// #[account(address = <expr> @ <custom_error>)] ///
/// Checks the account key matches the pubkey.
/// Custom errors are supported via @.

/// Example: ///

/// #[account(address = crate::ID)]
/// pub data: Account<'info, MyData>,
/// #[account(address = crate::ID @ MyError::MyErrorCode)]
/// pub data_two: Account<'info, MyData>
///                 
///
/// #[account(owner = <expr>)]

/// #[account(owner = <expr> @ <custom_error>)] ///
/// Checks the account owner matches expr.
/// Custom errors are supported via @.

/// Example: ///

/// #[account(owner = Token::ID @ MyError::MyErrorCode)]
/// pub data: Account<'info, MyData>,
/// #[account(owner = token_program.key())]
/// pub data_two: Account<'info, MyData>,
/// pub token_program: Program<'info, Token>
///                 
///
/// #[account(executable)] /// /// Checks the account is executable (i.e. the account is a program).
/// You may want to use the Program type instead.

/// Example: ///

/// #[account(executable)]
/// pub my_program: AccountInfo<'info>
///                 
///
/// #[account(rent_exempt = skip)]

/// #[account(rent_exempt = enforce)] ///
/// Enforces rent exemption with = enforce.
/// Skips rent exemption check that would normally be done /// through other constraints with = skip, /// e.g. when used with the zero constraint

/// Example: ///

/// #[account(zero, rent_exempt = skip)]
/// pub skipped_account: Account<'info, MyData>,
/// #[account(rent_exempt = enforce)]
/// pub enforced_account: AccountInfo<'info>
///                 
///
/// #[account(zero)] /// /// Checks the account discriminator is zero.
/// Enforces rent exemption unless skipped with rent_exempt = skip.

/// Use this constraint if you want to create an account in a previous instruction /// and then initialize it in your instruction instead of using init. /// This is necessary for accounts that are larger than 10 Kibibyte because those /// accounts cannot be created via a CPI (which is what init would do).

/// Anchor adds internal data to the account when using zero just like it /// does with init which is why zero implies mut. ///

/// Example: ///

/// #[account(zero)]
/// pub my_account: Account<'info, MyData>
///                 
///
/// #[account(close = <target_account>)] /// /// Marks the account as closed at the end of the instruction’s execution /// (sets its discriminator to the CLOSED_ACCOUNT_DISCRIMINATOR) /// and sends its lamports to the specified account.
/// Setting the discriminator to a special variant /// makes account revival attacks (where a subsequent instruction /// adds the rent exemption lamports again) impossible.
/// Requires mut to exist on the account. ///

/// Example: ///

/// #[account(mut, close = receiver)]
/// pub data_account: Account<'info, MyData>,
/// #[account(mut)]
/// pub receiver: SystemAccount<'info>
///                 
///
/// #[account(constraint = <expr>)]

#[account(constraint = <expr> @ <custom_error>)] ///
/// Constraint that checks whether the given expression evaluates to true.
/// Use this when no other constraint fits your use case. ///

/// Example: ///

/// #[account(constraint = one.keys[0].age == two.apple.age)]
/// pub one: Account<'info, MyData>,
/// pub two: Account<'info, OtherData>
///                 
///
/// /// # SPL Constraints /// /// Anchor provides constraints that make verifying SPL accounts easier. /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// ///
AttributeDescription
/// #[account(token::mint = <target_account>, token::authority = <target_account>)] /// /// Can be used as a check or with init to create a token /// account with the given mint address and authority.
/// When used as a check, it's possible to only specify a subset of the constraints. ///

/// Example: ///
/// use anchor_spl::{mint, token::{TokenAccount, Mint, Token}};
/// ...

/// #[account(
///     init,
///     payer = payer,
///     token::mint = mint,
///     token::authority = payer,
/// )]
/// pub token: Account<'info, TokenAccount>,
/// #[account(address = mint::USDC)]
/// pub mint: Account<'info, Mint>,
/// #[account(mut)]
/// pub payer: Signer<'info>,
/// pub token_program: Program<'info, Token>,
/// pub system_program: Program<'info, System>
///                 
///
/// #[account(mint::authority = <target_account>, mint::decimals = <expr>)] ///

/// #[account(mint::authority = <target_account>, mint::decimals = <expr>, mint::freeze_authority = <target_account>)] ///
/// Can be used as a check or with init to create a mint /// account with the given mint decimals and mint authority.
/// The freeze authority is optional when used with init.
/// When used as a check, it's possible to only specify a subset of the constraints. ///

/// Example: ///
/// use anchor_spl::token::{Mint, Token};
/// ...

/// #[account(
///     init,
///     payer = payer,
///     mint::decimals = 9,
///     mint::authority = payer,
/// )]
/// pub mint_one: Account<'info, Mint>,
/// #[account(
///     init,
///     payer = payer,
///     mint::decimals = 9,
///     mint::authority = payer,
///     mint::freeze_authority = payer
/// )]
/// pub mint_two: Account<'info, Mint>,
/// #[account(mut)]
/// pub payer: Signer<'info>,
/// pub token_program: Program<'info, Token>,
/// pub system_program: Program<'info, System>
///                 
///
/// #[account(associated_token::mint = <target_account>, associated_token::authority = <target_account>)] /// /// Can be used as a standalone as a check or with init to create an associated token /// account with the given mint address and authority. ///

/// Example: ///
/// use anchor_spl::{
///     associated_token::AssociatedToken,
///     mint,
///     token::{TokenAccount, Mint, Token}
/// };
/// ...

/// #[account(
///     init,
///     payer = payer,
///     associated_token::mint = mint,
///     associated_token::authority = payer,
/// )]
/// pub token: Account<'info, TokenAccount>,
/// #[account(
///     associated_token::mint = mint,
///     associated_token::authority = payer,
/// )]
/// pub second_token: Account<'info, TokenAccount>,
/// #[account(address = mint::USDC)]
/// pub mint: Account<'info, Mint>,
/// #[account(mut)]
/// pub payer: Signer<'info>,
/// pub token_program: Program<'info, Token>,
/// pub associated_token_program: Program<'info, AssociatedToken>,
/// pub system_program: Program<'info, System>
///                 
///
#[proc_macro_derive(Accounts, attributes(account, instruction))] pub fn derive_anchor_deserialize(item: TokenStream) -> TokenStream { parse_macro_input!(item as anchor_syn::AccountsStruct) .to_token_stream() .into() }