1use crate::instructions::{
9 CancelPublicAutomation, ClaimUsd, ClaimUsdInstructionArgs, CloseRound, CreateBoard, CreateEpochVault,
10 CreateOneBtcVault, CreatePublicAutomation, CreatePublicAutomationInstructionArgs, CreateSatrushConfig,
11 CreateSatrushConfigInstructionArgs, CreateSatsVault, CreateTreasury, DeployPublic, DeployPublicInstructionArgs,
12 ExecutePublicAutomation, ExecutePublicAutomationInstructionArgs, RotateRound, SettleDeployPublic, SwapRoundStake,
13 SwapRoundStakeInstructionArgs, TopUpPublicAutomation, TopUpPublicAutomationInstructionArgs,
14 UpdateBoardRoundDuration, UpdateBoardRoundDurationInstructionArgs, UpdateDeploymentSettleGraceDuration,
15 UpdateDeploymentSettleGraceDurationInstructionArgs, UpdateEpochVaultIterationDuration,
16 UpdateEpochVaultIterationDurationInstructionArgs, UpdateMinDeployUsdAmount,
17 UpdateMinDeployUsdAmountInstructionArgs, UpdateUnclaimedHashrateBps, UpdateUnclaimedHashrateBpsInstructionArgs,
18};
19use crate::types::AutomationStrategy;
20use crate::{
21 get_board_address, get_epoch_vault_address, get_epoch_vault_iteration_address, get_event_authority_address,
22 get_miner_address, get_one_btc_vault_address, get_one_btc_vault_iteration_address, get_public_automation_address,
23 get_public_deployment_address, get_round_address, get_satrush_config_address, get_sats_vault_address,
24 get_treasury_address,
25};
26use solana_instruction::{AccountMeta, Instruction};
27use solana_pubkey::Pubkey;
28
29pub const TOKEN_PROGRAM_ID: Pubkey = Pubkey::from_str_const("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
31pub const ASSOCIATED_TOKEN_PROGRAM_ID: Pubkey = Pubkey::from_str_const("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
33pub const SYSTEM_PROGRAM_ID: Pubkey = Pubkey::from_str_const("11111111111111111111111111111111");
35pub const SLOT_HASHES_ID: Pubkey = Pubkey::from_str_const("SysvarS1otHashes111111111111111111111111111");
37
38pub fn get_associated_token_address(wallet: &Pubkey, mint: &Pubkey) -> Pubkey {
40 Pubkey::find_program_address(
41 &[wallet.as_ref(), TOKEN_PROGRAM_ID.as_ref(), mint.as_ref()],
42 &ASSOCIATED_TOKEN_PROGRAM_ID,
43 )
44 .0
45}
46
47pub fn get_create_satrush_config_instruction(
50 authority: Pubkey,
51 args: CreateSatrushConfigInstructionArgs,
52) -> Instruction {
53 CreateSatrushConfig {
54 authority,
55 satrush_config: get_satrush_config_address().0,
56 system_program: SYSTEM_PROGRAM_ID,
57 }
58 .instruction(args)
59}
60
61pub fn get_create_board_instruction(authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Instruction {
64 let board = get_board_address().0;
65 CreateBoard {
66 authority,
67 satrush_config: get_satrush_config_address().0,
68 board,
69 initial_round: get_round_address(1).0,
70 usd_mint,
71 btc_mint,
72 board_usd_ata: get_associated_token_address(&board, &usd_mint),
73 board_btc_ata: get_associated_token_address(&board, &btc_mint),
74 token_program: TOKEN_PROGRAM_ID,
75 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
76 system_program: SYSTEM_PROGRAM_ID,
77 }
78 .instruction()
79}
80
81pub fn get_update_board_round_duration_instruction(authority: Pubkey, new_round_duration: u32) -> Instruction {
85 UpdateBoardRoundDuration {
86 authority,
87 satrush_config: get_satrush_config_address().0,
88 board: get_board_address().0,
89 }
90 .instruction(UpdateBoardRoundDurationInstructionArgs { new_round_duration })
91}
92
93pub fn get_update_min_deploy_usd_amount_instruction(authority: Pubkey, new_min_deploy_usd_amount: u64) -> Instruction {
98 UpdateMinDeployUsdAmount {
99 authority,
100 satrush_config: get_satrush_config_address().0,
101 }
102 .instruction(UpdateMinDeployUsdAmountInstructionArgs {
103 new_min_deploy_usd_amount,
104 })
105}
106
107pub fn get_update_unclaimed_hashrate_bps_instruction(
111 authority: Pubkey,
112 new_unclaimed_hashrate_bps: u32,
113) -> Instruction {
114 UpdateUnclaimedHashrateBps {
115 authority,
116 satrush_config: get_satrush_config_address().0,
117 }
118 .instruction(UpdateUnclaimedHashrateBpsInstructionArgs {
119 new_unclaimed_hashrate_bps,
120 })
121}
122
123pub fn get_update_epoch_vault_iteration_duration_instruction(
127 authority: Pubkey,
128 new_iteration_duration: u64,
129) -> Instruction {
130 UpdateEpochVaultIterationDuration {
131 authority,
132 satrush_config: get_satrush_config_address().0,
133 }
134 .instruction(UpdateEpochVaultIterationDurationInstructionArgs { new_iteration_duration })
135}
136
137pub fn get_update_deployment_settle_grace_duration_instruction(
141 authority: Pubkey,
142 new_grace_duration: u64,
143) -> Instruction {
144 UpdateDeploymentSettleGraceDuration {
145 authority,
146 satrush_config: get_satrush_config_address().0,
147 }
148 .instruction(UpdateDeploymentSettleGraceDurationInstructionArgs { new_grace_duration })
149}
150
151pub fn get_create_epoch_vault_instruction(authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Instruction {
154 let epoch_vault = get_epoch_vault_address().0;
155 CreateEpochVault {
156 authority,
157 satrush_config: get_satrush_config_address().0,
158 epoch_vault,
159 epoch_vault_iteration: get_epoch_vault_iteration_address(1).0,
160 usd_mint,
161 btc_mint,
162 epoch_vault_usd_ata: get_associated_token_address(&epoch_vault, &usd_mint),
163 epoch_vault_btc_ata: get_associated_token_address(&epoch_vault, &btc_mint),
164 token_program: TOKEN_PROGRAM_ID,
165 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
166 system_program: SYSTEM_PROGRAM_ID,
167 }
168 .instruction()
169}
170
171pub fn get_create_one_btc_vault_instruction(authority: Pubkey, usd_mint: Pubkey, btc_mint: Pubkey) -> Instruction {
174 let one_btc_vault = get_one_btc_vault_address().0;
175 CreateOneBtcVault {
176 authority,
177 satrush_config: get_satrush_config_address().0,
178 one_btc_vault,
179 one_btc_vault_iteration: get_one_btc_vault_iteration_address(1).0,
180 usd_mint,
181 btc_mint,
182 one_btc_vault_usd_ata: get_associated_token_address(&one_btc_vault, &usd_mint),
183 one_btc_vault_btc_ata: get_associated_token_address(&one_btc_vault, &btc_mint),
184 token_program: TOKEN_PROGRAM_ID,
185 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
186 system_program: SYSTEM_PROGRAM_ID,
187 }
188 .instruction()
189}
190
191pub fn get_create_treasury_instruction(authority: Pubkey, usd_mint: Pubkey) -> Instruction {
193 let treasury = get_treasury_address().0;
194 CreateTreasury {
195 authority,
196 satrush_config: get_satrush_config_address().0,
197 treasury,
198 usd_mint,
199 treasury_usd_ata: get_associated_token_address(&treasury, &usd_mint),
200 token_program: TOKEN_PROGRAM_ID,
201 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
202 system_program: SYSTEM_PROGRAM_ID,
203 }
204 .instruction()
205}
206
207pub fn get_deploy_public_instruction(
213 authority: Pubkey,
214 usd_mint: Pubkey,
215 round_id: u32,
216 selection_mask: u32,
217 amount: u64,
218) -> Instruction {
219 let board = get_board_address().0;
220
221 DeployPublic {
222 authority,
223 satrush_config: get_satrush_config_address().0,
224 board,
225 usd_mint,
226 board_usd_ata: get_associated_token_address(&board, &usd_mint),
227 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
228 round: get_round_address(round_id).0,
229 public_deployment: get_public_deployment_address(authority, round_id).0,
230 miner: get_miner_address(authority).0,
231 token_program: TOKEN_PROGRAM_ID,
232 system_program: SYSTEM_PROGRAM_ID,
233 }
234 .instruction(DeployPublicInstructionArgs { selection_mask, amount })
235}
236
237pub fn get_rotate_round_instruction(authority: Pubkey, usd_mint: Pubkey, current_round_id: u32) -> Instruction {
242 let board = get_board_address().0;
243 let epoch_vault = get_epoch_vault_address().0;
244 let one_btc_vault = get_one_btc_vault_address().0;
245 let treasury = get_treasury_address().0;
246
247 RotateRound {
248 authority,
249 satrush_config: get_satrush_config_address().0,
250 board,
251 current_round: get_round_address(current_round_id).0,
252 next_round: get_round_address(current_round_id + 1).0,
253 usd_mint,
254 board_usd_ata: get_associated_token_address(&board, &usd_mint),
255 epoch_vault,
256 epoch_vault_usd_ata: get_associated_token_address(&epoch_vault, &usd_mint),
257 one_btc_vault,
258 one_btc_vault_usd_ata: get_associated_token_address(&one_btc_vault, &usd_mint),
259 treasury,
260 treasury_usd_ata: get_associated_token_address(&treasury, &usd_mint),
261 slot_hashes: SLOT_HASHES_ID,
262 token_program: TOKEN_PROGRAM_ID,
263 system_program: SYSTEM_PROGRAM_ID,
264 event_authority: get_event_authority_address().0,
265 program: crate::SATRUSH_ID,
266 }
267 .instruction()
268}
269
270#[allow(clippy::too_many_arguments)]
276pub fn get_swap_round_stake_instruction(
277 authority: Pubkey,
278 usd_mint: Pubkey,
279 btc_mint: Pubkey,
280 round_id: u32,
281 min_btc_out: u64,
282 swap_program: Pubkey,
283 swap_data: Vec<u8>,
284 route_accounts: &[AccountMeta],
285) -> Instruction {
286 let board = get_board_address().0;
287 SwapRoundStake {
288 authority,
289 satrush_config: get_satrush_config_address().0,
290 board,
291 round: get_round_address(round_id).0,
292 usd_mint,
293 btc_mint,
294 board_usd_ata: get_associated_token_address(&board, &usd_mint),
295 board_btc_ata: get_associated_token_address(&board, &btc_mint),
296 swap_program,
297 token_program: TOKEN_PROGRAM_ID,
298 event_authority: get_event_authority_address().0,
299 program: crate::SATRUSH_ID,
300 }
301 .instruction_with_remaining_accounts(SwapRoundStakeInstructionArgs { min_btc_out, swap_data }, route_accounts)
302}
303
304pub fn get_settle_deploy_public_instruction(
309 authority: Pubkey,
310 deployment_authority: Pubkey,
311 rent_recipient: Pubkey,
312 usd_mint: Pubkey,
313 btc_mint: Pubkey,
314 round_id: u32,
315) -> Instruction {
316 let board = get_board_address().0;
317 let sats_vault = get_sats_vault_address().0;
318 let public_automation = get_public_automation_address(deployment_authority).0;
319 SettleDeployPublic {
320 authority,
321 rent_recipient,
322 satrush_config: get_satrush_config_address().0,
323 round: get_round_address(round_id).0,
324 board,
325 public_deployment: get_public_deployment_address(deployment_authority, round_id).0,
326 miner: get_miner_address(deployment_authority).0,
327 public_automation,
328 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
329 board_usd_ata: get_associated_token_address(&board, &usd_mint),
330 sats_vault,
331 btc_mint,
332 usd_mint,
333 board_btc_ata: get_associated_token_address(&board, &btc_mint),
334 sats_vault_btc_ata: get_associated_token_address(&sats_vault, &btc_mint),
335 token_program: TOKEN_PROGRAM_ID,
336 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
337 system_program: SYSTEM_PROGRAM_ID,
338 event_authority: get_event_authority_address().0,
339 program: crate::SATRUSH_ID,
340 }
341 .instruction()
342}
343
344#[allow(clippy::too_many_arguments)]
348pub fn get_create_public_automation_instruction(
349 authority: Pubkey,
350 usd_mint: Pubkey,
351 strategy: AutomationStrategy,
352 selection_mask: u32,
353 per_round_usd_amount: u64,
354 reload: bool,
355 deposit_usd_amount: u64,
356) -> Instruction {
357 let public_automation = get_public_automation_address(authority).0;
358 CreatePublicAutomation {
359 authority,
360 satrush_config: get_satrush_config_address().0,
361 public_automation,
362 usd_mint,
363 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
364 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
365 miner: get_miner_address(authority).0,
366 token_program: TOKEN_PROGRAM_ID,
367 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
368 system_program: SYSTEM_PROGRAM_ID,
369 }
370 .instruction(CreatePublicAutomationInstructionArgs {
371 strategy,
372 selection_mask,
373 per_round_usd_amount,
374 reload,
375 deposit_usd_amount,
376 })
377}
378
379pub fn get_top_up_public_automation_instruction(authority: Pubkey, usd_mint: Pubkey, amount: u64) -> Instruction {
382 let public_automation = get_public_automation_address(authority).0;
383 TopUpPublicAutomation {
384 authority,
385 satrush_config: get_satrush_config_address().0,
386 public_automation,
387 usd_mint,
388 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
389 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
390 token_program: TOKEN_PROGRAM_ID,
391 }
392 .instruction(TopUpPublicAutomationInstructionArgs { amount })
393}
394
395pub fn get_cancel_public_automation_instruction(authority: Pubkey, usd_mint: Pubkey) -> Instruction {
399 let public_automation = get_public_automation_address(authority).0;
400 CancelPublicAutomation {
401 authority,
402 satrush_config: get_satrush_config_address().0,
403 public_automation,
404 usd_mint,
405 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
406 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
407 token_program: TOKEN_PROGRAM_ID,
408 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
409 system_program: SYSTEM_PROGRAM_ID,
410 }
411 .instruction()
412}
413
414pub fn get_execute_public_automation_instruction(
418 crank_authority: Pubkey,
419 automation_authority: Pubkey,
420 usd_mint: Pubkey,
421 round_id: u32,
422 selection_mask: Option<u32>,
423) -> Instruction {
424 let board = get_board_address().0;
425 let public_automation = get_public_automation_address(automation_authority).0;
426
427 ExecutePublicAutomation {
428 authority: crank_authority,
429 satrush_config: get_satrush_config_address().0,
430 board,
431 round: get_round_address(round_id).0,
432 public_automation,
433 usd_mint,
434 automation_usd_ata: get_associated_token_address(&public_automation, &usd_mint),
435 board_usd_ata: get_associated_token_address(&board, &usd_mint),
436 public_deployment: get_public_deployment_address(automation_authority, round_id).0,
437 miner: get_miner_address(automation_authority).0,
438 slot_hashes: SLOT_HASHES_ID,
439 token_program: TOKEN_PROGRAM_ID,
440 system_program: SYSTEM_PROGRAM_ID,
441 }
442 .instruction(ExecutePublicAutomationInstructionArgs { selection_mask })
443}
444
445pub fn get_claim_usd_instruction(authority: Pubkey, usd_mint: Pubkey, amount: u64) -> Instruction {
449 let board = get_board_address().0;
450 ClaimUsd {
451 authority,
452 satrush_config: get_satrush_config_address().0,
453 board,
454 miner: get_miner_address(authority).0,
455 usd_mint,
456 board_usd_ata: get_associated_token_address(&board, &usd_mint),
457 authority_usd_ata: get_associated_token_address(&authority, &usd_mint),
458 token_program: TOKEN_PROGRAM_ID,
459 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
460 system_program: SYSTEM_PROGRAM_ID,
461 }
462 .instruction(ClaimUsdInstructionArgs { amount })
463}
464
465pub fn get_create_sats_vault_instruction(authority: Pubkey, btc_mint: Pubkey) -> Instruction {
467 let sats_vault = get_sats_vault_address().0;
468 CreateSatsVault {
469 authority,
470 satrush_config: get_satrush_config_address().0,
471 sats_vault,
472 btc_mint,
473 sats_vault_btc_ata: get_associated_token_address(&sats_vault, &btc_mint),
474 token_program: TOKEN_PROGRAM_ID,
475 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
476 system_program: SYSTEM_PROGRAM_ID,
477 }
478 .instruction()
479}
480
481pub fn get_close_round_instruction(
485 authority: Pubkey,
486 usd_mint: Pubkey,
487 btc_mint: Pubkey,
488 round_id: u32,
489) -> Instruction {
490 let board = get_board_address().0;
491 let treasury = get_treasury_address().0;
492 CloseRound {
493 authority,
494 satrush_config: get_satrush_config_address().0,
495 board,
496 round: get_round_address(round_id).0,
497 treasury,
498 usd_mint,
499 btc_mint,
500 board_usd_ata: get_associated_token_address(&board, &usd_mint),
501 board_btc_ata: get_associated_token_address(&board, &btc_mint),
502 treasury_usd_ata: get_associated_token_address(&treasury, &usd_mint),
503 treasury_btc_ata: get_associated_token_address(&treasury, &btc_mint),
504 token_program: TOKEN_PROGRAM_ID,
505 associated_token_program: ASSOCIATED_TOKEN_PROGRAM_ID,
506 system_program: SYSTEM_PROGRAM_ID,
507 event_authority: get_event_authority_address().0,
508 program: crate::SATRUSH_ID,
509 }
510 .instruction()
511}