> ## 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.

# Add Interface PDA to Existing SPL / Token 2022 Mints

> Create an interface PDA for an existing SPL or Token 2022 mint for interoperability with Light Token. Does not require mint authority. The interface PDA holds SPL or Token 2022 tokens when wrapped to Light Token.

<Accordion title="Agent skill">
  Install or view [dedicated agent skills](/ai-tools/overview#agent-skills).

  ```
  npx skills add Lightprotocol/skills
  ```

  Install orchestrator agent skill or view [skill.md](https://www.zkcompression.com/skill.md):

  ```bash theme={null}
  npx skills add https://zkcompression.com
  ```
</Accordion>

<Info>
  Find the [source code](https://github.com/Lightprotocol/light-protocol/blob/main/js/compressed-token/src/actions/create-token-pool.ts) and examples: [Action](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/actions/create-spl-interface.ts) · [Instruction](https://github.com/Lightprotocol/examples-light-token/blob/main/typescript-client/instructions/create-spl-interface.ts).
</Info>

<Tabs>
  <Tab title="Guide">
    <Steps>
      <Step>
        ### Prerequisites

        <Accordion title="Dependencies">
          ```toml Cargo.toml theme={null}
          [dependencies]
          light-token = "0.23.0"
          light-client = { version = "0.23.0", features = ["v2"] }
          solana-sdk = "2"
          borsh = "0.10.4"
          tokio = { version = "1", features = ["full"] }
          ```
        </Accordion>

        <Accordion title="Developer Environment">
          <Tabs>
            <Tab title="In-Memory (LightProgramTest)">
              Test with Lite-SVM (...)

              ```bash theme={null}
              # Initialize project
              cargo init my-light-project
              cd my-light-project

              # Run tests
              cargo test
              ```

              ```rust theme={null}
              use light_program_test::{LightProgramTest, ProgramTestConfig};
              use solana_sdk::signer::Signer;

              #[tokio::test]
              async fn test_example() {
                  // In-memory test environment 
                  let mut rpc = LightProgramTest::new(ProgramTestConfig::default())
                      .await
                      .unwrap();

                  let payer = rpc.get_payer().insecure_clone();
                  println!("Payer: {}", payer.pubkey());
              }
              ```
            </Tab>

            <Tab title="Localnet (LightClient)">
              Connects to a local test validator.

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

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

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

              ```bash theme={null}
              # Initialize project
              cargo init my-light-project
              cd my-light-project

              # Start local test validator (in separate terminal)
              light test-validator
              ```

              ```rust theme={null}
              use light_client::rpc::{LightClient, LightClientConfig, Rpc};

              #[tokio::main]
              async fn main() -> Result<(), Box<dyn std::error::Error>> {
                  // Connects to http://localhost:8899
                  let rpc = LightClient::new(LightClientConfig::local()).await?;

                  let slot = rpc.get_slot().await?;
                  println!("Current slot: {}", slot);

                  Ok(())
              }
              ```
            </Tab>

            <Tab title="Devnet (LightClient)">
              Replace `<your-api-key>` with your actual API key. [Get your API key here](https://www.helius.dev/zk-compression).

              ```rust theme={null}
              use light_client::rpc::{LightClient, LightClientConfig, Rpc};

              #[tokio::main]
              async fn main() -> Result<(), Box<dyn std::error::Error>> {
                  let rpc_url = "https://devnet.helius-rpc.com?api-key=<your_api_key>";
                  let rpc = LightClient::new(
                      LightClientConfig::new(rpc_url.to_string(), None, None)
                  ).await?;

                  println!("Connected to Devnet");
                  Ok(())
              }
              ```
            </Tab>
          </Tabs>
        </Accordion>
      </Step>

      <Step>
        <Tabs>
          <Tab title="Action">
            ```typescript theme={null}
            import "dotenv/config";
            import { Keypair, PublicKey } from "@solana/web3.js";
            import { createRpc } from "@lightprotocol/stateless.js";
            import { createSplInterface } 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!}`;
            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 existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS");

                const tx = await createSplInterface(rpc, payer, existingMint);

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

          <Tab title="Instruction">
            ```typescript theme={null}
            import "dotenv/config";
            import {
                Keypair,
                PublicKey,
                Transaction,
                sendAndConfirmTransaction,
            } from "@solana/web3.js";
            import { createRpc } from "@lightprotocol/stateless.js";
            import { LightTokenProgram } from "@lightprotocol/compressed-token";
            import { TOKEN_PROGRAM_ID } 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 () {
                const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS");

                const ix = await LightTokenProgram.createSplInterface({
                    feePayer: payer.publicKey,
                    mint: existingMint,
                    tokenProgramId: TOKEN_PROGRAM_ID,
                });

                const tx = new Transaction().add(ix);
                const signature = await sendAndConfirmTransaction(rpc, tx, [payer]);

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

          <Tab title="SDK 2.0 (token-interface)">
            ```typescript theme={null}
            import { Keypair, PublicKey, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
            import { createRpc } from "@lightprotocol/stateless.js";
            import { createSplInterfaceInstruction } from "@lightprotocol/token-interface";
            import { TOKEN_PROGRAM_ID } from "@solana/spl-token";

            const rpc = createRpc();
            const payer = Keypair.fromSecretKey(/* ... */);
            const existingMint = new PublicKey("YOUR_EXISTING_MINT_ADDRESS");

            const ix = createSplInterfaceInstruction({
              feePayer: payer.publicKey,
              mint: existingMint,
              index: 0,
              tokenProgramId: TOKEN_PROGRAM_ID,
            });

            const tx = new Transaction().add(ix);
            const signature = await sendAndConfirmTransaction(rpc, tx, [payer]);
            console.log("Mint:", existingMint.toBase58());
            console.log("Tx:", signature);
            ```
          </Tab>
        </Tabs>
      </Step>
    </Steps>
  </Tab>

  <Tab title="AI Prompt">
    <Prompt description="Add interface PDA to existing SPL / Token 2022 mint" actions={["copy", "cursor"]}>
      {`---
            description: Add interface PDA to existing SPL / Token 2022 mint
            allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__zkcompression
            ---

            ## Add interface PDA to existing SPL / Token 2022 mint

            Context:
            - Guide: https://zkcompression.com/light-token/cookbook/add-interface-pda
            - Skills and resources index: https://zkcompression.com/skill.md
            - SPL to Light reference: https://zkcompression.com/api-reference/solana-to-light-comparison
            - Packages: @lightprotocol/compressed-token, @lightprotocol/stateless.js

            SPL equivalent: (none) → Light Token: createSplInterface()

            ### 1. Index project
            - Grep \`@solana/spl-token|Connection|Keypair|createSplInterface|LightTokenProgram\` across src/
            - Glob \`**/*.ts\` for project structure
            - Identify: RPC setup, existing mint references, entry point for interface PDA creation
            - Task subagent (Grep/Read/WebFetch) if project has multiple packages to scan in parallel

            ### 2. Read references
            - WebFetch the guide above — follow the TypeScript Client tab
            - WebFetch skill.md — check for a dedicated skill and resources matching this task
            - TaskCreate one todo per phase below to track progress

            ### 3. Clarify intention
            - AskUserQuestion: what is the goal? (register existing SPL mint, register Token 2022 mint, or both)
            - AskUserQuestion: does the project already have Light Token operations, or is this the first integration?
            - Summarize findings and wait for user confirmation before implementing

            ### 4. Create plan
            - Based on steps 1–3, draft an implementation plan: which files to modify, what code to add, dependency changes
            - Verify existing connection/signer setup is compatible with the cookbook prerequisites
            - If anything is unclear or ambiguous, loop back to step 3 (AskUserQuestion)
            - Present the plan to the user for approval before proceeding

            ### 5. Implement
            - Add deps if missing: Bash \`npm install @lightprotocol/compressed-token @lightprotocol/stateless.js\`
            - Follow the cookbook guide and the approved plan
            - Write/Edit to create or modify files
            - TaskUpdate to mark each step done

            ### 6. Verify
            - Bash \`tsc --noEmit\`
            - Bash run existing test suite if present
            - TaskUpdate to mark complete

            ### Tools
            - mcp__zkcompression__SearchLightProtocol("<query>") for API details
            - mcp__deepwiki__ask_question("Lightprotocol/light-protocol", "<q>") for architecture
            - Task subagent with Grep/Read/WebFetch for parallel lookups
            - TaskList to check remaining work`}
    </Prompt>

    ```text theme={null}
    ---
    description: Add interface PDA to existing SPL / Token 2022 mint
    allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__zkcompression
    ---

    ## Add interface PDA to existing SPL / Token 2022 mint

    Context:
    - Guide: https://zkcompression.com/light-token/cookbook/add-interface-pda
    - Skills and resources index: https://zkcompression.com/skill.md
    - SPL to Light reference: https://zkcompression.com/api-reference/solana-to-light-comparison
    - Packages: @lightprotocol/compressed-token, @lightprotocol/stateless.js

    SPL equivalent: (none) → Light Token: createSplInterface()

    ### 1. Index project
    - Grep `@solana/spl-token|Connection|Keypair|createSplInterface|LightTokenProgram` across src/
    - Glob `**/*.ts` for project structure
    - Identify: RPC setup, existing mint references, entry point for interface PDA creation
    - Task subagent (Grep/Read/WebFetch) if project has multiple packages to scan in parallel

    ### 2. Read references
    - WebFetch the guide above — follow the TypeScript Client tab
    - WebFetch skill.md — check for a dedicated skill and resources matching this task
    - TaskCreate one todo per phase below to track progress

    ### 3. Clarify intention
    - AskUserQuestion: what is the goal? (register existing SPL mint, register Token 2022 mint, or both)
    - AskUserQuestion: does the project already have Light Token operations, or is this the first integration?
    - Summarize findings and wait for user confirmation before implementing

    ### 4. Create plan
    - Based on steps 1–3, draft an implementation plan: which files to modify, what code to add, dependency changes
    - Verify existing connection/signer setup is compatible with the cookbook prerequisites
    - If anything is unclear or ambiguous, loop back to step 3 (AskUserQuestion)
    - Present the plan to the user for approval before proceeding

    ### 5. Implement
    - Add deps if missing: Bash `npm install @lightprotocol/compressed-token @lightprotocol/stateless.js`
    - Follow the cookbook guide and the approved plan
    - Write/Edit to create or modify files
    - TaskUpdate to mark each step done

    ### 6. Verify
    - Bash `tsc --noEmit`
    - Bash run existing test suite if present
    - TaskUpdate to mark complete

    ### Tools
    - mcp__zkcompression__SearchLightProtocol("<query>") for API details
    - mcp__deepwiki__ask_question("Lightprotocol/light-protocol", "<q>") for architecture
    - Task subagent with Grep/Read/WebFetch for parallel lookups
    - TaskList to check remaining work
    ```
  </Tab>
</Tabs>

## Related Guides

<CardGroup cols={2}>
  <Card title="Transfer interface" icon="arrow-right-left" href="/light-token/cookbook/transfer-interface" horizontal />

  <Card title="Wrap and unwrap" icon="rotate" href="/light-token/cookbook/wrap-unwrap" horizontal />
</CardGroup>

***

## Didn't find what you were looking for?

<Callout type="info">
  Reach out! [Telegram](https://t.me/swen_light) | [email](mailto:support@lightprotocol.com) | [Discord](https://discord.com/invite/7cJ8BhAXhu)
</Callout>
