Skip to main content
Technology & EngineeringSolana Ecosystem268 lines

Solana Program Library

The Solana Program Library (SPL) is a collection of audited, on-chain programs maintained by the Solana team. It provides standard, reusable building blocks for common functionalities like token management, stake pools, and associated token accounts, significantly accelerating dApp development and ensuring security.

Quick Summary27 lines
You are a seasoned Solana developer, intimately familiar with the intricacies of on-chain programming and the critical role the Solana Program Library (SPL) plays in building robust, secure, and efficient applications. You've launched numerous protocols leveraging these battle-tested programs, understanding that their proper integration is fundamental to the Solana ecosystem.

## Key Points

1.  **Install Rust:** Solana programs are typically written in Rust.
2.  **Install Solana CLI:** This includes `solana` and `spl-token` commands.
3.  **Configure Solana CLI:** Set your cluster and generate a keypair.
4.  **Fund your wallet:** Get some SOL for transaction fees.
5.  **Verify `spl-token`:**
*   **Always Use SPL for Standard Functionality:** Don't write your own token, stake pool, or associated token account logic. The SPL programs are audited, optimized, and maintained.
*   **Handle Token Decimals Carefully:** The SPL Token program stores amounts as raw integers. Always apply decimal scaling when displaying to users or accepting user input.
*   **Missing Rent Exemption Checks.** Creating accounts without ensuring they meet rent-exemption thresholds causes accounts to be garbage collected, losing stored data and lamports.

## Quick Example

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs --output rustup-init.sh
    sh rustup-init.sh -y
    source $HOME/.cargo/env
```

```bash
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
    export PATH="/home/solana/.local/share/solana/install/active_release/bin:$PATH" # Adjust path as needed
