INTEGRATION
Compose ESEC into other protocols.
The cascade-vault program is plain Anchor. Any other Solana program can CPI into deposit / withdrawto route capital into ESEC as a strategy. This page documents the common integration patterns.
Yield router CPI
Use case: a generic yield router auto-allocates user deposits between Kamino, MarginFi, and ESEC based on real-time APY.
use cascade_vault::cpi::accounts::Deposit;
use cascade_vault::cpi as cascade_cpi;
pub fn route_to_cascade(ctx: Context<MyContext>, amount: u64) -> Result<()> {
let cpi_ctx = CpiContext::new(
ctx.accounts.cascade_program.to_account_info(),
Deposit {
depositor: ctx.accounts.router_authority.to_account_info(),
vault: ctx.accounts.cascade_vault.to_account_info(),
lp_mint: ctx.accounts.lp_mint.to_account_info(),
vault_asset: ctx.accounts.vault_asset.to_account_info(),
depositor_asset: ctx.accounts.router_asset.to_account_info(),
depositor_lp: ctx.accounts.router_lp.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
},
);
cascade_cpi::deposit(cpi_ctx, amount)?;
Ok(())
}AI agent treasury
Use case: an AI agent treasury parks idle capital in ESEC between active trades, withdrawing on signal.
// Agent has surplus stable from realized PnL.
// Park in ESEC for cycle yield while waiting for next signal.
await agentTreasury.allocate({
strategy: "cascade-lp",
asset: "USDC",
amount: idleBalance * 0.7n, // keep 30% liquid
});
// On signal, withdraw to redeploy capital.
await agentTreasury.deallocate({
strategy: "cascade-lp",
asset: "USDC",
fraction: 1.0,
});Kamino-style super-vault
Use case: a Kamino-style super-vault includes ESEC as one of N strategies, rebalancing periodically.
const strategies = [
{ name: "kamino-usdc", weight: 0.4 },
{ name: "marginfi-usdc", weight: 0.3 },
{ name: "cascade-usdc", weight: 0.3 },
];
// Rebalance every 24h via on-chain governance:
// compare 30-day APY across strategies
// shift weights toward the best performer (capped 50% to any single)
// atomically withdraw + redeposit via CPIReceipts as content primitives
Use case: a dashboard auto-renders every cycle close into a shareable PNG.
cascade.subscribeReceipts(async (receipt) => {
// Render PNG card.
const png = await cascade.generateReceiptCard(receipt);
// Auto-post to X.
await xClient.uploadAndPost({
image: png,
text: `${receipt.asset} cluster captured. ${receipt.reason}. tx: ${receipt.signature}`,
});
});Constraints
- Deposits and withdrawals require the vault to be in
Idlestate. CPI callers must check state first or handle theVaultNotIdleerror. - The
depositoraccount in deposit / withdraw is the authority signing the SPL transfer; for CPI from another program, this is typically the router PDA. - Withdraw fee (0.1% default) and performance fee (20% default of cycle profit) are charged in the asset; integrators see net amounts.