gmsol_sdk/builders/order/
update.rs1use gmsol_programs::gmsol_store::{
2 client::{accounts, args},
3 types,
4};
5use gmsol_solana_utils::{AtomicGroup, IntoAtomicGroup, ProgramExt};
6use typed_builder::TypedBuilder;
7
8use crate::{
9 builders::{
10 callback::{Callback, CallbackParams},
11 StoreProgram,
12 },
13 serde::StringPubkey,
14};
15
16#[cfg_attr(js, derive(tsify_next::Tsify))]
18#[cfg_attr(js, tsify(from_wasm_abi))]
19#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
20#[derive(Debug, Clone, TypedBuilder)]
21pub struct UpdateOrder {
22 #[cfg_attr(serde, serde(default))]
24 #[builder(default)]
25 pub program: StoreProgram,
26 #[builder(setter(into))]
28 pub payer: StringPubkey,
29 #[builder(setter(into))]
31 pub order: StringPubkey,
32 pub params: UpdateOrderParams,
34}
35
36#[cfg_attr(js, derive(tsify_next::Tsify))]
38#[cfg_attr(js, tsify(from_wasm_abi))]
39#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
40#[derive(Debug, Clone, TypedBuilder)]
41pub struct UpdateOrderParams {
42 #[cfg_attr(serde, serde(default))]
44 #[builder(default, setter(strip_option))]
45 pub size_delta_value: Option<u128>,
46 #[cfg_attr(serde, serde(default))]
48 #[builder(default, setter(strip_option))]
49 pub acceptable_price: Option<u128>,
50 #[cfg_attr(serde, serde(default))]
52 #[builder(default, setter(strip_option))]
53 pub trigger_price: Option<u128>,
54 #[cfg_attr(serde, serde(default))]
56 #[builder(default, setter(strip_option))]
57 pub min_output: Option<u128>,
58 #[cfg_attr(serde, serde(default))]
60 #[builder(default, setter(strip_option))]
61 pub valid_from_ts: Option<i64>,
62}
63
64impl From<UpdateOrderParams> for types::UpdateOrderParams {
65 fn from(params: UpdateOrderParams) -> Self {
66 Self {
67 size_delta_value: params.size_delta_value,
68 acceptable_price: params.acceptable_price,
69 trigger_price: params.trigger_price,
70 min_output: params.min_output,
71 valid_from_ts: params.valid_from_ts,
72 }
73 }
74}
75
76#[cfg_attr(js, derive(tsify_next::Tsify))]
78#[cfg_attr(js, tsify(from_wasm_abi))]
79#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
80#[derive(Debug, Clone, TypedBuilder)]
81pub struct UpdateOrderHint {
82 #[builder(setter(into))]
84 pub market_token: StringPubkey,
85 pub callback: Option<Callback>,
87}
88
89impl IntoAtomicGroup for UpdateOrder {
90 type Hint = UpdateOrderHint;
91
92 fn into_atomic_group(self, hint: &Self::Hint) -> gmsol_solana_utils::Result<AtomicGroup> {
93 let payer = self.payer.0;
94
95 let CallbackParams {
96 callback_authority,
97 callback_program,
98 callback_shared_data_account,
99 callback_partitioned_data_account,
100 ..
101 } = self.program.get_callback_params(hint.callback.as_ref());
102
103 let update = self
104 .program
105 .anchor_instruction(args::UpdateOrderV2 {
106 params: self.params.into(),
107 })
108 .anchor_accounts(
109 accounts::UpdateOrderV2 {
110 owner: payer,
111 store: self.program.store.0,
112 market: self.program.find_market_address(&hint.market_token),
113 order: self.order.0,
114 event_authority: self.program.find_event_authority_address(),
115 program: self.program.id.0,
116 callback_authority,
117 callback_program,
118 callback_shared_data_account,
119 callback_partitioned_data_account,
120 },
121 true,
122 )
123 .build();
124 Ok(AtomicGroup::with_instructions(&payer, Some(update)))
125 }
126}
127
128#[cfg_attr(js, derive(tsify_next::Tsify))]
130#[cfg_attr(js, tsify(from_wasm_abi))]
131#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
132#[derive(Debug, Clone, TypedBuilder)]
133pub struct SetShouldKeepPositionAccount {
134 #[cfg_attr(serde, serde(default))]
136 #[builder(default)]
137 pub program: StoreProgram,
138 #[builder(setter(into))]
140 pub payer: StringPubkey,
141 #[builder(setter(into))]
143 pub order: StringPubkey,
144 pub keep: bool,
146}
147
148impl IntoAtomicGroup for SetShouldKeepPositionAccount {
149 type Hint = ();
150
151 fn into_atomic_group(self, _hint: &Self::Hint) -> gmsol_solana_utils::Result<AtomicGroup> {
152 let owner = self.payer.0;
153 let ix = self
154 .program
155 .anchor_instruction(args::SetShouldKeepPositionAccount { keep: self.keep })
156 .anchor_accounts(
157 accounts::SetShouldKeepPositionAccount {
158 owner,
159 order: self.order.0,
160 },
161 false,
162 )
163 .build();
164
165 Ok(AtomicGroup::with_instructions(&self.payer, [ix]))
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use gmsol_solana_utils::transaction_builder::default_before_sign;
172 use solana_sdk::pubkey::Pubkey;
173
174 use crate::constants;
175
176 use super::*;
177
178 #[test]
179 fn update_order() -> crate::Result<()> {
180 let payer = Pubkey::new_unique();
181 let order = Pubkey::new_unique();
182 let market_token = Pubkey::new_unique();
183 let params = UpdateOrderParams::builder()
184 .size_delta_value(1_000 * constants::MARKET_USD_UNIT)
185 .build();
186 UpdateOrder::builder()
187 .payer(payer)
188 .order(order)
189 .params(params)
190 .build()
191 .into_atomic_group(
192 &UpdateOrderHint::builder()
193 .market_token(market_token)
194 .callback(None)
195 .build(),
196 )?
197 .partially_signed_transaction_with_blockhash_and_options(
198 Default::default(),
199 Default::default(),
200 None,
201 default_before_sign,
202 )?;
203 Ok(())
204 }
205}