nautilus_blockchain/exchanges/
extended.rs1use std::{ops::Deref, sync::Arc};
17
18use hypersync_client::simple_types::Log;
19use nautilus_model::{
20 defi::{
21 dex::{Dex, SharedDex},
22 token::Token,
23 },
24 enums::OrderSide,
25 types::{Price, Quantity},
26};
27
28use crate::events::{
29 burn::BurnEvent, collect::CollectEvent, flash::FlashEvent, initialize::InitializeEvent,
30 mint::MintEvent, pool_created::PoolCreatedEvent, swap::SwapEvent,
31};
32
33type ConvertTradeDataFn =
34 fn(&Token, &Token, &SwapEvent) -> anyhow::Result<(OrderSide, Quantity, Price)>;
35
36#[derive(Debug, Clone)]
38pub struct DexExtended {
39 pub dex: SharedDex,
41 pub parse_pool_created_event_fn: Option<fn(Log) -> anyhow::Result<PoolCreatedEvent>>,
43 pub parse_initialize_event_fn: Option<fn(SharedDex, Log) -> anyhow::Result<InitializeEvent>>,
45 pub parse_swap_event_fn: Option<fn(SharedDex, Log) -> anyhow::Result<SwapEvent>>,
47 pub parse_mint_event_fn: Option<fn(SharedDex, Log) -> anyhow::Result<MintEvent>>,
49 pub parse_burn_event_fn: Option<fn(SharedDex, Log) -> anyhow::Result<BurnEvent>>,
51 pub parse_collect_event_fn: Option<fn(SharedDex, Log) -> anyhow::Result<CollectEvent>>,
53 pub parse_flash_event_fn: Option<fn(SharedDex, Log) -> anyhow::Result<FlashEvent>>,
55 pub convert_to_trade_data_fn: Option<ConvertTradeDataFn>,
57}
58
59impl DexExtended {
60 #[must_use]
62 pub fn new(dex: Dex) -> Self {
63 Self {
64 dex: Arc::new(dex),
65 parse_pool_created_event_fn: None,
66 parse_initialize_event_fn: None,
67 parse_swap_event_fn: None,
68 parse_mint_event_fn: None,
69 parse_burn_event_fn: None,
70 parse_collect_event_fn: None,
71 convert_to_trade_data_fn: None,
72 parse_flash_event_fn: None,
73 }
74 }
75
76 pub fn set_pool_created_event_parsing(
78 &mut self,
79 parse_pool_created_event: fn(Log) -> anyhow::Result<PoolCreatedEvent>,
80 ) {
81 self.parse_pool_created_event_fn = Some(parse_pool_created_event);
82 }
83
84 pub fn set_initialize_event_parsing(
86 &mut self,
87 parse_initialize_event: fn(SharedDex, Log) -> anyhow::Result<InitializeEvent>,
88 ) {
89 self.parse_initialize_event_fn = Some(parse_initialize_event);
90 }
91
92 pub fn set_swap_event_parsing(
94 &mut self,
95 parse_swap_event: fn(SharedDex, Log) -> anyhow::Result<SwapEvent>,
96 ) {
97 self.parse_swap_event_fn = Some(parse_swap_event);
98 }
99
100 pub fn set_mint_event_parsing(
102 &mut self,
103 parse_mint_event: fn(SharedDex, Log) -> anyhow::Result<MintEvent>,
104 ) {
105 self.parse_mint_event_fn = Some(parse_mint_event);
106 }
107
108 pub fn set_burn_event_parsing(
110 &mut self,
111 parse_burn_event: fn(SharedDex, Log) -> anyhow::Result<BurnEvent>,
112 ) {
113 self.parse_burn_event_fn = Some(parse_burn_event);
114 }
115
116 pub fn set_collect_event_parsing(
118 &mut self,
119 parse_collect_event: fn(SharedDex, Log) -> anyhow::Result<CollectEvent>,
120 ) {
121 self.parse_collect_event_fn = Some(parse_collect_event);
122 }
123
124 pub fn set_flash_event_parsing(
126 &mut self,
127 parse_flash_event: fn(SharedDex, Log) -> anyhow::Result<FlashEvent>,
128 ) {
129 self.parse_flash_event_fn = Some(parse_flash_event);
130 }
131
132 pub fn set_convert_trade_data(&mut self, convert_trade_data: ConvertTradeDataFn) {
134 self.convert_to_trade_data_fn = Some(convert_trade_data);
135 }
136
137 pub fn parse_pool_created_event(&self, log: Log) -> anyhow::Result<PoolCreatedEvent> {
143 if let Some(parse_pool_created_event_fn) = &self.parse_pool_created_event_fn {
144 parse_pool_created_event_fn(log)
145 } else {
146 anyhow::bail!(
147 "Parsing of pool created event in not defined in this dex: {}:{}",
148 self.dex.chain,
149 self.dex.name,
150 )
151 }
152 }
153
154 pub fn parse_swap_event(&self, log: Log) -> anyhow::Result<SwapEvent> {
160 if let Some(parse_swap_event_fn) = &self.parse_swap_event_fn {
161 parse_swap_event_fn(self.dex.clone(), log)
162 } else {
163 anyhow::bail!(
164 "Parsing of swap event in not defined in this dex: {}:{}",
165 self.dex.chain,
166 self.dex.name
167 )
168 }
169 }
170
171 pub fn convert_to_trade_data(
177 &self,
178 token0: &Token,
179 token1: &Token,
180 swap_event: &SwapEvent,
181 ) -> anyhow::Result<(OrderSide, Quantity, Price)> {
182 if let Some(convert_to_trade_data_fn) = &self.convert_to_trade_data_fn {
183 convert_to_trade_data_fn(token0, token1, swap_event)
184 } else {
185 anyhow::bail!(
186 "Converting to trade data is not defined in this dex: {}:{}",
187 self.dex.chain,
188 self.dex.name
189 )
190 }
191 }
192
193 pub fn parse_mint_event(&self, log: Log) -> anyhow::Result<MintEvent> {
199 if let Some(parse_mint_event_fn) = &self.parse_mint_event_fn {
200 parse_mint_event_fn(self.dex.clone(), log)
201 } else {
202 anyhow::bail!(
203 "Parsing of mint event in not defined in this dex: {}:{}",
204 self.dex.chain,
205 self.dex.name
206 )
207 }
208 }
209
210 pub fn parse_burn_event(&self, log: Log) -> anyhow::Result<BurnEvent> {
216 if let Some(parse_burn_event_fn) = &self.parse_burn_event_fn {
217 parse_burn_event_fn(self.dex.clone(), log)
218 } else {
219 anyhow::bail!(
220 "Parsing of burn event in not defined in this dex: {}",
221 self.dex.name
222 )
223 }
224 }
225
226 pub fn needs_initialization(&self) -> bool {
228 self.dex.initialize_event.is_some()
229 }
230
231 pub fn parse_initialize_event(&self, log: Log) -> anyhow::Result<InitializeEvent> {
233 if let Some(parse_initialize_event_fn) = &self.parse_initialize_event_fn {
234 parse_initialize_event_fn(self.dex.clone(), log)
235 } else {
236 anyhow::bail!(
237 "Parsing of initialize event in not defined in this dex: {}",
238 self.dex.name
239 )
240 }
241 }
242
243 pub fn parse_collect_event(&self, log: Log) -> anyhow::Result<CollectEvent> {
249 if let Some(parse_collect_event_fn) = &self.parse_collect_event_fn {
250 parse_collect_event_fn(self.dex.clone(), log)
251 } else {
252 anyhow::bail!(
253 "Parsing of collect event in not defined in this dex: {}:{}",
254 self.dex.chain,
255 self.dex.name
256 )
257 }
258 }
259}
260
261impl Deref for DexExtended {
262 type Target = Dex;
263
264 fn deref(&self) -> &Self::Target {
265 &self.dex
266 }
267}