ore_relayer_api/
instruction.rs

1use bytemuck::{Pod, Zeroable};
2use num_enum::TryFromPrimitive;
3use ore_api::consts::*;
4use ore_utils::{impl_instruction_from_bytes, impl_to_bytes};
5use solana_program::{
6    instruction::{AccountMeta, Instruction},
7    pubkey::Pubkey,
8    system_program, sysvar,
9};
10
11use crate::consts::*;
12
13#[repr(u8)]
14#[derive(Clone, Copy, Debug, Eq, PartialEq,  TryFromPrimitive)]
15#[rustfmt::skip]
16pub enum RelayInstruction {
17    Claim = 0, 
18    CloseEscrow = 1,
19    OpenEscrow = 2,
20    Stake = 3,
21    Migrate = 4,
22
23    Collect = 101, 
24    UpdateMiner = 102, 
25}
26
27#[repr(C)]
28#[derive(Clone, Copy, Debug, Pod, Zeroable)]
29pub struct ClaimArgs {
30    pub amount: [u8; 8],
31}
32
33#[repr(C)]
34#[derive(Clone, Copy, Debug, Pod, Zeroable)]
35pub struct CollectArgs {
36    pub fee: [u8; 8],
37}
38
39#[repr(C)]
40#[derive(Clone, Copy, Debug, Pod, Zeroable)]
41pub struct OpenEscrowArgs {
42    pub escrow_bump: u8,
43    pub proof_bump: u8,
44}
45
46#[repr(C)]
47#[derive(Clone, Copy, Debug, Pod, Zeroable)]
48pub struct MigrateArgs {
49    pub proof_bump: u8,
50}
51
52#[repr(C)]
53#[derive(Clone, Copy, Debug, Pod, Zeroable)]
54pub struct StakeArgs {
55    pub amount: [u8; 8],
56}
57
58impl RelayInstruction {
59    pub fn to_vec(&self) -> Vec<u8> {
60        vec![*self as u8]
61    }
62}
63
64impl_to_bytes!(ClaimArgs);
65impl_to_bytes!(CollectArgs);
66impl_to_bytes!(OpenEscrowArgs);
67impl_to_bytes!(MigrateArgs);
68impl_to_bytes!(StakeArgs);
69
70impl_instruction_from_bytes!(ClaimArgs);
71impl_instruction_from_bytes!(CollectArgs);
72impl_instruction_from_bytes!(OpenEscrowArgs);
73impl_instruction_from_bytes!(MigrateArgs);
74impl_instruction_from_bytes!(StakeArgs);
75
76// Builds a collect instruction.
77pub fn collect(
78    signer: Pubkey,
79    escrow_authority: Pubkey,
80    beneficiary: Pubkey,
81    sol_fee: u64,
82) -> Instruction {
83    let (escrow_pda, _) =
84        Pubkey::find_program_address(&[ESCROW, escrow_authority.as_ref()], &crate::id());
85    let (proof_pda, _) =
86        Pubkey::find_program_address(&[PROOF, escrow_pda.as_ref()], &ore_api::id());
87    Instruction {
88        program_id: crate::id(),
89        accounts: vec![
90            AccountMeta::new(signer, true),
91            AccountMeta::new(beneficiary, false),
92            AccountMeta::new(escrow_pda, false),
93            AccountMeta::new(proof_pda, false),
94            AccountMeta::new_readonly(ore_api::consts::TREASURY_ADDRESS, false),
95            AccountMeta::new(ore_api::consts::TREASURY_TOKENS_ADDRESS, false),
96            AccountMeta::new_readonly(ore_api::id(), false),
97            AccountMeta::new_readonly(spl_token::id(), false),
98        ],
99        data: vec![
100            RelayInstruction::Collect.to_vec(),
101            CollectArgs {
102                fee: sol_fee.to_le_bytes(),
103            }
104            .to_bytes()
105            .to_vec(),
106        ]
107        .concat(),
108    }
109}
110
111// Builds a claim instruction.
112pub fn claim(signer: Pubkey, beneficiary: Pubkey, amount: u64) -> Instruction {
113    let (escrow_pda, _) = Pubkey::find_program_address(&[ESCROW, signer.as_ref()], &crate::id());
114    let (proof_pda, _) =
115        Pubkey::find_program_address(&[PROOF, escrow_pda.as_ref()], &ore_api::id());
116    Instruction {
117        program_id: crate::id(),
118        accounts: vec![
119            AccountMeta::new(signer, true),
120            AccountMeta::new(beneficiary, false),
121            AccountMeta::new(escrow_pda, false),
122            AccountMeta::new(proof_pda, false),
123            AccountMeta::new_readonly(ore_api::consts::TREASURY_ADDRESS, false),
124            AccountMeta::new(ore_api::consts::TREASURY_TOKENS_ADDRESS, false),
125            AccountMeta::new_readonly(ore_api::id(), false),
126            AccountMeta::new_readonly(spl_token::id(), false),
127        ],
128        data: [
129            RelayInstruction::Claim.to_vec(),
130            ClaimArgs {
131                amount: amount.to_le_bytes(),
132            }
133            .to_bytes()
134            .to_vec(),
135        ]
136        .concat(),
137    }
138}
139
140// Builds a stake instruction.
141pub fn stake(signer: Pubkey, sender: Pubkey, amount: u64) -> Instruction {
142    let (escrow_pda, _) = Pubkey::find_program_address(&[ESCROW, signer.as_ref()], &crate::id());
143    let escrow_tokens =
144        spl_associated_token_account::get_associated_token_address(&escrow_pda, &MINT_ADDRESS);
145    let (proof_pda, _) =
146        Pubkey::find_program_address(&[PROOF, escrow_pda.as_ref()], &ore_api::id());
147    Instruction {
148        program_id: crate::id(),
149        accounts: vec![
150            AccountMeta::new(signer, true),
151            AccountMeta::new(escrow_pda, false),
152            AccountMeta::new(escrow_tokens, false),
153            AccountMeta::new(proof_pda, false),
154            AccountMeta::new(sender, false),
155            AccountMeta::new(ore_api::consts::TREASURY_TOKENS_ADDRESS, false),
156            AccountMeta::new_readonly(ore_api::id(), false),
157            AccountMeta::new_readonly(spl_token::id(), false),
158        ],
159        data: [
160            RelayInstruction::Stake.to_vec(),
161            StakeArgs {
162                amount: amount.to_le_bytes(),
163            }
164            .to_bytes()
165            .to_vec(),
166        ]
167        .concat(),
168    }
169}
170
171// Builds an open_escrow instruction.
172pub fn open_escrow(signer: Pubkey, payer: Pubkey) -> Instruction {
173    let escrow_pda = Pubkey::find_program_address(&[ESCROW, signer.as_ref()], &crate::id());
174    let proof_pda = Pubkey::find_program_address(&[PROOF, escrow_pda.0.as_ref()], &ore_api::id());
175    let escrow_tokens_address =
176        spl_associated_token_account::get_associated_token_address(&escrow_pda.0, &MINT_ADDRESS);
177    Instruction {
178        program_id: crate::id(),
179        accounts: vec![
180            AccountMeta::new(signer, true),
181            AccountMeta::new_readonly(signer, false),
182            AccountMeta::new(payer, true),
183            AccountMeta::new(escrow_pda.0, false),
184            AccountMeta::new(escrow_tokens_address, false),
185            AccountMeta::new_readonly(MINT_ADDRESS, false),
186            AccountMeta::new(proof_pda.0, false),
187            AccountMeta::new_readonly(ore_api::id(), false),
188            AccountMeta::new_readonly(system_program::id(), false),
189            AccountMeta::new_readonly(spl_token::id(), false),
190            AccountMeta::new_readonly(spl_associated_token_account::id(), false),
191            AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
192        ],
193        data: [
194            RelayInstruction::OpenEscrow.to_vec(),
195            OpenEscrowArgs {
196                escrow_bump: escrow_pda.1,
197                proof_bump: proof_pda.1,
198            }
199            .to_bytes()
200            .to_vec(),
201        ]
202        .concat(),
203    }
204}
205
206// Builds an update_miner instruction.
207pub fn update_miner(signer: Pubkey, miner: Pubkey) -> Instruction {
208    let escrow_pda = Pubkey::find_program_address(&[ESCROW, signer.as_ref()], &crate::id());
209    let proof_pda = Pubkey::find_program_address(&[PROOF, escrow_pda.0.as_ref()], &ore_api::id());
210    Instruction {
211        program_id: crate::id(),
212        accounts: vec![
213            AccountMeta::new(signer, true),
214            AccountMeta::new(escrow_pda.0, false),
215            AccountMeta::new_readonly(miner, false),
216            AccountMeta::new(proof_pda.0, false),
217            AccountMeta::new_readonly(ore_api::id(), false),
218        ],
219        data: RelayInstruction::UpdateMiner.to_vec(),
220    }
221}
222
223// Builds an migrate instruction.
224// let [signer, signer_tokens_info, miner_info, payer, escrow_info, escrow_proof_info, escrow_tokens_info, mint_info, proof_info, treasury_info, treasury_tokens_info, ore_program, system_program, token_program, associated_token_program, slot_hashes_sysvar] =
225pub fn migrate(signer: Pubkey, payer: Pubkey, miner: Pubkey) -> Instruction {
226    let escrow_pda = Pubkey::find_program_address(&[ESCROW, signer.as_ref()], &crate::id());
227    let escrow_proof_pda =
228        Pubkey::find_program_address(&[PROOF, escrow_pda.0.as_ref()], &ore_api::id());
229    let escrow_tokens_address =
230        spl_associated_token_account::get_associated_token_address(&escrow_pda.0, &MINT_ADDRESS);
231    let proof_pda = Pubkey::find_program_address(&[PROOF, signer.as_ref()], &ore_api::id());
232    let signer_tokens_address =
233        spl_associated_token_account::get_associated_token_address(&signer, &MINT_ADDRESS);
234    Instruction {
235        program_id: crate::id(),
236        accounts: vec![
237            AccountMeta::new(signer, true),
238            AccountMeta::new(signer_tokens_address, false),
239            AccountMeta::new_readonly(miner, false),
240            AccountMeta::new(payer, true),
241            AccountMeta::new(escrow_pda.0, false),
242            AccountMeta::new(escrow_proof_pda.0, false),
243            AccountMeta::new(escrow_tokens_address, false),
244            AccountMeta::new_readonly(MINT_ADDRESS, false),
245            AccountMeta::new(proof_pda.0, false),
246            AccountMeta::new_readonly(ore_api::consts::TREASURY_ADDRESS, false),
247            AccountMeta::new(ore_api::consts::TREASURY_TOKENS_ADDRESS, false),
248            AccountMeta::new_readonly(ore_api::id(), false),
249            AccountMeta::new_readonly(system_program::id(), false),
250            AccountMeta::new_readonly(spl_token::id(), false),
251            AccountMeta::new_readonly(spl_associated_token_account::id(), false),
252            AccountMeta::new_readonly(sysvar::slot_hashes::id(), false),
253        ],
254        data: [
255            RelayInstruction::Migrate.to_vec(),
256            MigrateArgs {
257                proof_bump: proof_pda.1,
258            }
259            .to_bytes()
260            .to_vec(),
261        ]
262        .concat(),
263    }
264}