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, initialize::InitializeEvent, mint::MintEvent,
30 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 convert_to_trade_data_fn: Option<ConvertTradeDataFn>,
55}
56
57impl DexExtended {
58 #[must_use]
60 pub fn new(dex: Dex) -> Self {
61 Self {
62 dex: Arc::new(dex),
63 parse_pool_created_event_fn: None,
64 parse_initialize_event_fn: None,
65 parse_swap_event_fn: None,
66 parse_mint_event_fn: None,
67 parse_burn_event_fn: None,
68 parse_collect_event_fn: None,
69 convert_to_trade_data_fn: None,
70 }
71 }
72
73 pub fn set_pool_created_event_parsing(
75 &mut self,
76 parse_pool_created_event: fn(Log) -> anyhow::Result<PoolCreatedEvent>,
77 ) {
78 self.parse_pool_created_event_fn = Some(parse_pool_created_event);
79 }
80
81 pub fn set_initialize_event_parsing(
83 &mut self,
84 parse_initialize_event: fn(SharedDex, Log) -> anyhow::Result<InitializeEvent>,
85 ) {
86 self.parse_initialize_event_fn = Some(parse_initialize_event);
87 }
88
89 pub fn set_swap_event_parsing(
91 &mut self,
92 parse_swap_event: fn(SharedDex, Log) -> anyhow::Result<SwapEvent>,
93 ) {
94 self.parse_swap_event_fn = Some(parse_swap_event);
95 }
96
97 pub fn set_mint_event_parsing(
99 &mut self,
100 parse_mint_event: fn(SharedDex, Log) -> anyhow::Result<MintEvent>,
101 ) {
102 self.parse_mint_event_fn = Some(parse_mint_event);
103 }
104
105 pub fn set_burn_event_parsing(
107 &mut self,
108 parse_burn_event: fn(SharedDex, Log) -> anyhow::Result<BurnEvent>,
109 ) {
110 self.parse_burn_event_fn = Some(parse_burn_event);
111 }
112
113 pub fn set_collect_event_parsing(
115 &mut self,
116 parse_collect_event: fn(SharedDex, Log) -> anyhow::Result<CollectEvent>,
117 ) {
118 self.parse_collect_event_fn = Some(parse_collect_event);
119 }
120
121 pub fn set_convert_trade_data(&mut self, convert_trade_data: ConvertTradeDataFn) {
123 self.convert_to_trade_data_fn = Some(convert_trade_data);
124 }
125
126 pub fn parse_pool_created_event(&self, log: Log) -> anyhow::Result<PoolCreatedEvent> {
132 if let Some(parse_pool_created_event_fn) = &self.parse_pool_created_event_fn {
133 parse_pool_created_event_fn(log)
134 } else {
135 anyhow::bail!(
136 "Parsing of pool created event in not defined in this dex: {}:{}",
137 self.dex.chain,
138 self.dex.name,
139 )
140 }
141 }
142
143 pub fn parse_swap_event(&self, log: Log) -> anyhow::Result<SwapEvent> {
149 if let Some(parse_swap_event_fn) = &self.parse_swap_event_fn {
150 parse_swap_event_fn(self.dex.clone(), log)
151 } else {
152 anyhow::bail!(
153 "Parsing of swap event in not defined in this dex: {}:{}",
154 self.dex.chain,
155 self.dex.name
156 )
157 }
158 }
159
160 pub fn convert_to_trade_data(
166 &self,
167 token0: &Token,
168 token1: &Token,
169 swap_event: &SwapEvent,
170 ) -> anyhow::Result<(OrderSide, Quantity, Price)> {
171 if let Some(convert_to_trade_data_fn) = &self.convert_to_trade_data_fn {
172 convert_to_trade_data_fn(token0, token1, swap_event)
173 } else {
174 anyhow::bail!(
175 "Converting to trade data is not defined in this dex: {}:{}",
176 self.dex.chain,
177 self.dex.name
178 )
179 }
180 }
181
182 pub fn parse_mint_event(&self, log: Log) -> anyhow::Result<MintEvent> {
188 if let Some(parse_mint_event_fn) = &self.parse_mint_event_fn {
189 parse_mint_event_fn(self.dex.clone(), log)
190 } else {
191 anyhow::bail!(
192 "Parsing of mint event in not defined in this dex: {}:{}",
193 self.dex.chain,
194 self.dex.name
195 )
196 }
197 }
198
199 pub fn parse_burn_event(&self, log: Log) -> anyhow::Result<BurnEvent> {
205 if let Some(parse_burn_event_fn) = &self.parse_burn_event_fn {
206 parse_burn_event_fn(self.dex.clone(), log)
207 } else {
208 anyhow::bail!(
209 "Parsing of burn event in not defined in this dex: {}",
210 self.dex.name
211 )
212 }
213 }
214
215 pub fn needs_initialization(&self) -> bool {
217 self.dex.initialize_event.is_some()
218 }
219
220 pub fn parse_initialize_event(&self, log: Log) -> anyhow::Result<InitializeEvent> {
222 if let Some(parse_initialize_event_fn) = &self.parse_initialize_event_fn {
223 parse_initialize_event_fn(self.dex.clone(), log)
224 } else {
225 anyhow::bail!(
226 "Parsing of initialize event in not defined in this dex: {}",
227 self.dex.name
228 )
229 }
230 }
231
232 pub fn parse_collect_event(&self, log: Log) -> anyhow::Result<CollectEvent> {
238 if let Some(parse_collect_event_fn) = &self.parse_collect_event_fn {
239 parse_collect_event_fn(self.dex.clone(), log)
240 } else {
241 anyhow::bail!(
242 "Parsing of collect event in not defined in this dex: {}:{}",
243 self.dex.chain,
244 self.dex.name
245 )
246 }
247 }
248}
249
250impl Deref for DexExtended {
251 type Target = Dex;
252
253 fn deref(&self) -> &Self::Target {
254 &self.dex
255 }
256}