use crate::account::AccountView;
use crate::address::Address;
use crate::instruction::{InstructionAccount, InstructionView, Signer};
use crate::ProgramResult;
pub const SYSTEM_PROGRAM_ID: Address = Address::new_from_array([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
pub struct CreateAccount<'a, 'b> {
pub from: &'a AccountView,
pub to: &'a AccountView,
pub lamports: u64,
pub space: u64,
pub owner: &'b Address,
}
impl CreateAccount<'_, '_> {
#[inline]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
}
#[inline]
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
let mut data = [0u8; 52];
data[4..12].copy_from_slice(&self.lamports.to_le_bytes());
data[12..20].copy_from_slice(&self.space.to_le_bytes());
data[20..52].copy_from_slice(self.owner.as_array());
let accounts = [
InstructionAccount::writable_signer(self.from.address()),
InstructionAccount::writable_signer(self.to.address()),
];
let views = [self.from, self.to];
let instruction = InstructionView {
program_id: &SYSTEM_PROGRAM_ID,
data: &data,
accounts: &accounts,
};
crate::cpi::invoke_signed(&instruction, &views, signers)
}
}
pub struct Transfer<'a> {
pub from: &'a AccountView,
pub to: &'a AccountView,
pub lamports: u64,
}
impl Transfer<'_> {
#[inline]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
}
#[inline]
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
let mut data = [0u8; 12];
data[0] = 2;
data[4..12].copy_from_slice(&self.lamports.to_le_bytes());
let accounts = [
InstructionAccount::writable_signer(self.from.address()),
InstructionAccount::writable(self.to.address()),
];
let views = [self.from, self.to];
let instruction = InstructionView {
program_id: &SYSTEM_PROGRAM_ID,
data: &data,
accounts: &accounts,
};
crate::cpi::invoke_signed(&instruction, &views, signers)
}
}
pub struct Assign<'a, 'b> {
pub account: &'a AccountView,
pub owner: &'b Address,
}
impl Assign<'_, '_> {
#[inline]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
}
#[inline]
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
let mut data = [0u8; 36];
data[0] = 1;
data[4..36].copy_from_slice(self.owner.as_array());
let accounts = [InstructionAccount::writable_signer(self.account.address())];
let views = [self.account];
let instruction = InstructionView {
program_id: &SYSTEM_PROGRAM_ID,
data: &data,
accounts: &accounts,
};
crate::cpi::invoke_signed(&instruction, &views, signers)
}
}
pub struct Allocate<'a> {
pub account: &'a AccountView,
pub space: u64,
}
impl Allocate<'_> {
#[inline]
pub fn invoke(&self) -> ProgramResult {
self.invoke_signed(&[])
}
#[inline]
pub fn invoke_signed(&self, signers: &[Signer]) -> ProgramResult {
let mut data = [0u8; 12];
data[0] = 8;
data[4..12].copy_from_slice(&self.space.to_le_bytes());
let accounts = [InstructionAccount::writable_signer(self.account.address())];
let views = [self.account];
let instruction = InstructionView {
program_id: &SYSTEM_PROGRAM_ID,
data: &data,
accounts: &accounts,
};
crate::cpi::invoke_signed(&instruction, &views, signers)
}
}
pub mod instructions {
pub use super::{CreateAccount, Transfer, Assign, Allocate};
}