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
117#[derive(BorshSerialize)]
118pub struct TopUpInsuranceArgs {
119 pub amount: u64,
120}
121
122#[derive(BorshSerialize)]
123pub struct DepositFeeCreditsArgs {
124 pub account_idx: u16,
125 pub amount: u64,
126}
127
128#[derive(BorshSerialize)]
129pub struct ConvertReleasedPnlArgs {
130 pub account_idx: u16,
131 pub x_req: u64,
132 pub funding_rate: i64,
133}
134
135#[derive(BorshSerialize)]
136pub struct UpdateMatcherArgs {
137 pub new_matcher: Pubkey,
138}
139
140#[derive(BorshSerialize)]
141pub struct TransferAuthorityArgs {
142 pub new_authority: Pubkey,
143}
144
145pub fn initialize_market_ix(
148 program_id: &Pubkey,
149 market: &Pubkey,
150 authority: &Pubkey,
151 mint: &Pubkey,
152 vault: &Pubkey,
153 oracle: &Pubkey,
154 matcher: &Pubkey,
155 token_program: &Pubkey,
156 args: InitializeMarketArgs,
157) -> Instruction {
158 build_ix(
159 program_id,
160 "initialize_market",
161 args,
162 vec![
163 AccountMeta::new(*authority, true),
164 AccountMeta::new(*market, false),
165 AccountMeta::new_readonly(*mint, false),
166 AccountMeta::new(*vault, false),
167 AccountMeta::new_readonly(*oracle, false),
168 AccountMeta::new_readonly(*matcher, false),
169 AccountMeta::new_readonly(*token_program, false),
170 AccountMeta::new_readonly(system_program::id(), false),
171 ],
172 )
173}
174
175pub fn deposit_ix(
176 program_id: &Pubkey,
177 market: &Pubkey,
178 user: &Pubkey,
179 mint: &Pubkey,
180 user_token_account: &Pubkey,
181 vault: &Pubkey,
182 token_program: &Pubkey,
183 args: DepositArgs,
184) -> Instruction {
185 build_ix(
186 program_id,
187 "deposit",
188 args,
189 vec![
190 AccountMeta::new(*user, true),
191 AccountMeta::new(*market, false),
192 AccountMeta::new_readonly(*mint, false),
193 AccountMeta::new(*user_token_account, false),
194 AccountMeta::new(*vault, false),
195 AccountMeta::new_readonly(*token_program, false),
196 ],
197 )
198}
199
200pub fn withdraw_ix(
201 program_id: &Pubkey,
202 market: &Pubkey,
203 user: &Pubkey,
204 mint: &Pubkey,
205 user_token_account: &Pubkey,
206 vault: &Pubkey,
207 token_program: &Pubkey,
208 args: WithdrawArgs,
209) -> Instruction {
210 build_ix(
211 program_id,
212 "withdraw",
213 args,
214 vec![
215 AccountMeta::new(*user, true),
216 AccountMeta::new(*market, false),
217 AccountMeta::new_readonly(*mint, false),
218 AccountMeta::new(*user_token_account, false),
219 AccountMeta::new(*vault, false),
220 AccountMeta::new_readonly(*token_program, false),
221 ],
222 )
223}
224
225pub fn trade_ix(
226 program_id: &Pubkey,
227 market: &Pubkey,
228 authority: &Pubkey,
229 args: TradeArgs,
230) -> Instruction {
231 build_ix(
232 program_id,
233 "trade",
234 args,
235 vec![
236 AccountMeta::new_readonly(*authority, true),
237 AccountMeta::new(*market, false),
238 ],
239 )
240}
241
242pub fn crank_ix(
243 program_id: &Pubkey,
244 market: &Pubkey,
245 cranker: &Pubkey,
246 oracle: &Pubkey,
247 args: CrankArgs,
248) -> Instruction {
249 build_ix(
250 program_id,
251 "crank",
252 args,
253 vec![
254 AccountMeta::new_readonly(*cranker, true),
255 AccountMeta::new(*market, false),
256 AccountMeta::new_readonly(*oracle, false),
257 ],
258 )
259}
260
261pub fn liquidate_ix(
262 program_id: &Pubkey,
263 market: &Pubkey,
264 liquidator: &Pubkey,
265 args: LiquidateArgs,
266) -> Instruction {
267 build_ix(
268 program_id,
269 "liquidate",
270 args,
271 vec![
272 AccountMeta::new_readonly(*liquidator, true),
273 AccountMeta::new(*market, false),
274 ],
275 )
276}
277
278pub fn settle_ix(
279 program_id: &Pubkey,
280 market: &Pubkey,
281 user: &Pubkey,
282 args: SettleArgs,
283) -> Instruction {
284 build_ix(
285 program_id,
286 "settle",
287 args,
288 vec![
289 AccountMeta::new_readonly(*user, true),
290 AccountMeta::new(*market, false),
291 ],
292 )
293}
294
295pub fn close_account_ix(
296 program_id: &Pubkey,
297 market: &Pubkey,
298 user: &Pubkey,
299 args: CloseAccountArgs,
300) -> Instruction {
301 build_ix(
302 program_id,
303 "close_account",
304 args,
305 vec![
306 AccountMeta::new_readonly(*user, true),
307 AccountMeta::new(*market, false),
308 ],
309 )
310}
311
312pub fn reclaim_account_ix(
313 program_id: &Pubkey,
314 market: &Pubkey,
315 reclaimer: &Pubkey,
316 args: ReclaimAccountArgs,
317) -> Instruction {
318 build_ix(
319 program_id,
320 "reclaim_account",
321 args,
322 vec![
323 AccountMeta::new_readonly(*reclaimer, true),
324 AccountMeta::new(*market, false),
325 ],
326 )
327}
328
329pub fn withdraw_insurance_ix(
330 program_id: &Pubkey,
331 market: &Pubkey,
332 authority: &Pubkey,
333 mint: &Pubkey,
334 authority_token_account: &Pubkey,
335 vault: &Pubkey,
336 token_program: &Pubkey,
337 args: WithdrawInsuranceArgs,
338) -> Instruction {
339 build_ix(
340 program_id,
341 "withdraw_insurance",
342 args,
343 vec![
344 AccountMeta::new(*authority, true),
345 AccountMeta::new(*market, false),
346 AccountMeta::new_readonly(*mint, false),
347 AccountMeta::new(*authority_token_account, false),
348 AccountMeta::new(*vault, false),
349 AccountMeta::new_readonly(*token_program, false),
350 ],
351 )
352}
353
354pub fn top_up_insurance_ix(
355 program_id: &Pubkey,
356 market: &Pubkey,
357 depositor: &Pubkey,
358 mint: &Pubkey,
359 depositor_token_account: &Pubkey,
360 vault: &Pubkey,
361 token_program: &Pubkey,
362 args: TopUpInsuranceArgs,
363) -> Instruction {
364 build_ix(
365 program_id,
366 "top_up_insurance",
367 args,
368 vec![
369 AccountMeta::new(*depositor, true),
370 AccountMeta::new(*market, false),
371 AccountMeta::new_readonly(*mint, false),
372 AccountMeta::new(*depositor_token_account, false),
373 AccountMeta::new(*vault, false),
374 AccountMeta::new_readonly(*token_program, false),
375 ],
376 )
377}
378
379pub fn deposit_fee_credits_ix(
380 program_id: &Pubkey,
381 market: &Pubkey,
382 user: &Pubkey,
383 mint: &Pubkey,
384 user_token_account: &Pubkey,
385 vault: &Pubkey,
386 token_program: &Pubkey,
387 args: DepositFeeCreditsArgs,
388) -> Instruction {
389 build_ix(
390 program_id,
391 "deposit_fee_credits",
392 args,
393 vec![
394 AccountMeta::new(*user, true),
395 AccountMeta::new(*market, false),
396 AccountMeta::new_readonly(*mint, false),
397 AccountMeta::new(*user_token_account, false),
398 AccountMeta::new(*vault, false),
399 AccountMeta::new_readonly(*token_program, false),
400 ],
401 )
402}
403
404pub fn convert_released_pnl_ix(
405 program_id: &Pubkey,
406 market: &Pubkey,
407 user: &Pubkey,
408 oracle: &Pubkey,
409 args: ConvertReleasedPnlArgs,
410) -> Instruction {
411 build_ix(
412 program_id,
413 "convert_released_pnl",
414 args,
415 vec![
416 AccountMeta::new_readonly(*user, true),
417 AccountMeta::new(*market, false),
418 AccountMeta::new_readonly(*oracle, false),
419 ],
420 )
421}
422
423pub fn accrue_market_ix(
424 program_id: &Pubkey,
425 market: &Pubkey,
426 signer: &Pubkey,
427 oracle: &Pubkey,
428) -> Instruction {
429 build_ix(
430 program_id,
431 "accrue_market",
432 (),
433 vec![
434 AccountMeta::new_readonly(*signer, true),
435 AccountMeta::new(*market, false),
436 AccountMeta::new_readonly(*oracle, false),
437 ],
438 )
439}
440
441pub fn update_matcher_ix(
442 program_id: &Pubkey,
443 market: &Pubkey,
444 authority: &Pubkey,
445 args: UpdateMatcherArgs,
446) -> Instruction {
447 build_ix(
448 program_id,
449 "update_matcher",
450 args,
451 vec![
452 AccountMeta::new_readonly(*authority, true),
453 AccountMeta::new(*market, false),
454 ],
455 )
456}
457
458pub fn update_oracle_ix(
459 program_id: &Pubkey,
460 market: &Pubkey,
461 authority: &Pubkey,
462 new_oracle: &Pubkey,
463) -> Instruction {
464 build_ix(
465 program_id,
466 "update_oracle",
467 (),
468 vec![
469 AccountMeta::new_readonly(*authority, true),
470 AccountMeta::new(*market, false),
471 AccountMeta::new_readonly(*new_oracle, false),
472 ],
473 )
474}
475
476pub fn migrate_header_v1_ix(
477 program_id: &Pubkey,
478 market: &Pubkey,
479 authority: &Pubkey,
480) -> Instruction {
481 build_ix(
482 program_id,
483 "migrate_header_v1",
484 (),
485 vec![
486 AccountMeta::new(*authority, true),
487 AccountMeta::new(*market, false),
488 ],
489 )
490}
491
492pub fn transfer_authority_ix(
493 program_id: &Pubkey,
494 market: &Pubkey,
495 authority: &Pubkey,
496 args: TransferAuthorityArgs,
497) -> Instruction {
498 build_ix(
499 program_id,
500 "transfer_authority",
501 args,
502 vec![
503 AccountMeta::new_readonly(*authority, true),
504 AccountMeta::new(*market, false),
505 ],
506 )
507}
508
509pub fn accept_authority_ix(
510 program_id: &Pubkey,
511 market: &Pubkey,
512 new_authority: &Pubkey,
513) -> Instruction {
514 build_ix(
515 program_id,
516 "accept_authority",
517 (),
518 vec![
519 AccountMeta::new_readonly(*new_authority, true),
520 AccountMeta::new(*market, false),
521 ],
522 )
523}