Files
ore/api/src/instruction.rs
2024-07-09 16:23:25 -07:00

444 lines
17 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
use bytemuck::{Pod, Zeroable};
use drillx::Solution;
use num_enum::TryFromPrimitive;
use shank::ShankInstruction;
use solana_program::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
system_program, sysvar,
};
use crate::{
consts::*,
utils::{impl_instruction_from_bytes, impl_to_bytes},
};
#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, ShankInstruction, TryFromPrimitive)]
#[rustfmt::skip]
pub enum OreInstruction {
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "beneficiary", desc = "Beneficiary token account", writable)]
#[account(3, name = "proof", desc = "Ore proof account", writable)]
#[account(4, name = "treasury", desc = "Ore treasury account", writable)]
#[account(5, name = "treasury_tokens", desc = "Ore treasury token account", writable)]
#[account(6, name = "token_program", desc = "SPL token program")]
Claim = 0,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "proof", desc = "Ore proof account", writable)]
#[account(3, name = "system_program", desc = "Solana system program")]
Close = 1,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "config", desc = "Ore config account", writable)]
#[account(3, name = "proof", desc = "Ore proof account current top staker")]
#[account(4, name = "proof_new", desc = "Ore proof account new top staker")]
Crown = 2,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "bus", desc = "Ore bus account", writable)]
#[account(3, name = "config", desc = "Ore config account")]
#[account(4, name = "noise", desc = "Ore noise account")]
#[account(5, name = "proof", desc = "Ore proof account", writable)]
#[account(6, name = "slot_hashes", desc = "Solana slot hashes sysvar")]
Mine = 3,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "proof", desc = "Ore proof account", writable)]
#[account(3, name = "system_program", desc = "Solana system program")]
Open = 4,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "bus_0", desc = "Ore bus account 0", writable)]
#[account(3, name = "bus_1", desc = "Ore bus account 1", writable)]
#[account(4, name = "bus_2", desc = "Ore bus account 2", writable)]
#[account(5, name = "bus_3", desc = "Ore bus account 3", writable)]
#[account(6, name = "bus_4", desc = "Ore bus account 4", writable)]
#[account(7, name = "bus_5", desc = "Ore bus account 5", writable)]
#[account(8, name = "bus_6", desc = "Ore bus account 6", writable)]
#[account(9, name = "bus_7", desc = "Ore bus account 7", writable)]
#[account(10, name = "config", desc = "Ore config account")]
#[account(11, name = "mint", desc = "Ore token mint account", writable)]
#[account(12, name = "treasury", desc = "Ore treasury account", writable)]
#[account(13, name = "treasury_tokens", desc = "Ore treasury token account", writable)]
#[account(14, name = "token_program", desc = "SPL token program")]
Reset = 5,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "proof", desc = "Ore proof account", writable)]
#[account(3, name = "sender", desc = "Signer token account", writable)]
#[account(4, name = "treasury_tokens", desc = "Ore treasury token account", writable)]
#[account(5, name = "token_program", desc = "SPL token program")]
Stake = 6,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "proof", desc = "Ore proof account", writable)]
Update = 7,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Signer", signer)]
#[account(2, name = "beneficiary", desc = "Beneficiary token account", writable)]
#[account(3, name = "sender", desc = "Signer token account", writable)]
#[account(4, name = "treasury", desc = "Ore treasury account", writable)]
#[account(5, name = "mint", desc = "Ore token mint account", writable)]
#[account(6, name = "mint_v1", desc = "Ore v1 token mint account", writable)]
#[account(7, name = "token_program", desc = "SPL token program")]
Upgrade = 8,
#[account(0, name = "ore_program", desc = "Ore program")]
#[account(1, name = "signer", desc = "Admin signer", signer)]
#[account(2, name = "bus_0", desc = "Ore bus account 0", writable)]
#[account(3, name = "bus_1", desc = "Ore bus account 1", writable)]
#[account(4, name = "bus_2", desc = "Ore bus account 2", writable)]
#[account(5, name = "bus_3", desc = "Ore bus account 3", writable)]
#[account(6, name = "bus_4", desc = "Ore bus account 4", writable)]
#[account(7, name = "bus_5", desc = "Ore bus account 5", writable)]
#[account(8, name = "bus_6", desc = "Ore bus account 6", writable)]
#[account(9, name = "bus_7", desc = "Ore bus account 7", writable)]
#[account(10, name = "metadata", desc = "Ore mint metadata account", writable)]
#[account(11, name = "mint", desc = "Ore mint account", writable)]
#[account(12, name = "noise", desc = "Ore noise account", writable)]
#[account(13, name = "treasury", desc = "Ore treasury account", writable)]
#[account(14, name = "treasury_tokens", desc = "Ore treasury token account", writable)]
#[account(15, name = "system_program", desc = "Solana system program")]
#[account(16, name = "token_program", desc = "SPL token program")]
#[account(17, name = "associated_token_program", desc = "SPL associated token program")]
#[account(18, name = "mpl_metadata_program", desc = "Metaplex metadata program")]
#[account(19, name = "rent", desc = "Solana rent sysvar")]
Initialize = 100,
}
impl OreInstruction {
pub fn to_vec(&self) -> Vec<u8> {
vec![*self as u8]
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct InitializeArgs {
pub bus_0_bump: u8,
pub bus_1_bump: u8,
pub bus_2_bump: u8,
pub bus_3_bump: u8,
pub bus_4_bump: u8,
pub bus_5_bump: u8,
pub bus_6_bump: u8,
pub bus_7_bump: u8,
pub config_bump: u8,
pub metadata_bump: u8,
pub mint_bump: u8,
pub treasury_bump: u8,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct OpenArgs {
pub bump: u8,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct MineArgs {
pub digest: [u8; 16],
pub nonce: [u8; 8],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct ClaimArgs {
pub amount: [u8; 8],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct StakeArgs {
pub amount: [u8; 8],
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct UpgradeArgs {
pub amount: [u8; 8],
}
impl_to_bytes!(InitializeArgs);
impl_to_bytes!(OpenArgs);
impl_to_bytes!(MineArgs);
impl_to_bytes!(ClaimArgs);
impl_to_bytes!(StakeArgs);
impl_to_bytes!(UpgradeArgs);
impl_instruction_from_bytes!(InitializeArgs);
impl_instruction_from_bytes!(OpenArgs);
impl_instruction_from_bytes!(MineArgs);
impl_instruction_from_bytes!(ClaimArgs);
impl_instruction_from_bytes!(StakeArgs);
impl_instruction_from_bytes!(UpgradeArgs);
/// Builds a claim instruction.
pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction {
let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0;
let treasury_tokens = spl_associated_token_account::get_associated_token_address(
&TREASURY_ADDRESS,
&MINT_ADDRESS,
);
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(beneficiary, false),
AccountMeta::new(MINT_ADDRESS, false),
AccountMeta::new(proof, false),
AccountMeta::new_readonly(TREASURY_ADDRESS, false),
AccountMeta::new(treasury_tokens, false),
AccountMeta::new_readonly(spl_token::id(), false),
],
data: [
OreInstruction::Claim.to_vec(),
ClaimArgs {
amount: amount.to_le_bytes(),
}
.to_bytes()
.to_vec(),
]
.concat(),
}
}
/// Builds a close instruction.
pub fn close(signer: Pubkey) -> Instruction {
let proof_pda = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id());
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(proof_pda.0, false),
AccountMeta::new_readonly(solana_program::system_program::id(), false),
],
data: OreInstruction::Close.to_vec(),
}
}
/// Builds a mine instruction.
pub fn mine(signer: Pubkey, bus: Pubkey, solution: Solution) -> Instruction {
let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0;
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(bus, false),
AccountMeta::new_readonly(CONFIG_ADDRESS, false),
AccountMeta::new(proof, false),
AccountMeta::new_readonly(sysvar::instructions::id(), false),
AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
],
data: [
OreInstruction::Mine.to_vec(),
MineArgs {
digest: solution.d,
nonce: solution.n,
}
.to_bytes()
.to_vec(),
]
.concat(),
}
}
/// Builds an open instruction.
pub fn open(signer: Pubkey, miner: Pubkey, payer: Pubkey) -> Instruction {
let proof_pda = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id());
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(payer, true),
AccountMeta::new_readonly(miner, false),
AccountMeta::new(proof_pda.0, false),
AccountMeta::new_readonly(solana_program::system_program::id(), false),
AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
],
data: [
OreInstruction::Open.to_vec(),
OpenArgs { bump: proof_pda.1 }.to_bytes().to_vec(),
]
.concat(),
}
}
/// Builds a reset instruction.
pub fn reset(signer: Pubkey) -> Instruction {
let treasury_tokens = spl_associated_token_account::get_associated_token_address(
&TREASURY_ADDRESS,
&MINT_ADDRESS,
);
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(BUS_ADDRESSES[0], false),
AccountMeta::new(BUS_ADDRESSES[1], false),
AccountMeta::new(BUS_ADDRESSES[2], false),
AccountMeta::new(BUS_ADDRESSES[3], false),
AccountMeta::new(BUS_ADDRESSES[4], false),
AccountMeta::new(BUS_ADDRESSES[5], false),
AccountMeta::new(BUS_ADDRESSES[6], false),
AccountMeta::new(BUS_ADDRESSES[7], false),
AccountMeta::new(CONFIG_ADDRESS, false),
AccountMeta::new(MINT_ADDRESS, false),
AccountMeta::new(TREASURY_ADDRESS, false),
AccountMeta::new(treasury_tokens, false),
AccountMeta::new_readonly(spl_token::id(), false),
],
data: OreInstruction::Reset.to_vec(),
}
}
/// Build a stake instruction.
pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction {
let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0;
let treasury_tokens = spl_associated_token_account::get_associated_token_address(
&TREASURY_ADDRESS,
&MINT_ADDRESS,
);
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(proof, false),
AccountMeta::new(sender, false),
AccountMeta::new(treasury_tokens, false),
AccountMeta::new_readonly(spl_token::id(), false),
],
data: [
OreInstruction::Stake.to_vec(),
StakeArgs {
amount: amount.to_le_bytes(),
}
.to_bytes()
.to_vec(),
]
.concat(),
}
}
// Build an update instruction.
pub fn update(signer: Pubkey, miner: Pubkey) -> Instruction {
let proof = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &crate::id()).0;
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new_readonly(miner, false),
AccountMeta::new(proof, false),
],
data: OreInstruction::Update.to_vec(),
}
}
// Build an upgrade instruction.
pub fn upgrade(signer: Pubkey, beneficiary: Pubkey, sender: Pubkey, amount: u64) -> Instruction {
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(beneficiary, false),
AccountMeta::new(MINT_ADDRESS, false),
AccountMeta::new(MINT_V1_ADDRESS, false),
AccountMeta::new(sender, false),
AccountMeta::new(TREASURY_ADDRESS, false),
AccountMeta::new_readonly(spl_token::id(), false),
],
data: [
OreInstruction::Upgrade.to_vec(),
UpgradeArgs {
amount: amount.to_le_bytes(),
}
.to_bytes()
.to_vec(),
]
.concat(),
}
}
/// Builds an initialize instruction.
pub fn initialize(signer: Pubkey) -> Instruction {
let bus_pdas = [
Pubkey::find_program_address(&[BUS, &[0]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[1]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[2]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[3]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[4]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[5]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[6]], &crate::id()),
Pubkey::find_program_address(&[BUS, &[7]], &crate::id()),
];
let config_pda = Pubkey::find_program_address(&[CONFIG], &crate::id());
let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::id());
let treasury_pda = Pubkey::find_program_address(&[TREASURY], &crate::id());
let treasury_tokens =
spl_associated_token_account::get_associated_token_address(&treasury_pda.0, &mint_pda.0);
let metadata_pda = Pubkey::find_program_address(
&[
METADATA,
mpl_token_metadata::ID.as_ref(),
mint_pda.0.as_ref(),
],
&mpl_token_metadata::ID,
);
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(bus_pdas[0].0, false),
AccountMeta::new(bus_pdas[1].0, false),
AccountMeta::new(bus_pdas[2].0, false),
AccountMeta::new(bus_pdas[3].0, false),
AccountMeta::new(bus_pdas[4].0, false),
AccountMeta::new(bus_pdas[5].0, false),
AccountMeta::new(bus_pdas[6].0, false),
AccountMeta::new(bus_pdas[7].0, false),
AccountMeta::new(config_pda.0, false),
AccountMeta::new(metadata_pda.0, false),
AccountMeta::new(mint_pda.0, false),
AccountMeta::new(treasury_pda.0, false),
AccountMeta::new(treasury_tokens, false),
AccountMeta::new_readonly(system_program::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(spl_associated_token_account::id(), false),
AccountMeta::new_readonly(mpl_token_metadata::ID, false),
AccountMeta::new_readonly(sysvar::rent::id(), false),
],
data: [
OreInstruction::Initialize.to_vec(),
InitializeArgs {
bus_0_bump: bus_pdas[0].1,
bus_1_bump: bus_pdas[1].1,
bus_2_bump: bus_pdas[2].1,
bus_3_bump: bus_pdas[3].1,
bus_4_bump: bus_pdas[4].1,
bus_5_bump: bus_pdas[5].1,
bus_6_bump: bus_pdas[6].1,
bus_7_bump: bus_pdas[7].1,
config_bump: config_pda.1,
metadata_bump: metadata_pda.1,
mint_bump: mint_pda.1,
treasury_bump: treasury_pda.1,
}
.to_bytes()
.to_vec(),
]
.concat(),
}
}