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