> ## Documentation Index
> Fetch the complete documentation index at: https://luminouslabs-cc5545c6-docs-main-reorder.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# SPL to Light Reference

> Side-by-side mapping of every Light Token instruction against its SPL/Solana equivalent. Covers RPC, TypeScript client, Rust client, program CPI, and Anchor macros.

Side-by-side mapping of Light Token and SPL/Solana instructions. The Light Token SDK calls compression RPC methods internally — you use the same interface functions for all token operations.

***

## RPC

The Light Token SDK calls Photon RPC methods internally via interface functions like `transferInterface` and `getAtaInterface`. Call them directly for custom indexing, block explorers, or debugging.

> [API reference](/api-reference/json-rpc-methods/overview)

### Create an RPC connection

<Tabs>
  <Tab title="TypeScript">
    <Columns cols={2}>
      <Card title="Light Token">
        ```typescript theme={null}
        import { createRpc, Rpc } from "@lightprotocol/stateless.js";

        // Helius exposes Solana and Photon RPC endpoints through a single URL
        const rpc: Rpc = createRpc(RPC_ENDPOINT, RPC_ENDPOINT);
        ```
      </Card>

      <Card title="Solana">
        ```typescript theme={null}
        import { Connection } from "@solana/web3.js";

        const connection = new Connection(RPC_ENDPOINT);
        ```
      </Card>
    </Columns>
  </Tab>

  <Tab title="Rust">
    <Columns cols={2}>
      <Card title="Light Token">
        ```rust theme={null}
        use light_client::rpc::{LightClient, LightClientConfig, Rpc};

        let rpc = LightClient::new(
            LightClientConfig::new(rpc_url.to_string(), None, None)
        ).await?;
        ```
      </Card>

      <Card title="Solana">
        ```rust theme={null}
        use solana_client::rpc_client::RpcClient;

        let client = RpcClient::new(rpc_url.to_string());
        ```
      </Card>
    </Columns>
  </Tab>
</Tabs>

### Get balance

Fetch the parsed state of a light token account, including hot and cold balances.

> [Guide](/light-token/toolkits/for-payments) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/get-balance.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import {
      getAssociatedTokenAddressInterface,
      getAtaInterface,
    } from "@lightprotocol/compressed-token/unified";

    const ata = getAssociatedTokenAddressInterface(mint, owner);
    const account = await getAtaInterface(rpc, ata, owner, mint);

    console.log(account.parsed.amount);
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { getAccount } from "@solana/spl-token";

    const account = await getAccount(connection, ata);

    console.log(account.amount);
    ```
  </Card>
</Columns>

### Transaction history

Fetch merged and deduplicated transaction history across on-chain and compressed transactions.

> [Guide](/light-token/toolkits/for-payments) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/get-history.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    const result = await rpc.getSignaturesForOwnerInterface(owner);

    console.log(result.signatures); // Merged + deduplicated
    console.log(result.solana);     // On-chain txs only
    console.log(result.compressed); // Compressed txs only
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    const signatures = await connection.getSignaturesForAddress(ata);
    ```
  </Card>
</Columns>

***

## TypeScript client

`@lightprotocol/compressed-token` interface functions match the `@solana/spl-token` API. Use `rpc` (from `createRpc`) instead of `connection`.

#### Instruction API return types

Some instruction builders return a single instruction, others return a 2D array (`TransactionInstruction[][]`) where each inner array is one transaction. The 2D shape handles cases where cold balances need loading in a separate preceding transaction.

