1#![allow(unused_imports)]
5use crate::core::events::*;
21use crate::instr::inner_common::*;
22
23pub mod raydium_cpmm {
28 use super::*;
29
30 pub mod discriminators {
31 pub const SWAP_BASE_IN: [u8; 16] = [143, 190, 90, 218, 196, 30, 51, 222, 155, 167, 108, 32, 122, 76, 173, 64];
32 pub const SWAP_BASE_OUT: [u8; 16] = [55, 217, 98, 86, 163, 74, 180, 173, 155, 167, 108, 32, 122, 76, 173, 64];
33 pub const CREATE_POOL: [u8; 16] = [233, 146, 209, 142, 207, 104, 64, 188, 155, 167, 108, 32, 122, 76, 173, 64];
34 pub const DEPOSIT: [u8; 16] = [242, 35, 198, 137, 82, 225, 242, 182, 155, 167, 108, 32, 122, 76, 173, 64];
35 pub const WITHDRAW: [u8; 16] = [183, 18, 70, 156, 148, 109, 161, 34, 155, 167, 108, 32, 122, 76, 173, 64];
36 }
37
38 #[inline]
40 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
41 match disc {
42 &discriminators::SWAP_BASE_IN | &discriminators::SWAP_BASE_OUT => parse_swap(data, metadata),
43 &discriminators::DEPOSIT => parse_deposit(data, metadata),
44 &discriminators::WITHDRAW => parse_withdraw(data, metadata),
45 _ => None,
46 }
47 }
48
49 #[inline(always)]
55 fn parse_swap(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
56 #[cfg(feature = "parse-borsh")]
57 {
58 parse_swap_borsh(data, metadata)
59 }
60
61 #[cfg(feature = "parse-zero-copy")]
62 {
63 parse_swap_zero_copy(data, metadata)
64 }
65 }
66
67 #[cfg(feature = "parse-borsh")]
69 #[inline(always)]
70 fn parse_swap_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
71 const EVENT_SIZE: usize = 32 + 8 + 8;
77
78 if data.len() < EVENT_SIZE {
79 return None;
80 }
81
82 let event = borsh::from_slice::<RaydiumCpmmSwapEvent>(&data[..EVENT_SIZE]).ok()?;
83
84 Some(DexEvent::RaydiumCpmmSwap(RaydiumCpmmSwapEvent {
85 metadata,
86 ..event
87 }))
88 }
89
90 #[cfg(feature = "parse-zero-copy")]
92 #[inline(always)]
93 fn parse_swap_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
94 unsafe {
95 if !check_length(data, 32 + 8 + 8) {
96 return None;
97 }
98 let pool = read_pubkey_unchecked(data, 0);
99 let input_amount = read_u64_unchecked(data, 32);
100 let output_amount = read_u64_unchecked(data, 40);
101 Some(DexEvent::RaydiumCpmmSwap(RaydiumCpmmSwapEvent {
102 metadata,
103 pool_id: pool,
104 input_amount,
105 output_amount,
106 input_vault_before: 0,
107 output_vault_before: 0,
108 input_transfer_fee: 0,
109 output_transfer_fee: 0,
110 base_input: true,
111 }))
112 }
113 }
114
115 #[inline(always)]
121 fn parse_deposit(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
122 #[cfg(feature = "parse-borsh")]
123 {
124 parse_deposit_borsh(data, metadata)
125 }
126
127 #[cfg(feature = "parse-zero-copy")]
128 {
129 parse_deposit_zero_copy(data, metadata)
130 }
131 }
132
133 #[cfg(feature = "parse-borsh")]
135 #[inline(always)]
136 fn parse_deposit_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
137 const EVENT_SIZE: usize = 32 + 8 + 8 + 8;
144
145 if data.len() < EVENT_SIZE {
146 return None;
147 }
148
149 let event = borsh::from_slice::<RaydiumCpmmDepositEvent>(&data[..EVENT_SIZE]).ok()?;
150
151 Some(DexEvent::RaydiumCpmmDeposit(RaydiumCpmmDepositEvent {
152 metadata,
153 ..event
154 }))
155 }
156
157 #[cfg(feature = "parse-zero-copy")]
159 #[inline(always)]
160 fn parse_deposit_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
161 unsafe {
162 if !check_length(data, 32 + 8 + 8 + 8) {
163 return None;
164 }
165 let pool = read_pubkey_unchecked(data, 0);
166 let token0_amount = read_u64_unchecked(data, 32);
167 let token1_amount = read_u64_unchecked(data, 40);
168 let lp_token_amount = read_u64_unchecked(data, 48);
169 Some(DexEvent::RaydiumCpmmDeposit(RaydiumCpmmDepositEvent {
170 metadata,
171 pool,
172 lp_token_amount,
173 token0_amount,
174 token1_amount,
175 user: Pubkey::default(),
176 }))
177 }
178 }
179
180 #[inline(always)]
186 fn parse_withdraw(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
187 #[cfg(feature = "parse-borsh")]
188 {
189 parse_withdraw_borsh(data, metadata)
190 }
191
192 #[cfg(feature = "parse-zero-copy")]
193 {
194 parse_withdraw_zero_copy(data, metadata)
195 }
196 }
197
198 #[cfg(feature = "parse-borsh")]
200 #[inline(always)]
201 fn parse_withdraw_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
202 const EVENT_SIZE: usize = 32 + 8 + 8 + 8;
209
210 if data.len() < EVENT_SIZE {
211 return None;
212 }
213
214 let event = borsh::from_slice::<RaydiumCpmmWithdrawEvent>(&data[..EVENT_SIZE]).ok()?;
215
216 Some(DexEvent::RaydiumCpmmWithdraw(RaydiumCpmmWithdrawEvent {
217 metadata,
218 ..event
219 }))
220 }
221
222 #[cfg(feature = "parse-zero-copy")]
224 #[inline(always)]
225 fn parse_withdraw_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
226 unsafe {
227 if !check_length(data, 32 + 8 + 8 + 8) {
228 return None;
229 }
230 let pool = read_pubkey_unchecked(data, 0);
231 let lp_token_amount = read_u64_unchecked(data, 32);
232 let token0_amount = read_u64_unchecked(data, 40);
233 let token1_amount = read_u64_unchecked(data, 48);
234 Some(DexEvent::RaydiumCpmmWithdraw(RaydiumCpmmWithdrawEvent {
235 metadata,
236 pool,
237 lp_token_amount,
238 token0_amount,
239 token1_amount,
240 user: Pubkey::default(),
241 }))
242 }
243 }
244}
245
246pub mod raydium_amm {
251 use super::*;
252
253 pub mod discriminators {
254 pub const SWAP_BASE_IN: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 9, 155, 167, 108, 32, 122, 76, 173, 64];
255 pub const SWAP_BASE_OUT: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 11, 155, 167, 108, 32, 122, 76, 173, 64];
256 pub const DEPOSIT: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 3, 155, 167, 108, 32, 122, 76, 173, 64];
257 pub const WITHDRAW: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 4, 155, 167, 108, 32, 122, 76, 173, 64];
258 pub const INITIALIZE2: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 1, 155, 167, 108, 32, 122, 76, 173, 64];
259 }
260
261 #[inline]
263 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
264 match disc {
265 &discriminators::SWAP_BASE_IN | &discriminators::SWAP_BASE_OUT => parse_swap(data, metadata),
266 &discriminators::DEPOSIT => parse_deposit(data, metadata),
267 &discriminators::WITHDRAW => parse_withdraw(data, metadata),
268 _ => None,
269 }
270 }
271
272 #[inline(always)]
278 fn parse_swap(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
279 #[cfg(feature = "parse-borsh")]
280 {
281 parse_swap_borsh(data, metadata)
282 }
283
284 #[cfg(feature = "parse-zero-copy")]
285 {
286 parse_swap_zero_copy(data, metadata)
287 }
288 }
289
290 #[cfg(feature = "parse-borsh")]
292 #[inline(always)]
293 fn parse_swap_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
294 const EVENT_SIZE: usize = 32 + 8 + 8;
300
301 if data.len() < EVENT_SIZE {
302 return None;
303 }
304
305 let event = borsh::from_slice::<RaydiumAmmV4SwapEvent>(&data[..EVENT_SIZE]).ok()?;
306
307 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
308 metadata,
309 ..event
310 }))
311 }
312
313 #[cfg(feature = "parse-zero-copy")]
315 #[inline(always)]
316 fn parse_swap_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
317 unsafe {
318 if !check_length(data, 32 + 8 + 8) {
319 return None;
320 }
321 let amm = read_pubkey_unchecked(data, 0);
322 let amount_in = read_u64_unchecked(data, 32);
323 let amount_out = read_u64_unchecked(data, 40);
324 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
325 metadata,
326 amm,
327 amount_in,
328 amount_out,
329 minimum_amount_out: 0,
330 max_amount_in: 0,
331 token_program: Pubkey::default(),
332 amm_authority: Pubkey::default(),
333 amm_open_orders: Pubkey::default(),
334 amm_target_orders: None,
335 pool_coin_token_account: Pubkey::default(),
336 pool_pc_token_account: Pubkey::default(),
337 serum_program: Pubkey::default(),
338 serum_market: Pubkey::default(),
339 serum_bids: Pubkey::default(),
340 serum_asks: Pubkey::default(),
341 serum_event_queue: Pubkey::default(),
342 serum_coin_vault_account: Pubkey::default(),
343 serum_pc_vault_account: Pubkey::default(),
344 serum_vault_signer: Pubkey::default(),
345 user_source_token_account: Pubkey::default(),
346 user_destination_token_account: Pubkey::default(),
347 user_source_owner: Pubkey::default(),
348 }))
349 }
350 }
351
352 #[inline(always)]
358 fn parse_deposit(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
359 #[cfg(feature = "parse-borsh")]
360 {
361 parse_deposit_borsh(data, metadata)
362 }
363
364 #[cfg(feature = "parse-zero-copy")]
365 {
366 parse_deposit_zero_copy(data, metadata)
367 }
368 }
369
370 #[cfg(feature = "parse-borsh")]
372 #[inline(always)]
373 fn parse_deposit_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
374 const EVENT_SIZE: usize = 32 + 8 + 8;
380
381 if data.len() < EVENT_SIZE {
382 return None;
383 }
384
385 let event = borsh::from_slice::<RaydiumAmmV4DepositEvent>(&data[..EVENT_SIZE]).ok()?;
386
387 Some(DexEvent::RaydiumAmmV4Deposit(RaydiumAmmV4DepositEvent {
388 metadata,
389 ..event
390 }))
391 }
392
393 #[cfg(feature = "parse-zero-copy")]
395 #[inline(always)]
396 fn parse_deposit_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
397 unsafe {
398 if !check_length(data, 32 + 8 + 8) {
399 return None;
400 }
401 let amm = read_pubkey_unchecked(data, 0);
402 let max_coin_amount = read_u64_unchecked(data, 32);
403 let max_pc_amount = read_u64_unchecked(data, 40);
404 Some(DexEvent::RaydiumAmmV4Deposit(RaydiumAmmV4DepositEvent {
405 metadata,
406 amm,
407 max_coin_amount,
408 max_pc_amount,
409 base_side: 0,
410 token_program: Pubkey::default(),
411 amm_authority: Pubkey::default(),
412 amm_open_orders: Pubkey::default(),
413 amm_target_orders: Pubkey::default(),
414 lp_mint_address: Pubkey::default(),
415 pool_coin_token_account: Pubkey::default(),
416 pool_pc_token_account: Pubkey::default(),
417 serum_market: Pubkey::default(),
418 serum_event_queue: Pubkey::default(),
419 user_coin_token_account: Pubkey::default(),
420 user_pc_token_account: Pubkey::default(),
421 user_lp_token_account: Pubkey::default(),
422 user_owner: Pubkey::default(),
423 }))
424 }
425 }
426
427 #[inline(always)]
433 fn parse_withdraw(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
434 #[cfg(feature = "parse-borsh")]
435 {
436 parse_withdraw_borsh(data, metadata)
437 }
438
439 #[cfg(feature = "parse-zero-copy")]
440 {
441 parse_withdraw_zero_copy(data, metadata)
442 }
443 }
444
445 #[cfg(feature = "parse-borsh")]
447 #[inline(always)]
448 fn parse_withdraw_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
449 const EVENT_SIZE: usize = 32 + 8;
454
455 if data.len() < EVENT_SIZE {
456 return None;
457 }
458
459 let event = borsh::from_slice::<RaydiumAmmV4WithdrawEvent>(&data[..EVENT_SIZE]).ok()?;
460
461 Some(DexEvent::RaydiumAmmV4Withdraw(RaydiumAmmV4WithdrawEvent {
462 metadata,
463 ..event
464 }))
465 }
466
467 #[cfg(feature = "parse-zero-copy")]
469 #[inline(always)]
470 fn parse_withdraw_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
471 unsafe {
472 if !check_length(data, 32 + 8) {
473 return None;
474 }
475 let amm = read_pubkey_unchecked(data, 0);
476 let amount = read_u64_unchecked(data, 32);
477 Some(DexEvent::RaydiumAmmV4Withdraw(RaydiumAmmV4WithdrawEvent {
478 metadata,
479 amm,
480 amount,
481 token_program: Pubkey::default(),
482 amm_authority: Pubkey::default(),
483 amm_open_orders: Pubkey::default(),
484 amm_target_orders: Pubkey::default(),
485 lp_mint_address: Pubkey::default(),
486 pool_coin_token_account: Pubkey::default(),
487 pool_pc_token_account: Pubkey::default(),
488 pool_withdraw_queue: Pubkey::default(),
489 pool_temp_lp_token_account: Pubkey::default(),
490 serum_program: Pubkey::default(),
491 serum_market: Pubkey::default(),
492 serum_bids: Pubkey::default(),
493 serum_asks: Pubkey::default(),
494 serum_event_queue: Pubkey::default(),
495 serum_coin_vault_account: Pubkey::default(),
496 serum_pc_vault_account: Pubkey::default(),
497 serum_vault_signer: Pubkey::default(),
498 user_lp_token_account: Pubkey::default(),
499 user_coin_token_account: Pubkey::default(),
500 user_pc_token_account: Pubkey::default(),
501 user_owner: Pubkey::default(),
502 }))
503 }
504 }
505}
506
507pub mod orca {
512 use super::*;
527
528 pub mod discriminators {
529 pub const TRADED: [u8; 16] = [225, 202, 73, 175, 147, 43, 160, 150, 155, 167, 108, 32, 122, 76, 173, 64];
530 pub const LIQUIDITY_INCREASED: [u8; 16] = [30, 7, 144, 181, 102, 254, 155, 161, 155, 167, 108, 32, 122, 76, 173, 64];
531 pub const LIQUIDITY_DECREASED: [u8; 16] = [166, 1, 36, 71, 112, 202, 181, 171, 155, 167, 108, 32, 122, 76, 173, 64];
532 pub const POOL_INITIALIZED: [u8; 16] = [100, 118, 173, 87, 12, 198, 254, 229, 155, 167, 108, 32, 122, 76, 173, 64];
533 }
534
535 #[inline]
537 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
538 match disc {
539 &discriminators::TRADED => parse_swap(data, metadata),
540 &discriminators::LIQUIDITY_INCREASED => parse_liquidity_increased(data, metadata),
541 &discriminators::LIQUIDITY_DECREASED => parse_liquidity_decreased(data, metadata),
542 _ => None,
543 }
544 }
545
546 #[inline(always)]
552 fn parse_swap(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
553 #[cfg(feature = "parse-borsh")]
554 { parse_swap_borsh(data, metadata) }
555
556 #[cfg(feature = "parse-zero-copy")]
557 { parse_swap_zero_copy(data, metadata) }
558 }
559
560 #[cfg(feature = "parse-borsh")]
562 #[inline(always)]
563 fn parse_swap_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
564 const SWAP_EVENT_SIZE: usize = 32 + 8 + 8 + 1;
566 if data.len() < SWAP_EVENT_SIZE { return None; }
567
568 let mut event = borsh::from_slice::<OrcaWhirlpoolSwapEvent>(&data[..SWAP_EVENT_SIZE]).ok()?;
569 event.metadata = metadata;
570 Some(DexEvent::OrcaWhirlpoolSwap(event))
571 }
572
573 #[cfg(feature = "parse-zero-copy")]
575 #[inline(always)]
576 fn parse_swap_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
577 unsafe {
578 if !check_length(data, 32 + 8 + 8 + 1) { return None; }
579 let whirlpool = read_pubkey_unchecked(data, 0);
580 let input_amount = read_u64_unchecked(data, 32);
581 let output_amount = read_u64_unchecked(data, 40);
582 let a_to_b = read_bool_unchecked(data, 48);
583 Some(DexEvent::OrcaWhirlpoolSwap(OrcaWhirlpoolSwapEvent {
584 metadata, whirlpool, input_amount, output_amount, a_to_b,
585 pre_sqrt_price: 0, post_sqrt_price: 0,
586 input_transfer_fee: 0, output_transfer_fee: 0,
587 lp_fee: 0, protocol_fee: 0,
588 }))
589 }
590 }
591
592 #[inline(always)]
598 fn parse_liquidity_increased(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
599 #[cfg(feature = "parse-borsh")]
600 { parse_liquidity_increased_borsh(data, metadata) }
601
602 #[cfg(feature = "parse-zero-copy")]
603 { parse_liquidity_increased_zero_copy(data, metadata) }
604 }
605
606 #[cfg(feature = "parse-borsh")]
608 #[inline(always)]
609 fn parse_liquidity_increased_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
610 const LIQUIDITY_EVENT_SIZE: usize = 32 + 16 + 8 + 8;
612 if data.len() < LIQUIDITY_EVENT_SIZE { return None; }
613
614 let mut event = borsh::from_slice::<OrcaWhirlpoolLiquidityIncreasedEvent>(&data[..LIQUIDITY_EVENT_SIZE]).ok()?;
615 event.metadata = metadata;
616 Some(DexEvent::OrcaWhirlpoolLiquidityIncreased(event))
617 }
618
619 #[cfg(feature = "parse-zero-copy")]
621 #[inline(always)]
622 fn parse_liquidity_increased_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
623 unsafe {
624 if !check_length(data, 32 + 16 + 8 + 8) { return None; }
625 let whirlpool = read_pubkey_unchecked(data, 0);
626 let liquidity = read_u128_unchecked(data, 32);
627 let token_a_amount = read_u64_unchecked(data, 48);
628 let token_b_amount = read_u64_unchecked(data, 56);
629 Some(DexEvent::OrcaWhirlpoolLiquidityIncreased(OrcaWhirlpoolLiquidityIncreasedEvent {
630 metadata, whirlpool, liquidity, token_a_amount, token_b_amount,
631 position: Pubkey::default(), tick_lower_index: 0, tick_upper_index: 0,
632 token_a_transfer_fee: 0, token_b_transfer_fee: 0,
633 }))
634 }
635 }
636
637 #[inline(always)]
643 fn parse_liquidity_decreased(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
644 #[cfg(feature = "parse-borsh")]
645 { parse_liquidity_decreased_borsh(data, metadata) }
646
647 #[cfg(feature = "parse-zero-copy")]
648 { parse_liquidity_decreased_zero_copy(data, metadata) }
649 }
650
651 #[cfg(feature = "parse-borsh")]
653 #[inline(always)]
654 fn parse_liquidity_decreased_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
655 const LIQUIDITY_EVENT_SIZE: usize = 32 + 16 + 8 + 8;
657 if data.len() < LIQUIDITY_EVENT_SIZE { return None; }
658
659 let mut event = borsh::from_slice::<OrcaWhirlpoolLiquidityDecreasedEvent>(&data[..LIQUIDITY_EVENT_SIZE]).ok()?;
660 event.metadata = metadata;
661 Some(DexEvent::OrcaWhirlpoolLiquidityDecreased(event))
662 }
663
664 #[cfg(feature = "parse-zero-copy")]
666 #[inline(always)]
667 fn parse_liquidity_decreased_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
668 unsafe {
669 if !check_length(data, 32 + 16 + 8 + 8) { return None; }
670 let whirlpool = read_pubkey_unchecked(data, 0);
671 let liquidity = read_u128_unchecked(data, 32);
672 let token_a_amount = read_u64_unchecked(data, 48);
673 let token_b_amount = read_u64_unchecked(data, 56);
674 Some(DexEvent::OrcaWhirlpoolLiquidityDecreased(OrcaWhirlpoolLiquidityDecreasedEvent {
675 metadata, whirlpool, liquidity, token_a_amount, token_b_amount,
676 position: Pubkey::default(), tick_lower_index: 0, tick_upper_index: 0,
677 token_a_transfer_fee: 0, token_b_transfer_fee: 0,
678 }))
679 }
680 }
681}
682
683pub mod meteora_amm {
688 use super::*;
689
690 pub mod discriminators {
691 pub const SWAP: [u8; 16] = [81, 108, 227, 190, 205, 208, 10, 196, 155, 167, 108, 32, 122, 76, 173, 64];
692 pub const ADD_LIQUIDITY: [u8; 16] = [31, 94, 125, 90, 227, 52, 61, 186, 155, 167, 108, 32, 122, 76, 173, 64];
693 pub const REMOVE_LIQUIDITY: [u8; 16] = [116, 244, 97, 232, 103, 31, 152, 58, 155, 167, 108, 32, 122, 76, 173, 64];
694 pub const POOL_CREATED: [u8; 16] = [202, 44, 41, 88, 104, 220, 157, 82, 155, 167, 108, 32, 122, 76, 173, 64];
695 }
696
697 #[inline]
698 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
699 unsafe {
700 match disc {
701 &discriminators::SWAP => {
702 if !check_length(data, 8 + 8) { return None; }
703 let in_amount = read_u64_unchecked(data, 0);
704 let out_amount = read_u64_unchecked(data, 8);
705 Some(DexEvent::MeteoraPoolsSwap(MeteoraPoolsSwapEvent {
706 metadata, in_amount, out_amount, trade_fee: 0, admin_fee: 0, host_fee: 0,
707 }))
708 }
709 &discriminators::ADD_LIQUIDITY => {
710 if !check_length(data, 8 + 8 + 8) { return None; }
711 let lp_mint_amount = read_u64_unchecked(data, 0);
712 let token_a_amount = read_u64_unchecked(data, 8);
713 let token_b_amount = read_u64_unchecked(data, 16);
714 Some(DexEvent::MeteoraPoolsAddLiquidity(MeteoraPoolsAddLiquidityEvent {
715 metadata, lp_mint_amount, token_a_amount, token_b_amount,
716 }))
717 }
718 &discriminators::REMOVE_LIQUIDITY => {
719 if !check_length(data, 8 + 8 + 8) { return None; }
720 let lp_unmint_amount = read_u64_unchecked(data, 0);
721 let token_a_out_amount = read_u64_unchecked(data, 8);
722 let token_b_out_amount = read_u64_unchecked(data, 16);
723 Some(DexEvent::MeteoraPoolsRemoveLiquidity(MeteoraPoolsRemoveLiquidityEvent {
724 metadata, lp_unmint_amount, token_a_out_amount, token_b_out_amount,
725 }))
726 }
727 _ => None,
728 }
729 }
730 }
731}
732
733pub mod meteora_damm {
738 use super::*;
753
754 pub mod discriminators {
755 pub const SWAP: [u8; 16] = [228, 69, 165, 46, 81, 203, 154, 29, 27, 60, 21, 213, 138, 170, 187, 147];
756 pub const SWAP2: [u8; 16] = [228, 69, 165, 46, 81, 203, 154, 29, 189, 66, 51, 168, 38, 80, 117, 153];
757 pub const ADD_LIQUIDITY: [u8; 16] = [228, 69, 165, 46, 81, 203, 154, 29, 175, 242, 8, 157, 30, 247, 185, 169];
758 pub const REMOVE_LIQUIDITY: [u8; 16] = [228, 69, 165, 46, 81, 203, 154, 29, 87, 46, 88, 98, 175, 96, 34, 91];
759 pub const CREATE_POSITION: [u8; 16] = [228, 69, 165, 46, 81, 203, 154, 29, 156, 15, 119, 198, 29, 181, 221, 55];
760 pub const CLOSE_POSITION: [u8; 16] = [228, 69, 165, 46, 81, 203, 154, 29, 20, 145, 144, 68, 143, 142, 214, 178];
761 }
762
763 #[inline]
765 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
766 match disc {
767 &discriminators::SWAP => parse_swap(data, metadata),
768 &discriminators::SWAP2 => parse_swap2(data, metadata),
769 &discriminators::ADD_LIQUIDITY => parse_add_liquidity(data, metadata),
770 &discriminators::REMOVE_LIQUIDITY => parse_remove_liquidity(data, metadata),
771 &discriminators::CREATE_POSITION => parse_create_position(data, metadata),
772 &discriminators::CLOSE_POSITION => parse_close_position(data, metadata),
773 _ => None,
774 }
775 }
776
777 #[inline(always)]
783 fn parse_swap(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
784 #[cfg(feature = "parse-borsh")]
785 { parse_swap_borsh(data, metadata) }
786
787 #[cfg(feature = "parse-zero-copy")]
788 { parse_swap_zero_copy(data, metadata) }
789 }
790
791 #[cfg(feature = "parse-borsh")]
793 #[inline(always)]
794 fn parse_swap_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
795 const SWAP_EVENT_SIZE: usize = 32 + 8 + 8;
797 if data.len() < SWAP_EVENT_SIZE { return None; }
798
799 let event = borsh::from_slice::<MeteoraDammV2SwapEvent>(&data[..SWAP_EVENT_SIZE]).ok()?;
800 Some(DexEvent::MeteoraDammV2Swap(MeteoraDammV2SwapEvent { metadata, ..event }))
801 }
802
803 #[cfg(feature = "parse-zero-copy")]
805 #[inline(always)]
806 fn parse_swap_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
807 unsafe {
808 if !check_length(data, 32 + 8 + 8) { return None; }
809 let pool = read_pubkey_unchecked(data, 0);
810 let amount_in = read_u64_unchecked(data, 32);
811 let output_amount = read_u64_unchecked(data, 40);
812 Some(DexEvent::MeteoraDammV2Swap(MeteoraDammV2SwapEvent {
813 metadata, pool, amount_in, output_amount, ..Default::default()
814 }))
815 }
816 }
817
818 #[inline(always)]
824 fn parse_swap2(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
825 #[cfg(feature = "parse-borsh")]
826 { parse_swap2_borsh(data, metadata) }
827
828 #[cfg(feature = "parse-zero-copy")]
829 { parse_swap2_zero_copy(data, metadata) }
830 }
831
832 #[cfg(feature = "parse-borsh")]
834 #[inline(always)]
835 fn parse_swap2_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
836 const SWAP2_EVENT_MIN_SIZE: usize = 177;
845 if data.len() < SWAP2_EVENT_MIN_SIZE { return None; }
846
847 let mut offset = 0;
848
849 unsafe {
851 let pool = read_pubkey_unchecked(data, offset);
852 offset += 32;
853
854 let _config = read_pubkey_unchecked(data, offset);
855 offset += 32;
856
857 let trade_direction = read_u8_unchecked(data, offset);
858 offset += 1;
859
860 let has_referral = read_bool_unchecked(data, offset);
861 offset += 1;
862
863 let amount_0 = read_u64_unchecked(data, offset);
864 offset += 8;
865
866 let amount_1 = read_u64_unchecked(data, offset);
867 offset += 8;
868
869 let swap_mode = read_u8_unchecked(data, offset);
870 offset += 1;
871
872 let included_fee_input_amount = read_u64_unchecked(data, offset);
873 offset += 8;
874
875 let _excluded_fee_input_amount = read_u64_unchecked(data, offset);
876 offset += 8;
877
878 let _amount_left = read_u64_unchecked(data, offset);
879 offset += 8;
880
881 let output_amount = read_u64_unchecked(data, offset);
882 offset += 8;
883
884 let next_sqrt_price = read_u128_unchecked(data, offset);
885 offset += 16;
886
887 let lp_fee = read_u64_unchecked(data, offset);
888 offset += 8;
889
890 let protocol_fee = read_u64_unchecked(data, offset);
891 offset += 8;
892
893 let referral_fee = read_u64_unchecked(data, offset);
894 offset += 8;
895
896 let _quote_reserve_amount = read_u64_unchecked(data, offset);
897 offset += 8;
898
899 let _migration_threshold = read_u64_unchecked(data, offset);
900 offset += 8;
901
902 let current_timestamp = read_u64_unchecked(data, offset);
903
904 let (amount_in, minimum_amount_out) = if swap_mode == 0 {
906 (amount_0, amount_1)
907 } else {
908 (amount_1, amount_0)
909 };
910
911 Some(DexEvent::MeteoraDammV2Swap(MeteoraDammV2SwapEvent {
912 metadata,
913 pool,
914 trade_direction,
915 has_referral,
916 amount_in,
917 minimum_amount_out,
918 output_amount,
919 next_sqrt_price,
920 lp_fee,
921 protocol_fee,
922 partner_fee: 0,
923 referral_fee,
924 actual_amount_in: included_fee_input_amount,
925 current_timestamp,
926 ..Default::default()
927 }))
928 }
929 }
930
931 #[cfg(feature = "parse-zero-copy")]
933 #[inline(always)]
934 fn parse_swap2_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
935 const SWAP2_EVENT_MIN_SIZE: usize = 177;
943
944 unsafe {
945 if !check_length(data, SWAP2_EVENT_MIN_SIZE) { return None; }
946
947 let pool = read_pubkey_unchecked(data, 0);
948 let trade_direction = read_u8_unchecked(data, 64);
949 let has_referral = read_bool_unchecked(data, 65);
950 let amount_0 = read_u64_unchecked(data, 66);
951 let amount_1 = read_u64_unchecked(data, 74);
952 let swap_mode = read_u8_unchecked(data, 82);
953 let included_fee_input_amount = read_u64_unchecked(data, 83);
954 let output_amount = read_u64_unchecked(data, 107);
955 let next_sqrt_price = read_u128_unchecked(data, 115);
956 let lp_fee = read_u64_unchecked(data, 131);
957 let protocol_fee = read_u64_unchecked(data, 139);
958 let referral_fee = read_u64_unchecked(data, 147);
959 let current_timestamp = read_u64_unchecked(data, 169);
960
961 let (amount_in, minimum_amount_out) = if swap_mode == 0 {
963 (amount_0, amount_1)
964 } else {
965 (amount_1, amount_0)
966 };
967
968 Some(DexEvent::MeteoraDammV2Swap(MeteoraDammV2SwapEvent {
969 metadata,
970 pool,
971 trade_direction,
972 has_referral,
973 amount_in,
974 minimum_amount_out,
975 output_amount,
976 next_sqrt_price,
977 lp_fee,
978 protocol_fee,
979 partner_fee: 0,
980 referral_fee,
981 actual_amount_in: included_fee_input_amount,
982 current_timestamp,
983 ..Default::default()
984 }))
985 }
986 }
987
988 #[inline(always)]
994 fn parse_add_liquidity(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
995 #[cfg(feature = "parse-borsh")]
996 { parse_add_liquidity_borsh(data, metadata) }
997
998 #[cfg(feature = "parse-zero-copy")]
999 { parse_add_liquidity_zero_copy(data, metadata) }
1000 }
1001
1002 #[cfg(feature = "parse-borsh")]
1004 #[inline(always)]
1005 fn parse_add_liquidity_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1006 const ADD_LIQUIDITY_EVENT_SIZE: usize = 32 + 32 + 32 + 8 + 8;
1008 if data.len() < ADD_LIQUIDITY_EVENT_SIZE { return None; }
1009
1010 let event = borsh::from_slice::<MeteoraDammV2AddLiquidityEvent>(&data[..ADD_LIQUIDITY_EVENT_SIZE]).ok()?;
1011 Some(DexEvent::MeteoraDammV2AddLiquidity(MeteoraDammV2AddLiquidityEvent { metadata, ..event }))
1012 }
1013
1014 #[cfg(feature = "parse-zero-copy")]
1016 #[inline(always)]
1017 fn parse_add_liquidity_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1018 unsafe {
1019 if !check_length(data, 32 + 32 + 32 + 8 + 8) { return None; }
1020 let pool = read_pubkey_unchecked(data, 0);
1021 let position = read_pubkey_unchecked(data, 32);
1022 let owner = read_pubkey_unchecked(data, 64);
1023 let token_a_amount = read_u64_unchecked(data, 96);
1024 let token_b_amount = read_u64_unchecked(data, 104);
1025 Some(DexEvent::MeteoraDammV2AddLiquidity(MeteoraDammV2AddLiquidityEvent {
1026 metadata, pool, position, owner, token_a_amount, token_b_amount,
1027 liquidity_delta: 0, token_a_amount_threshold: 0, token_b_amount_threshold: 0,
1028 total_amount_a: 0, total_amount_b: 0,
1029 }))
1030 }
1031 }
1032
1033 #[inline(always)]
1039 fn parse_remove_liquidity(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1040 #[cfg(feature = "parse-borsh")]
1041 { parse_remove_liquidity_borsh(data, metadata) }
1042
1043 #[cfg(feature = "parse-zero-copy")]
1044 { parse_remove_liquidity_zero_copy(data, metadata) }
1045 }
1046
1047 #[cfg(feature = "parse-borsh")]
1049 #[inline(always)]
1050 fn parse_remove_liquidity_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1051 const REMOVE_LIQUIDITY_EVENT_SIZE: usize = 32 + 32 + 32 + 8 + 8;
1053 if data.len() < REMOVE_LIQUIDITY_EVENT_SIZE { return None; }
1054
1055 let event = borsh::from_slice::<MeteoraDammV2RemoveLiquidityEvent>(&data[..REMOVE_LIQUIDITY_EVENT_SIZE]).ok()?;
1056 Some(DexEvent::MeteoraDammV2RemoveLiquidity(MeteoraDammV2RemoveLiquidityEvent { metadata, ..event }))
1057 }
1058
1059 #[cfg(feature = "parse-zero-copy")]
1061 #[inline(always)]
1062 fn parse_remove_liquidity_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1063 unsafe {
1064 if !check_length(data, 32 + 32 + 32 + 8 + 8) { return None; }
1065 let pool = read_pubkey_unchecked(data, 0);
1066 let position = read_pubkey_unchecked(data, 32);
1067 let owner = read_pubkey_unchecked(data, 64);
1068 let token_a_amount = read_u64_unchecked(data, 96);
1069 let token_b_amount = read_u64_unchecked(data, 104);
1070 Some(DexEvent::MeteoraDammV2RemoveLiquidity(MeteoraDammV2RemoveLiquidityEvent {
1071 metadata, pool, position, owner, token_a_amount, token_b_amount,
1072 liquidity_delta: 0, token_a_amount_threshold: 0, token_b_amount_threshold: 0,
1073 }))
1074 }
1075 }
1076
1077 #[inline(always)]
1083 fn parse_create_position(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1084 #[cfg(feature = "parse-borsh")]
1085 { parse_create_position_borsh(data, metadata) }
1086
1087 #[cfg(feature = "parse-zero-copy")]
1088 { parse_create_position_zero_copy(data, metadata) }
1089 }
1090
1091 #[cfg(feature = "parse-borsh")]
1093 #[inline(always)]
1094 fn parse_create_position_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1095 const CREATE_POSITION_EVENT_SIZE: usize = 32 + 32 + 32 + 32;
1097 if data.len() < CREATE_POSITION_EVENT_SIZE { return None; }
1098
1099 let event = borsh::from_slice::<MeteoraDammV2CreatePositionEvent>(&data[..CREATE_POSITION_EVENT_SIZE]).ok()?;
1100 Some(DexEvent::MeteoraDammV2CreatePosition(MeteoraDammV2CreatePositionEvent { metadata, ..event }))
1101 }
1102
1103 #[cfg(feature = "parse-zero-copy")]
1105 #[inline(always)]
1106 fn parse_create_position_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1107 unsafe {
1108 if !check_length(data, 32 + 32 + 32 + 32) { return None; }
1109 let pool = read_pubkey_unchecked(data, 0);
1110 let owner = read_pubkey_unchecked(data, 32);
1111 let position = read_pubkey_unchecked(data, 64);
1112 let position_nft_mint = read_pubkey_unchecked(data, 96);
1113 Some(DexEvent::MeteoraDammV2CreatePosition(MeteoraDammV2CreatePositionEvent {
1114 metadata, pool, owner, position, position_nft_mint,
1115 }))
1116 }
1117 }
1118
1119 #[inline(always)]
1125 fn parse_close_position(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1126 #[cfg(feature = "parse-borsh")]
1127 { parse_close_position_borsh(data, metadata) }
1128
1129 #[cfg(feature = "parse-zero-copy")]
1130 { parse_close_position_zero_copy(data, metadata) }
1131 }
1132
1133 #[cfg(feature = "parse-borsh")]
1135 #[inline(always)]
1136 fn parse_close_position_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1137 const CLOSE_POSITION_EVENT_SIZE: usize = 32 + 32 + 32 + 32;
1139 if data.len() < CLOSE_POSITION_EVENT_SIZE { return None; }
1140
1141 let event = borsh::from_slice::<MeteoraDammV2ClosePositionEvent>(&data[..CLOSE_POSITION_EVENT_SIZE]).ok()?;
1142 Some(DexEvent::MeteoraDammV2ClosePosition(MeteoraDammV2ClosePositionEvent { metadata, ..event }))
1143 }
1144
1145 #[cfg(feature = "parse-zero-copy")]
1147 #[inline(always)]
1148 fn parse_close_position_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1149 unsafe {
1150 if !check_length(data, 32 + 32 + 32 + 32) { return None; }
1151 let pool = read_pubkey_unchecked(data, 0);
1152 let owner = read_pubkey_unchecked(data, 32);
1153 let position = read_pubkey_unchecked(data, 64);
1154 let position_nft_mint = read_pubkey_unchecked(data, 96);
1155 Some(DexEvent::MeteoraDammV2ClosePosition(MeteoraDammV2ClosePositionEvent {
1156 metadata, pool, owner, position, position_nft_mint,
1157 }))
1158 }
1159 }
1160}
1161
1162pub mod bonk {
1167 use super::*;
1182
1183 pub mod discriminators {
1184 pub const POOL_CREATE: [u8; 16] = [100, 50, 200, 150, 75, 120, 90, 30, 155, 167, 108, 32, 122, 76, 173, 64];
1185 pub const TRADE: [u8; 16] = [80, 120, 100, 200, 150, 75, 60, 40, 155, 167, 108, 32, 122, 76, 173, 64];
1186 pub const MIGRATE: [u8; 16] = [90, 130, 110, 210, 160, 85, 70, 50, 155, 167, 108, 32, 122, 76, 173, 64];
1187 }
1188
1189 #[inline]
1191 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1192 match disc {
1193 &discriminators::TRADE => parse_trade(data, metadata),
1194 _ => None,
1195 }
1196 }
1197
1198 #[inline(always)]
1204 fn parse_trade(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1205 #[cfg(feature = "parse-borsh")]
1206 { parse_trade_borsh(data, metadata) }
1207
1208 #[cfg(feature = "parse-zero-copy")]
1209 { parse_trade_zero_copy(data, metadata) }
1210 }
1211
1212 #[cfg(feature = "parse-borsh")]
1214 #[inline(always)]
1215 fn parse_trade_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1216 const TRADE_EVENT_SIZE: usize = 32 + 32 + 8 + 8 + 1;
1218 if data.len() < TRADE_EVENT_SIZE { return None; }
1219
1220 let mut event = borsh::from_slice::<BonkTradeEvent>(&data[..TRADE_EVENT_SIZE]).ok()?;
1221 event.metadata = metadata;
1222 event.trade_direction = if event.is_buy { TradeDirection::Buy } else { TradeDirection::Sell };
1223 event.exact_in = true;
1224 Some(DexEvent::BonkTrade(event))
1225 }
1226
1227 #[cfg(feature = "parse-zero-copy")]
1229 #[inline(always)]
1230 fn parse_trade_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1231 unsafe {
1232 if !check_length(data, 32 + 32 + 8 + 8 + 1) { return None; }
1233 let pool_state = read_pubkey_unchecked(data, 0);
1234 let user = read_pubkey_unchecked(data, 32);
1235 let amount_in = read_u64_unchecked(data, 64);
1236 let amount_out = read_u64_unchecked(data, 72);
1237 let is_buy = read_bool_unchecked(data, 80);
1238 Some(DexEvent::BonkTrade(BonkTradeEvent {
1239 metadata, pool_state, user, amount_in, amount_out, is_buy,
1240 trade_direction: if is_buy { TradeDirection::Buy } else { TradeDirection::Sell },
1241 exact_in: true,
1242 }))
1243 }
1244 }
1245}
1246
1247pub mod meteora_dlmm {
1252 use super::*;
1267
1268 pub mod discriminators {
1269 pub const SWAP: [u8; 16] = [143, 190, 90, 218, 196, 30, 51, 222, 155, 167, 108, 32, 122, 76, 173, 64];
1271 pub const ADD_LIQUIDITY: [u8; 16] = [181, 157, 89, 67, 143, 182, 52, 72, 155, 167, 108, 32, 122, 76, 173, 64];
1272 pub const REMOVE_LIQUIDITY: [u8; 16] = [80, 85, 209, 72, 24, 206, 35, 178, 155, 167, 108, 32, 122, 76, 173, 64];
1273 pub const INITIALIZE_POOL: [u8; 16] = [95, 180, 10, 172, 84, 174, 232, 40, 155, 167, 108, 32, 122, 76, 173, 64];
1274 pub const INITIALIZE_BIN_ARRAY: [u8; 16] = [11, 18, 155, 194, 33, 115, 238, 119, 155, 167, 108, 32, 122, 76, 173, 64];
1275 pub const CREATE_POSITION: [u8; 16] = [123, 233, 11, 43, 146, 180, 97, 119, 155, 167, 108, 32, 122, 76, 173, 64];
1276 pub const CLOSE_POSITION: [u8; 16] = [94, 168, 102, 45, 59, 122, 137, 54, 155, 167, 108, 32, 122, 76, 173, 64];
1277 pub const CLAIM_FEE: [u8; 16] = [152, 70, 208, 111, 104, 91, 44, 1, 155, 167, 108, 32, 122, 76, 173, 64];
1278 }
1279
1280 #[inline]
1282 pub fn parse(disc: &[u8; 16], data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1283 match disc {
1284 &discriminators::SWAP => parse_swap(data, metadata),
1285 &discriminators::ADD_LIQUIDITY => parse_add_liquidity(data, metadata),
1286 &discriminators::REMOVE_LIQUIDITY => parse_remove_liquidity(data, metadata),
1287 &discriminators::INITIALIZE_POOL => parse_initialize_pool(data, metadata),
1288 &discriminators::INITIALIZE_BIN_ARRAY => parse_initialize_bin_array(data, metadata),
1289 &discriminators::CREATE_POSITION => parse_create_position(data, metadata),
1290 &discriminators::CLOSE_POSITION => parse_close_position(data, metadata),
1291 &discriminators::CLAIM_FEE => parse_claim_fee(data, metadata),
1292 _ => None,
1293 }
1294 }
1295
1296 #[inline(always)]
1302 fn parse_swap(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1303 #[cfg(feature = "parse-borsh")]
1304 { parse_swap_borsh(data, metadata) }
1305
1306 #[cfg(feature = "parse-zero-copy")]
1307 { parse_swap_zero_copy(data, metadata) }
1308 }
1309
1310 #[cfg(feature = "parse-borsh")]
1312 #[inline(always)]
1313 fn parse_swap_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1314 const SWAP_EVENT_SIZE: usize = 32 + 32 + 4 + 4 + 8 + 8 + 1 + 8 + 8 + 16 + 8;
1316 if data.len() < SWAP_EVENT_SIZE { return None; }
1317
1318 let mut event = borsh::from_slice::<MeteoraDlmmSwapEvent>(&data[..SWAP_EVENT_SIZE]).ok()?;
1319 event.metadata = metadata;
1320 Some(DexEvent::MeteoraDlmmSwap(event))
1321 }
1322
1323 #[cfg(feature = "parse-zero-copy")]
1325 #[inline(always)]
1326 fn parse_swap_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1327 unsafe {
1328 if !check_length(data, 32 + 32 + 4 + 4 + 8 + 8 + 1 + 8 + 8 + 16 + 8) { return None; }
1329 let pool = read_pubkey_unchecked(data, 0);
1330 let from = read_pubkey_unchecked(data, 32);
1331 let start_bin_id = read_i32_unchecked(data, 64);
1332 let end_bin_id = read_i32_unchecked(data, 68);
1333 let amount_in = read_u64_unchecked(data, 72);
1334 let amount_out = read_u64_unchecked(data, 80);
1335 let swap_for_y = read_bool_unchecked(data, 88);
1336 let fee = read_u64_unchecked(data, 89);
1337 let protocol_fee = read_u64_unchecked(data, 97);
1338 let fee_bps = read_u128_unchecked(data, 105);
1339 let host_fee = read_u64_unchecked(data, 121);
1340 Some(DexEvent::MeteoraDlmmSwap(MeteoraDlmmSwapEvent {
1341 metadata, pool, from, start_bin_id, end_bin_id, amount_in, amount_out,
1342 swap_for_y, fee, protocol_fee, fee_bps, host_fee,
1343 }))
1344 }
1345 }
1346
1347 #[inline(always)]
1353 fn parse_add_liquidity(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1354 #[cfg(feature = "parse-borsh")]
1355 { parse_add_liquidity_borsh(data, metadata) }
1356
1357 #[cfg(feature = "parse-zero-copy")]
1358 { parse_add_liquidity_zero_copy(data, metadata) }
1359 }
1360
1361 #[cfg(feature = "parse-borsh")]
1363 #[inline(always)]
1364 fn parse_add_liquidity_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1365 const ADD_LIQUIDITY_EVENT_SIZE: usize = 32 + 32 + 32 + 16 + 4;
1367 if data.len() < ADD_LIQUIDITY_EVENT_SIZE { return None; }
1368
1369 let mut event = borsh::from_slice::<MeteoraDlmmAddLiquidityEvent>(&data[..ADD_LIQUIDITY_EVENT_SIZE]).ok()?;
1370 event.metadata = metadata;
1371 Some(DexEvent::MeteoraDlmmAddLiquidity(event))
1372 }
1373
1374 #[cfg(feature = "parse-zero-copy")]
1376 #[inline(always)]
1377 fn parse_add_liquidity_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1378 unsafe {
1379 if !check_length(data, 32 + 32 + 32 + 16 + 4) { return None; }
1380 let pool = read_pubkey_unchecked(data, 0);
1381 let from = read_pubkey_unchecked(data, 32);
1382 let position = read_pubkey_unchecked(data, 64);
1383 let amount_0 = read_u64_unchecked(data, 96);
1384 let amount_1 = read_u64_unchecked(data, 104);
1385 let active_bin_id = read_i32_unchecked(data, 112);
1386 Some(DexEvent::MeteoraDlmmAddLiquidity(MeteoraDlmmAddLiquidityEvent {
1387 metadata, pool, from, position, amounts: [amount_0, amount_1], active_bin_id,
1388 }))
1389 }
1390 }
1391
1392 #[inline(always)]
1398 fn parse_remove_liquidity(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1399 #[cfg(feature = "parse-borsh")]
1400 { parse_remove_liquidity_borsh(data, metadata) }
1401
1402 #[cfg(feature = "parse-zero-copy")]
1403 { parse_remove_liquidity_zero_copy(data, metadata) }
1404 }
1405
1406 #[cfg(feature = "parse-borsh")]
1408 #[inline(always)]
1409 fn parse_remove_liquidity_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1410 const REMOVE_LIQUIDITY_EVENT_SIZE: usize = 32 + 32 + 32 + 16 + 4;
1412 if data.len() < REMOVE_LIQUIDITY_EVENT_SIZE { return None; }
1413
1414 let mut event = borsh::from_slice::<MeteoraDlmmRemoveLiquidityEvent>(&data[..REMOVE_LIQUIDITY_EVENT_SIZE]).ok()?;
1415 event.metadata = metadata;
1416 Some(DexEvent::MeteoraDlmmRemoveLiquidity(event))
1417 }
1418
1419 #[cfg(feature = "parse-zero-copy")]
1421 #[inline(always)]
1422 fn parse_remove_liquidity_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1423 unsafe {
1424 if !check_length(data, 32 + 32 + 32 + 16 + 4) { return None; }
1425 let pool = read_pubkey_unchecked(data, 0);
1426 let from = read_pubkey_unchecked(data, 32);
1427 let position = read_pubkey_unchecked(data, 64);
1428 let amount_0 = read_u64_unchecked(data, 96);
1429 let amount_1 = read_u64_unchecked(data, 104);
1430 let active_bin_id = read_i32_unchecked(data, 112);
1431 Some(DexEvent::MeteoraDlmmRemoveLiquidity(MeteoraDlmmRemoveLiquidityEvent {
1432 metadata, pool, from, position, amounts: [amount_0, amount_1], active_bin_id,
1433 }))
1434 }
1435 }
1436
1437 #[inline(always)]
1443 fn parse_initialize_pool(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1444 #[cfg(feature = "parse-borsh")]
1445 { parse_initialize_pool_borsh(data, metadata) }
1446
1447 #[cfg(feature = "parse-zero-copy")]
1448 { parse_initialize_pool_zero_copy(data, metadata) }
1449 }
1450
1451 #[cfg(feature = "parse-borsh")]
1453 #[inline(always)]
1454 fn parse_initialize_pool_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1455 const INITIALIZE_POOL_EVENT_SIZE: usize = 32 + 32 + 4 + 2;
1457 if data.len() < INITIALIZE_POOL_EVENT_SIZE { return None; }
1458
1459 let mut event = borsh::from_slice::<MeteoraDlmmInitializePoolEvent>(&data[..INITIALIZE_POOL_EVENT_SIZE]).ok()?;
1460 event.metadata = metadata;
1461 Some(DexEvent::MeteoraDlmmInitializePool(event))
1462 }
1463
1464 #[cfg(feature = "parse-zero-copy")]
1466 #[inline(always)]
1467 fn parse_initialize_pool_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1468 unsafe {
1469 if !check_length(data, 32 + 32 + 4 + 2) { return None; }
1470 let pool = read_pubkey_unchecked(data, 0);
1471 let creator = read_pubkey_unchecked(data, 32);
1472 let active_bin_id = read_i32_unchecked(data, 64);
1473 let bin_step = read_u16_unchecked(data, 68);
1474 Some(DexEvent::MeteoraDlmmInitializePool(MeteoraDlmmInitializePoolEvent {
1475 metadata, pool, creator, active_bin_id, bin_step,
1476 }))
1477 }
1478 }
1479
1480 #[inline(always)]
1486 fn parse_initialize_bin_array(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1487 #[cfg(feature = "parse-borsh")]
1488 { parse_initialize_bin_array_borsh(data, metadata) }
1489
1490 #[cfg(feature = "parse-zero-copy")]
1491 { parse_initialize_bin_array_zero_copy(data, metadata) }
1492 }
1493
1494 #[cfg(feature = "parse-borsh")]
1496 #[inline(always)]
1497 fn parse_initialize_bin_array_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1498 const INITIALIZE_BIN_ARRAY_EVENT_SIZE: usize = 32 + 32 + 8;
1500 if data.len() < INITIALIZE_BIN_ARRAY_EVENT_SIZE { return None; }
1501
1502 let mut event = borsh::from_slice::<MeteoraDlmmInitializeBinArrayEvent>(&data[..INITIALIZE_BIN_ARRAY_EVENT_SIZE]).ok()?;
1503 event.metadata = metadata;
1504 Some(DexEvent::MeteoraDlmmInitializeBinArray(event))
1505 }
1506
1507 #[cfg(feature = "parse-zero-copy")]
1509 #[inline(always)]
1510 fn parse_initialize_bin_array_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1511 unsafe {
1512 if !check_length(data, 32 + 32 + 8) { return None; }
1513 let pool = read_pubkey_unchecked(data, 0);
1514 let bin_array = read_pubkey_unchecked(data, 32);
1515 let index = read_i64_unchecked(data, 64);
1516 Some(DexEvent::MeteoraDlmmInitializeBinArray(MeteoraDlmmInitializeBinArrayEvent {
1517 metadata, pool, bin_array, index,
1518 }))
1519 }
1520 }
1521
1522 #[inline(always)]
1528 fn parse_create_position(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1529 #[cfg(feature = "parse-borsh")]
1530 { parse_create_position_borsh(data, metadata) }
1531
1532 #[cfg(feature = "parse-zero-copy")]
1533 { parse_create_position_zero_copy(data, metadata) }
1534 }
1535
1536 #[cfg(feature = "parse-borsh")]
1538 #[inline(always)]
1539 fn parse_create_position_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1540 const CREATE_POSITION_EVENT_SIZE: usize = 32 + 32 + 32 + 4 + 4;
1542 if data.len() < CREATE_POSITION_EVENT_SIZE { return None; }
1543
1544 let mut event = borsh::from_slice::<MeteoraDlmmCreatePositionEvent>(&data[..CREATE_POSITION_EVENT_SIZE]).ok()?;
1545 event.metadata = metadata;
1546 Some(DexEvent::MeteoraDlmmCreatePosition(event))
1547 }
1548
1549 #[cfg(feature = "parse-zero-copy")]
1551 #[inline(always)]
1552 fn parse_create_position_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1553 unsafe {
1554 if !check_length(data, 32 + 32 + 32 + 4 + 4) { return None; }
1555 let pool = read_pubkey_unchecked(data, 0);
1556 let position = read_pubkey_unchecked(data, 32);
1557 let owner = read_pubkey_unchecked(data, 64);
1558 let lower_bin_id = read_i32_unchecked(data, 96);
1559 let width = read_u32_unchecked(data, 100);
1560 Some(DexEvent::MeteoraDlmmCreatePosition(MeteoraDlmmCreatePositionEvent {
1561 metadata, pool, position, owner, lower_bin_id, width,
1562 }))
1563 }
1564 }
1565
1566 #[inline(always)]
1572 fn parse_close_position(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1573 #[cfg(feature = "parse-borsh")]
1574 { parse_close_position_borsh(data, metadata) }
1575
1576 #[cfg(feature = "parse-zero-copy")]
1577 { parse_close_position_zero_copy(data, metadata) }
1578 }
1579
1580 #[cfg(feature = "parse-borsh")]
1582 #[inline(always)]
1583 fn parse_close_position_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1584 const CLOSE_POSITION_EVENT_SIZE: usize = 32 + 32 + 32;
1586 if data.len() < CLOSE_POSITION_EVENT_SIZE { return None; }
1587
1588 let mut event = borsh::from_slice::<MeteoraDlmmClosePositionEvent>(&data[..CLOSE_POSITION_EVENT_SIZE]).ok()?;
1589 event.metadata = metadata;
1590 Some(DexEvent::MeteoraDlmmClosePosition(event))
1591 }
1592
1593 #[cfg(feature = "parse-zero-copy")]
1595 #[inline(always)]
1596 fn parse_close_position_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1597 unsafe {
1598 if !check_length(data, 32 + 32 + 32) { return None; }
1599 let pool = read_pubkey_unchecked(data, 0);
1600 let position = read_pubkey_unchecked(data, 32);
1601 let owner = read_pubkey_unchecked(data, 64);
1602 Some(DexEvent::MeteoraDlmmClosePosition(MeteoraDlmmClosePositionEvent {
1603 metadata, pool, position, owner,
1604 }))
1605 }
1606 }
1607
1608 #[inline(always)]
1614 fn parse_claim_fee(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1615 #[cfg(feature = "parse-borsh")]
1616 { parse_claim_fee_borsh(data, metadata) }
1617
1618 #[cfg(feature = "parse-zero-copy")]
1619 { parse_claim_fee_zero_copy(data, metadata) }
1620 }
1621
1622 #[cfg(feature = "parse-borsh")]
1624 #[inline(always)]
1625 fn parse_claim_fee_borsh(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1626 const CLAIM_FEE_EVENT_SIZE: usize = 32 + 32 + 32 + 8 + 8;
1628 if data.len() < CLAIM_FEE_EVENT_SIZE { return None; }
1629
1630 let mut event = borsh::from_slice::<MeteoraDlmmClaimFeeEvent>(&data[..CLAIM_FEE_EVENT_SIZE]).ok()?;
1631 event.metadata = metadata;
1632 Some(DexEvent::MeteoraDlmmClaimFee(event))
1633 }
1634
1635 #[cfg(feature = "parse-zero-copy")]
1637 #[inline(always)]
1638 fn parse_claim_fee_zero_copy(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
1639 unsafe {
1640 if !check_length(data, 32 + 32 + 32 + 8 + 8) { return None; }
1641 let pool = read_pubkey_unchecked(data, 0);
1642 let position = read_pubkey_unchecked(data, 32);
1643 let owner = read_pubkey_unchecked(data, 64);
1644 let fee_x = read_u64_unchecked(data, 96);
1645 let fee_y = read_u64_unchecked(data, 104);
1646 Some(DexEvent::MeteoraDlmmClaimFee(MeteoraDlmmClaimFeeEvent {
1647 metadata, pool, position, owner, fee_x, fee_y,
1648 }))
1649 }
1650 }
1651}