CPI Cross Program
Call other programs with CPI. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Search across all documentation pages
Call other programs with CPI. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
CPI without PDA signer.
// invoke(&ix, &[from.clone(), to.clone(), system_program.clone()])?CPI where a PDA must sign.
// invoke_signed(&ix, accounts, signer_seeds)?Pass AccountInfo slices matching instruction metas order.
// accounts: &[AccountInfo]CPI cannot escalate privileges beyond caller.
// cannot mark writable if original ix lacked writableRuntime limits CPI call depth.
// keep CPI graphs shallowset_return_data / get_return_data for CPI results.
// sol_set_return_data(bytes)Transfer lamports via system program.
// system_instruction::transfer(&from, &to, lamports)SPL token transfer CPI.
// spl_token::instruction::transfer(...)AccountInfo is cloned cheaply (ref to shared state).
// account_info.clone()Extra accounts for flexible CPI targets.
// ctx.remaining_accountsVerify callee program id before CPI.
// require_keys_eq!(token_program.key(), spl_token::id())Callee may CPI further until depth limit.
// design for reentrancy safetyCPI errors bubble as ProgramError.
// map_err into your error enumPDA must be writable in metas to mutate.
// AccountMeta::new(pda, false)Seeds slices must live for invoke_signed call.
// let seeds: &[&[u8]] = &[...]Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, Rust 1.91.1, and @solana/kit 7.0.0.
Reviewed by Chris St. John·Last updated Jul 18, 2026