| Return type                  | APIs                                                                                                                                                   |
| :--------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TransactionInstruction`     | `createAssociatedTokenAccountInterfaceInstruction`, `createMintToInterfaceInstruction`, `createLightTokenTransferInstruction`, `createWrapInstruction` |
| `TransactionInstruction[][]` | `createTransferInterfaceInstructions`, `createLoadAtaInstructions`, `createUnwrapInstructions`                                                         |

For batch builders, loop over the array and build a transaction from each entry:

```typescript theme={null}
for (const ixs of instructions) {
  const tx = new Transaction().add(...ixs);
  await sendAndConfirmTransaction(rpc, tx, [payer, owner]);
}
```

### Create mint

Create a mint account with optional token metadata. The light token program sponsors rent-exemption.

> [Guide](/light-token/cookbook/create-mint) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/create-mint.ts) |
> [Source](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/create-mint-interface.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import { createMintInterface } from "@lightprotocol/compressed-token";

    const { mint } = await createMintInterface(
      rpc,
      payer,
      mintAuthority,
      freezeAuthority,
      decimals,
      mintKeypair
    );
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { createMint } from "@solana/spl-token";

    const mint = await createMint(
      connection,
      payer,
      mintAuthority,
      freezeAuthority,
      decimals
    );
    ```
  </Card>
</Columns>

### Create associated token account

Create an associated token account. Light-ATAs hold balances of light, SPL, or Token 2022 mints.

> [Guide](/light-token/cookbook/create-ata) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/create-ata.ts) |
> [Source](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/create-ata-interface.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import { createAtaInterface } from "@lightprotocol/compressed-token";

    const ata = await createAtaInterface(
      rpc,
      payer,
      mint,
      owner
    );
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { getOrCreateAssociatedTokenAccount } from "@solana/spl-token";

    const ata = await getOrCreateAssociatedTokenAccount(
      connection,
      payer,
      mint,
      owner
    );
    ```
  </Card>
</Columns>

### Mint tokens

Mint tokens to a destination account. Auto-detects the token program.

> [Guide](/light-token/cookbook/mint-to) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/mint-to.ts) |
> [Source](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/mint-to-interface.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import { mintToInterface } from "@lightprotocol/compressed-token";

    const tx = await mintToInterface(
      rpc,
      payer,
      mint,
      destination,
      mintAuthority,
      amount
    );
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { mintTo } from "@solana/spl-token";

    const tx = await mintTo(
      connection,
      payer,
      mint,
      destination,
      mintAuthority,
      amount
    );
    ```
  </Card>
</Columns>

### Transfer tokens

Transfer tokens between accounts. Handles loading cold state, creating the recipient ATA, and transferring in one call. Supports Light-to-Light, SPL-to-Light, and Light-to-SPL transfers.

> [Guide](/light-token/cookbook/transfer-interface) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/transfer-interface.ts) |
> [Source](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/transfer-interface.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import { transferInterface } from "@lightprotocol/compressed-token/unified";

    const tx = await transferInterface(
      rpc,
      payer,
      sourceAta,
      mint,
      recipient,
      owner,
      amount
    );
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { transfer } from "@solana/spl-token";

    const tx = await transfer(
      connection,
      payer,
      sourceAta,
      destinationAta,
      owner,
      amount
    );
    ```
  </Card>
</Columns>

<Accordion title="Unify fragmented token balances">
  When a user receives tokens from multiple senders, each compressed account is stored separately. Use `createTransferInterfaceInstructions` with `sliceLast` to load all fragments in parallel before transferring.

  > [Guide](/light-token/toolkits/for-payments) |
  > [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/toolkits/payments-and-wallets/send.ts)

  ```typescript theme={null}
  import { createTransferInterfaceInstructions } from "@lightprotocol/compressed-token/unified";
  import { sliceLast } from "@lightprotocol/stateless.js";

  const instructions = await createTransferInterfaceInstructions(
    rpc, payer.publicKey, mint, amount, owner.publicKey, recipient
  );

  const { rest: loadInstructions, last: transferInstructions } = sliceLast(instructions);

  // Load all compressed accounts in parallel
  await Promise.all(
    loadInstructions.map((ixs) => {
      const tx = new Transaction().add(...ixs);
      tx.sign(payer, owner);
      return sendAndConfirmTransaction(rpc, tx);
    })
  );

  // Then transfer
  const transferTx = new Transaction().add(...transferInstructions);
  transferTx.sign(payer, owner);
  await sendAndConfirmTransaction(rpc, transferTx);
  ```
</Accordion>

<Accordion title="Load ATA">
  Load creates the ATA if needed and loads any compressed state into it. Light Token accounts auto-compress inactive accounts. Before any action, the SDK detects cold balances and adds instructions to load them.

  > [Guide](/light-token/cookbook/load-ata) |
  > [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/load-ata.ts) |
  > [Source](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/v3/actions/load-ata.ts)

  ```typescript theme={null}
  import {
    loadAta,
    getAssociatedTokenAddressInterface,
  } from "@lightprotocol/compressed-token/unified";

  const ata = getAssociatedTokenAddressInterface(mint, recipient);

  const sig = await loadAta(rpc, ata, recipient, mint, payer);
  ```
</Accordion>

<Accordion title="Wrap and unwrap">
  **Wrap** moves tokens from an SPL/Token 2022 account to a Light Token ATA (hot balance). **Unwrap** moves tokens back to SPL — use this to compose with applications that do not yet support light-token.

  > [Guide](/light-token/cookbook/wrap-unwrap) |
  > [Example (wrap)](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/wrap.ts) |
  > [Example (unwrap)](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/unwrap.ts)

  ```typescript theme={null}
  import { getAssociatedTokenAddressSync } from "@solana/spl-token";
  import {
    wrap,
    getAssociatedTokenAddressInterface,
  } from "@lightprotocol/compressed-token/unified";

  const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey);
  const tokenAta = getAssociatedTokenAddressInterface(mint, owner.publicKey);

  await wrap(rpc, payer, splAta, tokenAta, owner, mint, amount);
  ```

  ```typescript theme={null}
  import { getAssociatedTokenAddressSync } from "@solana/spl-token";
  import { unwrap } from "@lightprotocol/compressed-token/unified";

  const splAta = getAssociatedTokenAddressSync(mint, owner.publicKey);

  await unwrap(rpc, payer, splAta, owner, mint, amount);
  ```
</Accordion>

### Approve delegate

Approve a delegate to spend tokens up to a specified amount.

> [Guide](/light-token/cookbook/approve-revoke) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/delegate-approve.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import { approve } from "@lightprotocol/compressed-token";

    const tx = await approve(
      rpc,
      payer,
      mint,
      amount,
      owner,
      delegate
    );
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { approve } from "@solana/spl-token";

    const tx = await approve(
      connection,
      payer,
      source,
      delegate,
      owner,
      amount
    );
    ```
  </Card>
