The stable integration contract is the public
cp-amm program, the published IDL, and the official SDK behavior. This page is cross-checked against the cp-amm source so account ordering and remaining-account notes match the on-chain handlers.Program ID
Generated Bindings
Prefer generated CPI bindings from thecp-amm IDL. The handlers use Anchor accounts, optional accounts, generated instruction args, #[event_cpi], and a custom optimized swap entrypoint with Anchor fallback.
The public integration contract is:
You can generate a client from the IDL or depend on the public
cp-amm crate from the DAMM v2 workspace when your build setup allows it.
If you depend on the Rust crate for CPI, enable the CPI-compatible features from the workspace:
CPI Instruction Scope
For the fullcp-amm instruction-family map, see DAMM v2 Program Instructions. This page focuses on CPI implementation details for the user instructions most integrations call: swap2, add_liquidity, remove_liquidity, claim_position_fee, claim_reward, and position lock flows.
For off-chain apps, bots, and launch scripts, the TypeScript SDK is usually simpler and safer.
Account Planning
Read token mint and vault addresses from pool state whenever possible. Avoid reconstructing token A/B assumptions from user input alone.
Event CPI Accounts
Mostcp-amm account structs use #[event_cpi]. Generated clients include event CPI accounts after the instruction’s primary accounts:
Keep these accounts in the generated order. They are part of Anchor’s account validation even though they are not business-state accounts.
Remaining Accounts
Rate-limiter pools reject swaps that do not include the instructions sysvar because the program validates single-swap behavior for that pool in the transaction. This remaining-account requirement applies to existing rate-limiter pools. New configs and new pools cannot useBaseFeeMode::RateLimiter.
swap and swap2, the optimized swap path expects the fixed swap account list plus remaining accounts. For existing rate-limiter pools, if the rate limiter is active, put the instructions sysvar as the first remaining account. Normal non-rate-limiter swaps do not need remaining accounts.
Token 2022 transfer-hook accounts are not a general DAMM v2 CPI surface. DAMM v2 accepts Transfer Hook permissionlessly only when both the hook program ID and authority are unset. Mints outside that allowlist need a token badge to pass mint validation, but DAMM v2 still does not forward transfer-hook extra accounts on transfers. See Token 2022 support.
initialize_pool and initialize_pool_with_dynamic_config skip permissionless-mint and token-badge checks when the private config has CreatePoolWithoutMintValidation. initialize_customizable_pool always validates mints (skip=false) and still expects token badge remaining accounts at index 0 (token A) and index 1 (token B) when a mint is not permissionless-supported. Token-2022 wrapped SOL is still rejected.Swap CPI Shape
For generated Anchor CPI, the account set mirrorsSwapCtx:
swap2 parameters use the same semantics as the SDK:

