streak_api/instruction.rs
1//! Instruction discriminators + payload types.
2
3use steel::*;
4
5/// One-time setup: creates `Treasury` PDA + treasury USDC ATA. `payer` must be `ADMIN_ADDRESS`.
6///
7/// **Accounts:** `payer`, `treasury`, `mint`, `treasury_ata`, `system_program`, `token_program`,
8/// `ata_program`.
9#[repr(C)]
10#[derive(Clone, Copy, Debug, Pod, Zeroable)]
11pub struct Initialize {}
12
13/// Purchase tickets (gaming credits) with USDC.
14///
15/// Buying tickets is separate from placing a bet. The user first buys credits here
16/// (on-chain, USDC split immediately), then places bets off-chain via the server
17/// using those credits.
18///
19/// 1. Transfers `amount` µUSDC from the user's ATA into the treasury ATA.
20/// 2. Updates `Treasury` PDA counters: `daily_accrual += 70%`, `weekly_jackpot += 15%`,
21/// `buyback += 10%`.
22/// 3. Forwards the team share (5%) from the treasury ATA to `FEE_COLLECTOR` (CPI).
23/// 4. Creates or increments the user's `UserCredits` PDA (`total_purchased += amount`).
24/// 5. Emits `TicketPurchased { user, amount }`.
25///
26/// The indexer reads `TicketPurchased` events to credit the user's off-chain spendable
27/// balance. Bets are placed and debited server-side against that balance.
28///
29/// **Accounts:** `user` (signer/payer), `user_ata`, `treasury`, `treasury_ata`, `credits`,
30/// `fee_collector_ata`, `mint`, `token_program`, `system_program`.
31#[repr(C)]
32#[derive(Clone, Copy, Debug, Pod, Zeroable)]
33pub struct BuyTicket {
34 /// Amount in µUSDC (6 decimals).
35 pub amount: [u8; 8],
36}
37
38/// Route claimed DBC / DAMM v2 trading fees into the treasury and split them on-chain.
39///
40/// The executor bot claims pool creator/LP fees off-chain via the Meteora SDK, receiving USDC
41/// into its own ATA. This instruction then:
42/// 1. Transfers `amount` µUSDC from the executor's ATA into the treasury ATA (CPI).
43/// 2. Splits the amount according to `TICKET_*_BPS` and updates `Treasury` counters.
44/// 3. Forwards the team share (5%) from the treasury ATA to `FEE_COLLECTOR` (CPI).
45/// 4. Emits `FeesRouted`.
46///
47/// **Accounts:** `executor` (signer), `executor_ata`, `treasury`, `treasury_ata`,
48/// `fee_collector_ata`, `mint`, `token_program`.
49#[repr(C)]
50#[derive(Clone, Copy, Debug, Pod, Zeroable)]
51pub struct AdminRouteFees {
52 pub amount: [u8; 8],
53}
54
55/// Transfer µUSDC from the treasury vault to a recipient ATA.
56///
57/// `pool` selects which jackpot counter to debit:
58/// - `DISBURSE_POOL_NONE` — bet-round winners (vault only; counters unchanged)
59/// - `DISBURSE_POOL_DAILY` — daily jackpot winners
60/// - `DISBURSE_POOL_WEEKLY` — weekly jackpot winners (partial release; call
61/// `AdminFinalizeWeekly` afterward to sweep leftover accrual → stability)
62///
63/// Only `EXECUTOR_ADDRESS` may sign. Emits `Paid`.
64///
65/// **Accounts:** `executor` (signer), `treasury`, `treasury_ata`, `recipient_ata`, `mint`,
66/// `token_program`.
67#[repr(C)]
68#[derive(Clone, Copy, Debug, Pod, Zeroable)]
69pub struct AdminDisburseFromTreasury {
70 pub amount: [u8; 8],
71 pub series_id: [u8; 2],
72 /// Which treasury counter to debit (`DISBURSE_POOL_*`).
73 pub pool: u8,
74 pub _pad_ix: [u8; 5],
75 pub period: [u8; 8],
76}
77
78/// Executor-only: sweep remaining `weekly_jackpot` into `stability_reserve` at week end.
79///
80/// No USDC transfer — accounting only. Emits `WeeklyFinalized`.
81///
82/// **Accounts:** `executor` (signer), `treasury`.
83#[repr(C)]
84#[derive(Clone, Copy, Debug, Pod, Zeroable)]
85pub struct AdminFinalizeWeekly {}
86
87/// Executor-only: sweep remaining `daily_jackpot` into `stability_reserve` at UTC day end.
88///
89/// No USDC transfer — accounting only. Emits `DailyFinalized`.
90///
91/// **Accounts:** `executor` (signer), `treasury`.
92#[repr(C)]
93#[derive(Clone, Copy, Debug, Pod, Zeroable)]
94pub struct AdminFinalizeDaily {}
95
96/// T+1 rotation: move `daily_accrual` → `daily_jackpot` for the next UTC day.
97///
98/// Requires `daily_jackpot == 0` (call `AdminFinalizeDaily` first). Emits `DailyRotated`.
99///
100/// **Accounts:** `executor` (signer), `treasury`.
101#[repr(C)]
102#[derive(Clone, Copy, Debug, Pod, Zeroable)]
103pub struct AdminRotateDailyVault {}
104
105use num_enum::TryFromPrimitive;
106
107#[repr(u8)]
108#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
109pub enum StreakInstruction {
110 Initialize = 0,
111 BuyTicket = 1,
112 AdminRouteFees = 2,
113 AdminDisburseFromTreasury = 3,
114 /// Reserved — was `PlaceBet` (removed; bets are server-authoritative).
115 _ReservedPlaceBet = 4,
116 /// Reserved — was `AdminSetTreasuryPools` (one-shot reconcile; removed post-migration).
117 _ReservedSetTreasuryPools = 5,
118 AdminFinalizeWeekly = 6,
119 AdminFinalizeDaily = 7,
120 AdminRotateDailyVault = 8,
121}
122
123instruction!(StreakInstruction, Initialize);
124instruction!(StreakInstruction, BuyTicket);
125instruction!(StreakInstruction, AdminRouteFees);
126instruction!(StreakInstruction, AdminDisburseFromTreasury);
127instruction!(StreakInstruction, AdminFinalizeWeekly);
128instruction!(StreakInstruction, AdminFinalizeDaily);
129instruction!(StreakInstruction, AdminRotateDailyVault);