Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.arcium.com/llms.txt

Use this file to discover all available pages before exploring further.

This guide covers upgrading from v0.9.x to v0.10.x. The main breaking changes come from the Anchor v1 / Solana CLI 3 toolchain bump, removed key-recovery helper APIs, and a few Arcium helper signature changes. v0.10.x also adds close-account commands, an interruptible migrate-cluster, Arcis match / if let / matches! support, and an update-notification banner.

Before you start

v0.10.x is a code-and-toolchain upgrade. Existing v0.9.x MXE, cluster, and key-recovery accounts remain compatible. Computation definitions initialized with finalization_authority = None remain layout-compatible. In v0.9.x, this was the third argument to init_comp_def. Recreate or validate any v0.9.x computation definition that used Some(finalization_authority) before relying on it. Only redeploy your app program if you rebuild or change it for v0.10.x.
This guide covers Arcium-specific migration work. Anchor v1 has additional program, interface definition language (IDL), dependency, and CI changes. Before deploying a rebuilt program, run through Solana Foundation’s Anchor v0.32 to v1 migration checklist, especially if your program publishes an on-chain IDL, uses declare_program!, raw AccountInfo, direct SPL Token dependencies, Borsh helpers, or external cross-program invocation (CPI) crates. Close legacy IDL accounts with the v0.32 CLI while the old program is still live.

1. Update Arcium tooling

arcup self update
arcup update
Verify:
arcium --version
You should see 0.10.3.

2. Update Solana and Anchor toolchains

Both toolchains have major version bumps. Install them before rebuilding. Solana CLI 3.1.10 (was 2.3.0):
sh -c "$(curl -sSfL https://release.anza.xyz/v3.1.10/install)"
solana --version
Anchor 1.0.2 (was 0.32.1). The avm source moved from coral-xyz/anchor to solana-foundation/anchor:
cargo install --git https://github.com/solana-foundation/anchor avm --locked --force
avm install 1.0.2
avm use 1.0.2
anchor --version

3. Update Rust dependencies

In your program’s Cargo.toml:
# Before
anchor-lang = { version = "0.32.1", features = ["init-if-needed"] }
anchor-spl  = "0.32.1"

# After
anchor-lang = { version = "1.0.2", features = ["init-if-needed"] }
anchor-spl  = "1.0.2"
Refresh the Arcium crate locks from your project root:
cargo update --manifest-path programs/your-program-name/Cargo.toml --package arcium-client --precise 0.10.3
cargo update --manifest-path programs/your-program-name/Cargo.toml --package arcium-macros --precise 0.10.3
cargo update --manifest-path programs/your-program-name/Cargo.toml --package arcium-anchor --precise 0.10.3
cargo update --manifest-path encrypted-ixs/Cargo.toml --package arcis --precise 0.10.3
If your encrypted-ixs/Cargo.toml pins blake3 or proc-macro-crate, you can drop those pins — they were Anchor 0.32 workarounds and are no longer needed.
This is the minimum Arcium dependency bump. Use the Anchor v1 checklist linked in Before you start for workspace resolver, direct solana-* crates, LiteSVM, SPL Token interface crates, and external cross-program invocation (CPI) dependencies.

4. Update TypeScript dependencies

The Anchor npm package was renamed:
// Before
"@coral-xyz/anchor": "0.32.1"

// After
"@anchor-lang/core": "^1.0.2"
Bump the Arcium clients to 0.10.3:
npm uninstall @coral-xyz/anchor
npm install @anchor-lang/core@^1.0.2 @arcium-hq/client@0.10.3 @arcium-hq/reader@0.10.3
Update every import:
// Before
import * as anchor from "@coral-xyz/anchor";
import { Program, AnchorProvider, BN } from "@coral-xyz/anchor";

// After
import * as anchor from "@anchor-lang/core";
import { Program, AnchorProvider, BN } from "@anchor-lang/core";
TypeScript is also bumped to ^5.7.3 (was ^4.3.5) — update if you pin it.

5. Anchor program changes

This section covers the Anchor v1 changes that commonly show up in Arcium programs. It is not a full Anchor v1 migration checklist.

Instructions sysvar address constant

