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
4 changes: 2 additions & 2 deletions .github/.ghaignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ tools/shank-and-solita/native
tokens/pda-mint-authority/native
tokens/nft-minter/native
tokens/transfer-tokens/native
tokens/spl-token-minter/native
tokens/token-minter/native
tokens/create-token/native

tokens/token-swap/anchor
Expand Down Expand Up @@ -68,6 +68,6 @@ basics/transfer-sol/steel
tokens/escrow/steel

tokens/pda-mint-authority/steel
tokens/spl-token-minter/steel
tokens/token-minter/steel
tokens/token-swap/steel
tokens/transfer-tokens/steel
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,11 @@ Create an NFT collection, mint NFTs, and verify NFTs as part of a collection usi

[⚓ Anchor](./tokens/nft-operations/anchor) [💫 Quasar](./tokens/nft-operations/quasar)

### SPL Token Minter
### Token Minter

Mint tokens from inside your own program using the Token program.
Mint tokens from inside your own program using the Classic Token Program.

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

### Transfer Tokens

Expand Down
40 changes: 25 additions & 15 deletions basics/close-account/anchor/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
# Destroy an Account
# Close Account

1. A `PDA` is created using the [create_user.rs](programs/destroy-an-account/src/instructions/create_user.rs) instruction.
Two instruction handlers: `create_user` initializes a PDA `UserState` account, and `close_user` closes it and returns the rent to the user.

1. `create_user` initializes the PDA with Anchor's `init` constraint:

```rust
#[account(
init,
seeds = [User::PREFIX.as_bytes(), user.key().as_ref()],
payer = user,
space = User::SIZE,
space = UserState::DISCRIMINATOR.len() + UserState::INIT_SPACE,
seeds = [b"USER", user.key().as_ref()],
bump,
)]
pub user_account: Box<Account<'info, User>>,
pub user_account: Account<'info, UserState>,
```

2. The account is closed in [destroy_user.rs](programs/destroy-an-account/src/instructions/destroy_user.rs), using Anchor's `close` helper on the account info:
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:

```rust
user_account.close(user.to_account_info())?;
#[account(
mut,
seeds = [b"USER", user.key().as_ref()],
bump = user_account.bump,
close = user, // close account and return lamports to user
)]
pub user_account: Account<'info, UserState>,
```

3. The test [destroy-an-account.ts](tests/destroy-an-account.ts) verifies that the account is null both before creation and after closing, via `fetchNullable`:
See [`programs/close-account/src/instructions/close_user.rs`](programs/close-account/src/instructions/close_user.rs).

```typescript
const userAccountBefore = await program.account.user.fetchNullable(userAccountAddress, "processed");
assert.equal(userAccountBefore, null);
// ...
const userAccountAfter = await program.account.user.fetchNullable(userAccountAddress, "processed");
assert.notEqual(userAccountAfter, null);
```
## 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:

```bash
anchor test
```
14 changes: 11 additions & 3 deletions basics/cross-program-invocation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,22 @@ In the `lever` crate's `Cargo.toml`:
no-entrypoint = []
```

Then, in the `hand` crate, import `lever` with that feature enabled:
In this example each crate also defines a `cpi` feature that depends on `no-entrypoint`, so callers can pick the more descriptive name:

```toml
[features]
no-entrypoint = []
cpi = ["no-entrypoint"]
```

Then, in the `hand` crate, import `lever` with the `cpi` feature enabled:

```toml
[dependencies]
lever = { path = "../lever", features = ["no-entrypoint"] }
cross-program-invocatio-native-lever = { path = "../lever", features = ["cpi"] }
```

In the `lever` crate, gate the `entrypoint!` macro on the feature being absent:
In the `lever` crate, gate the `entrypoint!` macro on the `no-entrypoint` feature being absent:

```rust
#[cfg(not(feature = "no-entrypoint"))]
Expand Down
15 changes: 6 additions & 9 deletions compression/cnft-burn/anchor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ An Anchor program that burns compressed NFTs (cNFTs) in your collection. The pro

