PDAs in Anchor Best Practices
Deterministic, validated PDA usage across program and clients.
How to Use This List
- Apply to every new PDA introduced in a program.
- Share seed constants between Rust and TypeScript.
- Test derivation in anchor test and kit client.
A - Derivation
- Document seeds in IDL docs or shared constants module clients must match byte-for-byte.
- Store canonical bump at init reference in later instructions.
- Use typed Account constraints not UncheckedAccount for PDAs.
- Keep seeds minimal long seed arrays cost CU.
B - Signing and CPIs
- Use ctx.bumps or stored bump in CPI signers never guess bump.
- Split treasury PDAs per market limit blast radius.
- Verify mint/ATA authority matches PDA on every token CPI.
FAQs
What Anchor version is assumed?
0.32.1 throughout this section.
Can a PDA be a Signer in accounts struct?
No. Use seeds constraints and CPI signing.
Where is bump stored?
In your account struct field, set at initialization.
How do clients derive PDAs?
Use @solana/kit 7.0.0 with matching seed bytes.
What program id is used for PDAs?
Your Anchor program's declare_id address.
Do seeds include bump?
Not in seeds array; bump is separate parameter to find_program_address.
How to debug PDA failures?
Compare logged keys; verify seeds and program id client-side.
Are PDAs rent-exempt?
Yes when holding data; fund with payer on init.
Can one PDA sign multiple CPIs in one ix?
Yes with same signer seeds for each CPI.
What to read next?
See Related links for deeper pdas bp topics.
Related
- PDAs in Anchor - intro
- Common PDA Mistakes - audit list
- Signing with PDAs - CPI signing
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.