This commit is contained in:
Han Yang 2022-09-25 02:11:12 +08:00 committed by GitHub
parent 7f243ce66c
commit 3970847e75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 172 additions and 0 deletions

1
Cargo.lock generated
View File

@ -277,6 +277,7 @@ name = "anchor-spl"
version = "0.25.0"
dependencies = [
"anchor-lang",
"borsh",
"mpl-token-metadata",
"serum_dex",
"solana-program",

View File

@ -14,12 +14,14 @@ token = ["spl-token"]
associated_token = ["spl-associated-token-account"]
governance = []
shmem = []
stake = ["borsh"]
devnet = []
metadata = ["mpl-token-metadata"]
dex = ["serum_dex"]
[dependencies]
anchor-lang = { path = "../lang", version = "0.25.0", features = ["derive"] }
borsh = { version = "^0.9", optional = true }
serum_dex = { git = "https://github.com/project-serum/serum-dex", rev = "1be91f2", version = "0.4.0", features = ["no-entrypoint"], optional = true }
solana-program = "~1.10.29"
spl-token = { version = "~3.3.0", features = ["no-entrypoint"], optional = true }

View File

@ -16,5 +16,8 @@ pub mod governance;
#[cfg(feature = "shmem")]
pub mod shmem;
#[cfg(feature = "stake")]
pub mod stake;
#[cfg(feature = "metadata")]
pub mod metadata;

166
spl/src/stake.rs Normal file
View File

@ -0,0 +1,166 @@
use anchor_lang::{
context::CpiContext,
solana_program::{
account_info::AccountInfo,
pubkey::Pubkey,
stake::{
self,
program::ID,
state::{StakeAuthorize, StakeState},
},
},
Accounts, Result,
};
use borsh::BorshDeserialize;
use std::ops::Deref;
// CPI functions
pub fn authorize<'info>(
ctx: CpiContext<'_, '_, '_, 'info, Authorize<'info>>,
stake_authorize: StakeAuthorize,
custodian: Option<AccountInfo<'info>>,
) -> Result<()> {
let ix = stake::instruction::authorize(
ctx.accounts.stake.key,
ctx.accounts.authorized.key,
ctx.accounts.new_authorized.key,
stake_authorize,
custodian.as_ref().map(|c| c.key),
);
let mut account_infos = vec![
ctx.accounts.stake,
ctx.accounts.clock,
ctx.accounts.authorized,
];
if let Some(c) = custodian {
account_infos.push(c);
}
solana_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,
custodian: Option<AccountInfo<'info>>,
) -> Result<()> {
let ix = stake::instruction::withdraw(
ctx.accounts.stake.key,
ctx.accounts.withdrawer.key,
ctx.accounts.to.key,
amount,
custodian.as_ref().map(|c| c.key),
);
let mut account_infos = vec![
ctx.accounts.stake,
ctx.accounts.to,
ctx.accounts.clock,
ctx.accounts.stake_history,
ctx.accounts.withdrawer,
];
if let Some(c) = custodian {
account_infos.push(c);
}
solana_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);
solana_program::program::invoke_signed(
&ix,
&[ctx.accounts.stake, ctx.accounts.clock, ctx.accounts.staker],
ctx.signer_seeds,
)
.map_err(Into::into)
}
// CPI accounts
#[derive(Accounts)]
pub struct Authorize<'info> {
/// The stake account to be updated
pub stake: AccountInfo<'info>,
/// The existing authority
pub authorized: AccountInfo<'info>,
/// The new authority to replace the existing authority
pub new_authorized: AccountInfo<'info>,
/// Clock sysvar
pub clock: AccountInfo<'info>,
}
#[derive(Accounts)]
pub struct Withdraw<'info> {
/// The stake account to be updated
pub stake: AccountInfo<'info>,
/// The stake account's withdraw authority
pub withdrawer: AccountInfo<'info>,
/// Account to send withdrawn lamports to
pub to: AccountInfo<'info>,
/// Clock sysvar
pub clock: AccountInfo<'info>,
/// StakeHistory sysvar
pub stake_history: AccountInfo<'info>,
}
#[derive(Accounts)]
pub struct DeactivateStake<'info> {
/// The stake account to be deactivated
pub stake: AccountInfo<'info>,
/// The stake account's stake authority
pub staker: AccountInfo<'info>,
/// Clock sysvar
pub clock: AccountInfo<'info>,
}
// State
#[derive(Clone)]
pub struct StakeAccount(StakeState);
impl anchor_lang::AccountDeserialize for StakeAccount {
fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
Self::try_deserialize_unchecked(buf)
}
fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
StakeState::deserialize(buf).map(Self).map_err(Into::into)
}
}
impl anchor_lang::AccountSerialize for StakeAccount {}
impl anchor_lang::Owner for StakeAccount {
fn owner() -> Pubkey {
ID
}
}
impl Deref for StakeAccount {
type Target = StakeState;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[derive(Clone)]
pub struct Stake;
impl anchor_lang::Id for Stake {
fn id() -> Pubkey {
ID
}
}