acta_maker_sdk/ws/maker/
quote.rs1use crate::ws::managed::{
2 MakerWsEndpoint, ManagedMessageReceiver, ManagedWsConfig, ManagedWsError, ManagedWsEvent,
3 ManagedWsHandle, ManagedWsState, SendTicket, WaitUntilReadyError, spawn_managed_ws,
4};
5use crate::ws::types::{
6 AddChannelsData, AddMintsData, BatchQuotesMessage, CancelAllQuotesMessage, CancelQuoteData,
7 ClientMessage, IndicativePricesResponseMessage, QuoteMessage, RemoveChannelsData,
8 RemoveMintsData, ReplaceQuoteMessage, SubscribeData, UnsubscribeData,
9};
10use tokio::sync::broadcast;
11
12use super::MakerClientError;
13
14#[derive(Clone)]
19pub struct MakerQuoteClient {
20 inner: ManagedWsHandle,
21}
22
23impl MakerQuoteClient {
24 pub fn spawn(config: ManagedWsConfig) -> Result<Self, MakerClientError> {
25 if config.endpoint != MakerWsEndpoint::Quote {
26 return Err(MakerClientError::WrongEndpoint {
27 client: "MakerQuoteClient",
28 required: MakerWsEndpoint::Quote,
29 actual: config.endpoint,
30 });
31 }
32 Ok(Self {
33 inner: spawn_managed_ws(config)?,
34 })
35 }
36
37 pub async fn quote(&self, payload: QuoteMessage) -> Result<(), ManagedWsError> {
38 self.inner.ensure_ready()?;
39 self.inner.send(ClientMessage::Quote(payload)).await
40 }
41
42 pub fn try_quote(&self, payload: QuoteMessage) -> Result<SendTicket, ManagedWsError> {
43 self.inner.ensure_ready()?;
44 self.inner.try_send(ClientMessage::Quote(payload))
45 }
46
47 pub async fn replace_quote(&self, payload: ReplaceQuoteMessage) -> Result<(), ManagedWsError> {
48 self.inner.ensure_ready()?;
49 self.inner.send(ClientMessage::ReplaceQuote(payload)).await
50 }
51
52 pub fn try_replace_quote(
53 &self,
54 payload: ReplaceQuoteMessage,
55 ) -> Result<SendTicket, ManagedWsError> {
56 self.inner.ensure_ready()?;
57 self.inner.try_send(ClientMessage::ReplaceQuote(payload))
58 }
59
60 pub async fn batch_quotes(&self, payload: BatchQuotesMessage) -> Result<(), ManagedWsError> {
61 self.inner.ensure_ready()?;
62 self.inner.send(ClientMessage::BatchQuotes(payload)).await
63 }
64
65 pub fn try_batch_quotes(
66 &self,
67 payload: BatchQuotesMessage,
68 ) -> Result<SendTicket, ManagedWsError> {
69 self.inner.ensure_ready()?;
70 self.inner.try_send(ClientMessage::BatchQuotes(payload))
71 }
72
73 pub async fn cancel_quote(&self, payload: CancelQuoteData) -> Result<(), ManagedWsError> {
74 self.inner.ensure_ready()?;
75 self.inner.send(ClientMessage::CancelQuote(payload)).await
76 }
77
78 pub fn try_cancel_quote(&self, payload: CancelQuoteData) -> Result<SendTicket, ManagedWsError> {
79 self.inner.ensure_ready()?;
80 self.inner.try_send(ClientMessage::CancelQuote(payload))
81 }
82
83 pub async fn cancel_all_quotes(
84 &self,
85 payload: CancelAllQuotesMessage,
86 ) -> Result<(), ManagedWsError> {
87 self.inner.ensure_ready()?;
88 self.inner
89 .send(ClientMessage::CancelAllQuotes(payload))
90 .await
91 }
92
93 pub fn try_cancel_all_quotes(
94 &self,
95 payload: CancelAllQuotesMessage,
96 ) -> Result<SendTicket, ManagedWsError> {
97 self.inner.ensure_ready()?;
98 self.inner.try_send(ClientMessage::CancelAllQuotes(payload))
99 }
100
101 pub async fn indicative_prices_response(
102 &self,
103 payload: IndicativePricesResponseMessage,
104 ) -> Result<(), ManagedWsError> {
105 self.inner.ensure_ready()?;
106 self.inner
107 .send(ClientMessage::IndicativePricesResponse(payload))
108 .await
109 }
110
111 pub fn try_indicative_prices_response(
112 &self,
113 payload: IndicativePricesResponseMessage,
114 ) -> Result<SendTicket, ManagedWsError> {
115 self.inner.ensure_ready()?;
116 self.inner
117 .try_send(ClientMessage::IndicativePricesResponse(payload))
118 }
119
120 pub async fn subscribe(&self, payload: SubscribeData) -> Result<(), ManagedWsError> {
121 self.inner.ensure_ready()?;
122 self.inner.send(ClientMessage::Subscribe(payload)).await
123 }
124
125 pub async fn unsubscribe(&self, payload: UnsubscribeData) -> Result<(), ManagedWsError> {
126 self.inner.ensure_ready()?;
127 self.inner.send(ClientMessage::Unsubscribe(payload)).await
128 }
129
130 pub async fn add_mints(&self, payload: AddMintsData) -> Result<(), ManagedWsError> {
131 self.inner.ensure_ready()?;
132 self.inner.send(ClientMessage::AddMints(payload)).await
133 }
134
135 pub async fn remove_mints(&self, payload: RemoveMintsData) -> Result<(), ManagedWsError> {
136 self.inner.ensure_ready()?;
137 self.inner.send(ClientMessage::RemoveMints(payload)).await
138 }
139
140 pub async fn add_channels(&self, payload: AddChannelsData) -> Result<(), ManagedWsError> {
141 self.inner.ensure_ready()?;
142 self.inner.send(ClientMessage::AddChannels(payload)).await
143 }
144
145 pub async fn remove_channels(&self, payload: RemoveChannelsData) -> Result<(), ManagedWsError> {
146 self.inner.ensure_ready()?;
147 self.inner
148 .send(ClientMessage::RemoveChannels(payload))
149 .await
150 }
151
152 pub fn subscribe_messages(&self) -> ManagedMessageReceiver {
153 self.inner.subscribe_messages()
154 }
155
156 pub fn subscribe_events(&self) -> broadcast::Receiver<ManagedWsEvent> {
157 self.inner.subscribe_events()
158 }
159
160 #[must_use]
161 pub fn state(&self) -> ManagedWsState {
162 self.inner.state()
163 }
164
165 pub async fn wait_until_ready(&self) -> Result<u64, WaitUntilReadyError> {
166 self.inner.wait_until_ready().await
167 }
168
169 #[must_use]
170 pub const fn raw(&self) -> &ManagedWsHandle {
171 &self.inner
172 }
173
174 #[must_use]
175 pub fn into_raw(self) -> ManagedWsHandle {
176 self.inner
177 }
178
179 pub async fn close(&self) -> Result<(), ManagedWsError> {
180 self.inner.close().await
181 }
182}
183
184#[cfg(test)]
185mod tests {
186 use std::sync::Arc;
187
188 use super::*;
189 use crate::ws::types::HelloData;
190
191 #[test]
192 fn quote_client_rejects_data_endpoint_before_spawning() {
193 let config = ManagedWsConfig::new(
194 "ws://localhost",
195 HelloData {
196 protocol_version: "1.0.0".to_string(),
197 features: Vec::new(),
198 client_name: None,
199 client_version: None,
200 },
201 Arc::new(crate::orders::BytesSigner::from_secret([1u8; 32])),
202 )
203 .with_endpoint(MakerWsEndpoint::Data);
204
205 assert!(matches!(
206 MakerQuoteClient::spawn(config),
207 Err(MakerClientError::WrongEndpoint {
208 required: MakerWsEndpoint::Quote,
209 actual: MakerWsEndpoint::Data,
210 ..
211 })
212 ));
213 }
214}