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

# Create a Mint Account with Interface PDA for Compression

> Create an SPL token mint with an interface PDA for compression. The interface PDA locks tokens while compressed and releases them when decompressed.

The mint account itself requires rent (like regular SPL mints), but individual compressed token accounts are rent-free.
Create an interface PDA for an existing SPL mint with [`createTokenPool()`](/compressed-tokens/guides/add-token-pools-to-mint-accounts) or use `createMint()` to create a new one from scratch.

<CodeGroup>
  ```typescript createMint() theme={null}
  // Create SPL mint with interface PDA for compression
  const { mint, transactionSignature } = await createMint(
      rpc,
      payer,
      mintAuthority.publicKey,
      decimals,
  );
  ```
</CodeGroup>

<Tip>
  **Best Practice:** Each mint supports a maximum of 4 interface PDAs total. During compression/decompression, interface PDAs get write-locked. Use `addTokenPools()` to create additional PDAs that increase per-block write-lock capacity.
</Tip>

## Get Started

<Steps>
  <Step>
    ### Create a Mint Account with Interface PDA for Compression

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

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

          Install the CLI globally:

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

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

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

          Install the CLI globally:

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

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

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

          Install the CLI globally:

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

        <Tab title="SDK 2.0 (token-interface)">
          Install packages in your working directory:

          ```bash theme={null}
          # npm
          npm install @lightprotocol/stateless.js@^0.23.0 \
                      @lightprotocol/token-interface@^0.1.2

          # yarn
          yarn add @lightprotocol/stateless.js@^0.23.0 \
                   @lightprotocol/token-interface@^0.1.2

          # pnpm
          pnpm add @lightprotocol/stateless.js@^0.23.0 \
                   @lightprotocol/token-interface@^0.1.2
          ```

          Install the CLI globally:

          ```bash theme={null}
          npm install -g @lightprotocol/zk-compression-cli
          ```
        </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 } from "@lightprotocol/stateless.js";
        import { createMint } from "@lightprotocol/compressed-token";
        import { homedir } from "os";
        import { readFileSync } from "fs";

        // devnet:
        const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
        // localnet:
        // const RPC_URL = undefined;
        const payer = Keypair.fromSecretKey(
            new Uint8Array(
                JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
            )
        );

        (async function () {
            // devnet:
            const rpc = createRpc(RPC_URL);
            // localnet:
            // const rpc = createRpc();

            const { mint, transactionSignature } = await createMint(
                rpc,
                payer,
                payer.publicKey,
                9
            );

            console.log("Mint:", mint.toBase58());
            console.log("Tx:", transactionSignature);
        })();
        ```
      </Tab>

      <Tab title="Instruction">
        ```typescript theme={null}
        import "dotenv/config";
        import {
            Keypair,
            ComputeBudgetProgram,
            PublicKey,
            Transaction,
            sendAndConfirmTransaction,
        } from "@solana/web3.js";
        import {
            createRpc,
            getBatchAddressTreeInfo,
            selectStateTreeInfo,
            LIGHT_TOKEN_PROGRAM_ID,
        } from "@lightprotocol/stateless.js";
        import { createMintInstruction } from "@lightprotocol/compressed-token";
        import { homedir } from "os";
        import { readFileSync } from "fs";

        const COMPRESSED_MINT_SEED = Buffer.from("compressed_mint");

        function findMintAddress(mintSigner: PublicKey): [PublicKey, number] {
            return PublicKey.findProgramAddressSync(
                [COMPRESSED_MINT_SEED, mintSigner.toBuffer()],
                LIGHT_TOKEN_PROGRAM_ID
            );
        }

        // 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 () {
            const mintSigner = Keypair.generate();
            const addressTreeInfo = getBatchAddressTreeInfo();
            const stateTreeInfo = selectStateTreeInfo(await rpc.getStateTreeInfos());
            const [mintPda] = findMintAddress(mintSigner.publicKey);

            const validityProof = await rpc.getValidityProofV2(
                [],
                [{ address: mintPda.toBytes(), treeInfo: addressTreeInfo }]
            );

            const ix = createMintInstruction(
                mintSigner.publicKey,
                9,
                payer.publicKey,
                null,
                payer.publicKey,
                validityProof,
                addressTreeInfo,
                stateTreeInfo
            );

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

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

# Advanced Configuration

<AccordionGroup>
  <Accordion title="Customize Mint Authority">
    Customize who can mint new compressed tokens.

    ```typescript theme={null}
    const mintAuthority = Keypair.generate();

    const { mint, transactionSignature } = await createMint(
        rpc,
        payer,
        mintAuthority.publicKey,
        9,
    );
    ```
  </Accordion>

  <Accordion title="Add Freeze Authority">
    Customize who can freeze/thaw compressed token accounts.

    ```typescript theme={null}
    const freezeAuthority = Keypair.generate();

    const { mint, transactionSignature } = await createMint(
        rpc,
        payer,
        payer.publicKey, // mint authority
        9, // decimals
        Keypair.generate(), // mint keypair
        undefined, // confirm options
        undefined, // token program ID
        freezeAuthority.publicKey, // freeze authority
    );
    ```
  </Accordion>
</AccordionGroup>

# Next Steps

<Card title="How to Add Interface PDAs for Existing Mints" icon="chevron-right" color="#0066ff" href="/compressed-tokens/guides/add-token-pools-to-mint-accounts" horizontal />
