1use borsh::BorshSerialize;
2use sha2::{Digest, Sha256};
3#[allow(deprecated)]
4use solana_sdk::{
5 instruction::{AccountMeta, Instruction},
6 pubkey::Pubkey,
7 system_program,
8};
9
10pub fn anchor_discriminator(name: &str) -> [u8; 8] {
12 let hash = Sha256::digest(format!("global:{name}").as_bytes());
13 let mut disc = [0u8; 8];
14 disc.copy_from_slice(&hash[..8]);
15 disc
16}
17
18pub fn build_ix(
20 program_id: &Pubkey,
21 name: &str,
22 args: impl BorshSerialize,
23 accounts: Vec<AccountMeta>,
24) -> Instruction {
25 let mut data = anchor_discriminator(name).to_vec();
26 args.serialize(&mut data).expect("borsh serialize");
27 Instruction {
28 program_id: *program_id,
29 accounts,
30 data,
31 }
32}
33
34#[derive(BorshSerialize)]
37pub struct InitializeMarketArgs {
38 pub init_slot: u64,
39 pub init_oracle_price: u64,
40 pub params: RiskParamsInput,
41}
42
43#[derive(BorshSerialize)]
44pub struct RiskParamsInput {
45 pub warmup_period_slots: u64,
46 pub maintenance_margin_bps: u64,
47 pub initial_margin_bps: u64,
48 pub trading_fee_bps: u64,
49 pub max_accounts: u64,
50 pub new_account_fee: u64,
51 pub maintenance_fee_per_slot: u64,
52 pub max_crank_staleness_slots: u64,
53 pub liquidation_fee_bps: u64,
54 pub liquidation_fee_cap: u64,
55 pub min_liquidation_abs: u64,
56 pub min_initial_deposit: u64,
57 pub min_nonzero_mm_req: u64,
58 pub min_nonzero_im_req: u64,
59 pub insurance_floor: u64,
60}
61
62#[derive(BorshSerialize)]
63pub struct DepositArgs {
64 pub account_idx: u16,
65 pub amount: u64,
66}
67
68#[derive(BorshSerialize)]
69pub struct WithdrawArgs {
70 pub account_idx: u16,
71 pub amount: u64,
72 pub funding_rate: i64,
73}
74
75#[derive(BorshSerialize)]
76pub struct TradeArgs {
77 pub account_a: u16,
78 pub account_b: u16,
79 pub size_q: i128,
80 pub exec_price: u64,
81 pub funding_rate: i64,
82}
83
84#[derive(BorshSerialize)]
85pub struct CrankArgs {
86 pub funding_rate: i64,
87}
88
89#[derive(BorshSerialize)]
90pub struct LiquidateArgs {
91 pub account_idx: u16,
92 pub funding_rate: i64,
93}
94
95#[derive(BorshSerialize)]
96pub struct SettleArgs {
97 pub account_idx: u16,
98 pub funding_rate: i64,
99}
100
101#[derive(BorshSerialize)]
102pub struct CloseAccountArgs {
103 pub account_idx: u16,
104 pub funding_rate: i64,
105}
106
107#[derive(BorshSerialize)]
108pub struct ReclaimAccountArgs {
109 pub account_idx: u16,
110}
111
112#[derive(BorshSerialize)]
113pub struct WithdrawInsuranceArgs {
114 pub amount: u64,
115}
116
117pub fn initialize_market_ix(
120 program_id: &Pubkey,
121 market: &Pubkey,
122 authority: &Pubkey,
123 mint: &Pubkey,
124 vault: &Pubkey,
125 oracle: &Pubkey,
126 matcher: &Pubkey,
127 token_program: &Pubkey,
128 args: InitializeMarketArgs,
129) -> Instruction {
130 build_ix(
131 program_id,
132 "initialize_market",
133 args,
134 vec![
135 AccountMeta::new(*authority, true),
136 AccountMeta::new(*market, false),
137 AccountMeta::new_readonly(*mint, false),
138 AccountMeta::new(*vault, false),
139 AccountMeta::new_readonly(*oracle, false),
140 AccountMeta::new_readonly(*matcher, false),
141 AccountMeta::new_readonly(*token_program, false),
142 AccountMeta::new_readonly(system_program::id(), false),
143 ],
144 )
145}
146
147pub fn deposit_ix(
148 program_id: &Pubkey,
149 market: &Pubkey,
150 user: &Pubkey,
151 mint: &Pubkey,
152 user_token_account: &Pubkey,
153 vault: &Pubkey,
154 token_program: &Pubkey,
155 args: DepositArgs,
156) -> Instruction {
157 build_ix(
158 program_id,
159 "deposit",
160 args,
161 vec![
162 AccountMeta::new(*user, true),
163 AccountMeta::new(*market, false),
164 AccountMeta::new_readonly(*mint, false),
165 AccountMeta::new(*user_token_account, false),
166 AccountMeta::new(*vault, false),
167 AccountMeta::new_readonly(*token_program, false),
168 ],
169 )
170}
171
172pub fn withdraw_ix(
173 program_id: &Pubkey,
174 market: &Pubkey,
175 user: &Pubkey,
176 mint: &Pubkey,
177 user_token_account: &Pubkey,
178 vault: &Pubkey,
179 token_program: &Pubkey,
180 args: WithdrawArgs,
181) -> Instruction {
182 build_ix(
183 program_id,
184 "withdraw",
185 args,
186 vec![
187 AccountMeta::new(*user, true),
188 AccountMeta::new(*market, false),
189 AccountMeta::new_readonly(*mint, false),
190 AccountMeta::new(*user_token_account, false),
191 AccountMeta::new(*vault, false),
192 AccountMeta::new_readonly(*token_program, false),
193 ],
194 )
195}
196
197pub fn trade_ix(
198 program_id: &Pubkey,
199 market: &Pubkey,
200 authority: &Pubkey,
201 args: TradeArgs,
202) -> Instruction {
203 build_ix(
204 program_id,
205 "trade",
206 args,
207 vec![
208 AccountMeta::new_readonly(*authority, true),
209 AccountMeta::new(*market, false),
210 ],
211 )
212}
213
214pub fn crank_ix(
215 program_id: &Pubkey,
216 market: &Pubkey,
217 cranker: &Pubkey,
218 oracle: &Pubkey,
219 args: CrankArgs,
220) -> Instruction {
221 build_ix(
222 program_id,
223 "crank",
224 args,
225 vec![
226 AccountMeta::new_readonly(*cranker, true),
227 AccountMeta::new(*market, false),
228 AccountMeta::new_readonly(*oracle, false),
229 ],
230 )
231}
232
233pub fn liquidate_ix(
234 program_id: &Pubkey,
235 market: &Pubkey,
236 liquidator: &Pubkey,
237 args: LiquidateArgs,
238) -> Instruction {
239 build_ix(
240 program_id,
241 "liquidate",
242 args,
243 vec![
244 AccountMeta::new_readonly(*liquidator, true),
245 AccountMeta::new(*market, false),
246 ],
247 )
248}
249
250pub fn settle_ix(
251 program_id: &Pubkey,
252 market: &Pubkey,
253 user: &Pubkey,
254 args: SettleArgs,
255) -> Instruction {
256 build_ix(
257 program_id,
258 "settle",
259 args,
260 vec![
261 AccountMeta::new_readonly(*user, true),
262 AccountMeta::new(*market, false),
263 ],
264 )
265}
266
267pub fn close_account_ix(
268 program_id: &Pubkey,
269 market: &Pubkey,
270 user: &Pubkey,
271 args: CloseAccountArgs,
272) -> Instruction {
273 build_ix(
274 program_id,
275 "close_account",
276 args,
277 vec![
278 AccountMeta::new_readonly(*user, true),
279 AccountMeta::new(*market, false),
280 ],
281 )
282}
283
284pub fn reclaim_account_ix(
285 program_id: &Pubkey,
286 market: &Pubkey,
287 reclaimer: &Pubkey,
288 args: ReclaimAccountArgs,
289) -> Instruction {
290 build_ix(
291 program_id,
292 "reclaim_account",
293 args,
294 vec![
295 AccountMeta::new_readonly(*reclaimer, true),
296 AccountMeta::new(*market, false),
297 ],
298 )
299}
300
301pub fn withdraw_insurance_ix(
302 program_id: &Pubkey,
303 market: &Pubkey,
304 authority: &Pubkey,
305 mint: &Pubkey,
306 authority_token_account: &Pubkey,
307 vault: &Pubkey,
308 token_program: &Pubkey,
309 args: WithdrawInsuranceArgs,
310) -> Instruction {
311 build_ix(
312 program_id,
313 "withdraw_insurance",
314 args,
315 vec![
316 AccountMeta::new(*authority, true),
317 AccountMeta::new(*market, false),
318 AccountMeta::new_readonly(*mint, false),
319 AccountMeta::new(*authority_token_account, false),
320 AccountMeta::new(*vault, false),
321 AccountMeta::new_readonly(*token_program, false),
322 ],
323 )
324}