</Columns>

### Revoke delegate

Remove all delegate permissions.

> [Guide](/light-token/cookbook/approve-revoke) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/delegate-revoke.ts)

<Columns cols={2}>
  <Card title="Light Token">
    ```typescript theme={null}
    import { revoke } from "@lightprotocol/compressed-token";

    const tx = await revoke(
      rpc,
      payer,
      delegatedAccounts,
      owner
    );
    ```
  </Card>

  <Card title="SPL">
    ```typescript theme={null}
    import { revoke } from "@solana/spl-token";

    const tx = await revoke(
      connection,
      payer,
      source,
      owner
    );
    ```
  </Card>
</Columns>

***

## Rust client

`light_token_client` uses builder structs with `.instruction()` or `.execute()`. All instructions map 1:1 to `spl_token::instruction::*`.

### Create mint

> [Guide](/light-token/cookbook/create-mint) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/create_mint.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CreateMint;

    let ix = CreateMint::new(
        params,
        mint_seed.pubkey(),
        payer.pubkey(),
        address_tree.tree,
        output_queue,
    )
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::initialize_mint;

    let ix = initialize_mint(
        &spl_token::id(),
        &mint.pubkey(),
        &mint_authority,
        Some(&freeze_authority),
        decimals,
    )?;
    ```
  </Card>
</Columns>

### Create associated token account

> [Guide](/light-token/cookbook/create-ata) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/create_associated_token_account.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CreateAssociatedTokenAccount;

    let ix = CreateAssociatedTokenAccount::new(
        payer.pubkey(),
        owner.pubkey(),
        mint,
    )
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_associated_token_account::instruction::create_associated_token_account;

    let ix = create_associated_token_account(
        &payer.pubkey(),
        &owner.pubkey(),
        &mint,
        &spl_token::id(),
    );
    ```
  </Card>
