1use super::utils::*;
6use crate::core::events::*;
7use solana_sdk::{pubkey::Pubkey, signature::Signature};
8
9pub mod discriminators {
11 pub const SWAP_BASE_IN_EVENT: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 9];
13 pub const SWAP_BASE_OUT_EVENT: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 11];
14 pub const DEPOSIT_EVENT: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 3];
15 pub const WITHDRAW_EVENT: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 4];
16 pub const INITIALIZE2_EVENT: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 1];
17 pub const WITHDRAW_PNL_EVENT: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 7];
18}
19
20pub const PROGRAM_ID: &str = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8";
22
23#[inline]
25pub fn parse_ray_log_swap(log: &str, metadata: EventMetadata) -> Option<DexEvent> {
26 const PREFIX: &str = "ray_log: ";
27 let start = log.find(PREFIX)? + PREFIX.len();
28 let data = base64_simd::STANDARD.decode_to_vec(log[start..].trim().as_bytes()).ok()?;
29 if data.len() != 57 || !matches!(data[0], 3 | 4) {
30 return None;
31 }
32 let first = read_u64_le(&data, 1)?;
33 let second = read_u64_le(&data, 9)?;
34 let actual = read_u64_le(&data, 49)?;
35 let (amount_in, minimum_amount_out, max_amount_in, amount_out) =
36 if data[0] == 3 { (first, second, 0, actual) } else { (actual, 0, first, second) };
37
38 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
39 metadata,
40 amount_in,
41 minimum_amount_out,
42 max_amount_in,
43 amount_out,
44 token_program: Pubkey::default(),
45 amm: Pubkey::default(),
46 amm_authority: Pubkey::default(),
47 amm_open_orders: Pubkey::default(),
48 amm_target_orders: None,
49 pool_coin_token_account: Pubkey::default(),
50 pool_pc_token_account: Pubkey::default(),
51 serum_program: Pubkey::default(),
52 serum_market: Pubkey::default(),
53 serum_bids: Pubkey::default(),
54 serum_asks: Pubkey::default(),
55 serum_event_queue: Pubkey::default(),
56 serum_coin_vault_account: Pubkey::default(),
57 serum_pc_vault_account: Pubkey::default(),
58 serum_vault_signer: Pubkey::default(),
59 user_source_token_account: Pubkey::default(),
60 user_destination_token_account: Pubkey::default(),
61 user_source_owner: Pubkey::default(),
62 }))
63}
64
65#[inline]
67pub fn parse_log(
68 log: &str,
69 signature: Signature,
70 slot: u64,
71 tx_index: u64,
72 block_time_us: Option<i64>,
73 grpc_recv_us: i64,
74) -> Option<DexEvent> {
75 parse_structured_log(log, signature, slot, tx_index, block_time_us, grpc_recv_us)
76}
77
78fn parse_structured_log(
80 log: &str,
81 signature: Signature,
82 slot: u64,
83 tx_index: u64,
84 block_time_us: Option<i64>,
85 grpc_recv_us: i64,
86) -> Option<DexEvent> {
87 let program_data = extract_program_data(log)?;
88 if program_data.len() < 8 {
89 return None;
90 }
91
92 let discriminator: [u8; 8] = program_data[0..8].try_into().ok()?;
93 let data = &program_data[8..];
94
95 match discriminator {
96 discriminators::SWAP_BASE_IN_EVENT => {
97 parse_swap_base_in_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
98 }
99 discriminators::SWAP_BASE_OUT_EVENT => {
100 parse_swap_base_out_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
101 }
102 discriminators::DEPOSIT_EVENT => {
103 parse_deposit_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
104 }
105 discriminators::WITHDRAW_EVENT => {
106 parse_withdraw_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
107 }
108 discriminators::INITIALIZE2_EVENT => {
109 parse_initialize2_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
110 }
111 discriminators::WITHDRAW_PNL_EVENT => {
112 parse_withdraw_pnl_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
113 }
114 _ => None,
115 }
116}
117
118#[inline(always)]
124pub fn parse_swap_base_in_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
125 let mut offset = 0;
126
127 let amm = read_pubkey(data, offset)?;
128 offset += 32;
129
130 let user = read_pubkey(data, offset)?;
131 offset += 32;
132
133 let amount_in = read_u64_le(data, offset)?;
134 offset += 8;
135
136 let minimum_amount_out = read_u64_le(data, offset)?;
137
138 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
139 metadata,
140 amount_in,
141 minimum_amount_out,
142 max_amount_in: 0,
143 amount_out: 0,
144 token_program: Pubkey::default(),
145 amm,
146 amm_authority: Pubkey::default(),
147 amm_open_orders: Pubkey::default(),
148 amm_target_orders: None,
149 pool_coin_token_account: Pubkey::default(),
150 pool_pc_token_account: Pubkey::default(),
151 serum_program: Pubkey::default(),
152 serum_market: Pubkey::default(),
153 serum_bids: Pubkey::default(),
154 serum_asks: Pubkey::default(),
155 serum_event_queue: Pubkey::default(),
156 serum_coin_vault_account: Pubkey::default(),
157 serum_pc_vault_account: Pubkey::default(),
158 serum_vault_signer: Pubkey::default(),
159 user_source_token_account: Pubkey::default(),
160 user_destination_token_account: Pubkey::default(),
161 user_source_owner: user,
162 }))
163}
164
165#[inline(always)]
167pub fn parse_swap_base_out_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
168 let mut offset = 0;
169
170 let amm = read_pubkey(data, offset)?;
171 offset += 32;
172
173 let user = read_pubkey(data, offset)?;
174 offset += 32;
175
176 let max_amount_in = read_u64_le(data, offset)?;
177 offset += 8;
178
179 let amount_out = read_u64_le(data, offset)?;
180
181 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
182 metadata,
183 amount_in: 0,
184 minimum_amount_out: 0,
185 max_amount_in,
186 amount_out,
187 token_program: Pubkey::default(),
188 amm,
189 amm_authority: Pubkey::default(),
190 amm_open_orders: Pubkey::default(),
191 amm_target_orders: None,
192 pool_coin_token_account: Pubkey::default(),
193 pool_pc_token_account: Pubkey::default(),
194 serum_program: Pubkey::default(),
195 serum_market: Pubkey::default(),
196 serum_bids: Pubkey::default(),
197 serum_asks: Pubkey::default(),
198 serum_event_queue: Pubkey::default(),
199 serum_coin_vault_account: Pubkey::default(),
200 serum_pc_vault_account: Pubkey::default(),
201 serum_vault_signer: Pubkey::default(),
202 user_source_token_account: Pubkey::default(),
203 user_destination_token_account: Pubkey::default(),
204 user_source_owner: user,
205 }))
206}
207
208#[inline(always)]
210pub fn parse_deposit_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
211 let mut offset = 0;
212
213 let amm = read_pubkey(data, offset)?;
214 offset += 32;
215
216 let user = read_pubkey(data, offset)?;
217 offset += 32;
218
219 let max_coin_amount = read_u64_le(data, offset)?;
220 offset += 8;
221
222 let max_pc_amount = read_u64_le(data, offset)?;
223 offset += 8;
224
225 let base_side = read_u64_le(data, offset)?;
226
227 Some(DexEvent::RaydiumAmmV4Deposit(RaydiumAmmV4DepositEvent {
228 metadata,
229 max_coin_amount,
230 max_pc_amount,
231 base_side,
232 token_program: Pubkey::default(),
233 amm,
234 amm_authority: Pubkey::default(),
235 amm_open_orders: Pubkey::default(),
236 amm_target_orders: Pubkey::default(),
237 lp_mint_address: Pubkey::default(),
238 pool_coin_token_account: Pubkey::default(),
239 pool_pc_token_account: Pubkey::default(),
240 serum_market: Pubkey::default(),
241 user_coin_token_account: Pubkey::default(),
242 user_pc_token_account: Pubkey::default(),
243 user_lp_token_account: Pubkey::default(),
244 user_owner: user,
245 serum_event_queue: Pubkey::default(),
246 }))
247}
248
249#[inline(always)]
251pub fn parse_withdraw_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
252 let mut offset = 0;
253
254 let amm = read_pubkey(data, offset)?;
255 offset += 32;
256
257 let user = read_pubkey(data, offset)?;
258 offset += 32;
259
260 let amount = read_u64_le(data, offset)?;
261
262 Some(DexEvent::RaydiumAmmV4Withdraw(RaydiumAmmV4WithdrawEvent {
263 metadata,
264 amount,
265 token_program: Pubkey::default(),
266 amm,
267 amm_authority: Pubkey::default(),
268 amm_open_orders: Pubkey::default(),
269 amm_target_orders: Pubkey::default(),
270 lp_mint_address: Pubkey::default(),
271 pool_coin_token_account: Pubkey::default(),
272 pool_pc_token_account: Pubkey::default(),
273 pool_withdraw_queue: Pubkey::default(),
274 pool_temp_lp_token_account: Pubkey::default(),
275 serum_program: Pubkey::default(),
276 serum_market: Pubkey::default(),
277 serum_coin_vault_account: Pubkey::default(),
278 serum_pc_vault_account: Pubkey::default(),
279 serum_vault_signer: Pubkey::default(),
280 user_lp_token_account: Pubkey::default(),
281 user_coin_token_account: Pubkey::default(),
282 user_pc_token_account: Pubkey::default(),
283 user_owner: user,
284 serum_event_queue: Pubkey::default(),
285 serum_bids: Pubkey::default(),
286 serum_asks: Pubkey::default(),
287 }))
288}
289
290#[inline(always)]
292pub fn parse_initialize2_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
293 let mut offset = 0;
294
295 let amm = read_pubkey(data, offset)?;
296 offset += 32;
297
298 let user = read_pubkey(data, offset)?;
299 offset += 32;
300
301 let nonce = *data.get(offset)?;
302 offset += 1;
303
304 let open_time = read_u64_le(data, offset)?;
305 offset += 8;
306
307 let init_pc_amount = read_u64_le(data, offset)?;
308 offset += 8;
309
310 let init_coin_amount = read_u64_le(data, offset)?;
311
312 Some(DexEvent::RaydiumAmmV4Initialize2(RaydiumAmmV4Initialize2Event {
313 metadata,
314 nonce,
315 open_time,
316 init_pc_amount,
317 init_coin_amount,
318 token_program: Pubkey::default(),
319 spl_associated_token_account: Pubkey::default(),
320 system_program: Pubkey::default(),
321 rent: Pubkey::default(),
322 amm,
323 amm_authority: Pubkey::default(),
324 amm_open_orders: Pubkey::default(),
325 lp_mint: Pubkey::default(),
326 coin_mint: Pubkey::default(),
327 pc_mint: Pubkey::default(),
328 pool_coin_token_account: Pubkey::default(),
329 pool_pc_token_account: Pubkey::default(),
330 pool_withdraw_queue: Pubkey::default(),
331 amm_target_orders: Pubkey::default(),
332 pool_temp_lp: Pubkey::default(),
333 serum_program: Pubkey::default(),
334 serum_market: Pubkey::default(),
335 user_wallet: user,
336 user_token_coin: Pubkey::default(),
337 user_token_pc: Pubkey::default(),
338 user_lp_token_account: Pubkey::default(),
339 }))
340}
341
342#[inline(always)]
344pub fn parse_withdraw_pnl_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
345 let mut offset = 0;
346
347 let amm = read_pubkey(data, offset)?;
348 offset += 32;
349
350 let pnl_owner = read_pubkey(data, offset)?;
351
352 Some(DexEvent::RaydiumAmmV4WithdrawPnl(RaydiumAmmV4WithdrawPnlEvent {
353 metadata,
354 token_program: Pubkey::default(),
355 amm,
356 amm_config: Pubkey::default(),
357 amm_authority: Pubkey::default(),
358 amm_open_orders: Pubkey::default(),
359 pool_coin_token_account: Pubkey::default(),
360 pool_pc_token_account: Pubkey::default(),
361 coin_pnl_token_account: Pubkey::default(),
362 pc_pnl_token_account: Pubkey::default(),
363 pnl_owner,
364 amm_target_orders: Pubkey::default(),
365 serum_program: Pubkey::default(),
366 serum_market: Pubkey::default(),
367 serum_event_queue: Pubkey::default(),
368 serum_coin_vault_account: Pubkey::default(),
369 serum_pc_vault_account: Pubkey::default(),
370 serum_vault_signer: Pubkey::default(),
371 }))
372}
373
374fn parse_swap_base_in_event(
376 data: &[u8],
377 signature: Signature,
378 slot: u64,
379 tx_index: u64,
380 block_time_us: Option<i64>,
381 grpc_recv_us: i64,
382) -> Option<DexEvent> {
383 let mut offset = 0;
384
385 let amm = read_pubkey(data, offset)?;
386 offset += 32;
387
388 let user = read_pubkey(data, offset)?;
389 offset += 32;
390
391 let amount_in = read_u64_le(data, offset)?;
392 offset += 8;
393
394 let minimum_amount_out = read_u64_le(data, offset)?;
395
396 let metadata =
397 create_metadata_simple(signature, slot, tx_index, block_time_us, amm, grpc_recv_us);
398
399 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
400 metadata,
401 amount_in,
402 minimum_amount_out,
403 max_amount_in: 0,
404 amount_out: 0,
405 token_program: Pubkey::default(),
406 amm,
407 amm_authority: Pubkey::default(),
408 amm_open_orders: Pubkey::default(),
409 amm_target_orders: None,
410 pool_coin_token_account: Pubkey::default(),
411 pool_pc_token_account: Pubkey::default(),
412 serum_program: Pubkey::default(),
413 serum_market: Pubkey::default(),
414 serum_bids: Pubkey::default(),
415 serum_asks: Pubkey::default(),
416 serum_event_queue: Pubkey::default(),
417 serum_coin_vault_account: Pubkey::default(),
418 serum_pc_vault_account: Pubkey::default(),
419 serum_vault_signer: Pubkey::default(),
420 user_source_token_account: Pubkey::default(),
421 user_destination_token_account: Pubkey::default(),
422 user_source_owner: user,
423 }))
424}
425
426fn parse_swap_base_out_event(
428 data: &[u8],
429 signature: Signature,
430 slot: u64,
431 tx_index: u64,
432 block_time_us: Option<i64>,
433 grpc_recv_us: i64,
434) -> Option<DexEvent> {
435 let mut offset = 0;
436
437 let amm = read_pubkey(data, offset)?;
438 offset += 32;
439
440 let user = read_pubkey(data, offset)?;
441 offset += 32;
442
443 let max_amount_in = read_u64_le(data, offset)?;
444 offset += 8;
445
446 let amount_out = read_u64_le(data, offset)?;
447
448 let metadata =
449 create_metadata_simple(signature, slot, tx_index, block_time_us, amm, grpc_recv_us);
450
451 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
452 metadata,
453 amount_in: 0,
454 minimum_amount_out: 0,
455 max_amount_in,
456 amount_out,
457 token_program: Pubkey::default(),
458 amm,
459 amm_authority: Pubkey::default(),
460 amm_open_orders: Pubkey::default(),
461 amm_target_orders: None,
462 pool_coin_token_account: Pubkey::default(),
463 pool_pc_token_account: Pubkey::default(),
464 serum_program: Pubkey::default(),
465 serum_market: Pubkey::default(),
466 serum_bids: Pubkey::default(),
467 serum_asks: Pubkey::default(),
468 serum_event_queue: Pubkey::default(),
469 serum_coin_vault_account: Pubkey::default(),
470 serum_pc_vault_account: Pubkey::default(),
471 serum_vault_signer: Pubkey::default(),
472 user_source_token_account: Pubkey::default(),
473 user_destination_token_account: Pubkey::default(),
474 user_source_owner: user,
475 }))
476}
477
478fn parse_deposit_event(
480 data: &[u8],
481 signature: Signature,
482 slot: u64,
483 tx_index: u64,
484 block_time_us: Option<i64>,
485 grpc_recv_us: i64,
486) -> Option<DexEvent> {
487 let mut offset = 0;
488
489 let amm = read_pubkey(data, offset)?;
490 offset += 32;
491
492 let user = read_pubkey(data, offset)?;
493 offset += 32;
494
495 let max_coin_amount = read_u64_le(data, offset)?;
496 offset += 8;
497
498 let max_pc_amount = read_u64_le(data, offset)?;
499 offset += 8;
500
501 let base_side = read_u64_le(data, offset)?;
502
503 let metadata =
504 create_metadata_simple(signature, slot, tx_index, block_time_us, amm, grpc_recv_us);
505
506 Some(DexEvent::RaydiumAmmV4Deposit(RaydiumAmmV4DepositEvent {
507 metadata,
508 max_coin_amount,
509 max_pc_amount,
510 base_side,
511 token_program: Pubkey::default(),
512 amm,
513 amm_authority: Pubkey::default(),
514 amm_open_orders: Pubkey::default(),
515 amm_target_orders: Pubkey::default(),
516 lp_mint_address: Pubkey::default(),
517 pool_coin_token_account: Pubkey::default(),
518 pool_pc_token_account: Pubkey::default(),
519 serum_market: Pubkey::default(),
520 user_coin_token_account: Pubkey::default(),
521 user_pc_token_account: Pubkey::default(),
522 user_lp_token_account: Pubkey::default(),
523 user_owner: user,
524 serum_event_queue: Pubkey::default(),
525 }))
526}
527
528fn parse_withdraw_event(
530 data: &[u8],
531 signature: Signature,
532 slot: u64,
533 tx_index: u64,
534 block_time_us: Option<i64>,
535 grpc_recv_us: i64,
536) -> Option<DexEvent> {
537 let mut offset = 0;
538
539 let amm = read_pubkey(data, offset)?;
540 offset += 32;
541
542 let user = read_pubkey(data, offset)?;
543 offset += 32;
544
545 let amount = read_u64_le(data, offset)?;
546
547 let metadata =
548 create_metadata_simple(signature, slot, tx_index, block_time_us, amm, grpc_recv_us);
549
550 Some(DexEvent::RaydiumAmmV4Withdraw(RaydiumAmmV4WithdrawEvent {
551 metadata,
552 amount,
553 token_program: Pubkey::default(),
554 amm,
555 amm_authority: Pubkey::default(),
556 amm_open_orders: Pubkey::default(),
557 amm_target_orders: Pubkey::default(),
558 lp_mint_address: Pubkey::default(),
559 pool_coin_token_account: Pubkey::default(),
560 pool_pc_token_account: Pubkey::default(),
561 pool_withdraw_queue: Pubkey::default(),
562 pool_temp_lp_token_account: Pubkey::default(),
563 serum_program: Pubkey::default(),
564 serum_market: Pubkey::default(),
565 serum_coin_vault_account: Pubkey::default(),
566 serum_pc_vault_account: Pubkey::default(),
567 serum_vault_signer: Pubkey::default(),
568 user_lp_token_account: Pubkey::default(),
569 user_coin_token_account: Pubkey::default(),
570 user_pc_token_account: Pubkey::default(),
571 user_owner: user,
572 serum_event_queue: Pubkey::default(),
573 serum_bids: Pubkey::default(),
574 serum_asks: Pubkey::default(),
575 }))
576}
577
578fn parse_initialize2_event(
580 data: &[u8],
581 signature: Signature,
582 slot: u64,
583 tx_index: u64,
584 block_time_us: Option<i64>,
585 grpc_recv_us: i64,
586) -> Option<DexEvent> {
587 let mut offset = 0;
588
589 let amm = read_pubkey(data, offset)?;
590 offset += 32;
591
592 let user = read_pubkey(data, offset)?;
593 offset += 32;
594
595 let nonce = *data.get(offset)?;
596 offset += 1;
597
598 let open_time = read_u64_le(data, offset)?;
599 offset += 8;
600
601 let init_pc_amount = read_u64_le(data, offset)?;
602 offset += 8;
603
604 let init_coin_amount = read_u64_le(data, offset)?;
605
606 let metadata =
607 create_metadata_simple(signature, slot, tx_index, block_time_us, amm, grpc_recv_us);
608
609 Some(DexEvent::RaydiumAmmV4Initialize2(RaydiumAmmV4Initialize2Event {
610 metadata,
611 nonce,
612 open_time,
613 init_pc_amount,
614 init_coin_amount,
615 token_program: Pubkey::default(),
616 spl_associated_token_account: Pubkey::default(),
617 system_program: Pubkey::default(),
618 rent: Pubkey::default(),
619 amm,
620 amm_authority: Pubkey::default(),
621 amm_open_orders: Pubkey::default(),
622 lp_mint: Pubkey::default(),
623 coin_mint: Pubkey::default(),
624 pc_mint: Pubkey::default(),
625 pool_coin_token_account: Pubkey::default(),
626 pool_pc_token_account: Pubkey::default(),
627 pool_withdraw_queue: Pubkey::default(),
628 amm_target_orders: Pubkey::default(),
629 pool_temp_lp: Pubkey::default(),
630 serum_program: Pubkey::default(),
631 serum_market: Pubkey::default(),
632 user_wallet: user,
633 user_token_coin: Pubkey::default(),
634 user_token_pc: Pubkey::default(),
635 user_lp_token_account: Pubkey::default(),
636 }))
637}
638
639fn parse_withdraw_pnl_event(
641 data: &[u8],
642 signature: Signature,
643 slot: u64,
644 tx_index: u64,
645 block_time_us: Option<i64>,
646 grpc_recv_us: i64,
647) -> Option<DexEvent> {
648 let mut offset = 0;
649
650 let amm = read_pubkey(data, offset)?;
651 offset += 32;
652
653 let pnl_owner = read_pubkey(data, offset)?;
654
655 let metadata =
656 create_metadata_simple(signature, slot, tx_index, block_time_us, amm, grpc_recv_us);
657
658 Some(DexEvent::RaydiumAmmV4WithdrawPnl(RaydiumAmmV4WithdrawPnlEvent {
659 metadata,
660 token_program: Pubkey::default(),
661 amm,
662 amm_config: Pubkey::default(),
663 amm_authority: Pubkey::default(),
664 amm_open_orders: Pubkey::default(),
665 pool_coin_token_account: Pubkey::default(),
666 pool_pc_token_account: Pubkey::default(),
667 coin_pnl_token_account: Pubkey::default(),
668 pc_pnl_token_account: Pubkey::default(),
669 pnl_owner,
670 amm_target_orders: Pubkey::default(),
671 serum_program: Pubkey::default(),
672 serum_market: Pubkey::default(),
673 serum_event_queue: Pubkey::default(),
674 serum_coin_vault_account: Pubkey::default(),
675 serum_pc_vault_account: Pubkey::default(),
676 serum_vault_signer: Pubkey::default(),
677 }))
678}
679
680fn parse_text_log(
682 log: &str,
683 signature: Signature,
684 slot: u64,
685 tx_index: u64,
686 block_time_us: Option<i64>,
687 grpc_recv_us: i64,
688) -> Option<DexEvent> {
689 if log.contains("swap") || log.contains("Swap") {
691 return parse_swap_log_fallback(
692 log,
693 signature,
694 slot,
695 tx_index,
696 block_time_us,
697 grpc_recv_us,
698 );
699 }
700
701 if log.contains("deposit") || log.contains("Deposit") {
703 return parse_deposit_log_fallback(
704 log,
705 signature,
706 slot,
707 tx_index,
708 block_time_us,
709 grpc_recv_us,
710 );
711 }
712
713 if log.contains("withdraw") || log.contains("Withdraw") {
715 return parse_withdraw_log_fallback(
716 log,
717 signature,
718 slot,
719 tx_index,
720 block_time_us,
721 grpc_recv_us,
722 );
723 }
724
725 None
726}
727
728fn parse_swap_log_fallback(
730 log: &str,
731 signature: Signature,
732 slot: u64,
733 tx_index: u64,
734 block_time_us: Option<i64>,
735 grpc_recv_us: i64,
736) -> Option<DexEvent> {
737 let amount_in = super::utils::text_parser::extract_number_from_text(log, "amount_in")
739 .or_else(|| super::utils::text_parser::extract_number_from_text(log, "amountIn"))
740 .unwrap_or(0);
741
742 let amount_out = super::utils::text_parser::extract_number_from_text(log, "amount_out")
743 .or_else(|| super::utils::text_parser::extract_number_from_text(log, "amountOut"))
744 .unwrap_or(0);
745
746 let minimum_amount_out =
747 super::utils::text_parser::extract_number_from_text(log, "minimum_amount_out")
748 .or_else(|| {
749 super::utils::text_parser::extract_number_from_text(log, "minimumAmountOut")
750 })
751 .unwrap_or(0);
752
753 let max_amount_in = super::utils::text_parser::extract_number_from_text(log, "max_amount_in")
754 .or_else(|| super::utils::text_parser::extract_number_from_text(log, "maxAmountIn"))
755 .unwrap_or(0);
756
757 let default_pubkey = Pubkey::default();
758 let metadata = create_metadata_simple(
759 signature,
760 slot,
761 tx_index,
762 block_time_us,
763 default_pubkey,
764 grpc_recv_us,
765 );
766
767 Some(DexEvent::RaydiumAmmV4Swap(RaydiumAmmV4SwapEvent {
768 metadata,
769 amount_in,
770 minimum_amount_out,
771 max_amount_in,
772 amount_out,
773 token_program: default_pubkey,
774 amm: default_pubkey,
775 amm_authority: default_pubkey,
776 amm_open_orders: default_pubkey,
777 amm_target_orders: None,
778 pool_coin_token_account: default_pubkey,
779 pool_pc_token_account: default_pubkey,
780 serum_program: default_pubkey,
781 serum_market: default_pubkey,
782 serum_bids: default_pubkey,
783 serum_asks: default_pubkey,
784 serum_event_queue: default_pubkey,
785 serum_coin_vault_account: default_pubkey,
786 serum_pc_vault_account: default_pubkey,
787 serum_vault_signer: default_pubkey,
788 user_source_token_account: default_pubkey,
789 user_destination_token_account: default_pubkey,
790 user_source_owner: default_pubkey,
791 }))
792}
793
794fn parse_deposit_log_fallback(
796 log: &str,
797 signature: Signature,
798 slot: u64,
799 tx_index: u64,
800 block_time_us: Option<i64>,
801 grpc_recv_us: i64,
802) -> Option<DexEvent> {
803 let max_coin_amount =
804 super::utils::text_parser::extract_number_from_text(log, "max_coin_amount")
805 .or_else(|| super::utils::text_parser::extract_number_from_text(log, "maxCoinAmount"))
806 .unwrap_or(0);
807
808 let max_pc_amount = super::utils::text_parser::extract_number_from_text(log, "max_pc_amount")
809 .or_else(|| super::utils::text_parser::extract_number_from_text(log, "maxPcAmount"))
810 .unwrap_or(0);
811
812 let base_side = super::utils::text_parser::extract_number_from_text(log, "base_side")
813 .or_else(|| super::utils::text_parser::extract_number_from_text(log, "baseSide"))
814 .unwrap_or(0);
815
816 let default_pubkey = Pubkey::default();
817 let metadata = create_metadata_simple(
818 signature,
819 slot,
820 tx_index,
821 block_time_us,
822 default_pubkey,
823 grpc_recv_us,
824 );
825
826 Some(DexEvent::RaydiumAmmV4Deposit(RaydiumAmmV4DepositEvent {
827 metadata,
828 max_coin_amount,
829 max_pc_amount,
830 base_side,
831 token_program: default_pubkey,
832 amm: default_pubkey,
833 amm_authority: default_pubkey,
834 amm_open_orders: default_pubkey,
835 amm_target_orders: default_pubkey,
836 lp_mint_address: default_pubkey,
837 pool_coin_token_account: default_pubkey,
838 pool_pc_token_account: default_pubkey,
839 serum_market: default_pubkey,
840 user_coin_token_account: default_pubkey,
841 user_pc_token_account: default_pubkey,
842 user_lp_token_account: default_pubkey,
843 user_owner: default_pubkey,
844 serum_event_queue: default_pubkey,
845 }))
846}
847
848fn parse_withdraw_log_fallback(
850 log: &str,
851 signature: Signature,
852 slot: u64,
853 tx_index: u64,
854 block_time_us: Option<i64>,
855 grpc_recv_us: i64,
856) -> Option<DexEvent> {
857 let amount = super::utils::text_parser::extract_number_from_text(log, "amount").unwrap_or(0);
858
859 let default_pubkey = Pubkey::default();
860 let metadata = create_metadata_simple(
861 signature,
862 slot,
863 tx_index,
864 block_time_us,
865 default_pubkey,
866 grpc_recv_us,
867 );
868
869 Some(DexEvent::RaydiumAmmV4Withdraw(RaydiumAmmV4WithdrawEvent {
870 metadata,
871 amount,
872 token_program: default_pubkey,
873 amm: default_pubkey,
874 amm_authority: default_pubkey,
875 amm_open_orders: default_pubkey,
876 amm_target_orders: default_pubkey,
877 lp_mint_address: default_pubkey,
878 pool_coin_token_account: default_pubkey,
879 pool_pc_token_account: default_pubkey,
880 pool_withdraw_queue: default_pubkey,
881 pool_temp_lp_token_account: default_pubkey,
882 serum_program: default_pubkey,
883 serum_market: default_pubkey,
884 serum_coin_vault_account: default_pubkey,
885 serum_pc_vault_account: default_pubkey,
886 serum_vault_signer: default_pubkey,
887 user_lp_token_account: default_pubkey,
888 user_coin_token_account: default_pubkey,
889 user_pc_token_account: default_pubkey,
890 user_owner: default_pubkey,
891 serum_event_queue: default_pubkey,
892 serum_bids: default_pubkey,
893 serum_asks: default_pubkey,
894 }))
895}