1use super::utils::*;
6use crate::core::events::*;
7use solana_sdk::pubkey::Pubkey;
8use solana_sdk::signature::Signature;
9
10pub mod discriminators {
12 pub const TRADED_EVENT: [u8; 8] = [225, 202, 73, 175, 147, 43, 160, 150];
13 pub const LIQUIDITY_INCREASED_EVENT: [u8; 8] = [30, 7, 144, 181, 102, 254, 155, 161];
14 pub const LIQUIDITY_DECREASED_EVENT: [u8; 8] = [166, 1, 36, 71, 112, 202, 181, 171];
15 pub const POOL_INITIALIZED_EVENT: [u8; 8] = [100, 118, 173, 87, 12, 198, 254, 229];
16}
17
18pub fn parse_log(
20 log: &str,
21 signature: Signature,
22 slot: u64,
23 tx_index: u64,
24 block_time_us: Option<i64>,
25 grpc_recv_us: i64,
26) -> Option<DexEvent> {
27 parse_structured_log(log, signature, slot, tx_index, block_time_us, grpc_recv_us)
28}
29
30fn parse_structured_log(
32 log: &str,
33 signature: Signature,
34 slot: u64,
35 tx_index: u64,
36 block_time_us: Option<i64>,
37 grpc_recv_us: i64,
38) -> Option<DexEvent> {
39 let program_data = extract_program_data(log)?;
40
41 if program_data.len() < 8 {
42 return None;
43 }
44
45 let discriminator: [u8; 8] = program_data[0..8].try_into().ok()?;
46 let data = &program_data[8..];
47
48 match discriminator {
49 discriminators::TRADED_EVENT => {
50 parse_traded_event(data, signature, slot, tx_index, block_time_us, grpc_recv_us)
51 }
52 discriminators::LIQUIDITY_INCREASED_EVENT => parse_liquidity_increased_event(
53 data,
54 signature,
55 slot,
56 tx_index,
57 block_time_us,
58 grpc_recv_us,
59 ),
60 discriminators::LIQUIDITY_DECREASED_EVENT => parse_liquidity_decreased_event(
61 data,
62 signature,
63 slot,
64 tx_index,
65 block_time_us,
66 grpc_recv_us,
67 ),
68 discriminators::POOL_INITIALIZED_EVENT => parse_pool_initialized_event(
69 data,
70 signature,
71 slot,
72 tx_index,
73 block_time_us,
74 grpc_recv_us,
75 ),
76 _ => None,
77 }
78}
79
80#[inline(always)]
86pub fn parse_traded_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
87 let mut offset = 0;
88
89 let whirlpool = read_pubkey(data, offset)?;
90 offset += 32;
91
92 let a_to_b = read_bool(data, offset)?;
93 offset += 1;
94
95 let pre_sqrt_price = read_u128_le(data, offset)?;
96 offset += 16;
97
98 let post_sqrt_price = read_u128_le(data, offset)?;
99 offset += 16;
100
101 let input_amount = read_u64_le(data, offset)?;
102 offset += 8;
103
104 let output_amount = read_u64_le(data, offset)?;
105 offset += 8;
106
107 let input_transfer_fee = read_u64_le(data, offset)?;
108 offset += 8;
109
110 let output_transfer_fee = read_u64_le(data, offset)?;
111 offset += 8;
112
113 let lp_fee = read_u64_le(data, offset)?;
114 offset += 8;
115
116 let protocol_fee = read_u64_le(data, offset)?;
117
118 Some(DexEvent::OrcaWhirlpoolSwap(OrcaWhirlpoolSwapEvent {
119 metadata,
120 whirlpool,
121 a_to_b,
122 pre_sqrt_price,
123 post_sqrt_price,
124 input_amount,
125 output_amount,
126 input_transfer_fee,
127 output_transfer_fee,
128 lp_fee,
129 protocol_fee,
130 }))
131}
132
133#[inline(always)]
135pub fn parse_liquidity_increased_from_data(
136 data: &[u8],
137 metadata: EventMetadata,
138) -> Option<DexEvent> {
139 let mut offset = 0;
140
141 let whirlpool = read_pubkey(data, offset)?;
142 offset += 32;
143
144 let position = read_pubkey(data, offset)?;
145 offset += 32;
146
147 let tick_lower_index = read_i32_le(data, offset)?;
148 offset += 4;
149
150 let tick_upper_index = read_i32_le(data, offset)?;
151 offset += 4;
152
153 let liquidity = read_u128_le(data, offset)?;
154 offset += 16;
155
156 let token_a_amount = read_u64_le(data, offset)?;
157 offset += 8;
158
159 let token_b_amount = read_u64_le(data, offset)?;
160 offset += 8;
161
162 let token_a_transfer_fee = read_u64_le(data, offset)?;
163 offset += 8;
164
165 let token_b_transfer_fee = read_u64_le(data, offset)?;
166
167 Some(DexEvent::OrcaWhirlpoolLiquidityIncreased(OrcaWhirlpoolLiquidityIncreasedEvent {
168 metadata,
169 whirlpool,
170 position,
171 tick_lower_index,
172 tick_upper_index,
173 liquidity,
174 token_a_amount,
175 token_b_amount,
176 token_a_transfer_fee,
177 token_b_transfer_fee,
178 }))
179}
180
181#[inline(always)]
183pub fn parse_liquidity_decreased_from_data(
184 data: &[u8],
185 metadata: EventMetadata,
186) -> Option<DexEvent> {
187 let mut offset = 0;
188
189 let whirlpool = read_pubkey(data, offset)?;
190 offset += 32;
191
192 let position = read_pubkey(data, offset)?;
193 offset += 32;
194
195 let tick_lower_index = read_i32_le(data, offset)?;
196 offset += 4;
197
198 let tick_upper_index = read_i32_le(data, offset)?;
199 offset += 4;
200
201 let liquidity = read_u128_le(data, offset)?;
202 offset += 16;
203
204 let token_a_amount = read_u64_le(data, offset)?;
205 offset += 8;
206
207 let token_b_amount = read_u64_le(data, offset)?;
208 offset += 8;
209
210 let token_a_transfer_fee = read_u64_le(data, offset)?;
211 offset += 8;
212
213 let token_b_transfer_fee = read_u64_le(data, offset)?;
214
215 Some(DexEvent::OrcaWhirlpoolLiquidityDecreased(OrcaWhirlpoolLiquidityDecreasedEvent {
216 metadata,
217 whirlpool,
218 position,
219 tick_lower_index,
220 tick_upper_index,
221 liquidity,
222 token_a_amount,
223 token_b_amount,
224 token_a_transfer_fee,
225 token_b_transfer_fee,
226 }))
227}
228
229#[inline(always)]
231pub fn parse_pool_initialized_from_data(data: &[u8], metadata: EventMetadata) -> Option<DexEvent> {
232 let mut offset = 0;
233
234 let whirlpool = read_pubkey(data, offset)?;
235 offset += 32;
236
237 let whirlpools_config = read_pubkey(data, offset)?;
238 offset += 32;
239
240 let token_mint_a = read_pubkey(data, offset)?;
241 offset += 32;
242
243 let token_mint_b = read_pubkey(data, offset)?;
244 offset += 32;
245
246 let tick_spacing = read_u16_le(data, offset)?;
247 offset += 2;
248
249 let token_program_a = read_pubkey(data, offset)?;
250 offset += 32;
251
252 let token_program_b = read_pubkey(data, offset)?;
253 offset += 32;
254
255 let decimals_a = read_u8(data, offset)?;
256 offset += 1;
257
258 let decimals_b = read_u8(data, offset)?;
259 offset += 1;
260
261 let initial_sqrt_price = read_u128_le(data, offset)?;
262
263 Some(DexEvent::OrcaWhirlpoolPoolInitialized(OrcaWhirlpoolPoolInitializedEvent {
264 metadata,
265 whirlpool,
266 whirlpools_config,
267 token_mint_a,
268 token_mint_b,
269 tick_spacing,
270 token_program_a,
271 token_program_b,
272 decimals_a,
273 decimals_b,
274 initial_sqrt_price,
275 }))
276}
277
278fn parse_traded_event(
280 data: &[u8],
281 signature: Signature,
282 slot: u64,
283 tx_index: u64,
284 block_time_us: Option<i64>,
285 grpc_recv_us: i64,
286) -> Option<DexEvent> {
287 let mut offset = 0;
288
289 let whirlpool = read_pubkey(data, offset)?;
290 offset += 32;
291
292 let a_to_b = read_bool(data, offset)?;
293 offset += 1;
294
295 let pre_sqrt_price = read_u128_le(data, offset)?;
296 offset += 16;
297
298 let post_sqrt_price = read_u128_le(data, offset)?;
299 offset += 16;
300
301 let input_amount = read_u64_le(data, offset)?;
302 offset += 8;
303
304 let output_amount = read_u64_le(data, offset)?;
305 offset += 8;
306
307 let input_transfer_fee = read_u64_le(data, offset)?;
308 offset += 8;
309
310 let output_transfer_fee = read_u64_le(data, offset)?;
311 offset += 8;
312
313 let lp_fee = read_u64_le(data, offset)?;
314 offset += 8;
315
316 let protocol_fee = read_u64_le(data, offset)?;
317
318 let metadata =
319 create_metadata_simple(signature, slot, tx_index, block_time_us, whirlpool, grpc_recv_us);
320
321 Some(DexEvent::OrcaWhirlpoolSwap(OrcaWhirlpoolSwapEvent {
322 metadata,
323
324 whirlpool,
326 a_to_b,
327 pre_sqrt_price,
328 post_sqrt_price,
329 input_amount,
330 output_amount,
331 input_transfer_fee,
332 output_transfer_fee,
333 lp_fee,
334 protocol_fee,
335 }))
352}
353
354fn parse_liquidity_increased_event(
356 data: &[u8],
357 signature: Signature,
358 slot: u64,
359 tx_index: u64,
360 block_time_us: Option<i64>,
361 grpc_recv_us: i64,
362) -> Option<DexEvent> {
363 let mut offset = 0;
364
365 let whirlpool = read_pubkey(data, offset)?;
366 offset += 32;
367
368 let position = read_pubkey(data, offset)?;
369 offset += 32;
370
371 let tick_lower_index = read_i32_le(data, offset)?;
372 offset += 4;
373
374 let tick_upper_index = read_i32_le(data, offset)?;
375 offset += 4;
376
377 let liquidity = read_u128_le(data, offset)?;
378 offset += 16;
379
380 let token_a_amount = read_u64_le(data, offset)?;
381 offset += 8;
382
383 let token_b_amount = read_u64_le(data, offset)?;
384 offset += 8;
385
386 let token_a_transfer_fee = read_u64_le(data, offset)?;
387 offset += 8;
388
389 let token_b_transfer_fee = read_u64_le(data, offset)?;
390
391 let metadata =
392 create_metadata_simple(signature, slot, tx_index, block_time_us, whirlpool, grpc_recv_us);
393
394 Some(DexEvent::OrcaWhirlpoolLiquidityIncreased(OrcaWhirlpoolLiquidityIncreasedEvent {
395 metadata,
396 whirlpool,
397 position,
398 tick_lower_index,
399 tick_upper_index,
400 liquidity,
401 token_a_amount,
402 token_b_amount,
403 token_a_transfer_fee,
404 token_b_transfer_fee,
405 }))
406}
407
408fn parse_liquidity_decreased_event(
410 data: &[u8],
411 signature: Signature,
412 slot: u64,
413 tx_index: u64,
414 block_time_us: Option<i64>,
415 grpc_recv_us: i64,
416) -> Option<DexEvent> {
417 let mut offset = 0;
418
419 let whirlpool = read_pubkey(data, offset)?;
420 offset += 32;
421
422 let position = read_pubkey(data, offset)?;
423 offset += 32;
424
425 let tick_lower_index = read_i32_le(data, offset)?;
426 offset += 4;
427
428 let tick_upper_index = read_i32_le(data, offset)?;
429 offset += 4;
430
431 let liquidity = read_u128_le(data, offset)?;
432 offset += 16;
433
434 let token_a_amount = read_u64_le(data, offset)?;
435 offset += 8;
436
437 let token_b_amount = read_u64_le(data, offset)?;
438 offset += 8;
439
440 let token_a_transfer_fee = read_u64_le(data, offset)?;
441 offset += 8;
442
443 let token_b_transfer_fee = read_u64_le(data, offset)?;
444
445 let metadata =
446 create_metadata_simple(signature, slot, tx_index, block_time_us, whirlpool, grpc_recv_us);
447
448 Some(DexEvent::OrcaWhirlpoolLiquidityDecreased(OrcaWhirlpoolLiquidityDecreasedEvent {
449 metadata,
450 whirlpool,
451 position,
452 tick_lower_index,
453 tick_upper_index,
454 liquidity,
455 token_a_amount,
456 token_b_amount,
457 token_a_transfer_fee,
458 token_b_transfer_fee,
459 }))
460}
461
462fn parse_pool_initialized_event(
464 data: &[u8],
465 signature: Signature,
466 slot: u64,
467 tx_index: u64,
468 block_time_us: Option<i64>,
469 grpc_recv_us: i64,
470) -> Option<DexEvent> {
471 let mut offset = 0;
472
473 let whirlpool = read_pubkey(data, offset)?;
474 offset += 32;
475
476 let whirlpools_config = read_pubkey(data, offset)?;
477 offset += 32;
478
479 let token_mint_a = read_pubkey(data, offset)?;
480 offset += 32;
481
482 let token_mint_b = read_pubkey(data, offset)?;
483 offset += 32;
484
485 let tick_spacing = read_u16_le(data, offset)?;
486 offset += 2;
487
488 let token_program_a = read_pubkey(data, offset)?;
489 offset += 32;
490
491 let token_program_b = read_pubkey(data, offset)?;
492 offset += 32;
493
494 let decimals_a = read_u8(data, offset)?;
495 offset += 1;
496
497 let decimals_b = read_u8(data, offset)?;
498 offset += 1;
499
500 let initial_sqrt_price = read_u128_le(data, offset)?;
501
502 let metadata =
503 create_metadata_simple(signature, slot, tx_index, block_time_us, whirlpool, grpc_recv_us);
504
505 Some(DexEvent::OrcaWhirlpoolPoolInitialized(OrcaWhirlpoolPoolInitializedEvent {
506 metadata,
507 whirlpool,
508 whirlpools_config,
509 token_mint_a,
510 token_mint_b,
511 tick_spacing,
512 token_program_a,
513 token_program_b,
514 decimals_a,
515 decimals_b,
516 initial_sqrt_price,
517 }))
518}
519
520fn parse_text_log(
522 _log: &str,
523 _signature: Signature,
524 _slot: u64,
525 _block_time_us: Option<i64>,
526) -> Option<DexEvent> {
527 None
529}