gmsol/store/
market.rs

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
17/// Vault Operations.
18pub trait VaultOps<C> {
19    /// Initialize a market vault for the given token.
20    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
54/// Market Ops.
55pub trait MarketOps<C> {
56    /// Get market status.
57    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    /// Get market token price.
67    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    /// Update market config.
77    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    /// Update market config flag
86    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    /// Update market config by key.
95    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    /// Update market config flag by key.
107    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    /// Toggle market.
119    fn toggle_market(
120        &self,
121        store: &Pubkey,
122        market_token: &Pubkey,
123        enable: bool,
124    ) -> TransactionBuilder<C>;
125
126    /// Toggle GT minting.
127    fn toggle_gt_minting(
128        &self,
129        store: &Pubkey,
130        market_token: &Pubkey,
131        enable: bool,
132    ) -> TransactionBuilder<C>;
133
134    /// Initialize Market Config Buffer.
135    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    /// Close Market Config Buffer.
143    fn close_marekt_config_buffer(
144        &self,
145        buffer: &Pubkey,
146        receiver: Option<&Pubkey>,
147    ) -> TransactionBuilder<C>;
148
149    /// Push to Market Config Buffer.
150    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    /// Set the authority of the Market Config Buffer.
157    fn set_market_config_buffer_authority(
158        &self,
159        buffer: &Pubkey,
160        new_authority: &Pubkey,
161    ) -> TransactionBuilder<C>;
162
163    /// Update Market Config with the buffer.
164    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}