> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/solana-foundation/anchor/llms.txt
> Use this file to discover all available pages before exploring further.

# SPL Integrations

> Learn how to integrate Solana Program Library (SPL) programs in your Anchor projects using the anchor-spl crate.

The `anchor-spl` crate provides CPI clients and helper modules for interacting with Solana's core SPL programs from your Anchor programs. This page covers the available modules and how to use them effectively.

## Installation

Add `anchor-spl` to your program's dependencies:

```shell theme={null}
cargo add anchor-spl
```

Update your `Cargo.toml` to include the IDL build feature:

```toml title="Cargo.toml" theme={null}
[features]
idl-build = [
    "anchor-lang/idl-build",
    "anchor-spl/idl-build",
]

[dependencies]
anchor-lang = "0.32.1"
anchor-spl = "0.32.1"
```

## Available Modules

The `anchor-spl` crate provides the following modules for common SPL program interactions:

### Token Programs

| Module                  | Description                                                           |
| ----------------------- | --------------------------------------------------------------------- |
| `token`                 | Original Token Program instructions and account types                 |
| `token_2022`            | Token Extensions Program base instructions                            |
| `token_2022_extensions` | Token Extensions Program extension-specific instructions              |
| `token_interface`       | Account types compatible with both Token Program and Token Extensions |
| `associated_token`      | Associated Token Account Program instructions                         |

### Other SPL Programs

| Module       | Description                                 |
| ------------ | ------------------------------------------- |
| `metadata`   | Metaplex Token Metadata Program integration |
| `memo`       | SPL Memo Program integration                |
| `stake`      | Solana Stake Program integration            |
| `governance` | SPL Governance Program integration          |

## Token Program Integration

The most common use case is interacting with Solana's Token Programs. The `anchor-spl` crate provides both program-specific modules (`token`, `token_2022`) and a unified interface (`token_interface`).

### Using Token Interface (Recommended)

The `token_interface` module provides account types that work with both the original Token Program and Token Extensions Program. This is the recommended approach for maximum compatibility:

```rust theme={null}
use anchor_spl::token_interface::{
    self, Mint, TokenAccount, TokenInterface, MintTo
};

#[derive(Accounts)]
pub struct MintTokens<'info> {
    #[account(mut)]
    pub mint: InterfaceAccount<'info, Mint>,
    #[account(mut)]
    pub token_account: InterfaceAccount<'info, TokenAccount>,
    pub authority: Signer<'info>,
    pub token_program: Interface<'info, TokenInterface>,
}

pub fn mint_tokens(ctx: Context<MintTokens>, amount: u64) -> Result<()> {
    token_interface::mint_to(
        CpiContext::new(
            ctx.accounts.token_program.to_account_info(),
            MintTo {
                mint: ctx.accounts.mint.to_account_info(),
                to: ctx.accounts.token_account.to_account_info(),
                authority: ctx.accounts.authority.to_account_info(),
            },
        ),
        amount,
    )?;
    Ok(())
}
```

### Program-Specific Modules

For scenarios requiring specific token program features:

```rust theme={null}
use anchor_spl::token_2022::{
    self, Token2022, transfer_checked, TransferChecked
};

#[derive(Accounts)]
pub struct TransferWithExtensions<'info> {
    #[account(mut)]
    pub from: Account<'info, TokenAccount>,
    #[account(mut)]
    pub to: Account<'info, TokenAccount>,
    pub mint: Account<'info, Mint>,
    pub authority: Signer<'info>,
    pub token_program: Program<'info, Token2022>,
}
```

## Associated Token Accounts

The `associated_token` module provides helper functions for working with Associated Token Accounts (ATAs):

