CPIs in Anchor Best Practices
Typed, safe, minimal cross-program calls for production Anchor 0.32.1 programs.
How to Use This List
- Review every new CPI in security PRs.
- Pin external IDLs used by declare_program!.
- Simulate CPI-heavy instructions on devnet.
A - Validation
- Use Program<T> for every CPI target never unchecked program accounts.
- Validate remaining_accounts before forward owner, discriminator, freshness.
- Cap remaining account count prevent CU griefing.
- Pin callee IDL version in repo with release tags.
B - Signing
- Use with_signer only with validated PDAs seeds enforced in struct.
- Prefer ctx.bumps over recomputing canonical bump.
- Avoid CPI in constraint expressions keep side effects in handlers.
FAQs
Anchor 0.32.1 error format?
Custom codes in IDL plus #[msg] strings.
emit! vs emit_cpi!?
emit_cpi! costs more CU but improves capture reliability.
Should I use msg! on mainnet?
Avoid except behind feature flags.
How do clients get error codes?
From IDL via Anchor or Codama codegen.
Do events appear in IDL?
Yes, #[event] types are listed.
Can constraints return custom errors?
Yes with @ MyError::Variant.
What uses CU in logging?
Each log line and formatted string.
How to test errors?
anchor test expecting error codes.
Are logs consensus data?
Yes, but not an API contract; use events.
Next read?
See Related for cpi bp.
Related
- CPI Basics in Anchor - intro
- CPI Safety - threats
- Instructions Best Practices - handlers
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.