nash_protocol/protocol/place_orders/
request.rs1use crate::errors::Result;
2use crate::graphql::place_limit_order;
3use crate::graphql::place_market_order;
4use super::super::State;
5use super::types::{
6 LimitOrdersConstructor, LimitOrdersRequest,
7 MarketOrdersConstructor, MarketOrdersRequest
8};
9
10use tokio::sync::RwLock;
11use std::sync::Arc;
12
13use std::collections::HashMap;
14use crate::protocol::multi_request::DynamicQueryBody;
15
16impl LimitOrdersRequest {
17 pub async fn make_constructor(&self, state: Arc<RwLock<State>>) -> Result<LimitOrdersConstructor> {
20 let mut constructors = Vec::new();
21 for request in &self.requests {
22 constructors.push(request.make_constructor(state.clone()).await?);
23 }
24 Ok(LimitOrdersConstructor { constructors })
25 }
26}
27
28impl MarketOrdersRequest {
29 pub async fn make_constructor(&self, state: Arc<RwLock<State>>) -> Result<MarketOrdersConstructor> {
32 let mut constructors = Vec::new();
33 for request in &self.requests {
34 constructors.push(request.make_constructor(state.clone()).await?);
35 }
36 Ok(MarketOrdersConstructor { constructors })
37 }
38}
39
40impl LimitOrdersConstructor {
41 pub fn graphql_request(
44 &self,
45 current_time: i64,
46 affiliate: Option<String>,
47 ) -> Result<Vec<place_limit_order::Variables>> {
48 let mut variables = Vec::new();
49 for (index, variable) in self.constructors.iter().enumerate() {
50 variables.push(variable.graphql_request(current_time + index as i64, affiliate.clone())?);
51 }
52 Ok(variables)
53 }
54
55 pub async fn signed_graphql_request(
58 &self,
59 current_time: i64,
60 affiliate: Option<String>,
61 state: Arc<RwLock<State>>,
62 order_precision: u32,
63 fee_precision: u32
64 ) -> Result<DynamicQueryBody> {
65 let variables = self.graphql_request(current_time, affiliate)?;
66 let mut map = HashMap::new();
67 let mut params = String::new();
68 let mut calls = String::new();
69 for (index, (variable, constructor)) in variables.into_iter().zip(self.constructors.iter()).enumerate() {
70 let nonces = constructor.make_payload_nonces(state.clone(), current_time + index as i64).await?;
72 let state = state.read().await;
73 let signer = state.signer()?;
74 let variable = constructor.sign_graphql_request(variable, nonces, signer, order_precision, fee_precision)?;
75
76 let payload = format!("payload{}", index);
78 let signature = format!("signature{}", index);
79 let affiliate = format!("affiliate{}", index);
80 params = if index == 0 { params } else { format!("{}, ", params)};
81 params = format!("{}${}: PlaceLimitOrderParams!, ${}: Signature!, ${}: AffiliateDeveloperCode", params, payload, signature, affiliate);
82 calls = format!(r#"
83 {}
84 response{}: placeLimitOrder(payload: ${}, signature: ${}, affiliateDeveloperCode: ${}) {{
85 id
86 status
87 ordersTillSignState,
88 buyOrSell,
89 market {{
90 name
91 }},
92 placedAt,
93 type
94 }}
95 "#, calls, index, payload, signature, affiliate);
96 map.insert(payload, serde_json::to_value(variable.payload).unwrap());
97 map.insert(signature, serde_json::to_value(variable.signature).unwrap());
98 map.insert(affiliate, serde_json::to_value(variable.affiliate).unwrap());
99 }
100 Ok(DynamicQueryBody {
101 variables: map,
102 operation_name: "PlaceLimitOrder",
103 query: format!(r#"
104 mutation PlaceLimitOrder({}) {{
105 {}
106 }}
107 "#, params, calls)
108 })
109 }
110}
111
112impl MarketOrdersConstructor {
113 pub fn graphql_request(
116 &self,
117 current_time: i64,
118 affiliate: Option<String>,
119 ) -> Result<Vec<place_market_order::Variables>> {
120 let mut variables = Vec::new();
121 for (index, variable) in self.constructors.iter().enumerate() {
122 variables.push(variable.graphql_request(current_time + index as i64, affiliate.clone())?);
123 }
124 Ok(variables)
125 }
126
127 pub async fn signed_graphql_request(
130 &self,
131 current_time: i64,
132 affiliate: Option<String>,
133 state: Arc<RwLock<State>>,
134 order_precision: u32,
135 fee_precision: u32
136 ) -> Result<DynamicQueryBody> {
137 let variables = self.graphql_request(current_time, affiliate)?;
138 let mut map = HashMap::new();
139 let mut params = String::new();
140 let mut calls = String::new();
141 for (index, (variable, constructor)) in variables.into_iter().zip(self.constructors.iter()).enumerate() {
142 let nonces = constructor.make_payload_nonces(state.clone(), current_time + index as i64).await?;
144 let state = state.read().await;
145 let signer = state.signer()?;
146 let variable = constructor.sign_graphql_request(variable, nonces, signer, order_precision, fee_precision)?;
147
148 let payload = format!("payload{}", index);
149 let signature = format!("signature{}", index);
150 let affiliate = format!("affiliate{}", index);
151 params = if index == 0 { params } else { format!("{}, ", params)};
152 params = format!("{}${}: PlaceMarketOrderParams!, ${}: Signature!, ${}: AffiliateDeveloperCode", params, payload, signature, affiliate);
153 calls = format!(r#"
154 {}
155 response{}: placeMarketOrder(payload: ${}, signature: ${}, affiliateDeveloperCode: ${}) {{
156 id
157 status
158 ordersTillSignState,
159 buyOrSell,
160 market {{
161 name
162 }},
163 placedAt,
164 type
165 }}
166 "#, calls, index, payload, signature, affiliate);
167 map.insert(payload, serde_json::to_value(variable.payload).unwrap());
168 map.insert(signature, serde_json::to_value(variable.signature).unwrap());
169 map.insert(affiliate, serde_json::to_value(variable.affiliate).unwrap());
170 }
171 Ok(DynamicQueryBody {
172 variables: map,
173 operation_name: "PlaceMarketOrder",
174 query: format!(r#"
175 mutation PlaceMarketOrder({}) {{
176 {}
177 }}
178 "#, params, calls)
179 })
180 }
181}