sol_parser_sdk/instr/
utils.rs1use solana_sdk::{pubkey::Pubkey, signature::Signature};
4use crate::core::events::EventMetadata;
5
6pub fn create_metadata(
8 signature: Signature,
9 slot: u64,
10 tx_index: u64,
11 block_time_us: i64,
12 grpc_recv_us: i64,
13) -> EventMetadata {
14 EventMetadata {
15 signature,
16 slot,
17 tx_index,
18 block_time_us,
19 grpc_recv_us,
20 }
21}
22
23#[inline(always)]
25pub fn create_metadata_simple(
26 signature: Signature,
27 slot: u64,
28 tx_index: u64,
29 block_time: Option<i64>,
30 _program_id: Pubkey,
31) -> EventMetadata {
32 let current_time = unsafe {
34 let mut ts = libc::timespec {
35 tv_sec: 0,
36 tv_nsec: 0,
37 };
38 #[cfg(target_os = "linux")]
39 libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, &mut ts);
40 #[cfg(not(target_os = "linux"))]
41 libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts);
42 (ts.tv_sec as i64 * 1_000_000) + (ts.tv_nsec as i64 / 1_000)
43 };
44
45 EventMetadata {
46 signature,
47 slot,
48 tx_index,
49 block_time_us: block_time.map_or(0, |t| t * 1_000_000),
50 grpc_recv_us: current_time,
51 }
52}
53
54#[inline(always)]
56pub fn read_u64_le(data: &[u8], offset: usize) -> Option<u64> {
57 data.get(offset..offset + 8)
58 .map(|slice| u64::from_le_bytes(slice.try_into().unwrap()))
59}
60
61#[inline(always)]
63pub fn read_u32_le(data: &[u8], offset: usize) -> Option<u32> {
64 data.get(offset..offset + 4)
65 .map(|slice| u32::from_le_bytes(slice.try_into().unwrap()))
66}
67
68#[inline(always)]
70pub fn read_u16_le(data: &[u8], offset: usize) -> Option<u16> {
71 data.get(offset..offset + 2)
72 .map(|slice| u16::from_le_bytes(slice.try_into().unwrap()))
73}
74
75#[inline(always)]
77pub fn read_u8(data: &[u8], offset: usize) -> Option<u8> {
78 data.get(offset).copied()
79}
80
81#[inline(always)]
83pub fn read_i32_le(data: &[u8], offset: usize) -> Option<i32> {
84 data.get(offset..offset + 4)
85 .map(|slice| i32::from_le_bytes(slice.try_into().unwrap()))
86}
87
88#[inline(always)]
90pub fn read_u128_le(data: &[u8], offset: usize) -> Option<u128> {
91 data.get(offset..offset + 16)
92 .map(|slice| u128::from_le_bytes(slice.try_into().unwrap()))
93}
94
95#[inline(always)]
97pub fn read_bool(data: &[u8], offset: usize) -> Option<bool> {
98 data.get(offset).map(|&b| b != 0)
99}
100
101#[inline(always)]
103pub fn read_pubkey(data: &[u8], offset: usize) -> Option<Pubkey> {
104 data.get(offset..offset + 32)
105 .and_then(|slice| Pubkey::try_from(slice).ok())
106}
107
108#[inline(always)]
110pub fn get_account(accounts: &[Pubkey], index: usize) -> Option<Pubkey> {
111 accounts.get(index).copied()
112}
113
114pub fn calculate_slippage_bps(amount_in: u64, amount_out_min: u64) -> u16 {
116 if amount_in == 0 {
117 return 0;
118 }
119
120 let slippage = ((amount_in.saturating_sub(amount_out_min)) * 10000) / amount_in;
122 slippage.min(10000) as u16
123}
124
125pub fn calculate_price_impact_bps(amount_in: u64, amount_out: u64, expected_out: u64) -> u16 {
127 if expected_out == 0 {
128 return 0;
129 }
130
131 let impact = ((expected_out.saturating_sub(amount_out)) * 10000) / expected_out;
132 impact.min(10000) as u16
133}
134
135pub fn read_bytes(data: &[u8], offset: usize, length: usize) -> Option<&[u8]> {
137 if data.len() < offset + length {
138 return None;
139 }
140 Some(&data[offset..offset + length])
141}
142
143pub fn read_vec_u64(data: &[u8], _offset: usize) -> Option<Vec<u64>> {
145 Some(vec![0, 0])
148}