</Columns>

### Create token account

> [Guide](/light-token/cookbook/create-token-account) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/instructions/create_token_account.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CreateTokenAccount;

    let ix = CreateTokenAccount::new(
        payer.pubkey(),
        account.pubkey(),
        mint,
        owner,
    )
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::initialize_account;

    let ix = initialize_account(
        &spl_token::id(),
        &account,
        &mint,
        &owner,
    )?;
    ```
  </Card>
</Columns>

### Mint tokens

> [Guide](/light-token/cookbook/mint-to) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/mint_to.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::MintTo;

    let ix = MintTo {
        mint,
        destination,
        amount,
        authority: payer.pubkey(),
        max_top_up: None,
        fee_payer: None,
    }
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::mint_to;

    let ix = mint_to(
        &spl_token::id(),
        &mint,
        &destination,
        &mint_authority,
        &[],
        amount,
    )?;
    ```
  </Card>
</Columns>

### Transfer (interface)

Unified interface that routes across Light Token, SPL, and Token 2022 accounts.

> [Guide](/light-token/cookbook/transfer-interface) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/transfer_interface.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::TransferInterface;

    let ix = TransferInterface {
        source,
        destination,
        amount,
        decimals,
        authority: payer.pubkey(),
        payer: payer.pubkey(),
        spl_interface: None,
        max_top_up: None,
        source_owner: LIGHT_TOKEN_PROGRAM_ID,
        destination_owner: LIGHT_TOKEN_PROGRAM_ID,
    }
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::transfer;

    let ix = transfer(
        &spl_token::id(),
        &source,
        &destination,
        &authority,
        &[],
        amount,
    )?;
    ```
  </Card>
</Columns>

### Transfer (checked)

Transfer with decimal validation.

> [Guide](/light-token/cookbook/transfer-checked) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/transfer_checked.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::TransferChecked;

    let ix = TransferChecked {
        source,
        destination,
        mint,
        amount,
        decimals,
        authority: payer.pubkey(),
    }
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::transfer_checked;

    let ix = transfer_checked(
        &spl_token::id(),
        &source,
        &mint,
        &destination,
        &authority,
        &[],
        amount,
        decimals,
    )?;
    ```
  </Card>
</Columns>

### Burn

Permanently destroy tokens and reduce mint supply.

> [Guide](/light-token/cookbook/burn) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/instructions/burn.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::Burn;

    let ix = Burn {
        source,
        mint,
        amount,
        authority: payer.pubkey(),
        max_top_up: None,
        fee_payer: None,
    }
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::burn;

    let ix = burn(
        &spl_token::id(),
        &source,
        &mint,
        &authority,
        &[],
        amount,
    )?;
    ```
  </Card>
</Columns>

### Freeze and thaw

Freeze prevents all transfers, burns, or closes. Only the freeze authority can freeze or thaw.

> [Guide](/light-token/cookbook/freeze-thaw) |
> [Example (freeze)](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/instructions/freeze.rs) |
> [Example (thaw)](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/instructions/thaw.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::Freeze;

    let ix = Freeze {
        token_account: ata,
        mint,
        freeze_authority: payer.pubkey(),
    }
    .instruction()?;
    ```

    ```rust theme={null}
    use light_token::instruction::Thaw;

    let ix = Thaw {
        token_account: ata,
        mint,
        freeze_authority: payer.pubkey(),
    }
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::{freeze_account, thaw_account};

    let ix = freeze_account(
        &spl_token::id(),
        &account,
        &mint,
        &freeze_authority,
        &[],
    )?;

    let ix = thaw_account(
        &spl_token::id(),
        &account,
        &mint,
        &freeze_authority,
        &[],
    )?;
    ```
  </Card>
