Sol.College

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 directorySource files
tokens419
basics304
games279
compression32
scripts10
cryptography6
oracles2

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.

solana-foundation/program-examples · 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)]
  1. Line 172 AuthorityType::MintTokens,: Mints new tokens. The mint authority must sign.
  2. Line 182 pub signer: Signer<'info>,: Requires this account to have signed the transaction.
  3. Line 184 pub token_program: Program<'info, Token2022>,: Targets the Token-2022 program instead of the original Token Program.
  4. 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.
  5. 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.
  6. 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.
  7. 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.
solana-foundation/program-examples · 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,
  1. Line 76 require!(computed_root.eq(&airdrop_state.merkle_root), ClaimError::InvalidProof);: An explicit validation that aborts the instruction with an error.
  2. 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.
  3. 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.
  4. 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.
  5. Line 84 transfer_checked(: A checked token transfer, which also verifies the mint and decimals.
  6. Line 85 CpiContext::new_with_signer(: Makes a CPI signed by a PDA. The signer seeds prove the program controls that address.
solana-foundation/program-examples · 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>,}
  1. Line 49 token_interface::mint_to(cpi_context, amount)?;: Mints new tokens. The mint authority must sign.
  2. Line 50 msg!("Mint Token");: Logs to the program log, which is visible in explorers and the test output.
  3. Line 59 pub signer: Signer<'info>,: Requires this account to have signed the transaction.
  4. Line 61 init,: Creates and pays for a new account. Space and payer must be specified.
  5. 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.
  6. Line 66 bump,: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
solana-foundation/program-examples · 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(
  1. Line 15 return err!(GameErrorCode::NotEnoughEnergy);: An explicit validation that aborts the instruction with an error.
  2. Line 22 msg!(: Logs to the program log, which is visible in explorers and the test output.
  3. 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.
  4. Line 31 let bump = ctx.bumps.nft_authority;: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
  5. Line 35 invoke_signed(: Makes a CPI signed by a PDA. The signer seeds prove the program controls that address.
  6. 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.

DirectoryCommandRuns
basics/realloc/anchoranchor buildcompile programs and generate IDLs
basics/realloc/anchoranchor testlocal validator + test suite
basics/realloc/anchoranchor run testpnpm mocha --import=tsx -t 1000000 tests/**/*.ts
basics/pda-rent-payer/anchoranchor buildcompile programs and generate IDLs
basics/pda-rent-payer/anchoranchor testlocal validator + test suite
basics/pda-rent-payer/anchoranchor run testpnpm mocha --import=tsx -t 1000000 tests/**/*.ts
basics/favorites/anchoranchor buildcompile programs and generate IDLs
basics/favorites/anchoranchor testlocal validator + test suite
basics/favorites/anchoranchor run testpnpm mocha --import=tsx -t 1000000 tests/**/*.ts
basics/processing-instructions/anchoranchor buildcompile programs and generate IDLs
basics/processing-instructions/anchoranchor testlocal validator + test suite
basics/processing-instructions/anchoranchor run testpnpm mocha --import=tsx -t 1000000 tests/**/*.ts
basics/cross-program-invocation/anchoranchor buildcompile programs and generate IDLs
basics/cross-program-invocation/anchoranchor testlocal validator + test suite
basics/cross-program-invocation/anchoranchor run testpnpm mocha --import=tsx -t 1000000 tests/**/*.ts
basics/checking-accounts/anchoranchor buildcompile programs and generate IDLs

What you could build from it

Used in lessons