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