use {
anchor_lang::{
prelude::borsh::BorshSchema,
prelude::Pubkey,
prelude::*,
solana_program::{self, instruction::Instruction},
AnchorDeserialize,
},
static_pubkey::static_pubkey,
std::{convert::TryFrom, hash::Hash},
};
pub static PAYER_PUBKEY: Pubkey = static_pubkey!("C1ockworkPayer11111111111111111111111111111");
pub fn anchor_sighash(name: &str) -> [u8; 8] {
let namespace = "global";
let preimage = format!("{}:{}", namespace, name);
let mut sighash = [0u8; 8];
sighash.copy_from_slice(
&anchor_lang::solana_program::hash::hash(preimage.as_bytes()).to_bytes()[..8],
);
sighash
}
#[derive(AnchorDeserialize, AnchorSerialize, BorshSchema, Clone, Debug, PartialEq)]
pub struct ClockData {
pub slot: u64,
pub epoch_start_timestamp: i64,
pub epoch: u64,
pub leader_schedule_epoch: u64,
pub unix_timestamp: i64,
}
impl From<Clock> for ClockData {
fn from(clock: Clock) -> Self {
ClockData {
slot: clock.slot,
epoch_start_timestamp: clock.epoch_start_timestamp,
epoch: clock.epoch,
leader_schedule_epoch: clock.leader_schedule_epoch,
unix_timestamp: clock.unix_timestamp,
}
}
}
impl From<&ClockData> for Clock {
fn from(clock: &ClockData) -> Self {
Clock {
slot: clock.slot,
epoch_start_timestamp: clock.epoch_start_timestamp,
epoch: clock.epoch,
leader_schedule_epoch: clock.leader_schedule_epoch,
unix_timestamp: clock.unix_timestamp,
}
}
}
impl TryFrom<Vec<u8>> for ClockData {
type Error = Error;
fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
Ok(
borsh::try_from_slice_with_schema::<ClockData>(data.as_slice())
.map_err(|_err| ErrorCode::AccountDidNotDeserialize)?,
)
}
}
#[derive(AnchorDeserialize, AnchorSerialize, Clone, Debug)]
pub struct ExecResponse {
pub kickoff_instruction: Option<InstructionData>,
pub next_instruction: Option<InstructionData>,
}
impl Default for ExecResponse {
fn default() -> Self {
return Self {
kickoff_instruction: None,
next_instruction: None,
};
}
}
#[derive(AnchorDeserialize, AnchorSerialize, BorshSchema, Clone, Debug, Hash, PartialEq)]
pub struct InstructionData {
pub program_id: Pubkey,
pub accounts: Vec<AccountMetaData>,
pub data: Vec<u8>,
}
impl From<Instruction> for InstructionData {
fn from(instruction: Instruction) -> Self {
InstructionData {
program_id: instruction.program_id,
accounts: instruction
.accounts
.iter()
.map(|a| AccountMetaData {
pubkey: a.pubkey,
is_signer: a.is_signer,
is_writable: a.is_writable,
})
.collect(),
data: instruction.data,
}
}
}
impl From<&InstructionData> for Instruction {
fn from(instruction: &InstructionData) -> Self {
Instruction {
program_id: instruction.program_id,
accounts: instruction
.accounts
.iter()
.map(|a| AccountMeta {
pubkey: a.pubkey,
is_signer: a.is_signer,
is_writable: a.is_writable,
})
.collect(),
data: instruction.data.clone(),
}
}
}
impl TryFrom<Vec<u8>> for InstructionData {
type Error = Error;
fn try_from(data: Vec<u8>) -> std::result::Result<Self, Self::Error> {
Ok(
borsh::try_from_slice_with_schema::<InstructionData>(data.as_slice())
.map_err(|_err| ErrorCode::AccountDidNotDeserialize)?,
)
}
}
#[derive(AnchorDeserialize, AnchorSerialize, BorshSchema, Clone, Debug, Hash, PartialEq)]
pub struct AccountMetaData {
pub pubkey: Pubkey,
pub is_signer: bool,
pub is_writable: bool,
}
impl AccountMetaData {
pub fn new(pubkey: Pubkey, is_signer: bool) -> Self {
Self {
pubkey,
is_signer,
is_writable: true,
}
}
pub fn new_readonly(pubkey: Pubkey, is_signer: bool) -> Self {
Self {
pubkey,
is_signer,
is_writable: false,
}
}
}