Full lesson
bergabman_Sol_Q423
Solana Q423 cohort
- Original
- Web3-Builders-Alliance/bergabman_Sol_Q423
- SuperStack fork
- Blockchains/bergabman_Sol_Q423 @
c16654e - Stars
- 10
- Last push (original)
- 2024-02-04
- Languages
- TypeScript, Rust
- Detected stack
- AnchorMetaplexweb3.js
- Categories
- Other
- Licence
- MIT
Architecture
83 source files. By extension: .rs ×42, .ts ×41.
| Top-level directory | Source files |
|---|---|
Cluster1 | 29 |
Cluster2 | 26 |
capstone | 18 |
WBA_PreReqQ4 | 10 |
On-chain programs: Cluster2/amm/programs/amm, Cluster2/anchor-escrow/programs/anchor-escrow, Cluster2/anchor-vault/programs/anchor-vault, Cluster2/anchor-vote-solb/programs/anchor-vote-solb, capstone/dev-capital/programs/dev-capital
Dapp: deploying
This fork is queued for its own live dapp on Sol.College, with a Devnet/Mainnet switch. It appears here, at /dapps/bergabman-sol-q423/, 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.
Cluster2/anchor-escrow/programs/anchor-escrow/src/contexts/take.rs L25–48 @ c16654e · MIT · original pub taker_ata_a: Account<'info, TokenAccount>, #[account( mut, associated_token::mint = mint_b, associated_token::authority = taker, )] pub taker_ata_b: Account<'info, TokenAccount>, #[account( init_if_needed, payer = taker, associated_token::mint = mint_b, associated_token::authority = maker, )] pub maker_ata_b: Account<'info, TokenAccount>, #[account( mut, close = maker, seeds = [b"escrow", maker.key().as_ref(), escrow.seed.to_le_bytes().as_ref()], bump = escrow.bump, has_one = mint_a, has_one = mint_b, )] pub escrow: Account<'info, Escrow>, #[account(- Line 33
init_if_needed,: Creates the account only if it doesn't exist. Watch for re-initialisation bugs. - Line 41
close = maker,: Closes the account at the end of the instruction and refunds its lamports. - Line 42
seeds = [b"escrow", maker.key().as_ref(), escrow.seed.to_le_bytes().as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 43
bump = escrow.bump,: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve. - Line 44
has_one = mint_a,: Checks that a stored pubkey field matches the passed account.
Cluster2/anchor-escrow/programs/anchor-escrow/src/contexts/refund.rs L13–36 @ c16654e · MIT · original pub mint_a: Account<'info, Mint>, #[account( init_if_needed, payer = maker, associated_token::mint = mint_a, associated_token::authority = maker, )] pub maker_ata_a: Account<'info, TokenAccount>, #[account( mut, close = maker, has_one = mint_a, seeds = [b"escrow", maker.key().as_ref(), escrow.seed.to_le_bytes().as_ref()], bump = escrow.bump )] pub escrow: Account<'info, Escrow>, #[account( mut, associated_token::mint = mint_a, associated_token::authority = escrow, )] pub vault: Account<'info, TokenAccount>, pub system_program: Program<'info, System>, pub token_program: Program<'info, Token>,- Line 15
init_if_needed,: Creates the account only if it doesn't exist. Watch for re-initialisation bugs. - Line 23
close = maker,: Closes the account at the end of the instruction and refunds its lamports. - Line 24
has_one = mint_a,: Checks that a stored pubkey field matches the passed account. - Line 25
seeds = [b"escrow", maker.key().as_ref(), escrow.seed.to_le_bytes().as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 26
bump = escrow.bump: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
Cluster2/amm/programs/amm/src/contexts/deposit.rs L1–24 @ c16654e · MIT · originaluse crate::{assert_non_zero, assert_not_expired, AmmError, Config};use anchor_lang::prelude::*;use anchor_spl::{ associated_token::AssociatedToken, token::{mint_to, transfer_checked, MintTo, Token, TransferChecked}, token_interface::{Mint, TokenAccount},};use constant_product_curve::ConstantProduct;#[derive(Accounts)]pub struct Deposit<'info> { #[account(mut)] pub user: Signer<'info>, pub mint_x: InterfaceAccount<'info, Mint>, pub mint_y: InterfaceAccount<'info, Mint>, #[account( mut, seeds = [b"lp", config.key().as_ref()], bump, mint::decimals = 6, mint::authority = auth, )] pub mint_lp: InterfaceAccount<'info, Mint>, #[account( mut,- Line 5
token::{mint_to, transfer_checked, MintTo, Token, TransferChecked},: A checked token transfer, which also verifies the mint and decimals. - Line 5
token::{mint_to, transfer_checked, MintTo, Token, TransferChecked},: Mints new tokens. The mint authority must sign. - Line 12
pub user: Signer<'info>,: Requires this account to have signed the transaction. - Line 17
seeds = [b"lp", config.key().as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 18
bump,: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
Cluster2/anchor-vault/programs/anchor-vault/src/lib.rs L49–72 @ c16654e · MIT · original }; let cpi_ctx = CpiContext::new_with_signer( ctx.accounts.system_program.to_account_info(), accounts, signer_seeds ); transfer(cpi_ctx, ctx.accounts.vault.lamports())?; Ok(()) }} #[derive(Accounts)]pub struct Vault<'info> { #[account(mut)] signer: Signer<'info>, #[account( mut, seeds = [b"vault", signer.key().as_ref()], bump )] vault: SystemAccount<'info>,- Line 51
let cpi_ctx = CpiContext::new_with_signer(: Makes a CPI signed by a PDA. The signer seeds prove the program controls that address. - Line 66
signer: Signer<'info>,: Requires this account to have signed the transaction. - Line 69
seeds = [b"vault", signer.key().as_ref()],: Declares the PDA seeds. Anchor re-derives the address and rejects the account if it doesn't match. - Line 70
bump: Uses the bump seed, the extra byte that pushes the derived address off the ed25519 curve.
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 |
|---|---|---|
Cluster2/anchor-vote-solb | npm run lint | prettier */*.js "*/**/*{.js,.ts}" --check |
Cluster2/anchor-vault | npm run lint | prettier */*.js "*/**/*{.js,.ts}" --check |
Cluster2/anchor-escrow | npm run lint | prettier */*.js "*/**/*{.js,.ts}" --check |
Cluster2/amm | npm run lint | prettier */*.js "*/**/*{.js,.ts}" --check |
capstone/dev-capital | npm run lint | prettier */*.js "*/**/*{.js,.ts}" --check |
Cluster2/anchor-vote-solb | anchor build | compile programs and generate IDLs |
Cluster2/anchor-vote-solb | anchor test | local validator + test suite |
Cluster2/anchor-vote-solb | anchor run test | yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts |
Cluster2/anchor-vault | anchor build | compile programs and generate IDLs |
Cluster2/anchor-vault | anchor test | local validator + test suite |
Cluster2/anchor-vault | anchor run test | yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts |
Cluster2/anchor-escrow | anchor build | compile programs and generate IDLs |
Cluster2/anchor-escrow | anchor test | local validator + test suite |
Cluster2/anchor-escrow | anchor run test | yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts |
Cluster2/amm | anchor build | compile programs and generate IDLs |
Cluster2/amm | anchor test | local validator + test suite |
What you could build from it
- Fork the SuperStack copy and extend it within the Other gaps listed on the idea page.
- Learn the pattern first: Program Derived Addresses (PDAs)
- Learn the pattern first: Cross-Program Invocations (CPIs)