1use std::ops::Deref;
2
3use anchor_client::{
4 anchor_lang::system_program,
5 solana_sdk::{pubkey::Pubkey, signer::Signer},
6};
7use gmsol_model::{price::Prices, PnlFactorKind};
8use gmsol_solana_utils::transaction_builder::TransactionBuilder;
9use gmsol_store::{
10 accounts, instruction,
11 states::{
12 market::config::{EntryArgs, MarketConfigFlag},
13 Factor, MarketConfigKey,
14 },
15};
16
17pub trait VaultOps<C> {
19 fn initialize_market_vault(
21 &self,
22 store: &Pubkey,
23 token: &Pubkey,
24 ) -> (TransactionBuilder<C>, Pubkey);
25}
26
27impl<C, S> VaultOps<C> for crate::Client<C>
28where
29 C: Deref<Target = S> + Clone,
30 S: Signer,
31{
32 fn initialize_market_vault(
33 &self,
34 store: &Pubkey,
35 token: &Pubkey,
36 ) -> (TransactionBuilder<C>, Pubkey) {
37 let authority = self.payer();
38 let vault = self.find_market_vault_address(store, token);
39 let builder = self
40 .store_transaction()
41 .anchor_accounts(accounts::InitializeMarketVault {
42 authority,
43 store: *store,
44 mint: *token,
45 vault,
46 system_program: system_program::ID,
47 token_program: anchor_spl::token::ID,
48 })
49 .anchor_args(instruction::InitializeMarketVault {});
50 (builder, vault)
51 }
52}
53
54pub trait MarketOps<C> {
56 fn get_market_status(
58 &self,
59 store: &Pubkey,
60 market_token: &Pubkey,
61 prices: Prices<u128>,
62 maximize_pnl: bool,
63 maximize_pool_value: bool,
64 ) -> TransactionBuilder<C>;
65
66 fn get_market_token_price(
68 &self,
69 store: &Pubkey,
70 market_token: &Pubkey,
71 prices: Prices<u128>,
72 pnl_factor: PnlFactorKind,
73 maximize: bool,
74 ) -> TransactionBuilder<C>;
75
76 fn update_market_config(
78 &self,
79 store: &Pubkey,
80 market_token: &Pubkey,
81 key: &str,
82 value: &Factor,
83 ) -> crate::Result<TransactionBuilder<C>>;
84
85 fn update_market_config_flag(
87 &self,
88 store: &Pubkey,
89 market_token: &Pubkey,
90 key: &str,
91 value: bool,
92 ) -> crate::Result<TransactionBuilder<C>>;
93
94 fn update_market_config_by_key(
96 &self,
97 store: &Pubkey,
98 market_token: &Pubkey,
99 key: MarketConfigKey,
100 value: &Factor,
101 ) -> crate::Result<TransactionBuilder<C>> {
102 let key = key.to_string();
103 self.update_market_config(store, market_token, &key, value)
104 }
105
106 fn update_market_config_flag_by_key(
108 &self,
109 store: &Pubkey,
110 market_token: &Pubkey,
111 key: MarketConfigFlag,
112 value: bool,
113 ) -> crate::Result<TransactionBuilder<C>> {
114 let key = key.to_string();
115 self.update_market_config_flag(store, market_token, &key, value)
116 }
117
118 fn toggle_market(
120 &self,
121 store: &Pubkey,
122 market_token: &Pubkey,
123 enable: bool,
124 ) -> TransactionBuilder<C>;
125
126 fn toggle_gt_minting(
128 &self,
129 store: &Pubkey,
130 market_token: &Pubkey,
131 enable: bool,
132 ) -> TransactionBuilder<C>;
133
134 fn initialize_market_config_buffer<'a>(
136 &'a self,
137 store: &Pubkey,
138 buffer: &'a dyn Signer,
139 expire_after_secs: u32,
140 ) -> TransactionBuilder<'a, C>;
141
142 fn close_marekt_config_buffer(
144 &self,
145 buffer: &Pubkey,
146 receiver: Option<&Pubkey>,
147 ) -> TransactionBuilder<C>;
148
149 fn push_to_market_config_buffer<S: ToString>(
151 &self,
152 buffer: &Pubkey,
153 new_configs: impl IntoIterator<Item = (S, Factor)>,
154 ) -> TransactionBuilder<C>;
155
156 fn set_market_config_buffer_authority(
158 &self,
159 buffer: &Pubkey,
160 new_authority: &Pubkey,
161 ) -> TransactionBuilder<C>;
162
163 fn update_market_config_with_buffer(
165 &self,
166 store: &Pubkey,
167 market_token: &Pubkey,
168 buffer: &Pubkey,
169 ) -> TransactionBuilder<C>;
170}
171
172impl<C, S> MarketOps<C> for crate::Client<C>
173where
174 C: Deref<Target = S> + Clone,
175 S: Signer,
176{
177 fn get_market_status(
178 &self,
179 store: &Pubkey,
180 market_token: &Pubkey,
181 prices: Prices<u128>,
182 maximize_pnl: bool,
183 maximize_pool_value: bool,
184 ) -> TransactionBuilder<C> {
185 self.store_transaction()
186 .anchor_args(instruction::GetMarketStatus {
187 prices,
188 maximize_pnl,
189 maximize_pool_value,
190 })
191 .anchor_accounts(accounts::ReadMarket {
192 market: self.find_market_address(store, market_token),
193 })
194 }
195
196 fn get_market_token_price(
197 &self,
198 store: &Pubkey,
199 market_token: &Pubkey,
200 prices: Prices<u128>,
201 pnl_factor: PnlFactorKind,
202 maximize: bool,
203 ) -> TransactionBuilder<C> {
204 self.store_transaction()
205 .anchor_args(instruction::GetMarketTokenPrice {
206 prices,
207 pnl_factor: pnl_factor.to_string(),
208 maximize,
209 })
210 .anchor_accounts(accounts::ReadMarketWithToken {
211 market: self.find_market_address(store, market_token),
212 market_token: *market_token,
213 })
214 }
215
216 fn update_market_config(
217 &self,
218 store: &Pubkey,
219 market_token: &Pubkey,
220 key: &str,
221 value: &Factor,
222 ) -> crate::Result<TransactionBuilder<C>> {
223 let req = self
224 .store_transaction()
225 .anchor_args(instruction::UpdateMarketConfig {
226 key: key.to_string(),
227 value: *value,
228 })
229 .anchor_accounts(accounts::UpdateMarketConfig {
230 authority: self.payer(),
231 store: *store,
232 market: self.find_market_address(store, market_token),
233 });
234 Ok(req)
235 }
236
237 fn update_market_config_flag(
238 &self,
239 store: &Pubkey,
240 market_token: &Pubkey,
241 key: &str,
242 value: bool,
243 ) -> crate::Result<TransactionBuilder<C>> {
244 let req = self
245 .store_transaction()
246 .anchor_args(instruction::UpdateMarketConfigFlag {
247 key: key.to_string(),
248 value,
249 })
250 .anchor_accounts(accounts::UpdateMarketConfig {
251 authority: self.payer(),
252 store: *store,
253 market: self.find_market_address(store, market_token),
254 });
255 Ok(req)
256 }
257
258 fn toggle_market(
259 &self,
260 store: &Pubkey,
261 market_token: &Pubkey,
262 enable: bool,
263 ) -> TransactionBuilder<C> {
264 self.store_transaction()
265 .anchor_args(instruction::ToggleMarket { enable })
266 .anchor_accounts(accounts::ToggleMarket {
267 authority: self.payer(),
268 store: *store,
269 market: self.find_market_address(store, market_token),
270 })
271 }
272
273 fn toggle_gt_minting(
274 &self,
275 store: &Pubkey,
276 market_token: &Pubkey,
277 enable: bool,
278 ) -> TransactionBuilder<C> {
279 self.store_transaction()
280 .anchor_args(instruction::ToggleGtMinting { enable })
281 .anchor_accounts(accounts::ToggleGTMinting {
282 authority: self.payer(),
283 store: *store,
284 market: self.find_market_address(store, market_token),
285 })
286 }
287
288 fn initialize_market_config_buffer<'a>(
289 &'a self,
290 store: &Pubkey,
291 buffer: &'a dyn Signer,
292 expire_after_secs: u32,
293 ) -> TransactionBuilder<'a, C> {
294 self.store_transaction()
295 .anchor_args(instruction::InitializeMarketConfigBuffer { expire_after_secs })
296 .anchor_accounts(accounts::InitializeMarketConfigBuffer {
297 authority: self.payer(),
298 store: *store,
299 buffer: buffer.pubkey(),
300 system_program: system_program::ID,
301 })
302 .signer(buffer)
303 }
304
305 fn close_marekt_config_buffer(
306 &self,
307 buffer: &Pubkey,
308 receiver: Option<&Pubkey>,
309 ) -> TransactionBuilder<C> {
310 self.store_transaction()
311 .anchor_args(instruction::CloseMarketConfigBuffer {})
312 .anchor_accounts(accounts::CloseMarketConfigBuffer {
313 authority: self.payer(),
314 buffer: *buffer,
315 receiver: receiver.copied().unwrap_or(self.payer()),
316 })
317 }
318
319 fn push_to_market_config_buffer<K: ToString>(
320 &self,
321 buffer: &Pubkey,
322 new_configs: impl IntoIterator<Item = (K, Factor)>,
323 ) -> TransactionBuilder<C> {
324 self.store_transaction()
325 .anchor_args(instruction::PushToMarketConfigBuffer {
326 new_configs: new_configs
327 .into_iter()
328 .map(|(key, value)| EntryArgs {
329 key: key.to_string(),
330 value,
331 })
332 .collect(),
333 })
334 .anchor_accounts(accounts::PushToMarketConfigBuffer {
335 authority: self.payer(),
336 buffer: *buffer,
337 system_program: system_program::ID,
338 })
339 }
340
341 fn set_market_config_buffer_authority(
342 &self,
343 buffer: &Pubkey,
344 new_authority: &Pubkey,
345 ) -> TransactionBuilder<C> {
346 self.store_transaction()
347 .anchor_args(instruction::SetMarketConfigBufferAuthority {
348 new_authority: *new_authority,
349 })
350 .anchor_accounts(accounts::SetMarketConfigBufferAuthority {
351 authority: self.payer(),
352 buffer: *buffer,
353 })
354 }
355
356 fn update_market_config_with_buffer(
357 &self,
358 store: &Pubkey,
359 market_token: &Pubkey,
360 buffer: &Pubkey,
361 ) -> TransactionBuilder<C> {
362 self.store_transaction()
363 .anchor_args(instruction::UpdateMarketConfigWithBuffer {})
364 .anchor_accounts(accounts::UpdateMarketConfigWithBuffer {
365 authority: self.payer(),
366 store: *store,
367 market: self.find_market_address(store, market_token),
368 buffer: *buffer,
369 })
370 }
371}