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

# Sponsor Rent Top-Ups for Users

> The Light SDK sponsors rent-exemption for Solana accounts and keeps accounts active through periodic top-ups paid by the fee payer. Sponsor top-ups by setting your application as the fee payer to abstract away holding SOL from your users or provide a rent-free experience similar to transaction fee sponsorship.

***

<Accordion title="Prerequisite: How Rent Sponsorship works">
  Rent sponsorship is a built-in feature of the Light SDK’s that sponsors rent-exemption for all account types to reduce creation cost.
  This is dealt with under the hood in a way that doesn’t disrupt the UX of what your users are used to with SPL-token.

  **Rent-exemption: sponsored by a rent sponsor PDA.**

  Every Solana account requires a rent-exempt balance in SOL upon creation.
  A rent sponsor PDA by Light Protocol pays the rent-exemption cost for the account so account creators never lock up SOL for rent.

  **Top-ups: paid by the fee payer.**

  The `feePayer` on the transaction bumps a small virtual rent balance (766 lamports by default)
  on each write to keep the account active (hot balance).
  If you're building a wallet or dApp, set your application as the fee payer and your users never pay rent or top-ups.

  <Info>
    "Cold" accounts virtual rent balance below threshold (eg 24h without write bump) get auto-compressed.
    The cold account's state is cryptographically preserved on the Solana ledger.
    Users can load a cold account into hot state in-flight when using the account again.
  </Info>

  ```text theme={null}
      Rent sponsor PDA              Fee payer bumps
      pays rent-exemption           virtual rent on write
           │                              │
           ▼                              │
      ┌─────────┐                    ┌────┴────┐
      │ CREATE  │ ──────────────────►│   HOT   │◄───┐
      └─────────┘                    └────┬────┘    │
                                          │         │
                                    no writes for   │ client loads
                                    threshold       │ cold → hot
                                    (e.g. 24h)      │
                                          │         │
                                          ▼         │
                                     ┌─────────┐    │
                                     │  COLD   │────┘
                                     └─────────┘
  ```
</Accordion>

## How to use Sponsored Rent Top-Ups for Accounts and Transfers

To sponsor rent top-ups for your users, set the `payer` parameter to the sponsor’s public key when calling `createTransferInterfaceInstructions` (TypeScript) or building a `TransferInterface` instruction (Rust). The sponsor pays SOL for any rent top-ups while the user only signs to authorize the transfer.

<Info>
  You can set the payer to any signing account on any Light Token transaction.
</Info>

<Tabs>
  <Tab title="TypeScript Client">
    ```typescript theme={null}
    import { Keypair, Transaction, sendAndConfirmTransaction } from "@solana/web3.js";
    import { createRpc } from "@lightprotocol/stateless.js";
    import {
        createAtaInterface,
        createLightTokenTransferInstruction,
        getAssociatedTokenAddressInterface,
    } from "@lightprotocol/compressed-token";
    import { PublicKey } from "@solana/web3.js";

    const rpc = createRpc();

    // Top-Up Sponsor: your application server, pays SOL for rent top-ups
    const sponsor: Keypair = /* your server keypair */;

    // User: only signs to authorize the transfer
    const sender: Keypair = /* user's keypair */;
    const recipient = new PublicKey(/* recipient address */);
    const mint = new PublicKey(/* e.g. USDC mint */);

    (async function () {
        const senderAta = getAssociatedTokenAddressInterface(mint, sender.publicKey);
        const recipientAta = getAssociatedTokenAddressInterface(mint, recipient);

        // Create recipient associated token account if it doesn't exist
        await createAtaInterface(rpc, sponsor, mint, recipient);

        const ix = createLightTokenTransferInstruction(
            senderAta,
            recipientAta,
            sender.publicKey,
            500_000,
            sponsor.publicKey, 
        );

        const tx = new Transaction().add(ix);
        const sig = await sendAndConfirmTransaction(rpc, tx, [sponsor, sender]);

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

  <Tab title="Rust Client">
    ```rust theme={null}
    use light_client::rpc::Rpc;
    use light_program_test::{LightProgramTest, ProgramTestConfig};
    use light_token::instruction::{
        get_associated_token_address, CreateAssociatedTokenAccount,
        TransferInterface, LIGHT_TOKEN_PROGRAM_ID,
    };
    use solana_sdk::{pubkey::Pubkey, signature::Keypair, signer::Signer};

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let mut rpc = LightProgramTest::new(ProgramTestConfig::new_v2(true, None)).await?;

        // Top-Up Sponsor: your application server, pays SOL for rent top-ups
        let sponsor = rpc.get_payer().insecure_clone();

        // User: only signs to authorize the transfer
        let sender: Keypair = /* user's keypair */;
        let recipient: Pubkey = /* recipient address */;
        let mint: Pubkey = /* e.g. USDC mint */;
        let decimals = 6u8;

        let sender_ata = get_associated_token_address(&sender.pubkey(), &mint);
        let recipient_ata = get_associated_token_address(&recipient, &mint);

        // Create recipient associated token account if it doesn't exist
        let create_ata_ix =
            CreateAssociatedTokenAccount::new(sponsor.pubkey(), recipient, mint).instruction()?;
        rpc.create_and_send_transaction(&[create_ata_ix], &sponsor.pubkey(), &[&sponsor])
            .await?;

        let transfer_ix = TransferInterface {
            source: sender_ata,
            destination: recipient_ata,
            amount: 500_000,
            decimals,
            authority: sender.pubkey(),
            payer: sponsor.pubkey(),
            spl_interface: None,
            source_owner: LIGHT_TOKEN_PROGRAM_ID,
            destination_owner: LIGHT_TOKEN_PROGRAM_ID,
        }
        .instruction()?;

        let sig = rpc
            .create_and_send_transaction(&[transfer_ix], &sponsor.pubkey(), &[&sponsor, &sender])
            .await?;

        println!("Tx: {sig}");

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

  <Tab title="AI Prompt">
    <Prompt description="Sponsor rent top-ups for Light Token users" actions={["copy", "cursor"]}>
      {`---
            description: Sponsor rent top-ups for Light Token users
            allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__zkcompression
            ---

            ## Sponsor rent top-ups for Light Token users

            Context:
            - Guide: https://zkcompression.com/light-token/toolkits/sponsor-top-ups
            - Skills and resources index: https://zkcompression.com/skill.md
            - SPL to Light reference: https://zkcompression.com/api-reference/solana-to-light-comparison
            - Dedicated skill: https://github.com/Lightprotocol/skills/tree/main/skills/payments-and-wallets
            - Packages: @lightprotocol/compressed-token, @lightprotocol/stateless.js

            How rent sponsorship works:
            - A rent sponsor PDA pays the rent-exemption cost on account creation so creators never lock up SOL
            - The fee payer bumps a small virtual rent balance (766 lamports) on each write to keep the account active (hot)
            - Set your application as the fee payer so users never pay rent or top-ups

            Key APIs:
            | Language   | Function                                        | Payer parameter                           |
            | TypeScript | createLightTokenTransferInstruction()            | 5th argument: \`sponsor.publicKey\`         |
            | TypeScript | createAtaInterface()                             | 2nd argument: \`sponsor\` (Keypair)         |
            | Rust       | TransferInterface { ..., payer: sponsor.pubkey() } | \`payer\` field                           |
            | Rust       | CreateAssociatedTokenAccount::new(sponsor, ...)  | 1st argument: sponsor pubkey              |

            ### 1. Index project
            - Grep \`feePayer|payer|createTransferInstruction|createLightTokenTransferInstruction|@lightprotocol|@solana/spl-token|Connection\` across src/
            - Glob \`**/*.ts\` and \`**/*.tsx\` for project structure
            - Identify: existing token operations, RPC config, fee payer setup, signing flow
            - Check package.json for existing @lightprotocol/* dependencies
            - Task subagent (Grep/Read/WebFetch) if project has multiple packages to scan in parallel

            ### 2. Read references
            - WebFetch the guide above — review TypeScript and Rust code examples
            - 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? (add sponsored top-ups to existing light-token code, new integration from scratch, migrate from user-pays to sponsor-pays)
            - AskUserQuestion: TypeScript or Rust client?
            - AskUserQuestion: which operations need sponsoring? (transfers only, ATA creation + transfers, all write operations)
            - 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
            - Key pattern: set the \`payer\` parameter to the sponsor's public key on transfer and ATA creation instructions
            - The sponsor Keypair must sign the transaction alongside the user
            - 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\`
            - Set up RPC: \`createRpc(RPC_ENDPOINT)\` with a ZK Compression endpoint (Helius, Triton)
            - Import from \`@lightprotocol/compressed-token\` for the token APIs
            - Set sponsor as payer: \`createLightTokenTransferInstruction(senderAta, recipientAta, sender.publicKey, amount, sponsor.publicKey)\`
            - Sign with both sponsor and sender: \`sendAndConfirmTransaction(rpc, tx, [sponsor, sender])\`
            - Follow the 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: Sponsor rent top-ups for Light Token users
    allowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__zkcompression
    ---

    ## Sponsor rent top-ups for Light Token users

    Context:
    - Guide: https://zkcompression.com/light-token/toolkits/sponsor-top-ups
    - Skills and resources index: https://zkcompression.com/skill.md
    - SPL to Light reference: https://zkcompression.com/api-reference/solana-to-light-comparison
    - Dedicated skill: https://github.com/Lightprotocol/skills/tree/main/skills/payments-and-wallets
    - Packages: @lightprotocol/compressed-token, @lightprotocol/stateless.js

    How rent sponsorship works:
    - A rent sponsor PDA pays the rent-exemption cost on account creation so creators never lock up SOL
    - The fee payer bumps a small virtual rent balance (766 lamports) on each write to keep the account active (hot)
    - Set your application as the fee payer so users never pay rent or top-ups

    Key APIs:
    | Language   | Function                                        | Payer parameter                           |
    | TypeScript | createLightTokenTransferInstruction()            | 5th argument: `sponsor.publicKey`         |
    | TypeScript | createAtaInterface()                             | 2nd argument: `sponsor` (Keypair)         |
    | Rust       | TransferInterface { ..., payer: sponsor.pubkey() } | `payer` field                           |
    | Rust       | CreateAssociatedTokenAccount::new(sponsor, ...)  | 1st argument: sponsor pubkey              |

    ### 1. Index project
    - Grep `feePayer|payer|createTransferInstruction|createLightTokenTransferInstruction|@lightprotocol|@solana/spl-token|Connection` across src/
    - Glob `**/*.ts` and `**/*.tsx` for project structure
    - Identify: existing token operations, RPC config, fee payer setup, signing flow
    - Check package.json for existing @lightprotocol/* dependencies
    - Task subagent (Grep/Read/WebFetch) if project has multiple packages to scan in parallel

    ### 2. Read references
    - WebFetch the guide above — review TypeScript and Rust code examples
    - 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? (add sponsored top-ups to existing light-token code, new integration from scratch, migrate from user-pays to sponsor-pays)
    - AskUserQuestion: TypeScript or Rust client?
    - AskUserQuestion: which operations need sponsoring? (transfers only, ATA creation + transfers, all write operations)
    - 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
    - Key pattern: set the `payer` parameter to the sponsor's public key on transfer and ATA creation instructions
    - The sponsor Keypair must sign the transaction alongside the user
    - 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`
    - Set up RPC: `createRpc(RPC_ENDPOINT)` with a ZK Compression endpoint (Helius, Triton)
    - Import from `@lightprotocol/compressed-token` for the token APIs
    - Set sponsor as payer: `createLightTokenTransferInstruction(senderAta, recipientAta, sender.publicKey, amount, sponsor.publicKey)`
    - Sign with both sponsor and sender: `sendAndConfirmTransaction(rpc, tx, [sponsor, sender])`
    - Follow the 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>

***

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