```rust theme={null}
use anchor_spl::{
    associated_token::AssociatedToken,
    token_interface::{Mint, TokenAccount, TokenInterface},
};

#[derive(Accounts)]
pub struct CreateATA<'info> {
    #[account(mut)]
    pub payer: Signer<'info>,
    #[account(
        init,
        payer = payer,
        associated_token::mint = mint,
        associated_token::authority = payer,
    )]
    pub token_account: InterfaceAccount<'info, TokenAccount>,
    pub mint: InterfaceAccount<'info, Mint>,
    pub token_program: Interface<'info, TokenInterface>,
    pub associated_token_program: Program<'info, AssociatedToken>,
    pub system_program: Program<'info, System>,
}
```

## Token Extensions

Token 2022 introduces extensions that add functionality to mints and token accounts. Use the `token_2022_extensions` module:

```rust theme={null}
use anchor_spl::token_2022_extensions::{
    transfer_fee, TransferFee, TransferFeeConfig,
};

#[derive(Accounts)]
pub struct InitializeTransferFee<'info> {
    #[account(mut)]
    pub mint: Account<'info, Mint>,
    pub authority: Signer<'info>,
    pub token_program: Program<'info, Token2022>,
}

pub fn initialize_transfer_fee(
    ctx: Context<InitializeTransferFee>,
    transfer_fee_basis_points: u16,
    maximum_fee: u64,
) -> Result<()> {
    transfer_fee::initialize_transfer_fee_config(
        CpiContext::new(
            ctx.accounts.token_program.to_account_info(),
            TransferFeeConfig {
                mint: ctx.accounts.mint.to_account_info(),
            },
        ),
        Some(&ctx.accounts.authority.key()),
        Some(&ctx.accounts.authority.key()),
        transfer_fee_basis_points,
        maximum_fee,
    )?;
    Ok(())
}
```

## Metadata Integration

For NFTs and fungible tokens with metadata, use the `metadata` module:

```rust theme={null}
use anchor_spl::metadata::{
    Metadata,
    mpl_token_metadata::types::DataV2,
};

#[derive(Accounts)]
pub struct CreateMetadata<'info> {
    #[account(mut)]
    pub metadata: UncheckedAccount<'info>,
    pub mint: Account<'info, Mint>,
    pub mint_authority: Signer<'info>,
    #[account(mut)]
    pub payer: Signer<'info>,
    pub update_authority: SystemAccount<'info>,
    pub system_program: Program<'info, System>,
    pub rent: Sysvar<'info, Rent>,
    pub metadata_program: Program<'info, Metadata>,
}
```

<Callout type="info">
  The metadata module requires enabling the `metadata` feature in your Cargo.toml:

  ```toml theme={null}
  anchor-spl = { version = "0.32.1", features = ["metadata"] }
  ```
</Callout>

## Memo Program

Add on-chain memos to your transactions:

```rust theme={null}
use anchor_spl::memo::{Memo, BuildMemo};

#[derive(Accounts)]
pub struct AddMemo<'info> {
    pub signer: Signer<'info>,
    pub memo_program: Program<'info, Memo>,
}

pub fn add_memo(ctx: Context<AddMemo>, memo: String) -> Result<()> {
    let cpi_program = ctx.accounts.memo_program.to_account_info();
    let cpi_accounts = BuildMemo {
        memo: memo.as_bytes(),
    };
    anchor_spl::memo::build_memo(
        CpiContext::new(cpi_program, cpi_accounts),
        memo.as_bytes(),
    )?;
    Ok(())
}
```

## Feature Flags

The `anchor-spl` crate uses feature flags to control which modules are included:

```toml theme={null}
[dependencies.anchor-spl]
version = "0.32.1"
features = [
    "token",                    # Token Program
    "token_2022",              # Token Extensions Program
    "token_2022_extensions",   # Token Extensions
    "associated_token",        # Associated Token Accounts
    "metadata",                # Metaplex Metadata
    "memo",                    # Memo Program
    "stake",                   # Stake Program
    "governance",              # Governance Program
]
```

By default, `token`, `token_2022`, `token_2022_extensions`, `associated_token`, and `mint` features are enabled.

