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_mission_task_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: ClaimMissionTaskReward {}.to_bytes(),
594 }
595}
596
597pub fn claim_dine_reward(signer: Pubkey) -> Instruction {
599 let config_address = config_pda(&program_id()).0;
600 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
601 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
602
603 Instruction {
604 program_id: program_id(),
605 accounts: vec![
606 AccountMeta::new(signer, true),
607 AccountMeta::new_readonly(config_address, false),
608 AccountMeta::new(dojo_address, false),
609 AccountMeta::new(tasks_address, false),
610 ],
611 data: ClaimDineReward {}.to_bytes(),
612 }
613}
614
615pub fn ed25519_verify_instruction_for_daily_claim(
618 dojo_pda: Pubkey,
619 signature: [u8; 64],
620) -> Instruction {
621 use crate::consts::{CLAIM_TASK_PREFIX, DAILY_TASK_START, TASK_VERIFIER};
622 let mut message = Vec::with_capacity(CLAIM_TASK_PREFIX.len() + 32 + 8);
623 message.extend_from_slice(CLAIM_TASK_PREFIX);
624 message.extend_from_slice(dojo_pda.as_ref());
625 message.extend_from_slice(&DAILY_TASK_START.to_le_bytes());
626 let verifier_bytes: [u8; 32] = TASK_VERIFIER.to_bytes();
627 crate::utils::new_ed25519_instruction_with_signature(&message, &signature, &verifier_bytes)
628}
629
630pub fn claim_daily_reward(signer: Pubkey, signature: [u8; 64]) -> Instruction {
633 let config_address = config_pda(&program_id()).0;
634 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
635 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
636 let instructions_sysvar = solana_program::sysvar::instructions::ID;
637
638 Instruction {
639 program_id: program_id(),
640 accounts: vec![
641 AccountMeta::new(signer, true),
642 AccountMeta::new_readonly(config_address, false),
643 AccountMeta::new(dojo_address, false),
644 AccountMeta::new(tasks_address, false),
645 AccountMeta::new_readonly(instructions_sysvar, false),
646 ],
647 data: ClaimDailyReward { signature }.to_bytes(),
648 }
649}
650
651pub fn ed25519_verify_instruction_for_off_chain_task(
653 dojo_pda: Pubkey,
654 task_id: u64,
655 signature: [u8; 64],
656) -> Instruction {
657 use crate::consts::{CLAIM_TASK_PREFIX, TASK_VERIFIER};
658 let mut message = Vec::with_capacity(CLAIM_TASK_PREFIX.len() + 32 + 8);
659 message.extend_from_slice(CLAIM_TASK_PREFIX);
660 message.extend_from_slice(dojo_pda.as_ref());
661 message.extend_from_slice(&task_id.to_le_bytes());
662 let verifier_bytes: [u8; 32] = TASK_VERIFIER.to_bytes();
663 crate::utils::new_ed25519_instruction_with_signature(&message, &signature, &verifier_bytes)
664}
665
666pub fn claim_off_chain_task_reward(
669 signer: Pubkey,
670 task_id: u64,
671 signature: [u8; 64],
672) -> Instruction {
673 let config_address = config_pda(&program_id()).0;
674 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
675 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
676 let instructions_sysvar = solana_program::sysvar::instructions::ID;
677
678 Instruction {
679 program_id: program_id(),
680 accounts: vec![
681 AccountMeta::new(signer, true),
682 AccountMeta::new_readonly(config_address, false),
683 AccountMeta::new(dojo_address, false),
684 AccountMeta::new(tasks_address, false),
685 AccountMeta::new_readonly(instructions_sysvar, false),
686 ],
687 data: ClaimOffChainTaskReward {
688 task_id: task_id.to_le_bytes(),
689 signature,
690 }
691 .to_bytes(),
692 }
693}
694
695pub fn claim_seeker_task_reward(
700 signer: Pubkey,
701 signer_sgt_token_account: Pubkey,
702 sgt_mint: Pubkey,
703) -> Instruction {
704 let config_address = config_pda(&program_id()).0;
705 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
706 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
707 let (seeker_address, _) = seeker_pda(&program_id(), &sgt_mint);
708
709 Instruction {
710 program_id: program_id(),
711 accounts: vec![
712 AccountMeta::new(signer, true),
713 AccountMeta::new_readonly(config_address, false),
714 AccountMeta::new(dojo_address, false),
715 AccountMeta::new(tasks_address, false),
716 AccountMeta::new_readonly(signer_sgt_token_account, false),
717 AccountMeta::new_readonly(sgt_mint, false),
718 AccountMeta::new_readonly(spl_token_2022::ID, false),
719 AccountMeta::new(seeker_address, false),
720 AccountMeta::new_readonly(system_program::ID, false),
721 ],
722 data: ClaimSeekerTaskReward {}.to_bytes(),
723 }
724}
725
726pub fn mint_soulbound(
730 signer: Pubkey,
731 signer_sgt_token_account: Pubkey,
732 sgt_mint: Pubkey,
733 soulbound_mint: Pubkey,
734) -> Instruction {
735 let config_address = config_pda(&program_id()).0;
736 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
737 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
738 let (seeker_address, _) = seeker_pda(&program_id(), &sgt_mint);
739 let (treasury_address, _) = treasury_pda(&program_id());
740 let soulbound_token = get_associated_token_address(&signer, &soulbound_mint);
741
742 Instruction {
743 program_id: program_id(),
744 accounts: vec![
745 AccountMeta::new(signer, true),
746 AccountMeta::new_readonly(config_address, false),
747 AccountMeta::new(dojo_address, false),
748 AccountMeta::new(tasks_address, false),
749 AccountMeta::new(seeker_address, false),
750 AccountMeta::new_readonly(signer_sgt_token_account, false),
751 AccountMeta::new_readonly(sgt_mint, false),
752 AccountMeta::new(soulbound_mint, true), AccountMeta::new_readonly(treasury_address, false),
754 AccountMeta::new(DGT_GROUP, false), AccountMeta::new(soulbound_token, false),
756 AccountMeta::new_readonly(spl_token_2022::ID, false),
757 AccountMeta::new_readonly(system_program::ID, false),
758 AccountMeta::new_readonly(spl_associated_token_account::ID, false),
759 ],
760 data: MintSoulbound {}.to_bytes(),
761 }
762}
763
764pub fn start_mission(signer: Pubkey, mission_type: u64, slot_mask: u64) -> Instruction {
768 let config_address = config_pda(&program_id()).0;
769 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
770 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
771 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
772 let game_address = game_pda(&program_id()).0;
773 let treasury_address = treasury_pda(&program_id()).0;
774 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
775 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
776
777 Instruction {
778 program_id: program_id(),
779 accounts: vec![
780 AccountMeta::new(signer, true),
781 AccountMeta::new_readonly(config_address, false),
782 AccountMeta::new(dojo_address, false),
783 AccountMeta::new(barracks_address, false),
784 AccountMeta::new(mission_address, false),
785 AccountMeta::new(game_address, false),
786 AccountMeta::new(user_ata, false),
787 AccountMeta::new(treasury_ata, false),
788 AccountMeta::new(DOJO_MINT, false),
789 AccountMeta::new(treasury_address, false),
790 AccountMeta::new_readonly(spl_token::ID, false),
791 AccountMeta::new_readonly(system_program::ID, false),
792 ],
793 data: StartMission {
794 mission_type: mission_type.to_le_bytes(),
795 slot_mask: slot_mask.to_le_bytes(),
796 }
797 .to_bytes(),
798 }
799}
800
801pub fn claim_mission_reward(
803 signer: Pubkey,
804 mission_index: u64,
805 seed: [u8; 32],
806 prestige: Option<Pubkey>,
807) -> Instruction {
808 let config_address = config_pda(&program_id()).0;
809 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
810 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
811 let (mission_address, _) = mission_pda(&program_id(), &dojo_address);
812 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
813 let game_address = game_pda(&program_id()).0;
814 let treasury_address = treasury_pda(&program_id()).0;
815 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
816 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
817
818 let mut accounts = vec![
819 AccountMeta::new(signer, true),
820 AccountMeta::new_readonly(config_address, false),
821 AccountMeta::new(dojo_address, false),
822 AccountMeta::new_readonly(barracks_address, false),
823 AccountMeta::new(mission_address, false),
824 AccountMeta::new(game_address, false),
825 AccountMeta::new(tasks_address, false),
826 AccountMeta::new(user_ata, false),
827 AccountMeta::new(DOJO_MINT, false),
828 AccountMeta::new(treasury_address, false),
829 AccountMeta::new(treasury_ata, false),
830 AccountMeta::new_readonly(spl_token::ID, false),
831 ];
832 if let Some(addr) = prestige {
833 accounts.push(AccountMeta::new(addr, false));
834 }
835
836 Instruction {
837 program_id: program_id(),
838 accounts,
839 data: ClaimMissionReward {
840 mission_index: mission_index.to_le_bytes(),
841 seed,
842 }
843 .to_bytes(),
844 }
845}
846
847pub fn claim_collection_reward(signer: Pubkey, collection_index: u8) -> Instruction {
850 let config_address = config_pda(&program_id()).0;
851 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
852 let (tasks_address, _) = tasks_pda(&program_id(), &dojo_address);
853
854 Instruction {
855 program_id: program_id(),
856 accounts: vec![
857 AccountMeta::new(signer, true),
858 AccountMeta::new_readonly(config_address, false),
859 AccountMeta::new(dojo_address, false),
860 AccountMeta::new(tasks_address, false),
861 ],
862 data: ClaimCollectionReward { collection_index }.to_bytes(),
863 }
864}
865
866pub fn buy_flash_sale(signer: Pubkey) -> Instruction {
868 let config_address = config_pda(&program_id()).0;
869 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
870 let treasury_address = treasury_pda(&program_id()).0;
871 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
872 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
873
874 Instruction {
875 program_id: program_id(),
876 accounts: vec![
877 AccountMeta::new(signer, true),
878 AccountMeta::new_readonly(config_address, false),
879 AccountMeta::new(dojo_address, false),
880 AccountMeta::new(user_ata, false),
881 AccountMeta::new_readonly(treasury_address, false),
882 AccountMeta::new(treasury_ata, false),
883 AccountMeta::new_readonly(spl_token::ID, false),
884 ],
885 data: BuyFlashSale {}.to_bytes(),
886 }
887}
888
889pub fn buy_tickets_with_shards(signer: Pubkey) -> Instruction {
891 let config_address = config_pda(&program_id()).0;
892 let game_address = game_pda(&program_id()).0;
893 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
894 let treasury_address = treasury_pda(&program_id()).0;
895 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
896 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
897
898 Instruction {
899 program_id: program_id(),
900 accounts: vec![
901 AccountMeta::new(signer, true),
902 AccountMeta::new_readonly(config_address, false),
903 AccountMeta::new(game_address, false),
904 AccountMeta::new(dojo_address, false),
905 AccountMeta::new(user_ata, false),
906 AccountMeta::new(treasury_ata, false),
907 AccountMeta::new(DOJO_MINT, false),
908 AccountMeta::new(treasury_address, false),
909 AccountMeta::new_readonly(spl_token::ID, false),
910 ],
911 data: BuyTicketsWithShards {}.to_bytes(),
912 }
913}
914
915pub fn buy_bundle(signer: Pubkey) -> Instruction {
917 let config_address = config_pda(&program_id()).0;
918 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
919 let treasury_address = treasury_pda(&program_id()).0;
920
921 Instruction {
922 program_id: program_id(),
923 accounts: vec![
924 AccountMeta::new(signer, true),
925 AccountMeta::new_readonly(config_address, false),
926 AccountMeta::new(dojo_address, false),
927 AccountMeta::new(treasury_address, false),
928 AccountMeta::new(FEE_COLLECTOR, false),
929 AccountMeta::new_readonly(system_program::ID, false),
930 ],
931 data: BuyBundle {}.to_bytes(),
932 }
933}
934
935pub fn clear_forge_cooldown(signer: Pubkey) -> Instruction {
937 let config_address = config_pda(&program_id()).0;
938 let game_address = game_pda(&program_id()).0;
939 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
940 let (forge_address, _) = forge_pda(&program_id(), &dojo_address);
941 let treasury_address = treasury_pda(&program_id()).0;
942 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
943 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
944
945 Instruction {
946 program_id: program_id(),
947 accounts: vec![
948 AccountMeta::new(signer, true),
949 AccountMeta::new_readonly(config_address, false),
950 AccountMeta::new(game_address, false),
951 AccountMeta::new(dojo_address, false),
952 AccountMeta::new(forge_address, false),
953 AccountMeta::new(user_ata, false),
954 AccountMeta::new(treasury_ata, false),
955 AccountMeta::new(DOJO_MINT, false),
956 AccountMeta::new(treasury_address, false),
957 AccountMeta::new_readonly(spl_token::ID, false),
958 ],
959 data: ClearForgeCooldown {}.to_bytes(),
960 }
961}
962
963pub fn set_genesis_slot(authority: Pubkey, genesis_slot: u64, halving_period_slots: u64) -> Instruction {
965 let config_address = config_pda(&program_id()).0;
966 let game_address = game_pda(&program_id()).0;
967
968 Instruction {
969 program_id: program_id(),
970 accounts: vec![
971 AccountMeta::new(authority, true),
972 AccountMeta::new(config_address, false),
973 AccountMeta::new(game_address, false),
974 ],
975 data: SetGenesisSlot {
976 genesis_slot: genesis_slot.to_le_bytes(),
977 halving_period_slots: halving_period_slots.to_le_bytes(),
978 }
979 .to_bytes(),
980 }
981}
982
983pub fn roll_scene_section_amethyst(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
986 let config_address = config_pda(&program_id()).0;
987 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
988 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
989
990 Instruction {
991 program_id: program_id(),
992 accounts: vec![
993 AccountMeta::new(signer, true),
994 AccountMeta::new_readonly(config_address, false),
995 AccountMeta::new(dojo_address, false),
996 AccountMeta::new(scenes_address, false),
997 AccountMeta::new_readonly(system_program::ID, false),
998 ],
999 data: RollSceneSectionAmethyst {
1000 count: count.to_le_bytes(),
1001 seed,
1002 }
1003 .to_bytes(),
1004 }
1005}
1006
1007pub fn roll_scene_section_shards(signer: Pubkey, count: u64, seed: [u8; 32]) -> Instruction {
1010 let config_address = config_pda(&program_id()).0;
1011 let game_address = game_pda(&program_id()).0;
1012 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1013 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1014 let treasury_address = treasury_pda(&program_id()).0;
1015 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
1016 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
1017
1018 Instruction {
1019 program_id: program_id(),
1020 accounts: vec![
1021 AccountMeta::new(signer, true),
1022 AccountMeta::new_readonly(config_address, false),
1023 AccountMeta::new(game_address, false),
1024 AccountMeta::new(dojo_address, false),
1025 AccountMeta::new(scenes_address, false),
1026 AccountMeta::new(user_ata, false),
1027 AccountMeta::new(treasury_ata, false),
1028 AccountMeta::new(DOJO_MINT, false),
1029 AccountMeta::new(treasury_address, false),
1030 AccountMeta::new_readonly(spl_token::ID, false),
1031 AccountMeta::new_readonly(system_program::ID, false),
1032 ],
1033 data: RollSceneSectionShards {
1034 count: count.to_le_bytes(),
1035 seed,
1036 }
1037 .to_bytes(),
1038 }
1039}
1040
1041pub fn salvage_scene_section(signer: Pubkey) -> Instruction {
1043 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1044 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1045
1046 Instruction {
1047 program_id: program_id(),
1048 accounts: vec![
1049 AccountMeta::new(signer, true),
1050 AccountMeta::new(dojo_address, false),
1051 AccountMeta::new(scenes_address, false),
1052 ],
1053 data: SalvageSceneSection {}.to_bytes(),
1054 }
1055}
1056
1057pub fn update_active_scene(signer: Pubkey, scene_id: u64) -> Instruction {
1060 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1061 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1062 let game_address = game_pda(&program_id()).0;
1063 let (barracks_address, _) = barracks_pda(&program_id(), &dojo_address);
1064
1065 Instruction {
1066 program_id: program_id(),
1067 accounts: vec![
1068 AccountMeta::new(signer, true),
1069 AccountMeta::new(dojo_address, false),
1070 AccountMeta::new(scenes_address, false),
1071 AccountMeta::new(game_address, false),
1072 AccountMeta::new(barracks_address, false),
1073 ],
1074 data: UpdateActiveScene {
1075 scene_id: scene_id.to_le_bytes(),
1076 }
1077 .to_bytes(),
1078 }
1079}
1080
1081pub fn buy_chest(signer: Pubkey) -> Instruction {
1083 let config_address = config_pda(&program_id()).0;
1084 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1085 let treasury_address = treasury_pda(&program_id()).0;
1086
1087 Instruction {
1088 program_id: program_id(),
1089 accounts: vec![
1090 AccountMeta::new(signer, true),
1091 AccountMeta::new_readonly(config_address, false),
1092 AccountMeta::new(dojo_address, false),
1093 AccountMeta::new(treasury_address, false),
1094 AccountMeta::new(FEE_COLLECTOR, false),
1095 AccountMeta::new_readonly(system_program::ID, false),
1096 ],
1097 data: BuyChest {}.to_bytes(),
1098 }
1099}
1100
1101pub fn buy_scene(signer: Pubkey, scene_id: u64) -> Instruction {
1103 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1104 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1105
1106 Instruction {
1107 program_id: program_id(),
1108 accounts: vec![
1109 AccountMeta::new(signer, true),
1110 AccountMeta::new(dojo_address, false),
1111 AccountMeta::new(scenes_address, false),
1112 AccountMeta::new_readonly(system_program::ID, false),
1113 ],
1114 data: BuyScene {
1115 scene_id: scene_id.to_le_bytes(),
1116 }
1117 .to_bytes(),
1118 }
1119}
1120
1121pub fn buy_scene_dojo(signer: Pubkey, scene_id: u64) -> Instruction {
1123 let config_address = config_pda(&program_id()).0;
1124 let (game_address, _) = game_pda(&program_id());
1125 let (dojo_address, _) = dojo_pda(&program_id(), &signer);
1126 let (scenes_address, _) = scenes_pda(&program_id(), &dojo_address);
1127 let treasury_address = treasury_pda(&program_id()).0;
1128 let user_ata = get_associated_token_address(&signer, &DOJO_MINT);
1129 let treasury_ata = get_associated_token_address(&treasury_address, &DOJO_MINT);
1130
1131 Instruction {
1132 program_id: program_id(),
1133 accounts: vec![
1134 AccountMeta::new(signer, true),
1135 AccountMeta::new_readonly(config_address, false),
1136 AccountMeta::new(game_address, false),
1137 AccountMeta::new(dojo_address, false),
1138 AccountMeta::new(scenes_address, false),
1139 AccountMeta::new(user_ata, false),
1140 AccountMeta::new(treasury_ata, false),
1141 AccountMeta::new(DOJO_MINT, false),
1142 AccountMeta::new(treasury_address, false),
1143 AccountMeta::new_readonly(spl_token::ID, false),
1144 AccountMeta::new_readonly(system_program::ID, false),
1145 ],
1146 data: BuySceneDojo {
1147 scene_id: scene_id.to_le_bytes(),
1148 }
1149 .to_bytes(),
1150 }
1151}
1152
1153pub fn log(config: Pubkey, msg: &[u8]) -> Instruction {
1155 let mut data = Log {
1156 _reserved: [0u8; 8],
1157 }
1158 .to_bytes();
1159 data.extend_from_slice(msg);
1160 Instruction {
1161 program_id: program_id(),
1162 accounts: vec![AccountMeta::new(config, true)],
1163 data,
1164 }
1165}