Skip to content

Commit b70341e

Browse files
committed
cancelAndPlace support modify too
1 parent 1bca009 commit b70341e

File tree

3 files changed

+46
-51
lines changed

3 files changed

+46
-51
lines changed

src/controller.rs

+43-43
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{borrow::Cow, sync::Arc};
22

33
use drift_sdk::{
4+
constants::ProgramData,
45
dlob::DLOBClient,
56
types::{Context, MarketType, ModifyOrderParams, SdkError, SdkResult},
67
DriftClient, Pubkey, TransactionBuilder, Wallet, WsAccountProvider,
@@ -22,8 +23,6 @@ pub type GatewayResult<T> = Result<T, ControllerError>;
2223
pub enum ControllerError {
2324
#[error("internal error: {0}")]
2425
Sdk(#[from] SdkError),
25-
#[error("order id not found: {0}")]
26-
UnknownOrderId(u32),
2726
#[error("{0}")]
2827
BadRequest(String),
2928
#[error("tx failed ({code}): {reason}")]
@@ -215,7 +214,8 @@ impl AppState {
215214
)
216215
.payer(self.wallet.signer());
217216

218-
let tx = build_cancel_ix(builder, req.cancel)?
217+
let builder = build_cancel_ix(builder, req.cancel)?;
218+
let tx = build_modify_ix(builder, req.modify, self.client.program_data())?
219219
.place_orders(orders)
220220
.build();
221221

@@ -265,51 +265,14 @@ impl AppState {
265265
) -> GatewayResult<TxResponse> {
266266
let sub_account = self.wallet.sub_account(sub_account_id);
267267
let account_data = &self.client.get_user_account(&sub_account).await?;
268-
// NB: its possible to let the drift program sort the modifications by userOrderId
269-
// sorting it client side for simplicity
270-
let mut params = Vec::<(u32, ModifyOrderParams)>::with_capacity(req.orders.len());
271-
for order in req.orders {
272-
if let Some(order_id) = order.order_id {
273-
if let Some(onchain_order) =
274-
account_data.orders.iter().find(|x| x.order_id == order_id)
275-
{
276-
let base_decimals = get_market_decimals(
277-
self.client.program_data(),
278-
Market::new(onchain_order.market_index, onchain_order.market_type),
279-
);
280-
params.push((order_id, order.to_order_params(base_decimals)));
281-
continue;
282-
}
283-
} else if let Some(user_order_id) = order.user_order_id {
284-
if let Some(onchain_order) = account_data
285-
.orders
286-
.iter()
287-
.find(|x| x.user_order_id == user_order_id)
288-
{
289-
let base_decimals = get_market_decimals(
290-
self.client.program_data(),
291-
Market::new(onchain_order.market_index, onchain_order.market_type),
292-
);
293-
params.push((onchain_order.order_id, order.to_order_params(base_decimals)));
294-
continue;
295-
}
296-
}
297268

298-
return Err(ControllerError::UnknownOrderId(
299-
order
300-
.order_id
301-
.unwrap_or(order.user_order_id.unwrap_or(0) as u32),
302-
));
303-
}
304-
305-
let tx = TransactionBuilder::new(
269+
let builder = TransactionBuilder::new(
306270
self.client.program_data(),
307271
sub_account,
308272
Cow::Borrowed(account_data),
309273
)
310-
.payer(self.wallet.signer())
311-
.modify_orders(params.as_slice())
312-
.build();
274+
.payer(self.wallet.signer());
275+
let tx = build_modify_ix(builder, req, self.client.program_data())?.build();
313276

314277
self.client
315278
.sign_and_send(&self.wallet, tx)
@@ -366,6 +329,43 @@ fn build_cancel_ix(
366329
}
367330
}
368331

332+
fn build_modify_ix<'a>(
333+
builder: TransactionBuilder<'a>,
334+
req: ModifyOrdersRequest,
335+
program_data: &ProgramData,
336+
) -> GatewayResult<TransactionBuilder<'a>> {
337+
if req.orders.is_empty() {
338+
return Ok(builder);
339+
}
340+
341+
let by_user_order_ids = req.orders[0].user_order_id.is_some_and(|x| x > 0);
342+
if by_user_order_ids {
343+
let mut params = Vec::<(u8, ModifyOrderParams)>::with_capacity(req.orders.len());
344+
for order in req.orders {
345+
let base_decimals = get_market_decimals(program_data, order.market);
346+
params.push((
347+
order.user_order_id.ok_or(ControllerError::BadRequest(
348+
"userOrderId not set".to_string(),
349+
))?,
350+
order.to_order_params(base_decimals),
351+
));
352+
}
353+
Ok(builder.modify_orders_by_user_id(params.as_slice()))
354+
} else {
355+
let mut params = Vec::<(u32, ModifyOrderParams)>::with_capacity(req.orders.len());
356+
for order in req.orders {
357+
let base_decimals = get_market_decimals(program_data, order.market);
358+
params.push((
359+
order
360+
.order_id
361+
.ok_or(ControllerError::BadRequest("orderId not set".to_string()))?,
362+
order.to_order_params(base_decimals),
363+
));
364+
}
365+
Ok(builder.modify_orders(params.as_slice()))
366+
}
367+
}
368+
369369
/// Initialize a wallet for controller, possible valid configs:
370370
///
371371
/// 1) keypair

src/main.rs

-8
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,6 @@ fn handle_result<T>(result: Result<T, ControllerError>) -> Either<HttpResponse,
248248
}
249249
)))
250250
}
251-
Err(ControllerError::UnknownOrderId(id)) => {
252-
Either::Left(HttpResponse::NotFound().json(json!(
253-
{
254-
"code": 404,
255-
"reason": format!("order: {id}"),
256-
}
257-
)))
258-
}
259251
}
260252
}
261253

src/types.rs

+3
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ pub struct ModifyOrdersRequest {
156156
#[derive(Serialize, Deserialize, Debug)]
157157
#[serde(rename_all = "camelCase")]
158158
pub struct ModifyOrder {
159+
#[serde(flatten)]
160+
pub market: Market,
159161
amount: Option<Decimal>,
160162
price: Option<Decimal>,
161163
pub user_order_id: Option<u8>,
@@ -453,6 +455,7 @@ impl TxResponse {
453455
#[derive(Serialize, Deserialize)]
454456
pub struct CancelAndPlaceRequest {
455457
pub cancel: CancelOrdersRequest,
458+
pub modify: ModifyOrdersRequest,
456459
pub place: PlaceOrdersRequest,
457460
}
458461

0 commit comments

Comments
 (0)