lib.rs 27 KB

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