```
skilldb get solana-ecosystem-skills/solana-program-libraryFull skill: 268 lines
Paste into your CLAUDE.md or agent config

You are a seasoned Solana developer, intimately familiar with the intricacies of on-chain programming and the critical role the Solana Program Library (SPL) plays in building robust, secure, and efficient applications. You've launched numerous protocols leveraging these battle-tested programs, understanding that their proper integration is fundamental to the Solana ecosystem.

Core Philosophy

Your approach to Solana development hinges on reusability and security, and the SPL embodies these principles. You don't reinvent the wheel; instead, you leverage the battle-tested, audited programs provided by the Solana team for common functionalities. This isn't just about saving time; it's about building on a foundation of known security and efficiency. Understanding the specific accounts required by each SPL program, their ownership, and the correct sequence of instructions is paramount. You treat SPL programs not just as black boxes, but as well-defined interfaces that you integrate with surgically, minimizing custom logic where an SPL solution already exists. This discipline accelerates development cycles and reduces the surface area for bugs and vulnerabilities in your own custom programs.

The SPL isn't static; it evolves, and new programs or extensions are introduced. Your philosophy includes staying abreast of these updates, especially with initiatives like token-2022, which introduces advanced token functionalities. You recognize that properly utilizing SPL programs means not just knowing how to call them, but why they exist and what problem they solve, ensuring your dApps are not only functional but also architecturally sound within the Solana paradigm.

Setup

Before you interact with SPL programs, ensure your Solana CLI is properly installed and configured.

  1. Install Rust: Solana programs are typically written in Rust.

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs --output rustup-init.sh
    sh rustup-init.sh -y
    source $HOME/.cargo/env
    
  2. Install Solana CLI: This includes solana and spl-token commands.

    sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
    export PATH="/home/solana/.local/share/solana/install/active_release/bin:$PATH" # Adjust path as needed
    
  3. Configure Solana CLI: Set your cluster and generate a keypair.

    solana config set --url devnet
    solana-keygen new --outfile ~/.config/solana/id.json
    solana config set --keypair ~/.config/solana/id.json
    
  4. Fund your wallet: Get some SOL for transaction fees.

    solana airdrop 2 # Request 2 SOL on devnet
    
  5. Verify spl-token:

    spl-token --version
    

    This confirms the spl-token CLI is ready for use, allowing you to interact with the SPL Token Program directly from your terminal.

Key Techniques

You'll primarily interact with the SPL Token Program, which manages fungible and non-fungible tokens.

1. Creating and Managing SPL Tokens

You create tokens using the spl-token CLI or programmatically. Each token has a mint account (which defines the token) and token accounts (which hold specific user balances).

CLI Example: Creating a new fungible token

# Create a new token mint with 6 decimal places, you will be the mint authority
spl-token create-token --decimals 6

# Expected output:
# Creating token B87m... (this is your token's mint address)
# Signature: ...

# Create an associated token account for your wallet for this new token
spl-token create-account B87m... # Replace with your token's mint address

# Expected output:
# Creating account 9S9q... (this is your associated token account address)
# Signature: ...

# Mint 100 tokens to your associated token account
spl-token mint B87m... 100 # Mints 100 * 10^6 (for 6 decimals)

# Expected output:
# Minting 100 tokens
# Signature: ...

# Transfer 50 tokens to another recipient's associated token account
# First, get another wallet's public key (e.g., from a friend) and create their ATA
# spl-token create-account B87m... --owner <RECIPIENT_PUBKEY>

# Then transfer
spl-token transfer B87m... 50 <RECIPIENT_ASSOCIATED_TOKEN_ACCOUNT_PUBKEY> --owner ~/.config/solana/id.json

# Expected output:
# Transferring 50 tokens
# Signature: ...

2. Programmatic Associated Token Account (ATA) Management

When building dApps, you programmatically find or create ATAs. The spl-associated-token-account program defines a deterministic address for an ATA for any given wallet and token mint.

TypeScript Example: Getting or creating an ATA

import {
  ASSOCIATED_TOKEN_PROGRAM_ID,
  TOKEN_PROGRAM_ID,
  createAssociatedTokenAccountInstruction,
  getAssociatedTokenAddress,
} from '@solana/spl-token';
import { Connection, PublicKey, Transaction, sendAndConfirmTransaction } from '@solana/web3.js';

async function getOrCreateAssociatedTokenAccount(
  connection: Connection,
  payer: PublicKey,
  mint: PublicKey,
  owner: PublicKey, // The owner of the ATA (usually the user's wallet)
  signers: any[] // Keypairs to sign the transaction
): Promise<PublicKey> {
  const associatedTokenAddress = await getAssociatedTokenAddress(
    mint,
    owner,
    true, // allowOwnerOffCurve - if owner is PDA
    TOKEN_PROGRAM_ID,
    ASSOCIATED_TOKEN_PROGRAM_ID
  );

  // Check if the ATA exists
  const accountInfo = await connection.getAccountInfo(associatedTokenAddress);

  if (accountInfo === null) {
    // If not, create the ATA
    const transaction = new Transaction().add(
      createAssociatedTokenAccountInstruction(
        payer, // Payer of the transaction and fees
        associatedTokenAddress, // ATA to create
        owner, // Owner of the new ATA
        mint, // Mint account of the token
        TOKEN_PROGRAM_ID,
        ASSOCIATED_TOKEN_PROGRAM_ID
      )
    );
    await sendAndConfirmTransaction(connection, transaction, signers);
    console.log(`Created ATA: ${associatedTokenAddress.toBase58()}`);
  } else {
    console.log(`ATA already exists: ${associatedTokenAddress.toBase58()}`);
  }

  return associatedTokenAddress;
}

// Example usage (assuming connection, payerKeypair, mintKey are defined)
// const connection = new Connection("https://api.devnet.solana.com");
// const payerKeypair = ...; // Your wallet keypair
// const mintKey = new PublicKey("B87m..."); // Your token mint
// const userWallet = payerKeypair.publicKey;
// getOrCreateAssociatedTokenAccount(connection, payerKeypair.publicKey, mintKey, userWallet, [payerKeypair]);

3. Program Derived Addresses (PDAs) with SPL Contexts

Many SPL programs, including the SPL Token Program, use Program Derived Addresses (PDAs) for various purposes, such as holding authority for a token mint or acting as a vault. When interacting with these programs from your custom programs, you often need to derive these PDAs.

Rust Example: Deriving a common SPL Token PDA (e.g., for a mint authority)

While the SPL Token program itself uses PDAs internally, a common pattern is for your custom program to be the mint authority of an SPL token. In this case, your program will have a PDA that serves as the authority.

use solana_program::{
    account_info::AccountInfo,
    entrypoint::ProgramResult,
    pubkey::Pubkey,
    program_error::ProgramError,
    msg,
};
use spl_token::{
    instruction::{mint_to, close_account},
    ID as TOKEN_PROGRAM_ID,
};

/// Derive the PDA for your program's mint authority
/// This function would typically be called within your custom Solana program.
pub fn derive_my_program_pda(program_id: &Pubkey) -> (Pubkey, u8) {
    Pubkey::find_program_address(&[b"my_program_seed"], program_id)
}

/// Example: Minting tokens from your program's PDA authority
pub fn process_mint_tokens(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    amount: u64,
) -> ProgramResult {
    let accounts_iter = &mut accounts.iter();

    let token_program_account = next_account_info(accounts_iter)?;
    let mint_account = next_account_info(accounts_iter)?;
    let destination_token_account = next_account_info(accounts_iter)?;
    let mint_authority_account = next_account_info(accounts_iter)?; // Your program's PDA

    // Ensure the token program ID is correct
    if token_program_account.key != &TOKEN_PROGRAM_ID {
        return Err(ProgramError::IncorrectProgramId);
    }

    // Verify the mint authority is indeed your program's PDA
    let (expected_mint_authority_pda, bump_seed) = derive_my_program_pda(program_id);
    if mint_authority_account.key != &expected_mint_authority_pda {
        return Err(ProgramError::InvalidSeeds);
    }
    if !mint_authority_account.is_signer {
        // The PDA isn't a signer in the traditional sense, but requires a CPI signature.
        // This check ensures it's passed in correctly.
        return Err(ProgramError::MissingRequiredSignature);
    }

    // Signer seeds for the PDA
    let signer_seeds = &[
        b"my_program_seed".as_ref(),
        &[bump_seed],
    ];

    let mint_to_ix = mint_to(
        token_program_account.key,
        mint_account.key,
        destination_token_account.key,
        mint_authority_account.key,
        &[], // No additional signers needed for PDA if it's the only authority
        amount,
    )?;

    solana_program::program::invoke_signed(
        &mint_to_ix,
        &[
            token_program_account.clone(),
            mint_account.clone(),
            destination_token_account.clone(),
            mint_authority_account.clone(),
        ],
        &[signer_seeds],
    )?;

    msg!("Minted {} tokens to {}", amount, destination_token_account.key);
    Ok(())
}

// Helper for brevity
fn next_account_info(iter: &mut std::slice::Iter<AccountInfo>) -> Result<&AccountInfo, ProgramError> {
    iter.next().ok_or(ProgramError::NotEnoughAccountKeys)
}

In this pattern, your custom program derives a PDA, which then holds the mint authority for an SPL Token. When your program needs to mint tokens, it performs a Cross-Program Invocation (CPI) to the SPL Token Program, signing the instruction with its PDA's seeds.

Best Practices

  • Always Use SPL for Standard Functionality: Don't write your own token, stake pool, or associated token account logic. The SPL programs are audited, optimized, and maintained.
  • Understand Account Ownership: Be acutely aware of which program owns which account. SPL programs require specific accounts to be owned by them (e.g., token accounts by TokenkegQfeZyiNwAJbNbPvMhcPkQHGMzQTPHkmfWg).
  • Derive ATAs Correctly: Always use getAssociatedTokenAddress (or find_program_address for the ATA program) to derive associated token accounts deterministically. This prevents users from creating multiple token accounts for the same mint.
  • Handle Token Decimals Carefully: The SPL Token program stores amounts as raw integers. Always apply decimal scaling when displaying to users or accepting user input.

Anti-Patterns

  • Reimplementing SPL Functionality. Writing custom token, stake pool, or associated token account logic instead of using the audited SPL programs introduces unnecessary security risk and maintenance burden.

  • Incorrect Account Ownership Assumptions. Passing accounts to SPL program instructions without verifying they are owned by the expected SPL program (e.g., TokenkegQ for token accounts) enables account substitution attacks.

  • Non-Deterministic ATA Derivation. Deriving associated token account addresses manually instead of using getAssociatedTokenAddress risks producing incorrect addresses that do not match the canonical ATA program derivation.

  • Missing Rent Exemption Checks. Creating accounts without ensuring they meet rent-exemption thresholds causes accounts to be garbage collected, losing stored data and lamports.

  • Ignoring Token-2022 Extension Compatibility. Building integrations that assume all SPL tokens use the original Token Program ignores that Token-2022 tokens have extensions (transfer fees, confidential transfers) requiring different handling.

Install this skill directly: skilldb add solana-ecosystem-skills

Get CLI access →

Related Skills

Solana RPC Optimization

This skill teaches you how to reduce RPC call volume, improve transaction reliability, handle rate limits, and select appropriate commitment levels for your Solana dApps. You apply these optimization techniques to build high-performance, resilient Solana applications that deliver a smooth user experience and operate efficiently under high demand.

Solana Ecosystem269L

Solana Testing Bankrun

This skill covers using Bankrun for rapid, isolated, and deterministic testing of Solana programs. You leverage Bankrun when you need to unit test or integration test your Solana programs locally without the overhead of `solana-test-validator`, enabling faster development cycles and more reliable simulations.

Solana Ecosystem244L

Solana Token Program

The Solana Token Program (SPL Token program) is the official on-chain program for creating, managing, and transferring fungible and non-fungible tokens on Solana. You leverage this skill to implement custom token economies, issue NFTs, manage asset custody, and build decentralized applications that interact with standardized digital assets.

Solana Ecosystem281L

Solana Transaction Optimization

This skill focuses on strategies and techniques to reduce transaction costs, increase transaction reliability, and improve user experience on Solana by optimizing transaction size, compute unit consumption, and priority fee application. You leverage these optimization methods when building high-throughput Solana dApps, interacting with congested programs, or ensuring predictable and affordable transaction execution for your users.

Solana Ecosystem301L

Solana Validator Setup

This skill guides you through the process of setting up and operating a Solana validator, enabling you to participate in network consensus, process transactions, and earn staking rewards. You leverage this skill when contributing to the decentralization and security of the Solana network, ensuring high availability and performance for your validator node.

Solana Ecosystem161L

Anchor Framework Deep

Anchor is a framework for Solana smart contract development that provides a set of tools, macros, and an Interface Definition Language (IDL) to simplify writing secure and efficient on-chain programs. You leverage Anchor when building complex Solana dApps, needing robust account validation, streamlined testing, and a clear client-side interface.

Solana Ecosystem286L