1use borsh::BorshSerialize;
2use sha2::{Digest, Sha256};
3use solana_sdk::{
4 instruction::{AccountMeta, Instruction},
5 pubkey::Pubkey,
6 system_program,
7};
8
9pub fn anchor_discriminator(name: &str) -> [u8; 8] {
11 let hash = Sha256::digest(format!("global:{name}").as_bytes());
12 let mut disc = [0u8; 8];
13 disc.copy_from_slice(&hash[..8]);
14 disc
15}
16
17pub fn build_ix(
19 program_id: &Pubkey,
20 name: &str,
21 args: impl BorshSerialize,
22 accounts: Vec<AccountMeta>,
23) -> Instruction {
24 let mut data = anchor_discriminator(name).to_vec();
25 args.serialize(&mut data).expect("borsh serialize");
26 Instruction {
27 program_id: *program_id,
28 accounts,
29 data,
30 }
31}
32
33#[derive(BorshSerialize)]
36pub struct InitializeMarketArgs {
37 pub init_slot: u64,
38 pub init_oracle_price: u64,
39 pub params: RiskParamsInput,
40}
41
42#[derive(BorshSerialize)]
43pub struct RiskParamsInput {
44 pub maintenance_margin_bps: u64,
45 pub initial_margin_bps: u64,
46 pub liquidation_fee_bps: u64,
47 pub insurance_fee_bps: u64,
48 pub adl_threshold_bps: u64,
49 pub max_leverage_q: u64,
50 pub min_order_size_q: u64,
51 pub tick_size: u64,
52 pub max_oi_imbalance_q: u64,
53 pub haircut_start_bps: u64,
54 pub haircut_end_bps: u64,
55 pub haircut_maturity_slots: u64,
56 pub matured_haircut_bps: u64,
57 pub max_accounts: u64,
58 pub min_nonzero_mm_req: u128,
59 pub min_nonzero_im_req: u128,
60}
61
62#[derive(BorshSerialize)]
63pub struct DepositArgs {
64 pub account_idx: u16,
65 pub amount: u128,
66}
67
68#[derive(BorshSerialize)]
69pub struct WithdrawArgs {
70 pub account_idx: u16,
71 pub amount: u128,
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 oracle_price: u64,
87 pub funding_rate: i64,
88}
89
90#[derive(BorshSerialize)]
91pub struct LiquidateArgs {
92 pub account_idx: u16,
93 pub funding_rate: i64,
94}
95
96#[derive(BorshSerialize)]
97pub struct SettleArgs {
98 pub account_idx: u16,
99 pub funding_rate: i64,
100}
101
102#[derive(BorshSerialize)]
103pub struct CloseAccountArgs {
104 pub account_idx: u16,
105 pub funding_rate: i64,
106}
107
108pub fn initialize_market_ix(
111 program_id: &Pubkey,
112 market: &Pubkey,
113 authority: &Pubkey,
114 args: InitializeMarketArgs,
115) -> Instruction {
116 build_ix(
117 program_id,
118 "initialize_market",
119 args,
120 vec![
121 AccountMeta::new(*market, false),
122 AccountMeta::new(*authority, true),
123 AccountMeta::new_readonly(system_program::id(), false),
124 ],
125 )
126}
127
128pub fn deposit_ix(
129 program_id: &Pubkey,
130 market: &Pubkey,
131 user: &Pubkey,
132 args: DepositArgs,
133) -> Instruction {
134 build_ix(
135 program_id,
136 "deposit",
137 args,
138 vec![
139 AccountMeta::new(*market, false),
140 AccountMeta::new_readonly(*user, true),
141 ],
142 )
143}
144
145pub fn withdraw_ix(
146 program_id: &Pubkey,
147 market: &Pubkey,
148 user: &Pubkey,
149 args: WithdrawArgs,
150) -> Instruction {
151 build_ix(
152 program_id,
153 "withdraw",
154 args,
155 vec![
156 AccountMeta::new(*market, false),
157 AccountMeta::new_readonly(*user, true),
158 ],
159 )
160}
161
162pub fn trade_ix(
163 program_id: &Pubkey,
164 market: &Pubkey,
165 authority: &Pubkey,
166 args: TradeArgs,
167) -> Instruction {
168 build_ix(
169 program_id,
170 "trade",
171 args,
172 vec![
173 AccountMeta::new(*market, false),
174 AccountMeta::new_readonly(*authority, true),
175 ],
176 )
177}
178
179pub fn crank_ix(
180 program_id: &Pubkey,
181 market: &Pubkey,
182 cranker: &Pubkey,
183 args: CrankArgs,
184) -> Instruction {
185 build_ix(
186 program_id,
187 "crank",
188 args,
189 vec![
190 AccountMeta::new(*market, false),
191 AccountMeta::new_readonly(*cranker, true),
192 ],
193 )
194}
195
196pub fn liquidate_ix(
197 program_id: &Pubkey,
198 market: &Pubkey,
199 liquidator: &Pubkey,
200 args: LiquidateArgs,
201) -> Instruction {
202 build_ix(
203 program_id,
204 "liquidate",
205 args,
206 vec![
207 AccountMeta::new(*market, false),
208 AccountMeta::new_readonly(*liquidator, true),
209 ],
210 )
211}
212
213pub fn settle_ix(
214 program_id: &Pubkey,
215 market: &Pubkey,
216 user: &Pubkey,
217 args: SettleArgs,
218) -> Instruction {
219 build_ix(
220 program_id,
221 "settle",
222 args,
223 vec![
224 AccountMeta::new(*market, false),
225 AccountMeta::new_readonly(*user, true),
226 ],
227 )
228}
229
230pub fn close_account_ix(
231 program_id: &Pubkey,
232 market: &Pubkey,
233 user: &Pubkey,
234 args: CloseAccountArgs,
235) -> Instruction {
236 build_ix(
237 program_id,
238 "close_account",
239 args,
240 vec![
241 AccountMeta::new(*market, false),
242 AccountMeta::new_readonly(*user, true),
243 ],
244 )
245}