anchor_lang::solana_program::sysvar::instructions no longer exists. Use the constant re-exported by arcium-anchor, and switch AccountInfo to UncheckedAccount (Anchor 1 no longer accepts AccountInfo<'info> in account structs):
// Before
#[account(address = ::anchor_lang::solana_program::sysvar::instructions::ID)]
/// CHECK: instructions_sysvar, checked by the account constraint
pub instructions_sysvar: AccountInfo<'info>,

// After
#[account(address = ::arcium_anchor::solana_instructions_sysvar::ID)]
/// CHECK: instructions_sysvar, checked by the account constraint
pub instructions_sysvar: UncheckedAccount<'info>,

Box-wrap heavy accounts on the queue side

Anchor 1 tightened stack-frame limits. Large Arcium accounts (MXEAccount, Cluster, ComputationDefinitionAccount) blow the stack on the queue path unless boxed. Wrap them in Box<...> in your #[queue_computation_accounts] struct:
// Before
pub mxe_account:      Account<'info, MXEAccount>,
pub cluster_account:  Account<'info, Cluster>,
pub comp_def_account: Account<'info, ComputationDefinitionAccount>,

// After
pub mxe_account:      Box<Account<'info, MXEAccount>>,
pub cluster_account:  Box<Account<'info, Cluster>>,
pub comp_def_account: Box<Account<'info, ComputationDefinitionAccount>>,
Callback-side accounts (#[callback_accounts]) can stay un-boxed — the callback path has less stack pressure.

Computation-definition helper changes

Replace deprecated init_comp_def calls with init_computation_def. The old third finalization_authority argument was removed:
// Before
init_comp_def(ctx.accounts, None, None)?;

// After
init_computation_def(ctx.accounts, None)?;
Generated init*CompDef TypeScript methods also no longer take a finalizationAuth argument:
// Before
await program.methods.initAddTogetherCompDef(finalizationAuth).rpc();

// After
await program.methods.initAddTogetherCompDef().rpc();
The PDA helpers that took ErrorCode::ClusterNotSet now use one-argument forms. The MXE cluster is non-optional in v0.10.x, so the macros read mxe_account.cluster directly and no longer need a caller-supplied local error:
// Before
derive_mempool_pda!(mxe_account, ErrorCode::ClusterNotSet)
derive_execpool_pda!(mxe_account, ErrorCode::ClusterNotSet)
derive_comp_pda!(computation_offset, mxe_account, ErrorCode::ClusterNotSet)
derive_cluster_pda!(mxe_account, ErrorCode::ClusterNotSet)

// After
derive_mempool_pda!(mxe_account)
derive_execpool_pda!(mxe_account)
derive_comp_pda!(computation_offset, mxe_account)
derive_cluster_pda!(mxe_account)
If ErrorCode::ClusterNotSet was the only reason your #[error_code] enum defined it, you can remove the variant to keep the IDL clean and avoid a dead-code warning. (The variant still exists in Arcium’s core error enum; this is purely about your own program’s local enum.)
// Optional cleanup if no longer referenced
#[error_code]
pub enum ErrorCode {
    #[msg("The computation was aborted")]
    AbortedComputation,
    // Removed: ClusterNotSet — was only used by the deprecated PDA macro args above.
}

SPL token CPI: pass Pubkey, not AccountInfo

CpiContext::new / new_with_signer now expect a Pubkey for the program argument:
// Before
let cpi_program = ctx.accounts.token_program.to_account_info();

// After
let cpi_program = ctx.accounts.token_program.key();
This only affects programs that do SPL transfers.

6. TypeScript client changes

Beyond the package rename:

initMxePart2 argument order changed

recoveryPeers moved from position 4 to position 6. Positional callers will silently pass wrong values — review every call site.
// Before
initMxePart2(
  provider,
  clusterOffset,
  mxeProgramId,
  recoveryPeers,
  keygenOffset,
  keyRecoveryInitOffset,
  lutOffset,
);

// After
initMxePart2(
  provider,
  clusterOffset,
  mxeProgramId,
  keygenOffset,
  keyRecoveryInitOffset,
  recoveryPeers,
  lutOffset,
);
The following helpers were removed from @arcium-hq/client — key recovery now runs through CLI flows (arcium init-mxe --resume and arcium migrate-cluster --resume):
  • queueKeyRecoveryInit
  • recoverMxe
  • initKeyRecoveryExecution
  • submitKeyRecoveryShare
  • finalizeKeyRecoveryExecution
If your @arcium-hq/reader code subscribes to computation events, the callback parameter type narrowed from ArciumEventData to ComputationEventData. The runtime shape is unchanged; update annotations only. Avoid asserting a fixed number of cluster accounts in tests. Localnet runs without a recovery cluster can return only the primary cluster account:
// Brittle — assumes the localnet always has a recovery cluster
expect(clusterAccs.length).to.equal(2);

// After — filter by offset instead
const primary = clusterAccs.find(c => c.offset === clusterOffset);

7. CLI changes

init-key-recovery-material and migrate-cluster --skip-recovery have been removed. Their replacements are split by lifecycle:
  • interrupted MXE initialization / key-recovery-material setup: rerun arcium init-mxe --resume
  • interrupted cluster migration: use arcium migrate-cluster --resume or --abort
# Resume an interrupted cluster migration
arcium migrate-cluster <mxe-program-id> \
  --keypair-path <path-to-your-keypair> \
  --rpc-url <your-rpc-url> \
  --resume

# Abort a stuck cluster migration
arcium migrate-cluster <mxe-program-id> \
  --keypair-path <path-to-your-keypair> \
  --rpc-url <your-rpc-url> \
  --abort
--cluster-offset is required on the initial call only; with --resume/--abort the CLI infers it from on-chain state.

init-mxe --resume now covers key-recovery material

arcium init-mxe --resume existed in v0.9.x. In v0.10.x it also resumes the key-recovery-material step that used to live behind init-key-recovery-material. Keep passing --recovery-set-size <N>. The minimum is 4, but larger clusters may require more. If the value does not match on-chain state, the CLI prints the expected --cluster-offset and --recovery-set-size.
arcium init-mxe \
  --keypair-path ~/.config/solana/id.json \
  --callback-program <mxe-program-id> \
  --cluster-offset <offset> \
  --recovery-set-size 8 \
  --rpc-url <your-rpc-url> \
  --resume

arcium test --detach skips the auto-snapshot

Non-detached arcium test runs now auto-call arcium snapshot-mxe-keygen at the end so subsequent --skip-keygen runs can reuse cached MXE keys. With --detach this step is skipped — the validator outlives the CLI, so you must call arcium snapshot-mxe-keygen --rpc-url l yourself before tearing the validator down:
arcium test --detach
# ... interact with the running validator ...
arcium snapshot-mxe-keygen --rpc-url l
# then teardown

--skip-keygen exports ARCIUM_SKIP_KEY_RECOVERY_INIT=1

When arcium test --skip-keygen or arcium localnet --skip-keygen reuses cached MXE keys, the CLI also sets ARCIUM_SKIP_KEY_RECOVERY_INIT=1 in the test environment. Use it to skip legacy key-recovery-init setup when the MXE starts in a post-keygen state. Custom tests that always queue key-recovery-init will fail on --skip-keygen reruns without honoring this flag.

arcium test --test-name rewrites Anchor.toml

--test-name <name> runs only tests/<name>.ts by temporarily rewriting the [scripts] test glob in Anchor.toml from *.ts to <name>.ts. The CLI reverts the file on success — if a run terminates abnormally (Ctrl-C, SIGKILL), the rewrite may persist. Restore the original glob manually if so.

arcium mxe-info output changes

Two cosmetic shifts in mxe-info output: Ed25519 verifying key was renamed to ArcisEd25519 pubkey, and a new Key recovery material status: Ok|Not finalized line was added. Scripts parsing mxe-info output need updating. For closing MXEs and computation definitions, see Account lifecycle and closing.

8. Anchor.toml cleanup

The [registry] block was stale in v0.9.x scaffolds and can be removed:
# Stale — remove
[registry]
url = "https://api.apr.dev"
The [test.validator] startup_wait = 10000 block is optional and scaffold-dependent — the v0.10.3 example programs drop it, but arcium init still appends it for new projects. Leave it in place if your tests need the longer validator startup wait. Some v0.10.3 examples include an empty [hooks] section; matching it is optional.

9. Arcis circuit changes

Item shadowing of a let-binding is now rejected. Code like this used to compile and won’t anymore:
// Rejected in v0.10.x
let f = || false;
fn f() -> bool { true }
f();
A let can still shadow a previous let — only mixing items (fn, const) with same-named values is rejected. Arcis also gained match, if let, and matches! support. Let chains require edition = "2024" in encrypted-ixs/Cargo.toml. See Operations.

10. Node operators

Update your Docker image tag in docker-compose.yml:
# Before
image: arcium/arx-node:v0.9.7

# After
image: arcium/arx-node:v0.10.3
Then pull and restart:
docker compose pull
docker compose up -d
If you run a trusted dealer, the config schema changed: fields moved under a [dealer] section, local_addr was renamed to local_ip, and a new required master_seed_path was added. Treat master_seed_path as the highest-sensitivity host secret — leaking it compromises all keyshares. See Node Setup.

11. Troubleshooting

  • Anchor/sysvar compile errors: check Anchor program changes.
  • init_comp_def not found: use init_computation_def(ctx.accounts, None) or the OffChain form in Computation Definition Accounts.
  • PDA helper macro arity errors: remove the second ErrorCode::ClusterNotSet argument.
  • init-key-recovery-material missing: rerun arcium init-mxe --resume.
  • migrate-cluster --skip-recovery missing: use --resume or --abort.
  • Other Anchor v1 compile errors: run through the Anchor v0.32 to v1 checklist linked in Before you start.
  • Close-account errors: see Account lifecycle and closing.

12. Verify migration

Before deploying, complete the Anchor v1 checklist linked in Before you start, including legacy IDL cleanup if your program publishes an on-chain IDL.
arcium build
cargo check --all
arcium test

13. Changes summary

Changev0.9.xv0.10.x
Solana CLI2.3.03.1.10
Anchor CLI0.32.11.0.2
avm sourcecoral-xyz/anchorsolana-foundation/anchor
anchor-lang / anchor-spl0.32.11.0.2
npm Anchor package@coral-xyz/anchor@anchor-lang/core
TypeScript^4.3.5^5.7.3
Instructions sysvar::anchor_lang::solana_program::sysvar::instructions::ID::arcium_anchor::solana_instructions_sysvar::ID
Sysvar field typeAccountInfo<'info>UncheckedAccount<'info>
Queue-side MXE accountsAccount<'info, MXEAccount>Box<Account<'info, MXEAccount>> (same for Cluster, CompDef)
SPL CPI program argtoken_program.to_account_info()token_program.key()
Comp-def init helperinit_comp_def(ctx.accounts, None, None)init_computation_def(ctx.accounts, None)
Generated comp-def TSinitFooCompDef(finalizationAuth)initFooCompDef()
PDA helper arityderive_*_pda!(..., ErrorCode::ClusterNotSet)derive_*_pda!(...)
initMxePart2 arg orderrecoveryPeers at position 4recoveryPeers at position 6
Key recovery TS helpersrecoverMxe, queueKeyRecoveryInit, submitKeyRecoveryShare, …Removed — driven by init-mxe --resume / migrate-cluster --resume
migrate-cluster flags--skip-recovery--resume / --abort state machine
init-key-recovery-materialCLI subcommandRemoved (folded into init-mxe --resume)
Arx Node Dockerv0.9.7v0.10.3
Arcium Rust crates0.9.x0.10.3
TypeScript clients@arcium-hq/{client,reader}@0.9.x@arcium-hq/{client,reader}@0.10.3

New in v0.10.x

These features are new in v0.10.x. See the linked documentation for details:
  • Close MXE / computation definition: arcium deactivate-computation-definition → TTL → close-computation-definition and close-mxe reclaim rent from accounts you no longer need. See Account lifecycle and closing.
  • Interruptible cluster migration: arcium migrate-cluster --resume / --abort replace --skip-recovery. arcium init-mxe --resume also resumes key-recovery-material setup. See Deployment.
  • Faster localnet reruns: arcium snapshot-mxe-keygen --rpc-url l + arcium localnet --skip-keygen / arcium test --skip-keygen reuse cached MXE keys between runs.
  • Run a single test: arcium test --test-name <name> restricts the run to tests/<name>.ts.
  • Arcis pattern matching: match, if let, and the matches! macro are now supported. Let chains require edition = "2024" in encrypted-ixs/Cargo.toml. See Operations.
  • Update-notification banner: arcium and arcup show a one-line banner when a new release is available. Suppress with ARCIUM_NO_UPDATE_CHECK=1; the banner is automatically silent in CI.
  • Better callback failure errors: callback failures now report a CircuitFailureReason (off-chain fetch failed, hash mismatch, CU mismatch, serialization, …) instead of a single generic error.
  • arcup version: prints the currently-active toolchain version (alias arcup v).

What’s next?

Deployment

Deploy and manage your MXE.

Arcis Operations

Use the new pattern-matching syntax in your circuits.