cpi feature to call Alpha Vault from another Anchor program:
[dependencies]
alpha-vault = { path = "../alpha-vault/programs/alpha-vault", features = ["cpi"] }
CPI Pattern
Anchor generates a CPI module for the program instructions. Account structs use the same names as the instruction contexts in the Alpha Vault source.use alpha_vault::cpi;
use alpha_vault::cpi::accounts::DepositCtx;
use alpha_vault::program::AlphaVault;
use anchor_lang::prelude::*;
pub fn deposit_into_alpha_vault<'info>(
ctx: Context<'_, '_, '_, 'info, YourDepositCtx<'info>>,
max_amount: u64,
) -> Result<()> {
let cpi_program = ctx.accounts.alpha_vault_program.to_account_info();
let cpi_accounts = DepositCtx {
vault: ctx.accounts.vault.to_account_info(),
pool: ctx.accounts.pool.to_account_info(),
escrow: ctx.accounts.escrow.to_account_info(),
source_token: ctx.accounts.source_token.to_account_info(),
token_vault: ctx.accounts.token_vault.to_account_info(),
token_mint: ctx.accounts.token_mint.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
owner: ctx.accounts.owner.to_account_info(),
};
cpi::deposit(CpiContext::new(cpi_program, cpi_accounts), max_amount)
}
Instructions marked with
#[event_cpi] require the event-CPI accounts generated by Anchor. If you construct CPI calls manually, include the generated event authority and program accounts expected by the IDL.Common CPI Calls
| CPI call | Account context | Parameters | Notes |
|---|---|---|---|
cpi::create_new_escrow | CreateNewEscrowCtx | None | Permissionless only. Runs during the deposit window. |
cpi::create_permissioned_escrow | CreatePermissionedEscrowWithMerkleProofCtx | max_cap, proof | Verifies wallet cap proof against MerkleRootConfig. |
cpi::create_permissioned_escrow_with_authority | CreatePermissionedEscrowWithAuthorityCtx | max_cap | Payer must equal vault_authority. |
cpi::deposit | DepositCtx | max_amount | Owner signer transfers quote into the vault token account. |
cpi::withdraw | WithdrawCtx | amount | Pro Rata only. Can withdraw deposits or overflow depending on current time point. |
cpi::withdraw_remaining_quote | WithdrawRemainingQuoteCtx | None | Runs after the buying window and marks the escrow refunded. |
cpi::claim_token | ClaimTokenCtx | None | Runs after start_vesting_point. |
cpi::close_escrow | CloseEscrowCtx | None | Requires the escrow to be closable. |
cpi::fill_dlmm | FillDlmmCtx | max_amount, remaining_accounts_info | Requires DLMM bin array and transfer-hook remaining accounts when applicable. |
cpi::fill_dynamic_amm | FillDynamicAmmCtx | max_amount | Calls Dynamic AMM / DAMM v1. |
cpi::fill_damm_v2 | FillDammV2Ctx | max_amount | Calls DAMM v2. |
Account Requirements
| Flow | Required signer | Important accounts |
|---|---|---|
| Escrow creation, permissionless | payer | vault, pool, escrow PDA, owner, optional treasury fee receiver. |
| Escrow creation, Merkle proof | payer | vault, pool, escrow PDA, owner, merkle_root_config, optional treasury fee receiver. |
| Escrow creation, authority | payer equal to vault_authority | vault, pool, escrow PDA, owner. |
| User deposit | owner | Owner quote token source, vault quote token ATA, quote mint, token program. |
| User withdraw or refund | owner | User quote destination, vault quote token ATA, quote mint, token program. |
| User claim | owner | User base destination, vault base token ATA, base mint, token program. |
| Fill | cranker | Vault quote and base token accounts, connected pool-specific accounts, optional crank whitelist, optional treasury fee receiver. |
Remaining Accounts
| Situation | Remaining accounts |
|---|---|
| Destination account requires Token 2022 memo transfer | Pass the memo program first for withdraw, withdraw_remaining_quote, or claim_token. |
| DLMM fill with Token 2022 transfer hooks | Pass the transfer-hook accounts described by RemainingAccountsInfo, followed by writable bin array accounts. |
| Dynamic AMM fill | No Alpha Vault-specific remaining accounts are read by the handler. |
| DAMM v2 fill | No Alpha Vault-specific remaining accounts are read by the handler. |
Common CPI Failures
| Error area | CPI-side fix |
|---|---|
| Pool type mismatch | Call the fill instruction matching vault.pool_type. |
| Time window mismatch | Read the connected pool timing and vault timing before sending CPI. |
| Missing treasury | Pass the treasury as crank_fee_receiver or escrow_fee_receiver when no valid whitelist removes the fee path. |
| Permission mode mismatch | Use the escrow creation instruction that matches vault.whitelist_mode. |
| Token 2022 transfer fee | Pass max amounts in raw token units and expect credited amounts to be transfer-fee excluded. |
Best Practices
| Check | Detail |
|---|---|
| Prefer generated bindings | Use the local Anchor crate with the cpi feature or generated IDL bindings. Avoid hand-typing account order from memory. |
| Compare with the SDK | Build the same flow with @meteora-ag/alpha-vault and compare account metas, signers, writable flags, and optional accounts. |
| Read vault state first | Load Vault before deciding the flow. Validate vault_mode, whitelist_mode, pool_type, token vaults, mints, and authority from account state. |
| Respect pool timing | Read the connected pool timing before deposits, fills, refunds, and claims. Alpha Vault actions are gated by both vault points and pool pre-activation points. |
| Keep pool type explicit | Route fills by vault.pool_type: DLMM, Dynamic AMM / DAMM v1, or DAMM v2. Each path has a different account set. |
| Treat Merkle caps as state | For Merkle-proof vaults, verify the proof off-chain before sending CPI and use the same max_cap passed to the program. |
| Plan fee accounts | Permissionless escrow creation and non-whitelisted fills can require the Alpha Vault treasury. Permissioned vaults must not charge escrow fees. |
| Handle once-only actions | withdraw_remaining_quote marks the escrow refunded. Escrow close also depends on claims, refunds, and overflow withdrawals being complete. |
| Simulate Token 2022 paths | Transfer-fee mints change credited amounts, and memo-required destination accounts need the memo program in remaining accounts. DLMM transfer hooks need matching remaining-account slices. |
| Test every mode you support | Pro Rata and FCFS differ in deposits, withdrawals, caps, overflow behavior, and swappable amounts. Permissionless, Merkle, and authority access also differ. |
Testing
Use the local Alpha Vault test suite as a reference for account metas and edge cases:cd alpha-vault
anchor build
anchor test

