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

# 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 top-ups for other users, set the `feePayer` field to the public key of the account that will pay the top-ups.
Any account that signs the transaction can be the fee payer, which enables rent top-up sponsorship for Solana.
The following example shows how to transfer a token from one user to another and sponsor the top-up for the transaction.

<Info>
  You can set the fee payer to any signing account on any transaction with Light Token.
</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>
</Tabs>
