use satellite_lang::{
arch_program::{
account::AccountInfo,
pubkey::Pubkey,
stake::{
self,
program::STAKE_PROGRAM_ID,
state::{StakeAuthorize, StakeState},
},
},
context::CpiContext,
Accounts, Result,
};
use std::ops::Deref;
pub fn authorize<'info>(
ctx: CpiContext<'_, '_, '_, 'info, Authorize<'info>>,
stake_authorize: StakeAuthorize,
) -> Result<()> {
let ix = stake::instruction::authorize(
ctx.accounts.stake.key,
ctx.accounts.authorized.key,
ctx.accounts.new_authorized.key,
stake_authorize,
);
let account_infos = vec![
ctx.accounts.stake,
ctx.accounts.authorized,
];
satellite_lang::arch_program::program::invoke_signed(&ix, &account_infos, ctx.signer_seeds)
.map_err(Into::into)
}
pub fn withdraw<'info>(
ctx: CpiContext<'_, '_, '_, 'info, Withdraw<'info>>,
amount: u64,
) -> Result<()> {
let ix = stake::instruction::withdraw(
ctx.accounts.stake.key,
ctx.accounts.withdrawer.key,
ctx.accounts.to.key,
amount,
);
let account_infos = vec![
ctx.accounts.stake,
ctx.accounts.to,
ctx.accounts.withdrawer,
];
satellite_lang::arch_program::program::invoke_signed(&ix, &account_infos, ctx.signer_seeds)
.map_err(Into::into)
}
pub fn deactivate_stake<'info>(
ctx: CpiContext<'_, '_, '_, 'info, DeactivateStake<'info>>,
) -> Result<()> {
let ix = stake::instruction::deactivate_stake(ctx.accounts.stake.key, ctx.accounts.staker.key);
satellite_lang::arch_program::program::invoke_signed(
&ix,
&[ctx.accounts.stake, ctx.accounts.staker],
ctx.signer_seeds,
)
.map_err(Into::into)
}
#[derive(Accounts)]
pub struct Authorize<'info> {
pub stake: AccountInfo<'info>,
pub authorized: AccountInfo<'info>,
pub new_authorized: AccountInfo<'info>,
}
#[derive(Accounts)]
pub struct Withdraw<'info> {
pub stake: AccountInfo<'info>,
pub withdrawer: AccountInfo<'info>,
pub to: AccountInfo<'info>,
}
#[derive(Accounts)]
pub struct DeactivateStake<'info> {
pub stake: AccountInfo<'info>,
pub staker: AccountInfo<'info>,
}
#[derive(Clone)]
pub struct StakeAccount(StakeState);
impl satellite_lang::AccountDeserialize for StakeAccount {
fn try_deserialize(buf: &mut &[u8]) -> satellite_lang::Result<Self> {
Self::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> satellite_lang::Result<Self> {
let needed = StakeState::size_of();
if buf.len() < needed {
return Err(satellite_lang::error::ErrorCode::AccountDidNotDeserialize.into());
}
let head = &buf[..needed];
let value = unsafe { core::ptr::read_unaligned(head.as_ptr() as *const StakeState) };
Ok(Self(value))
}
}
impl satellite_lang::AccountSerialize for StakeAccount {}
impl satellite_lang::Owner for StakeAccount {
fn owner() -> Pubkey {
STAKE_PROGRAM_ID
}
}
impl Deref for StakeAccount {
type Target = StakeState;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone)]
pub struct Stake;
impl satellite_lang::Id for Stake {
fn id() -> Pubkey {
STAKE_PROGRAM_ID
}
}