| Crates.io | anchor-modular-program |
| lib.rs | anchor-modular-program |
| version | 0.1.3 |
| created_at | 2025-04-24 22:37:36.071341+00 |
| updated_at | 2025-04-25 03:10:57.750239+00 |
| description | Replacement #[program] macro that allows specifying additional instruction modules |
| homepage | |
| repository | https://github.com/ssadler/anchor_modular_program |
| max_upload_size | |
| id | 1648322 |
| size | 21,013 |
Replacement #[program] macro that allows specifying additional instruction modules
Lets say you want to import instructions from your module extra::instructions,
and you have the required types (contexts, instruction argument types) at
extra::types:
use anchor_lang::prelude::*;
use anchor_modular_program::*;
declare_id!("...");
mod extra;
use extra::types::*;
#[modular_program(
modules=[
extra::instructions
]
)]
mod my_program {
use super::*;
}
Instructions from extra::instructions will be included (forwarded, rather than
included directly), prefixed with extra_.
As well as specifying a module path in the local program, you can provide a spec:
#[modular_program(
modules=[
{
module: etc, // rust module path to instructions module
prefix: "etc", // prefixed with "etc_", or "" for no prefix
file_path: "./src/etc/mod.rs", // path to instructions
wrapper: path::to::macro // see [#wrapper-macros](Wrapper Macros)
}
]
)
See the Test Program for examples.
It's possible to specify a macro that will define how the instruction is called, the macro takes the path to the function and the instruction parameters, i.e.:
macro_rules! call_instruction_macro {
($ix:path, $ctx:ident: $ctx_type:ty $(, $arg:ident: $arg_type:ty )*) => {
{ msg!("Before");
// If you want to use a custom context wrapper, you need to
// `use` it `as Context` in your instructions module
let ctx = MyContextWrapper::new($ctx);
let out = $ix(ctx $(, $arg))?;
msg!("After");
Ok(out)
}
};
}
extra::instructions is converted to the file path
src/extra/instructions.rs.PRs welcome