## Components

- `programs/` — the Anchor program.
- `tests/` — tests for the program.
- `programs/cnft-burn/` — the Anchor program.
- `migrations/` — deployment script.

## Deployment
There is no `tests/` directory in this example today. The program is intended to be deployed and exercised against a real cluster.

The program is deployed on devnet at `FbeHkUEevbhKmdk5FE5orcTaJkCYn5drwZoZXaxQXXNn`. To deploy your own copy, change the program ID in `lib.rs` and `Anchor.toml`.
## Deployment

## How to run
The program ID declared in [`programs/cnft-burn/src/lib.rs`](programs/cnft-burn/src/lib.rs) is `C6qxH8n6mZxrrbtMtYWYSp8JR8vkQ55X1o4EBg7twnMv`. Whether this address is currently deployed on any cluster is not tracked in this repo — verify with `solana program show <id>` against the cluster you care about.

1. Configure the RPC endpoint in `cnft-burn.ts`.
2. `anchor build` from the example root.
3. `anchor deploy` to deploy to your chosen cluster.
4. `pnpm test` to run the tests.
To deploy your own copy, change the program ID in `lib.rs` and `Anchor.toml`, then run `anchor build && anchor deploy`.

## Acknowledgements

Expand Down
10 changes: 6 additions & 4 deletions compression/cnft-vault/anchor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ Use this as a reference for working with cNFTs in your own programs.

## Components

- `programs/` — the Anchor program.
- `tests/` — TypeScript client-side tests.
- `tests/scripts/` — standalone scripts you can run individually. `withdrawWithLookup.ts` demonstrates using the program with Address Lookup Tables.
- `programs/cnft-vault/` — the Anchor program.

There is no `tests/` directory in this example today. The program is intended to be deployed and exercised against a real cluster.

## Deployment

Deployed on devnet at `CNftyK7T8udPwYRzZUMWzbh79rKrz9a5GwV2wv7iEHpk`. To deploy your own, change the program ID in `lib.rs` and `Anchor.toml`.
The program ID declared in [`programs/cnft-vault/src/lib.rs`](programs/cnft-vault/src/lib.rs) is `Fd4iwpPWaCU8BNwGQGtvvrcvG4Tfizq3RgLm8YLBJX6D`. Whether this address is currently deployed on any cluster is not tracked in this repo — verify with `solana program show <id>` against the cluster you care about.

To deploy your own copy, change the program ID in `lib.rs` and `Anchor.toml`, then run `anchor build && anchor deploy`.

## Limitations

Expand Down
26 changes: 6 additions & 20 deletions compression/cutils/anchor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,20 @@ Use this as a reference for working with cNFTs in your own programs.

## Components

- `programs/` — the Anchor program. The setup uses a `validate`/`actuate` pattern via Anchor's `access_control` macro; this pairs well with the cNFT verification logic.
- `tests/` — TypeScript tests.
- `setup.ts` — run first if you don't already have a collection with a merkle tree.
- `tests.ts` — individual minting and verification tests.
- `programs/cutils/` — the Anchor program. The setup uses a `validate`/`actuate` pattern via Anchor's `access_control` macro; this pairs well with the cNFT verification logic.

There is no `tests/` directory in this example today. The program is intended to be deployed and exercised against a real cluster.

## Deployment

Deployed on devnet at `burZc1SfqbrAP35XG63YZZ82C9Zd22QUwhCXoEUZWNF`. To deploy your own, change the program ID in `lib.rs` and `Anchor.toml`.
The program ID declared in [`programs/cutils/src/lib.rs`](programs/cutils/src/lib.rs) is `BuFyrgRYzg2nPhqYrxZ7d9uYUs4VXtxH71U8EcoAfTQZ`. Whether this address is currently deployed on any cluster is not tracked in this repo — verify with `solana program show <id>` against the cluster you care about.

