Anchor v2 alpha is here! Up to 95% smaller binaries, 3.0 to 50.4× fewer CU
Anchor Docs
A lone boy hauls an anchor on the shore, evoking the weight of maritime destiny and Homer's mastery of atmosphere and technique.
Boy with Anchor, Winslow Homer, 1873
Overview

Reference

Reference documentation for the Anchor framework.

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:

#[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#

#[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]#

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 = true
rust = true
js = { 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 = 10000

genesis#

Starts solana-test-validator with the listed programs preloaded:

[[test.genesis]]
address = "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"
program = "dex.so"
[[test.genesis]]
address = "22Y43yTVxuUkoRKdm9thyRhQ3SdgQS7c7kB6UNCiaczD"
program = "swap.so"
upgradeable = true

upgradeable#

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 PwDiXFxQsGra4sFFTT8r1QWRMd4vfumiWC1jfWNfdYT

test.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 = 5000 # Time (ms) to wait for Surfpool to start. Default: 5000.
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: 5000.

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 = true
datasource_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 on slot_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.0.1" # `anchor-cli` version to use (requires `avm`)
solana_version = "3.1.10" # Solana version to use (applies to all Solana tools)
package_manager = "yarn" # JS package manager to use

package_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 names
post_build = "echo bar"
# Accepts a list of commands, run in series
pre-test = ["echo 1", "echo 2"]
# Non-zero exit codes will abort the CLI
post-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:

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:

Terminal window
anchor --help
Usage: anchor-1.0.1 [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
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 version

anchor account#

Terminal window
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.

ArgumentDescription
<program-name>The name of the program where the account struct resides, usually under programs/<program-name>/. Case-sensitive, exactly matching the folder name (typically kebab-case).
<AccountTypeName>The name of the account struct, usually in PascalCase.
<account-pubkey>The Pubkey of the account to deserialize, in Base58.

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:

Terminal window
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#

Terminal window
anchor build

Builds programs in the workspace targeting Solana’s BPF runtime and emits IDLs into the target/idl directory:

Terminal window
anchor build --verifiable

Runs 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>:

Terminal window
anchor build -- --features my-feature

Cluster#

anchor cluster list#

Terminal window
anchor cluster list

Lists the cluster endpoints:

Cluster Endpoints:
* Mainnet - https://api.mainnet-beta.solana.com
* Devnet - https://api.devnet.solana.com
* Testnet - https://api.testnet.solana.com

anchor codama#

Terminal window
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#

Terminal window
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#

Terminal window
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#

Terminal window
anchor deploy

Deploys 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#

Terminal window
anchor expand

Expands 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#

Terminal window
anchor idl build

Generates the IDL for the program using the compilation method.

anchor idl init#

Terminal window
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#

Terminal window
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:

Terminal window
anchor idl fetch GrAkKfEpTKQuVHG2Y97Y2FF4i7y7Q5AHLK94JBy7Y5yv

anchor idl authority#

Terminal window
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#

Terminal window
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#

Terminal window
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:

Terminal window
anchor idl set-authority -n <new-authority> -p <program-id>

Sets a new authority on the IDL account. Both new-authority and program-id must be encoded in base 58.

anchor init#

Terminal window
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:

Terminal window
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:

Terminal window
anchor init --anchor-version v1 # Default: Anchor v1 Rust templates
anchor init --anchor-version v2 # Anchor v2 Rust templates

The v2 templates depend on the anchor-next git crates until the v2 release is published.

Keys#

Program keypair commands.

anchor keys list#

Terminal window
anchor keys list

Lists all program keypairs declared in the workspace.

anchor keys sync#

Terminal window
anchor keys sync

Syncs each program’s declare_id!() value with the actual pubkey of its keypair file.

anchor migrate#

Terminal window
anchor migrate

Runs the deploy script located at migrations/deploy.js, injecting a provider configured from the workspace’s Anchor.toml:

migrations/deploy.js
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#

Terminal window
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:

Terminal window
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:

Terminal window
anchor new --anchor-version v1 <program-name> # Default: Anchor v1 Rust templates
anchor new --anchor-version v2 <program-name> # Anchor v2 Rust templates

anchor shell#

Terminal window
anchor shell

Starts 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#

Terminal window
anchor test

Runs 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#

Terminal window
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#

Terminal window
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.

Anchor 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:

Terminal window
avm --help
Anchor 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
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 version

avm 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:

Terminal window
avm install latest
avm install latest-pre-release

You can also install with the following arguments:

Argument exampleDescription
avm install 1.0.0-rc.3Install specific pre-release tag
avm install 0.30.1-cfe82aa682138f7c6c58bf7a78f48f7d63e9e466Install a <version>-<commit> pair
avm install cfe82aa682138f7c6c58bf7a78f48f7d63e9e466Install by full commit hash
avm install cfe82aaInstall by short commit hash

avm list#

List installed and available versions with avm list. Pass --pre-release to include pre-release versions:

Terminal window
avm list --pre-release

avm 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:

Terminal window
avm update --pre-release

avm 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:

Terminal window
avm use latest
avm use latest-pre-release

avm self-update#

Update avm itself with avm self-update. By default this installs the latest stable release of avm.

FlagDescription
--pre-releaseUpdate to the latest pre-release version instead of the latest stable
--bleeding-edgeBuild and install from the latest commit on the master branch (conflicts with --pre-release)
Terminal window
avm self-update
avm self-update --pre-release
avm self-update --bleeding-edge

avm 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#

RustTypeScriptExample
boolbooleantrue

Numbers#

RustTypeScriptExample
u8 / u16 / u32 / i8 / i16 / i32number99
u64 / u128 / i64 / i128anchor.BNnew anchor.BN(99)
f32 / f64number1.0

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#

RustTypeScriptExample
Stringstring"hello"

Collections#

Arrays and vectors#

RustTypeScriptExample
[T; N] (fixed array)Array<T>[1, 2, 3]
Vec<T> (vector)Array<T>[1, 2, 3]

Optional values#

RustTypeScriptExample
Option<T>T | null | undefinednull for None, 42 for Some(42)

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 variant
const one = { one: {} }
// Named variant
const two = {
two: { val: 99 },
}
// Tuple variant
const three = {
three: [12, -34],
}

Example programs

A curated list of example Anchor programs for common patterns and token operations.

Basics#

ExampleDescription
checking-accountsChecking account example with Anchor
close-accountClose account example with Anchor
counterCounter program using Anchor
create-accountCreate accounts with Anchor
cross-program-invocationCross program invocation with Anchor
favoritesStore user “favorites” with Anchor
hello-solanaBasic “Hello, Solana!” program with Anchor
pda-rent-payerPDA rent payer example with Anchor
processing-instructionsProcess instructions using Anchor
program-derived-addressesProgram-derived addresses with Anchor
reallocReallocate account data with Anchor
rentCalculate account SOL rent with Anchor
transfer-solTransfer SOL tokens with Anchor

Tokens#

ExampleDescription
create-tokenCreate an SPL token with Anchor
escrowEscrow program using Anchor
nft-minterMint NFTs using Anchor
nft-operationsNFT operations with Anchor
pda-mint-authorityPDA as mint authority with Anchor
spl-token-minterSPL token minting with Anchor
token-fundraiserToken fundraiser using Anchor
token-swapSwap tokens with Anchor
transfer-tokensTransfer SPL tokens using Anchor

Token extensions#

ExampleDescription
basicsBasics of Token 2022 with Anchor
cpi-guardCPI guard example with Anchor
default-account-stateDefault account state setup with Anchor
groupToken grouping example with Anchor
immutable-ownerImmutable owner setup with Anchor
interest-bearingInterest-bearing tokens using Anchor
memo-transferMemo transfer with Anchor
metadataToken metadata with Anchor
mint-close-authorityMint close authority with Anchor
multiple-extensionsMultiple extensions example with Anchor
nft-meta-data-pointerNFT metadata pointer with Anchor
non-transferableNon-transferable tokens using Anchor
permanent-delegatePermanent delegate setup with Anchor
transfer-feeTransfer fees example with Anchor
transfer-hookTransfer hook example with Anchor
Esc

Start typing to search the docs.