1use super::utils::*;
6use crate::core::events::*;
7use solana_sdk::signature::Signature;
8
9pub mod discriminators {
11 pub const SWAP_EVENT: [u8; 8] = [81, 108, 227, 190, 205, 208, 10, 196];
12 pub const SWAP2_EVENT: [u8; 8] = [46, 116, 82, 215, 148, 27, 84, 77];
13 pub const ADD_LIQUIDITY_EVENT: [u8; 8] = [31, 94, 125, 90, 227, 52, 61, 186];
14 pub const REMOVE_LIQUIDITY_EVENT: [u8; 8] = [116, 244, 97, 232, 103, 31, 152, 58];
15 pub const INITIALIZE_POOL_EVENT: [u8; 8] = [185, 74, 252, 125, 27, 215, 188, 111];
16 pub const CREATE_POSITION_EVENT: [u8; 8] = [144, 142, 252, 84, 157, 53, 37, 121];
17 pub const CLOSE_POSITION_EVENT: [u8; 8] = [255, 196, 16, 107, 28, 202, 53, 128];
18 pub const CLAIM_FEE_EVENT: [u8; 8] = [75, 122, 154, 48, 140, 74, 123, 163];
19 pub const CLAIM_FEE2_EVENT: [u8; 8] = [232, 171, 242, 97, 58, 77, 35, 45];
20
21 pub const LEGACY_SWAP_EVENT: [u8; 8] = [143, 190, 90, 218, 196, 30, 51, 222];
22 pub const LEGACY_ADD_LIQUIDITY_EVENT: [u8; 8] = [181, 157, 89, 67, 143, 182, 52, 72];
23 pub const LEGACY_REMOVE_LIQUIDITY_EVENT: [u8; 8] = [80, 85, 209, 72, 24, 206, 35, 178];
24 pub const LEGACY_INITIALIZE_BIN_ARRAY_EVENT: [u8; 8] = [11, 18, 155, 194, 33, 115, 238, 119];
25 pub const LEGACY_INITIALIZE_POOL_EVENT: [u8; 8] = [95, 180, 10, 172, 84, 174, 232, 40];
26 pub const LEGACY_CREATE_POSITION_EVENT: [u8; 8] = [123, 233, 11, 43, 146, 180, 97, 119];
27 pub const LEGACY_CLOSE_POSITION_EVENT: [u8; 8] = [94, 168, 102, 45, 59, 122, 137, 54];
28 pub const LEGACY_CLAIM_FEE_EVENT: [u8; 8] = [152, 70, 208, 111, 104, 91, 44, 1];
29}
30
31pub fn parse_log(
33 log: &str,
34 signature: Signature,
35 slot: u64,
36 tx_index: u64,
37 block_time_us: Option<i64>,
38 grpc_recv_us: i64,
39) -> Option<DexEvent> {
40 parse_structured_log(log, signature, slot, tx_index, block_time_us, grpc_recv_us)
41}
42
43fn parse_structured_log(
45 log: &str,
46 signature: Signature,
47 slot: u64,
48 tx_index: u64,
49 block_time_us: Option<i64>,
50 grpc_recv_us: i64,
51) -> Option<DexEvent> {
52 let program_data = extract_program_data(log)?;
53 if program_data.len() < 8 {
54 return None;
55 }
56
57 let discriminator: [u8; 8] = program_data[0..8].try_into().ok()?;
58 let data = &program_data[8..];
59
60 match discriminator {
61 discriminators::SWAP_EVENT | discriminators::LEGACY_SWAP_EVENT => {
62 parse_swap_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
63 }
64 discriminators::SWAP2_EVENT => {
65 parse_swap2_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
66 }
67 discriminators::ADD_LIQUIDITY_EVENT | discriminators::LEGACY_ADD_LIQUIDITY_EVENT => {
68 parse_add_liquidity_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
69 }
70 discriminators::REMOVE_LIQUIDITY_EVENT | discriminators::LEGACY_REMOVE_LIQUIDITY_EVENT => {
71 parse_remove_liquidity_event(
72 data,
73 signature,
74 slot,
75 tx_index,
76 block_time_us,
77 grpc_recv_us,
78 )
79 }
80 discriminators::LEGACY_INITIALIZE_BIN_ARRAY_EVENT => parse_initialize_bin_array_event(
81 data,
82 signature,
83 slot,
84 tx_index,
85 block_time_us,
86 grpc_recv_us,
87 ),
88 discriminators::INITIALIZE_POOL_EVENT => {
89 parse_lb_pair_create_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
90 }
91 discriminators::LEGACY_INITIALIZE_POOL_EVENT => parse_initialize_pool_event(
92 data,
93 signature,
94 slot,
95 tx_index,
96 block_time_us,
97 grpc_recv_us,
98 ),
99 discriminators::CREATE_POSITION_EVENT => parse_position_create_event(
100 data,
101 signature,
102 slot,
103 tx_index,
104 block_time_us,
105 grpc_recv_us,
106 ),
107 discriminators::LEGACY_CREATE_POSITION_EVENT => parse_create_position_event(
108 data,
109 signature,
110 slot,
111 tx_index,
112 block_time_us,
113 grpc_recv_us,
114 ),
115 discriminators::CLOSE_POSITION_EVENT => {
116 parse_position_close_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
117 }
118 discriminators::LEGACY_CLOSE_POSITION_EVENT => {
119 parse_close_position_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
120 }
121 discriminators::CLAIM_FEE_EVENT | discriminators::LEGACY_CLAIM_FEE_EVENT => {
122 parse_claim_fee_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
123 }
124 discriminators::CLAIM_FEE2_EVENT => {
125 parse_claim_fee2_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
126 }
127 _ => None,
128 }
129}
130
131#[inline(always)]
136pub fn parse_swap_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
137 let mut offset = 0;
138
139 let pool = read_pubkey(data, offset)?;
140 offset += 32;
141
142 let from = read_pubkey(data, offset)?;
143 offset += 32;
144
145 let start_bin_id = read_i32_le(data, offset)?;
146 offset += 4;
147
148 let end_bin_id = read_i32_le(data, offset)?;
149 offset += 4;
150
151 let amount_in = read_u64_le(data, offset)?;
152 offset += 8;
153
154 let amount_out = read_u64_le(data, offset)?;
155 offset += 8;
156
157 let swap_for_y = read_bool(data, offset)?;
158 offset += 1;
159
160 let fee = read_u64_le(data, offset)?;
161 offset += 8;
162
163 let protocol_fee = read_u64_le(data, offset)?;
164 offset += 8;
165
166 let fee_bps = read_u128_le(data, offset)?;
167 offset += 16;
168
169 let host_fee = read_u64_le(data, offset)?;
170
171 Some(DexEvent::MeteoraDlmmSwap(MeteoraDlmmSwapEvent {
172 metadata,
173 token_x_mint: solana_sdk::pubkey::Pubkey::default(),
174 token_y_mint: solana_sdk::pubkey::Pubkey::default(),
175 pool,
176 from,
177 start_bin_id,
178 end_bin_id,
179 amount_in,
180 amount_out,
181 swap_for_y,
182 fee,
183 protocol_fee,
184 fee_bps,
185 host_fee,
186 }))
187}
188
189#[inline(always)]
190pub fn parse_swap2_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
191 if data.len() < 147 {
192 return None;
193 }
194 let mut offset = 0;
195
196 let pool = read_pubkey(data, offset)?;
197 offset += 32;
198
199 let from = read_pubkey(data, offset)?;
200 offset += 32;
201
202 let start_bin_id = read_i32_le(data, offset)?;
203 offset += 4;
204
205 let end_bin_id = read_i32_le(data, offset)?;
206 offset += 4;
207
208 let swap_for_y = read_bool(data, offset)?;
209 offset += 1;
210
211 let fee_bps = read_u128_le(data, offset)?;
212 offset += 16;
213
214 let amount_in = read_u64_le(data, offset)?;
215 offset += 8;
216
217 let _amount_left = read_u64_le(data, offset)?;
218 offset += 8;
219
220 let amount_out = read_u64_le(data, offset)?;
221 offset += 8;
222
223 let fee = read_u64_le(data, offset)?;
224 offset += 8;
225
226 let protocol_fee = read_u64_le(data, offset)?;
227 offset += 8;
228
229 let _limit_order_fee = read_u64_le(data, offset)?;
230 offset += 8;
231
232 let host_fee = read_u64_le(data, offset)?;
233
234 Some(DexEvent::MeteoraDlmmSwap(MeteoraDlmmSwapEvent {
235 metadata,
236 token_x_mint: solana_sdk::pubkey::Pubkey::default(),
237 token_y_mint: solana_sdk::pubkey::Pubkey::default(),
238 pool,
239 from,
240 start_bin_id,
241 end_bin_id,
242 amount_in,
243 amount_out,
244 swap_for_y,
245 fee,
246 protocol_fee,
247 fee_bps,
248 host_fee,
249 }))
250}
251
252#[inline(always)]
253pub fn parse_add_liquidity_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
254 let mut offset = 0;
255
256 let pool = read_pubkey(data, offset)?;
257 offset += 32;
258
259 let from = read_pubkey(data, offset)?;
260 offset += 32;
261
262 let position = read_pubkey(data, offset)?;
263 offset += 32;
264
265 let amount_0 = read_u64_le(data, offset)?;
266 offset += 8;
267
268 let amount_1 = read_u64_le(data, offset)?;
269 offset += 8;
270
271 let active_bin_id = read_i32_le(data, offset)?;
272
273 Some(DexEvent::MeteoraDlmmAddLiquidity(MeteoraDlmmAddLiquidityEvent {
274 metadata,
275 pool,
276 from,
277 position,
278 amounts: [amount_0, amount_1],
279 active_bin_id,
280 }))
281}
282
283#[inline(always)]
284pub fn parse_remove_liquidity_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
285 let mut offset = 0;
286
287 let pool = read_pubkey(data, offset)?;
288 offset += 32;
289
290 let from = read_pubkey(data, offset)?;
291 offset += 32;
292
293 let position = read_pubkey(data, offset)?;
294 offset += 32;
295
296 let amount_0 = read_u64_le(data, offset)?;
297 offset += 8;
298
299 let amount_1 = read_u64_le(data, offset)?;
300 offset += 8;
301
302 let active_bin_id = read_i32_le(data, offset)?;
303
304 Some(DexEvent::MeteoraDlmmRemoveLiquidity(MeteoraDlmmRemoveLiquidityEvent {
305 metadata,
306 pool,
307 from,
308 position,
309 amounts: [amount_0, amount_1],
310 active_bin_id,
311 }))
312}
313
314#[inline(always)]
315pub fn parse_initialize_pool_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
316 let mut offset = 0;
317
318 let pool = read_pubkey(data, offset)?;
319 offset += 32;
320
321 let creator = read_pubkey(data, offset)?;
322 offset += 32;
323
324 let active_bin_id = read_i32_le(data, offset)?;
325 offset += 4;
326
327 let bin_step = read_u16_le(data, offset)?;
328
329 Some(DexEvent::MeteoraDlmmInitializePool(MeteoraDlmmInitializePoolEvent {
330 metadata,
331 pool,
332 creator,
333 active_bin_id,
334 bin_step,
335 }))
336}
337
338#[inline(always)]
339pub fn parse_initialize_bin_array_from_data(
340 data: &[u8],
341 metadata: EventMetadata,
342) -> Option<DexEvent> {
343 let mut offset = 0;
344
345 let pool = read_pubkey(data, offset)?;
346 offset += 32;
347
348 let bin_array = read_pubkey(data, offset)?;
349 offset += 32;
350
351 let index = read_i64_le(data, offset)?;
352
353 Some(DexEvent::MeteoraDlmmInitializeBinArray(MeteoraDlmmInitializeBinArrayEvent {
354 metadata,
355 pool,
356 bin_array,
357 index,
358 }))
359}
360
361#[inline(always)]
362pub fn parse_create_position_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
363 let mut offset = 0;
364
365 let pool = read_pubkey(data, offset)?;
366 offset += 32;
367
368 let position = read_pubkey(data, offset)?;
369 offset += 32;
370
371 let owner = read_pubkey(data, offset)?;
372 offset += 32;
373
374 let lower_bin_id = read_i32_le(data, offset)?;
375 offset += 4;
376
377 let width = read_u32_le(data, offset)?;
378
379 Some(DexEvent::MeteoraDlmmCreatePosition(MeteoraDlmmCreatePositionEvent {
380 metadata,
381 pool,
382 position,
383 owner,
384 lower_bin_id,
385 width,
386 }))
387}
388
389#[inline(always)]
390pub fn parse_close_position_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
391 let mut offset = 0;
392
393 let pool = read_pubkey(data, offset)?;
394 offset += 32;
395
396 let position = read_pubkey(data, offset)?;
397 offset += 32;
398
399 let owner = read_pubkey(data, offset)?;
400
401 Some(DexEvent::MeteoraDlmmClosePosition(MeteoraDlmmClosePositionEvent {
402 metadata,
403 pool,
404 position,
405 owner,
406 }))
407}
408
409#[inline(always)]
410pub fn parse_claim_fee_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
411 let mut offset = 0;
412
413 let pool = read_pubkey(data, offset)?;
414 offset += 32;
415
416 let position = read_pubkey(data, offset)?;
417 offset += 32;
418
419 let owner = read_pubkey(data, offset)?;
420 offset += 32;
421
422 let fee_x = read_u64_le(data, offset)?;
423 offset += 8;
424
425 let fee_y = read_u64_le(data, offset)?;
426
427 Some(DexEvent::MeteoraDlmmClaimFee(MeteoraDlmmClaimFeeEvent {
428 metadata,
429 pool,
430 position,
431 owner,
432 fee_x,
433 fee_y,
434 }))
435}
436
437#[inline(always)]
438pub fn parse_claim_fee2_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
439 if data.len() < 116 {
440 return None;
441 }
442 parse_claim_fee_from_data(data, metadata)
443}
444
445#[inline(always)]
446pub fn parse_lb_pair_create_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
447 let mut offset = 0;
448
449 let pool = read_pubkey(data, offset)?;
450 offset += 32;
451
452 let bin_step = read_u16_le(data, offset)?;
453
454 Some(DexEvent::MeteoraDlmmInitializePool(MeteoraDlmmInitializePoolEvent {
455 metadata,
456 pool,
457 creator: Default::default(),
458 active_bin_id: 0,
459 bin_step,
460 }))
461}
462
463#[inline(always)]
464pub fn parse_position_create_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
465 let mut offset = 0;
466
467 let pool = read_pubkey(data, offset)?;
468 offset += 32;
469
470 let position = read_pubkey(data, offset)?;
471 offset += 32;
472
473 let owner = read_pubkey(data, offset)?;
474
475 Some(DexEvent::MeteoraDlmmCreatePosition(MeteoraDlmmCreatePositionEvent {
476 metadata,
477 pool,
478 position,
479 owner,
480 lower_bin_id: 0,
481 width: 0,
482 }))
483}
484
485#[inline(always)]
486pub fn parse_position_close_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
487 let mut offset = 0;
488
489 let position = read_pubkey(data, offset)?;
490 offset += 32;
491
492 let owner = read_pubkey(data, offset)?;
493
494 Some(DexEvent::MeteoraDlmmClosePosition(MeteoraDlmmClosePositionEvent {
495 metadata,
496 pool: Default::default(),
497 position,
498 owner,
499 }))
500}
501
502fn parse_swap_event(
504 data: &[u8],
505 signature: Signature,
506 slot: u64,
507 tx_index: u64,
508 block_time_us: Option<i64>,
509 grpc_recv_us: i64,
510) -> Option<DexEvent> {
511 let mut offset = 0;
512
513 let pool = read_pubkey(data, offset)?;
514 offset += 32;
515
516 let from = read_pubkey(data, offset)?;
517 offset += 32;
518
519 let start_bin_id = read_i32_le(data, offset)?;
520 offset += 4;
521
522 let end_bin_id = read_i32_le(data, offset)?;
523 offset += 4;
524
525 let amount_in = read_u64_le(data, offset)?;
526 offset += 8;
527
528 let amount_out = read_u64_le(data, offset)?;
529 offset += 8;
530
531 let swap_for_y = read_bool(data, offset)?;
532 offset += 1;
533
534 let fee = read_u64_le(data, offset)?;
535 offset += 8;
536
537 let protocol_fee = read_u64_le(data, offset)?;
538 offset += 8;
539
540 let fee_bps = read_u128_le(data, offset)?;
541 offset += 16;
542
543 let host_fee = read_u64_le(data, offset)?;
544
545 let metadata =
546 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
547
548 Some(DexEvent::MeteoraDlmmSwap(MeteoraDlmmSwapEvent {
549 metadata,
550 token_x_mint: solana_sdk::pubkey::Pubkey::default(),
551 token_y_mint: solana_sdk::pubkey::Pubkey::default(),
552 pool,
553 from,
554 start_bin_id,
555 end_bin_id,
556 amount_in,
557 amount_out,
558 swap_for_y,
559 fee,
560 protocol_fee,
561 fee_bps,
562 host_fee,
563 }))
564}
565
566fn parse_swap2_event(
567 data: &[u8],
568 signature: Signature,
569 slot: u64,
570 tx_index: u64,
571 block_time_us: Option<i64>,
572 grpc_recv_us: i64,
573) -> Option<DexEvent> {
574 let metadata = create_metadata_simple(
575 signature,
576 slot,
577 tx_index,
578 block_time_us,
579 Default::default(),
580 grpc_recv_us,
581 );
582 parse_swap2_from_data(data, metadata)
583}
584
585fn parse_add_liquidity_event(
587 data: &[u8],
588 signature: Signature,
589 slot: u64,
590 tx_index: u64,
591 block_time_us: Option<i64>,
592 grpc_recv_us: i64,
593) -> Option<DexEvent> {
594 let mut offset = 0;
595
596 let pool = read_pubkey(data, offset)?;
597 offset += 32;
598
599 let from = read_pubkey(data, offset)?;
600 offset += 32;
601
602 let position = read_pubkey(data, offset)?;
603 offset += 32;
604
605 let amount_0 = read_u64_le(data, offset)?;
606 offset += 8;
607
608 let amount_1 = read_u64_le(data, offset)?;
609 offset += 8;
610
611 let active_bin_id = read_i32_le(data, offset)?;
612
613 let metadata =
614 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
615
616 Some(DexEvent::MeteoraDlmmAddLiquidity(MeteoraDlmmAddLiquidityEvent {
617 metadata,
618 pool,
619 from,
620 position,
621 amounts: [amount_0, amount_1],
622 active_bin_id,
623 }))
624}
625
626fn parse_remove_liquidity_event(
628 data: &[u8],
629 signature: Signature,
630 slot: u64,
631 tx_index: u64,
632 block_time_us: Option<i64>,
633 grpc_recv_us: i64,
634) -> Option<DexEvent> {
635 let mut offset = 0;
636
637 let pool = read_pubkey(data, offset)?;
638 offset += 32;
639
640 let from = read_pubkey(data, offset)?;
641 offset += 32;
642
643 let position = read_pubkey(data, offset)?;
644 offset += 32;
645
646 let amount_0 = read_u64_le(data, offset)?;
647 offset += 8;
648
649 let amount_1 = read_u64_le(data, offset)?;
650 offset += 8;
651
652 let active_bin_id = read_i32_le(data, offset)?;
653
654 let metadata =
655 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
656
657 Some(DexEvent::MeteoraDlmmRemoveLiquidity(MeteoraDlmmRemoveLiquidityEvent {
658 metadata,
659 pool,
660 from,
661 position,
662 amounts: [amount_0, amount_1],
663 active_bin_id,
664 }))
665}
666
667fn parse_initialize_pool_event(
669 data: &[u8],
670 signature: Signature,
671 slot: u64,
672 tx_index: u64,
673 block_time_us: Option<i64>,
674 grpc_recv_us: i64,
675) -> Option<DexEvent> {
676 let mut offset = 0;
677
678 let pool = read_pubkey(data, offset)?;
679 offset += 32;
680
681 let creator = read_pubkey(data, offset)?;
682 offset += 32;
683
684 let active_bin_id = read_i32_le(data, offset)?;
685 offset += 4;
686
687 let bin_step = read_u16_le(data, offset)?;
688
689 let metadata =
690 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
691
692 Some(DexEvent::MeteoraDlmmInitializePool(MeteoraDlmmInitializePoolEvent {
693 metadata,
694 pool,
695 creator,
696 active_bin_id,
697 bin_step,
698 }))
699}
700
701fn parse_initialize_bin_array_event(
703 data: &[u8],
704 signature: Signature,
705 slot: u64,
706 tx_index: u64,
707 block_time_us: Option<i64>,
708 grpc_recv_us: i64,
709) -> Option<DexEvent> {
710 let mut offset = 0;
711
712 let pool = read_pubkey(data, offset)?;
713 offset += 32;
714
715 let bin_array = read_pubkey(data, offset)?;
716 offset += 32;
717
718 let index = read_i64_le(data, offset)?;
719
720 let metadata =
721 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
722
723 Some(DexEvent::MeteoraDlmmInitializeBinArray(MeteoraDlmmInitializeBinArrayEvent {
724 metadata,
725 pool,
726 bin_array,
727 index,
728 }))
729}
730
731fn parse_create_position_event(
733 data: &[u8],
734 signature: Signature,
735 slot: u64,
736 tx_index: u64,
737 block_time_us: Option<i64>,
738 grpc_recv_us: i64,
739) -> Option<DexEvent> {
740 let mut offset = 0;
741
742 let pool = read_pubkey(data, offset)?;
743 offset += 32;
744
745 let position = read_pubkey(data, offset)?;
746 offset += 32;
747
748 let owner = read_pubkey(data, offset)?;
749 offset += 32;
750
751 let lower_bin_id = read_i32_le(data, offset)?;
752 offset += 4;
753
754 let width = read_u32_le(data, offset)?;
755
756 let metadata =
757 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
758
759 Some(DexEvent::MeteoraDlmmCreatePosition(MeteoraDlmmCreatePositionEvent {
760 metadata,
761 pool,
762 position,
763 owner,
764 lower_bin_id,
765 width,
766 }))
767}
768
769fn parse_close_position_event(
771 data: &[u8],
772 signature: Signature,
773 slot: u64,
774 tx_index: u64,
775 block_time_us: Option<i64>,
776 grpc_recv_us: i64,
777) -> Option<DexEvent> {
778 let mut offset = 0;
779
780 let pool = read_pubkey(data, offset)?;
781 offset += 32;
782
783 let position = read_pubkey(data, offset)?;
784 offset += 32;
785
786 let owner = read_pubkey(data, offset)?;
787
788 let metadata =
789 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
790
791 Some(DexEvent::MeteoraDlmmClosePosition(MeteoraDlmmClosePositionEvent {
792 metadata,
793 pool,
794 position,
795 owner,
796 }))
797}
798
799fn parse_claim_fee_event(
801 data: &[u8],
802 signature: Signature,
803 slot: u64,
804 tx_index: u64,
805 block_time_us: Option<i64>,
806 grpc_recv_us: i64,
807) -> Option<DexEvent> {
808 let mut offset = 0;
809
810 let pool = read_pubkey(data, offset)?;
811 offset += 32;
812
813 let position = read_pubkey(data, offset)?;
814 offset += 32;
815
816 let owner = read_pubkey(data, offset)?;
817 offset += 32;
818
819 let fee_x = read_u64_le(data, offset)?;
820 offset += 8;
821
822 let fee_y = read_u64_le(data, offset)?;
823
824 let metadata =
825 create_metadata_simple(signature, slot, tx_index, block_time_us, pool, grpc_recv_us);
826
827 Some(DexEvent::MeteoraDlmmClaimFee(MeteoraDlmmClaimFeeEvent {
828 metadata,
829 pool,
830 position,
831 owner,
832 fee_x,
833 fee_y,
834 }))
835}
836
837fn parse_claim_fee2_event(
838 data: &[u8],
839 signature: Signature,
840 slot: u64,
841 tx_index: u64,
842 block_time_us: Option<i64>,
843 grpc_recv_us: i64,
844) -> Option<DexEvent> {
845 let metadata = create_metadata_simple(
846 signature,
847 slot,
848 tx_index,
849 block_time_us,
850 Default::default(),
851 grpc_recv_us,
852 );
853 parse_claim_fee2_from_data(data, metadata)
854}
855
856fn parse_lb_pair_create_event(
857 data: &[u8],
858 signature: Signature,
859 slot: u64,
860 tx_index: u64,
861 block_time_us: Option<i64>,
862 grpc_recv_us: i64,
863) -> Option<DexEvent> {
864 let metadata = create_metadata_simple(
865 signature,
866 slot,
867 tx_index,
868 block_time_us,
869 Default::default(),
870 grpc_recv_us,
871 );
872 parse_lb_pair_create_from_data(data, metadata)
873}
874
875fn parse_position_create_event(
876 data: &[u8],
877 signature: Signature,
878 slot: u64,
879 tx_index: u64,
880 block_time_us: Option<i64>,
881 grpc_recv_us: i64,
882) -> Option<DexEvent> {
883 let metadata = create_metadata_simple(
884 signature,
885 slot,
886 tx_index,
887 block_time_us,
888 Default::default(),
889 grpc_recv_us,
890 );
891 parse_position_create_from_data(data, metadata)
892}
893
894fn parse_position_close_event(
895 data: &[u8],
896 signature: Signature,
897 slot: u64,
898 tx_index: u64,
899 block_time_us: Option<i64>,
900 grpc_recv_us: i64,
901) -> Option<DexEvent> {
902 let metadata = create_metadata_simple(
903 signature,
904 slot,
905 tx_index,
906 block_time_us,
907 Default::default(),
908 grpc_recv_us,
909 );
910 parse_position_close_from_data(data, metadata)
911}
912
913fn parse_text_log(
915 log: &str,
916 signature: Signature,
917 slot: u64,
918 tx_index: u64,
919 block_time_us: Option<i64>,
920 grpc_recv_us: i64,
921) -> Option<DexEvent> {
922 use super::utils::text_parser::*;
923
924 if log.contains("swap") || log.contains("Swap") {
925 return parse_swap_from_text(log, signature, slot, tx_index, block_time_us, grpc_recv_us);
926 }
927
928 if log.contains("add") && log.contains("liquidity") {
929 return parse_add_liquidity_from_text(
930 log,
931 signature,
932 slot,
933 tx_index,
934 block_time_us,
935 grpc_recv_us,
936 );
937 }
938
939 if log.contains("remove") && log.contains("liquidity") {
940 return parse_remove_liquidity_from_text(
941 log,
942 signature,
943 slot,
944 tx_index,
945 block_time_us,
946 grpc_recv_us,
947 );
948 }
949
950 if log.contains("initialize") && log.contains("pool") {
951 return parse_initialize_pool_from_text(
952 log,
953 signature,
954 slot,
955 tx_index,
956 block_time_us,
957 grpc_recv_us,
958 );
959 }
960
961 None
962}
963
964fn parse_swap_from_text(
966 log: &str,
967 signature: Signature,
968 slot: u64,
969 tx_index: u64,
970 block_time_us: Option<i64>,
971 grpc_recv_us: i64,
972) -> Option<DexEvent> {
973 use super::utils::text_parser::*;
974
975 let metadata = create_metadata_simple(
976 signature,
977 slot,
978 tx_index,
979 block_time_us,
980 solana_sdk::pubkey::Pubkey::default(),
981 grpc_recv_us,
982 );
983
984 Some(DexEvent::MeteoraDlmmSwap(MeteoraDlmmSwapEvent {
985 metadata,
986 token_x_mint: solana_sdk::pubkey::Pubkey::default(),
987 token_y_mint: solana_sdk::pubkey::Pubkey::default(),
988 pool: solana_sdk::pubkey::Pubkey::default(),
989 from: solana_sdk::pubkey::Pubkey::default(),
990 start_bin_id: 0,
991 end_bin_id: 0,
992 amount_in: extract_number_from_text(log, "amount_in").unwrap_or(1_000_000),
993 amount_out: extract_number_from_text(log, "amount_out").unwrap_or(950_000),
994 swap_for_y: detect_trade_type(log).unwrap_or(true),
995 fee: extract_number_from_text(log, "fee").unwrap_or(3000),
996 protocol_fee: 0,
997 fee_bps: 0,
998 host_fee: 0,
999 }))
1000}
1001
1002fn parse_add_liquidity_from_text(
1004 log: &str,
1005 signature: Signature,
1006 slot: u64,
1007 tx_index: u64,
1008 block_time_us: Option<i64>,
1009 grpc_recv_us: i64,
1010) -> Option<DexEvent> {
1011 use super::utils::text_parser::*;
1012
1013 let metadata = create_metadata_simple(
1014 signature,
1015 slot,
1016 tx_index,
1017 block_time_us,
1018 solana_sdk::pubkey::Pubkey::default(),
1019 grpc_recv_us,
1020 );
1021
1022 Some(DexEvent::MeteoraDlmmAddLiquidity(MeteoraDlmmAddLiquidityEvent {
1023 metadata,
1024 pool: solana_sdk::pubkey::Pubkey::default(),
1025 from: solana_sdk::pubkey::Pubkey::default(),
1026 position: solana_sdk::pubkey::Pubkey::default(),
1027 amounts: [
1028 extract_number_from_text(log, "amount_x").unwrap_or(500_000),
1029 extract_number_from_text(log, "amount_y").unwrap_or(500_000),
1030 ],
1031 active_bin_id: 0,
1032 }))
1033}
1034
1035fn parse_remove_liquidity_from_text(
1037 log: &str,
1038 signature: Signature,
1039 slot: u64,
1040 tx_index: u64,
1041 block_time_us: Option<i64>,
1042 grpc_recv_us: i64,
1043) -> Option<DexEvent> {
1044 use super::utils::text_parser::*;
1045
1046 let metadata = create_metadata_simple(
1047 signature,
1048 slot,
1049 tx_index,
1050 block_time_us,
1051 solana_sdk::pubkey::Pubkey::default(),
1052 grpc_recv_us,
1053 );
1054
1055 Some(DexEvent::MeteoraDlmmRemoveLiquidity(MeteoraDlmmRemoveLiquidityEvent {
1056 metadata,
1057 pool: solana_sdk::pubkey::Pubkey::default(),
1058 from: solana_sdk::pubkey::Pubkey::default(),
1059 position: solana_sdk::pubkey::Pubkey::default(),
1060 amounts: [
1061 extract_number_from_text(log, "amount_x").unwrap_or(500_000),
1062 extract_number_from_text(log, "amount_y").unwrap_or(500_000),
1063 ],
1064 active_bin_id: 0,
1065 }))
1066}
1067
1068fn parse_initialize_pool_from_text(
1070 log: &str,
1071 signature: Signature,
1072 slot: u64,
1073 tx_index: u64,
1074 block_time_us: Option<i64>,
1075 grpc_recv_us: i64,
1076) -> Option<DexEvent> {
1077 use super::utils::text_parser::*;
1078
1079 let metadata = create_metadata_simple(
1080 signature,
1081 slot,
1082 tx_index,
1083 block_time_us,
1084 solana_sdk::pubkey::Pubkey::default(),
1085 grpc_recv_us,
1086 );
1087
1088 Some(DexEvent::MeteoraDlmmInitializePool(MeteoraDlmmInitializePoolEvent {
1089 metadata,
1090 pool: solana_sdk::pubkey::Pubkey::default(),
1091 creator: solana_sdk::pubkey::Pubkey::default(),
1092 active_bin_id: extract_number_from_text(log, "bin_id").unwrap_or(0) as i32,
1093 bin_step: extract_number_from_text(log, "bin_step").unwrap_or(1) as u16,
1094 }))
1095}