Use this file to discover all available pages before exploring further.
Your existing quoting, routing, and swap logic stays the same.
The only addition: when a market has cold accounts, detect them, and prepend load instructions before the swap.
Add a cache for cold accounts. This can be independent from your regular account cache.
cold_cache: HashMap<[u8; 32], AccountInterface>, // Accounts that are currently cold (used for loading)
If you stream, subscribe to accounts and transactions with the Light Token Program.
Subscription
Detects
Account sub (owner: cToken...)
Hot state + cold-to-hot
Transaction sub (account_include: cToken...)
Hot-to-cold
Hot-to-cold — in your transaction handler, listen to accounts whose balance dropped to zero. Async-fetch the AccountInterface
(which includes the ColdContext needed for load instructions):
Some(UpdateOneof::Transaction(tx_update)) => { if let Some(ref tx_info) = tx_update.transaction { for pubkey in find_closed_accounts(tx_info) { if cache.remove(&pubkey).is_some() { let rpc = rpc.clone(); let cold_cache = cold_cache.clone(); tokio::spawn(async move { if let Ok(Some(iface)) = rpc.get_account_interface(&pubkey, None).await { cold_cache.insert(pubkey, iface); } }); } } }}
find_closed_accounts checks pre_balances[i] > 0 && post_balances[i] == 0 across all transaction
keys (including ALT-loaded addresses). See full implementation.Cold-to-hot — your existing account subscription picks up the hot account again. No cache changes needed because account state does not change while cold.
Some(UpdateOneof::Account(account_update)) => { if let Some(account) = account_update.account { let pubkey: [u8; 32] = account.pubkey.as_slice().try_into().unwrap(); // remove from cold cache. cold_cache.remove(&pubkey); }}
For the full streaming guide, see Streaming Token Accounts
and Streaming Mints.If you don’t stream, call get_multiple_account_interfaces at swap time and check is_cold() to detect cold accounts.
When you detect cold accounts in a market (via your cold_set or via is_cold() on fetched accounts),
fetch their ColdContext via get_account_interface and build load instructions.
use light_client::interface::{create_load_instructions, LightProgramInterface};// 1. Identify which accounts the swap toucheslet pubkeys = sdk.instruction_accounts(&AmmInstruction::Swap);// 2. Check which are cold (from your streaming cache, or fetch)let cold_pubkeys: Vec<_> = pubkeys.iter().filter(|p| cold_set.contains(p)).collect();// 3. If any are cold, fetch their ColdContext and build load instructionslet mut ixs = vec![];if !cold_pubkeys.is_empty() { let interfaces = rpc .get_multiple_account_interfaces(cold_pubkeys, None) .await? .value; let cold: Vec<_> = interfaces.into_iter().flatten().collect(); let specs = sdk.load_specs(&cold)?; ixs.extend(create_load_instructions(&specs, payer, config_pda, &rpc).await?);}// 4. Swap instruction is unchangedixs.push(sdk.swap_ix(&swap_params)?);
[dependencies]light-client = { version = "0.19.0", features = ["v2"] }# AMM SDK that implements LightProgramInterface (provided by the AMM team)example-amm-sdk = "0.1"
use light_client::interface::{create_load_instructions, LightProgramInterface};use example_amm_sdk::{ExampleAmmSdk, AmmInstruction};// Construct SDK from pool data (same as before -- pool data is always available,// hot or cold, via get_account_interface or your cache).let sdk = ExampleAmmSdk::new(pool_address, pool_data)?;// Quote works the same regardless of hot/cold.let quote = sdk.quote(amount_in, min_out)?;// Build transaction.let mut ixs = vec![];// Check if any swap accounts are cold.let pubkeys = sdk.instruction_accounts(&AmmInstruction::Swap);let cold_pubkeys: Vec<_> = pubkeys.iter().filter(|p| cold_set.contains(p)).collect();if !cold_pubkeys.is_empty() { // Fetch ColdContext for cold accounts. let interfaces = rpc .get_multiple_account_interfaces(cold_pubkeys, None) .await? .value; let cold: Vec<_> = interfaces.into_iter().flatten().collect(); let specs = sdk.load_specs(&cold)?; ixs.extend(create_load_instructions(&specs, payer.pubkey(), config_pda, &rpc).await?);}// Swap instruction is the same as without rent-free accounts.ixs.push(sdk.swap_ix(&swap_params)?);rpc.send_transaction(&ixs, &payer).await?;
Accounts go cold after extended inactivity. Their virtual rent balance drops
below a threshold and miners compress them onto the Solana ledger.They stay cold until any client loads them back in-flight via create_load_instructions.Touching cold markets is rare. The hot path has zero overhead.
No. Swap instructions are identical. If the market is hot, the transaction
is the same as today. If cold, you prepend create_load_instructions.
Can I quote cold markets?
Yes. You regular account cache stays the same even if a market is cold, so you can keep quoting with it.
Do rent-free markets increase latency?
Hot (common path): No.Cold: Loading accounts adds 1-200ms depending on whether a validity proof
is needed. If load + swap exceed Solana’s 1232 byte limit, use Jito bundles.
How long do accounts stay hot after loading?
Until they go inactive again. Each write resets the timer. The inactivity
threshold is configurable by the program owner (e.g. 24h of no writes).
What if load + swap exceed Solana's tx size limit?
Hot markets work all the same
as long as Solana is up. Cold accounts can’t be loaded until the indexer
recovers. Compression is cryptographically verifiable, and safety
does not depend on the indexer.
I don't stream. Can I still support rent free markets?
Yes.
To read state, and to build txns, simply use get_multiple_account_interfaces
for the instruction’s accounts and check is_cold(). This adds a RPC round-trip
but requires no streaming setup.
API is in Beta and subject to change.Questions or need hands-on support? Telegram | email | Discord
Integrate rent-free AMM markets into a router or aggregator
---description: Integrate rent-free AMM markets into a router or aggregatorallowed-tools: Bash, Read, Write, Edit, Glob, Grep, WebFetch, AskUserQuestion, Task, TaskCreate, TaskGet, TaskList, TaskUpdate, TaskOutput, mcp__deepwiki, mcp__zkcompression---## Integrate rent-free AMM markets into a router or aggregatorContext:- Guide: https://zkcompression.com/light-token/defi/routers- Skills and resources index: https://zkcompression.com/skill.md- Dedicated skill: https://github.com/Lightprotocol/skills/tree/main/skills/light-sdk- Crate: light-client (features: v2) — provides AccountInterface, LightProgramInterface, create_load_instructions- AMM reference: https://github.com/Lightprotocol/cp-swap-reference- Streaming guides: https://zkcompression.com/light-token/toolkits/for-streaming-tokensKey APIs: create_load_instructions(), LightProgramInterface trait, get_account_interface(), get_multiple_account_interfaces(), is_cold()### 1. Index project- Grep `LightProgramInterface|create_load_instructions|AccountInterface|is_cold|get_account_interface|swap|amm|router|aggregator` across src/- Glob `**/*.rs` and `**/Cargo.toml` for project structure- Identify: existing routing/quoting logic, account caching, swap instruction building, streaming setup- Read Cargo.toml — note existing dependencies and light-client version- Task subagent (Grep/Read/WebFetch) if project has multiple crates to scan in parallel### 2. Read references- WebFetch the guide above- 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 cold market support to existing router, build new router with rent-free market support, integrate a specific AMM SDK)- AskUserQuestion: does the project already stream account updates, or does it fetch at swap time?- AskUserQuestion: does the project use Jito bundles for multi-transaction swaps?- Summarize findings and wait for user confirmation before implementing### 4. Create plan- Based on steps 1–3, draft an implementation plan- Follow the guide's progression: Cold Account Cache → Detecting Cold Accounts → Building Swap Transactions with Load Instructions- If streaming: add account + transaction subscriptions for the Light Token Program- If fetch-at-swap-time: add get_multiple_account_interfaces + is_cold() check before building swap tx- 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 `cargo add light-client@0.19 --features v2`- Add AMM SDK dependency per the approved plan- Follow the guide and the approved plan- Write/Edit to create or modify files- TaskUpdate to mark each step done### 6. Verify- Bash `cargo check`- Bash `cargo test` if tests exist- 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