Full lesson
program-examples
A repository of Solana program examples
What it does
From the project README:
[](https://github.com/solana-developers/program-examples/actions/workflows/anchor.yml) [](https://github.com/solana-developers/program-examples/actions/workflows/solana-pinocchio.yml) [](https://github.com/solana-developers/program-examples/actions/workflows/solana-native.yml)
- Original
- solana-foundation/program-examples
- SuperStack fork
- Blockchains/program-examples @
de09019 - Stars
- 1,435
- Last push (original)
- 2026-11-02
- Languages
- Rust, TypeScript, Shell, Assembly, Just, JavaScript
- Detected stack
- @solana/kitAnchorMetaplexNext.jsPinocchioweb3.js
- Categories
- Infrastructure & Tooling
- Licence
- MIT
Architecture
1052 source files. By extension: .rs ×525, .ts ×391, .tsx ×132, .js ×4.
| Top-level directory | Source files |
|---|---|
tokens | 419 |
basics | 304 |
games | 279 |
compression | 32 |
scripts | 10 |
cryptography | 6 |
oracles | 2 |
On-chain programs: basics/account-data/anchor/programs/anchor-program-example, basics/checking-accounts/anchor/programs/anchor-program-example, basics/close-account/anchor/programs/close-account, basics/counter/anchor/programs/counter_anchor, basics/create-account/anchor/programs/create-system-account, basics/cross-program-invocation/anchor/programs/hand, basics/cross-program-invocation/anchor/programs/lever, basics/cross-program-invocation/native/programs/hand
Dapp: deploying
This fork is queued for its own live dapp on Sol.College, with a Devnet/Mainnet switch. It appears here, at /dapps/program-examples/, once it is deployed and checked on devnet. Until then, run it locally with the commands below.
Key code, explained
Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.
tokens/token-2022/nft-meta-data-pointer/anchor/programs/extension_nft/src/instructions/mint_nft.rs L169–192 @ de09019 · MIT · original }, signer ), AuthorityType::MintTokens, None )?; Ok(())} #[derive(Accounts)]pub struct MintNft<'info> { #[account(mut)] pub signer: Signer<'info>, pub system_program: Program<'info, System>, pub token_program: Program<'info, Token2022>, /// CHECK: We will create this one for the user #[account(mut)] pub token_account: AccountInfo<'info>, #[account(mut)] pub mint: Signer<'info>, pub rent: Sysvar<'info, Rent>, pub associated_token_program: Program<'info, AssociatedToken>, #[account(init_if_needed, seeds = [b"nft_authority".as_ref()], bump, space = 8, payer = signer)]- Line 172
AuthorityType::MintTokens,: Mints new tokens. The mint authority must sign. - Line 182
pub signer: Signer<'info>,: Requires this account to have signed the transaction. - Line 184
pub token_program: Program<'info, Token2022>,: Targets the Token-2022 program instead of the original Token Program. - Line 192
#[account(init_if_needed, seeds = [b"nft_authority".as_ref()], bump, space = 8, payer = si: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 192
#[account(init_if_needed, seeds = [b"nft_authority".as_ref()], bump, space = 8, payer = si: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 192
#[account(init_if_needed, seeds = [b"nft_authority".as_ref()], bump, space = 8, payer = si: Creates the account only if it doesn't exist. Watch for re-initialisation bugs. - Line 192
#[account(init_if_needed, seeds = [b"nft_authority".as_ref()], bump, space = 8, payer = si: Creates and pays for a new account. Space and payer must be specified.
tokens/merkle-tree-token-claimer/anchor/programs/merkle-tree-token-claimer/src/lib.rs L73–96 @ de09019 · MIT · original let computed_root = compute_merkle_root(&leaf, &hashes, index)?; require!(computed_root.eq(&airdrop_state.merkle_root), ClaimError::InvalidProof); let new_amount_claimed = airdrop_state.amount_claimed.checked_add(amount).ok_or(ClaimError::AmountOverflow)?; require!(new_amount_claimed <= airdrop_state.airdrop_amount, ClaimError::ClaimExceedsAirdrop); let mint_key = ctx.accounts.mint.key().to_bytes(); let signer_seeds = &[b"merkle_tree".as_ref(), mint_key.as_ref(), &[airdrop_state.bump]]; transfer_checked( CpiContext::new_with_signer( ctx.accounts.token_program.key(), TransferChecked { from: ctx.accounts.vault.to_account_info(), mint: ctx.accounts.mint.to_account_info(), to: ctx.accounts.signer_ata.to_account_info(), authority: airdrop_state.to_account_info(), }, &[signer_seeds], ), amount, ctx.accounts.mint.decimals,- Line 76
require!(computed_root.eq(&airdrop_state.merkle_root), ClaimError::InvalidProof);: An explicit validation that aborts the instruction with an error. - Line 78
let new_amount_claimed = airdrop_state.amount_claimed.checked_add(amount).ok_or(ClaimError: Uses checked arithmetic so overflow fails instead of wrapping. - Line 82
let signer_seeds = &[b"merkle_tree".as_ref(), mint_key.as_ref(), &[airdrop_state.bump]];: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 82
let signer_seeds = &[b"merkle_tree".as_ref(), mint_key.as_ref(), &[airdrop_state.bump]];: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 84
transfer_checked(: A checked token transfer, which also verifies the mint and decimals. - Line 85
CpiContext::new_with_signer(: Makes a CPI signed by a PDA. The signer seeds prove the program controls that address.
tokens/token-2022/basics/anchor/programs/basics/src/lib.rs L49–71 @ de09019 · MIT · original token_interface::mint_to(cpi_context, amount)?; msg!("Mint Token"); Ok(()) }} #[derive(Accounts)]#[instruction(token_name: String)]pub struct CreateToken<'info> { #[account(mut)] pub signer: Signer<'info>, #[account( init, payer = signer, mint::decimals = 6, mint::authority = signer.key(), seeds = [b"token-2022-token", signer.key().as_ref(), token_name.as_bytes()], bump, )] pub mint: InterfaceAccount<'info, Mint>, pub system_program: Program<'info, System>, pub token_program: Interface<'info, TokenInterface>,}- Line 49
token_interface::mint_to(cpi_context, amount)?;: Mints new tokens. The mint authority must sign. - Line 50
msg!("Mint Token");: Logs to the program log, which is visible in explorers and the test output. - Line 59
pub signer: Signer<'info>,: Requires this account to have signed the transaction. - Line 61
init,: Creates and pays for a new account. Space and payer must be specified. - Line 65
seeds = [b"token-2022-token", signer.key().as_ref(), token_name.as_bytes()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 66
bump,: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
tokens/token-2022/nft-meta-data-pointer/anchor/programs/extension_nft/src/instructions/chop_tree.rs L13–36 @ de09019 · MIT · original if account.player.energy < amount { return err!(GameErrorCode::NotEnoughEnergy); } account.player.last_id = counter; account.player.chop_tree(amount)?; account.game_data.on_tree_chopped(amount)?; msg!( "You chopped a tree and got 1 wood. You have {} wood and {} energy left.", ctx.accounts.player.wood, ctx.accounts.player.energy ); // We use a PDA as a mint authority for the metadata account because we want to be able to update the NFT from // the program. let seeds = b"nft_authority"; let bump = ctx.bumps.nft_authority; let signer: &[&[&[u8]]] = &[&[seeds, &[bump]]]; // Update the metadata account with an additional metadata field in this case the player level invoke_signed( &anchor_spl::token_2022_extensions::spl_token_metadata_interface::instruction::update_field(- Line 15
return err!(GameErrorCode::NotEnoughEnergy);: An explicit validation that aborts the instruction with an error. - Line 22
msg!(: Logs to the program log, which is visible in explorers and the test output. - Line 30
let seeds = b"nft_authority";: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 31
let bump = ctx.bumps.nft_authority;: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 35
invoke_signed(: Makes a CPI signed by a PDA. The signer seeds prove the program controls that address. - Line 36
&anchor_spl::token_2022_extensions::spl_token_metadata_interface::instruction::update_fiel: Targets the Token-2022 program instead of the original Token Program.
How to run, build and test
These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.
| Directory | Command | Runs |
|---|---|---|
basics/realloc/anchor | anchor build | compile programs and generate IDLs |
basics/realloc/anchor | anchor test | local validator + test suite |
basics/realloc/anchor | anchor run test | pnpm mocha --import=tsx -t 1000000 tests/**/*.ts |
basics/pda-rent-payer/anchor | anchor build | compile programs and generate IDLs |
basics/pda-rent-payer/anchor | anchor test | local validator + test suite |
basics/pda-rent-payer/anchor | anchor run test | pnpm mocha --import=tsx -t 1000000 tests/**/*.ts |
basics/favorites/anchor | anchor build | compile programs and generate IDLs |
basics/favorites/anchor | anchor test | local validator + test suite |
basics/favorites/anchor | anchor run test | pnpm mocha --import=tsx -t 1000000 tests/**/*.ts |
basics/processing-instructions/anchor | anchor build | compile programs and generate IDLs |
basics/processing-instructions/anchor | anchor test | local validator + test suite |
basics/processing-instructions/anchor | anchor run test | pnpm mocha --import=tsx -t 1000000 tests/**/*.ts |
basics/cross-program-invocation/anchor | anchor build | compile programs and generate IDLs |
basics/cross-program-invocation/anchor | anchor test | local validator + test suite |
basics/cross-program-invocation/anchor | anchor run test | pnpm mocha --import=tsx -t 1000000 tests/**/*.ts |
basics/checking-accounts/anchor | anchor build | compile programs and generate IDLs |
What you could build from it
- Fork the SuperStack copy and extend it within the Infrastructure & Tooling gaps listed on the idea page.
- Learn the pattern first: Building and sending transactions from a client
- Learn the pattern first: Anchor account constraints