1use solana_program::{
4 instruction::{AccountMeta, Instruction},
5 pubkey::Pubkey,
6};
7use solana_sdk_ids::system_program;
8use spl_associated_token_account::get_associated_token_address;
9
10use crate::{
11 consts::{DOJO_MINT, FEE_COLLECTOR},
12 instruction::*,
13 state::*,
14};
15
16fn program_id() -> Pubkey {
17 crate::ID
18}
19
20pub fn initialize(authority: Pubkey) -> Instruction {
22 let config_address = config_pda(&program_id()).0;
23 let game_address = game_pda(&program_id()).0;
24 let treasury_address = treasury_pda(&program_id()).0;
25 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
26
27 Instruction {
28 program_id: program_id(),
29 accounts: vec![
30 AccountMeta::new(authority, true),
31 AccountMeta::new(config_address, false),
32 AccountMeta::new(game_address, false),
33 AccountMeta::new(treasury_address, false),
34 AccountMeta::new(treasury_ata, false),
35 AccountMeta::new_readonly(DOJO_MINT, false),
36 AccountMeta::new_readonly(spl_token::ID, false),
37 AccountMeta::new_readonly(spl_associated_token_account::ID, false),
38 AccountMeta::new_readonly(system_program::ID, false),
39 ],
40 data: Initialize {}.to_bytes(),
41 }
42}
43
44pub fn buy_starter_pack(
47 signer: Pubkey,
48 referrer: Option<Pubkey>,
49) -> Instruction {
50 let config_address = config_pda(&program_id()).0;
51 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
52 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
53 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
54 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
55 let treasury_address = treasury_pda(&program_id()).0;
56
57 let referrer_bytes = referrer.map(|p| p.to_bytes()).unwrap_or([0u8; 32]);
58
59 let game_address = game_pda(&program_id()).0;
60 let mut accounts = vec![
61 AccountMeta::new(signer, true),
62 AccountMeta::new(config_address, false),
63 AccountMeta::new(game_address, false),
64 AccountMeta::new(dojo_address, false),
65 AccountMeta::new(barracks_address, false),
66 AccountMeta::new(forge_address, false),
67 AccountMeta::new(tasks_address, false),
68 AccountMeta::new(treasury_address, false),
69 AccountMeta::new(FEE_COLLECTOR, false),
70 AccountMeta::new_readonly(system_program::ID, false),
71 ];
72 if let Some(ref_dojo) = referrer {
73 let (referral_address, _) = referral_pda(&program_id(), &ref_dojo);
74 accounts.push(AccountMeta::new_readonly(ref_dojo, false));
75 accounts.push(AccountMeta::new(referral_address, false));
76 }
77
78 Instruction {
79 program_id: program_id(),
80 accounts,
81 data: BuyStarterPack { referrer: referrer_bytes }.to_bytes(),
82 }
83}
84
85pub fn recruit_shogun_tickets(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
88 let config_address = config_pda(&program_id()).0;
89 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
90 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
91
92 Instruction {
93 program_id: program_id(),
94 accounts: vec![
95 AccountMeta::new(signer, true),
96 AccountMeta::new_readonly(config_address, false),
97 AccountMeta::new(dojo_address, false),
98 AccountMeta::new(tasks_address, false),
99 ],
100 data: RecruitShogunTickets {
101 count: count.to_le_bytes(),
102 seed,
103 }
104 .to_bytes(),
105 }
106}
107
108pub fn recruit_shogun_sol(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
111 let config_address = config_pda(&program_id()).0;
112 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
113 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
114
115 Instruction {
116 program_id: program_id(),
117 accounts: vec![
118 AccountMeta::new(signer, true),
119 AccountMeta::new_readonly(config_address, false),
120 AccountMeta::new(dojo_address, false),
121 AccountMeta::new(tasks_address, false),
122 AccountMeta::new(FEE_COLLECTOR, false),
123 ],
124 data: RecruitShogunSol {
125 count: count.to_le_bytes(),
126 seed,
127 }
128 .to_bytes(),
129 }
130}
131
132pub fn seat_shogun(signer: Pubkey, slot: u64, rarity: u64, element: u64) -> Instruction {
134 let config_address = config_pda(&program_id()).0;
135 let game_address = game_pda(&program_id()).0;
136 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
137 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
138
139 Instruction {
140 program_id: program_id(),
141 accounts: vec![
142 AccountMeta::new(signer, true),
143 AccountMeta::new_readonly(config_address, false),
144 AccountMeta::new(game_address, false),
145 AccountMeta::new(dojo_address, false),
146 AccountMeta::new(barracks_address, false),
147 ],
148 data: SeatShogun {
149 slot: slot.to_le_bytes(),
150 rarity: rarity.to_le_bytes(),
151 element: element.to_le_bytes(),
152 }
153 .to_bytes(),
154 }
155}
156
157pub fn replace_shogun(signer: Pubkey, slot: u64, new_rarity: u64, new_element: u64) -> Instruction {
159 let config_address = config_pda(&program_id()).0;
160 let game_address = game_pda(&program_id()).0;
161 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
162 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
163
164 Instruction {
165 program_id: program_id(),
166 accounts: vec![
167 AccountMeta::new(signer, true),
168 AccountMeta::new_readonly(config_address, false),
169 AccountMeta::new(game_address, false),
170 AccountMeta::new(dojo_address, false),
171 AccountMeta::new(barracks_address, false),
172 ],
173 data: ReplaceShogun {
174 slot: slot.to_le_bytes(),
175 new_rarity: new_rarity.to_le_bytes(),
176 new_element: new_element.to_le_bytes(),
177 }
178 .to_bytes(),
179 }
180}
181
182pub fn seat_shogun_fill_all(
184 signer: Pubkey,
185 entries: impl IntoIterator<Item = (u64, u64)>,
186) -> Instruction {
187 let config_address = config_pda(&program_id()).0;
188 let game_address = game_pda(&program_id()).0;
189 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
190 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
191
192 let mut arr: [SeatShogunFillAllEntry; 12] = [SeatShogunFillAllEntry {
193 rarity: [0; 8],
194 element: [0; 8],
195 }; 12];
196 let mut count = 0u8;
197 for (i, (rarity, element)) in entries.into_iter().take(12).enumerate() {
198 arr[i] = SeatShogunFillAllEntry {
199 rarity: rarity.to_le_bytes(),
200 element: element.to_le_bytes(),
201 };
202 count += 1;
203 }
204
205 Instruction {
206 program_id: program_id(),
207 accounts: vec![
208 AccountMeta::new(signer, true),
209 AccountMeta::new_readonly(config_address, false),
210 AccountMeta::new(game_address, false),
211 AccountMeta::new(dojo_address, false),
212 AccountMeta::new(barracks_address, false),
213 ],
214 data: SeatShogunFillAll {
215 count,
216 _pad: [0; 7],
217 entries: arr,
218 }
219 .to_bytes(),
220 }
221}
222
223pub fn dine(signer: Pubkey, slot: u64, tier: u64) -> Instruction {
225 let config_address = config_pda(&program_id()).0;
226 let game_address = game_pda(&program_id()).0;
227 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
228 let treasury_address = treasury_pda(&program_id()).0;
229 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
230 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
231 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
232
233 Instruction {
234 program_id: program_id(),
235 accounts: vec![
236 AccountMeta::new(signer, true),
237 AccountMeta::new_readonly(config_address, false),
238 AccountMeta::new(game_address, false),
239 AccountMeta::new(dojo_address, false),
240 AccountMeta::new(barracks_address, false),
241 AccountMeta::new(user_ata, false),
242 AccountMeta::new(treasury_ata, false),
243 AccountMeta::new(DOJO_MINT, false),
244 AccountMeta::new(treasury_address, false),
245 AccountMeta::new_readonly(spl_token::ID, false),
246 ],
247 data: Dine {
248 tier: tier.to_le_bytes(),
249 slot: slot.to_le_bytes(),
250 }
251 .to_bytes(),
252 }
253}
254
255pub fn upgrade_barracks_shards(signer: Pubkey) -> Instruction {
257 let config_address = config_pda(&program_id()).0;
258 let game_address = game_pda(&program_id()).0;
259 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
260 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
261 let treasury_address = treasury_pda(&program_id()).0;
262 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
263 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
264
265 Instruction {
266 program_id: program_id(),
267 accounts: vec![
268 AccountMeta::new(signer, true),
269 AccountMeta::new_readonly(config_address, false),
270 AccountMeta::new(game_address, false),
271 AccountMeta::new(dojo_address, false),
272 AccountMeta::new(barracks_address, false),
273 AccountMeta::new(user_ata, false),
274 AccountMeta::new(treasury_ata, false),
275 AccountMeta::new(DOJO_MINT, false),
276 AccountMeta::new(treasury_address, false),
277 AccountMeta::new_readonly(spl_token::ID, false),
278 ],
279 data: UpgradeBarracksShards {}.to_bytes(),
280 }
281}
282
283pub fn upgrade_barracks_sol(signer: Pubkey) -> Instruction {
285 let config_address = config_pda(&program_id()).0;
286 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
287 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
288
289 Instruction {
290 program_id: program_id(),
291 accounts: vec![
292 AccountMeta::new(signer, true),
293 AccountMeta::new_readonly(config_address, false),
294 AccountMeta::new(dojo_address, false),
295 AccountMeta::new(barracks_address, false),
296 AccountMeta::new(FEE_COLLECTOR, false),
297 AccountMeta::new_readonly(system_program::ID, false),
298 ],
299 data: UpgradeBarracksSol {}.to_bytes(),
300 }
301}
302
303pub fn upgrade_forge(signer: Pubkey) -> Instruction {
305 let config_address = config_pda(&program_id()).0;
306 let game_address = game_pda(&program_id()).0;
307 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
308 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
309 let treasury_address = treasury_pda(&program_id()).0;
310 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
311 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
312
313 Instruction {
314 program_id: program_id(),
315 accounts: vec![
316 AccountMeta::new(signer, true),
317 AccountMeta::new_readonly(config_address, false),
318 AccountMeta::new(game_address, false),
319 AccountMeta::new(dojo_address, false),
320 AccountMeta::new(forge_address, false),
321 AccountMeta::new(FEE_COLLECTOR, false),
322 AccountMeta::new_readonly(system_program::ID, false),
323 AccountMeta::new(user_ata, false),
324 AccountMeta::new(treasury_ata, false),
325 AccountMeta::new(DOJO_MINT, false),
326 AccountMeta::new(treasury_address, false),
327 AccountMeta::new_readonly(spl_token::ID, false),
328 ],
329 data: UpgradeForge {}.to_bytes(),
330 }
331}
332
333pub fn merge_shogun(signer: Pubkey, merge_type: u64, seed: [u8; 32]) -> Instruction {
336 let config_address = config_pda(&program_id()).0;
337 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
338 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
339
340 Instruction {
341 program_id: program_id(),
342 accounts: vec![
343 AccountMeta::new(signer, true),
344 AccountMeta::new_readonly(config_address, false),
345 AccountMeta::new(dojo_address, false),
346 AccountMeta::new(tasks_address, false),
347 ],
348 data: MergeShogun {
349 merge_type: merge_type.to_le_bytes(),
350 seed,
351 }
352 .to_bytes(),
353 }
354}
355
356pub fn prestige_upgrade(signer: Pubkey, slot: u64) -> Instruction {
358 let config_address = config_pda(&program_id()).0;
359 let game_address = game_pda(&program_id()).0;
360 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
361 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
362 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
363
364 Instruction {
365 program_id: program_id(),
366 accounts: vec![
367 AccountMeta::new(signer, true),
368 AccountMeta::new_readonly(config_address, false),
369 AccountMeta::new(game_address, false),
370 AccountMeta::new(dojo_address, false),
371 AccountMeta::new(barracks_address, false),
372 AccountMeta::new(tasks_address, false),
373 ],
374 data: PrestigeUpgrade {
375 slot: slot.to_le_bytes(),
376 }
377 .to_bytes(),
378 }
379}
380
381pub fn level_up_shogun(signer: Pubkey, slot: u64) -> Instruction {
383 let config_address = config_pda(&program_id()).0;
384 let game_address = game_pda(&program_id()).0;
385 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
386 let treasury_address = treasury_pda(&program_id()).0;
387 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
388 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
389 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
390
391 Instruction {
392 program_id: program_id(),
393 accounts: vec![
394 AccountMeta::new(signer, true),
395 AccountMeta::new_readonly(config_address, false),
396 AccountMeta::new(game_address, false),
397 AccountMeta::new(dojo_address, false),
398 AccountMeta::new(barracks_address, false),
399 AccountMeta::new(user_ata, false),
400 AccountMeta::new(treasury_ata, false),
401 AccountMeta::new(DOJO_MINT, false),
402 AccountMeta::new(treasury_address, false),
403 AccountMeta::new_readonly(spl_token::ID, false),
404 ],
405 data: LevelUpShogun {
406 slot: slot.to_le_bytes(),
407 }
408 .to_bytes(),
409 }
410}
411
412pub fn claim_shards(signer: Pubkey) -> Instruction {
415 let config_address = config_pda(&program_id()).0;
416 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
417 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
418 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
419 let treasury_address = treasury_pda(&program_id()).0;
420 let dojo_ata = get_associated_token_address(&signer, &DOJO_MINT);
421
422 Instruction {
423 program_id: program_id(),
424 accounts: vec![
425 AccountMeta::new(signer, true),
426 AccountMeta::new_readonly(config_address, false),
427 AccountMeta::new(dojo_address, false),
428 AccountMeta::new(forge_address, false),
429 AccountMeta::new(barracks_address, false),
430 AccountMeta::new(dojo_ata, false),
431 AccountMeta::new(DOJO_MINT, false),
432 AccountMeta::new(treasury_address, false),
433 AccountMeta::new_readonly(spl_token::ID, false),
434 ],
435 data: ClaimShards {}.to_bytes(),
436 }
437}
438
439pub fn claim_referral_reward(signer: Pubkey, referrer_dojo: Pubkey) -> Instruction {
441 let (referral_address, _) = referral_pda(&program_id(), &referrer_dojo);
442 let treasury_address = treasury_pda(&program_id()).0;
443
444 Instruction {
445 program_id: program_id(),
446 accounts: vec![
447 AccountMeta::new(signer, true),
448 AccountMeta::new(referrer_dojo, false),
449 AccountMeta::new(referral_address, false),
450 AccountMeta::new(treasury_address, false),
451 AccountMeta::new_readonly(system_program::ID, false),
452 ],
453 data: ClaimReferralReward {}.to_bytes(),
454 }
455}
456
457pub fn claim_recruit_reward(signer: Pubkey) -> Instruction {
459 let config_address = config_pda(&program_id()).0;
460 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
461 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
462
463 Instruction {
464 program_id: program_id(),
465 accounts: vec![
466 AccountMeta::new(signer, true),
467 AccountMeta::new_readonly(config_address, false),
468 AccountMeta::new(dojo_address, false),
469 AccountMeta::new(tasks_address, false),
470 ],
471 data: ClaimRecruitReward {}.to_bytes(),
472 }
473}
474
475pub fn claim_forge_reward(signer: Pubkey) -> Instruction {
477 let config_address = config_pda(&program_id()).0;
478 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
479 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
480
481 Instruction {
482 program_id: program_id(),
483 accounts: vec![
484 AccountMeta::new(signer, true),
485 AccountMeta::new_readonly(config_address, false),
486 AccountMeta::new(dojo_address, false),
487 AccountMeta::new(tasks_address, false),
488 ],
489 data: ClaimForgeReward {}.to_bytes(),
490 }
491}
492
493pub fn claim_dine_reward(signer: Pubkey) -> Instruction {
495 let config_address = config_pda(&program_id()).0;
496 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
497 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
498
499 Instruction {
500 program_id: program_id(),
501 accounts: vec![
502 AccountMeta::new(signer, true),
503 AccountMeta::new_readonly(config_address, false),
504 AccountMeta::new(dojo_address, false),
505 AccountMeta::new(tasks_address, false),
506 ],
507 data: ClaimDineReward {}.to_bytes(),
508 }
509}
510
511pub fn ed25519_verify_instruction_for_daily_claim(
514 dojo_pda: Pubkey,
515 signature: [u8; 64],
516) -> Instruction {
517 use crate::consts::{CLAIM_TASK_PREFIX, DAILY_TASK_START, TASK_VERIFIER};
518 let mut message = Vec::with_capacity(CLAIM_TASK_PREFIX.len() + 32 + 8);
519 message.extend_from_slice(CLAIM_TASK_PREFIX);
520 message.extend_from_slice(dojo_pda.as_ref());
521 message.extend_from_slice(&DAILY_TASK_START.to_le_bytes());
522 let verifier_bytes: [u8; 32] = TASK_VERIFIER.to_bytes();
523 crate::utils::new_ed25519_instruction_with_signature(&message, &signature, &verifier_bytes)
524}
525
526pub fn claim_daily_reward(signer: Pubkey, signature: [u8; 64]) -> Instruction {
529 let config_address = config_pda(&program_id()).0;
530 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
531 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
532 let instructions_sysvar = solana_program::sysvar::instructions::ID;
533
534 Instruction {
535 program_id: program_id(),
536 accounts: vec![
537 AccountMeta::new(signer, true),
538 AccountMeta::new_readonly(config_address, false),
539 AccountMeta::new(dojo_address, false),
540 AccountMeta::new(tasks_address, false),
541 AccountMeta::new_readonly(instructions_sysvar, false),
542 ],
543 data: ClaimDailyReward { signature }.to_bytes(),
544 }
545}
546
547pub fn claim_collection_reward(signer: Pubkey, collection_index: u8) -> Instruction {
550 let config_address = config_pda(&program_id()).0;
551 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
552 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
553
554 Instruction {
555 program_id: program_id(),
556 accounts: vec![
557 AccountMeta::new(signer, true),
558 AccountMeta::new_readonly(config_address, false),
559 AccountMeta::new(dojo_address, false),
560 AccountMeta::new(tasks_address, false),
561 ],
562 data: ClaimCollectionReward { collection_index }.to_bytes(),
563 }
564}
565
566pub fn buy_flash_sale(signer: Pubkey) -> Instruction {
568 let config_address = config_pda(&program_id()).0;
569 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
570 let treasury_address = treasury_pda(&program_id()).0;
571 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
572 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
573
574 Instruction {
575 program_id: program_id(),
576 accounts: vec![
577 AccountMeta::new(signer, true),
578 AccountMeta::new_readonly(config_address, false),
579 AccountMeta::new(dojo_address, false),
580 AccountMeta::new(user_ata, false),
581 AccountMeta::new_readonly(treasury_address, false),
582 AccountMeta::new(treasury_ata, false),
583 AccountMeta::new_readonly(spl_token::ID, false),
584 ],
585 data: BuyFlashSale {}.to_bytes(),
586 }
587}
588
589pub fn buy_tickets_with_shards(signer: Pubkey) -> Instruction {
591 let config_address = config_pda(&program_id()).0;
592 let game_address = game_pda(&program_id()).0;
593 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
594 let treasury_address = treasury_pda(&program_id()).0;
595 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
596 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
597
598 Instruction {
599 program_id: program_id(),
600 accounts: vec![
601 AccountMeta::new(signer, true),
602 AccountMeta::new_readonly(config_address, false),
603 AccountMeta::new(game_address, false),
604 AccountMeta::new(dojo_address, false),
605 AccountMeta::new(user_ata, false),
606 AccountMeta::new(treasury_ata, false),
607 AccountMeta::new(DOJO_MINT, false),
608 AccountMeta::new(treasury_address, false),
609 AccountMeta::new_readonly(spl_token::ID, false),
610 ],
611 data: BuyTicketsWithShards {}.to_bytes(),
612 }
613}
614
615pub fn buy_bundle(signer: Pubkey) -> Instruction {
617 let config_address = config_pda(&program_id()).0;
618 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
619
620 Instruction {
621 program_id: program_id(),
622 accounts: vec![
623 AccountMeta::new(signer, true),
624 AccountMeta::new_readonly(config_address, false),
625 AccountMeta::new(dojo_address, false),
626 AccountMeta::new(FEE_COLLECTOR, false),
627 AccountMeta::new_readonly(system_program::ID, false),
628 ],
629 data: BuyBundle {}.to_bytes(),
630 }
631}
632
633pub fn clear_forge_cooldown(signer: Pubkey) -> Instruction {
635 let config_address = config_pda(&program_id()).0;
636 let game_address = game_pda(&program_id()).0;
637 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
638 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
639 let treasury_address = treasury_pda(&program_id()).0;
640 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
641 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
642
643 Instruction {
644 program_id: program_id(),
645 accounts: vec![
646 AccountMeta::new(signer, true),
647 AccountMeta::new_readonly(config_address, false),
648 AccountMeta::new(game_address, false),
649 AccountMeta::new(dojo_address, false),
650 AccountMeta::new(forge_address, false),
651 AccountMeta::new(user_ata, false),
652 AccountMeta::new(treasury_ata, false),
653 AccountMeta::new(DOJO_MINT, false),
654 AccountMeta::new(treasury_address, false),
655 AccountMeta::new_readonly(spl_token::ID, false),
656 ],
657 data: ClearForgeCooldown {}.to_bytes(),
658 }
659}
660
661pub fn set_genesis_slot(authority: Pubkey, genesis_slot: u64, halving_period_slots: u64) -> Instruction {
663 let config_address = config_pda(&program_id()).0;
664 let game_address = game_pda(&program_id()).0;
665
666 Instruction {
667 program_id: program_id(),
668 accounts: vec![
669 AccountMeta::new(authority, true),
670 AccountMeta::new(config_address, false),
671 AccountMeta::new(game_address, false),
672 ],
673 data: SetGenesisSlot {
674 genesis_slot: genesis_slot.to_le_bytes(),
675 halving_period_slots: halving_period_slots.to_le_bytes(),
676 }
677 .to_bytes(),
678 }
679}
680
681pub fn migrate_dojo(signer: Pubkey) -> Instruction {
683 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
684
685 Instruction {
686 program_id: program_id(),
687 accounts: vec![
688 AccountMeta::new(signer, true),
689 AccountMeta::new(dojo_address, false),
690 AccountMeta::new_readonly(system_program::ID, false),
691 ],
692 data: MigrateDojo {}.to_bytes(),
693 }
694}
695
696pub fn roll_scene_section_amethyst(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
699 let config_address = config_pda(&program_id()).0;
700 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
701 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
702
703 Instruction {
704 program_id: program_id(),
705 accounts: vec![
706 AccountMeta::new(signer, true),
707 AccountMeta::new_readonly(config_address, false),
708 AccountMeta::new(dojo_address, false),
709 AccountMeta::new(scenes_address, false),
710 AccountMeta::new_readonly(system_program::ID, false),
711 ],
712 data: RollSceneSectionAmethyst {
713 count: count.to_le_bytes(),
714 seed,
715 }
716 .to_bytes(),
717 }
718}
719
720pub fn roll_scene_section_shards(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
723 let config_address = config_pda(&program_id()).0;
724 let game_address = game_pda(&program_id()).0;
725 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
726 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
727 let treasury_address = treasury_pda(&program_id()).0;
728 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
729 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
730
731 Instruction {
732 program_id: program_id(),
733 accounts: vec![
734 AccountMeta::new(signer, true),
735 AccountMeta::new_readonly(config_address, false),
736 AccountMeta::new(game_address, false),
737 AccountMeta::new(dojo_address, false),
738 AccountMeta::new(scenes_address, false),
739 AccountMeta::new(user_ata, false),
740 AccountMeta::new(treasury_ata, false),
741 AccountMeta::new_readonly(DOJO_MINT, false),
742 AccountMeta::new(treasury_address, false),
743 AccountMeta::new_readonly(spl_token::ID, false),
744 AccountMeta::new_readonly(system_program::ID, false),
745 ],
746 data: RollSceneSectionShards {
747 count: count.to_le_bytes(),
748 seed,
749 }
750 .to_bytes(),
751 }
752}
753
754pub fn salvage_scene_section(
757 signer: Pubkey,
758 items: impl IntoIterator<Item = (u8, u8, u16)>,
759) -> Instruction {
760 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
761 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
762
763 let items: Vec<_> = items.into_iter().take(64).collect();
764 let item_count = items.len() as u8;
765 let mut salvage_items = [SalvageItem {
766 scene_id: 0,
767 section_id: 0,
768 count: 0,
769 }; 64];
770 for (i, (scene_id, section_id, count)) in items.into_iter().enumerate() {
771 salvage_items[i] = SalvageItem {
772 scene_id,
773 section_id,
774 count,
775 };
776 }
777
778 Instruction {
779 program_id: program_id(),
780 accounts: vec![
781 AccountMeta::new(signer, true),
782 AccountMeta::new(dojo_address, false),
783 AccountMeta::new(scenes_address, false),
784 ],
785 data: SalvageSceneSection {
786 item_count,
787 _pad: [0; 3],
788 items: salvage_items,
789 }
790 .to_bytes(),
791 }
792}
793
794pub fn buy_scene(signer: Pubkey, scene_id: u64) -> Instruction {
796 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
797 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
798
799 Instruction {
800 program_id: program_id(),
801 accounts: vec![
802 AccountMeta::new(signer, true),
803 AccountMeta::new(dojo_address, false),
804 AccountMeta::new(scenes_address, false),
805 AccountMeta::new_readonly(system_program::ID, false),
806 ],
807 data: BuyScene {
808 scene_id: scene_id.to_le_bytes(),
809 }
810 .to_bytes(),
811 }
812}
813
814pub fn buy_scene_dojo(signer: Pubkey, scene_id: u64) -> Instruction {
816 let config_address = config_pda(&program_id()).0;
817 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
818 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
819 let treasury_address = treasury_pda(&program_id()).0;
820 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
821 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
822
823 Instruction {
824 program_id: program_id(),
825 accounts: vec![
826 AccountMeta::new(signer, true),
827 AccountMeta::new_readonly(config_address, false),
828 AccountMeta::new(dojo_address, false),
829 AccountMeta::new(scenes_address, false),
830 AccountMeta::new(user_ata, false),
831 AccountMeta::new(treasury_ata, false),
832 AccountMeta::new(DOJO_MINT, false),
833 AccountMeta::new(treasury_address, false),
834 AccountMeta::new_readonly(spl_token::ID, false),
835 AccountMeta::new_readonly(system_program::ID, false),
836 ],
837 data: BuySceneDojo {
838 scene_id: scene_id.to_le_bytes(),
839 }
840 .to_bytes(),
841 }
842}
843
844pub fn log(config: Pubkey, msg: &[u8]) -> Instruction {
846 let mut data = Log {
847 _reserved: [0u8; 8],
848 }
849 .to_bytes();
850 data.extend_from_slice(msg);
851 Instruction {
852 program_id: program_id(),
853 accounts: vec![AccountMeta::new(config, true)],
854 data,
855 }
856}