Hands-on Solana learning repo with small daily programs (day_1 to day_X) and TypeScript tests.
This README is written for learning: each section explains what to run and why it matters.
- How to write Anchor programs in Rust.
- How to call instructions from TypeScript tests.
- How account validation works (
Context<...>and#[derive(Accounts)]). - How errors and
require!behave in Solana programs. - How IDL files connect on-chain Rust code to off-chain clients.
- How to build, deploy, and test each program on localnet.
programs/
day_1 ... day_X/ # Solana programs (Rust + Anchor)
tests/
day_1.ts ... day_5.ts # Client-side tests (TypeScript + Anchor)
Anchor.toml # Program IDs, localnet config, test script
Makefile # Day-specific deploy/test shortcuts
Install and verify:
- Rust (toolchain in this repo is pinned in
rust-toolchain.toml). - Solana CLI (
solana --version). - Anchor CLI (
anchor --version). - Node.js + Yarn (
node -v,yarn -v).
If your wallet is not set up yet:
solana-keygen new
solana config set --url http://127.0.0.1:8899Install JavaScript dependencies:
yarn installBuild all programs:
anchor buildStart local validator (terminal 1):
solana-test-validator --resetRun tests against that validator (terminal 2):
anchor test --skip-local-validator- File:
programs/day_1/src/lib.rs - Test:
tests/day_1.ts - Goal: call a basic instruction (
initialize) and confirm your local setup works.
- File:
programs/day_2/src/lib.rs - Test:
tests/day_2.ts - Goal: pass
u64,String, andVec<u64>from TypeScript into Rust. - Practice safe math with
checked_add,checked_sub,checked_mul,checked_div, andchecked_pow.
- File:
programs/day_3/src/lib.rs - Test:
tests/day_3.ts - Goal: compare an instruction with required signer accounts vs an instruction with empty accounts.
- File:
programs/day_4/src/lib.rs - Test:
tests/day_4.ts - Goal: use
require!and custom#[error_code]enums, then assert those errors in tests.
- File:
programs/day_5/src/lib.rs - Test:
tests/day_5.ts - Goal: instantiate an Anchor
Programclient manually fromtarget/idl/day_5.json.
- File:
programs/day_6/src/lib.rs - Goal: starter module ready for extending with new topics.
solana-test-validator
solana-test-validator --resetanchor build
anchor keys syncmake test DAY=day_2
# or shortcut:
make test-day_2anchor test --skip-local-validatorsolana address
solana balance
solana airdrop 2solana logs
ls .anchor/program-logs/Many examples use u64 because it is a common integer type for balances, counters, and amounts.
In TypeScript tests, pass large integers using BN (bn.js) to avoid JavaScript number limits.
Rust can panic on overflow depending on build settings, but in on-chain code you should prefer explicit safe math:
checked_*returnsOption<T>.- Handle
Noneand return a program error when needed.
This repo shows safe math patterns in day_2.
Each transaction has a compute budget. If your instruction uses too much compute, the transaction fails. Small code choices can change compute usage, so test and measure while optimizing.
Anchor generates IDL JSON files under target/idl/.
IDL describes instruction names, arguments, and account requirements so clients can call your program safely.
Equivalent mental model for Solidity developers: IDL is similar to ABI metadata.
Note: Rust snake_case instruction names become camelCase in TypeScript clients.
Use require!(condition, CustomError) for guard checks.
If a condition fails, your instruction returns an error and the transaction is reverted.
day_4 demonstrates both success and failure test cases.
Reference: https://www.anchor-lang.com/docs/features/errors
Anchor deploys upgradeable programs by default (upgrade authority exists).
You can upgrade while authority is active; removing authority makes the program immutable.
For tests, --skip-deploy or --skip-local-validator helps target an already running environment.
- Start validator:
solana-test-validator --reset - Build programs:
anchor build - Run one lesson:
make test DAY=day_4 - Inspect logs:
solana logs - Modify program logic and rerun the same day
Repeat this loop until you can explain both the Rust instruction and the TypeScript call path.
AccountNotFoundor signer errors: verify account constraints in the instructionContext.- Program ID mismatch:
run
anchor keys syncand rebuild. - Wallet has no SOL:
run
solana airdrop 2. - Tests target wrong RPC:
ensure provider points to localnet (
http://127.0.0.1:8899).