1use solana_program::{pubkey::Pubkey, system_program};
4use spl_associated_token_account::{
5 get_associated_token_address, get_associated_token_address_with_program_id,
6};
7use steel::*;
8
9use crate::{
10 consts::{EXECUTOR_ADDRESS, FEE_COLLECTOR, USDC_MAINNET_MINT},
11 instruction::{AdminDisburseFromTreasury, AdminFinalizeDaily, AdminFinalizeWeekly, AdminRotateDailyVault, AdminRouteFees, BuyTicket, Initialize},
12 state::{Treasury, User},
13};
14
15#[inline(always)]
16pub fn program_id() -> Pubkey {
17 crate::ID
18}
19
20pub fn treasury_usdc_ata() -> Pubkey {
23 get_associated_token_address(&Treasury::pda().0, &USDC_MAINNET_MINT)
24}
25
26pub fn treasury_usdc_ata_with_token_program(token_program: &Pubkey) -> Pubkey {
27 get_associated_token_address_with_program_id(
28 &Treasury::pda().0,
29 &USDC_MAINNET_MINT,
30 token_program,
31 )
32}
33
34pub fn associated_usdc_ata(owner: Pubkey, token_program: &Pubkey) -> Pubkey {
35 get_associated_token_address_with_program_id(&owner, &USDC_MAINNET_MINT, token_program)
36}
37
38pub fn usdc_ata(owner: Pubkey) -> Pubkey {
39 get_associated_token_address(&owner, &USDC_MAINNET_MINT)
40}
41
42pub fn fee_collector_usdc_ata_with_token_program(token_program: &Pubkey) -> Pubkey {
43 get_associated_token_address_with_program_id(&FEE_COLLECTOR, &USDC_MAINNET_MINT, token_program)
44}
45
46pub fn initialize(payer: Pubkey, token_program: Pubkey) -> Instruction {
50 let treasury_address = Treasury::pda().0;
51 let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
52 Instruction {
53 program_id: crate::ID,
54 accounts: vec![
55 AccountMeta::new(payer, true),
56 AccountMeta::new(treasury_address, false),
57 AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
58 AccountMeta::new(treasury_ata, false),
59 AccountMeta::new_readonly(system_program::ID, false),
60 AccountMeta::new_readonly(token_program, false),
61 AccountMeta::new_readonly(spl_associated_token_account::ID, false),
62 ],
63 data: Initialize {}.to_bytes(),
64 }
65}
66
67pub fn buy_ticket(user: Pubkey, amount: u64, token_program: Pubkey) -> Instruction {
75 let user_ata = associated_usdc_ata(user, &token_program);
76 let treasury_address = Treasury::pda().0;
77 let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
78 let user_pda = User::pda(&user).0;
79 let fee_collector_ata = fee_collector_usdc_ata_with_token_program(&token_program);
80 Instruction {
81 program_id: crate::ID,
82 accounts: vec![
83 AccountMeta::new(user, true),
84 AccountMeta::new(user_ata, false),
85 AccountMeta::new(treasury_address, false),
86 AccountMeta::new(treasury_ata, false),
87 AccountMeta::new(user_pda, false),
88 AccountMeta::new(fee_collector_ata, false),
89 AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
90 AccountMeta::new_readonly(token_program, false),
91 AccountMeta::new_readonly(system_program::ID, false),
92 ],
93 data: BuyTicket {
94 amount: amount.to_le_bytes(),
95 }
96 .to_bytes(),
97 }
98}
99
100pub fn route_fees(executor: Pubkey, amount: u64, token_program: Pubkey) -> Instruction {
102 let treasury_address = Treasury::pda().0;
103 let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
104 let executor_ata = associated_usdc_ata(executor, &token_program);
105 let fee_collector_ata = fee_collector_usdc_ata_with_token_program(&token_program);
106 Instruction {
107 program_id: crate::ID,
108 accounts: vec![
109 AccountMeta::new(executor, true),
110 AccountMeta::new(executor_ata, false),
111 AccountMeta::new(treasury_address, false),
112 AccountMeta::new(treasury_ata, false),
113 AccountMeta::new(fee_collector_ata, false),
114 AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
115 AccountMeta::new_readonly(token_program, false),
116 ],
117 data: AdminRouteFees {
118 amount: amount.to_le_bytes(),
119 }
120 .to_bytes(),
121 }
122}
123
124pub fn route_fees_default_executor(amount: u64, token_program: Pubkey) -> Instruction {
126 route_fees(EXECUTOR_ADDRESS, amount, token_program)
127}
128
129pub fn disburse_from_treasury(
134 executor: Pubkey,
135 recipient_ata: Pubkey,
136 amount: u64,
137 series_id: u16,
138 period: u64,
139 token_program: Pubkey,
140 pool: u8,
141) -> Instruction {
142 let treasury_address = Treasury::pda().0;
143 let treasury_ata = treasury_usdc_ata_with_token_program(&token_program);
144 Instruction {
145 program_id: crate::ID,
146 accounts: vec![
147 AccountMeta::new(executor, true),
148 AccountMeta::new(treasury_address, false),
149 AccountMeta::new(treasury_ata, false),
150 AccountMeta::new(recipient_ata, false),
151 AccountMeta::new_readonly(USDC_MAINNET_MINT, false),
152 AccountMeta::new_readonly(token_program, false),
153 ],
154 data: AdminDisburseFromTreasury {
155 amount: amount.to_le_bytes(),
156 series_id: series_id.to_le_bytes(),
157 pool,
158 _pad_ix: [0; 5],
159 period: period.to_le_bytes(),
160 }
161 .to_bytes(),
162 }
163}
164
165pub fn finalize_weekly(executor: Pubkey) -> Instruction {
167 Instruction {
168 program_id: crate::ID,
169 accounts: vec![
170 AccountMeta::new(executor, true),
171 AccountMeta::new(Treasury::pda().0, false),
172 ],
173 data: AdminFinalizeWeekly {}.to_bytes(),
174 }
175}
176
177pub fn finalize_daily(executor: Pubkey) -> Instruction {
179 Instruction {
180 program_id: crate::ID,
181 accounts: vec![
182 AccountMeta::new(executor, true),
183 AccountMeta::new(Treasury::pda().0, false),
184 ],
185 data: AdminFinalizeDaily {}.to_bytes(),
186 }
187}
188
189pub fn rotate_daily_vault(executor: Pubkey) -> Instruction {
191 Instruction {
192 program_id: crate::ID,
193 accounts: vec![
194 AccountMeta::new(executor, true),
195 AccountMeta::new(Treasury::pda().0, false),
196 ],
197 data: AdminRotateDailyVault {}.to_bytes(),
198 }
199}