Conceptos básicos de CPI en Anchor
8 ejemplos para empezar con las CPI de Anchor: 5 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
8 ejemplos para empezar con las CPI de Anchor: 5 básicos y 3 intermedios.
Cargo.toml del programaLa CPI del programa System mueve lamports entre cuentas.
use anchor_lang::system_program::{self, Transfer};
system_program::transfer(
CpiContext::new(
ctx.accounts.system_program.to_account_info(),
Transfer {
from: ctx.accounts.payer.to_account_info(),
to: ctx.accounts.recipient.to_account_info(),
},
),
lamports,
)?;? para propagar ProgramErroranchor-spl envuelve la invocación del programa de token. Usa transfer_checked - token::transfer / Transfer están obsoletos porque no llevan mint ni decimales.
use anchor_spl::token_interface::{self, TransferChecked};
token_interface::transfer_checked(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
TransferChecked {
from: ctx.accounts.from_ata.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.to_ata.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
},
),
amount,
ctx.accounts.mint.decimals,
)?;with_signermut, y ambas deben referenciar el mint proporcionadoInterface<TokenInterface> (o Program<Token>) en las cuentasLas PDAs firman las CPI a través de porciones de semillas.
use anchor_spl::token_interface::{self, TransferChecked};
let seeds: &[&[u8]] = &[b"vault", &[ctx.bumps.vault]];
let signer: &[&[&[u8]]] = &[seeds];
token_interface::transfer_checked(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
TransferChecked {
from: ctx.accounts.vault_ata.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.user_ata.to_account_info(),
authority: ctx.accounts.vault.to_account_info(),
},
signer,
),
amount,
ctx.accounts.mint.decimals,
)?;signer_seeds es &[&[&[u8]]] - una porción interna por cada PDA firmante.key() a un let antes de .as_ref() en un array de semillas, o el temporal se desecha demasiado pronto (E0716)ctx.bumps cuando esté disponible; la cuenta de autoridad es la PDAAñade semillas a un contexto existente con .with_signer.
let cpi_ctx = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
transfer_accounts, // una struct TransferChecked construida anteriormente
);
token_interface::transfer_checked(
cpi_ctx.with_signer(signer),
amount,
ctx.accounts.mint.decimals,
)?;new_with_signerFija los IDs de programa de CPI en la struct de cuentas.
pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,Interface para Token-2022Anchor 0.32 genera clientes CPI a partir de IDLs externas.
// lib.rs
declare_program!(other_program);
pub fn call_other(ctx: Context<CallOther>) -> Result<()> {
other_program::cpi::do_something(
CpiContext::new(
ctx.accounts.other_program.to_account_info(),
other_program::cpi::accounts::DoSomething { /* ... */ },
),
)?;
Ok(())
}declare_program!cpi::Relacionado: CPI a Programas Personalizados
Reenvía cuentas adicionales al destino de la CPI.
let mut cpi_ctx = CpiContext::new(program, accounts);
cpi_ctx = cpi_ctx.with_remaining_accounts(ctx.remaining_accounts.to_vec());
other_program::cpi::advanced(cpi_ctx)?;Relacionado: Pasar Cuentas Restantes
Los fallos de CPI se devuelven como ProgramError en el llamador.
token_interface::transfer_checked(cpi_ctx, amount, decimals)
.map_err(|_| MyError::TransferFailed)?;#[error_code] personalizadosVersiones de la pila: Esta página se escribió para Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0 y LiteSVM 0.6.x.
Revisado por Chris St. John·Última actualización: 16 jul 2026