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 maintenance_margin_bps: u64,
46 pub initial_margin_bps: u64,
47 pub liquidation_fee_bps: u64,
48 pub insurance_fee_bps: u64,
49 pub adl_threshold_bps: u64,
50 pub max_leverage_q: u64,
51 pub min_order_size_q: u64,
52 pub tick_size: u64,
53 pub max_oi_imbalance_q: u64,
54 pub haircut_start_bps: u64,
55 pub haircut_end_bps: u64,
56 pub haircut_maturity_slots: u64,
57 pub matured_haircut_bps: u64,
58 pub max_accounts: u64,
59 pub min_nonzero_mm_req: u128,
60 pub min_nonzero_im_req: u128,
61}
62
63#[derive(BorshSerialize)]
64pub struct DepositArgs {
65 pub account_idx: u16,
66 pub amount: u128,
67}
68
69#[derive(BorshSerialize)]
70pub struct WithdrawArgs {
71 pub account_idx: u16,
72 pub amount: u128,
73 pub funding_rate: i64,
74}
75
76#[derive(BorshSerialize)]
77pub struct TradeArgs {
78 pub account_a: u16,
79 pub account_b: u16,
80 pub size_q: i128,
81 pub exec_price: u64,
82 pub funding_rate: i64,
83}
84
85#[derive(BorshSerialize)]
86pub struct CrankArgs {
87 pub oracle_price: u64,
88 pub funding_rate: i64,
89}
90
91#[derive(BorshSerialize)]
92pub struct LiquidateArgs {
93 pub account_idx: u16,
94 pub funding_rate: i64,
95}
96
97#[derive(BorshSerialize)]
98pub struct SettleArgs {
99 pub account_idx: u16,
100 pub funding_rate: i64,
101}
102
103#[derive(BorshSerialize)]
104pub struct CloseAccountArgs {
105 pub account_idx: u16,
106 pub funding_rate: i64,
107}
108
109pub fn initialize_market_ix(
112 program_id: &Pubkey,
113 market: &Pubkey,
114 authority: &Pubkey,
115 args: InitializeMarketArgs,
116) -> Instruction {
117 build_ix(
118 program_id,
119 "initialize_market",
120 args,
121 vec![
122 AccountMeta::new(*market, false),
123 AccountMeta::new(*authority, true),
124 AccountMeta::new_readonly(system_program::id(), false),
125 ],
126 )
127}
128
129pub fn deposit_ix(
130 program_id: &Pubkey,
131 market: &Pubkey,
132 user: &Pubkey,
133 args: DepositArgs,
134) -> Instruction {
135 build_ix(
136 program_id,
137 "deposit",
138 args,
139 vec![
140 AccountMeta::new(*market, false),
141 AccountMeta::new_readonly(*user, true),
142 ],
143 )
144}
145
146pub fn withdraw_ix(
147 program_id: &Pubkey,
148 market: &Pubkey,
149 user: &Pubkey,
150 args: WithdrawArgs,
151) -> Instruction {
152 build_ix(
153 program_id,
154 "withdraw",
155 args,
156 vec![
157 AccountMeta::new(*market, false),
158 AccountMeta::new_readonly(*user, true),
159 ],
160 )
161}
162
163pub fn trade_ix(
164 program_id: &Pubkey,
165 market: &Pubkey,
166 authority: &Pubkey,
167 args: TradeArgs,
168) -> Instruction {
169 build_ix(
170 program_id,
171 "trade",
172 args,
173 vec![
174 AccountMeta::new(*market, false),
175 AccountMeta::new_readonly(*authority, true),
176 ],
177 )
178}
179
180pub fn crank_ix(
181 program_id: &Pubkey,
182 market: &Pubkey,
183 cranker: &Pubkey,
184 args: CrankArgs,
185) -> Instruction {
186 build_ix(
187 program_id,
188 "crank",
189 args,
190 vec![
191 AccountMeta::new(*market, false),
192 AccountMeta::new_readonly(*cranker, true),
193 ],
194 )
195}
196
197pub fn liquidate_ix(
198 program_id: &Pubkey,
199 market: &Pubkey,
200 liquidator: &Pubkey,
201 args: LiquidateArgs,
202) -> Instruction {
203 build_ix(
204 program_id,
205 "liquidate",
206 args,
207 vec![
208 AccountMeta::new(*market, false),
209 AccountMeta::new_readonly(*liquidator, true),
210 ],
211 )
212}
213
214pub fn settle_ix(
215 program_id: &Pubkey,
216 market: &Pubkey,
217 user: &Pubkey,
218 args: SettleArgs,
219) -> Instruction {
220 build_ix(
221 program_id,
222 "settle",
223 args,
224 vec![
225 AccountMeta::new(*market, false),
226 AccountMeta::new_readonly(*user, true),
227 ],
228 )
229}
230
231pub fn close_account_ix(
232 program_id: &Pubkey,
233 market: &Pubkey,
234 user: &Pubkey,
235 args: CloseAccountArgs,
236) -> Instruction {
237 build_ix(
238 program_id,
239 "close_account",
240 args,
241 vec![
242 AccountMeta::new(*market, false),
243 AccountMeta::new_readonly(*user, true),
244 ],
245 )
246}