</Columns>

### Approve and revoke

Approve a delegate or remove all delegate permissions.

> [Guide](/light-token/cookbook/approve-revoke) |
> [Example (approve)](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/approve.rs) |
> [Example (revoke)](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/revoke.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::Approve;

    let ix = Approve {
        token_account: ata,
        delegate: delegate.pubkey(),
        owner: payer.pubkey(),
        amount,
    }
    .instruction()?;
    ```

    ```rust theme={null}
    use light_token::instruction::Revoke;

    let ix = Revoke {
        token_account: ata,
        owner: payer.pubkey(),
    }
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::{approve, revoke};

    let ix = approve(
        &spl_token::id(),
        &source,
        &delegate,
        &owner,
        &[],
        amount,
    )?;

    let ix = revoke(
        &spl_token::id(),
        &source,
        &owner,
        &[],
    )?;
    ```
  </Card>
</Columns>

### Close token account

Close an empty token account and reclaim lamports.

> [Guide](/light-token/cookbook/close-token-account) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/instructions/close.rs) |
> [Source](https://docs.rs/light-token-client)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::{CloseAccount, LIGHT_TOKEN_PROGRAM_ID};

    let ix = CloseAccount::new(
        LIGHT_TOKEN_PROGRAM_ID,
        account,
        destination,
        owner,
    )
    .instruction()?;
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::close_account;

    let ix = close_account(
        &spl_token::id(),
        &account,
        &destination,
        &owner,
        &[],
    )?;
    ```
  </Card>
</Columns>

### Wrap and unwrap

Move tokens between SPL/Token 2022 and Light Token accounts.

> [Guide](/light-token/cookbook/wrap-unwrap) |
> [Example (wrap)](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/wrap.rs) |
> [Example (unwrap)](https://github.com/Lightprotocol/examples-light-token/blob/main/rust-client/actions/unwrap.rs) |
> [Source](https://docs.rs/light-token-client)

<Card title="Light Token (no SPL equivalent)">
  ```rust theme={null}
  use light_token_client::actions::wrap::Wrap;

  Wrap {
      rpc: &mut rpc,
      payer: &payer,
      spl_ata,
      light_ata,
      owner: &owner,
      mint,
      amount,
  }
  .execute()
  .await?;
  ```

  ```rust theme={null}
  use light_token_client::actions::unwrap::Unwrap;

  Unwrap {
      rpc: &mut rpc,
      payer: &payer,
      spl_ata,
      owner: &owner,
      mint,
      amount,
  }
  .execute()
  .await?;
  ```
</Card>

***

## Program CPI

`light_token::instruction::*Cpi` structs map 1:1 to `spl_token::instruction::*`. Use `.invoke()` for external signers or `.invoke_signed()` for PDA signers. Add `.rent_free()` to sponsor rent-exemption on account creation.

### CreateMintCpi

Create a rent-free mint account via CPI.

> [Guide](/light-token/cookbook/create-mint) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/create-mint/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CreateMintCpi;

    CreateMintCpi {
        mint_seed: mint_seed.clone(),
        authority: authority.clone(),
        payer: payer.clone(),
        address_tree: address_tree.clone(),
        output_queue: output_queue.clone(),
        compressible_config: compressible_config.clone(),
        mint: mint.clone(),
        rent_sponsor: rent_sponsor.clone(),
        system_accounts,
        cpi_context: None,
        cpi_context_account: None,
        params,
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::initialize_mint;

    let ix = initialize_mint(
        &spl_token::id(),
        &mint.pubkey(),
        &mint_authority,
        Some(&freeze_authority),
        decimals,
    )?;

    invoke(&ix, &[mint, rent_sysvar])?;
    ```
  </Card>
</Columns>

### CreateAssociatedAccountCpi

Create a rent-free associated token account via CPI.

> [Guide](/light-token/cookbook/create-ata) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/create-ata/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CreateAssociatedAccountCpi;

    CreateAssociatedAccountCpi {
        payer: payer.clone(),
        owner: owner.clone(),
        mint: mint.clone(),
        ata: associated_token_account.clone(),
        bump,
    }
    .rent_free(
        compressible_config.clone(),
        rent_sponsor.clone(),
        system_program.clone(),
    )
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_associated_token_account::instruction::create_associated_token_account;

    let ix = create_associated_token_account(
        &payer.pubkey(),
        &owner.pubkey(),
        &mint,
        &spl_token::id(),
    );

    invoke(&ix, &[payer, owner, mint])?;
    ```
  </Card>
</Columns>

### CreateTokenAccountCpi

Create a rent-free token account via CPI.

> [Guide](/light-token/cookbook/create-token-account) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/create-token-account/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CreateTokenAccountCpi;

    CreateTokenAccountCpi {
        payer: payer.clone(),
        account: account.clone(),
        mint: mint.clone(),
        owner,
    }
    .rent_free(
        compressible_config.clone(),
        rent_sponsor.clone(),
        system_program.clone(),
        token_program.key,
    )
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::initialize_account;

    let ix = initialize_account(
        &spl_token::id(),
        &account,
        &mint,
        &owner,
    )?;

    invoke(&ix, &[account, mint, owner])?;
    ```
  </Card>
</Columns>

### MintToCpi

Mint tokens to a destination account via CPI.

> [Guide](/light-token/cookbook/mint-to) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/mint-to/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::MintToCpi;

    MintToCpi {
        mint: mint.clone(),
        destination: destination.clone(),
        authority: authority.clone(),
        amount,
        fee_payer: None,
        max_top_up: None,
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::mint_to;

    let ix = mint_to(
        &spl_token::id(),
        &mint,
        &destination,
        &mint_authority,
        &[],
        amount,
    )?;

    invoke(&ix, &[mint, destination, authority])?;
    ```
  </Card>
</Columns>

### TransferCheckedCpi

Transfer with decimal validation via CPI.

> [Guide](/light-token/cookbook/transfer-checked) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/transfer-checked/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::TransferCheckedCpi;

    TransferCheckedCpi {
        source: source.clone(),
        destination: destination.clone(),
        mint: mint.clone(),
        authority: authority.clone(),
        amount,
        decimals,
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::transfer_checked;

    let ix = transfer_checked(
        &spl_token::id(),
        &source,
        &mint,
        &destination,
        &authority,
        &[],
        amount,
        decimals,
    )?;

    invoke(&ix, &[source, mint, destination, authority])?;
    ```
  </Card>
</Columns>

### BurnCpi

Burn tokens via CPI.

> [Guide](/light-token/cookbook/burn) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/burn/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::BurnCpi;

    BurnCpi {
        source: source.clone(),
        mint: mint.clone(),
        authority: authority.clone(),
        amount,
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::burn;

    let ix = burn(
        &spl_token::id(),
        &source,
        &mint,
        &authority,
        &[],
        amount,
    )?;

    invoke(&ix, &[source, mint, authority])?;
    ```
  </Card>
</Columns>

### FreezeCpi and ThawCpi

Freeze or thaw a token account via CPI.

> [Guide](/light-token/cookbook/freeze-thaw) |
> [Example (freeze)](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/freeze/src/lib.rs) |
> [Example (thaw)](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/thaw/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::FreezeCpi;

    FreezeCpi {
        token_account: token_account.clone(),
        mint: mint.clone(),
        freeze_authority: freeze_authority.clone(),
    }
    .invoke()?
    ```

    ```rust theme={null}
    use light_token::instruction::ThawCpi;

    ThawCpi {
        token_account: token_account.clone(),
        mint: mint.clone(),
        freeze_authority: freeze_authority.clone(),
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::{freeze_account, thaw_account};

    let ix = freeze_account(
        &spl_token::id(), &account, &mint, &freeze_authority, &[],
    )?;
    invoke(&ix, &[account, mint, freeze_authority])?;

    let ix = thaw_account(
        &spl_token::id(), &account, &mint, &freeze_authority, &[],
    )?;
    invoke(&ix, &[account, mint, freeze_authority])?;
    ```
  </Card>
</Columns>

### ApproveCpi and RevokeCpi

Approve a delegate or revoke permissions via CPI.

> [Guide](/light-token/cookbook/approve-revoke) |
> [Example (approve)](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/approve/src/lib.rs) |
> [Example (revoke)](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/revoke/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::ApproveCpi;

    ApproveCpi {
        token_account: token_account.clone(),
        delegate: delegate.clone(),
        owner: owner.clone(),
        amount,
    }
    .invoke()?
    ```

    ```rust theme={null}
    use light_token::instruction::RevokeCpi;

    RevokeCpi {
        token_account: token_account.clone(),
        owner: owner.clone(),
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::{approve, revoke};

    let ix = approve(
        &spl_token::id(), &source, &delegate, &owner, &[], amount,
    )?;
    invoke(&ix, &[source, delegate, owner])?;

    let ix = revoke(
        &spl_token::id(), &source, &owner, &[],
    )?;
    invoke(&ix, &[source, owner])?;
    ```
  </Card>
</Columns>

### CloseAccountCpi

Close a token account and reclaim lamports via CPI.

> [Guide](/light-token/cookbook/close-token-account) |
> [Example](https://github.com/Lightprotocol/examples-light-token/blob/main/programs/anchor/basic-instructions/close/src/lib.rs) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_token::instruction::CloseAccountCpi;

    CloseAccountCpi {
        account: account.clone(),
        destination: destination.clone(),
        authority: authority.clone(),
    }
    .invoke()?
    ```
  </Card>

  <Card title="SPL">
    ```rust theme={null}
    use spl_token::instruction::close_account;

    let ix = close_account(
        &spl_token::id(), &account, &destination, &owner, &[],
    )?;
    invoke(&ix, &[account, destination, owner])?;
    ```
  </Card>
</Columns>

***

## Anchor macros

`#[light_account(...)]` replaces `#[account(...)]` for rent-free account initialization. Add `#[light_program]` above `#[program]` to enable compression.

### Create mint

> [Guide](/light-token/cookbook/create-mint) |
> [Example](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/basic-macros/create-mint) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    #[light_account(init,
        mint::signer = mint_signer,
        mint::authority = fee_payer,
        mint::decimals = 9,
        mint::seeds = &[MINT_SIGNER_SEED, self.authority.to_account_info().key.as_ref()],
        mint::bump = params.mint_signer_bump
    )]
    pub mint: UncheckedAccount<'info>,
    ```
  </Card>

  <Card title="Anchor">
    ```rust theme={null}
    #[account(
        init,
        payer = fee_payer,
        mint::decimals = 9,
        mint::authority = fee_payer,
    )]
    pub mint: InterfaceAccount<'info, Mint>,
    ```
  </Card>
</Columns>

### Create mint with metadata

Metadata fields are declared inline instead of requiring a separate CPI.

> [Guide](/light-token/cookbook/create-mint) |
> [Example](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/basic-macros/create-mint) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    #[light_account(init,
        mint::signer = mint_signer,
        mint::authority = fee_payer,
        mint::decimals = 9,
        mint::seeds = &[MINT_SIGNER_SEED, self.authority.to_account_info().key.as_ref()],
        mint::bump = params.mint_signer_bump,
        mint::name = params.name.clone(),
        mint::symbol = params.symbol.clone(),
        mint::uri = params.uri.clone(),
        mint::update_authority = authority
    )]
    pub mint: UncheckedAccount<'info>,
    ```
  </Card>

  <Card title="Anchor + Token 2022">
    ```rust theme={null}
    #[account(
        init,
        payer = fee_payer,
        mint::decimals = 9,
        mint::authority = fee_payer,
        extensions::metadata_pointer::authority = fee_payer,
        extensions::metadata_pointer::metadata_address = mint_account,
    )]
    pub mint_account: InterfaceAccount<'info, Mint>,

    // Metadata requires a separate CPI:
    token_metadata_initialize(
        cpi_ctx,
        params.name,
        params.symbol,
        params.uri,
    )?;
    ```
  </Card>
</Columns>

### Create associated token account

> [Guide](/light-token/cookbook/create-ata) |
> [Example](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/basic-macros/create-ata) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    #[light_account(
        init,
        associated_token::authority = ata_owner,
        associated_token::mint = ata_mint,
        associated_token::bump = params.ata_bump
    )]
    pub ata: UncheckedAccount<'info>,
    ```
  </Card>

  <Card title="Anchor">
    ```rust theme={null}
    #[account(
        init,
        payer = fee_payer,
        associated_token::mint = mint,
        associated_token::authority = owner,
    )]
    pub ata: Account<'info, TokenAccount>,
    ```
  </Card>
</Columns>

### Create token account (vault)

> [Guide](/light-token/cookbook/create-token-account) |
> [Example](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/basic-macros/create-token-account) |
> [Source](https://docs.rs/light-token)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    #[account(
        mut,
        seeds = [VAULT_SEED, mint.key().as_ref()],
        bump,
    )]
    #[light_account(init,
        token::authority = [VAULT_SEED, self.mint.key()],
        token::mint = mint,
        token::owner = vault_authority,
        token::bump = params.vault_bump
    )]
    pub vault: UncheckedAccount<'info>,
    ```
  </Card>

  <Card title="Anchor">
    ```rust theme={null}
    #[account(
        init,
        payer = fee_payer,
        token::mint = mint,
        token::authority = authority,
    )]
    pub vault: Account<'info, TokenAccount>,
    ```
  </Card>
