Skip to main content

gmsol_sdk/js/simulation/
order.rs

1//! Order simulation.
2
3use serde::{Deserialize, Serialize};
4use tsify_next::Tsify;
5use wasm_bindgen::prelude::*;
6
7use crate::{
8    builders::order::{CreateOrderKind, CreateOrderParams},
9    js::simulation::{encode_borsh_base64, encode_bytemuck_base64},
10    serde::StringPubkey,
11    simulation::order::OrderSimulationOutput,
12};
13
14use crate::js::position::JsPositionModel;
15
16/// Arguments for order simulation.
17#[derive(Debug, Serialize, Deserialize, Tsify)]
18#[tsify(into_wasm_abi, from_wasm_abi)]
19pub struct SimulateOrderArgs {
20    pub(crate) kind: CreateOrderKind,
21    pub(crate) params: CreateOrderParams,
22    pub(crate) collateral_or_swap_out_token: StringPubkey,
23    #[serde(default)]
24    pub(crate) pay_token: Option<StringPubkey>,
25    #[serde(default)]
26    pub(crate) receive_token: Option<StringPubkey>,
27    #[serde(default)]
28    pub(crate) swap_path: Option<Vec<StringPubkey>>,
29    #[serde(default)]
30    pub(crate) prefer_swap_out_token_update: Option<bool>,
31    #[serde(default)]
32    pub(crate) skip_limit_price_validation: Option<bool>,
33    #[serde(default)]
34    pub(crate) limit_swap_slippage: Option<u128>,
35    #[serde(default)]
36    pub(crate) update_prices_for_limit_order: Option<bool>,
37}
38
39/// A JS binding for [`OrderSimulationOutput`].
40#[wasm_bindgen(js_name = OrderSimulationOutput)]
41pub struct JsOrderSimulationOutput {
42    pub(crate) output: OrderSimulationOutput,
43}
44
45/// Simulation output for increase order.
46#[derive(Debug, Serialize, Deserialize, Tsify)]
47#[tsify(into_wasm_abi)]
48pub struct IncreaseOrderSimulationOutput {
49    swaps: Vec<String>,
50    report: String,
51    position: Option<String>,
52}
53
54/// Simulation output for decrease order.
55#[derive(Debug, Serialize, Deserialize, Tsify)]
56#[tsify(into_wasm_abi)]
57pub struct DecreaseOrderSimulationOutput {
58    swaps: Vec<String>,
59    report: String,
60    position: Option<String>,
61    decrease_swap: Option<String>,
62}
63
64/// Simulation output for swap order.
65#[derive(Debug, Serialize, Deserialize, Tsify)]
66#[tsify(into_wasm_abi)]
67pub struct SwapOrderSimulationOutput {
68    output_token: StringPubkey,
69    amount: u128,
70    report: Vec<String>,
71}
72
73#[wasm_bindgen(js_class = OrderSimulationOutput)]
74impl JsOrderSimulationOutput {
75    /// Returns increase order simulation output.
76    pub fn increase(
77        &self,
78        skip_position: Option<bool>,
79    ) -> crate::Result<Option<IncreaseOrderSimulationOutput>> {
80        if let OrderSimulationOutput::Increase {
81            swaps,
82            report,
83            position,
84        } = &self.output
85        {
86            let encode_position = !skip_position.unwrap_or_default();
87            Ok(Some(IncreaseOrderSimulationOutput {
88                swaps: swaps
89                    .iter()
90                    .map(encode_borsh_base64)
91                    .collect::<crate::Result<Vec<_>>>()?,
92                report: encode_borsh_base64(report)?,
93                position: encode_position.then(|| encode_bytemuck_base64(position.position())),
94            }))
95        } else {
96            Ok(None)
97        }
98    }
99
100    /// Returns decrease order simulation output.
101    pub fn decrease(
102        &self,
103        skip_position: Option<bool>,
104    ) -> crate::Result<Option<DecreaseOrderSimulationOutput>> {
105        if let OrderSimulationOutput::Decrease {
106            swaps,
107            report,
108            position,
109        } = &self.output
110        {
111            let encode_position = !skip_position.unwrap_or_default();
112            Ok(Some(DecreaseOrderSimulationOutput {
113                swaps: swaps
114                    .iter()
115                    .map(encode_borsh_base64)
116                    .collect::<crate::Result<Vec<_>>>()?,
117                report: encode_borsh_base64(report)?,
118                position: encode_position.then(|| encode_bytemuck_base64(position.position())),
119                decrease_swap: position
120                    .swap_history()
121                    .first()
122                    .map(|s| encode_borsh_base64(&**s))
123                    .transpose()?,
124            }))
125        } else {
126            Ok(None)
127        }
128    }
129
130    /// Returns swap order simulation output.
131    pub fn swap(&self) -> crate::Result<Option<SwapOrderSimulationOutput>> {
132        if let OrderSimulationOutput::Swap(swap) = &self.output {
133            Ok(Some(SwapOrderSimulationOutput {
134                output_token: (*swap.output_token()).into(),
135                amount: swap.amount(),
136                report: swap
137                    .reports()
138                    .iter()
139                    .map(encode_borsh_base64)
140                    .collect::<crate::Result<Vec<_>>>()?,
141            }))
142        } else {
143            Ok(None)
144        }
145    }
146
147    /// Returns the result position model.
148    pub fn position_model(&self) -> Option<JsPositionModel> {
149        match &self.output {
150            OrderSimulationOutput::Increase { position, .. }
151            | OrderSimulationOutput::Decrease { position, .. } => {
152                Some(JsPositionModel::from(position.clone()))
153            }
154            _ => None,
155        }
156    }
157}