Struct anchor_lang::context::CpiContext
source · pub struct CpiContext<'a, 'b, 'c, 'info, T>where
T: ToAccountMetas + ToAccountInfos<'info>,{
pub accounts: T,
pub remaining_accounts: Vec<AccountInfo<'info>>,
pub program: AccountInfo<'info>,
pub signer_seeds: &'a [&'b [&'c [u8]]],
}
Expand description
Context specifying non-argument inputs for cross-program-invocations.
Example with and without PDA signature
ⓘ
// Callee Program
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod callee {
use super::*;
pub fn init(ctx: Context<Init>) -> Result<()> {
(*ctx.accounts.data).authority = ctx.accounts.authority.key();
Ok(())
}
pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
(*ctx.accounts.data_acc).data = data;
Ok(())
}
}
#[account]
#[derive(Default)]
pub struct Data {
data: u64,
authority: Pubkey,
}
#[derive(Accounts)]
pub struct Init<'info> {
#[account(init, payer = payer)]
pub data: Account<'info, Data>,
pub payer: Signer<'info>,
pub authority: UncheckedAccount<'info>,
pub system_program: Program<'info, System>
}
#[derive(Accounts)]
pub struct SetData<'info> {
#[account(mut, has_one = authority)]
pub data_acc: Account<'info, Data>,
pub authority: Signer<'info>,
}
// Caller Program
use anchor_lang::prelude::*;
use callee::{self, program::Callee};
declare_id!("Sxg7dBh5VLT8S1o6BqncZCPq9nhHHukjfVd6ohQJeAk");
#[program]
pub mod caller {
use super::*;
pub fn do_cpi(ctx: Context<DoCpi>, data: u64) -> Result<()> {
let callee_id = ctx.accounts.callee.to_account_info();
let callee_accounts = callee::cpi::accounts::SetData {
data_acc: ctx.accounts.data_acc.to_account_info(),
authority: ctx.accounts.callee_authority.to_account_info(),
};
let cpi_ctx = CpiContext::new(callee_id, callee_accounts);
callee::cpi::set_data(cpi_ctx, data)
}
pub fn do_cpi_with_pda_authority(ctx: Context<DoCpiWithPDAAuthority>, bump: u8, data: u64) -> Result<()> {
let seeds = &[&[b"example_seed", bytemuck::bytes_of(&bump)][..]];
let callee_id = ctx.accounts.callee.to_account_info();
let callee_accounts = callee::cpi::accounts::SetData {
data_acc: ctx.accounts.data_acc.to_account_info(),
authority: ctx.accounts.callee_authority.to_account_info(),
};
let cpi_ctx = CpiContext::new_with_signer(callee_id, callee_accounts, seeds);
callee::cpi::set_data(cpi_ctx, data)
}
}
// We can use "UncheckedAccount"s here because
// the callee program does the checks.
// We use "mut" so the autogenerated clients know
// that this account should be mutable.
#[derive(Accounts)]
pub struct DoCpi<'info> {
#[account(mut)]
pub data_acc: UncheckedAccount<'info>,
pub callee_authority: UncheckedAccount<'info>,
pub callee: Program<'info, Callee>,
}
#[derive(Accounts)]
pub struct DoCpiWithPDAAuthority<'info> {
#[account(mut)]
pub data_acc: UncheckedAccount<'info>,
pub callee_authority: UncheckedAccount<'info>,
pub callee: Program<'info, Callee>,
}
Fields§
§accounts: T
§remaining_accounts: Vec<AccountInfo<'info>>
§program: AccountInfo<'info>
§signer_seeds: &'a [&'b [&'c [u8]]]
Implementations§
source§impl<'a, 'b, 'c, 'info, T> CpiContext<'a, 'b, 'c, 'info, T>where
T: ToAccountMetas + ToAccountInfos<'info>,
impl<'a, 'b, 'c, 'info, T> CpiContext<'a, 'b, 'c, 'info, T>where T: ToAccountMetas + ToAccountInfos<'info>,
pub fn new(program: AccountInfo<'info>, accounts: T) -> Self
pub fn new_with_signer( program: AccountInfo<'info>, accounts: T, signer_seeds: &'a [&'b [&'c [u8]]] ) -> Self
pub fn with_signer(self, signer_seeds: &'a [&'b [&'c [u8]]]) -> Self
pub fn with_remaining_accounts(self, ra: Vec<AccountInfo<'info>>) -> Self
Trait Implementations§
source§impl<'info, T: ToAccountInfos<'info> + ToAccountMetas> ToAccountInfos<'info> for CpiContext<'_, '_, '_, 'info, T>
impl<'info, T: ToAccountInfos<'info> + ToAccountMetas> ToAccountInfos<'info> for CpiContext<'_, '_, '_, 'info, T>
fn to_account_infos(&self) -> Vec<AccountInfo<'info>>
source§impl<'info, T: ToAccountInfos<'info> + ToAccountMetas> ToAccountMetas for CpiContext<'_, '_, '_, 'info, T>
impl<'info, T: ToAccountInfos<'info> + ToAccountMetas> ToAccountMetas for CpiContext<'_, '_, '_, 'info, T>
source§fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta>
fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta>
is_signer
is given as an optional override for the signer meta field.
This covers the edge case when a program-derived-address needs to relay
a transaction from a client to another program but sign the transaction
before the relay. The client cannot mark the field as a signer, and so
we have to override the is_signer meta field given by the client.Auto Trait Implementations§
impl<'a, 'b, 'c, 'info, T> !RefUnwindSafe for CpiContext<'a, 'b, 'c, 'info, T>
impl<'a, 'b, 'c, 'info, T> !Send for CpiContext<'a, 'b, 'c, 'info, T>
impl<'a, 'b, 'c, 'info, T> !Sync for CpiContext<'a, 'b, 'c, 'info, T>
impl<'a, 'b, 'c, 'info, T> Unpin for CpiContext<'a, 'b, 'c, 'info, T>where T: Unpin,
impl<'a, 'b, 'c, 'info, T> !UnwindSafe for CpiContext<'a, 'b, 'c, 'info, T>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more