Derive LightAccount and add a compression_info: Option<CompressionInfo> field
Accounts
Derive LightAccounts and add #[light_account] on init accounts
Program module
Add #[light_program] on top of #[program]
Instructions (swap, deposit, withdraw, …)
No changes
Audit overhead is minimal as your program logic is mostly untouched. The rest is
macro-generated.If you don’t use Anchor, let us know.
References for native solana-program integration coming soon.
You can find a complete rent-free AMM reference implementation here.
Replace spl_token with light_token instructions as you need. The API is a superset of SPL-token so switching is straightforward.Examples include: MintToCpi, TransferCpi, TransferInterfaceCpi,
CreateTokenAccountCpi, and CreateTokenAtaCpi.
To make it easy for clients to integrate with your program, implement the
LightProgramInterface trait in your program’s SDK crate.For a detailed example of how clients use this trait, check out the Router Integration page.
Example: Trait Implementation
Report incorrect code
Copy
Ask AI
pub struct AmmSdk { pool_state_pubkey: Option<Pubkey>, token_0_vault: Option<Pubkey>, token_1_vault: Option<Pubkey>, // ... other fields program_owned_specs: HashMap<Pubkey, PdaSpec<LightAccountVariant>>,}pub enum AmmInstruction { Swap, Deposit, Withdraw,}impl LightProgramInterface for AmmSdk { type Variant = LightAccountVariant; type Instruction = AmmInstruction; type Error = AmmSdkError; fn program_id(&self) -> Pubkey { PROGRAM_ID } fn from_keyed_accounts(accounts: &[AccountInterface]) -> Result<Self, Self::Error> { let mut sdk = Self::new(); for account in accounts { sdk.parse_account(account)?; } Ok(sdk) } fn get_accounts_to_update(&self, ix: &Self::Instruction) -> Vec<AccountToFetch> { match ix { AmmInstruction::Swap => vec![ AccountToFetch::pda(self.pool_state_pubkey.unwrap(), PROGRAM_ID), AccountToFetch::token(self.token_0_vault.unwrap()), AccountToFetch::token(self.token_1_vault.unwrap()), ], // ... } } fn update(&mut self, accounts: &[AccountInterface]) -> Result<(), Self::Error> { for account in accounts { self.parse_account(account)?; } Ok(()) } fn get_specs_for_instruction(&self, ix: &Self::Instruction) -> Vec<AccountSpec<Self::Variant>> { // Return specs for accounts needed by this instruction // Specs include the variant (seeds) needed for loading cold accounts back onchain. self.program_owned_specs .values() .cloned() .map(AccountSpec::Pda) .collect() }}
The SDK pays the rent-exemption cost. Inactive (cold) accounts auto-compress. Your program only ever interacts with hot accounts.
Clients can load cold accounts back when needed via create_load_instructions.Under the hood, clients use AccountInterface - a superset of Solana’s Account that unifies hot and cold state. See Router Integration for details.
When creating an
account for the first time, the SDK provides a proof that the account doesn’t
exist in the cold address space. The SVM already verifies this for the onchain
space. Both address spaces are checked before creation, preventing re-init
attacks, even if the account is currently cold.
Who triggers compression?
Miners automatically compress when
virtual rent is below threshold (e.g., multiple epochs without any writes). In
practice, cold markets should be rare. The common path (hot) has no extra
overhead and does not increase CU or txn size.
Can active pools get compressed?
No. Any write bumps the virtual rent balance. Active accounts do not get compressed.
Do I need to run infrastructure?
No. Helius and Triton run
the Interface RPC endpoints, self-hosting the Photon indexer is optional. Helius
Labs maintains the open-source Photon indexer implementation.
What if the indexer is down?
Hot markets work all the same as long as Solana is up. Cold accounts cannot be loaded into hot state until your indexer or RPC provider recovers.
Note that compression is cryptographically verifiable, so integrity and safety are not dependent on the indexer or any other external service beyond the onchain protocol.
API is in Beta and subject to change.Questions or need hands-on support? Telegram | email | Discord