anchor_attribute_program/
lib.rs

1extern crate proc_macro;
2
3mod declare_program;
4
5use declare_program::DeclareProgram;
6use quote::ToTokens;
7use syn::parse_macro_input;
8
9/// The `#[program]` attribute defines the module containing all instruction
10/// handlers defining all entries into a Solana program.
11#[proc_macro_attribute]
12pub fn program(
13    _args: proc_macro::TokenStream,
14    input: proc_macro::TokenStream,
15) -> proc_macro::TokenStream {
16    parse_macro_input!(input as anchor_syn::Program)
17        .to_token_stream()
18        .into()
19}
20
21/// Declare an external program based on its IDL.
22///
23/// The IDL of the program must exist in a directory named `idls`. This directory can be at any
24/// depth, e.g. both inside the program's directory (`<PROGRAM_DIR>/idls`) and inside Anchor
25/// workspace root directory (`<PROGRAM_DIR>/../../idls`) are valid.
26///
27/// # Usage
28///
29/// ```rs
30/// declare_program!(program_name);
31/// ```
32///
33/// This generates a module named `program_name` that can be used to interact with the program
34/// without having to add the program's crate as a dependency.
35///
36/// Both on-chain and off-chain usage is supported.
37///
38/// Use `cargo doc --open` to see the generated modules and their documentation.
39///
40/// # Note
41///
42/// Re-defining the same program to use the same definitions should be avoided since this results
43/// in a larger binary size.
44///
45/// A program should only be defined once. If you have multiple programs that depend on the same
46/// definition, you should consider creating a separate crate for the external program definition
47/// and reusing it in your programs.
48///
49/// # Example
50///
51/// A full on-chain CPI usage example can be found [here].
52///
53/// [here]: https://github.com/coral-xyz/anchor/tree/v0.31.1/tests/declare-program
54#[proc_macro]
55pub fn declare_program(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
56    parse_macro_input!(input as DeclareProgram)
57        .to_token_stream()
58        .into()
59}
60
61/// The `#[interface]` attribute is used to mark an instruction as belonging
62/// to an interface implementation, thus transforming its discriminator to the
63/// proper bytes for that interface instruction.
64///
65/// # Example
66///
67/// ```rust,ignore
68/// use anchor_lang::prelude::*;
69///
70/// // SPL Transfer Hook Interface: `Execute` instruction.
71/// //
72/// // This instruction is invoked by Token-2022 when a transfer occurs,
73/// // if a mint has specified this program as its transfer hook.
74/// #[interface(spl_transfer_hook_interface::execute)]
75/// pub fn execute_transfer(ctx: Context<Execute>, amount: u64) -> Result<()> {
76///     // Check that all extra accounts were provided
77///     let data = ctx.accounts.extra_metas_account.try_borrow_data()?;
78///     ExtraAccountMetaList::check_account_infos::<ExecuteInstruction>(
79///         &ctx.accounts.to_account_infos(),
80///         &TransferHookInstruction::Execute { amount }.pack(),
81///         &ctx.program_id,
82///         &data,
83///     )?;
84///
85///     // Or maybe perform some custom logic
86///     if ctx.accounts.token_metadata.mint != ctx.accounts.token_account.mint {
87///         return Err(ProgramError::IncorrectAccount);
88///     }
89///
90///     Ok(())
91/// }
92/// ```
93#[cfg(feature = "interface-instructions")]
94#[deprecated(
95    since = "0.31.1",
96    note = "Use `#[instruction(discriminator = <EXPR>)]` instead.
97    See examples in https://github.com/coral-xyz/anchor/tree/v0.31.1/tests/spl/transfer-hook"
98)]
99#[proc_macro_attribute]
100pub fn interface(
101    _args: proc_macro::TokenStream,
102    input: proc_macro::TokenStream,
103) -> proc_macro::TokenStream {
104    // This macro itself is a no-op, but must be defined as a proc-macro
105    // attribute to be used on a function as the `#[interface]` attribute.
106    //
107    // The `#[program]` macro will detect this attribute and transform the
108    // discriminator.
109    input
110}
111
112/// This attribute is used to override the Anchor defaults of program instructions.
113///
114/// # Arguments
115///
116/// - `discriminator`: Override the default 8-byte discriminator
117///
118///     **Usage:** `discriminator = <CONST_EXPR>`
119///
120///     All constant expressions are supported.
121///
122///     **Examples:**
123///
124///     - `discriminator = 1` (shortcut for `[1]`)
125///     - `discriminator = [1, 2, 3, 4]`
126///     - `discriminator = b"hi"`
127///     - `discriminator = MY_DISC`
128///     - `discriminator = get_disc(...)`
129///
130/// # Example
131///
132/// ```ignore
133/// use anchor_lang::prelude::*;
134///
135/// declare_id!("CustomDiscriminator111111111111111111111111");
136///
137/// #[program]
138/// pub mod custom_discriminator {
139///     use super::*;
140///
141///     #[instruction(discriminator = [1, 2, 3, 4])]
142///     pub fn my_ix(_ctx: Context<MyIx>) -> Result<()> {
143///         Ok(())
144///     }
145/// }
146///
147/// #[derive(Accounts)]
148/// pub struct MyIx<'info> {
149///     pub signer: Signer<'info>,
150/// }
151/// ```
152#[proc_macro_attribute]
153pub fn instruction(
154    _args: proc_macro::TokenStream,
155    input: proc_macro::TokenStream,
156) -> proc_macro::TokenStream {
157    // This macro itself is a no-op, but the `#[program]` macro will detect this attribute and use
158    // the arguments to transform the instruction.
159    input
160}