## Common Patterns

### Creating and Minting Tokens

```rust theme={null}
use anchor_lang::prelude::*;
use anchor_spl::{
    associated_token::AssociatedToken,
    token_interface::{self, Mint, MintTo, TokenAccount, TokenInterface},
};

declare_id!("YourProgramIDHere");

#[program]
pub mod token_operations {
    use super::*;

    pub fn create_and_mint(
        ctx: Context<CreateAndMint>,
        amount: u64,
    ) -> Result<()> {
        // Mint tokens to the associated token account
        token_interface::mint_to(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                MintTo {
                    mint: ctx.accounts.mint.to_account_info(),
                    to: ctx.accounts.token_account.to_account_info(),
                    authority: ctx.accounts.mint_authority.to_account_info(),
                },
            ),
            amount,
        )?;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct CreateAndMint<'info> {
    #[account(mut)]
    pub mint_authority: Signer<'info>,
    #[account(
        mut,
        mint::authority = mint_authority,
        mint::decimals = 9,
    )]
    pub mint: InterfaceAccount<'info, Mint>,
    #[account(
        init_if_needed,
        payer = mint_authority,
        associated_token::mint = mint,
        associated_token::authority = mint_authority,
    )]
    pub token_account: InterfaceAccount<'info, TokenAccount>,
    pub token_program: Interface<'info, TokenInterface>,
    pub associated_token_program: Program<'info, AssociatedToken>,
    pub system_program: Program<'info, System>,
}
```

### Transfer with Authority

```rust theme={null}
use anchor_spl::token_interface::{self, Transfer};

pub fn transfer_tokens(
    ctx: Context<TransferTokens>,
    amount: u64,
) -> Result<()> {
    token_interface::transfer(
        CpiContext::new(
            ctx.accounts.token_program.to_account_info(),
            Transfer {
                from: ctx.accounts.from.to_account_info(),
                to: ctx.accounts.to.to_account_info(),
                authority: ctx.accounts.authority.to_account_info(),
            },
        ),
        amount,
    )?;
    Ok(())
}

#[derive(Accounts)]
pub struct TransferTokens<'info> {
    #[account(mut)]
    pub from: InterfaceAccount<'info, TokenAccount>,
    #[account(mut)]
    pub to: InterfaceAccount<'info, TokenAccount>,
    pub authority: Signer<'info>,
    pub token_program: Interface<'info, TokenInterface>,
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use InterfaceAccount for Token Compatibility">
    Always use `InterfaceAccount<'info, T>` and `Interface<'info, TokenInterface>` when you want your program to work with both Token Program and Token Extensions Program:

    ```rust theme={null}
    // Good - Works with both programs
    pub mint: InterfaceAccount<'info, Mint>,
    pub token_program: Interface<'info, TokenInterface>,

    // Limited - Only works with original Token Program
    pub mint: Account<'info, Mint>,
    pub token_program: Program<'info, Token>,
    ```
  </Accordion>

  <Accordion title="Check Account Ownership">
    Always validate that token accounts belong to the expected token program:

    ```rust theme={null}
    require_eq!(
        ctx.accounts.token_account.owner,
        ctx.accounts.token_program.key(),
        ErrorCode::InvalidTokenProgram
    );
    ```
  </Accordion>

  <Accordion title="Validate Mint Relationships">
    Ensure token accounts belong to the correct mint:

    ```rust theme={null}
    #[account(
        mut,
        token::mint = mint,
        token::authority = authority,
    )]
    pub token_account: InterfaceAccount<'info, TokenAccount>,
    ```
  </Accordion>
</AccordionGroup>

## Resources

* [anchor-spl Source Code](https://github.com/coral-xyz/anchor/tree/master/spl)
* [Solana Token Program Documentation](https://spl.solana.com/token)
* [Token Extensions Program Guide](https://spl.solana.com/token-2022)
* [Anchor Token Examples](/tokens/overview)
