Reference
Reference documentation for the Anchor framework.
Account constraints
Anchor.toml configuration
Anchor.toml file.Anchor CLI
NO_DNA
Anchor version manager
Rust to JS type conversion
Example programs
Account constraints
Reference for Anchor account constraints used inside the #[account(...)] attribute.
Account constraints are declared inside the #[account(...)] attribute on fields of a struct that derives Accounts. They run before the instruction handler and reject the transaction if any check fails.
See the constraint codegen for implementation details.
Notation (Custom error syntax)
Each constraint accepts an optional @ <custom_error> clause to override the default error. Wherever you see @ <custom_error> in the snippets below, the constraint will return that variant instead of Anchor’s built-in error code on failure.
Normal constraints#
#[account(signer)]#
Checks the given account signed the transaction. Prefer the Signer type if signer is the only constraint needed on the account:
#[account(signer)]#[account(signer @ <custom_error>)]#[account(mut)]#
Checks the given account is mutable and persists any state changes after the instruction completes:
#[account(mut)]#[account(mut @ <custom_error>)]#[account(dup)]#
Allows a mutable account to be passed in more than once. Anchor blocks duplicate mutable accounts by default to avoid silent overwrites; dup opts back in when the duplication is intentional.
Note
This constraint only applies to mutable account types that serialize on exit. UncheckedAccount, Signer, SystemAccount, AccountLoader, Program, and Interface allow duplicates already because they don’t serialize data on exit.
#[account(mut, dup)]#[account(mut, dup @ <custom_error>)]#[derive(Accounts)]pub struct AllowsDuplicateMutable<'info> { #[account(mut)] pub account1: Account<'info, Counter>, // This account can be the same as account1 #[account(mut, dup)] pub account2: Account<'info, Counter>,}
pub fn allows_duplicate_mutable(ctx: Context<AllowsDuplicateMutable>) -> Result<()> { Ok(())}#[account(init)]#
Creates the account via a CPI to the System Program and writes the 8-byte account discriminator. Requires payer and space:
#[account( init, payer = <target_account>, space = <num_bytes>)]#[account(init_if_needed)]#
Same as init but only runs if the account does not exist yet. Requires the init-if-needed cargo feature:
#[account( init_if_needed, payer = <target_account>)]
#[account( init_if_needed, payer = <target_account>, space = <num_bytes>)]#[account(seeds, bump)]#
Checks that the given account is a PDA derived from the currently executing program, the seeds, and (if provided) the bump. See Program derived address for usage patterns:
#[account( seeds = <seeds>, bump)]
#[account( seeds = <seeds>, bump, seeds::program = <expr>)]
#[account( seeds = <seeds>, bump = <expr>)]
#[account( seeds = <seeds>, bump = <expr>, seeds::program = <expr>)]#[account(has_one = target)]#
Checks that the target field stored on the account matches the key of the target field in the Accounts struct:
#[account( has_one = <target_account>)]
#[account( has_one = <target_account> @ <custom_error>)]#[account(address = expr)]#
Checks the account key matches the given pubkey:
#[account(address = <expr>)]#[account(address = <expr> @ <custom_error>)]#[account(owner = expr)]#
Checks the account owner matches expr:
#[account(owner = <expr>)]#[account(owner = <expr> @ <custom_error>)]#[account(executable)]#
Checks the account is executable (the account is a program):
#[account(executable)]#[account(zero)]#
Checks the account discriminator is zero. Use for accounts larger than 10 KiB, where init exceeds the System Program’s allocation limit:
#[account(zero)]#[account(close = target)]#
Closes the account by sending its lamports to target and zeroing its data:
#[account(close = <target_account>)]#[account(constraint = expr)]#
Custom constraint that checks whether the given expression evaluates to true:
#[account(constraint = <expr>)]#[account( constraint = <expr> @ <custom_error>)]#[account(realloc)]#
Reallocates program account space at the start of an instruction. realloc::zero controls whether new bytes are zeroed:
If the change is additive, lamports are transferred from realloc::payer
to maintain rent exemption. If the change is subtractive, all lamports above
the new rent-exempt minimum are transferred back to realloc::payer.
Warning: Do not use subtractive realloc on accounts that intentionally hold
extra lamports, such as vaults. Those extra lamports will also be transferred
to realloc::payer; the current v1 behavior does not limit refunds to
rent savings alone.
#[account( realloc = <space>, realloc::payer = <target>, realloc::zero = <bool>)]#[account(discriminator = <expr>)]#
Overrides the auto-generated discriminator for an account. Any constant expression is accepted. All-zero discriminators are rejected because zeroed discriminators are indistinguishable from newly allocated accounts; see zeroed discriminators for the security background:
#[account(discriminator = 12)]#[account(discriminator = [1, 2, 3, 4])]#[account(discriminator = MY_CONST_DISCRIMINATOR)]SPL constraints#
#[account(token::*)]#
Creates or validates token accounts with the specified mint and authority:
#[account( token::mint = <target_account>, token::authority = <target_account>)]
#[account( token::mint = <target_account>, token::authority = <target_account>, token::token_program = <target_account>)]#[account(mint::*)]#
Creates or validates mint accounts with the specified parameters:
#[account( mint::authority = <target_account>, mint::decimals = <expr>)]
#[account( mint::authority = <target_account>, mint::decimals = <expr>, mint::freeze_authority = <target_account>)]#[account(associated_token::*)]#
Creates or validates associated token accounts:
#[account( associated_token::mint = <target_account>, associated_token::authority = <target_account>)]
#[account( associated_token::mint = <target_account>, associated_token::authority = <target_account>, associated_token::token_program = <target_account>)]#[account(*::token_program = expr)]#
Overrides the token program used by token, mint, or associated_token constraints:
#[account(*::token_program = <target_account>)]Token extensions constraints#
These extensions are checked both when the mint is initialized and when an
existing mint is reused with init_if_needed.
#[account(extensions::close_authority::*)]#
Creates or validates the close authority extension on the mint account:
#[account( extensions::close_authority::authority = <target_account>)]#[account(extensions::permanent_delegate::*)]#
Creates or validates the permanent delegate extension on the mint account:
#[account( extensions::permanent_delegate::delegate = <target_account>)]#[account(extensions::transfer_hook::*)]#
Creates or validates the transfer hook extension on the mint account:
#[account( extensions::transfer_hook::authority = <target_account>, extensions::transfer_hook::program_id = <target_account>)]#[account(extensions::group_pointer::*)]#
Creates or validates the group pointer extension on the mint account:
#[account( extensions::group_pointer::authority = <target_account>, extensions::group_pointer::group_address = <target_account>)]#[account(extensions::group_member_pointer::*)]#
Creates or validates the group member pointer extension on the mint account:
#[account( extensions::group_member_pointer::authority = <target_account>, extensions::group_member_pointer::member_address = <target_account>)]#[account(extensions::metadata_pointer::*)]#
Creates or validates the metadata pointer extension on the mint account:
#[account( extensions::metadata_pointer::authority = <target_account>, extensions::metadata_pointer::metadata_address = <target_account>)]Instruction attribute#
#[instruction(...)]#
Exposes the instruction’s arguments to the Accounts struct so constraints can reference them. The example below uses input in the space calculation when initializing an account:
#[program]pub mod example { use super::*;
pub fn initialize(ctx: Context<Initialize>, input: String) -> Result<()> { // --snip-- }}
#[derive(Accounts)]#[instruction(input: String)]pub struct Initialize<'info> { #[account( init, payer = signer, space = 8 + 4 + input.len(), )] pub new_account: Account<'info, DataAccount>, // --snip--}Arguments must appear in the same order as the handler signature. Listing every argument is valid:
#[program]pub mod example { use super::*;
pub fn initialize(ctx: Context<Initialize>, input_one: String, input_two: String) -> Result<()> { // --snip-- }}
#[derive(Accounts)]#[instruction(input_one: String, input_two: String)]pub struct Initialize<'info> { // --snip--}Omitting trailing arguments is valid:
#[program]pub mod example { use super::*;
pub fn initialize(ctx: Context<Initialize>, input_one: String, input_two: String) -> Result<()> { // --snip-- }}
#[derive(Accounts)]#[instruction(input_one: String)]pub struct Initialize<'info> { // --snip--}Skipping a leading argument is invalid and produces a compile error:
#[program]pub mod example { use super::*;
pub fn initialize(ctx: Context<Initialize>, input_one: String, input_two: String) -> Result<()> { // --snip-- }}
#[derive(Accounts)]#[instruction(input_two: String)]pub struct Initialize<'info> { // --snip--}Anchor.toml configuration
Reference for the fields available in an Anchor workspace's Anchor.toml file.
Anchor.toml configures a workspace’s provider, programs, scripts, test validator, and toolchain. The full set of fields is defined in the Config struct in the Anchor CLI.
[provider] (required)#
Sets the wallet and cluster used for all anchor commands:
[provider]cluster = "localnet" # The cluster used for all commands.wallet = "~/.config/solana/id.json" # The keypair used for all commands.[scripts] (required for testing)#
Defines named scripts runnable with anchor run <script>. The test script is executed by anchor test:
[scripts]test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"skip_local_validator#
When set to true, anchor test does not start a local validator for localnet tests. anchor init writes this for Rust templates that run the Solana VM in-process, such as LiteSVM and Mollusk:
skip_local_validator = true[features]#
resolution#
Enables IDL account resolution. Defaults to true:
[features]resolution = true[workspace]#
idls#
Copies the generated <program_name>.json IDL to the given directory on anchor build. Use this when another tool or a versioned frontend needs the JSON outside the workspace target directory:
[workspace]idls = "app/src/idls/"types#
Copies the generated <idl>.ts file to the given directory on anchor build. Useful for committing the IDL types into a frontend that does not have access to the target directory:
[workspace]types = "app/src/idl/"members#
Paths (relative to Anchor.toml) to every Cargo.toml manifest the anchor CLI should compile. Programs using the standard Anchor workflow can omit this field; non-Anchor programs that still publish through the CLI must list their manifests here:
[workspace]members = [ "programs/*", "other_place/my_program"]exclude#
Lists workspace paths to skip, mirroring the include list in members:
[workspace]exclude = [ "programs/my_program"][programs]#
Maps program names to addresses, scoped by cluster:
[programs.localnet]my_program = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"During tests on localnet, Anchor reads programs.localnet to tell solana-test-validator which programs to load at genesis via --bpf-program.
[clients]#
Configures Codama client generation. When auto = true, anchor build converts emitted Anchor IDLs into Codama IDLs and invokes the selected language renderers after the build completes.
Each language can be enabled with a boolean or a table. If path is omitted, the default output directory is clients/<language>. Supported language keys are js, js-umi, rust, and go:
[clients]auto = truerust = truejs = { enable = true }go = { enable = true, path = "go-client" }js-umi = false[test]#
startup_wait#
Increases the time anchor waits for solana-test-validator to start. Useful when cloning many accounts (see test.validator.clone) extends startup time:
[test]startup_wait = 10000genesis#
Starts solana-test-validator with the listed programs preloaded:
[[test.genesis]]address = "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"program = "dex.so"
[[test.genesis]]address = "22Y43yTVxuUkoRKdm9thyRhQ3SdgQS7c7kB6UNCiaczD"program = "swap.so"upgradeable = trueupgradeable#
Deploys the program-under-test with --upgradeable-program so tests can exercise instructions gated on the upgrade authority. The initial upgrade authority is set to provider.wallet.
When unset or false, the program is deployed with --bpf-program and cannot be upgraded:
[test]upgradeable = true[test.validator]#
Forwards options to solana-test-validator (run solana-test-validator --help for the full list) during commands like anchor test:
[test.validator]url = "https://api.mainnet-beta.solana.com" # This is the url of the cluster that accounts are cloned from (See `test.validator.clone`).warp_slot = 1337 # Warp the ledger to `warp_slot` after starting the validator.slots_per_epoch = 5 # Override the number of slots in an epoch.rpc_port = 1337 # Set JSON RPC on this port, and the next port for the RPC websocket.limit_ledger_size = 1337 # Keep this amount of shreds in root slots.ledger = "test-ledger" # Set ledger location.gossip_port = 1337 # Gossip port number for the validator.gossip_host = "127.0.0.1" # Gossip DNS name or IP address for the validator to advertise in gossip.faucet_sol = 1337 # Give the faucet address this much SOL in genesis.faucet_port = 1337 # Enable the faucet on this port.dynamic_port_range = "1337 - 13337" # Range to use for dynamically assigned ports.bind_address = "127.0.0.1" # IP address to bind the validator ports.test.validator.clone#
Clones an account from test.validator.url into the test cluster. If address points to a program owned by the BPF upgradeable loader, Anchor (>= 0.23.0) clones the program data account automatically:
[test.validator]url = "https://api.mainnet-beta.solana.com"
[[test.validator.clone]]address = "7NL2qWArf2BbEBBH1vTRZCsoNqFATTddH6h8GkVvrLpG"[[test.validator.clone]]address = "2RaN5auQwMdg5efgCaVqpETBV8sacWGR8tkK4m9kjo5r"[[test.validator.clone]]address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s" # implicitly also clones PwDiXFxQsGra4sFFTT8r1QWRMd4vfumiWC1jfWNfdYTtest.validator.account#
Uploads an account from a .json file:
[[test.validator.account]]address = "Ev8WSPQsGb4wfjybqff5eZNcS3n6HaMsBkMk9suAiuM"filename = "some_account.json"
[[test.validator.account]]address = "Ev8WSPQsGb4wfjybqff5eZNcS3n6HaMsBkMk9suAiuM"filename = "some_other_account.json"[surfpool]#
Configures the Surfpool validator, used when anchor test --validator surfpool selects Surfpool as the local network backend. Surfpool is a lightweight Solana simulator with features like automatic account cloning and runbook execution. All fields are optional and have sensible defaults:
[surfpool]startup_wait = 30000 # Time (ms) to wait for Surfpool to start. Default: 30000.shutdown_wait = 2000 # Time (ms) to wait for Surfpool to shut down. Default: 2000.rpc_port = 8899 # JSON RPC port. Default: 8899.ws_port = 8900 # WebSocket port. If not set, derived automatically.host = "127.0.0.1" # IP address to bind to. Default: "127.0.0.1".online = true # Enable online mode (clone accounts from a remote cluster).datasource_rpc_url = "https://api.mainnet.solana.com"airdrop_addresses = ["addr1...", "addr2..."] # Addresses to airdrop SOL to at startup.manifest_file_path = "./Cargo.toml" # Path to the Cargo.toml manifest file.runbooks = ["./runbooks/setup.json"] # Paths to runbook files to execute on startup.slot_time = 400 # Simulated slot time in milliseconds.log_level = "info" # Log level for Surfpool. Default: "none".block_production_mode = "clock" # Block production mode. Default: "transaction".startup_wait#
Time in milliseconds to wait for Surfpool to start up. Useful when loading many accounts or running runbooks at startup. Default: 30000.
shutdown_wait#
Time in milliseconds to wait for Surfpool to shut down gracefully. Default: 2000.
rpc_port#
The port on which Surfpool exposes its JSON RPC endpoint. Default: 8899.
ws_port#
The port for the WebSocket endpoint. If not specified, it is derived automatically.
host#
The IP address to bind the Surfpool validator ports to. Default: "127.0.0.1".
online#
When set to true, Surfpool operates in online mode, cloning accounts from the remote cluster specified by datasource_rpc_url. Default: false.
datasource_rpc_url#
The RPC URL of the remote cluster used as a data source when online is enabled:
[surfpool]online = truedatasource_rpc_url = "https://api.mainnet.solana.com"airdrop_addresses#
A list of base58-encoded addresses that will receive an airdrop of SOL when Surfpool starts:
[surfpool]airdrop_addresses = [ "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS", "7NL2qWArf2BbEBBH1vTRZCsoNqFATTddH6h8GkVvrLpG",]manifest_file_path#
Path to the Cargo.toml manifest file for the workspace. Typically not needed because Anchor resolves it automatically.
runbooks#
A list of file paths to runbooks that Surfpool will execute on startup. Runbooks allow setting up initial state (deploy programs, create accounts, etc.) before tests run:
[surfpool]runbooks = ["./runbooks/setup.json"]slot_time#
The simulated slot time in milliseconds. Controls how fast slots advance in the Surfpool simulator.
log_level#
Log verbosity for the Surfpool process. Common values include "none", "info", "debug", "warn", and "error". Default: "none".
block_production_mode#
Controls how Surfpool produces blocks. Default: "transaction". Known values:
"clock"produces blocks at regular intervals based onslot_time."transaction"produces a new block for each incoming transaction.
[surfpool]block_production_mode = "clock"[toolchain]#
Overrides toolchain versions for the workspace, similar to rust-toolchain.toml:
[toolchain]anchor_version = "1.2.0" # `anchor-cli` version to use (requires `avm`)solana_version = "4.1.2" # Solana version to use (applies to all Solana tools)package_manager = "yarn" # JS package manager to usepackage_manager#
Selects the JS package manager Anchor uses for client and workspace commands. Valid values are npm, yarn, pnpm, and bun.
When the field is omitted, Anchor probes pnpm, yarn, then npm and uses the first one found on PATH. Values must be lowercase, since they are deserialized with serde(rename_all = "lowercase"):
[toolchain]package_manager = "pnpm"hooks#
Configures commands that run at specific stages of the build, test, and deploy pipeline:
[hooks]# Accepts kebab-case names...pre-build = "echo foo"# ...and snake-case namespost_build = "echo bar"# Accepts a list of commands, run in seriespre-test = ["echo 1", "echo 2"]# Non-zero exit codes will abort the CLIpost-test = "exit 1"# Unused hooks may be omitted# pre-deploy = []# post-deploy = [][registry] (removed)#
The [registry] section is no longer supported and was removed in 1.0.0. Remove it from any existing Anchor.toml:
[registry]url = "https://anchor.projectserum.com"Anchor CLI
Anchor CLI reference documentation.
The Anchor CLI manages an Anchor workspace: scaffolding projects, building programs, deploying to a cluster, running tests, and interacting with on-chain IDLs. Run anchor --help on any subcommand for the full list of flags:
For non-human or agent-driven usage, see NO_DNA.
anchor --helpUsage: anchor-1.2.0 [OPTIONS] <COMMAND>
Commands: init Initializes a workspace build Builds the workspace expand Expands macros (wrapper around cargo expand) verify Verifies the on-chain bytecode matches the locally compiled artifact. Run this command inside a program subdirectory, i.e., in the dir containing the program's Cargo.toml test Runs integration tests fuzz Coverage-guided fuzzing for Solana programs (powered by Crucible). new Creates a new program idl Commands for interacting with interface definitions clean Remove all artifacts from the generated directories except program keypairs migrate Runs the deploy migration script airdrop Request an airdrop of SOL cluster Cluster commands config Configuration management commands shell Starts a node shell with an Anchor client setup according to the local config run Runs the script defined by the current workspace's Anchor.toml keys Program keypair commands localnet Localnet commands account Fetch and deserialize an account using the IDL provided completions Generates shell completions address Get your public key balance Get your balance epoch Get current epoch epoch-info Get information about the current epoch logs Stream transaction logs show-account Show the contents of an account keygen Keypair generation and management program Program deployment and management commands help Print this message or the help of the given subcommand(s)
Options: --provider.cluster <CLUSTER> Cluster override --provider.wallet <WALLET> Wallet override --commitment <COMMITMENT> Commitment override (valid values: processed, confirmed, finalized) -h, --help Print help -V, --version Print versionanchor account#
anchor account <program-name>.<AccountTypeName> <account-pubkey>Fetches an account with the given public key and deserializes the data to JSON using the type name provided. When run inside a workspace, the workspace’s IDL files supply the data types. Otherwise, an IDL file path must be provided.
For example, anchor account anchor-escrow.EscrowAccount 3PNkzWKXCsbjijbasnx55NEpJe8DFXvEEbJKdRKpDcfK deserializes the account at the given pubkey using the EscrowAccount struct defined in the anchor-escrow program:
anchor account <program-name>.<AccountTypeName> <account-pubkey> --idl <path/to/idl.json>Pass --idl to deserialize using a specific IDL file even when inside a workspace.
anchor build#
anchor buildBuilds programs in the workspace targeting Solana’s BPF runtime and emits IDLs into the target/idl directory:
Anchor passes --tools-version v1.57 and --arch v3 to cargo build-sbf by default. Override them with anchor build --tools-version <version> --arch <arch>.
Programs built with --arch v3 require compatible local test tooling: platform-tools v1.53 or newer, a Solana/Agave 4.0 or newer solana-test-validator, Surfpool 1.4 or newer, and LiteSVM 0.13.1 or newer.
anchor build --verifiableRuns the build inside a Docker image so that the output binary is deterministic (assuming a Cargo.lock file is used). This command must be run from within a single crate subdirectory in the workspace, for example programs/<my-program>/. See verifiable builds for details.
Tip (Passing arguments to cargo build-sbf)
Forward arguments to the underlying cargo build-sbf command with -- <ARGS>:
anchor build -- --features my-featureCluster#
anchor cluster list#
anchor cluster listLists the cluster endpoints:
Cluster Endpoints:
* Mainnet - https://api.mainnet-beta.solana.com* Devnet - https://api.devnet.solana.com* Testnet - https://api.testnet.solana.comanchor codama#
anchor codama convert <target/idl/program.json> --out <codama-idl.json>anchor codama generate -l rust,js -p clients <target/idl/program.json>convert translates an Anchor IDL into a Codama IDL. generate runs the same conversion in-process and then invokes the Codama renderer packages for the requested languages. Supported language values are js, js-umi, rust, and go.
Codama client generation can also run automatically after anchor build when [clients] auto = true is set in Anchor.toml.
anchor coverage#
cd programs/<program-name>anchor coverage [--skip-run] [--skip-build] [--output target/coverage/sbf.lcov]Generates LCOV source coverage from SBF register traces. Run from inside a program directory unless --trace-dir points at an existing trace set. By default traces are collected under target/coverage/traces. Pass --skip-run to generate coverage from existing traces.
anchor debugger#
anchor debugger [<test-name>] [--skip-run] [--skip-build] [--gdb]Runs tests with profiling enabled and opens an instruction-level TUI over the captured SBF traces. --skip-run reuses existing traces, and --gdb captures through the sbpf gdb-stub trace path (which is much slower).
anchor deploy#
anchor deployDeploys all programs in the workspace to the configured cluster.
Tip (Different from solana program deploy)
Each invocation of anchor deploy generates a new program address. To upgrade an
existing program, use anchor upgrade or solana program deploy
with the existing program ID.
anchor expand#
anchor expandExpands the macros of the program when run inside a program folder, or the entire workspace when run from the workspace root. Pass --program-name to expand only a specific program.
IDL#
The idl subcommand provides commands for interacting with interface definition files. Storing an IDL on chain at a deterministic address (a function of the program’s ID) lets clients be generated from nothing but the program ID.
anchor idl build#
anchor idl buildGenerates the IDL for the program using the compilation method.
anchor idl init#
anchor idl init -f <target/idl/program.json> <program-id>Creates an IDL account, writing the given <target/idl/program.json> file into a program-owned account. By default, the size of the account is double the size of the IDL, leaving room for growth in case the IDL is upgraded later. The <program-id argument is optional. When omitted, idl.address from Anchor.toml is used.
anchor idl fetch#
anchor idl fetch -o <out-file.json> <program-id>Fetches an IDL from the configured blockchain. For example, point Anchor.toml at the mainnet cluster and run:
anchor idl fetch GrAkKfEpTKQuVHG2Y97Y2FF4i7y7Q5AHLK94JBy7Y5yvanchor idl authority#
anchor idl authority <program-id>Outputs the IDL account’s authority, which is the wallet that has the ability to update the IDL.
anchor idl erase-authority#
anchor idl erase-authority -p <program-id>Erases the IDL account’s authority so that upgrades can no longer occur. The configured wallet must be the current authority.
anchor idl upgrade#
anchor idl upgrade -f <target/idl/program.json>Upgrades the on-chain IDL to the new target/idl/program.json. The configured wallet must be the current authority. The program-id argument is optional. When omitted, idl.address is used.
anchor idl close#
anchor idl close <program-id>Closes the metadata account and recovers the rent. By default this closes the idl seed account. Pass --seed for a different seed:
anchor idl close <program-id> --seed <custom-seed>anchor idl create-buffer#
anchor idl create-buffer -f <filepath>Creates a buffer account for metadata. Use this for large IDLs that need to be written across multiple transactions.
anchor idl set-buffer-authority#
anchor idl set-buffer-authority <buffer> -n <new-authority>Sets a new authority on a buffer account.
anchor idl write-buffer#
anchor idl write-buffer <program-id> -b <buffer>Writes metadata to the program using a pre-created buffer account. --seed selects the metadata seed (defaults to idl):
anchor idl write-buffer <program-id> -b <buffer> --seed <seed>Pass --close-buffer to close the buffer account after writing:
anchor idl write-buffer <program-id> -b <buffer> --close-bufferanchor init#
anchor init <project-name>Initializes a project workspace with the following structure:
- app/Application frontend
migrations/
- deploy.js Deploy script
- programs/Solana program crates
- tests/JavaScript integration tests
- Anchor.toml Anchor configuration file
- Cargo.toml Rust workspace configuration
- package.json JavaScript dependencies
By default, programs are initialized with a modular structure (multiple files) to promote better code organization. The --template flag selects a different layout:
anchor init --template multiple # Default: modular structure (recommended)anchor init --template single # Single lib.rs file (for prototyping)The modular template organizes code into separate files for instructions, state, constants, and errors, making it easier to navigate and maintain as the program grows. See Anchor.toml for the full configuration reference.
Pass --anchor-version to select v1 or v2 Rust templates:
anchor init --anchor-version v1 # Default: Anchor v1 Rust templatesanchor init --anchor-version v2 # Anchor v2 Rust templatesThe v2 templates depend on the anchor-next git crates until the v2 release is published.
Keys#
Program keypair commands.
anchor keys list#
anchor keys listLists all program keypairs declared in the workspace.
anchor keys sync#
anchor keys syncSyncs each program’s declare_id!() value with the actual pubkey of its keypair file.
anchor migrate#
anchor migrateRuns the deploy script located at migrations/deploy.js, injecting a provider configured from the workspace’s Anchor.toml:
const anchor = require('@anchor-lang/core')
module.exports = async function (provider) { anchor.setProvider(provider)
// Add your deploy script here.}Migrations currently support only this simple deploy script.
anchor new#
anchor new <program-name>Creates a new program in the workspace’s programs/ directory initialized with boilerplate. By default the modular structure template is used. Pass --template to select another:
anchor new --template multiple <program-name> # Default: modular (recommended)anchor new --template single <program-name> # Single file (for prototyping)Pass --anchor-version to select v1 or v2 Rust templates:
anchor new --anchor-version v1 <program-name> # Default: Anchor v1 Rust templatesanchor new --anchor-version v2 <program-name> # Anchor v2 Rust templatesanchor shell#
anchor shellStarts a Node.js shell with an Anchor client set up according to the local config. The client can interact with deployed programs in the workspace.
anchor test#
anchor testRuns an integration test suite against the configured cluster, deploying fresh versions of all workspace programs first.
When the configured network is a localnet, anchor test starts the local network automatically and runs the tests against it. By default, Surfpool is used as the local network backend. Pass --validator legacy to use solana-test-validator instead.
Note (Local validator conflicts)
anchor test starts its own local validator. Shut down any other local validators first, or the command fails.
To run against a local validator that’s already running, pass --skip-local-validator.
Program logs are streamed to .anchor/program-logs/<address>.<program-name>.log while tests run.
Pass --profile with Rust/LiteSVM-style tests that enable the generated profile feature to collect SBF register traces and render flamegraph SVGs under target/anchor-v2-profile/. Those traces also feed anchor debugger and anchor coverage.
anchor upgrade#
anchor upgrade <target/deploy/program.so> --program-id <program-id>Uses Solana’s upgradeable BPF loader to upgrade the on-chain program code. The configured wallet must be the upgrade authority.
anchor verify#
anchor verify <program-id>Verifies that the on-chain bytecode matches the locally compiled artifact. See verifiable builds for the build setup that produces a deterministic binary.
NO_DNA
Reference documentation for Anchor's NO_DNA support
Anchor supports the NO_DNA convention for non-human CLI usage. See
no-dna.org. Set NO_DNA to a non-empty value when
invoking Anchor from an agent, automation, or another non-interactive
workflow that should not block on supported interactive waits or confirmation
prompts. NO_DNA=1 is the standard example.
Usage#
Prefix the command:
NO_DNA=1 anchor test --detachNO_DNA=1 anchor localnetNO_DNA=1 anchor program close <ACCOUNT> --bypass-warningNO_DNA=1 anchor legacy-idl erase-authority --program-id <PROGRAM_ID> --bypass-warningOr export it for a session:
export NO_DNA=1anchor test --detachNote (Destructive commands stay explicit)
NO_DNA does not auto-confirm destructive actions. For commands such as
anchor program close and anchor legacy-idl erase-authority, pass the
existing explicit bypass flag yourself.
Checking support from the CLI#
The CLI help text documents NO_DNA where it applies:
anchor --helpanchor test --helpanchor localnet --helpanchor program close --helpanchor legacy-idl erase-authority --helpAnchor version manager
Manage multiple installations of the anchor-cli binary.
Anchor Version Manager (avm) manages multiple installations of the anchor-cli binary. Use it to switch between versions for verifiable builds or to work with an alternate release:
avm --helpAnchor version manager
Usage: avm <COMMAND>
Commands: use Use a specific version of Anchor install Install a version of Anchor uninstall Uninstall a version of Anchor list List available versions of Anchor update Update to the latest Anchor version solana Resolve or install the Solana CLI for the current project platform-tools Inspect or manage the Solana platform-tools toolchain self-update Update avm itself to the latest version via cargo install completions Generate shell completions for AVM help Print this message or the help of the given subcommand(s)
Options: -h, --help Print help -V, --version Print versionavm install#
Install a version of anchor-cli with avm install <version-or-commit>. The version argument follows semver, or pass latest for the latest stable release and latest-pre-release for the latest pre-release:
avm install latestavm install latest-pre-releaseYou can also install with the following arguments:
avm list#
List installed and available versions with avm list. Pass --pre-release to include pre-release versions:
avm list --pre-releaseavm uninstall#
Remove an installed version with avm uninstall <version>.
avm update#
Update to the latest stable version with avm update. Pass --pre-release to update to the latest pre-release instead:
avm update --pre-releaseavm use#
Select an installed version with avm use <version>. The selected version remains active until the command runs again with a different argument. As with avm install, the version argument accepts latest or latest-pre-release:
avm use latestavm use latest-pre-releaseavm solana#
avm solana resolveavm solana install [<version>] [--force]Resolve or install the Solana CLI version for the current project. When no version is passed to install, AVM first checks [toolchain] solana_version in Anchor.toml, then the solana-program dependency in Cargo.toml. If the project does not pin Solana directly, AVM resolves the Anchor version and maps it to Anchor’s recommended Solana version.
Project Solana versions are parsed as semver requirements. AVM chooses the newest hosted Solana CLI installer that satisfies the requirement; use an exact comparator such as =4.1.2 to require one specific hosted version.
When anchor is invoked through the AVM stub, AVM also ensures the resolved Solana CLI version is active before spawning the selected anchor-cli binary.
avm platform-tools#
avm platform-tools resolveavm platform-tools install [<version>] [--force]avm platform-tools listavm platform-tools uninstall <version>Resolve or manage the platform-tools version used by Solana’s SBF toolchain. When no version is passed to install, AVM uses the project-resolved Solana version and the embedded platform-tools map. If the Solana version is a semver requirement, AVM considers hosted Solana CLI versions satisfying that requirement and prefers one whose platform-tools rustc can compile the locked program dependency graph.
avm platform-tools resolve also accepts --solana-version or --anchor-version to resolve without inspecting the current project.
AVM also queries the latest platform-tools release at most once every 24 hours and checks whether it is present in cargo build-sbf’s cache. If it is missing, AVM prints the exact cargo build-sbf --install-only command needed to install it; it never installs that cached toolchain automatically.
avm self-update#
Update avm itself with avm self-update. By default this installs the latest stable release of avm.
avm self-updateavm self-update --pre-releaseavm self-update --bleeding-edgeavm also passively warns you when it detects that a newer version of itself is available.
Rust to JS type conversion
Reference for how Anchor converts between Rust and TypeScript types in generated clients.
Anchor’s generated TypeScript clients map Rust types in the program IDL to JavaScript values using the rules below. Instruction arguments and account fields follow the same mapping.
Primitive types#
Booleans#
Numbers#
Integers up to 32 bits fit in a JavaScript number. Wider integers exceed Number.MAX_SAFE_INTEGER, so Anchor represents them with BN to preserve precision.
Strings#
Collections#
Arrays and vectors#
Optional values#
Complex types#
Structs#
A Rust struct becomes a TypeScript object type with the same field names:
struct MyStruct { val: u16,}type MyStruct = { val: number}
const instance = { val: 99 }Enums#
A Rust enum becomes an object with a single key matching the active variant. Unit variants carry an empty object, named variants carry an object of fields, and tuple variants carry an array of positional values:
enum MyEnum { One, Two { val: u32 }, Three(u8, i16),}// Unit variantconst one = { one: {} }
// Named variantconst two = { two: { val: 99 },}
// Tuple variantconst three = { three: [12, -34],}Example programs
A curated list of example Anchor programs for common patterns and token operations.
There are extensive examples for individual Anchor features on the Solana Foundation Program Examples repo.
Additionally, the Quicknode Solana Program Examples repo includes Anchor examples of larger programs, like order books, loan markets, betting markets, and so on. The current Anchor stack, including Anchor 1.x, the multiple files layout, and LiteSVM for tests is used throughout.