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::{DGT_GROUP, 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 (mission_address, _) = mission_pda(&program_id(), &dojo_address);
56 let treasury_address = treasury_pda(&program_id()).0;
57
58 let referrer_bytes = referrer.map(|p| p.to_bytes()).unwrap_or([0u8; 32]);
59
60 let game_address = game_pda(&program_id()).0;
61 let mut accounts = vec![
62 AccountMeta::new(signer, true),
63 AccountMeta::new(config_address, false),
64 AccountMeta::new(game_address, false),
65 AccountMeta::new(dojo_address, false),
66 AccountMeta::new(barracks_address, false),
67 AccountMeta::new(forge_address, false),
68 AccountMeta::new(tasks_address, false),
69 AccountMeta::new(mission_address, false),
70 AccountMeta::new(treasury_address, false),
71 AccountMeta::new(FEE_COLLECTOR, false),
72 AccountMeta::new_readonly(system_program::ID, false),
73 ];
74 if let Some(ref_dojo) = referrer {
75 let (referral_address, _) = referral_pda(&program_id(), &ref_dojo);
76 accounts.push(AccountMeta::new_readonly(ref_dojo, false));
77 accounts.push(AccountMeta::new(referral_address, false));
78 }
79
80 Instruction {
81 program_id: program_id(),
82 accounts,
83 data: BuyStarterPack { referrer: referrer_bytes }.to_bytes(),
84 }
85}
86
87pub fn recruit_shogun_tickets(
91 signer: Pubkey,
92 count: u64,
93 seed: [u8; 32],
94 prestige: Option<Pubkey>,
95) -> Instruction {
96 let config_address = config_pda(&program_id()).0;
97 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
98 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
99
100 let mut accounts = vec![
101 AccountMeta::new(signer, true),
102 AccountMeta::new_readonly(config_address, false),
103 AccountMeta::new(dojo_address, false),
104 AccountMeta::new(tasks_address, false),
105 ];
106 if let Some(addr) = prestige {
107 accounts.push(AccountMeta::new(addr, false));
108 }
109
110 Instruction {
111 program_id: program_id(),
112 accounts,
113 data: RecruitShogunTickets {
114 count: count.to_le_bytes(),
115 seed,
116 }
117 .to_bytes(),
118 }
119}
120
121pub fn recruit_shogun_sol(
125 signer: Pubkey,
126 count: u64,
127 seed: [u8; 32],
128 prestige: Option<Pubkey>,
129) -> Instruction {
130 let config_address = config_pda(&program_id()).0;
131 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
132 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
133
134 let treasury_address = treasury_pda(&program_id()).0;
135 let mut accounts = vec![
136 AccountMeta::new(signer, true),
137 AccountMeta::new_readonly(config_address, false),
138 AccountMeta::new(dojo_address, false),
139 AccountMeta::new(tasks_address, false),
140 AccountMeta::new(treasury_address, false),
141 AccountMeta::new(FEE_COLLECTOR, false),
142 ];
143 if let Some(addr) = prestige {
144 accounts.push(AccountMeta::new(addr, false));
145 }
146
147 Instruction {
148 program_id: program_id(),
149 accounts,
150 data: RecruitShogunSol {
151 count: count.to_le_bytes(),
152 seed,
153 }
154 .to_bytes(),
155 }
156}
157
158pub fn seat_shogun(
161 signer: Pubkey,
162 slot: u64,
163 rarity: u64,
164 element: u64,
165 prestige: Option<Pubkey>,
166) -> Instruction {
167 let config_address = config_pda(&program_id()).0;
168 let game_address = game_pda(&program_id()).0;
169 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
170 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
171
172 let mut accounts = vec![
173 AccountMeta::new(signer, true),
174 AccountMeta::new_readonly(config_address, false),
175 AccountMeta::new(game_address, false),
176 AccountMeta::new(dojo_address, false),
177 AccountMeta::new(barracks_address, false),
178 ];
179 if let Some(addr) = prestige {
180 accounts.push(AccountMeta::new(addr, false));
181 }
182
183 Instruction {
184 program_id: program_id(),
185 accounts,
186 data: SeatShogun {
187 slot: slot.to_le_bytes(),
188 rarity: rarity.to_le_bytes(),
189 element: element.to_le_bytes(),
190 }
191 .to_bytes(),
192 }
193}
194
195pub fn replace_shogun(
198 signer: Pubkey,
199 slot: u64,
200 new_rarity: u64,
201 new_element: u64,
202 prestige: Option<Pubkey>,
203) -> Instruction {
204 let config_address = config_pda(&program_id()).0;
205 let game_address = game_pda(&program_id()).0;
206 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
207 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
208 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
209
210 let mut accounts = vec![
211 AccountMeta::new(signer, true),
212 AccountMeta::new_readonly(config_address, false),
213 AccountMeta::new(game_address, false),
214 AccountMeta::new(dojo_address, false),
215 AccountMeta::new(barracks_address, false),
216 AccountMeta::new_readonly(mission_address, false),
217 ];
218 if let Some(addr) = prestige {
219 accounts.push(AccountMeta::new(addr, false));
220 }
221
222 Instruction {
223 program_id: program_id(),
224 accounts,
225 data: ReplaceShogun {
226 slot: slot.to_le_bytes(),
227 new_rarity: new_rarity.to_le_bytes(),
228 new_element: new_element.to_le_bytes(),
229 }
230 .to_bytes(),
231 }
232}
233
234pub fn seat_shogun_fill_all(
237 signer: Pubkey,
238 entries: impl IntoIterator<Item = (u64, u64)>,
239 prestige: Option<Pubkey>,
240) -> Instruction {
241 let config_address = config_pda(&program_id()).0;
242 let game_address = game_pda(&program_id()).0;
243 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
244 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
245
246 let mut arr: [SeatShogunFillAllEntry; 12] = [SeatShogunFillAllEntry {
247 rarity: [0; 8],
248 element: [0; 8],
249 }; 12];
250 let mut count = 0u8;
251 for (i, (rarity, element)) in entries.into_iter().take(12).enumerate() {
252 arr[i] = SeatShogunFillAllEntry {
253 rarity: rarity.to_le_bytes(),
254 element: element.to_le_bytes(),
255 };
256 count += 1;
257 }
258
259 let mut accounts = vec![
260 AccountMeta::new(signer, true),
261 AccountMeta::new_readonly(config_address, false),
262 AccountMeta::new(game_address, false),
263 AccountMeta::new(dojo_address, false),
264 AccountMeta::new(barracks_address, false),
265 ];
266 if let Some(addr) = prestige {
267 accounts.push(AccountMeta::new(addr, false));
268 }
269
270 Instruction {
271 program_id: program_id(),
272 accounts,
273 data: SeatShogunFillAll {
274 count,
275 _pad: [0; 7],
276 entries: arr,
277 }
278 .to_bytes(),
279 }
280}
281
282pub fn dine(signer: Pubkey, slot: u64, tier: u64) -> Instruction {
284 let config_address = config_pda(&program_id()).0;
285 let game_address = game_pda(&program_id()).0;
286 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
287 let treasury_address = treasury_pda(&program_id()).0;
288 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
289 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
290 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
291
292 Instruction {
293 program_id: program_id(),
294 accounts: vec![
295 AccountMeta::new(signer, true),
296 AccountMeta::new_readonly(config_address, false),
297 AccountMeta::new(game_address, false),
298 AccountMeta::new(dojo_address, false),
299 AccountMeta::new(barracks_address, false),
300 AccountMeta::new(user_ata, false),
301 AccountMeta::new(treasury_ata, false),
302 AccountMeta::new(DOJO_MINT, false),
303 AccountMeta::new(treasury_address, false),
304 AccountMeta::new_readonly(spl_token::ID, false),
305 ],
306 data: Dine {
307 tier: tier.to_le_bytes(),
308 slot: slot.to_le_bytes(),
309 }
310 .to_bytes(),
311 }
312}
313
314pub fn upgrade_barracks_shards(signer: Pubkey) -> Instruction {
316 let config_address = config_pda(&program_id()).0;
317 let game_address = game_pda(&program_id()).0;
318 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
319 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
320 let treasury_address = treasury_pda(&program_id()).0;
321 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
322 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
323
324 Instruction {
325 program_id: program_id(),
326 accounts: vec![
327 AccountMeta::new(signer, true),
328 AccountMeta::new_readonly(config_address, false),
329 AccountMeta::new(game_address, false),
330 AccountMeta::new(dojo_address, false),
331 AccountMeta::new(barracks_address, false),
332 AccountMeta::new(user_ata, false),
333 AccountMeta::new(treasury_ata, false),
334 AccountMeta::new(DOJO_MINT, false),
335 AccountMeta::new(treasury_address, false),
336 AccountMeta::new_readonly(spl_token::ID, false),
337 ],
338 data: UpgradeBarracksShards {}.to_bytes(),
339 }
340}
341
342pub fn upgrade_barracks_sol(signer: Pubkey) -> Instruction {
344 let config_address = config_pda(&program_id()).0;
345 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
346 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
347 let treasury_address = treasury_pda(&program_id()).0;
348
349 Instruction {
350 program_id: program_id(),
351 accounts: vec![
352 AccountMeta::new(signer, true),
353 AccountMeta::new_readonly(config_address, false),
354 AccountMeta::new(dojo_address, false),
355 AccountMeta::new(barracks_address, false),
356 AccountMeta::new(treasury_address, false),
357 AccountMeta::new(FEE_COLLECTOR, false),
358 AccountMeta::new_readonly(system_program::ID, false),
359 ],
360 data: UpgradeBarracksSol {}.to_bytes(),
361 }
362}
363
364pub fn upgrade_forge(signer: Pubkey) -> Instruction {
366 let config_address = config_pda(&program_id()).0;
367 let game_address = game_pda(&program_id()).0;
368 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
369 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
370 let treasury_address = treasury_pda(&program_id()).0;
371 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
372 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
373
374 Instruction {
375 program_id: program_id(),
376 accounts: vec![
377 AccountMeta::new(signer, true),
378 AccountMeta::new_readonly(config_address, false),
379 AccountMeta::new(game_address, false),
380 AccountMeta::new(dojo_address, false),
381 AccountMeta::new(forge_address, false),
382 AccountMeta::new(FEE_COLLECTOR, false),
383 AccountMeta::new_readonly(system_program::ID, false),
384 AccountMeta::new(user_ata, false),
385 AccountMeta::new(treasury_ata, false),
386 AccountMeta::new(DOJO_MINT, false),
387 AccountMeta::new(treasury_address, false),
388 AccountMeta::new_readonly(spl_token::ID, false),
389 ],
390 data: UpgradeForge {}.to_bytes(),
391 }
392}
393
394pub fn merge_shogun(
398 signer: Pubkey,
399 merge_type: u64,
400 seed: [u8; 32],
401 prestige: Option<Pubkey>,
402) -> Instruction {
403 let config_address = config_pda(&program_id()).0;
404 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
405 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
406
407 let mut accounts = vec![
408 AccountMeta::new(signer, true),
409 AccountMeta::new_readonly(config_address, false),
410 AccountMeta::new(dojo_address, false),
411 AccountMeta::new(tasks_address, false),
412 ];
413 if let Some(addr) = prestige {
414 accounts.push(AccountMeta::new(addr, false));
415 }
416
417 Instruction {
418 program_id: program_id(),
419 accounts,
420 data: MergeShogun {
421 merge_type: merge_type.to_le_bytes(),
422 seed,
423 }
424 .to_bytes(),
425 }
426}
427
428pub fn prestige_upgrade(signer: Pubkey, slot: u64, prestige: Option<Pubkey>) -> Instruction {
431 let config_address = config_pda(&program_id()).0;
432 let game_address = game_pda(&program_id()).0;
433 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
434 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
435 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
436 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
437
438 let mut accounts = vec![
439 AccountMeta::new(signer, true),
440 AccountMeta::new_readonly(config_address, false),
441 AccountMeta::new(game_address, false),
442 AccountMeta::new(dojo_address, false),
443 AccountMeta::new(barracks_address, false),
444 AccountMeta::new_readonly(mission_address, false),
445 AccountMeta::new(tasks_address, false),
446 ];
447 if let Some(addr) = prestige {
448 accounts.push(AccountMeta::new(addr, false));
449 }
450
451 Instruction {
452 program_id: program_id(),
453 accounts,
454 data: PrestigeUpgrade {
455 slot: slot.to_le_bytes(),
456 }
457 .to_bytes(),
458 }
459}
460
461pub fn level_up_shogun(signer: Pubkey, slot: u64) -> Instruction {
463 let config_address = config_pda(&program_id()).0;
464 let game_address = game_pda(&program_id()).0;
465 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
466 let treasury_address = treasury_pda(&program_id()).0;
467 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
468 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
469 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
470 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
471
472 Instruction {
473 program_id: program_id(),
474 accounts: vec![
475 AccountMeta::new(signer, true),
476 AccountMeta::new_readonly(config_address, false),
477 AccountMeta::new(game_address, false),
478 AccountMeta::new(dojo_address, false),
479 AccountMeta::new(barracks_address, false),
480 AccountMeta::new_readonly(mission_address, false),
481 AccountMeta::new(user_ata, false),
482 AccountMeta::new(treasury_ata, false),
483 AccountMeta::new(DOJO_MINT, false),
484 AccountMeta::new(treasury_address, false),
485 AccountMeta::new_readonly(spl_token::ID, false),
486 ],
487 data: LevelUpShogun {
488 slot: slot.to_le_bytes(),
489 }
490 .to_bytes(),
491 }
492}
493
494pub fn claim_shards(signer: Pubkey) -> Instruction {
497 let config_address = config_pda(&program_id()).0;
498 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
499 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
500 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
501 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
502 let game_address = game_pda(&program_id()).0;
503 let treasury_address = treasury_pda(&program_id()).0;
504 let dojo_ata = get_associated_token_address(&signer, &DOJO_MINT);
505
506 Instruction {
507 program_id: program_id(),
508 accounts: vec![
509 AccountMeta::new(signer, true),
510 AccountMeta::new_readonly(config_address, false),
511 AccountMeta::new(dojo_address, false),
512 AccountMeta::new(forge_address, false),
513 AccountMeta::new(barracks_address, false),
514 AccountMeta::new_readonly(mission_address, false),
515 AccountMeta::new_readonly(game_address, false),
516 AccountMeta::new(dojo_ata, false),
517 AccountMeta::new(DOJO_MINT, false),
518 AccountMeta::new(treasury_address, false),
519 AccountMeta::new_readonly(spl_token::ID, false),
520 ],
521 data: ClaimShards {}.to_bytes(),
522 }
523}
524
525pub fn claim_referral_reward(signer: Pubkey, referrer_dojo: Pubkey) -> Instruction {
527 let (referral_address, _) = referral_pda(&program_id(), &referrer_dojo);
528 let treasury_address = treasury_pda(&program_id()).0;
529
530 Instruction {
531 program_id: program_id(),
532 accounts: vec![
533 AccountMeta::new(signer, true),
534 AccountMeta::new(referrer_dojo, false),
535 AccountMeta::new(referral_address, false),
536 AccountMeta::new(treasury_address, false),
537 AccountMeta::new_readonly(system_program::ID, false),
538 ],
539 data: ClaimReferralReward {}.to_bytes(),
540 }
541}
542
543pub fn claim_recruit_reward(signer: Pubkey) -> Instruction {
545 let config_address = config_pda(&program_id()).0;
546 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
547 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
548
549 Instruction {
550 program_id: program_id(),
551 accounts: vec![
552 AccountMeta::new(signer, true),
553 AccountMeta::new_readonly(config_address, false),
554 AccountMeta::new(dojo_address, false),
555 AccountMeta::new(tasks_address, false),
556 ],
557 data: ClaimRecruitReward {}.to_bytes(),
558 }
559}
560
561pub fn claim_forge_reward(signer: Pubkey) -> Instruction {
563 let config_address = config_pda(&program_id()).0;
564 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
565 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
566
567 Instruction {
568 program_id: program_id(),
569 accounts: vec![
570 AccountMeta::new(signer, true),
571 AccountMeta::new_readonly(config_address, false),
572 AccountMeta::new(dojo_address, false),
573 AccountMeta::new(tasks_address, false),
574 ],
575 data: ClaimForgeReward {}.to_bytes(),
576 }
577}
578
579pub fn claim_dine_reward(signer: Pubkey) -> Instruction {
581 let config_address = config_pda(&program_id()).0;
582 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
583 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
584
585 Instruction {
586 program_id: program_id(),
587 accounts: vec![
588 AccountMeta::new(signer, true),
589 AccountMeta::new_readonly(config_address, false),
590 AccountMeta::new(dojo_address, false),
591 AccountMeta::new(tasks_address, false),
592 ],
593 data: ClaimDineReward {}.to_bytes(),
594 }
595}
596
597pub fn ed25519_verify_instruction_for_daily_claim(
600 dojo_pda: Pubkey,
601 signature: [u8; 64],
602) -> Instruction {
603 use crate::consts::{CLAIM_TASK_PREFIX, DAILY_TASK_START, TASK_VERIFIER};
604 let mut message = Vec::with_capacity(CLAIM_TASK_PREFIX.len() + 32 + 8);
605 message.extend_from_slice(CLAIM_TASK_PREFIX);
606 message.extend_from_slice(dojo_pda.as_ref());
607 message.extend_from_slice(&DAILY_TASK_START.to_le_bytes());
608 let verifier_bytes: [u8; 32] = TASK_VERIFIER.to_bytes();
609 crate::utils::new_ed25519_instruction_with_signature(&message, &signature, &verifier_bytes)
610}
611
612pub fn claim_daily_reward(signer: Pubkey, signature: [u8; 64]) -> Instruction {
615 let config_address = config_pda(&program_id()).0;
616 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
617 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
618 let instructions_sysvar = solana_program::sysvar::instructions::ID;
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(tasks_address, false),
627 AccountMeta::new_readonly(instructions_sysvar, false),
628 ],
629 data: ClaimDailyReward { signature }.to_bytes(),
630 }
631}
632
633pub fn ed25519_verify_instruction_for_off_chain_task(
635 dojo_pda: Pubkey,
636 task_id: u64,
637 signature: [u8; 64],
638) -> Instruction {
639 use crate::consts::{CLAIM_TASK_PREFIX, TASK_VERIFIER};
640 let mut message = Vec::with_capacity(CLAIM_TASK_PREFIX.len() + 32 + 8);
641 message.extend_from_slice(CLAIM_TASK_PREFIX);
642 message.extend_from_slice(dojo_pda.as_ref());
643 message.extend_from_slice(&task_id.to_le_bytes());
644 let verifier_bytes: [u8; 32] = TASK_VERIFIER.to_bytes();
645 crate::utils::new_ed25519_instruction_with_signature(&message, &signature, &verifier_bytes)
646}
647
648pub fn claim_off_chain_task_reward(
651 signer: Pubkey,
652 task_id: u64,
653 signature: [u8; 64],
654) -> Instruction {
655 let config_address = config_pda(&program_id()).0;
656 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
657 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
658 let instructions_sysvar = solana_program::sysvar::instructions::ID;
659
660 Instruction {
661 program_id: program_id(),
662 accounts: vec![
663 AccountMeta::new(signer, true),
664 AccountMeta::new_readonly(config_address, false),
665 AccountMeta::new(dojo_address, false),
666 AccountMeta::new(tasks_address, false),
667 AccountMeta::new_readonly(instructions_sysvar, false),
668 ],
669 data: ClaimOffChainTaskReward {
670 task_id: task_id.to_le_bytes(),
671 signature,
672 }
673 .to_bytes(),
674 }
675}
676
677pub fn claim_seeker_task_reward(
682 signer: Pubkey,
683 signer_sgt_token_account: Pubkey,
684 sgt_mint: Pubkey,
685) -> Instruction {
686 let config_address = config_pda(&program_id()).0;
687 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
688 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
689 let (seeker_address, _) = seeker_pda(&program_id(), &sgt_mint);
690
691 Instruction {
692 program_id: program_id(),
693 accounts: vec![
694 AccountMeta::new(signer, true),
695 AccountMeta::new_readonly(config_address, false),
696 AccountMeta::new(dojo_address, false),
697 AccountMeta::new(tasks_address, false),
698 AccountMeta::new_readonly(signer_sgt_token_account, false),
699 AccountMeta::new_readonly(sgt_mint, false),
700 AccountMeta::new_readonly(spl_token_2022::ID, false),
701 AccountMeta::new(seeker_address, false),
702 AccountMeta::new_readonly(system_program::ID, false),
703 ],
704 data: ClaimSeekerTaskReward {}.to_bytes(),
705 }
706}
707
708pub fn mint_soulbound(
712 signer: Pubkey,
713 signer_sgt_token_account: Pubkey,
714 sgt_mint: Pubkey,
715 soulbound_mint: Pubkey,
716) -> Instruction {
717 let config_address = config_pda(&program_id()).0;
718 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
719 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
720 let (seeker_address, _) = seeker_pda(&program_id(), &sgt_mint);
721 let (treasury_address, _) = treasury_pda(&program_id());
722 let soulbound_token = get_associated_token_address(&signer, &soulbound_mint);
723
724 Instruction {
725 program_id: program_id(),
726 accounts: vec![
727 AccountMeta::new(signer, true),
728 AccountMeta::new_readonly(config_address, false),
729 AccountMeta::new(dojo_address, false),
730 AccountMeta::new(tasks_address, false),
731 AccountMeta::new(seeker_address, false),
732 AccountMeta::new_readonly(signer_sgt_token_account, false),
733 AccountMeta::new_readonly(sgt_mint, false),
734 AccountMeta::new(soulbound_mint, true), AccountMeta::new_readonly(treasury_address, false),
736 AccountMeta::new(DGT_GROUP, false), AccountMeta::new(soulbound_token, false),
738 AccountMeta::new_readonly(spl_token_2022::ID, false),
739 AccountMeta::new_readonly(system_program::ID, false),
740 AccountMeta::new_readonly(spl_associated_token_account::ID, false),
741 ],
742 data: MintSoulbound {}.to_bytes(),
743 }
744}
745
746pub fn start_mission(signer: Pubkey, mission_type: u64, slot_mask: u64) -> Instruction {
750 let config_address = config_pda(&program_id()).0;
751 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
752 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
753 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
754 let game_address = game_pda(&program_id()).0;
755 let treasury_address = treasury_pda(&program_id()).0;
756 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
757 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
758
759 Instruction {
760 program_id: program_id(),
761 accounts: vec![
762 AccountMeta::new(signer, true),
763 AccountMeta::new_readonly(config_address, false),
764 AccountMeta::new(dojo_address, false),
765 AccountMeta::new(barracks_address, false),
766 AccountMeta::new(mission_address, false),
767 AccountMeta::new(game_address, false),
768 AccountMeta::new(user_ata, false),
769 AccountMeta::new(treasury_ata, false),
770 AccountMeta::new(DOJO_MINT, false),
771 AccountMeta::new(treasury_address, false),
772 AccountMeta::new_readonly(spl_token::ID, false),
773 AccountMeta::new_readonly(system_program::ID, false),
774 ],
775 data: StartMission {
776 mission_type: mission_type.to_le_bytes(),
777 slot_mask: slot_mask.to_le_bytes(),
778 }
779 .to_bytes(),
780 }
781}
782
783pub fn claim_mission_reward(
785 signer: Pubkey,
786 mission_index: u64,
787 seed: [u8; 32],
788 prestige: Option<Pubkey>,
789) -> Instruction {
790 let config_address = config_pda(&program_id()).0;
791 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
792 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
793 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
794 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
795 let game_address = game_pda(&program_id()).0;
796 let treasury_address = treasury_pda(&program_id()).0;
797 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
798 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
799
800 let mut accounts = vec![
801 AccountMeta::new(signer, true),
802 AccountMeta::new_readonly(config_address, false),
803 AccountMeta::new(dojo_address, false),
804 AccountMeta::new_readonly(barracks_address, false),
805 AccountMeta::new(mission_address, false),
806 AccountMeta::new(game_address, false),
807 AccountMeta::new(tasks_address, false),
808 AccountMeta::new(user_ata, false),
809 AccountMeta::new(DOJO_MINT, false),
810 AccountMeta::new(treasury_address, false),
811 AccountMeta::new(treasury_ata, false),
812 AccountMeta::new_readonly(spl_token::ID, false),
813 ];
814 if let Some(addr) = prestige {
815 accounts.push(AccountMeta::new(addr, false));
816 }
817
818 Instruction {
819 program_id: program_id(),
820 accounts,
821 data: ClaimMissionReward {
822 mission_index: mission_index.to_le_bytes(),
823 seed,
824 }
825 .to_bytes(),
826 }
827}
828
829pub fn claim_collection_reward(signer: Pubkey, collection_index: u8) -> Instruction {
832 let config_address = config_pda(&program_id()).0;
833 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
834 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
835
836 Instruction {
837 program_id: program_id(),
838 accounts: vec![
839 AccountMeta::new(signer, true),
840 AccountMeta::new_readonly(config_address, false),
841 AccountMeta::new(dojo_address, false),
842 AccountMeta::new(tasks_address, false),
843 ],
844 data: ClaimCollectionReward { collection_index }.to_bytes(),
845 }
846}
847
848pub fn buy_flash_sale(signer: Pubkey) -> Instruction {
850 let config_address = config_pda(&program_id()).0;
851 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
852 let treasury_address = treasury_pda(&program_id()).0;
853 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
854 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
855
856 Instruction {
857 program_id: program_id(),
858 accounts: vec![
859 AccountMeta::new(signer, true),
860 AccountMeta::new_readonly(config_address, false),
861 AccountMeta::new(dojo_address, false),
862 AccountMeta::new(user_ata, false),
863 AccountMeta::new_readonly(treasury_address, false),
864 AccountMeta::new(treasury_ata, false),
865 AccountMeta::new_readonly(spl_token::ID, false),
866 ],
867 data: BuyFlashSale {}.to_bytes(),
868 }
869}
870
871pub fn buy_tickets_with_shards(signer: Pubkey) -> Instruction {
873 let config_address = config_pda(&program_id()).0;
874 let game_address = game_pda(&program_id()).0;
875 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
876 let treasury_address = treasury_pda(&program_id()).0;
877 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
878 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
879
880 Instruction {
881 program_id: program_id(),
882 accounts: vec![
883 AccountMeta::new(signer, true),
884 AccountMeta::new_readonly(config_address, false),
885 AccountMeta::new(game_address, false),
886 AccountMeta::new(dojo_address, false),
887 AccountMeta::new(user_ata, false),
888 AccountMeta::new(treasury_ata, false),
889 AccountMeta::new(DOJO_MINT, false),
890 AccountMeta::new(treasury_address, false),
891 AccountMeta::new_readonly(spl_token::ID, false),
892 ],
893 data: BuyTicketsWithShards {}.to_bytes(),
894 }
895}
896
897pub fn buy_bundle(signer: Pubkey) -> Instruction {
899 let config_address = config_pda(&program_id()).0;
900 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
901 let treasury_address = treasury_pda(&program_id()).0;
902
903 Instruction {
904 program_id: program_id(),
905 accounts: vec![
906 AccountMeta::new(signer, true),
907 AccountMeta::new_readonly(config_address, false),
908 AccountMeta::new(dojo_address, false),
909 AccountMeta::new(treasury_address, false),
910 AccountMeta::new(FEE_COLLECTOR, false),
911 AccountMeta::new_readonly(system_program::ID, false),
912 ],
913 data: BuyBundle {}.to_bytes(),
914 }
915}
916
917pub fn clear_forge_cooldown(signer: Pubkey) -> Instruction {
919 let config_address = config_pda(&program_id()).0;
920 let game_address = game_pda(&program_id()).0;
921 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
922 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
923 let treasury_address = treasury_pda(&program_id()).0;
924 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
925 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
926
927 Instruction {
928 program_id: program_id(),
929 accounts: vec![
930 AccountMeta::new(signer, true),
931 AccountMeta::new_readonly(config_address, false),
932 AccountMeta::new(game_address, false),
933 AccountMeta::new(dojo_address, false),
934 AccountMeta::new(forge_address, false),
935 AccountMeta::new(user_ata, false),
936 AccountMeta::new(treasury_ata, false),
937 AccountMeta::new(DOJO_MINT, false),
938 AccountMeta::new(treasury_address, false),
939 AccountMeta::new_readonly(spl_token::ID, false),
940 ],
941 data: ClearForgeCooldown {}.to_bytes(),
942 }
943}
944
945pub fn set_genesis_slot(authority: Pubkey, genesis_slot: u64, halving_period_slots: u64) -> Instruction {
947 let config_address = config_pda(&program_id()).0;
948 let game_address = game_pda(&program_id()).0;
949
950 Instruction {
951 program_id: program_id(),
952 accounts: vec![
953 AccountMeta::new(authority, true),
954 AccountMeta::new(config_address, false),
955 AccountMeta::new(game_address, false),
956 ],
957 data: SetGenesisSlot {
958 genesis_slot: genesis_slot.to_le_bytes(),
959 halving_period_slots: halving_period_slots.to_le_bytes(),
960 }
961 .to_bytes(),
962 }
963}
964
965pub fn roll_scene_section_amethyst(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
968 let config_address = config_pda(&program_id()).0;
969 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
970 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
971
972 Instruction {
973 program_id: program_id(),
974 accounts: vec![
975 AccountMeta::new(signer, true),
976 AccountMeta::new_readonly(config_address, false),
977 AccountMeta::new(dojo_address, false),
978 AccountMeta::new(scenes_address, false),
979 AccountMeta::new_readonly(system_program::ID, false),
980 ],
981 data: RollSceneSectionAmethyst {
982 count: count.to_le_bytes(),
983 seed,
984 }
985 .to_bytes(),
986 }
987}
988
989pub fn roll_scene_section_shards(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
992 let config_address = config_pda(&program_id()).0;
993 let game_address = game_pda(&program_id()).0;
994 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
995 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
996 let treasury_address = treasury_pda(&program_id()).0;
997 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
998 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
999
1000 Instruction {
1001 program_id: program_id(),
1002 accounts: vec![
1003 AccountMeta::new(signer, true),
1004 AccountMeta::new_readonly(config_address, false),
1005 AccountMeta::new(game_address, false),
1006 AccountMeta::new(dojo_address, false),
1007 AccountMeta::new(scenes_address, false),
1008 AccountMeta::new(user_ata, false),
1009 AccountMeta::new(treasury_ata, false),
1010 AccountMeta::new(DOJO_MINT, false),
1011 AccountMeta::new(treasury_address, false),
1012 AccountMeta::new_readonly(spl_token::ID, false),
1013 AccountMeta::new_readonly(system_program::ID, false),
1014 ],
1015 data: RollSceneSectionShards {
1016 count: count.to_le_bytes(),
1017 seed,
1018 }
1019 .to_bytes(),
1020 }
1021}
1022
1023pub fn salvage_scene_section(signer: Pubkey) -> Instruction {
1025 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1026 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1027
1028 Instruction {
1029 program_id: program_id(),
1030 accounts: vec![
1031 AccountMeta::new(signer, true),
1032 AccountMeta::new(dojo_address, false),
1033 AccountMeta::new(scenes_address, false),
1034 ],
1035 data: SalvageSceneSection {}.to_bytes(),
1036 }
1037}
1038
1039pub fn update_active_scene(signer: Pubkey, scene_id: u64) -> Instruction {
1042 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1043 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1044 let game_address = game_pda(&program_id()).0;
1045 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
1046
1047 Instruction {
1048 program_id: program_id(),
1049 accounts: vec![
1050 AccountMeta::new(signer, true),
1051 AccountMeta::new(dojo_address, false),
1052 AccountMeta::new(scenes_address, false),
1053 AccountMeta::new(game_address, false),
1054 AccountMeta::new(barracks_address, false),
1055 ],
1056 data: UpdateActiveScene {
1057 scene_id: scene_id.to_le_bytes(),
1058 }
1059 .to_bytes(),
1060 }
1061}
1062
1063pub fn buy_chest(signer: Pubkey) -> Instruction {
1065 let config_address = config_pda(&program_id()).0;
1066 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1067 let treasury_address = treasury_pda(&program_id()).0;
1068
1069 Instruction {
1070 program_id: program_id(),
1071 accounts: vec![
1072 AccountMeta::new(signer, true),
1073 AccountMeta::new_readonly(config_address, false),
1074 AccountMeta::new(dojo_address, false),
1075 AccountMeta::new(treasury_address, false),
1076 AccountMeta::new(FEE_COLLECTOR, false),
1077 AccountMeta::new_readonly(system_program::ID, false),
1078 ],
1079 data: BuyChest {}.to_bytes(),
1080 }
1081}
1082
1083pub fn buy_scene(signer: Pubkey, scene_id: u64) -> Instruction {
1085 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1086 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1087
1088 Instruction {
1089 program_id: program_id(),
1090 accounts: vec![
1091 AccountMeta::new(signer, true),
1092 AccountMeta::new(dojo_address, false),
1093 AccountMeta::new(scenes_address, false),
1094 AccountMeta::new_readonly(system_program::ID, false),
1095 ],
1096 data: BuyScene {
1097 scene_id: scene_id.to_le_bytes(),
1098 }
1099 .to_bytes(),
1100 }
1101}
1102
1103pub fn buy_scene_dojo(signer: Pubkey, scene_id: u64) -> Instruction {
1105 let config_address = config_pda(&program_id()).0;
1106 let (game_address, _) = game_pda(&program_id());
1107 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1108 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1109 let treasury_address = treasury_pda(&program_id()).0;
1110 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
1111 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
1112
1113 Instruction {
1114 program_id: program_id(),
1115 accounts: vec![
1116 AccountMeta::new(signer, true),
1117 AccountMeta::new_readonly(config_address, false),
1118 AccountMeta::new(game_address, false),
1119 AccountMeta::new(dojo_address, false),
1120 AccountMeta::new(scenes_address, false),
1121 AccountMeta::new(user_ata, false),
1122 AccountMeta::new(treasury_ata, false),
1123 AccountMeta::new(DOJO_MINT, false),
1124 AccountMeta::new(treasury_address, false),
1125 AccountMeta::new_readonly(spl_token::ID, false),
1126 AccountMeta::new_readonly(system_program::ID, false),
1127 ],
1128 data: BuySceneDojo {
1129 scene_id: scene_id.to_le_bytes(),
1130 }
1131 .to_bytes(),
1132 }
1133}
1134
1135pub fn log(config: Pubkey, msg: &[u8]) -> Instruction {
1137 let mut data = Log {
1138 _reserved: [0u8; 8],
1139 }
1140 .to_bytes();
1141 data.extend_from_slice(msg);
1142 Instruction {
1143 program_id: program_id(),
1144 accounts: vec![AccountMeta::new(config, true)],
1145 data,
1146 }
1147}