To deploy your own copy, change the program ID in `lib.rs` and `Anchor.toml`, then run `anchor build && anchor deploy`.

## Limitations

Reference implementation only.

**This example pins Anchor 0.26.0** because of mpl-bubblegum dependency constraints at the time of writing.

## How to run

1. Configure the RPC endpoint in `utils/readAPI.ts`.
2. `cd` to the example root.
3. `pnpm install`.
4. (Optional) `npx tsx tests/setup.ts` to create an NFT collection and its merkle tree.
5. Comment out the tests you don't want to run in `tests/tests.ts`.
6. If minting, set your NFT URI.
7. If verifying, set the asset ID (cNFT mint address) you want to verify.
8. Run `anchor test --skip-build --skip-deploy --skip-local-validator`.
9. View your cNFTs on devnet via the Solflare wallet.
10. You may also want to change the wallet path in `Anchor.toml`.

## Acknowledgements

- [@nickfrosty](https://twitter.com/nickfrosty) for the sample code and [live demo](https://youtu.be/LxhTxS9DexU).
Expand Down
18 changes: 10 additions & 8 deletions tokens/create-token/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Create an SPL Token
# Create a Token

Create an SPL Token on Solana with metadata such as a symbol and an icon.
Create a token on Solana with metadata such as a symbol and an icon.

All tokens on Solana — including NFTs are SPL Tokens. They follow the SPL Token standard (similar in spirit to ERC-20).
All fungible assets and NFTs on Solana are tokens. They follow the Classic Token Program standard (similar in spirit to ERC-20), or the newer Token Extensions standard.

```text
Default SPL Tokens : 9 decimals
NFTs : 0 decimals
Typical fungible tokens : 9 decimals
NFTs : 0 decimals
```

## How decimals work
Expand All @@ -19,7 +19,7 @@ For a token JOE with 9 decimals:

## Mint and metadata

An SPL Token is represented onchain by a **Mint Account**:
A token is represented onchain by a **Mint Account**:

```typescript
{
Expand All @@ -41,9 +41,11 @@ Metadata about a mint — name, symbol, image URI — lives in a separate **Meta
}
```

> Metaplex is the de facto standard for SPL Token metadata on Solana. The [Metaplex Token Metadata Program](https://docs.metaplex.com/) is what creates these metadata accounts.
> Metaplex is the de facto standard for token metadata on Solana with the Classic Token Program. The [Metaplex Token Metadata Program](https://docs.metaplex.com/) creates these metadata accounts.
>
> Tokens using the Token Extensions metadata extension store metadata directly on the mint and don't need a separate Metaplex account.

## Steps to create an SPL Token
## Steps to create a token

1. Create an account for the mint.
2. Initialize that account as a Mint Account.
Expand Down
2 changes: 1 addition & 1 deletion tokens/create-token/quasar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ declare_id!("22222222222222222222222222222222222222222222");
/// Creates a token mint and mints initial tokens to the creator's token account.
///
/// The Anchor version uses Metaplex for onchain metadata. Quasar's metadata
/// crate is demonstrated in the `nft-minter` and `spl-token-minter` examples;
/// crate is demonstrated in the `nft-minter` and `token-minter` examples;
/// this example focuses on the core SPL Token operations: creating a mint and
/// minting tokens.
#[program]
Expand Down
4 changes: 2 additions & 2 deletions tokens/nft-minter/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# NFT Minter

Minting NFTs is the same as [minting any SPL Token on Solana](../spl-token-minter/), with one extra step at the end.
Minting NFTs is the same as [minting any token on Solana](../token-minter/), with one extra step at the end.

When you mint SPL Tokens, you can in most cases continue to mint more tokens later, growing the supply. An NFT is supposed to have a supply of **one**. So we need to make sure no more can ever be minted.
When you mint tokens, you can in most cases continue to mint more later, growing the supply. An NFT is supposed to have a supply of **one**, so no more can ever be minted.

The way to do that is to remove the mint authority from the mint:

Expand Down
Loading
Loading