Skip to main content

tengu_api/
consts.rs

1//! PDA seeds and constants.
2
3use solana_program::pubkey::Pubkey;
4use solana_program::pubkey;
5
6pub const ADMIN_ADDRESS: Pubkey = pubkey!("DEvGq2WVuA3qkSCtwwuMYThY4onkJunEHSAxU5cieph8");
7pub const FEE_COLLECTOR: Pubkey = pubkey!("FEEjHM2DoFu6UifSBmrxTQ6X2KkWQ1dbPXASCtdLUdnx");
8/// SOL payment split: treasury gets this share (basis points). 9000 = 90%.
9pub const SOL_SPLIT_TREASURY_BPS: u64 = 9000;
10/// SOL payment split: fee collector gets this share (basis points). 1000 = 10%.
11pub const SOL_SPLIT_FEE_BPS: u64 = 1000;
12
13pub const TASK_VERIFIER: Pubkey = pubkey!("tASK7746ambmkkTvqtyCehd3F56X4VJpr9GCPh4bUmu");
14/// $DOJO SPL token mint. Matches ui constants.ts DOJO_MINT.
15pub const DOJO_MINT: Pubkey = pubkey!("ShardMNKCZTxGVpnsJEL6tapMhf7DCM7WMqW7kADwQ8");
16
17/// Dojos Genesis Token (DGT) group mint. Soulbound mints have TokenGroupMember.group == this.
18pub const DGT_GROUP: Pubkey = pubkey!("DGT1rCDvLYEmasQJ2M9naJ2iakFrsS4Vn4XvmNWJREje");
19
20/// Seeker Genesis Token (SGT) group from Solana Mobile. Used to detect Seeker users. Matches ui SGT_GROUP.
21pub const SGT_GROUP: Pubkey = pubkey!("GT22s89nU4iWFkNXj1Bw6uYhJJWDRPpShHt4Bk8f99Te");
22
23pub const CONFIG: &[u8] = b"config";
24pub const GAME: &[u8] = b"game";
25pub const DOJO: &[u8] = b"dojo";
26pub const SHOGUN: &[u8] = b"shogun";
27pub const BARRACKS: &[u8] = b"barracks";
28pub const MISSION: &[u8] = b"mission";
29pub const FORGE: &[u8] = b"forge";
30pub const TASKS: &[u8] = b"tasks";
31pub const TREASURY: &[u8] = b"treasury";
32pub const REFERRAL: &[u8] = b"referral";
33pub const PRESTIGE: &[u8] = b"prestige";
34/// Seeker: one account per SGT mint that has claimed the Seeker task (anti-Sybil).
35pub const SEEKER: &[u8] = b"seeker";
36/// Prestige levels for fodder (1–6). Index = collection_index * PRESTIGE_LEVELS + (prestige - 1).
37pub const PRESTIGE_LEVELS: usize = 6;
38
39pub const ED25519_SIGNATURE_OFFSETS_START: usize = 2;
40pub const ED25519_SIGNATURE_OFFSETS_SIZE: usize = 14;
41pub const ED25519_DATA_START: usize = ED25519_SIGNATURE_OFFSETS_START + ED25519_SIGNATURE_OFFSETS_SIZE;
42pub const ED25519_PUBKEY_SIZE: usize = 32;
43pub const ED25519_SIGNATURE_SIZE: usize = 64;
44
45/// Solana: ~0.4s per slot. Ore/chakra/cooldowns use Solana slots.
46pub const SECONDS_PER_SLOT: f64 = 0.4;
47/// Slots in 24h (86400 / 0.4 ≈ 216000).
48pub const ONE_DAY_SLOTS: u64 = 216_000;
49pub const CHAKRA_MAX: u64 = ONE_DAY_SLOTS;
50/// Chakra granted per dine tier: 24h, 48h, 72h.
51pub const CHAKRA_24H: u64 = ONE_DAY_SLOTS;
52pub const CHAKRA_48H: u64 = 2 * ONE_DAY_SLOTS;
53pub const CHAKRA_72H: u64 = 3 * ONE_DAY_SLOTS;
54/// Ore = (spirit_power * slots_elapsed) / ORE_DIVISOR. 200 = 0.5x vs Ninja (Solana 2x faster).
55pub const ORE_DIVISOR: u64 = 200;
56/// Pool-split: raw $DOJO emission per slot (6 decimals). Hyper Ninja: 1000/block × 8640 blocks/day = 8.64M/day; Solana 216k slots/day → 40/slot.
57pub const EMISSION_RAW_PER_SLOT_BASE: u64 = 40_000_000;
58pub const DOJO_DECIMALS: u8 = 6;
59/// One $DOJO token, denominated in raw units (6 decimals).
60pub const ONE_DOJO: u64 = 10u64.pow(DOJO_DECIMALS as u32);
61
62pub const SLOTS_PER_LEVEL: u64 = 3;
63pub const MAX_BARRACKS_SLOTS: usize = 12;
64/// Max total fodder (sum of fodder_counts) before recruit. Must reforge to free space.
65pub const MAX_FODDER_TOTAL: u64 = 200;
66
67pub const STARTER_TICKET_PRICE: u64 = 1_000_000_000;
68pub const RECRUIT_SOL_PRICE: u64 = 100_000_000;
69
70/// Base cost (first dine for this shogun). 150/300/450 shards.
71pub const DINE_COST_24H: u64 = 150_000_000;
72pub const DINE_COST_48H: u64 = 300_000_000;
73pub const DINE_COST_72H: u64 = 450_000_000;
74
75/// Escalated cost (second+ dine for this shogun). 195/390/585 shards.
76pub const DINE_COST_24H_ESCALATED: u64 = 195_000_000;
77pub const DINE_COST_48H_ESCALATED: u64 = 390_000_000;
78pub const DINE_COST_72H_ESCALATED: u64 = 585_000_000;
79
80pub const BARRACKS_COST_1_2_SHARDS: u64 = 50_000_000;
81pub const BARRACKS_COST_1_2_SOL: u64 = 10_000_000;
82pub const BARRACKS_COST_2_3_SHARDS: u64 = 300_000_000;
83pub const BARRACKS_COST_2_3_SOL: u64 = 100_000_000;
84pub const BARRACKS_COST_3_4: u64 = 8_000_000_000;
85
86/// 1→2: 0.1 SOL.
87pub const FORGE_COST_1_2: u64 = 100_000_000;
88/// 2→3: 1 SOL.
89pub const FORGE_COST_2_3: u64 = 1_000_000_000;
90/// 3→4: 2 SOL.
91pub const FORGE_COST_3_4: u64 = 2_000_000_000;
92/// 4→5: 5 SOL.
93pub const FORGE_COST_4_5: u64 = 5_000_000_000;
94/// 5→6: 12 SOL.
95pub const FORGE_COST_5_6: u64 = 12_000_000_000;
96/// 6→7: 21 SOL (max level).
97pub const FORGE_COST_6_7: u64 = 21_000_000_000;
98
99/// 1→2: no cooldown (unused; we use _2_3 for level 2).
100pub const FORGE_COOLDOWN_1_2: u64 = 0;
101/// 2→3: no cooldown after 1→2; 30 min after 2→3 (level 3 uses _3_4).
102pub const FORGE_COOLDOWN_2_3: u64 = 0;
103/// 3→4: 30 min in slots (1800s / 0.4 = 4500). Cooldown after 2→3.
104pub const FORGE_COOLDOWN_3_4: u64 = 4_500;
105/// 4→5: 90 min in slots (5400s / 0.4 = 13500). Cooldown after 3→4.
106pub const FORGE_COOLDOWN_4_5: u64 = 13_500;
107/// 5→6: 180 min in slots (10800s / 0.4 = 27000). Cooldown after 4→5.
108pub const FORGE_COOLDOWN_5_6: u64 = 27_000;
109/// 6→7: 300 min in slots (18000s / 0.4 = 45000). Cooldown after 5→6 (max level).
110pub const FORGE_COOLDOWN_6_7: u64 = 45_000;
111
112/// Same as ONE_DOJO. Speed-up forge: cost per minute = remaining minutes (Ninja decay).
113pub const SHARDS_RAW_PER_UNIT: u64 = ONE_DOJO;
114
115// Leveling: cost = 200 + 800*(level-1). Capped at 100.
116pub const LEVEL_UP_COST_BASE: u64 = 200_000_000;   // 200 shards raw
117pub const LEVEL_UP_COST_INCREMENT: u64 = 800_000_000; // 800 shards raw per level
118pub const MAX_SHOGUN_LEVEL: u64 = 100;
119
120pub const SP_N: u64 = 10;   // 1x
121pub const SP_R: u64 = 20;   // 2x
122pub const SP_SR: u64 = 80;  // 8x
123pub const SP_SSR: u64 = 200; // 20x
124pub const SP_UR: u64 = 600; // 60x
125
126pub const DROP_N: u64 = 541;
127pub const DROP_R: u64 = 324;
128pub const DROP_SR: u64 = 108;
129pub const DROP_SSR: u64 = 22;
130pub const DROP_UR: u64 = 5;
131
132pub const RECRUITMENT_TICKET_REWARD_1: u64 = 1;
133pub const RECRUITMENT_TICKET_REWARD_2: u64 = 2;
134pub const RECRUITMENT_TICKET_REWARD_3: u64 = 3;
135pub const RECRUITMENT_TICKET_REWARD_4: u64 = 4;
136pub const RECRUITMENT_TICKET_REWARD_5: u64 = 5;
137pub const RECRUITMENT_TICKET_REWARD_6: u64 = 6;
138pub const RECRUITMENT_TICKET_REWARD_7: u64 = 7;
139pub const RECRUITMENT_TICKET_REWARD_8: u64 = 8;
140pub const RECRUITMENT_TICKET_REWARD_9: u64 = 9;
141pub const RECRUITMENT_TICKET_REWARD_10: u64 = 10;
142pub const RECRUITMENT_TICKET_REWARD_11: u64 = 11;
143pub const RECRUITMENT_TICKET_REWARD_12: u64 = 12;
144pub const RECRUITMENT_TICKET_REWARD_13: u64 = 13;
145pub const RECRUITMENT_TICKET_REWARD_15: u64 = 15;
146
147pub const ELEMENT_RARITY_REWARD_N: u64 = 1;
148pub const ELEMENT_RARITY_REWARD_R: u64 = 1;
149pub const ELEMENT_RARITY_REWARD_SR: u64 = 2;
150pub const ELEMENT_RARITY_REWARD_SSR: u64 = 5;
151pub const ELEMENT_RARITY_REWARD_UR: u64 = 20;
152
153pub const DAILY_TASK_START: u64 = 17;
154
155pub const CLAIM_TASK_PREFIX: &[u8] = b"dojos:claim_task:";
156pub const ELEMENT_RARITY_SET_SIZE: usize = 3;
157
158// Task ID layout:
159// 0–7: On-chain tasks (recruit, dine, forge Lv.2)
160// 8: Collection rewards (3 ninjas same element+rarity; 25 combos)
161// 9–16: Off-chain tasks (signature required)
162// 17–24: Daily resettable tasks (signature, bits reset daily)
163// 33–35: Forge Lv.3, Lv.4, Lv.5
164pub const TASK_FORGE_3: u64 = 33;
165pub const TASK_FORGE_4: u64 = 34;
166pub const TASK_FORGE_5: u64 = 35;
167pub const FORGE_3_REWARD: u64 = 2;
168pub const FORGE_4_REWARD: u64 = 5;
169pub const FORGE_5_REWARD: u64 = 10;
170pub const FORGE_6_REWARD: u64 = 15;
171pub const FORGE_7_REWARD: u64 = 20;
172
173pub const MAX_SUPPLY: u64 = ONE_DOJO * 1_000_000_000;
174
175// Missions (expeditions)
176pub const MAX_MISSION_ENTRIES: usize = 12;
177pub const MISSION_TYPE_SHORT: u64 = 0;
178pub const MISSION_TYPE_MEDIUM: u64 = 1;
179pub const MISSION_TYPE_LONG: u64 = 2;
180pub const MISSION_SLOTS_SHORT: u64 = 2;
181pub const MISSION_SLOTS_MEDIUM: u64 = 2;
182pub const MISSION_SLOTS_LONG: u64 = 3;
183pub const MISSION_DURATION_SHORT: u64 = 2_250;
184pub const MISSION_DURATION_MEDIUM: u64 = 13_500;
185pub const MISSION_DURATION_LONG: u64 = 54_000;
186pub const MISSION_COST_SHORT: u64 = 50_000_000;
187pub const MISSION_COST_MEDIUM: u64 = 100_000_000;
188pub const MISSION_COST_LONG: u64 = 200_000_000;
189
190// Reward caps by mission type (Short 1x, Medium 2x, Long 4x). Shards in raw 6 decimals.
191pub const MISSION_REWARD_SHARDS_SHORT: u64 = 500_000_000;
192pub const MISSION_REWARD_SHARDS_MEDIUM: u64 = 1_000_000_000;
193pub const MISSION_REWARD_SHARDS_LONG: u64 = 2_000_000_000;
194pub const MISSION_REWARD_TICKETS_SHORT: u64 = 20;
195pub const MISSION_REWARD_TICKETS_MEDIUM: u64 = 40;
196pub const MISSION_REWARD_TICKETS_LONG: u64 = 80;
197pub const MISSION_REWARD_FREE_ROLLS_SHORT: u64 = 1;
198pub const MISSION_REWARD_FREE_ROLLS_MEDIUM: u64 = 3;
199pub const MISSION_REWARD_FREE_ROLLS_LONG: u64 = 10;
200
201// Scene collection
202pub const SCENES: &[u8] = b"scenes";
203pub const SCENE_DEFAULT_ID: u64 = 0;
204pub const SCENE_SECTIONS_PER_SCENE: usize = 12;
205pub const SCENE_COUNT_MAX: usize = 9;
206pub const SCENE_COUNT: u64 = 8;
207/// Scenes in roll pool (1–5). Excludes scene 0 (Green Mountain) and buyable scenes 6–8.
208pub const SCENE_ROLL_COUNT: u64 = 5;
209pub const SCENE_ROLL_SHARD_COUNT: u64 = 10;
210/// Scenes 6–8 can be bought with Amethyst (unlock entire scene).
211pub const SCENE_BUY_START: u64 = 6;
212
213// Scene bonuses for claim_shards (ore = (spirit_power * chakra) / divisor; bonuses apply after sum).
214/// Scene 0 (Green Mountain): no bonus.
215/// Scenes 1, 6, 7, 8: flat +50_000 Spirit Power.
216pub const SCENE_BONUS_FLAT_50K: u64 = 50_000;
217/// Scene 2: flat +100_000 Spirit Power.
218pub const SCENE_BONUS_FLAT_100K: u64 = 100_000;
219/// Scene 3: +2% multiplier (basis points).
220pub const SCENE_BONUS_PCT_2: u64 = 200;
221/// Scene 4: +3% multiplier (basis points).
222pub const SCENE_BONUS_PCT_3: u64 = 300;
223/// Scene 5: +5% multiplier (basis points).
224pub const SCENE_BONUS_PCT_5: u64 = 500;