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

# Wrap & Unwrap SPL/Token-22 <> Light Token

> Move tokens between SPL/Token-22 token and light-token accounts. Use to interact with applications that only support SPL/Token-22.

***

* **Wrap**: Move tokens from SPL/T22 account → light-token ATA (hot balance)
* **Unwrap**: Move tokens from light-token ATA (hot balance) → SPL/T22 account

<Info>
  Find the source code:
  [wrap.ts](https://github.com/Lightprotocol/light-protocol/blob/0c4e2417b2df2d564721b89e18d1aad3665120e7/js/compressed-token/src/v3/actions/wrap.ts)
  |
  [unwrap.ts](https://github.com/Lightprotocol/light-protocol/blob/0c4e2417b2df2d564721b89e18d1aad3665120e7/js/compressed-token/src/v3/actions/unwrap.ts)
</Info>

## Get Started

<Tabs>
  <Tab title="Wrap">
    <Steps>
      <Step>
        ### Wrap SPL Tokens to Light Token ATA

        <Accordion title="Installation">
          <Tabs>
            <Tab title="npm">
              Install packages in your working directory:

              ```bash theme={null}
              npm install @lightprotocol/stateless.js@beta \
                          @lightprotocol/compressed-token@beta
              ```

              Install the CLI globally:

              ```bash theme={null}
              npm install -g @lightprotocol/zk-compression-cli@beta
              ```
            </Tab>

            <Tab title="yarn">
              Install packages in your working directory:

              ```bash theme={null}
              yarn add @lightprotocol/stateless.js@beta \
                       @lightprotocol/compressed-token@beta
              ```

              Install the CLI globally:

              ```bash theme={null}
              yarn global add @lightprotocol/zk-compression-cli@beta
              ```
            </Tab>

            <Tab title="pnpm">
              Install packages in your working directory:

              ```bash theme={null}
              pnpm add @lightprotocol/stateless.js@beta \
                       @lightprotocol/compressed-token@beta
              ```

              Install the CLI globally:

              ```bash theme={null}
              pnpm add -g @lightprotocol/zk-compression-cli@beta
              ```
            </Tab>
          </Tabs>
        </Accordion>

        <Tabs>
          <Tab title="Localnet">
            ```bash theme={null}
            # start local test-validator in a separate terminal
            light test-validator
            ```

            <Note>
              In the code examples, use `createRpc()` without arguments for localnet.
            </Note>
          </Tab>

          <Tab title="Devnet">
            Get an API key from [Helius](https://helius.dev) and add to `.env`:

            ```bash title=".env" theme={null}
            API_KEY=<your-helius-api-key>
            ```

            <Note>
              In the code examples, use `createRpc(RPC_URL)` with the devnet URL.
            </Note>
          </Tab>
        </Tabs>

        <Tabs>
          <Tab title="Action">
            ```typescript theme={null}
            import "dotenv/config";
            import { Keypair } from "@solana/web3.js";
            import { createRpc, bn } from "@lightprotocol/stateless.js";
            import {
                createMint,
                mintTo,
                decompress,
                wrap,
                getAssociatedTokenAddressInterface,
                createAtaInterfaceIdempotent,
            } from "@lightprotocol/compressed-token";
            import { createAssociatedTokenAccount } from "@solana/spl-token";
            import { homedir } from "os";
            import { readFileSync } from "fs";

            // devnet:
            const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
            const rpc = createRpc(RPC_URL);
            // localnet:
            // const rpc = createRpc();

            const payer = Keypair.fromSecretKey(
                new Uint8Array(
                    JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
                )
            );

            (async function () {
                // Setup: Get SPL tokens (needed to wrap)
                const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
                const splAta = await createAssociatedTokenAccount(
                    rpc,
                    payer,
                    mint,
                    payer.publicKey
                );
                await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000));
                await decompress(rpc, payer, mint, bn(1000), payer, splAta);

                // Wrap SPL tokens to rent-free token ATA
                const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey);
                await createAtaInterfaceIdempotent(rpc, payer, mint, payer.publicKey);

                const tx = await wrap(rpc, payer, splAta, lightTokenAta, payer, mint, bn(500));

                console.log("Tx:", tx);
            })();
            ```
          </Tab>

          <Tab title="Instruction">
            ```typescript theme={null}
            import "dotenv/config";
            import { Keypair, ComputeBudgetProgram, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
            import { createRpc, bn } from "@lightprotocol/stateless.js";
            import {
                createMint,
                mintTo,
                decompress,
                createWrapInstruction,
                getAssociatedTokenAddressInterface,
                createAtaInterfaceIdempotent,
                getSplInterfaceInfos,
            } from "@lightprotocol/compressed-token";
            import { createAssociatedTokenAccount } from "@solana/spl-token";
            import { homedir } from "os";
            import { readFileSync } from "fs";

            // devnet:
            const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
            const rpc = createRpc(RPC_URL);
            // localnet:
            // const rpc = createRpc();

            const payer = Keypair.fromSecretKey(
                new Uint8Array(
                    JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
                )
            );

            (async function () {
                // Setup: Get SPL tokens (needed to wrap)
                const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
                const splAta = await createAssociatedTokenAccount(
                    rpc,
                    payer,
                    mint,
                    payer.publicKey
                );
                await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000));
                await decompress(rpc, payer, mint, bn(1000), payer, splAta);

                // Create wrap instruction
                const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey);
                await createAtaInterfaceIdempotent(rpc, payer, mint, payer.publicKey);

                const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint);
                const splInterfaceInfo = splInterfaceInfos.find(
                    (info) => info.isInitialized
                );

                if (!splInterfaceInfo) throw new Error("No SPL interface found");

                const ix = createWrapInstruction(
                    splAta,
                    lightTokenAta,
                    payer.publicKey,
                    mint,
                    bn(500),
                    splInterfaceInfo,
                    9, // decimals - must match the mint decimals
                    payer.publicKey
                );

                const tx = new Transaction().add(
                    ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }),
                    ix
                );
                const signature = await sendAndConfirmTransaction(rpc, tx, [payer]);

                console.log("Tx:", signature);
            })();
            ```
          </Tab>
        </Tabs>
      </Step>
    </Steps>
  </Tab>

  <Tab title="Unwrap">
    <Steps>
      <Step>
        ### Unwrap Light Tokens to SPL Account

        <Tabs>
          <Tab title="Action">
            ```typescript theme={null}
            import "dotenv/config";
            import { Keypair } from "@solana/web3.js";
            import { createRpc, bn } from "@lightprotocol/stateless.js";
            import { createMint, mintTo } from "@lightprotocol/compressed-token";
            import { unwrap } from "@lightprotocol/compressed-token/unified";
            import { createAssociatedTokenAccount } from "@solana/spl-token";
            import { homedir } from "os";
            import { readFileSync } from "fs";

            // devnet:
            const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
            const rpc = createRpc(RPC_URL);
            // localnet:
            // const rpc = createRpc();

            const payer = Keypair.fromSecretKey(
                new Uint8Array(
                    JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
                )
            );

            (async function () {
                // Setup: Get compressed tokens (cold storage)
                const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
                await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000));

                // Unwrap rent-free tokens to SPL ATA
                const splAta = await createAssociatedTokenAccount(
                    rpc,
                    payer,
                    mint,
                    payer.publicKey
                );
                const tx = await unwrap(rpc, payer, splAta, payer, mint, bn(500));

                console.log("Tx:", tx);
            })();
            ```
          </Tab>

          <Tab title="Instruction">
            ```typescript theme={null}
            import "dotenv/config";
            import { Keypair, ComputeBudgetProgram, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
            import { createRpc, bn } from "@lightprotocol/stateless.js";
            import {
                createMint,
                mintTo,
                loadAta,
                getAssociatedTokenAddressInterface,
                getSplInterfaceInfos,
            } from "@lightprotocol/compressed-token";
            import { createUnwrapInstruction } from "@lightprotocol/compressed-token/unified";
            import { createAssociatedTokenAccount } from "@solana/spl-token";
            import { homedir } from "os";
            import { readFileSync } from "fs";

            // devnet:
            const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
            const rpc = createRpc(RPC_URL);
            // localnet:
            // const rpc = createRpc();

            const payer = Keypair.fromSecretKey(
                new Uint8Array(
                    JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
                )
            );

            (async function () {
                // Setup: Get compressed tokens (cold storage)
                const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
                await mintTo(rpc, payer, mint, payer.publicKey, payer, bn(1000));

                // Load compressed tokens to hot balance, then create unwrap instruction
                const lightTokenAta = getAssociatedTokenAddressInterface(mint, payer.publicKey);
                await loadAta(rpc, lightTokenAta, payer, mint, payer);

                const splAta = await createAssociatedTokenAccount(
                    rpc,
                    payer,
                    mint,
                    payer.publicKey
                );

                const splInterfaceInfos = await getSplInterfaceInfos(rpc, mint);
                const splInterfaceInfo = splInterfaceInfos.find(
                    (info) => info.isInitialized
                );

                if (!splInterfaceInfo) throw new Error("No SPL interface found");

                const ix = createUnwrapInstruction(
                    lightTokenAta,
                    splAta,
                    payer.publicKey,
                    mint,
                    bn(500),
                    splInterfaceInfo,
                    9, // decimals - must match the mint decimals
                    payer.publicKey
                );

                const tx = new Transaction().add(
                    ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }),
                    ix
                );
                const signature = await sendAndConfirmTransaction(rpc, tx, [payer]);

                console.log("Tx:", signature);
            })();
            ```
          </Tab>
        </Tabs>
      </Step>
    </Steps>
  </Tab>
</Tabs>
