1use std::{ops::Deref, sync::Arc};
17
18use nautilus_model::defi::{
19 dex::{Dex, SharedDex},
20 pool_analysis::PoolEventKind,
21 rpc::RpcLog,
22};
23
24use crate::{
25 events::{
26 burn::BurnEvent, collect::CollectEvent, fee_protocol_collect::FeeProtocolCollectEvent,
27 fee_protocol_update::FeeProtocolUpdateEvent, flash::FlashEvent,
28 initialize::InitializeEvent, mint::MintEvent, pool_created::PoolCreatedEvent,
29 swap::SwapEvent,
30 },
31 hypersync::HypersyncLog,
32};
33
34#[derive(Debug, Clone)]
36pub struct DexExtended {
37 pub dex: SharedDex,
39 pub parse_pool_created_event_hypersync_fn:
42 Option<fn(HypersyncLog) -> anyhow::Result<PoolCreatedEvent>>,
43 pub parse_initialize_event_hypersync_fn:
45 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<InitializeEvent>>,
46 pub parse_swap_event_hypersync_fn:
48 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<SwapEvent>>,
49 pub parse_mint_event_hypersync_fn:
51 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<MintEvent>>,
52 pub parse_burn_event_hypersync_fn:
54 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<BurnEvent>>,
55 pub parse_collect_event_hypersync_fn:
57 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<CollectEvent>>,
58 pub parse_flash_event_hypersync_fn:
60 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<FlashEvent>>,
61 pub parse_fee_protocol_update_event_hypersync_fn:
63 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<FeeProtocolUpdateEvent>>,
64 pub parse_fee_protocol_collect_event_hypersync_fn:
66 Option<fn(SharedDex, &HypersyncLog) -> anyhow::Result<FeeProtocolCollectEvent>>,
67 pub parse_pool_created_event_rpc_fn: Option<fn(&RpcLog) -> anyhow::Result<PoolCreatedEvent>>,
70 pub parse_initialize_event_rpc_fn:
72 Option<fn(SharedDex, &RpcLog) -> anyhow::Result<InitializeEvent>>,
73 pub parse_swap_event_rpc_fn: Option<fn(SharedDex, &RpcLog) -> anyhow::Result<SwapEvent>>,
75 pub parse_mint_event_rpc_fn: Option<fn(SharedDex, &RpcLog) -> anyhow::Result<MintEvent>>,
77 pub parse_burn_event_rpc_fn: Option<fn(SharedDex, &RpcLog) -> anyhow::Result<BurnEvent>>,
79 pub parse_collect_event_rpc_fn: Option<fn(SharedDex, &RpcLog) -> anyhow::Result<CollectEvent>>,
81 pub parse_flash_event_rpc_fn: Option<fn(SharedDex, &RpcLog) -> anyhow::Result<FlashEvent>>,
83 pub parse_fee_protocol_update_event_rpc_fn:
85 Option<fn(SharedDex, &RpcLog) -> anyhow::Result<FeeProtocolUpdateEvent>>,
86 pub parse_fee_protocol_collect_event_rpc_fn:
88 Option<fn(SharedDex, &RpcLog) -> anyhow::Result<FeeProtocolCollectEvent>>,
89}
90
91impl DexExtended {
92 #[must_use]
94 pub fn new(dex: Dex) -> Self {
95 Self {
96 dex: Arc::new(dex),
97 parse_pool_created_event_hypersync_fn: None,
99 parse_initialize_event_hypersync_fn: None,
100 parse_swap_event_hypersync_fn: None,
101 parse_mint_event_hypersync_fn: None,
102 parse_burn_event_hypersync_fn: None,
103 parse_collect_event_hypersync_fn: None,
104 parse_flash_event_hypersync_fn: None,
105 parse_fee_protocol_update_event_hypersync_fn: None,
106 parse_fee_protocol_collect_event_hypersync_fn: None,
107 parse_pool_created_event_rpc_fn: None,
109 parse_initialize_event_rpc_fn: None,
110 parse_swap_event_rpc_fn: None,
111 parse_mint_event_rpc_fn: None,
112 parse_burn_event_rpc_fn: None,
113 parse_collect_event_rpc_fn: None,
114 parse_flash_event_rpc_fn: None,
115 parse_fee_protocol_update_event_rpc_fn: None,
116 parse_fee_protocol_collect_event_rpc_fn: None,
117 }
118 }
119
120 pub fn set_pool_created_event_hypersync_parsing(
122 &mut self,
123 parse_fn: fn(HypersyncLog) -> anyhow::Result<PoolCreatedEvent>,
124 ) {
125 self.parse_pool_created_event_hypersync_fn = Some(parse_fn);
126 }
127
128 pub fn set_initialize_event_hypersync_parsing(
130 &mut self,
131 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<InitializeEvent>,
132 ) {
133 self.parse_initialize_event_hypersync_fn = Some(parse_fn);
134 }
135
136 pub fn set_swap_event_hypersync_parsing(
138 &mut self,
139 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<SwapEvent>,
140 ) {
141 self.parse_swap_event_hypersync_fn = Some(parse_fn);
142 }
143
144 pub fn set_mint_event_hypersync_parsing(
146 &mut self,
147 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<MintEvent>,
148 ) {
149 self.parse_mint_event_hypersync_fn = Some(parse_fn);
150 }
151
152 pub fn set_burn_event_hypersync_parsing(
154 &mut self,
155 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<BurnEvent>,
156 ) {
157 self.parse_burn_event_hypersync_fn = Some(parse_fn);
158 }
159
160 pub fn set_collect_event_hypersync_parsing(
162 &mut self,
163 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<CollectEvent>,
164 ) {
165 self.parse_collect_event_hypersync_fn = Some(parse_fn);
166 }
167
168 pub fn set_flash_event_hypersync_parsing(
170 &mut self,
171 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<FlashEvent>,
172 ) {
173 self.parse_flash_event_hypersync_fn = Some(parse_fn);
174 }
175
176 pub fn set_fee_protocol_update_event_hypersync_parsing(
178 &mut self,
179 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<FeeProtocolUpdateEvent>,
180 ) {
181 self.parse_fee_protocol_update_event_hypersync_fn = Some(parse_fn);
182 }
183
184 pub fn set_fee_protocol_collect_event_hypersync_parsing(
186 &mut self,
187 parse_fn: fn(SharedDex, &HypersyncLog) -> anyhow::Result<FeeProtocolCollectEvent>,
188 ) {
189 self.parse_fee_protocol_collect_event_hypersync_fn = Some(parse_fn);
190 }
191
192 pub fn set_pool_created_event_rpc_parsing(
194 &mut self,
195 parse_fn: fn(&RpcLog) -> anyhow::Result<PoolCreatedEvent>,
196 ) {
197 self.parse_pool_created_event_rpc_fn = Some(parse_fn);
198 }
199
200 pub fn set_initialize_event_rpc_parsing(
202 &mut self,
203 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<InitializeEvent>,
204 ) {
205 self.parse_initialize_event_rpc_fn = Some(parse_fn);
206 }
207
208 pub fn set_swap_event_rpc_parsing(
210 &mut self,
211 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<SwapEvent>,
212 ) {
213 self.parse_swap_event_rpc_fn = Some(parse_fn);
214 }
215
216 pub fn set_mint_event_rpc_parsing(
218 &mut self,
219 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<MintEvent>,
220 ) {
221 self.parse_mint_event_rpc_fn = Some(parse_fn);
222 }
223
224 pub fn set_burn_event_rpc_parsing(
226 &mut self,
227 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<BurnEvent>,
228 ) {
229 self.parse_burn_event_rpc_fn = Some(parse_fn);
230 }
231
232 pub fn set_collect_event_rpc_parsing(
234 &mut self,
235 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<CollectEvent>,
236 ) {
237 self.parse_collect_event_rpc_fn = Some(parse_fn);
238 }
239
240 pub fn set_flash_event_rpc_parsing(
242 &mut self,
243 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<FlashEvent>,
244 ) {
245 self.parse_flash_event_rpc_fn = Some(parse_fn);
246 }
247
248 pub fn set_fee_protocol_update_event_rpc_parsing(
250 &mut self,
251 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<FeeProtocolUpdateEvent>,
252 ) {
253 self.parse_fee_protocol_update_event_rpc_fn = Some(parse_fn);
254 }
255
256 pub fn set_fee_protocol_collect_event_rpc_parsing(
258 &mut self,
259 parse_fn: fn(SharedDex, &RpcLog) -> anyhow::Result<FeeProtocolCollectEvent>,
260 ) {
261 self.parse_fee_protocol_collect_event_rpc_fn = Some(parse_fn);
262 }
263
264 pub fn parse_pool_created_event_hypersync(
270 &self,
271 log: HypersyncLog,
272 ) -> anyhow::Result<PoolCreatedEvent> {
273 if let Some(parse_fn) = &self.parse_pool_created_event_hypersync_fn {
274 parse_fn(log)
275 } else {
276 anyhow::bail!(
277 "HyperSync parsing of pool created event is not defined in this dex: {}:{}",
278 self.dex.chain,
279 self.dex.name,
280 )
281 }
282 }
283
284 pub fn parse_swap_event_hypersync(&self, log: &HypersyncLog) -> anyhow::Result<SwapEvent> {
290 if let Some(parse_fn) = &self.parse_swap_event_hypersync_fn {
291 parse_fn(self.dex.clone(), log)
292 } else {
293 anyhow::bail!(
294 "HyperSync parsing of swap event is not defined in this dex: {}:{}",
295 self.dex.chain,
296 self.dex.name
297 )
298 }
299 }
300
301 pub fn parse_mint_event_hypersync(&self, log: &HypersyncLog) -> anyhow::Result<MintEvent> {
307 if let Some(parse_fn) = &self.parse_mint_event_hypersync_fn {
308 parse_fn(self.dex.clone(), log)
309 } else {
310 anyhow::bail!(
311 "HyperSync parsing of mint event is not defined in this dex: {}:{}",
312 self.dex.chain,
313 self.dex.name
314 )
315 }
316 }
317
318 pub fn parse_burn_event_hypersync(&self, log: &HypersyncLog) -> anyhow::Result<BurnEvent> {
324 if let Some(parse_fn) = &self.parse_burn_event_hypersync_fn {
325 parse_fn(self.dex.clone(), log)
326 } else {
327 anyhow::bail!(
328 "HyperSync parsing of burn event is not defined in this dex: {}:{}",
329 self.dex.chain,
330 self.dex.name
331 )
332 }
333 }
334
335 pub fn parse_initialize_event_hypersync(
341 &self,
342 log: &HypersyncLog,
343 ) -> anyhow::Result<InitializeEvent> {
344 if let Some(parse_fn) = &self.parse_initialize_event_hypersync_fn {
345 parse_fn(self.dex.clone(), log)
346 } else {
347 anyhow::bail!(
348 "HyperSync parsing of initialize event is not defined in this dex: {}:{}",
349 self.dex.chain,
350 self.dex.name
351 )
352 }
353 }
354
355 pub fn parse_collect_event_hypersync(
361 &self,
362 log: &HypersyncLog,
363 ) -> anyhow::Result<CollectEvent> {
364 if let Some(parse_fn) = &self.parse_collect_event_hypersync_fn {
365 parse_fn(self.dex.clone(), log)
366 } else {
367 anyhow::bail!(
368 "HyperSync parsing of collect event is not defined in this dex: {}:{}",
369 self.dex.chain,
370 self.dex.name
371 )
372 }
373 }
374
375 pub fn parse_flash_event_hypersync(&self, log: &HypersyncLog) -> anyhow::Result<FlashEvent> {
381 if let Some(parse_fn) = &self.parse_flash_event_hypersync_fn {
382 parse_fn(self.dex.clone(), log)
383 } else {
384 anyhow::bail!(
385 "HyperSync parsing of flash event is not defined in this dex: {}:{}",
386 self.dex.chain,
387 self.dex.name
388 )
389 }
390 }
391
392 pub fn parse_fee_protocol_update_event_hypersync(
398 &self,
399 log: &HypersyncLog,
400 ) -> anyhow::Result<FeeProtocolUpdateEvent> {
401 if let Some(parse_fn) = &self.parse_fee_protocol_update_event_hypersync_fn {
402 parse_fn(self.dex.clone(), log)
403 } else {
404 anyhow::bail!(
405 "HyperSync parsing of SetFeeProtocol event is not defined in this dex: {}:{}",
406 self.dex.chain,
407 self.dex.name
408 )
409 }
410 }
411
412 pub fn parse_fee_protocol_collect_event_hypersync(
418 &self,
419 log: &HypersyncLog,
420 ) -> anyhow::Result<FeeProtocolCollectEvent> {
421 if let Some(parse_fn) = &self.parse_fee_protocol_collect_event_hypersync_fn {
422 parse_fn(self.dex.clone(), log)
423 } else {
424 anyhow::bail!(
425 "HyperSync parsing of CollectProtocol event is not defined in this dex: {}:{}",
426 self.dex.chain,
427 self.dex.name
428 )
429 }
430 }
431
432 pub fn parse_pool_created_event_rpc(&self, log: &RpcLog) -> anyhow::Result<PoolCreatedEvent> {
438 if let Some(parse_fn) = &self.parse_pool_created_event_rpc_fn {
439 parse_fn(log)
440 } else {
441 anyhow::bail!(
442 "RPC parsing of pool created event is not defined in this dex: {}:{}",
443 self.dex.chain,
444 self.dex.name,
445 )
446 }
447 }
448
449 pub fn parse_swap_event_rpc(&self, log: &RpcLog) -> anyhow::Result<SwapEvent> {
455 if let Some(parse_fn) = &self.parse_swap_event_rpc_fn {
456 parse_fn(self.dex.clone(), log)
457 } else {
458 anyhow::bail!(
459 "RPC parsing of swap event is not defined in this dex: {}:{}",
460 self.dex.chain,
461 self.dex.name
462 )
463 }
464 }
465
466 pub fn parse_mint_event_rpc(&self, log: &RpcLog) -> anyhow::Result<MintEvent> {
472 if let Some(parse_fn) = &self.parse_mint_event_rpc_fn {
473 parse_fn(self.dex.clone(), log)
474 } else {
475 anyhow::bail!(
476 "RPC parsing of mint event is not defined in this dex: {}:{}",
477 self.dex.chain,
478 self.dex.name
479 )
480 }
481 }
482
483 pub fn parse_burn_event_rpc(&self, log: &RpcLog) -> anyhow::Result<BurnEvent> {
489 if let Some(parse_fn) = &self.parse_burn_event_rpc_fn {
490 parse_fn(self.dex.clone(), log)
491 } else {
492 anyhow::bail!(
493 "RPC parsing of burn event is not defined in this dex: {}:{}",
494 self.dex.chain,
495 self.dex.name
496 )
497 }
498 }
499
500 pub fn parse_initialize_event_rpc(&self, log: &RpcLog) -> anyhow::Result<InitializeEvent> {
506 if let Some(parse_fn) = &self.parse_initialize_event_rpc_fn {
507 parse_fn(self.dex.clone(), log)
508 } else {
509 anyhow::bail!(
510 "RPC parsing of initialize event is not defined in this dex: {}:{}",
511 self.dex.chain,
512 self.dex.name
513 )
514 }
515 }
516
517 pub fn parse_collect_event_rpc(&self, log: &RpcLog) -> anyhow::Result<CollectEvent> {
523 if let Some(parse_fn) = &self.parse_collect_event_rpc_fn {
524 parse_fn(self.dex.clone(), log)
525 } else {
526 anyhow::bail!(
527 "RPC parsing of collect event is not defined in this dex: {}:{}",
528 self.dex.chain,
529 self.dex.name
530 )
531 }
532 }
533
534 pub fn parse_flash_event_rpc(&self, log: &RpcLog) -> anyhow::Result<FlashEvent> {
540 if let Some(parse_fn) = &self.parse_flash_event_rpc_fn {
541 parse_fn(self.dex.clone(), log)
542 } else {
543 anyhow::bail!(
544 "RPC parsing of flash event is not defined in this dex: {}:{}",
545 self.dex.chain,
546 self.dex.name
547 )
548 }
549 }
550
551 pub fn parse_fee_protocol_update_event_rpc(
557 &self,
558 log: &RpcLog,
559 ) -> anyhow::Result<FeeProtocolUpdateEvent> {
560 if let Some(parse_fn) = &self.parse_fee_protocol_update_event_rpc_fn {
561 parse_fn(self.dex.clone(), log)
562 } else {
563 anyhow::bail!(
564 "RPC parsing of SetFeeProtocol event is not defined in this dex: {}:{}",
565 self.dex.chain,
566 self.dex.name
567 )
568 }
569 }
570
571 pub fn parse_fee_protocol_collect_event_rpc(
577 &self,
578 log: &RpcLog,
579 ) -> anyhow::Result<FeeProtocolCollectEvent> {
580 if let Some(parse_fn) = &self.parse_fee_protocol_collect_event_rpc_fn {
581 parse_fn(self.dex.clone(), log)
582 } else {
583 anyhow::bail!(
584 "RPC parsing of CollectProtocol event is not defined in this dex: {}:{}",
585 self.dex.chain,
586 self.dex.name
587 )
588 }
589 }
590
591 #[must_use]
593 pub fn needs_initialization(&self) -> bool {
594 self.dex.initialize_event.is_some()
595 }
596
597 #[must_use]
602 pub fn supports_pool_discovery(&self) -> bool {
603 self.parse_pool_created_event_hypersync_fn.is_some()
604 }
605
606 #[must_use]
613 pub fn missing_pool_analysis_parsers(&self) -> Vec<PoolEventKind> {
614 [
615 (
616 PoolEventKind::Initialize,
617 self.parse_initialize_event_hypersync_fn.is_some(),
618 ),
619 (
620 PoolEventKind::Swap,
621 self.parse_swap_event_hypersync_fn.is_some(),
622 ),
623 (
624 PoolEventKind::Mint,
625 self.parse_mint_event_hypersync_fn.is_some(),
626 ),
627 (
628 PoolEventKind::Burn,
629 self.parse_burn_event_hypersync_fn.is_some(),
630 ),
631 (
632 PoolEventKind::Collect,
633 self.parse_collect_event_hypersync_fn.is_some(),
634 ),
635 ]
636 .into_iter()
637 .filter_map(|(kind, present)| (!present).then_some(kind))
638 .collect()
639 }
640
641 #[must_use]
647 pub fn supports_fee_protocol_replay(&self) -> bool {
648 self.missing_pool_analysis_parsers().is_empty()
649 && self.parse_fee_protocol_update_event_hypersync_fn.is_some()
650 }
651}
652
653impl Deref for DexExtended {
654 type Target = Dex;
655
656 fn deref(&self) -> &Self::Target {
657 &self.dex
658 }
659}