1use crate::instructions::{
9 CancelPublicAutomation, ClaimUsd, ClaimUsdInstructionArgs, CreateBoard, CreateEpochVault, CreateOneBtcVault,
10 CreatePublicAutomation, CreatePublicAutomationInstructionArgs, CreateSatrushConfig,
11 CreateSatrushConfigInstructionArgs, CreateSatsVault, CreateTreasury, DeployPublic, DeployPublicInstructionArgs,
12 ExecutePublicAutomation, ExecutePublicAutomationInstructionArgs, RotateRound, SettleDeployPublic, SwapRoundStake,
13 SwapRoundStakeInstructionArgs, TopUpPublicAutomation, TopUpPublicAutomationInstructionArgs,
14 UpdateBoardRoundDuration, UpdateBoardRoundDurationInstructionArgs,
15};
16use crate::types::AutomationStrategy;
17use crate::{
18 get_board_address, get_epoch_vault_address, get_epoch_vault_iteration_address, get_event_authority_address,
19 get_miner_address, get_one_btc_vault_address, get_one_btc_vault_iteration_address, get_public_automation_address,
20 get_public_deployment_address, get_round_address, get_satrush_config_address, get_sats_vault_address,
21 get_treasury_address,
22};
23use solana_instruction::{AccountMeta, Instruction};
24use solana_pubkey::Pubkey;
25
26pub const TOKEN_PROGRAM_ID: Pubkey = Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
28pub const ASSOCIATED_TOKEN_PROGRAM_ID: Pubkey = Pubkey::from_str_const("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
30pub const SYSTEM_PROGRAM_ID: Pubkey = Pubkey::from_str_const("11111111111111111111111111111111");
32pub const SLOT_HASHES_ID: Pubkey = Pubkey::from_str_const("SysvarS1otHashes111111111111111111111111111");
34
35pub fn get_associated_token_address(wallet: &Pubkey, mint: &Pubkey) -> Pubkey {
37 Pubkey::find_program_address(
38 &[wallet.as_ref(), TOKEN_PROGRAM_ID.as_ref(), mint.as_ref()],
39 &ASSOCIATED_TOKEN_PROGRAM_ID,
40 )
41 .0
42}
43
44pub fn get_create_satrush_config_instruction(
47 authority: Pubkey,
48 args: CreateSatrushConfigInstructionArgs,
49) -> Instruction {
50 CreateSatrushConfig {
51 authority,
52 satrush_config: get_satrush_config_address().0,
53 system_program: SYSTEM_PROGRAM_ID,
54 }
55 .instruction(args)
56}
57
58pub fn get_create_board_instruction(authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Instruction {
61 let board = get_board_address().0;
62 CreateBoard {
63 authority,
64 satrush_config: get_satrush_config_address().0,
65 board,
66 initial_round: get_round_address(1).0,
67 usd_mint,
68 btc_mint,
69 board_usd_ata: get_associated_token_address(&board, &usd_mint),
70 board_btc_ata: get_associated_token_address(&board, &btc_mint),
71 token_program: TOKEN_PROGRAM_ID,
72 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
73 system_program: SYSTEM_PROGRAM_ID,
74 }
75 .instruction()
76}
77
78pub fn get_update_board_round_duration_instruction(authority: Pubkey, new_round_duration: u32) -> Instruction {
82 UpdateBoardRoundDuration {
83 authority,
84 satrush_config: get_satrush_config_address().0,
85 board: get_board_address().0,
86 }
87 .instruction(UpdateBoardRoundDurationInstructionArgs { new_round_duration })
88}
89
90pub fn get_create_epoch_vault_instruction(authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Instruction {
93 let epoch_vault = get_epoch_vault_address().0;
94 CreateEpochVault {
95 authority,
96 satrush_config: get_satrush_config_address().0,
97 epoch_vault,
98 epoch_vault_iteration: get_epoch_vault_iteration_address(1).0,
99 usd_mint,
100 btc_mint,
101 epoch_vault_usd_ata: get_associated_token_address(&epoch_vault, &usd_mint),
102 epoch_vault_btc_ata: get_associated_token_address(&epoch_vault, &btc_mint),
103 token_program: TOKEN_PROGRAM_ID,
104 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
105 system_program: SYSTEM_PROGRAM_ID,
106 }
107 .instruction()
108}
109
110pub fn get_create_one_btc_vault_instruction(authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Instruction {
113 let one_btc_vault = get_one_btc_vault_address().0;
114 CreateOneBtcVault {
115 authority,
116 satrush_config: get_satrush_config_address().0,
117 one_btc_vault,
118 one_btc_vault_iteration: get_one_btc_vault_iteration_address(1).0,
119 usd_mint,
120 btc_mint,
121 one_btc_vault_usd_ata: get_associated_token_address(&one_btc_vault, &usd_mint),
122 one_btc_vault_btc_ata: get_associated_token_address(&one_btc_vault, &btc_mint),
123 token_program: TOKEN_PROGRAM_ID,
124 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
125 system_program: SYSTEM_PROGRAM_ID,
126 }
127 .instruction()
128}
129
130pub fn get_create_treasury_instruction(authority: Pubkey, usd_mint: Pubkey) -> Instruction {
132 let treasury = get_treasury_address().0;
133 CreateTreasury {
134 authority,
135 satrush_config: get_satrush_config_address().0,
136 treasury,
137 usd_mint,
138 treasury_usd_ata: get_associated_token_address(&treasury, &usd_mint),
139 token_program: TOKEN_PROGRAM_ID,
140 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
141 system_program: SYSTEM_PROGRAM_ID,
142 }
143 .instruction()
144}
145
146pub fn get_deploy_public_instruction(
151 authority: Pubkey,
152 usd_mint: Pubkey,
153 round_id: u32,
154 selection_mask: u32,
155 amount: u64,
156) -> Instruction {
157 let board = get_board_address().0;
158 let epoch_vault = get_epoch_vault_address().0;
159 let one_btc_vault = get_one_btc_vault_address().0;
160 let treasury = get_treasury_address().0;
161
162 DeployPublic {
163 authority,
164 satrush_config: get_satrush_config_address().0,
165 board,
166 usd_mint,
167 board_usd_ata: get_associated_token_address(&board, &usd_mint),
168 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
169 round: get_round_address(round_id).0,
170 public_deployment: get_public_deployment_address(authority, round_id).0,
171 miner: get_miner_address(authority).0,
172 epoch_vault,
173 epoch_vault_usd_ata: get_associated_token_address(&epoch_vault, &usd_mint),
174 one_btc_vault,
175 one_btc_vault_usd_ata: get_associated_token_address(&one_btc_vault, &usd_mint),
176 treasury,
177 treasury_usd_ata: get_associated_token_address(&treasury, &usd_mint),
178 token_program: TOKEN_PROGRAM_ID,
179 system_program: SYSTEM_PROGRAM_ID,
180 }
181 .instruction(DeployPublicInstructionArgs { selection_mask, amount })
182}
183
184pub fn get_rotate_round_instruction(authority: Pubkey, current_round_id: u32) -> Instruction {
188 RotateRound {
189 authority,
190 satrush_config: get_satrush_config_address().0,
191 board: get_board_address().0,
192 current_round: get_round_address(current_round_id).0,
193 next_round: get_round_address(current_round_id + 1).0,
194 slot_hashes: SLOT_HASHES_ID,
195 system_program: SYSTEM_PROGRAM_ID,
196 event_authority: get_event_authority_address().0,
197 program: crate::SATRUSH_ID,
198 }
199 .instruction()
200}
201
202#[allow(clippy::too_many_arguments)]
208pub fn get_swap_round_stake_instruction(
209 authority: Pubkey,
210 usd_mint: Pubkey,
211 btc_mint: Pubkey,
212 round_id: u32,
213 min_btc_out: u64,
214 swap_program: Pubkey,
215 swap_data: Vec<u8>,
216 route_accounts: &[AccountMeta],
217) -> Instruction {
218 let board = get_board_address().0;
219 SwapRoundStake {
220 authority,
221 satrush_config: get_satrush_config_address().0,
222 board,
223 round: get_round_address(round_id).0,
224 usd_mint,
225 btc_mint,
226 board_usd_ata: get_associated_token_address(&board, &usd_mint),
227 board_btc_ata: get_associated_token_address(&board, &btc_mint),
228 swap_program,
229 token_program: TOKEN_PROGRAM_ID,
230 event_authority: get_event_authority_address().0,
231 program: crate::SATRUSH_ID,
232 }
233 .instruction_with_remaining_accounts(SwapRoundStakeInstructionArgs { min_btc_out, swap_data }, route_accounts)
234}
235
236pub fn get_settle_deploy_public_instruction(
241 authority: Pubkey,
242 deployment_authority: Pubkey,
243 rent_recipient: Pubkey,
244 usd_mint: Pubkey,
245 btc_mint: Pubkey,
246 round_id: u32,
247) -> Instruction {
248 let board = get_board_address().0;
249 let sats_vault = get_sats_vault_address().0;
250 let public_automation = get_public_automation_address(deployment_authority).0;
251 SettleDeployPublic {
252 authority,
253 rent_recipient,
254 satrush_config: get_satrush_config_address().0,
255 round: get_round_address(round_id).0,
256 board,
257 public_deployment: get_public_deployment_address(deployment_authority, round_id).0,
258 miner: get_miner_address(deployment_authority).0,
259 public_automation,
260 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
261 board_usd_ata: get_associated_token_address(&board, &usd_mint),
262 sats_vault,
263 btc_mint,
264 usd_mint,
265 board_btc_ata: get_associated_token_address(&board, &btc_mint),
266 sats_vault_btc_ata: get_associated_token_address(&sats_vault, &btc_mint),
267 token_program: TOKEN_PROGRAM_ID,
268 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
269 system_program: SYSTEM_PROGRAM_ID,
270 event_authority: get_event_authority_address().0,
271 program: crate::SATRUSH_ID,
272 }
273 .instruction()
274}
275
276#[allow(clippy::too_many_arguments)]
280pub fn get_create_public_automation_instruction(
281 authority: Pubkey,
282 usd_mint: Pubkey,
283 strategy: AutomationStrategy,
284 selection_mask: u32,
285 per_round_usd_amount: u64,
286 reload: bool,
287 deposit_usd_amount: u64,
288) -> Instruction {
289 let public_automation = get_public_automation_address(authority).0;
290 CreatePublicAutomation {
291 authority,
292 satrush_config: get_satrush_config_address().0,
293 public_automation,
294 usd_mint,
295 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
296 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
297 miner: get_miner_address(authority).0,
298 token_program: TOKEN_PROGRAM_ID,
299 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
300 system_program: SYSTEM_PROGRAM_ID,
301 }
302 .instruction(CreatePublicAutomationInstructionArgs {
303 strategy,
304 selection_mask,
305 per_round_usd_amount,
306 reload,
307 deposit_usd_amount,
308 })
309}
310
311pub fn get_top_up_public_automation_instruction(authority: Pubkey, usd_mint: Pubkey, amount: u64) -> Instruction {
314 let public_automation = get_public_automation_address(authority).0;
315 TopUpPublicAutomation {
316 authority,
317 satrush_config: get_satrush_config_address().0,
318 public_automation,
319 usd_mint,
320 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
321 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
322 token_program: TOKEN_PROGRAM_ID,
323 }
324 .instruction(TopUpPublicAutomationInstructionArgs { amount })
325}
326
327pub fn get_cancel_public_automation_instruction(authority: Pubkey, usd_mint: Pubkey) -> Instruction {
331 let public_automation = get_public_automation_address(authority).0;
332 CancelPublicAutomation {
333 authority,
334 satrush_config: get_satrush_config_address().0,
335 public_automation,
336 usd_mint,
337 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
338 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
339 token_program: TOKEN_PROGRAM_ID,
340 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
341 system_program: SYSTEM_PROGRAM_ID,
342 }
343 .instruction()
344}
345
346pub fn get_execute_public_automation_instruction(
350 crank_authority: Pubkey,
351 automation_authority: Pubkey,
352 usd_mint: Pubkey,
353 round_id: u32,
354 selection_mask: Option<u32>,
355) -> Instruction {
356 let board = get_board_address().0;
357 let epoch_vault = get_epoch_vault_address().0;
358 let one_btc_vault = get_one_btc_vault_address().0;
359 let treasury = get_treasury_address().0;
360 let public_automation = get_public_automation_address(automation_authority).0;
361
362 ExecutePublicAutomation {
363 authority: crank_authority,
364 satrush_config: get_satrush_config_address().0,
365 board,
366 round: get_round_address(round_id).0,
367 public_automation,
368 usd_mint,
369 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
370 board_usd_ata: get_associated_token_address(&board, &usd_mint),
371 public_deployment: get_public_deployment_address(automation_authority, round_id).0,
372 miner: get_miner_address(automation_authority).0,
373 epoch_vault,
374 epoch_vault_usd_ata: get_associated_token_address(&epoch_vault, &usd_mint),
375 one_btc_vault,
376 one_btc_vault_usd_ata: get_associated_token_address(&one_btc_vault, &usd_mint),
377 treasury,
378 treasury_usd_ata: get_associated_token_address(&treasury, &usd_mint),
379 slot_hashes: SLOT_HASHES_ID,
380 token_program: TOKEN_PROGRAM_ID,
381 system_program: SYSTEM_PROGRAM_ID,
382 }
383 .instruction(ExecutePublicAutomationInstructionArgs { selection_mask })
384}
385
386pub fn get_claim_usd_instruction(authority: Pubkey, usd_mint: Pubkey, amount: u64) -> Instruction {
390 let board = get_board_address().0;
391 ClaimUsd {
392 authority,
393 satrush_config: get_satrush_config_address().0,
394 board,
395 miner: get_miner_address(authority).0,
396 usd_mint,
397 board_usd_ata: get_associated_token_address(&board, &usd_mint),
398 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
399 token_program: TOKEN_PROGRAM_ID,
400 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
401 system_program: SYSTEM_PROGRAM_ID,
402 }
403 .instruction(ClaimUsdInstructionArgs { amount })
404}
405
406pub fn get_create_sats_vault_instruction(authority: Pubkey, btc_mint: Pubkey) -> Instruction {
408 let sats_vault = get_sats_vault_address().0;
409 CreateSatsVault {
410 authority,
411 satrush_config: get_satrush_config_address().0,
412 sats_vault,
413 btc_mint,
414 sats_vault_btc_ata: get_associated_token_address(&sats_vault, &btc_mint),
415 token_program: TOKEN_PROGRAM_ID,
416 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
417 system_program: SYSTEM_PROGRAM_ID,
418 }
419 .instruction()
420}