Skip to main content

sol_parser_sdk/instr/
mod.rs

1//! 指令解析器模块
2//!
3//! 包含所有 DEX 协议的指令解析器实现
4
5pub mod meteora_amm;
6pub mod meteora_damm;
7pub mod meteora_dlmm;
8pub mod orca_whirlpool;
9pub mod program_ids;
10pub mod pump;
11pub mod pump_amm;
12pub mod pump_fees;
13pub mod raydium_amm;
14pub mod raydium_clmm;
15pub mod raydium_cpmm;
16pub mod raydium_launchpad;
17pub mod utils;
18
19// Inner instruction 解析器(16字节 discriminator)
20pub mod all_inner;
21pub mod inner_common; // 通用零拷贝读取函数
22pub mod pump_amm_inner; // PumpSwap inner instruction
23pub mod pump_inner; // PumpFun inner instruction
24pub mod raydium_clmm_inner; // Raydium CLMM inner instruction // 其他所有协议的 inner instruction(统一文件)
25use crate::grpc::types::EventTypeFilter;
26// 重新导出主要解析函数
27pub use meteora_damm::parse_instruction as parse_meteora_damm_instruction;
28pub use pump::parse_instruction as parse_pumpfun_instruction;
29pub use pump_amm::parse_instruction as parse_pumpswap_instruction;
30pub use raydium_launchpad::parse_instruction as parse_raydium_launchpad_instruction;
31
32// 重新导出工具函数
33pub use utils::*;
34
35use crate::core::events::DexEvent;
36use program_ids::*;
37use solana_sdk::{pubkey::Pubkey, signature::Signature};
38
39#[inline(always)]
40fn filter_parsed_event(
41    event: Option<DexEvent>,
42    event_type_filter: Option<&EventTypeFilter>,
43) -> Option<DexEvent> {
44    let event = event?;
45    if event_type_filter.map(|f| f.should_include_dex_event(&event)).unwrap_or(true) {
46        Some(event)
47    } else {
48        None
49    }
50}
51
52/// 统一的指令解析入口函数
53#[inline]
54pub fn parse_instruction_unified(
55    instruction_data: &[u8],
56    accounts: &[Pubkey],
57    signature: Signature,
58    slot: u64,
59    tx_index: u64,
60    block_time_us: Option<i64>,
61    grpc_recv_us: i64,
62    event_type_filter: Option<&EventTypeFilter>,
63    program_id: &Pubkey,
64) -> Option<DexEvent> {
65    // 快速检查指令数据长度,避免无效解析
66    if instruction_data.is_empty() {
67        return None;
68    }
69
70    // 根据程序 ID 路由到相应的解析器,按使用频率排序
71
72    // Pumpfun
73    if *program_id == PUMPFUN_PROGRAM_ID {
74        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_pumpfun() {
75            return None;
76        }
77        return filter_parsed_event(
78            parse_pumpfun_instruction(
79                instruction_data,
80                accounts,
81                signature,
82                slot,
83                tx_index,
84                block_time_us,
85                grpc_recv_us,
86            ),
87            event_type_filter,
88        );
89    }
90    // PumpSwap (Pump AMM)
91    else if *program_id == PUMPSWAP_PROGRAM_ID {
92        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_pumpswap() {
93            return None;
94        }
95        return filter_parsed_event(
96            parse_pumpswap_instruction(
97                instruction_data,
98                accounts,
99                signature,
100                slot,
101                tx_index,
102                block_time_us,
103            ),
104            event_type_filter,
105        );
106    }
107    // Meteora DAMM
108    else if *program_id == METEORA_DAMM_V2_PROGRAM_ID {
109        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_meteora_damm_v2() {
110            return None;
111        }
112        return filter_parsed_event(
113            parse_meteora_damm_instruction(
114                instruction_data,
115                accounts,
116                signature,
117                slot,
118                tx_index,
119                block_time_us,
120                grpc_recv_us,
121            ),
122            event_type_filter,
123        );
124    }
125    // Pump fees (`pfeeUx...`)
126    else if *program_id == PUMP_FEES_PROGRAM_ID {
127        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_pump_fees() {
128            return None;
129        }
130        return filter_parsed_event(
131            crate::instr::pump_fees::parse_instruction(
132                instruction_data,
133                accounts,
134                signature,
135                slot,
136                tx_index,
137                block_time_us,
138                grpc_recv_us,
139            ),
140            event_type_filter,
141        );
142    }
143    // Bonk / Raydium Launchpad
144    else if *program_id == BONK_PROGRAM_ID {
145        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_raydium_launchpad() {
146            return None;
147        }
148        return filter_parsed_event(
149            parse_raydium_launchpad_instruction(
150                instruction_data,
151                accounts,
152                signature,
153                slot,
154                tx_index,
155                block_time_us,
156            ),
157            event_type_filter,
158        );
159    }
160    // Raydium CPMM
161    else if *program_id == RAYDIUM_CPMM_PROGRAM_ID {
162        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_raydium_cpmm() {
163            return None;
164        }
165        return filter_parsed_event(
166            crate::instr::raydium_cpmm::parse_instruction(
167                instruction_data,
168                accounts,
169                signature,
170                slot,
171                tx_index,
172                block_time_us,
173            ),
174            event_type_filter,
175        );
176    }
177    // Raydium CLMM
178    else if *program_id == RAYDIUM_CLMM_PROGRAM_ID {
179        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_raydium_clmm() {
180            return None;
181        }
182        return filter_parsed_event(
183            crate::instr::raydium_clmm::parse_instruction(
184                instruction_data,
185                accounts,
186                signature,
187                slot,
188                tx_index,
189                block_time_us,
190            ),
191            event_type_filter,
192        );
193    }
194    // Raydium AMM V4
195    else if *program_id == RAYDIUM_AMM_V4_PROGRAM_ID {
196        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_raydium_amm_v4() {
197            return None;
198        }
199        return filter_parsed_event(
200            crate::instr::raydium_amm::parse_instruction(
201                instruction_data,
202                accounts,
203                signature,
204                slot,
205                tx_index,
206                block_time_us,
207            ),
208            event_type_filter,
209        );
210    }
211    // Orca Whirlpool
212    else if *program_id == ORCA_WHIRLPOOL_PROGRAM_ID {
213        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_orca_whirlpool() {
214            return None;
215        }
216        return filter_parsed_event(
217            crate::instr::orca_whirlpool::parse_instruction(
218                instruction_data,
219                accounts,
220                signature,
221                slot,
222                tx_index,
223                block_time_us,
224            ),
225            event_type_filter,
226        );
227    }
228    // Meteora Pools / AMM
229    else if *program_id == METEORA_POOLS_PROGRAM_ID {
230        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_meteora_pools() {
231            return None;
232        }
233        return filter_parsed_event(
234            crate::instr::meteora_amm::parse_instruction(
235                instruction_data,
236                accounts,
237                signature,
238                slot,
239                tx_index,
240                block_time_us,
241            ),
242            event_type_filter,
243        );
244    }
245    // Meteora DLMM
246    else if *program_id == METEORA_DLMM_PROGRAM_ID {
247        if event_type_filter.is_some() && !event_type_filter.unwrap().includes_meteora_dlmm() {
248            return None;
249        }
250        return filter_parsed_event(
251            crate::instr::meteora_dlmm::parse_instruction(
252                instruction_data,
253                accounts,
254                signature,
255                slot,
256                tx_index,
257                block_time_us,
258            ),
259            event_type_filter,
260        );
261    }
262
263    None
264}