A quick guide using Anchor and the whirlpool_cpi crate
What You'll Learn
Orca Whirlpools is a concentrated liquidity AMM on Solana. When you provide liquidity, you earn:
- Trading Fees: A share of swaps within your price range (Token A + Token B)
- Rewards: Up to 3 incentive tokens configured by the pool operator
This guide shows how to collect both programmatically using CPI.
The Critical Step Everyone Misses
You must call update_fees_and_rewards before collecting, or you will receive 0 tokens.
The position account stores fees/rewards as checkpoints. The update instruction calculates what's owed since the last checkpoint and writes it to fee_owed_a, fee_owed_b, and reward_infos[].amount_owed. Without this step, those fields remain at zero.
// CRITICAL: Always call this BEFORE collect_fees or collect_reward
execute_update_fees_and_rewards_cpi(
&ctx.accounts.whirlpool_program,
&ctx.accounts.whirlpool.to_account_info(),
&ctx.accounts.position.to_account_info(),
&ctx.accounts.tick_array_lower.to_account_info(),
&ctx.accounts.tick_array_upper.to_account_info(),
Some(vault_seeds),
)?;
Collecting Fees
After updating, call collect_fees to receive both pool tokens:
whirlpool_cpi::cpi::collect_fees(cpi_ctx)?;
Collecting Rewards
Rewards use an index-based system (0, 1, or 2). Check whirlpool.rewardInfos[index] for active rewards:
// Client-side: iterate through active reward slots
for (let rewardIndex = 0; rewardIndex < 3; rewardIndex++) {
const rewardInfo = pool_data.data.rewardInfos[rewardIndex]
// Skip uninitialized slots
if (rewardInfo.mint.toString() === "11111111111111111111111111111111") {
continue
}
// Collect this reward using its index, mint, and vault
await program.methods
.collectRewardsOrcaPosition(operationId, rewardIndex)
.accounts({
rewardTokenMint: rewardInfo.mint,
rewardVault: rewardInfo.vault,
// ... other accounts
})
.rpc()
}
Quick Summary
-
Always update first - Call
update_fees_and_rewardsor get 0 tokens - Fees are both tokens - One call collects Token A and Token B
-
Rewards are per-index - Loop through
rewardInfos[0..2]and collect each active one
๐ Read the full guide for complete CPI implementations, account structures, and client-side fee/reward quote calculations using the Orca SDK.
Top comments (0)