1use crate::core::events::*;
10
11#[inline(always)]
23pub fn merge_events(base: &mut DexEvent, inner: DexEvent) {
24 use DexEvent::*;
25
26 match (base, inner) {
27 (PumpFunTrade(b), PumpFunTrade(i)) | (PumpFunTrade(b), PumpFunBuy(i))
29 | (PumpFunTrade(b), PumpFunSell(i)) | (PumpFunTrade(b), PumpFunBuyExactSolIn(i))
30 | (PumpFunBuy(b), PumpFunTrade(i)) | (PumpFunBuy(b), PumpFunBuy(i))
31 | (PumpFunSell(b), PumpFunTrade(i)) | (PumpFunSell(b), PumpFunSell(i))
32 | (PumpFunBuyExactSolIn(b), PumpFunTrade(i)) | (PumpFunBuyExactSolIn(b), PumpFunBuyExactSolIn(i))
33 => merge_pumpfun_trade(b, i),
34
35 (PumpFunCreate(b), PumpFunCreate(i)) => merge_pumpfun_create(b, i),
36 (PumpFunMigrate(b), PumpFunMigrate(i)) => merge_pumpfun_migrate(b, i),
37
38 (PumpSwapBuy(b), PumpSwapBuy(i)) => merge_generic(b, i),
40 (PumpSwapSell(b), PumpSwapSell(i)) => merge_generic(b, i),
41 (PumpSwapCreatePool(b), PumpSwapCreatePool(i)) => merge_generic(b, i),
42 (PumpSwapLiquidityAdded(b), PumpSwapLiquidityAdded(i)) => merge_generic(b, i),
43 (PumpSwapLiquidityRemoved(b), PumpSwapLiquidityRemoved(i)) => merge_generic(b, i),
44
45 (RaydiumClmmSwap(b), RaydiumClmmSwap(i)) => merge_generic(b, i),
47 (RaydiumClmmIncreaseLiquidity(b), RaydiumClmmIncreaseLiquidity(i)) => merge_generic(b, i),
48 (RaydiumClmmDecreaseLiquidity(b), RaydiumClmmDecreaseLiquidity(i)) => merge_generic(b, i),
49 (RaydiumClmmCreatePool(b), RaydiumClmmCreatePool(i)) => merge_generic(b, i),
50 (RaydiumClmmCollectFee(b), RaydiumClmmCollectFee(i)) => merge_generic(b, i),
51
52 (RaydiumCpmmSwap(b), RaydiumCpmmSwap(i)) => merge_generic(b, i),
54 (RaydiumCpmmDeposit(b), RaydiumCpmmDeposit(i)) => merge_generic(b, i),
55 (RaydiumCpmmWithdraw(b), RaydiumCpmmWithdraw(i)) => merge_generic(b, i),
56
57 (RaydiumAmmV4Swap(b), RaydiumAmmV4Swap(i)) => merge_generic(b, i),
59 (RaydiumAmmV4Deposit(b), RaydiumAmmV4Deposit(i)) => merge_generic(b, i),
60 (RaydiumAmmV4Withdraw(b), RaydiumAmmV4Withdraw(i)) => merge_generic(b, i),
61
62 (OrcaWhirlpoolSwap(b), OrcaWhirlpoolSwap(i)) => merge_generic(b, i),
64 (OrcaWhirlpoolLiquidityIncreased(b), OrcaWhirlpoolLiquidityIncreased(i)) => merge_generic(b, i),
65 (OrcaWhirlpoolLiquidityDecreased(b), OrcaWhirlpoolLiquidityDecreased(i)) => merge_generic(b, i),
66
67 (MeteoraPoolsSwap(b), MeteoraPoolsSwap(i)) => merge_generic(b, i),
69 (MeteoraPoolsAddLiquidity(b), MeteoraPoolsAddLiquidity(i)) => merge_generic(b, i),
70 (MeteoraPoolsRemoveLiquidity(b), MeteoraPoolsRemoveLiquidity(i)) => merge_generic(b, i),
71
72 (MeteoraDammV2Swap(b), MeteoraDammV2Swap(i)) => merge_generic(b, i),
74 (MeteoraDammV2AddLiquidity(b), MeteoraDammV2AddLiquidity(i)) => merge_generic(b, i),
75 (MeteoraDammV2RemoveLiquidity(b), MeteoraDammV2RemoveLiquidity(i)) => merge_generic(b, i),
76 (MeteoraDammV2CreatePosition(b), MeteoraDammV2CreatePosition(i)) => merge_generic(b, i),
77 (MeteoraDammV2ClosePosition(b), MeteoraDammV2ClosePosition(i)) => merge_generic(b, i),
78
79 (BonkTrade(b), BonkTrade(i)) => merge_generic(b, i),
81
82 _ => {}
84 }
85}
86
87#[inline(always)]
94fn merge_generic<T>(base: &mut T, inner: T) {
95 *base = inner;
96}
97
98#[inline(always)]
109fn merge_pumpfun_trade(base: &mut PumpFunTradeEvent, inner: PumpFunTradeEvent) {
110 base.mint = inner.mint;
112 base.sol_amount = inner.sol_amount;
113 base.token_amount = inner.token_amount;
114 base.is_buy = inner.is_buy;
115 base.user = inner.user;
116 base.timestamp = inner.timestamp;
117 base.virtual_sol_reserves = inner.virtual_sol_reserves;
118 base.virtual_token_reserves = inner.virtual_token_reserves;
119 base.real_sol_reserves = inner.real_sol_reserves;
120 base.real_token_reserves = inner.real_token_reserves;
121 base.fee_recipient = inner.fee_recipient;
122 base.fee_basis_points = inner.fee_basis_points;
123 base.fee = inner.fee;
124 base.creator = inner.creator;
125 base.creator_fee_basis_points = inner.creator_fee_basis_points;
126 base.creator_fee = inner.creator_fee;
127
128 base.track_volume = inner.track_volume;
130 base.total_unclaimed_tokens = inner.total_unclaimed_tokens;
131 base.total_claimed_tokens = inner.total_claimed_tokens;
132 base.current_sol_volume = inner.current_sol_volume;
133 base.last_update_timestamp = inner.last_update_timestamp;
134 base.ix_name = inner.ix_name;
135
136 }
139
140#[inline(always)]
142fn merge_pumpfun_create(base: &mut PumpFunCreateTokenEvent, inner: PumpFunCreateTokenEvent) {
143 base.name = inner.name;
145 base.symbol = inner.symbol;
146 base.uri = inner.uri;
147 base.mint = inner.mint;
148 base.bonding_curve = inner.bonding_curve;
149 base.user = inner.user;
150 base.creator = inner.creator;
151 base.timestamp = inner.timestamp;
152 base.virtual_token_reserves = inner.virtual_token_reserves;
153 base.virtual_sol_reserves = inner.virtual_sol_reserves;
154 base.real_token_reserves = inner.real_token_reserves;
155 base.token_total_supply = inner.token_total_supply;
156 base.token_program = inner.token_program;
157 base.is_mayhem_mode = inner.is_mayhem_mode;
158}
159
160#[inline(always)]
162fn merge_pumpfun_migrate(base: &mut PumpFunMigrateEvent, inner: PumpFunMigrateEvent) {
163 base.user = inner.user;
165 base.mint = inner.mint;
166 base.mint_amount = inner.mint_amount;
167 base.sol_amount = inner.sol_amount;
168 base.pool_migration_fee = inner.pool_migration_fee;
169 base.bonding_curve = inner.bonding_curve;
170 base.timestamp = inner.timestamp;
171 base.pool = inner.pool;
172}
173
174#[inline(always)]
185pub fn can_merge(base: &DexEvent, inner: &DexEvent) -> bool {
186 if base.metadata().signature != inner.metadata().signature {
188 return false;
189 }
190
191 match (base, inner) {
193 (DexEvent::PumpFunTrade(_), DexEvent::PumpFunTrade(_))
195 | (DexEvent::PumpFunTrade(_), DexEvent::PumpFunBuy(_))
196 | (DexEvent::PumpFunTrade(_), DexEvent::PumpFunSell(_))
197 | (DexEvent::PumpFunTrade(_), DexEvent::PumpFunBuyExactSolIn(_))
198 | (DexEvent::PumpFunBuy(_), DexEvent::PumpFunTrade(_))
199 | (DexEvent::PumpFunBuy(_), DexEvent::PumpFunBuy(_))
200 | (DexEvent::PumpFunSell(_), DexEvent::PumpFunTrade(_))
201 | (DexEvent::PumpFunSell(_), DexEvent::PumpFunSell(_))
202 | (DexEvent::PumpFunBuyExactSolIn(_), DexEvent::PumpFunTrade(_))
203 | (DexEvent::PumpFunBuyExactSolIn(_), DexEvent::PumpFunBuyExactSolIn(_)) => true,
204
205 (DexEvent::PumpFunCreate(_), DexEvent::PumpFunCreate(_)) => true,
207
208 (DexEvent::PumpFunMigrate(_), DexEvent::PumpFunMigrate(_)) => true,
210
211 _ => false,
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219 use solana_sdk::{pubkey::Pubkey, signature::Signature};
220
221 #[test]
222 fn test_merge_pumpfun_trade() {
223 let metadata = EventMetadata {
224 signature: Signature::default(),
225 slot: 100,
226 tx_index: 1,
227 block_time_us: 1000,
228 grpc_recv_us: 2000,
229 };
230
231 let mut base = DexEvent::PumpFunTrade(PumpFunTradeEvent {
233 metadata: metadata.clone(),
234 bonding_curve: Pubkey::new_unique(),
235 associated_bonding_curve: Pubkey::new_unique(),
236 ..Default::default()
237 });
238
239 let inner = DexEvent::PumpFunTrade(PumpFunTradeEvent {
241 metadata: metadata.clone(),
242 mint: Pubkey::new_unique(),
243 sol_amount: 1000,
244 token_amount: 2000,
245 is_buy: true,
246 user: Pubkey::new_unique(),
247 ..Default::default()
248 });
249
250 merge_events(&mut base, inner);
252
253 if let DexEvent::PumpFunTrade(trade) = base {
255 assert_eq!(trade.sol_amount, 1000);
256 assert_eq!(trade.token_amount, 2000);
257 assert!(trade.is_buy);
258 assert_ne!(trade.bonding_curve, Pubkey::default());
260 assert_ne!(trade.associated_bonding_curve, Pubkey::default());
261 } else {
262 panic!("Expected PumpFunTrade event");
263 }
264 }
265
266 #[test]
267 fn test_can_merge() {
268 let metadata = EventMetadata {
269 signature: Signature::default(),
270 slot: 100,
271 tx_index: 1,
272 block_time_us: 1000,
273 grpc_recv_us: 2000,
274 };
275
276 let base = DexEvent::PumpFunTrade(PumpFunTradeEvent {
277 metadata: metadata.clone(),
278 ..Default::default()
279 });
280
281 let inner = DexEvent::PumpFunBuy(PumpFunTradeEvent {
282 metadata: metadata.clone(),
283 ..Default::default()
284 });
285
286 assert!(can_merge(&base, &inner));
288
289 let different_sig = DexEvent::PumpFunTrade(PumpFunTradeEvent {
291 metadata: EventMetadata {
292 signature: Signature::new_unique(),
293 ..metadata
294 },
295 ..Default::default()
296 });
297
298 assert!(!can_merge(&base, &different_sig));
299 }
300}