CPI
Anchor → Pinocchio
| Anchor | Pinocchio |
|---|---|
CpiContext::new() |
Struct-based instruction (e.g., Transfer { ... }) |
CpiContext::new_with_signer() |
.invoke_signed(&[signer]) |
anchor_spl::token::transfer() |
pinocchio_token::instructions::Transfer |
system_program::transfer() |
pinocchio_system::instructions::Transfer |
Basic CPI
use pinocchio_system::instructions::Transfer;
fn transfer_sol(from: &AccountView, to: &AccountView, amount: u64) -> ProgramResult {
Transfer {
from,
to,
lamports: amount,
}.invoke()
}
Anchor equivalent:
system_program::transfer(
CpiContext::new(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer {
from: ctx.accounts.from.to_account_info(),
to: ctx.accounts.to.to_account_info(),
},
),
amount,
)?;
CPI with PDA Signer
use pinocchio::cpi::{Signer, Seed};
use pinocchio_system::instructions::Transfer;
fn withdraw(
vault: &AccountView,
recipient: &AccountView,
vault_state: &Vault,
amount: u64,
) -> ProgramResult {
let bump_bytes = [vault_state.bump];
let seeds: [Seed; 3] = [
Seed::from(b"vault"),
Seed::from(vault_state.authority.as_slice()),
Seed::from(&bump_bytes),
];
let signer = Signer::from(&seeds);
Transfer {
from: vault,
to: recipient,
lamports: amount,
}.invoke_signed(&[signer])
}
Anchor equivalent:
let seeds = &[b"vault", authority.as_ref(), &[bump]];
let signer = &[&seeds[..]];
system_program::transfer(
CpiContext::new_with_signer(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer { from, to },
signer,
),
amount,
)?;
Token Transfer
use pinocchio_token::instructions::Transfer;
fn transfer_tokens(
from: &AccountView,
to: &AccountView,
authority: &AccountView,
amount: u64,
) -> ProgramResult {
Transfer {
from,
to,
authority,
amount,
}.invoke()
}
Anchor equivalent:
token::transfer(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
token::Transfer {
from: ctx.accounts.from.to_account_info(),
to: ctx.accounts.to.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
},
),
amount,
)?;
Token Transfer with PDA
use pinocchio_token::instructions::Transfer;
use pinocchio::cpi::{Signer, Seed};
fn vault_transfer(
vault_token: &AccountView,
destination: &AccountView,
vault_pda: &AccountView,
vault_state: &Vault,
amount: u64,
) -> ProgramResult {
let bump_bytes = [vault_state.bump];
let seeds: [Seed; 3] = [
Seed::from(b"vault"),
Seed::from(vault_state.authority.as_slice()),
Seed::from(&bump_bytes),
];
let signer = Signer::from(&seeds);
Transfer {
from: vault_token,
to: destination,
authority: vault_pda,
amount,
}.invoke_signed(&[signer])
}
Available CPIs
pinocchio-system:
CreateAccount,Transfer,Allocate,Assign
pinocchio-token:
Transfer,MintTo,Burn,InitializeMint2,InitializeAccount3Approve,Revoke,SetAuthority,CloseAccount
Sysvars
use pinocchio::sysvars::{Clock, Rent};
let clock = Clock::get()?;
let timestamp = clock.unix_timestamp;
let rent = Rent::get()?;
let lamports = rent.try_minimum_balance(100)?;