Skip to main content

anchor_derive_accounts/
lib.rs

1extern crate proc_macro;
2
3use {proc_macro::TokenStream, quote::ToTokens, syn::parse_macro_input};
4
5/// Implements an [`Accounts`](./trait.Accounts.html) deserializer on the given
6/// struct. Can provide further functionality through the use of attributes.
7///
8/// # Table of Contents
9/// - [Instruction Attribute](#instruction-attribute)
10/// - [Constraints](#constraints)
11///
12/// # Instruction Attribute
13///
14/// You can access the instruction's arguments with the
15/// `#[instruction(..)]` attribute. You have to list them
16/// in the same order as in the instruction but you can
17/// omit all arguments after the last one you need.
18///
19/// # Example
20///
21/// ```ignore
22/// ...
23/// pub fn initialize(ctx: Context<Create>, bump: u8, authority: Pubkey, data: u64) -> anchor_lang::Result<()> {
24///     ...
25///     Ok(())
26/// }
27/// ...
28/// #[derive(Accounts)]
29/// #[instruction(bump: u8)]
30/// pub struct Initialize<'info> {
31///     ...
32/// }
33/// ```
34///
35/// # Constraints
36///
37/// There are different types of constraints that can be applied with the `#[account(..)]` attribute.
38///
39/// Attributes may reference other data structures. When `<expr>` is used in the tables below, an arbitrary expression
40/// 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`
41/// used, the `target_account` must exist in the struct and the `.key()` is implicit, e.g. `payer = authority`.
42///
43/// - [Normal Constraints](#normal-constraints)
44/// - [SPL Constraints](#spl-constraints)
45///
46/// # Normal Constraints
47/// <table>
48///     <thead>
49///         <tr>
50///             <th>Attribute</th>
51///             <th>Description</th>
52///         </tr>
53///     </thead>
54///     <tbody>
55///         <tr>
56///             <td>
57///                 <code>#[account(signer)]</code> <br><br><code>#[account(signer @ &lt;custom_error&gt;)]</code>
58///             </td>
59///             <td>
60///                 Checks the given account signed the transaction.<br>
61///                 Custom errors are supported via <code>@</code>.<br>
62///                 Consider using the <code>Signer</code> type if you would only have this constraint on the account.<br><br>
63///                 Example:
64///                 <pre><code>
65/// #[account(signer)]
66/// pub authority: AccountInfo&lt;'info&gt;,
67/// #[account(signer @ MyError::MyErrorCode)]
68/// pub payer: AccountInfo&lt;'info&gt;
69///                 </code></pre>
70///             </td>
71///         </tr>
72///         <tr>
73///             <td>
74///                 <code>#[account(mut)]</code> <br><br><code>#[account(mut @ &lt;custom_error&gt;)]</code>
75///             </td>
76///             <td>
77///                 Checks the given account is mutable.<br>
78///                 Makes anchor persist any state changes.<br>
79///                 Custom errors are supported via <code>@</code>.<br><br>
80///                 Example:
81///                 <pre><code>
82/// #[account(mut)]
83/// pub data_account: Account&lt;'info, MyData&gt;,
84/// #[account(mut @ MyError::MyErrorCode)]
85/// pub data_account_two: Account&lt;'info, MyData&gt;
86///                 </code></pre>
87///             </td>
88///         </tr>
89///         <tr>
90///             <td>
91///                 <code>#[account(dup)]</code> <br><br>
92///             </td>
93///             <td>
94///                 Allows the same mutable account to be passed multiple times within the same instruction context.<br>
95///                 By default, Anchor will prevents duplicate mutable accounts to avoid potential security issues and unintended behavior.<br>
96///                 The <code>dup</code> constraint explicitly allows this for cases where it's intentional and safe.<br>
97///                 This constraint only applies to mutable account (`mut`) types that serialize on exit. Other types like <br>
98///                `UncheckedAccount`, `Signer`, `SystemAccount`, `AccountLoader`, `Program`, `Interface` and Readonly accounts <br>
99///                 naturally allow duplicates as they don't serialize data on exit.<br>
100///                 Example:
101///                 <pre><code>
102/// #[account(mut)]
103/// pub account1: Account&lt;'info, Counter&gt;,
104///                 </code></pre>
105///             </td>
106///         </tr>
107///         <tr>
108///             <td>
109///                 <code>#[account(init, payer = &lt;target_account&gt;, space = &lt;num_bytes&gt;)]</code>
110///             </td>
111///             <td>
112///                 Creates the account via a CPI to the system program and
113///                 initializes it (sets its account discriminator). The annotated account is required to sign for this instruction
114///                 unless `seeds` is provided. <br>
115///                 Marks the account as mutable and is mutually exclusive with <code>mut</code>.<br>
116///                 Makes the account rent exempt unless skipped with <code>rent_exempt = skip</code>.<br><br>
117///                 Use <code>#[account(zero)]</code> for accounts larger than 10 Kibibyte.<br><br>
118///                 <code>init</code> has to be used with additional constraints:
119///                 <ul>
120///                     <li>
121///                         Requires the <code>payer</code> constraint to also be on the account.
122///                         The <code>payer</code> account pays for the
123///                         account creation.
124///                     </li>
125///                     <li>
126///                         Requires the system program to exist on the struct
127///                         and be called <code>system_program</code>.
128///                     </li>
129///                     <li>
130///                         Requires that the <code>space</code> constraint is specified.
131///                         When using the <code>space</code> constraint, one must remember to add 8 to it
132///                         which is the size of the account discriminator. This only has to be done
133///                         for accounts owned by anchor programs.<br>
134///                         The given space number is the size of the account in bytes, so accounts that hold
135///                         a variable number of items such as a <code>Vec</code> should allocate sufficient space for all items that may
136///                         be added to the data structure because account size is fixed.
137///                         Check out the <a href = "https://www.anchor-lang.com/docs/space" target = "_blank" rel = "noopener noreferrer">space reference</a>
138///                         and the <a href = "https://borsh.io/" target = "_blank" rel = "noopener noreferrer">borsh library</a>
139///                         (which anchor uses under the hood for serialization) specification to learn how much
140///                         space different data structures require.
141///                     </li>
142///                 <br>
143///                 Example:
144///                 <pre>
145/// #[account]
146/// pub struct MyData {
147/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
148/// }&#10;
149/// #[derive(Accounts)]
150/// pub struct Initialize&lt;'info&gt; {
151/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init, payer = payer, space = 8 + 8)]
152/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account_two: Account&lt;'info, MyData&gt;,
153/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(mut)]
154/// &nbsp;&nbsp;&nbsp;&nbsp;pub payer: Signer&lt;'info&gt;,
155/// &nbsp;&nbsp;&nbsp;&nbsp;pub system_program: Program&lt;'info, System&gt;,
156/// }
157///                 </pre>
158///                 </ul>
159///                 <code>init</code> can be combined with other constraints (at the same time):
160///                 <ul>
161///                     <li>
162///                         By default <code>init</code> sets the owner field of the created account to the
163///                         currently executing program. Add the <code>owner</code> constraint to specify a
164///                         different program owner.
165///                     </li>
166///                     <li>
167///                         Use the <code>seeds</code> constraint together with <code>bump</code>to create PDAs.<br>
168///                         <code>init</code> uses <code>find_program_address</code> to calculate the pda so the
169///                         bump value can be left empty.<br>
170///                         However, if you want to use the bump in your instruction,
171///                         you can pass it in as instruction data and set the bump value like shown in the example,
172///                         using the <code>instruction_data</code> attribute.
173///                         Anchor will then check that the bump returned by <code>find_program_address</code> equals
174///                         the bump in the instruction data.<br>
175///                         <code>seeds::program</code> cannot be used together with init because the creation of an
176///                         account requires its signature which for PDAs only the currently executing program can provide.
177///                     </li>
178///                 </ul>
179///                 Example:
180///                 <pre>
181/// #[derive(Accounts)]
182/// #[instruction(bump: u8)]
183/// pub struct Initialize&lt;'info&gt; {
184/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
185/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer, space = 8 + 8
186/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seeds = [b"example_seed"], bump = bump
187/// &nbsp;&nbsp;&nbsp;&nbsp;)]
188/// &nbsp;&nbsp;&nbsp;&nbsp;pub pda_data_account: Account&lt;'info, MyData&gt;,
189/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
190/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer,
191/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;space = 8 + 8, owner = other_program.key()
192/// &nbsp;&nbsp;&nbsp;&nbsp;)]
193/// &nbsp;&nbsp;&nbsp;&nbsp;pub account_for_other_program: AccountInfo&lt;'info&gt;,
194/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(
195/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init, payer = payer, space = 8 + 8,
196/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;owner = other_program.key(),
197/// &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seeds = [b"other_seed"], bump
198/// &nbsp;&nbsp;&nbsp;&nbsp;)]
199/// &nbsp;&nbsp;&nbsp;&nbsp;pub pda_for_other_program: AccountInfo&lt;'info&gt;,
200/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(mut)]
201/// &nbsp;&nbsp;&nbsp;&nbsp;pub payer: Signer&lt;'info&gt;,
202/// &nbsp;&nbsp;&nbsp;&nbsp;pub system_program: Program&lt;'info, System&gt;,
203/// &nbsp;&nbsp;&nbsp;&nbsp;pub other_program: Program&lt;'info, OtherProgram&gt;
204/// }
205///                 </pre>
206///             </td>
207///         </tr>
208///         <tr>
209///             <td>
210///                 <code>#[account(init_if_needed, payer = &lt;target_account&gt;)]</code><br><br>
211///                 <code>#[account(init_if_needed, payer = &lt;target_account&gt;, space = &lt;num_bytes&gt;)]</code>
212///             </td>
213///             <td>
214///                 Exact same functionality as the <code>init</code> constraint but only runs if the account does not exist yet.<br>
215///                 If the account does exist, it still checks whether the given init constraints are correct,
216///                 e.g. that the account has the expected amount of space and, if it's a PDA, the correct seeds etc.<br><br>
217///                 This feature should be used with care and is therefore behind a feature flag.
218///                 You can enable it by importing <code>anchor-lang</code> with the <code>init-if-needed</code> cargo feature.<br>
219///                 When using <code>init_if_needed</code>, you need to make sure you properly protect yourself
220///                 against re-initialization attacks. You need to include checks in your code that check
221///                 that the initialized account cannot be reset to its initial settings after the first time it was
222///                 initialized (unless that it what you want).<br>
223///                 Because of the possibility of re-initialization attacks and the general guideline that instructions
224///                 should avoid having multiple execution flows (which is important so they remain easy to understand),
225///                 consider breaking up your instruction into two instructions - one for initializing and one for using
226///                 the account - unless you have a good reason not to do so.
227///                 <br><br>
228///                 Example:
229///                 <pre>
230/// #[account]
231/// #[derive(Default)]
232/// pub struct MyData {
233/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
234/// }&#10;
235/// #[account]
236/// pub struct OtherData {
237/// &nbsp;&nbsp;&nbsp;&nbsp;pub data: u64
238/// }&#10;
239/// #[derive(Accounts)]
240/// pub struct Initialize&lt;'info&gt; {
241/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init_if_needed, payer = payer)]
242/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account: Account&lt;'info, MyData&gt;,
243/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(init_if_needed, payer = payer, space = 8 + 8)]
244/// &nbsp;&nbsp;&nbsp;&nbsp;pub data_account_two: Account&lt;'info, OtherData&gt;,
245/// &nbsp;&nbsp;&nbsp;&nbsp;#[account(mut)]
246/// &nbsp;&nbsp;&nbsp;&nbsp;pub payer: Signer&lt;'info&gt;,
247/// &nbsp;&nbsp;&nbsp;&nbsp;pub system_program: Program&lt;'info, System&gt;
248/// }
249///                 </pre>
250///             </td>
251///         </tr>
252///         <tr>
253///             <td>
254///                 <code>#[account(seeds = &lt;seeds&gt;, bump)]</code><br><br>
255///                 <code>#[account(seeds = &lt;seeds&gt;, bump, seeds::program = &lt;expr&gt;)]</code><br><br>
256///                 <code>#[account(seeds = &lt;seeds&gt;, bump = &lt;expr&gt;)]</code><br><br>
257///                 <code>#[account(seeds = &lt;seeds&gt;, bump = &lt;expr&gt;, seeds::program = &lt;expr&gt;)]</code><br><br>
258///             </td>
259///             <td>
260///                 Checks that given account is a PDA derived from the currently executing program,
261///                 the seeds, and if provided, the bump. If not provided, anchor uses the canonical
262///                 bump. <br>
263///                 Add <code>seeds::program = &lt;expr&gt;</code> to derive the PDA from a different
264///                 program than the currently executing one.<br>
265///                 This constraint behaves slightly differently when used with <code>init</code>.
266///                 See its description.
267///                 <br><br>
268///                 Example:
269///                 <pre><code>
270/// #[derive(Accounts)]
271/// #[instruction(first_bump: u8, second_bump: u8)]
272/// pub struct Example {
273///     #[account(seeds = [b"example_seed"], bump)]
274///     pub canonical_pda: AccountInfo&lt;'info&gt;,
275///     #[account(
276///         seeds = [b"example_seed"],
277///         bump,
278///         seeds::program = other_program.key()
279///     )]
280///     pub canonical_pda_two: AccountInfo&lt;'info&gt;,
281///     #[account(seeds = [b"other_seed"], bump = first_bump)]
282///     pub arbitrary_pda: AccountInfo&lt;'info&gt;
283///     #[account(
284///         seeds = [b"other_seed"],
285///         bump = second_bump,
286///         seeds::program = other_program.key()
287///     )]
288///     pub arbitrary_pda_two: AccountInfo&lt;'info&gt;,
289///     pub other_program: Program&lt;'info, OtherProgram&gt;
290/// }
291///                 </code></pre>
292///             </td>
293///         </tr>
294///         <tr>
295///             <td>
296///                 <code>#[account(has_one = &lt;target_account&gt;)]</code><br><br>
297///                 <code>#[account(has_one = &lt;target_account&gt; @ &lt;custom_error&gt;)]</code>
298///             </td>
299///             <td>
300///                 Checks the <code>target_account</code> field on the account matches the
301///                 key of the <code>target_account</code> field in the Accounts struct.<br>
302///                 Custom errors are supported via <code>@</code>.<br><br>
303///                 Example:
304///                 <pre><code>
305/// #[account(mut, has_one = authority)]
306/// pub data: Account&lt;'info, MyData&gt;,
307/// pub authority: Signer&lt;'info&gt;
308///                 </code></pre>
309///                 In this example <code>has_one</code> checks that <code>data.authority = authority.key()</code>
310///             </td>
311///         </tr>
312///         <tr>
313///             <td>
314///                 <code>#[account(address = &lt;expr&gt;)]</code><br><br>
315///                 <code>#[account(address = &lt;expr&gt; @ &lt;custom_error&gt;)]</code>
316///             </td>
317///             <td>
318///                 Checks the account key matches the pubkey.<br>
319///                 Custom errors are supported via <code>@</code>.<br><br>
320///                 Example:
321///                 <pre><code>
322/// #[account(address = crate::ID)]
323/// pub data: Account&lt;'info, MyData&gt;,
324/// #[account(address = crate::ID @ MyError::MyErrorCode)]
325/// pub data_two: Account&lt;'info, MyData&gt;
326///                 </code></pre>
327///             </td>
328///         </tr>
329///         <tr>
330///             <td>
331///                 <code>#[account(owner = &lt;expr&gt;)]</code><br><br>
332///                 <code>#[account(owner = &lt;expr&gt; @ &lt;custom_error&gt;)]</code>
333///             </td>
334///             <td>
335///                 Checks the account owner matches <code>expr</code>.<br>
336///                 Custom errors are supported via <code>@</code>.<br><br>
337///                 Example:
338///                 <pre><code>
339/// #[account(owner = Token::ID @ MyError::MyErrorCode)]
340/// pub data: Account&lt;'info, MyData&gt;,
341/// #[account(owner = token_program.key())]
342/// pub data_two: Account&lt;'info, MyData&gt;,
343/// pub token_program: Program&lt;'info, Token&gt;
344///                 </code></pre>
345///             </td>
346///         </tr>
347///         <tr>
348///             <td>
349///                 <code>#[account(executable)]</code>
350///             </td>
351///             <td>
352///                 Checks the account is executable (i.e. the account is a program).<br>
353///                 You may want to use the <code>Program</code> type instead.<br><br>
354///                 Example:
355///                 <pre><code>
356/// #[account(executable)]
357/// pub my_program: AccountInfo&lt;'info&gt;
358///                 </code></pre>
359///             </td>
360///         </tr>
361///         <tr>
362///             <td>
363///                 <code>#[account(rent_exempt = skip)]</code><br><br>
364///                 <code>#[account(rent_exempt = enforce)]</code>
365///             </td>
366///             <td>
367///                 Enforces rent exemption with <code>= enforce</code>.<br>
368///                 Skips rent exemption check that would normally be done
369///                 through other constraints with <code>= skip</code>,
370///                 e.g. when used with the <code>zero</code> constraint<br><br>
371///                 Example:
372///                 <pre><code>
373/// #[account(zero, rent_exempt = skip)]
374/// pub skipped_account: Account&lt;'info, MyData&gt;,
375/// #[account(rent_exempt = enforce)]
376/// pub enforced_account: AccountInfo&lt;'info&gt;
377///                 </code></pre>
378///             </td>
379///         </tr>
380///         <tr>
381///             <td>
382///                 <code>#[account(zero)]</code>
383///             </td>
384///             <td>
385///                 Checks the account discriminator is zero.<br>
386///                 Enforces rent exemption unless skipped with <code>rent_exempt = skip</code>.<br><br>
387///                 Use this constraint if you want to create an account in a previous instruction
388///                 and then initialize it in your instruction instead of using <code>init</code>.
389///                 This is necessary for accounts that are larger than 10 Kibibyte because those
390///                 accounts cannot be created via a CPI (which is what <code>init</code> would do).<br><br>
391///                 Anchor adds internal data to the account when using <code>zero</code> just like it
392///                 does with <code>init</code> which is why <code>zero</code> implies <code>mut</code>.
393///                 <br><br>
394///                 Example:
395///                 <pre><code>
396/// #[account(zero)]
397/// pub my_account: Account&lt;'info, MyData&gt;
398///                 </code></pre>
399///             </td>
400///         </tr>
401///         <tr>
402///             <td>
403///                 <code>#[account(close = &lt;target_account&gt;)]</code>
404///             </td>
405///             <td>
406///                 Closes the account by:<br>
407///                 &nbsp;&nbsp;&nbsp;&nbsp;- Sending the lamports to the specified account<br>
408///                 &nbsp;&nbsp;&nbsp;&nbsp;- Assigning the owner to the System Program<br>
409///                 &nbsp;&nbsp;&nbsp;&nbsp;- Resetting the data of the account<br><br>
410///                 Requires <code>mut</code> to exist on the account.
411///                 <br><br>
412///                 Example:
413///                 <pre><code>
414/// #[account(mut, close = receiver)]
415/// pub data_account: Account&lt;'info, MyData&gt;,
416/// #[account(mut)]
417/// pub receiver: SystemAccount&lt;'info&gt;
418///                 </code></pre>
419///             </td>
420///         </tr>
421///         <tr>
422///             <td>
423///                 <code>#[account(constraint = &lt;expr&gt;)]</code><br><br><code>#[account(constraint = &lt;expr&gt; @ &lt;custom_error&gt;)]</code>
424///             </td>
425///             <td>
426///                 Constraint that checks whether the given expression evaluates to true.<br>
427///                 Use this when no other constraint fits your use case.
428///                 <br><br>
429///                 Example:
430///                 <pre><code>
431/// #[account(constraint = one.keys[0].age == two.apple.age)]
432/// pub one: Account&lt;'info, MyData&gt;,
433/// pub two: Account&lt;'info, OtherData&gt;
434///                 </code></pre>
435///             </td>
436///         </tr>
437///         <tr>
438///             <td>
439///                 <code>#[account(realloc = &lt;space&gt;, realloc::payer = &lt;target&gt;, realloc::zero = &lt;bool&gt;)]</code>
440///             </td>
441///             <td>
442///                 Used to <a href="https://docs.rs/solana-program/latest/solana_program/account_info/struct.AccountInfo.html#method.realloc" target = "_blank" rel = "noopener noreferrer">realloc</a>
443///                 program account space at the beginning of an instruction.
444///                 <br><br>
445///                 The account must be marked as <code>mut</code> and applied to either <code>Account</code> or <code>AccountLoader</code> types.
446///                 <br><br>
447///                 If the change in account data length is additive, lamports will be transferred from the <code>realloc::payer</code> into the
448///                 program account in order to maintain rent exemption. Likewise, if the change is subtractive, lamports will be transferred from
449///                 the program account back into the <code>realloc::payer</code>.
450///                 <br><br>
451///                 The <code>realloc::zero</code> constraint is required in order to determine whether the new memory should be zero initialized after
452///                 reallocation. Please read the documentation on the <code>AccountInfo::realloc</code> function linked above to understand the
453///                 caveats regarding compute units when providing <code>true</code> or <code>false</code> to this flag.
454///                 <br><br>
455///                 The manual use of `AccountInfo::realloc` is discouraged in favor of the `realloc` constraint group due to the lack of native runtime checks
456///                 to prevent reallocation over the `MAX_PERMITTED_DATA_INCREASE` limit (which can unintentionally cause account data overwrite other accounts).
457///                 The constraint group also ensure account reallocation idempotency but checking and restricting duplicate account reallocation within a single ix.
458///                 <br><br>
459///                 Example:
460///                 <pre>
461/// #[derive(Accounts)]
462/// pub struct Example {
463///     #[account(mut)]
464///     pub payer: Signer&lt;'info&gt;,
465///     #[account(
466///         mut,
467///         seeds = [b"example"],
468///         bump,
469///         realloc = 8 + std::mem::size_of::&lt;MyType&gt;() + 100,
470///         realloc::payer = payer,
471///         realloc::zero = false,
472///     )]
473///     pub acc: Account&lt;'info, MyType&gt;,
474///     pub system_program: Program&lt;'info, System&gt;,
475/// }
476///                 </pre>
477///             </td>
478///         </tr>
479///     </tbody>
480/// </table>
481///
482/// # SPL Constraints
483///
484/// Anchor provides constraints that make verifying SPL accounts easier.
485///
486/// <table>
487///     <thead>
488///         <tr>
489///             <th>Attribute</th>
490///             <th>Description</th>
491///         </tr>
492///     </thead>
493///     <tbody>
494///         <tr>
495///             <td>
496///                 <code>#[account(token::mint = &lt;target_account&gt;, token::authority = &lt;target_account&gt;)]</code>
497///             <br><br>
498///                 <code>#[account(token::mint = &lt;target_account&gt;, token::authority = &lt;target_account&gt;, token::token_program = &lt;target_account&gt;)]</code>
499///             </td>
500///             <td>
501///                 Can be used as a check or with <code>init</code> to create a token
502///                 account with the given mint address and authority.<br>
503///                  When used as a check, it's possible to only specify a subset of the constraints.
504///                 <br><br>
505///                 Example:
506///                 <pre>
507/// use anchor_spl::{mint, token::{TokenAccount, Mint, Token}};
508/// ...&#10;
509/// #[account(
510///     init,
511///     payer = payer,
512///     token::mint = mint,
513///     token::authority = payer,
514/// )]
515/// pub token: Account&lt;'info, TokenAccount&gt;,
516/// #[account(address = mint::USDC)]
517/// pub mint: Account&lt;'info, Mint&gt;,
518/// #[account(mut)]
519/// pub payer: Signer&lt;'info&gt;,
520/// pub token_program: Program&lt;'info, Token&gt;,
521/// pub system_program: Program&lt;'info, System&gt;
522///                 </pre>
523///             </td>
524///         </tr>
525///         <tr>
526///             <td>
527///                 <code>#[account(mint::authority = &lt;target_account&gt;, mint::decimals = &lt;expr&gt;)]</code>
528///                 <br><br>
529///                 <code>#[account(mint::authority = &lt;target_account&gt;, mint::decimals = &lt;expr&gt;, mint::freeze_authority = &lt;target_account&gt;)]</code>
530///             </td>
531///             <td>
532///                 Can be used as a check or with <code>init</code> to create a mint
533///                 account with the given mint decimals and mint authority.<br>
534///                 The freeze authority is optional when used with <code>init</code>.<br>
535///                 When used as a check, it's possible to only specify a subset of the constraints.
536///                 <br><br>
537///                 Example:
538///                 <pre>
539/// use anchor_spl::token::{Mint, Token};
540/// ...&#10;
541/// #[account(
542///     init,
543///     payer = payer,
544///     mint::decimals = 9,
545///     mint::authority = payer,
546/// )]
547/// pub mint_one: Account&lt;'info, Mint&gt;,
548/// #[account(
549///     init,
550///     payer = payer,
551///     mint::decimals = 9,
552///     mint::authority = payer,
553///     mint::freeze_authority = payer
554/// )]
555/// pub mint_two: Account&lt;'info, Mint&gt;,
556/// #[account(mut)]
557/// pub payer: Signer&lt;'info&gt;,
558/// pub token_program: Program&lt;'info, Token&gt;,
559/// pub system_program: Program&lt;'info, System&gt;
560///                 </pre>
561///             </td>
562///         </tr>
563///         <tr>
564///             <td>
565///                 <code>#[account(associated_token::mint = &lt;target_account&gt;, associated_token::authority = &lt;target_account&gt;)]</code>
566///                <br><br>
567///                 <code>#[account(associated_token::mint = &lt;target_account&gt;, associated_token::authority = &lt;target_account&gt;, associated_token::token_program = &lt;target_account&gt;)]</code>
568///             </td>
569///             <td>
570///                 Can be used as a standalone as a check or with <code>init</code> to create an associated token
571///                 account with the given mint address and authority.
572///                 <br><br>
573///                 Example:
574///                 <pre>
575/// use anchor_spl::{
576///     associated_token::AssociatedToken,
577///     mint,
578///     token::{TokenAccount, Mint, Token}
579/// };
580/// ...&#10;
581/// #[account(
582///     init,
583///     payer = payer,
584///     associated_token::mint = mint,
585///     associated_token::authority = payer,
586/// )]
587/// pub token: Account&lt;'info, TokenAccount&gt;,
588/// #[account(
589///     associated_token::mint = mint,
590///     associated_token::authority = payer,
591/// )]
592/// pub second_token: Account&lt;'info, TokenAccount&gt;,
593/// #[account(address = mint::USDC)]
594/// pub mint: Account&lt;'info, Mint&gt;,
595/// #[account(mut)]
596/// pub payer: Signer&lt;'info&gt;,
597/// pub token_program: Program&lt;'info, Token&gt;,
598/// pub associated_token_program: Program&lt;'info, AssociatedToken&gt;,
599/// pub system_program: Program&lt;'info, System&gt;
600///                 </pre>
601///             </td>
602///         </tr><tr>
603///             <td>
604///                 <code>#[account(*::token_program = &lt;target_account&gt;)]</code>
605///             </td>
606///             <td>
607///                 The <code>token_program</code> can optionally be overridden.
608///                 <br><br>
609///                 Example:
610///                 <pre>
611/// use anchor_spl::token_interface::{TokenInterface, TokenAccount, Mint};
612/// ...&#10;
613/// #[account(
614///     mint::token_program = token_a_token_program,
615/// )]
616/// pub token_a_mint: InterfaceAccount&lt;'info, Mint&gt;,
617/// #[account(
618///     mint::token_program = token_b_token_program,
619/// )]
620/// pub token_b_mint: InterfaceAccount&lt;'info, Mint&gt;,
621/// #[account(
622///     init,
623///     payer = payer,
624///     token::mint = token_a_mint,
625///     token::authority = payer,
626///     token::token_program = token_a_token_program,
627/// )]
628/// pub token_a_account: InterfaceAccount&lt;'info, TokenAccount&gt;,
629/// #[account(
630///     init,
631///     payer = payer,
632///     token::mint = token_b_mint,
633///     token::authority = payer,
634///     token::token_program = token_b_token_program,
635/// )]
636/// pub token_b_account: InterfaceAccount&lt;'info, TokenAccount&gt;,
637/// pub token_a_token_program: Interface&lt;'info, TokenInterface&gt;,
638/// pub token_b_token_program: Interface&lt;'info, TokenInterface&gt;,
639/// #[account(mut)]
640/// pub payer: Signer&lt;'info&gt;,
641/// pub system_program: Program&lt;'info, System&gt;
642///                 </pre>
643///             </td>
644///         </tr>
645///     </tbody>
646/// </table>
647#[proc_macro_derive(Accounts, attributes(account, instruction))]
648pub fn derive_accounts(item: TokenStream) -> TokenStream {
649    parse_macro_input!(item as anchor_syn::AccountsStruct)
650        .to_token_stream()
651        .into()
652}