1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ClientConfig {
6 pub enable_metrics: bool,
8 pub connection_timeout_ms: u64,
10 pub request_timeout_ms: u64,
12 pub enable_tls: bool,
14 pub max_retries: u32,
15 pub retry_delay_ms: u64,
16 pub max_concurrent_streams: u32,
17 pub keep_alive_interval_ms: u64,
18 pub keep_alive_timeout_ms: u64,
19 pub buffer_size: usize,
20}
21
22impl Default for ClientConfig {
23 fn default() -> Self {
24 Self {
25 enable_metrics: false,
26 connection_timeout_ms: 8000,
27 request_timeout_ms: 15000,
28 enable_tls: true,
29 max_retries: 3,
30 retry_delay_ms: 1000,
31 max_concurrent_streams: 100,
32 keep_alive_interval_ms: 30000,
33 keep_alive_timeout_ms: 5000,
34 buffer_size: 8192,
35 }
36 }
37}
38
39impl ClientConfig {
40 pub fn low_latency() -> Self {
41 Self {
42 enable_metrics: false,
43 connection_timeout_ms: 5000,
44 request_timeout_ms: 10000,
45 enable_tls: true,
46 max_retries: 1,
47 retry_delay_ms: 100,
48 max_concurrent_streams: 200,
49 keep_alive_interval_ms: 10000,
50 keep_alive_timeout_ms: 2000,
51 buffer_size: 16384,
52 }
53 }
54
55 pub fn high_throughput() -> Self {
56 Self {
57 enable_metrics: true,
58 connection_timeout_ms: 10000,
59 request_timeout_ms: 30000,
60 enable_tls: true,
61 max_retries: 5,
62 retry_delay_ms: 2000,
63 max_concurrent_streams: 500,
64 keep_alive_interval_ms: 60000,
65 keep_alive_timeout_ms: 10000,
66 buffer_size: 32768,
67 }
68 }
69}
70
71#[derive(Debug, Clone)]
72pub struct TransactionFilter {
73 pub account_include: Vec<String>,
74 pub account_exclude: Vec<String>,
75 pub account_required: Vec<String>,
76}
77
78impl TransactionFilter {
79 pub fn new() -> Self {
80 Self {
81 account_include: Vec::new(),
82 account_exclude: Vec::new(),
83 account_required: Vec::new(),
84 }
85 }
86
87 pub fn include_account(mut self, account: impl Into<String>) -> Self {
88 self.account_include.push(account.into());
89 self
90 }
91
92 pub fn exclude_account(mut self, account: impl Into<String>) -> Self {
93 self.account_exclude.push(account.into());
94 self
95 }
96
97 pub fn require_account(mut self, account: impl Into<String>) -> Self {
98 self.account_required.push(account.into());
99 self
100 }
101
102 pub fn from_program_ids(program_ids: Vec<String>) -> Self {
104 Self {
105 account_include: program_ids,
106 account_exclude: Vec::new(),
107 account_required: Vec::new(),
108 }
109 }
110}
111
112impl Default for TransactionFilter {
113 fn default() -> Self {
114 Self::new()
115 }
116}
117
118#[derive(Debug, Clone)]
119pub struct AccountFilter {
120 pub account: Vec<String>,
121 pub owner: Vec<String>,
122 pub filters: Vec<AccountFilterData>,
123}
124
125impl AccountFilter {
126 pub fn new() -> Self {
127 Self {
128 account: Vec::new(),
129 owner: Vec::new(),
130 filters: Vec::new(),
131 }
132 }
133
134 pub fn add_account(mut self, account: impl Into<String>) -> Self {
135 self.account.push(account.into());
136 self
137 }
138
139 pub fn add_owner(mut self, owner: impl Into<String>) -> Self {
140 self.owner.push(owner.into());
141 self
142 }
143
144 pub fn add_filter(mut self, filter: AccountFilterData) -> Self {
145 self.filters.push(filter);
146 self
147 }
148
149 pub fn from_program_owners(program_ids: Vec<String>) -> Self {
151 Self {
152 account: Vec::new(),
153 owner: program_ids,
154 filters: Vec::new(),
155 }
156 }
157}
158
159impl Default for AccountFilter {
160 fn default() -> Self {
161 Self::new()
162 }
163}
164
165#[derive(Debug, Clone)]
166pub struct AccountFilterData {
167 pub memcmp: Option<AccountFilterMemcmp>,
168 pub datasize: Option<u64>,
169}
170
171#[derive(Debug, Clone)]
172pub struct AccountFilterMemcmp {
173 pub offset: u64,
174 pub bytes: Vec<u8>,
175}
176
177#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
178pub enum Protocol {
179 PumpFun,
180 PumpSwap,
181 Bonk,
182 RaydiumCpmm,
183 RaydiumClmm,
184 RaydiumAmmV4,
185}
186
187#[derive(Debug, Clone, Copy, PartialEq, Eq)]
188pub enum EventType {
189 BlockMeta,
191
192 BonkTrade,
194 BonkPoolCreate,
195 BonkMigrateAmm,
196
197 PumpFunTrade,
199 PumpFunCreate,
200 PumpFunComplete,
201 PumpFunMigrate,
202
203 PumpSwapBuy,
205 PumpSwapSell,
206 PumpSwapCreatePool,
207 PumpSwapPoolCreated,
208 PumpSwapTrade,
209 PumpSwapLiquidityAdded,
210 PumpSwapLiquidityRemoved,
211 PumpSwapPoolUpdated,
212 PumpSwapFeesClaimed,
213
214 RaydiumCpmmSwap,
216 RaydiumCpmmDeposit,
217 RaydiumCpmmWithdraw,
218 RaydiumCpmmInitialize,
219
220 RaydiumClmmSwap,
222 RaydiumClmmCreatePool,
223 RaydiumClmmOpenPosition,
224 RaydiumClmmClosePosition,
225 RaydiumClmmIncreaseLiquidity,
226 RaydiumClmmDecreaseLiquidity,
227 RaydiumClmmOpenPositionWithTokenExtNft,
228 RaydiumClmmCollectFee,
229
230 RaydiumAmmV4Swap,
232 RaydiumAmmV4Deposit,
233 RaydiumAmmV4Withdraw,
234 RaydiumAmmV4Initialize2,
235 RaydiumAmmV4WithdrawPnl,
236
237 OrcaWhirlpoolSwap,
239 OrcaWhirlpoolLiquidityIncreased,
240 OrcaWhirlpoolLiquidityDecreased,
241 OrcaWhirlpoolPoolInitialized,
242
243 MeteoraPoolsSwap,
245 MeteoraPoolsAddLiquidity,
246 MeteoraPoolsRemoveLiquidity,
247 MeteoraPoolsBootstrapLiquidity,
248 MeteoraPoolsPoolCreated,
249 MeteoraPoolsSetPoolFees,
250
251 MeteoraDammV2Swap,
253 MeteoraDammV2AddLiquidity,
254 MeteoraDammV2RemoveLiquidity,
255 MeteoraDammV2InitializePool,
256 MeteoraDammV2CreatePosition,
257 MeteoraDammV2ClosePosition,
258 MeteoraDammV2ClaimPositionFee,
259 MeteoraDammV2InitializeReward,
260 MeteoraDammV2FundReward,
261 MeteoraDammV2ClaimReward,
262
263 TokenAccount,
265 NonceAccount,
266 TokenInfo,
267}
268
269#[derive(Debug, Clone)]
270pub struct EventTypeFilter {
271 pub include_only: Option<Vec<EventType>>,
272 pub exclude_types: Option<Vec<EventType>>,
273}
274
275impl EventTypeFilter {
276 pub fn include_only(types: Vec<EventType>) -> Self {
277 Self {
278 include_only: Some(types),
279 exclude_types: None,
280 }
281 }
282
283 pub fn exclude_types(types: Vec<EventType>) -> Self {
284 Self {
285 include_only: None,
286 exclude_types: Some(types),
287 }
288 }
289
290 pub fn should_include(&self, event_type: EventType) -> bool {
291 if let Some(ref include_only) = self.include_only {
292 return include_only.contains(&event_type);
293 }
294
295 if let Some(ref exclude_types) = self.exclude_types {
296 return !exclude_types.contains(&event_type);
297 }
298
299 true
300 }
301
302 #[inline]
303 pub fn includes_pumpfun(&self) -> bool {
304 if let Some(ref include_only) = self.include_only {
305 return include_only.iter().any(|t| matches!(t,
306 EventType::PumpFunTrade | EventType::PumpFunCreate |
307 EventType::PumpFunComplete | EventType::PumpFunMigrate));
308 }
309
310 if let Some(ref exclude_types) = self.exclude_types {
311 return !exclude_types.iter().any(|t| matches!(t,
312 EventType::PumpFunTrade | EventType::PumpFunCreate |
313 EventType::PumpFunComplete | EventType::PumpFunMigrate));
314 }
315
316 true
317 }
318}
319
320#[derive(Debug, Clone)]
321pub struct SlotFilter {
322 pub min_slot: Option<u64>,
323 pub max_slot: Option<u64>,
324}
325
326impl SlotFilter {
327 pub fn new() -> Self {
328 Self {
329 min_slot: None,
330 max_slot: None,
331 }
332 }
333
334 pub fn min_slot(mut self, slot: u64) -> Self {
335 self.min_slot = Some(slot);
336 self
337 }
338
339 pub fn max_slot(mut self, slot: u64) -> Self {
340 self.max_slot = Some(slot);
341 self
342 }
343}
344
345impl Default for SlotFilter {
346 fn default() -> Self {
347 Self::new()
348 }
349}