</Columns>

### Light-PDA init

Add `#[light_program]` above `#[program]`, derive `LightAccount` on state structs with a `compression_info` field, and derive `LightAccounts` on the accounts struct.

> [Guide](/pda/light-pda/overview) |
> [Example](https://github.com/Lightprotocol/examples-light-token/tree/main/programs/anchor/basic-macros/counter) |
> [Source](https://docs.rs/light-account)

<Columns cols={2}>
  <Card title="Light Token">
    ```rust theme={null}
    use light_account::{
        CompressionInfo, LightAccount, LightAccounts,
        CreateAccountsProof, derive_light_cpi_signer,
        light_program, CpiSigner, LightDiscriminator,
    };

    #[light_program]
    #[program]
    pub mod my_program {
        // instruction logic unchanged
    }

    #[derive(LightAccount, LightDiscriminator)]
    pub struct MyState {
        pub compression_info: CompressionInfo,
        pub authority: Pubkey,
        pub data: u64,
    }

    #[derive(LightAccounts)]
    pub struct Initialize<'info> {
        #[light_account(init)]
        pub state: UncheckedAccount<'info>,
        #[account(mut)]
        pub pda_rent_sponsor: AccountInfo<'info>,
        // ...
    }
    ```
  </Card>

  <Card title="Anchor">
    ```rust theme={null}
    #[program]
    pub mod my_program {
        // instruction logic unchanged
    }

    #[account]
    pub struct MyState {
        pub authority: Pubkey,
        pub data: u64,
    }

    #[derive(Accounts)]
    pub struct Initialize<'info> {
        #[account(
            init,
            payer = payer,
            space = 8 + MyState::INIT_SPACE,
        )]
        pub state: Account<'info, MyState>,
        #[account(mut)]
        pub payer: Signer<'info>,
        pub system_program: Program<'info, System>,
    }
    ```
  </Card>
</Columns>
