PDA Basics
10 examples to get you started with PDAs - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with PDAs - 7 basic and 3 intermediate.
solana address helpers off-chain.Clients find PDA + bump before building transactions.
use solana_program::pubkey::Pubkey;
let program_id = Pubkey::new_unique();
let (pda, bump) = Pubkey::find_program_address(&[b"vault"], &program_id);find_program_address tries bumps 255..0.Transactions reference the PDA pubkey like any account.
// AccountMeta::new(pda, false) - PDA is not a wallet signerinvoke_signed.Seeds are byte strings - pubkeys, strings, numbers.
let seeds: &[&[u8]] = &[b"escrow", buyer.as_ref(), seller.as_ref()];Changing program id changes PDA address.
Pubkey::find_program_address(seeds, program_id);End users never hold PDA private keys.
// Only the owning program can sign for PDA via invoke_signedPDAs are intentionally off ed25519 curve.
// Off-chain: Pubkey::create_program_address validates bumpcreate_program_address fails if on-curve.find_program_address searches valid bump.Only the deriving program can sign for PDA.
invoke_signed(&ix, accounts, &[&[b"vault", &[bump]]])?;Save bump at init to avoid search on-chain.
pub struct Vault { pub bump: u8, pub total: u64 }seeds[bump] == stored_bump on each ix.Related: Canonical Bumps - bump storage
Token accounts can use PDA as authority.
// seeds: [b"token", mint.key.as_ref(), owner.as_ref()]invoke_signed.Related: PDAs as Authorities - vaults
Different seed sets should not collide semantically.
const PREFIX_VAULT: &[u8] = b"vault";
const PREFIX_ESCROW: &[u8] = b"escrow";Related: Seed Design & Collisions - design rules
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.
Reviewed by Chris St. John·Last updated Jul 16, 2026