Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Quicknode Solana Program Examples

> A fork of the [Solana Foundation program examples](https://github.com/solana-developers/program-examples) with current versions, more programs, and additional frameworks.
> A fork of the [Solana Foundation program examples](https://github.com/solana-developers/program-examples) with current versions, more [programs](https://solana.com/docs/terminology#program), and additional frameworks.

[![Anchor](../../actions/workflows/anchor.yml/badge.svg)](../../actions/workflows/anchor.yml) [![Quasar](../../actions/workflows/quasar.yml/badge.svg)](../../actions/workflows/quasar.yml) [![Pinocchio](../../actions/workflows/pinocchio.yml/badge.svg)](../../actions/workflows/pinocchio.yml) [![Native](../../actions/workflows/native.yml/badge.svg)](../../actions/workflows/native.yml) [![ASM](../../actions/workflows/solana-asm.yml/badge.svg)](../../actions/workflows/solana-asm.yml)

Expand All @@ -13,7 +13,7 @@ Each example is available in one or more of the following frameworks:
- [🧬 ASM](https://github.com/blueshift-gg/sbpf) — hand-written sBPF assembly built with the `sbpf` toolchain. Run `pnpm build-and-test` to build and test.

> [!NOTE]
> You don't need to write your own program for basic tasks like creating accounts, transferring SOL, or minting tokens. These are handled by existing programs like the System Program and Token Program.
> You don't need to write your own program for basic tasks like creating [accounts](https://solana.com/docs/terminology#account), transferring SOL, or minting tokens. These are handled by existing programs like the System Program and Token Program.

## Financial Software

Expand All @@ -37,7 +37,7 @@ Create a fundraiser specifying a target mint and amount. Contributors deposit to

### Pyth Price Feeds

Read offchain price data onchain using the Pyth oracle network.
Read offchain price data [onchain](https://solana.com/docs/terminology#onchain) using the Pyth oracle network.

[⚓ Anchor](./oracles/pyth/anchor) [💫 Quasar](./oracles/pyth/quasar)

Expand All @@ -57,7 +57,7 @@ Store and retrieve data using Solana accounts.

### Counter

Use a PDA to store global state — a counter that increments when called.
Use a [PDA](https://solana.com/docs/terminology#program-derived-address-pda) to store global state — a counter that increments when called.

[⚓ Anchor](./basics/counter/anchor) [💫 Quasar](./basics/counter/quasar) [🤥 Pinocchio](./basics/counter/pinocchio) [🦀 Native](./basics/counter/native)

Expand All @@ -69,13 +69,13 @@ Save and update per-user state, ensuring users can only modify their own data.

### Checking Accounts

Validate that accounts provided in incoming instructions meet specific criteria.
Validate that accounts provided in incoming [instructions](https://solana.com/docs/terminology#instruction) meet specific criteria.

[⚓ Anchor](./basics/checking-accounts/anchor) [💫 Quasar](./basics/checking-accounts/quasar) [🤥 Pinocchio](./basics/checking-accounts/pinocchio) [🦀 Native](./basics/checking-accounts/native) [🧬 ASM](./basics/checking-accounts/asm)

### Close Account

Close an account and reclaim its lamports.
Close an account and reclaim its [lamports](https://solana.com/docs/terminology#lamport).

[⚓ Anchor](./basics/close-account/anchor) [💫 Quasar](./basics/close-account/quasar) [🤥 Pinocchio](./basics/close-account/pinocchio) [🦀 Native](./basics/close-account/native)

Expand All @@ -93,13 +93,13 @@ Call one program from another — the hand program invokes the lever program to

### PDA Rent Payer

Use a PDA to pay rent for creating a new account.
Use a PDA to pay [rent](https://solana.com/docs/terminology#rent) for creating a new account.

[⚓ Anchor](./basics/pda-rent-payer/anchor) [💫 Quasar](./basics/pda-rent-payer/quasar) [🤥 Pinocchio](./basics/pda-rent-payer/pinocchio) [🦀 Native](./basics/pda-rent-payer/native)

### Processing Instructions

Add parameters to an instruction handler and use them.
Add parameters to an [instruction handler](https://solana.com/docs/terminology#instruction-handler) and use them.

[⚓ Anchor](./basics/processing-instructions/anchor) [💫 Quasar](./basics/processing-instructions/quasar) [🤥 Pinocchio](./basics/processing-instructions/pinocchio) [🦀 Native](./basics/processing-instructions/native)

Expand Down Expand Up @@ -155,7 +155,7 @@ Create an NFT collection, mint NFTs, and verify NFTs as part of a collection usi

### Token Minter

Mint tokens from inside your own program using the Classic Token Program.
Mint tokens from inside your own program using the [Classic Token Program](https://solana.com/docs/terminology#token-program).

[⚓ Anchor](./tokens/token-minter/anchor) [💫 Quasar](./tokens/token-minter/quasar) [🦀 Native](./tokens/token-minter/native)

Expand All @@ -181,19 +181,19 @@ Control token transfers using an external secp256k1 delegate signature.

### Basics

Create token mints, mint tokens, and transfer tokens using Token Extensions.
Create token mints, mint tokens, and transfer tokens using [Token Extensions](https://solana.com/docs/terminology#token-extensions-program).

[⚓ Anchor](./tokens/token-extensions/basics/anchor) [💫 Quasar](./tokens/token-extensions/basics/quasar)

### CPI Guard

Prevent certain token actions from occurring within cross-program invocations.
Prevent certain token actions from occurring within [cross-program invocations](https://solana.com/docs/terminology#cross-program-invocation-cpi).

[⚓ Anchor](./tokens/token-extensions/cpi-guard/anchor) [💫 Quasar](./tokens/token-extensions/cpi-guard/quasar)

### Default Account State

Create new token accounts that are frozen by default.
Create new [token accounts](https://solana.com/docs/terminology#token-account) that are frozen by default.

[⚓ Anchor](./tokens/token-extensions/default-account-state/anchor) [💫 Quasar](./tokens/token-extensions/default-account-state/quasar) [🦀 Native](./tokens/token-extensions/default-account-state/native)

Expand Down Expand Up @@ -223,7 +223,7 @@ Require all transfers to include a descriptive memo.

### Onchain Metadata

Store metadata directly inside the token mint account, without needing additional programs.
Store metadata directly inside the token [mint account](https://solana.com/docs/terminology#token-mint), without needing additional programs.

[⚓ Anchor](./tokens/token-extensions/metadata/anchor)

Expand Down
4 changes: 2 additions & 2 deletions basics/checking-accounts/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Checking Accounts

Solana programs should check the instructions they receive to ensure security and to make sure required invariants hold.
Solana [programs](https://solana.com/docs/terminology#program) should check the [instructions](https://solana.com/docs/terminology#instruction) they receive to ensure security and to make sure required invariants hold.

The exact checks depend on what the program does. Common ones include:

- Verifying that the `program_id` on the instruction matches your own program.
- Verifying the order and number of accounts.
- Verifying the order and number of [accounts](https://solana.com/docs/terminology#account).
- Checking the initialization state of an account.
8 changes: 4 additions & 4 deletions basics/close-account/anchor/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Close Account

Two instruction handlers: `create_user` initializes a PDA `UserState` account, and `close_user` closes it and returns the rent to the user.
Two [instruction handlers](https://solana.com/docs/terminology#instruction-handler): `create_user` initializes a [PDA](https://solana.com/docs/terminology#program-derived-address-pda) `UserState` [account](https://solana.com/docs/terminology#account), and `close_user` closes it and returns the [rent](https://solana.com/docs/terminology#rent) to the user.

1. `create_user` initializes the PDA with Anchor's `init` constraint:
1. `create_user` initializes the PDA with [Anchor](https://solana.com/docs/terminology#anchor)'s `init` constraint:

```rust
#[account(
Expand All @@ -17,7 +17,7 @@ Two instruction handlers: `create_user` initializes a PDA `UserState` account, a

See [`programs/close-account/src/instructions/create_user.rs`](programs/close-account/src/instructions/create_user.rs).

2. `close_user` closes the account using Anchor's `close` constraint, which returns lamports to the given account:
2. `close_user` closes the account using Anchor's `close` constraint, which returns [lamports](https://solana.com/docs/terminology#lamport) to the given account:

```rust
#[account(
Expand All @@ -33,7 +33,7 @@ Two instruction handlers: `create_user` initializes a PDA `UserState` account, a

## Tests

Tests live in [`programs/close-account/tests/test_close_account.rs`](programs/close-account/tests/test_close_account.rs) and run against litesvm. `Anchor.toml`'s `scripts.test` is `cargo test`, so `anchor test` builds the program and runs the Rust tests:
Tests live in [`programs/close-account/tests/test_close_account.rs`](programs/close-account/tests/test_close_account.rs) and run against litesvm. `Anchor.toml`'s `scripts.test` is `cargo test`, so `anchor test` builds the [program](https://solana.com/docs/terminology#program) and runs the Rust tests:

```bash
anchor test
Expand Down
4 changes: 2 additions & 2 deletions basics/counter/anchor/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Anchor Counter

Anchor enforces `init` constraints that nudge you towards good programming patterns.
[Anchor](https://solana.com/docs/terminology#anchor) enforces `init` constraints that nudge you towards good programming patterns.

This program has an additional initialization handler for `Counter`s that the Solana native equivalent does not.
This [program](https://solana.com/docs/terminology#program) has an additional initialization handler for `Counter`s that the Solana native equivalent does not.
2 changes: 1 addition & 1 deletion basics/counter/mpl-stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A Solana-native counter built using the MPL (Metaplex) stack.

## Setup

1. Build the program: `cargo build-sbf`
1. Build the [program](https://solana.com/docs/terminology#program): `cargo build-sbf`
2. Build the IDL: `shank build`
3. Build the TypeScript SDK: `pnpm solita`
- Temporary workaround: edit `ts/generated/accounts/Counter.ts` line 58 to
Expand Down
2 changes: 1 addition & 1 deletion basics/counter/native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Counter written in Solana native, using only the Solana toolchain.

## Setup

1. Build the program: `cargo build-sbf`
1. Build the [program](https://solana.com/docs/terminology#program): `cargo build-sbf`
2. Run the tests: `pnpm test`

## Debugging
Expand Down
2 changes: 1 addition & 1 deletion basics/counter/pinocchio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Counter written using the Pinocchio framework, with only the Solana toolchain.

## Setup

1. Build the program: `cargo build-sbf`
1. Build the [program](https://solana.com/docs/terminology#program): `cargo build-sbf`
2. Run the tests: `pnpm test`

## Debugging
Expand Down
4 changes: 2 additions & 2 deletions basics/create-account/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Create Account

Create a Solana account.
Create a Solana [account](https://solana.com/docs/terminology#account).

The account is a **system account** — owned by the System Program, which means only the System Program can modify its data. In this example, the account simply holds some SOL.

The tests cover two ways to create the account:

1. **Via cross-program invocation (CPI):** the client sends a transaction to our deployed program, which in turn calls the System Program.
1. **Via [cross-program invocation](https://solana.com/docs/terminology#cross-program-invocation-cpi) (CPI):** the client sends a transaction to our deployed [program](https://solana.com/docs/terminology#program), which in turn calls the System Program.
2. **Directly:** the client sends the create-account transaction straight to the System Program.

See [cross-program-invocation](../cross-program-invocation) for more CPI examples.
Expand Down
10 changes: 5 additions & 5 deletions basics/cross-program-invocation/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Cross-Program Invocation (CPI)

A cross-program invocation is calling one program from another. You use CPIs when your program needs to compose with other onchain programs to do its work.
A [cross-program invocation](https://solana.com/docs/terminology#cross-program-invocation-cpi) is calling one [program](https://solana.com/docs/terminology#program) from another. You use CPIs when your program needs to compose with other [onchain](https://solana.com/docs/terminology#onchain) programs to do its work.

Whether a given operation should be done via a CPI or via separate RPC calls from the client is a design choice. The main reason to use a CPI is a **dependent operation** that must happen atomically with the rest of your logic.

Consider this sequence in a token mint program:
Consider this sequence in a token [mint](https://solana.com/docs/terminology#token-mint) program:

1. Create and initialize the mint.
2. Create a metadata account for the mint.
3. Create and initialize a user's token account for the mint.
2. Create a metadata [account](https://solana.com/docs/terminology#account) for the mint.
3. Create and initialize a user's [token account](https://solana.com/docs/terminology#token-account) for the mint.
4. Mint some tokens to the user's token account.

You cannot create a metadata account without first having the mint. Once you decide that steps 1 and 4 must be onchain, the only sensible option is to also do steps 2 and 3 onchain — you cannot pause a program mid-flight to let the client do work.
Expand Down Expand Up @@ -56,4 +56,4 @@ See the [Features chapter of the Cargo Book](https://doc.rust-lang.org/cargo/ref

<img src="istockphoto-1303616086-612x612.jpeg" alt="lever" width="128" align="center"/>

The `hand` program's `pull_lever` instruction handler does a CPI into the `lever` program's `switch_power` instruction handler. Pull the lever, switch the power.
The `hand` program's `pull_lever` [instruction handler](https://solana.com/docs/terminology#instruction-handler) does a CPI into the `lever` program's `switch_power` instruction handler. Pull the lever, switch the power.
10 changes: 5 additions & 5 deletions basics/cross-program-invocation/quasar/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Cross-Program Invocation — Quasar

This example contains **two separate Quasar programs** that work together:
This example contains **two separate Quasar [programs](https://solana.com/docs/terminology#program)** that work together:

- **`lever/`** — A program with onchain `PowerStatus` state and a `switch_power` instruction handler that toggles a boolean.
- **`hand/`** — A program that calls the lever program's `switch_power` via CPI.
- **`lever/`** — A program with [onchain](https://solana.com/docs/terminology#onchain) `PowerStatus` state and a `switch_power` [instruction handler](https://solana.com/docs/terminology#instruction-handler) that toggles a boolean.
- **`hand/`** — A program that calls the lever program's `switch_power` via [CPI](https://solana.com/docs/terminology#cross-program-invocation-cpi).

## Building

Expand All @@ -27,10 +27,10 @@ The hand tests load **both** programs into `QuasarSvm` and verify that the CPI c

## CPI pattern

Quasar doesn't have a `declare_program!` equivalent for importing arbitrary program instruction types (unlike Anchor). Instead, the hand program:
Quasar doesn't have a `declare_program!` equivalent for importing arbitrary program [instruction](https://solana.com/docs/terminology#instruction) types (unlike [Anchor](https://solana.com/docs/terminology#anchor)). Instead, the hand program:

1. Defines a **marker type** (`LeverProgram`) that implements the `Id` trait with the lever's program address.
2. Uses `Program<LeverProgram>` in the accounts struct for compile-time address and executable validation.
2. Uses `Program<LeverProgram>` in the [accounts](https://solana.com/docs/terminology#account) struct for compile-time address and executable validation.
3. Builds the CPI instruction data **manually** using `BufCpiCall`, constructing the lever's wire format directly.

This is lower-level than Anchor's CPI pattern but gives full control and works with any program.
2 changes: 1 addition & 1 deletion basics/favorites/anchor/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Favorites

A basic Anchor app that uses PDAs to store per-user data, and Anchor account constraints to ensure each user can only modify their own data.
A basic [Anchor](https://solana.com/docs/terminology#anchor) app that uses [PDAs](https://solana.com/docs/terminology#program-derived-address-pda) to store per-user data, and Anchor [account](https://solana.com/docs/terminology#account) constraints to ensure each user can only modify their own data.

Used by the [Solana Professional Education](https://github.com/solana-developers/professional-education) course.

Expand Down
4 changes: 2 additions & 2 deletions basics/hello-solana/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Hello Solana

Our first Solana program — a "hello, world" that logs a greeting. Along the way, a quick look at what's inside a Solana transaction.
Our first Solana [program](https://solana.com/docs/terminology#program) — a "hello, world" that logs a greeting. Along the way, a quick look at what's inside a Solana transaction.

## Transactions

Expand All @@ -9,7 +9,7 @@ Our first Solana program — a "hello, world" that logs a greeting. Along the wa
Two things to keep separate:

- :key: **Transactions** are for **the Solana runtime**. They contain everything the runtime needs to allow or deny a transaction (signers, recent blockhash, etc.) and to decide what can run in parallel.
- :key: **Instructions** are for **Solana programs**. They tell a program what to do.
- :key: **[Instructions](https://solana.com/docs/terminology#instruction)** are for **Solana programs**. They tell a program what to do.
- :key: Your program receives one instruction at a time (`program_id`, `accounts`, `instruction_data`).

### Transaction
Expand Down
4 changes: 2 additions & 2 deletions basics/pda-rent-payer/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# PDA Rent-Payer

Use a PDA to pay rent for a new account.
Use a [PDA](https://solana.com/docs/terminology#program-derived-address-pda) to pay [rent](https://solana.com/docs/terminology#rent) for a new [account](https://solana.com/docs/terminology#account).

Accounts on Solana are created under ownership of the System Program when you transfer lamports to them, so you can pay for a new account simply by transferring lamports from your PDA to the new account's public key.
Accounts on Solana are created under ownership of the System Program when you transfer [lamports](https://solana.com/docs/terminology#lamport) to them, so you can pay for a new account simply by transferring lamports from your PDA to the new account's public key.
4 changes: 2 additions & 2 deletions basics/processing-instructions/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Custom Instruction Data

Pass your own custom instruction data to a program. The data must be serialized in a format the Solana runtime can read — typically via the `borsh` crate on both the client and program sides.
Pass your own custom [instruction](https://solana.com/docs/terminology#instruction) data to a [program](https://solana.com/docs/terminology#program). The data must be serialized in a format the Solana runtime can read — typically via the `borsh` crate on both the client and program sides.

- **For `native`:** add `borsh` and `borsh-derive` to `Cargo.toml` so you can mark a struct as serializable.
- **For Anchor:** the framework handles serialization for you via the IDL.
- **For [Anchor](https://solana.com/docs/terminology#anchor):** the framework handles serialization for you via the IDL.
4 changes: 2 additions & 2 deletions basics/realloc/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Realloc

Resize a Solana account after it has been created — grow or shrink the data it can hold.
Resize a Solana [account](https://solana.com/docs/terminology#account) after it has been created — grow or shrink the data it can hold.

## A note on `realloc` vs `resize`

The runtime method `AccountInfo::realloc` has been deprecated in favor of `AccountInfo::resize` ([anchor#4526](https://github.com/solana-foundation/anchor/issues/4526)). New code should call `AccountInfo::resize`.

The Anchor account-constraint macros (`#[account(realloc = ..., realloc::payer = ..., realloc::zero = ...)]`) are **not yet renamed** and still use the `realloc` spelling. That is the correct form to use today; track the issue above for any future change.
The [Anchor](https://solana.com/docs/terminology#anchor) account-constraint macros (`#[account(realloc = ..., realloc::payer = ..., realloc::zero = ...)]`) are **not yet renamed** and still use the `realloc` spelling. That is the correct form to use today; track the issue above for any future change.
Loading
Loading