Program Patterns Basics
10 examples to get you started with Program Patterns - 7 basic and 3 intermediate.
Prerequisites
- PDAs, CPIs, and serialization basics from prior on-chain-rust sections.
Basic Examples
1. Init account pattern
Create + write discriminator + state.
// 1. create_account CPI 2. set disc 3. serialize State- Reject reinit if lamports > 0.
- Payer signs rent.
- See account initialization patterns.
2. Vault PDA custody
Program holds funds via PDA authority.
// seeds [b"vault", user] + invoke_signed transfers- Business rules before sign.
- Per-user seeds.
- Token + SOL variants.
3. Authority check
Stored pubkey must sign or match PDA.
if !authority.is_signer { return Err(...); }- Role separation admin vs user.
- Two-step ownership transfer.
- Avoid single global admin.
4. State machine enum
Account stores status; ix validate transitions.
enum Status { Open, Filled, Cancelled }- Illegal transition returns error.
- Terminal states reject further ops.
- Emit event on transition.
5. Fee collection
Split amount to treasury on action.
let fee = amount.checked_mul(bps)?.checked_div(10000)?;- Checked math.
- Treasury PDA or ATA.
- Document fee bps immutably or via config.
6. Clock-based expiry
Read Clock sysvar for deadlines.
let clock = Clock::get()?;
if clock.unix_timestamp > deadline { return Err(...); }- Slots vs unix time.
- Validator clock trustworthy within bounds.
- Grace periods explicit.
7. Close account
Zero data, transfer lamports, mark closed.
// zero data, transfer rent to recipient- Prevent revival attacks.
- Only authority may close.
- Anchor
closeconstraint pattern.
Intermediate Examples
8. Escrow release
Conditions + token CPI from escrow PDA.
// verify + invoke_signed token transfer- CEI ordering.
- Reentrancy aware.
- See vault & escrow page.
Related: Vault & Escrow
9. Config account
Global params with admin rotate.
struct Config { admin: Pubkey, fee_bps: u16 }- Timelock optional.
- Bounds on fee_bps.
- Upgrade-safe layout.
Related: Access Control & Authorities
10. Versioned schema
Migration ix for layout v2.
if version == 1 { migrate_v1_to_v2()? }- Lazy migration.
- Dual-read window.
- See upgrade-safe design.
Related: Upgrade-Safe Data Design
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.