refactor: restructure event handling from trait objects to enum pattern

- Convert UnifiedEvent from trait object (Box<dyn UnifiedEvent>) to concrete enum type
  - Remove match_event! macro in favor of native match expressions
  - Simplify event metadata access: event.event_type() -> event.metadata().event_type
  - Unify event callback signatures: Fn(Box<dyn UnifiedEvent>) -> Fn(UnifiedEvent)
  - Update all example code to use the new enum-based event system
  - Optimize type system to reduce runtime overhead and improve type safety

  Affected scope:
  - Core event parser and processor
  - All protocol event definitions (PumpFun, PumpSwap, Bonk, Raydium series, etc.)
  - gRPC and Shred streaming modules
  - All example code
This commit is contained in:
ysq
2025-10-10 18:19:44 +08:00
parent 77caa39f0c
commit 312a675a40
43 changed files with 1013 additions and 1839 deletions
+2 -75
View File
@@ -1,79 +1,6 @@
pub mod types;
pub mod utils;
pub mod filter;
pub mod high_performance_clock;
/// 自动生成UnifiedEvent trait实现的宏
#[macro_export]
macro_rules! impl_unified_event {
// 带有自定义ID表达式的版本
($struct_name:ident, $($field:ident),*) => {
impl $crate::streaming::event_parser::core::traits::UnifiedEvent for $struct_name {
fn event_type(&self) -> $crate::streaming::event_parser::common::types::EventType {
self.metadata.event_type.clone()
}
fn signature(&self) -> &solana_sdk::signature::Signature {
&self.metadata.signature
}
fn slot(&self) -> u64 {
self.metadata.slot
}
fn recv_us(&self) -> i64 {
self.metadata.recv_us
}
fn handle_us(&self) -> i64 {
self.metadata.handle_us
}
fn set_handle_us(&mut self, handle_us: i64) {
self.metadata.handle_us = handle_us;
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
self
}
fn clone_boxed(&self) -> Box<dyn $crate::streaming::event_parser::core::traits::UnifiedEvent> {
Box::new(self.clone())
}
fn merge(&mut self, other: &dyn $crate::streaming::event_parser::core::traits::UnifiedEvent) {
if let Some(_e) = other.as_any().downcast_ref::<$struct_name>() {
$(
self.$field = _e.$field.clone();
)*
}
}
fn set_swap_data(&mut self, swap_data: $crate::streaming::event_parser::common::types::SwapData) {
self.metadata.set_swap_data(swap_data);
}
fn swap_data_is_parsed(&self) -> bool {
self.metadata.swap_data.is_some()
}
fn outer_index(&self) -> i64 {
self.metadata.outer_index
}
fn inner_index(&self) -> Option<i64> {
self.metadata.inner_index
}
fn transaction_index(&self) -> Option<u64> {
self.metadata.transaction_index
}
}
};
}
pub mod types;
pub mod utils;
pub use types::*;
pub use utils::*;
+87 -97
View File
@@ -4,23 +4,7 @@ use serde::{Deserialize, Serialize};
use solana_sdk::{pubkey::Pubkey, signature::Signature};
use std::{borrow::Cow, fmt, str::FromStr, sync::Arc};
use crate::{
match_event,
streaming::{
common::SimdUtils,
event_parser::{
protocols::{
bonk::BonkTradeEvent,
pumpfun::PumpFunTradeEvent,
pumpswap::{PumpSwapBuyEvent, PumpSwapSellEvent},
raydium_amm_v4::RaydiumAmmV4SwapEvent,
raydium_clmm::{RaydiumClmmSwapEvent, RaydiumClmmSwapV2Event},
raydium_cpmm::RaydiumCpmmSwapEvent,
},
UnifiedEvent,
},
},
};
use crate::streaming::{common::SimdUtils, event_parser::UnifiedEvent};
// Object pool size configuration
const EVENT_METADATA_POOL_SIZE: usize = 1000;
@@ -364,7 +348,7 @@ lazy_static::lazy_static! {
/// Parse token transfer data from next instructions
pub fn parse_swap_data_from_next_instructions(
event: &dyn UnifiedEvent,
event: &UnifiedEvent,
inner_instruction: &solana_transaction_status::InnerInstructions,
current_index: i8,
accounts: &[Pubkey],
@@ -378,7 +362,7 @@ pub fn parse_swap_data_from_next_instructions(
};
// 先根据 event 取出关键信息
let mut user: Option<Pubkey> = None;
// let mut user: Option<Pubkey> = None;
let mut from_mint: Option<Pubkey> = None;
let mut to_mint: Option<Pubkey> = None;
let mut user_from_token: Option<Pubkey> = None;
@@ -386,63 +370,66 @@ pub fn parse_swap_data_from_next_instructions(
let mut from_vault: Option<Pubkey> = None;
let mut to_vault: Option<Pubkey> = None;
match_event!(&*event, {
BonkTradeEvent => |e: BonkTradeEvent| {
user = Some(e.payer);
match event {
UnifiedEvent::BonkTradeEvent(e) => {
// user = Some(e.payer);
from_mint = Some(e.base_token_mint);
to_mint = Some(e.quote_token_mint);
user_from_token = Some(e.user_base_token);
user_to_token = Some(e.user_quote_token);
from_vault = Some(e.base_vault);
to_vault = Some(e.quote_vault);
},
PumpFunTradeEvent => |e: PumpFunTradeEvent| {
}
UnifiedEvent::PumpFunTradeEvent(e) => {
swap_data.from_mint = if e.is_buy { *SOL_MINT } else { e.mint };
swap_data.to_mint = if e.is_buy { e.mint } else { *SOL_MINT };
},
PumpSwapBuyEvent => |e: PumpSwapBuyEvent| {
swap_data.to_mint = if e.is_buy { e.mint } else { *SOL_MINT };
}
UnifiedEvent::PumpSwapBuyEvent(e) => {
swap_data.from_mint = e.quote_mint;
swap_data.to_mint = e.base_mint;
},
PumpSwapSellEvent => |e: PumpSwapSellEvent| {
swap_data.to_mint = e.base_mint;
}
UnifiedEvent::PumpSwapSellEvent(e) => {
swap_data.from_mint = e.base_mint;
swap_data.to_mint = e.quote_mint;
},
RaydiumCpmmSwapEvent => |e: RaydiumCpmmSwapEvent| {
user = Some(e.payer);
swap_data.to_mint = e.quote_mint;
}
UnifiedEvent::RaydiumCpmmSwapEvent(e) => {
// user = Some(e.payer);
from_mint = Some(e.input_token_mint);
to_mint = Some(e.output_token_mint);
to_mint = Some(e.output_token_mint);
user_from_token = Some(e.input_token_account);
user_to_token = Some(e.output_token_account);
user_to_token = Some(e.output_token_account);
from_vault = Some(e.input_vault);
to_vault = Some(e.output_vault);
},
RaydiumClmmSwapEvent => |e: RaydiumClmmSwapEvent| {
user = Some(e.payer);
swap_data.description = Some("Unable to get from_mint and to_mint from RaydiumClmmSwapEvent".into());
to_vault = Some(e.output_vault);
}
UnifiedEvent::RaydiumClmmSwapEvent(e) => {
// user = Some(e.payer);
swap_data.description =
Some("Unable to get from_mint and to_mint from RaydiumClmmSwapEvent".into());
user_from_token = Some(e.input_token_account);
user_to_token = Some(e.output_token_account);
user_to_token = Some(e.output_token_account);
from_vault = Some(e.input_vault);
to_vault = Some(e.output_vault);
},
RaydiumClmmSwapV2Event => |e: RaydiumClmmSwapV2Event| {
user = Some(e.payer);
to_vault = Some(e.output_vault);
}
UnifiedEvent::RaydiumClmmSwapV2Event(e) => {
// user = Some(e.payer);
from_mint = Some(e.input_vault_mint);
to_mint = Some(e.output_vault_mint);
to_mint = Some(e.output_vault_mint);
user_from_token = Some(e.input_token_account);
user_to_token = Some(e.output_token_account);
user_to_token = Some(e.output_token_account);
from_vault = Some(e.input_vault);
to_vault = Some(e.output_vault);
},
RaydiumAmmV4SwapEvent => |e: RaydiumAmmV4SwapEvent| {
user = Some(e.user_source_owner);
swap_data.description = Some("Unable to get from_mint and to_mint from RaydiumAmmV4SwapEvent".into());
to_vault = Some(e.output_vault);
}
UnifiedEvent::RaydiumAmmV4SwapEvent(e) => {
// user = Some(e.user_source_owner);
swap_data.description =
Some("Unable to get from_mint and to_mint from RaydiumAmmV4SwapEvent".into());
user_from_token = Some(e.user_source_token_account);
user_to_token = Some(e.user_destination_token_account);
user_to_token = Some(e.user_destination_token_account);
from_vault = Some(e.pool_pc_token_account);
to_vault = Some(e.pool_coin_token_account);
},
});
to_vault = Some(e.pool_coin_token_account);
}
_ => {}
}
let user_to_token = user_to_token.unwrap_or_default();
let user_from_token = user_from_token.unwrap_or_default();
@@ -531,7 +518,7 @@ pub fn parse_swap_data_from_next_instructions(
/// Parse token transfer data from next instructions
/// TODO: - wait refactor
pub fn parse_swap_data_from_next_grpc_instructions(
event: &dyn UnifiedEvent,
event: &UnifiedEvent,
inner_instruction: &yellowstone_grpc_proto::prelude::InnerInstructions,
current_index: i8,
accounts: &[Pubkey],
@@ -545,7 +532,7 @@ pub fn parse_swap_data_from_next_grpc_instructions(
};
// 先根据 event 取出关键信息
let mut user: Option<Pubkey> = None;
// let mut user: Option<Pubkey> = None;
let mut from_mint: Option<Pubkey> = None;
let mut to_mint: Option<Pubkey> = None;
let mut user_from_token: Option<Pubkey> = None;
@@ -553,63 +540,66 @@ pub fn parse_swap_data_from_next_grpc_instructions(
let mut from_vault: Option<Pubkey> = None;
let mut to_vault: Option<Pubkey> = None;
match_event!(&*event, {
BonkTradeEvent => |e: BonkTradeEvent| {
user = Some(e.payer);
match event {
UnifiedEvent::BonkTradeEvent(e) => {
// user = Some(e.payer);
from_mint = Some(e.base_token_mint);
to_mint = Some(e.quote_token_mint);
user_from_token = Some(e.user_base_token);
user_to_token = Some(e.user_quote_token);
from_vault = Some(e.base_vault);
to_vault = Some(e.quote_vault);
},
PumpFunTradeEvent => |e: PumpFunTradeEvent| {
}
UnifiedEvent::PumpFunTradeEvent(e) => {
swap_data.from_mint = if e.is_buy { *SOL_MINT } else { e.mint };
swap_data.to_mint = if e.is_buy { e.mint } else { *SOL_MINT };
},
PumpSwapBuyEvent => |e: PumpSwapBuyEvent| {
swap_data.to_mint = if e.is_buy { e.mint } else { *SOL_MINT };
}
UnifiedEvent::PumpSwapBuyEvent(e) => {
swap_data.from_mint = e.quote_mint;
swap_data.to_mint = e.base_mint;
},
PumpSwapSellEvent => |e: PumpSwapSellEvent| {
swap_data.to_mint = e.base_mint;
}
UnifiedEvent::PumpSwapSellEvent(e) => {
swap_data.from_mint = e.base_mint;
swap_data.to_mint = e.quote_mint;
},
RaydiumCpmmSwapEvent => |e: RaydiumCpmmSwapEvent| {
user = Some(e.payer);
swap_data.to_mint = e.quote_mint;
}
UnifiedEvent::RaydiumCpmmSwapEvent(e) => {
// user = Some(e.payer);
from_mint = Some(e.input_token_mint);
to_mint = Some(e.output_token_mint);
to_mint = Some(e.output_token_mint);
user_from_token = Some(e.input_token_account);
user_to_token = Some(e.output_token_account);
user_to_token = Some(e.output_token_account);
from_vault = Some(e.input_vault);
to_vault = Some(e.output_vault);
},
RaydiumClmmSwapEvent => |e: RaydiumClmmSwapEvent| {
user = Some(e.payer);
swap_data.description = Some("Unable to get from_mint and to_mint from RaydiumClmmSwapEvent".into());
to_vault = Some(e.output_vault);
}
UnifiedEvent::RaydiumClmmSwapEvent(e) => {
// user = Some(e.payer);
swap_data.description =
Some("Unable to get from_mint and to_mint from RaydiumClmmSwapEvent".into());
user_from_token = Some(e.input_token_account);
user_to_token = Some(e.output_token_account);
user_to_token = Some(e.output_token_account);
from_vault = Some(e.input_vault);
to_vault = Some(e.output_vault);
},
RaydiumClmmSwapV2Event => |e: RaydiumClmmSwapV2Event| {
user = Some(e.payer);
to_vault = Some(e.output_vault);
}
UnifiedEvent::RaydiumClmmSwapV2Event(e) => {
// user = Some(e.payer);
from_mint = Some(e.input_vault_mint);
to_mint = Some(e.output_vault_mint);
to_mint = Some(e.output_vault_mint);
user_from_token = Some(e.input_token_account);
user_to_token = Some(e.output_token_account);
user_to_token = Some(e.output_token_account);
from_vault = Some(e.input_vault);
to_vault = Some(e.output_vault);
},
RaydiumAmmV4SwapEvent => |e: RaydiumAmmV4SwapEvent| {
user = Some(e.user_source_owner);
swap_data.description = Some("Unable to get from_mint and to_mint from RaydiumAmmV4SwapEvent".into());
to_vault = Some(e.output_vault);
}
UnifiedEvent::RaydiumAmmV4SwapEvent(e) => {
// user = Some(e.user_source_owner);
swap_data.description =
Some("Unable to get from_mint and to_mint from RaydiumAmmV4SwapEvent".into());
user_from_token = Some(e.user_source_token_account);
user_to_token = Some(e.user_destination_token_account);
user_to_token = Some(e.user_destination_token_account);
from_vault = Some(e.pool_pc_token_account);
to_vault = Some(e.pool_coin_token_account);
},
});
to_vault = Some(e.pool_coin_token_account);
}
_ => {}
}
let user_to_token = user_to_token.unwrap_or_default();
let user_from_token = user_from_token.unwrap_or_default();
@@ -1,4 +1,3 @@
use crate::impl_unified_event;
use crate::streaming::common::SimdUtils;
use crate::streaming::event_parser::common::filter::EventTypeFilter;
use crate::streaming::event_parser::common::high_performance_clock::elapsed_micros_since;
@@ -46,7 +45,6 @@ pub struct TokenAccountEvent {
pub amount: Option<u64>,
pub token_owner: Pubkey,
}
impl_unified_event!(TokenAccountEvent,);
/// Nonce account event
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -60,7 +58,6 @@ pub struct NonceAccountEvent {
pub nonce: String,
pub authority: String,
}
impl_unified_event!(NonceAccountEvent,);
/// Nonce account event
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -74,11 +71,10 @@ pub struct TokenInfoEvent {
pub supply: u64,
pub decimals: u8,
}
impl_unified_event!(TokenInfoEvent,);
/// 账户事件解析器
pub type AccountEventParserFn =
fn(account: &AccountPretty, metadata: EventMetadata) -> Option<Box<dyn UnifiedEvent>>;
fn(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent>;
static PROTOCOL_CONFIGS_CACHE: OnceLock<HashMap<Protocol, Vec<AccountEventParseConfig>>> =
OnceLock::new();
@@ -256,7 +252,7 @@ impl AccountEventParser {
protocols: &[Protocol],
account: AccountPretty,
event_type_filter: Option<&EventTypeFilter>,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
let configs = Self::configs(protocols, event_type_filter);
for config in configs {
if config.program_id == Pubkey::default()
@@ -275,13 +271,11 @@ impl AccountEventParser {
event_type: config.event_type,
program_id: config.program_id,
recv_us: account.recv_us,
handle_us: elapsed_micros_since(account.recv_us),
..Default::default()
},
);
if let Some(mut event) = event {
event.set_handle_us(elapsed_micros_since(account.recv_us));
return Some(event);
}
return event;
}
}
None
@@ -290,7 +284,7 @@ impl AccountEventParser {
pub fn parse_token_account_event(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
let pubkey = account.pubkey;
let executable = account.executable;
let lamports = account.lamports;
@@ -310,8 +304,8 @@ impl AccountEventParser {
decimals: mint.decimals,
};
let recv_delta = elapsed_micros_since(account.recv_us);
event.set_handle_us(recv_delta);
return Some(Box::new(event));
event.metadata.handle_us = recv_delta;
return Some(UnifiedEvent::TokenInfoEvent(event));
}
}
// Spl Token2022 Mint
@@ -328,8 +322,8 @@ impl AccountEventParser {
decimals: mint.base.decimals,
};
let recv_delta = elapsed_micros_since(account.recv_us);
event.set_handle_us(recv_delta);
return Some(Box::new(event));
event.metadata.handle_us = recv_delta;
return Some(UnifiedEvent::TokenInfoEvent(event));
}
}
let amount = if account.owner.to_bytes() == spl_token_2022::ID.to_bytes() {
@@ -351,14 +345,14 @@ impl AccountEventParser {
token_owner: account.owner,
};
let recv_delta = elapsed_micros_since(account.recv_us);
event.set_handle_us(recv_delta);
Some(Box::new(event))
event.metadata.handle_us = recv_delta;
Some(UnifiedEvent::TokenAccountEvent(event))
}
pub fn parse_nonce_account_event(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if let Ok(info) = parse_nonce(&account.data) {
match info {
solana_account_decoder::parse_nonce::UiNonceState::Initialized(details) => {
@@ -372,8 +366,8 @@ impl AccountEventParser {
nonce: details.blockhash,
authority: details.authority,
};
event.set_handle_us(elapsed_micros_since(account.recv_us));
return Some(Box::new(event));
event.metadata.handle_us = elapsed_micros_since(account.recv_us);
return Some(UnifiedEvent::NonceAccountEvent(event));
}
solana_account_decoder::parse_nonce::UiNonceState::Uninitialized => {}
}
@@ -10,9 +10,9 @@ impl CommonEventParser {
block_hash: String,
block_time_ms: i64,
recv_us: i64,
) -> Box<dyn UnifiedEvent> {
) -> UnifiedEvent {
let mut block_meta_event = BlockMetaEvent::new(slot, block_hash, block_time_ms, recv_us);
block_meta_event.set_handle_us(elapsed_micros_since(recv_us));
Box::new(block_meta_event)
block_meta_event.metadata.handle_us = elapsed_micros_since(recv_us);
UnifiedEvent::BlockMetaEvent(block_meta_event)
}
}
+92 -78
View File
@@ -12,9 +12,8 @@ use crate::streaming::{
is_dev_address_in_signature,
},
protocols::{
bonk::{parser::BONK_PROGRAM_ID, BonkPoolCreateEvent, BonkTradeEvent},
pumpfun::{parser::PUMPFUN_PROGRAM_ID, PumpFunCreateTokenEvent, PumpFunTradeEvent},
pumpswap::{parser::PUMPSWAP_PROGRAM_ID, PumpSwapBuyEvent, PumpSwapSellEvent},
bonk::parser::BONK_PROGRAM_ID, pumpfun::parser::PUMPFUN_PROGRAM_ID,
pumpswap::parser::PUMPSWAP_PROGRAM_ID,
raydium_amm_v4::parser::RAYDIUM_AMM_V4_PROGRAM_ID,
raydium_clmm::parser::RAYDIUM_CLMM_PROGRAM_ID,
raydium_cpmm::parser::RAYDIUM_CPMM_PROGRAM_ID,
@@ -23,7 +22,10 @@ use crate::streaming::{
},
};
use prost_types::Timestamp;
use solana_sdk::{bs58, message::compiled_instruction::CompiledInstruction, pubkey::Pubkey, signature::Signature, transaction::VersionedTransaction};
use solana_sdk::{
bs58, message::compiled_instruction::CompiledInstruction, pubkey::Pubkey, signature::Signature,
transaction::VersionedTransaction,
};
use solana_transaction_status::{
EncodedConfirmedTransactionWithStatusMeta, InnerInstruction, InnerInstructions, UiInstruction,
};
@@ -81,11 +83,11 @@ impl Default for AccountPubkeyCache {
/// 内联指令事件解析器
pub type InnerInstructionEventParser =
fn(data: &[u8], metadata: EventMetadata) -> Option<Box<dyn UnifiedEvent>>;
fn(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent>;
/// 指令事件解析器
pub type InstructionEventParser =
fn(data: &[u8], accounts: &[Pubkey], metadata: EventMetadata) -> Option<Box<dyn UnifiedEvent>>;
fn(data: &[u8], accounts: &[Pubkey], metadata: EventMetadata) -> Option<UnifiedEvent>;
/// 通用事件解析器配置
#[derive(Debug, Clone)]
@@ -200,7 +202,7 @@ impl EventParser {
inner_instructions: &[yellowstone_grpc_proto::prelude::InnerInstructions],
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
// 获取交易的指令和账户
let mut accounts = accounts.to_vec();
@@ -283,7 +285,7 @@ impl EventParser {
inner_instructions: &[InnerInstructions],
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
// 获取交易的指令和账户
let compiled_instructions = transaction.message.instructions();
@@ -356,11 +358,11 @@ impl EventParser {
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
inner_instructions: &[InnerInstructions],
callback: Arc<dyn Fn(Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn Fn(UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
// 创建适配器回调,将所有权回调转换为引用回调
let adapter_callback = Arc::new(move |event: &Box<dyn UnifiedEvent>| {
callback(event.clone_boxed());
let adapter_callback = Arc::new(move |event: &UnifiedEvent| {
callback(event.clone());
});
self.parse_versioned_transaction(
&versioned_tx,
@@ -387,7 +389,7 @@ impl EventParser {
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
inner_instructions: &[InnerInstructions],
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
let accounts: Vec<Pubkey> = versioned_tx.message.static_account_keys().to_vec();
self.parse_instruction_events_from_versioned_transaction(
@@ -415,11 +417,11 @@ impl EventParser {
recv_us: i64,
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
callback: Arc<dyn Fn(Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn Fn(UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
// 创建适配器回调,将所有权回调转换为引用回调
let adapter_callback = Arc::new(move |event: &Box<dyn UnifiedEvent>| {
callback(event.clone_boxed());
let adapter_callback = Arc::new(move |event: &UnifiedEvent| {
callback(event.clone());
});
// 调用原始方法
self.parse_grpc_transaction(
@@ -444,7 +446,7 @@ impl EventParser {
recv_us: i64,
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
if let Some(transition) = grpc_tx.transaction {
if let Some(message) = &transition.message {
@@ -508,7 +510,7 @@ impl EventParser {
&self,
signature: Signature,
transaction: EncodedConfirmedTransactionWithStatusMeta,
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
let versioned_tx = match transaction.transaction.transaction.decode() {
Some(tx) => tx,
@@ -628,7 +630,7 @@ impl EventParser {
outer_index: i64,
inner_index: Option<i64>,
transaction_index: Option<u64>,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if let Some(parser) = config.inner_instruction_parser {
let timestamp = block_time.unwrap_or(Timestamp { seconds: 0, nanos: 0 });
let block_time_ms = timestamp.seconds * 1000 + (timestamp.nanos as i64) / 1_000_000;
@@ -665,7 +667,7 @@ impl EventParser {
outer_index: i64,
inner_index: Option<i64>,
transaction_index: Option<u64>,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if let Some(parser) = config.instruction_parser {
let timestamp = block_time.unwrap_or(Timestamp { seconds: 0, nanos: 0 });
let block_time_ms = timestamp.seconds * 1000 + (timestamp.nanos as i64) / 1_000_000;
@@ -701,7 +703,7 @@ impl EventParser {
inner_index: Option<i64>,
transaction_index: Option<u64>,
config: &GenericEventParseConfig,
) -> Vec<Box<dyn UnifiedEvent>> {
) -> Vec<UnifiedEvent> {
// Use SIMD-optimized data validation with correct discriminator length
let discriminator_len = config.inner_instruction_discriminator.len();
if !SimdUtils::validate_instruction_data_simd(
@@ -751,7 +753,7 @@ impl EventParser {
inner_index: Option<i64>,
transaction_index: Option<u64>,
config: &GenericEventParseConfig,
) -> Vec<Box<dyn UnifiedEvent>> {
) -> Vec<UnifiedEvent> {
// Use SIMD-optimized data validation with correct discriminator length
let discriminator_len = config.inner_instruction_discriminator.len();
if !SimdUtils::validate_instruction_data_simd(
@@ -803,7 +805,7 @@ impl EventParser {
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
inner_instructions: Option<&InnerInstructions>,
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
let program_id = accounts[instruction.program_id_index as usize];
if !self.should_handle(&program_id) {
@@ -860,7 +862,7 @@ impl EventParser {
for (_disc, config, mut event) in all_results {
// 阻塞处理:原有的同步逻辑
let mut inner_instruction_event: Option<Box<dyn UnifiedEvent>> = None;
let mut inner_instruction_event: Option<UnifiedEvent> = None;
if inner_instructions.is_some() {
let inner_instructions_ref = inner_instructions.unwrap();
@@ -887,9 +889,9 @@ impl EventParser {
});
let swap_data_handle = s.spawn(|| {
if !event.swap_data_is_parsed() {
if !event.metadata().swap_data.is_some() {
parse_swap_data_from_next_instructions(
&*event,
&event,
inner_instructions_ref,
inner_index.unwrap_or(-1_i64) as i8,
&accounts,
@@ -905,7 +907,7 @@ impl EventParser {
inner_instruction_event = inner_event_result;
if let Some(swap_data) = swap_data_result {
event.set_swap_data(swap_data);
event.metadata_mut().set_swap_data(swap_data);
}
}
@@ -916,10 +918,10 @@ impl EventParser {
// 合并事件
if let Some(inner_instruction_event) = inner_instruction_event {
event.merge(&*inner_instruction_event);
// event.merge(&*inner_instruction_event);
}
// 设置处理时间(使用高性能时钟)
event.set_handle_us(elapsed_micros_since(recv_us));
event.metadata_mut().handle_us = elapsed_micros_since(recv_us);
event = process_event(event, bot_wallet);
callback(&event);
}
@@ -942,7 +944,7 @@ impl EventParser {
bot_wallet: Option<Pubkey>,
transaction_index: Option<u64>,
inner_instructions: Option<&yellowstone_grpc_proto::prelude::InnerInstructions>,
callback: Arc<dyn for<'a> Fn(&'a Box<dyn UnifiedEvent>) + Send + Sync>,
callback: Arc<dyn for<'a> Fn(&'a UnifiedEvent) + Send + Sync>,
) -> anyhow::Result<()> {
let program_id = accounts[instruction.program_id_index as usize];
if !self.should_handle(&program_id) {
@@ -999,7 +1001,7 @@ impl EventParser {
for (_disc, config, mut event) in all_results {
// 阻塞处理:原有的同步逻辑
let mut inner_instruction_event: Option<Box<dyn UnifiedEvent>> = None;
let mut inner_instruction_event: Option<UnifiedEvent> = None;
if inner_instructions.is_some() {
let inner_instructions_ref = inner_instructions.unwrap();
@@ -1026,9 +1028,9 @@ impl EventParser {
});
let swap_data_handle = s.spawn(|| {
if !event.swap_data_is_parsed() {
if !event.metadata().swap_data.is_some() {
parse_swap_data_from_next_grpc_instructions(
&*event,
&event,
inner_instructions_ref,
inner_index.unwrap_or(-1_i64) as i8,
&accounts,
@@ -1044,7 +1046,7 @@ impl EventParser {
inner_instruction_event = inner_event_result;
if let Some(swap_data) = swap_data_result {
event.set_swap_data(swap_data);
event.metadata_mut().set_swap_data(swap_data);
}
}
@@ -1055,10 +1057,10 @@ impl EventParser {
// 合并事件
if let Some(inner_instruction_event) = inner_instruction_event {
event.merge(&*inner_instruction_event);
// event.merge(&*inner_instruction_event);
}
// 设置处理时间(使用高性能时钟)
event.set_handle_us(elapsed_micros_since(recv_us));
event.metadata_mut().handle_us = elapsed_micros_since(recv_us);
event = process_event(event, bot_wallet);
callback(&event);
}
@@ -1074,54 +1076,66 @@ impl EventParser {
// }
}
fn process_event(
mut event: Box<dyn UnifiedEvent>,
bot_wallet: Option<Pubkey>,
) -> Box<dyn UnifiedEvent> {
let signature = *event.signature(); // Copy the signature to avoid borrowing issues
if let Some(token_info) = event.as_any().downcast_ref::<PumpFunCreateTokenEvent>() {
add_dev_address(&signature, token_info.user);
if token_info.creator != Pubkey::default() && token_info.creator != token_info.user {
add_dev_address(&signature, token_info.creator);
fn process_event(mut event: UnifiedEvent, bot_wallet: Option<Pubkey>) -> UnifiedEvent {
let signature = event.metadata().signature; // Copy the signature to avoid borrowing issues
match event {
UnifiedEvent::PumpFunCreateTokenEvent(token_info) => {
add_dev_address(&signature, token_info.user);
if token_info.creator != Pubkey::default() && token_info.creator != token_info.user {
add_dev_address(&signature, token_info.creator);
}
UnifiedEvent::PumpFunCreateTokenEvent(token_info)
}
} else if let Some(trade_info) = event.as_any_mut().downcast_mut::<PumpFunTradeEvent>() {
if is_dev_address_in_signature(&signature, &trade_info.user)
|| is_dev_address_in_signature(&signature, &trade_info.creator)
{
trade_info.is_dev_create_token_trade = true;
} else if Some(trade_info.user) == bot_wallet {
trade_info.is_bot = true;
} else {
trade_info.is_dev_create_token_trade = false;
UnifiedEvent::PumpFunTradeEvent(mut trade_info) => {
if is_dev_address_in_signature(&signature, &trade_info.user)
|| is_dev_address_in_signature(&signature, &trade_info.creator)
{
trade_info.is_dev_create_token_trade = true;
} else if Some(trade_info.user) == bot_wallet {
trade_info.is_bot = true;
} else {
trade_info.is_dev_create_token_trade = false;
}
if trade_info.metadata.swap_data.is_some() {
trade_info.metadata.swap_data.as_mut().unwrap().from_amount =
if trade_info.is_buy { trade_info.sol_amount } else { trade_info.token_amount };
trade_info.metadata.swap_data.as_mut().unwrap().to_amount =
if trade_info.is_buy { trade_info.token_amount } else { trade_info.sol_amount };
}
UnifiedEvent::PumpFunTradeEvent(trade_info)
}
if trade_info.metadata.swap_data.is_some() {
trade_info.metadata.swap_data.as_mut().unwrap().from_amount =
if trade_info.is_buy { trade_info.sol_amount } else { trade_info.token_amount };
trade_info.metadata.swap_data.as_mut().unwrap().to_amount =
if trade_info.is_buy { trade_info.token_amount } else { trade_info.sol_amount };
UnifiedEvent::PumpSwapBuyEvent(mut trade_info) => {
if trade_info.metadata.swap_data.is_some() {
trade_info.metadata.swap_data.as_mut().unwrap().from_amount =
trade_info.user_quote_amount_in;
trade_info.metadata.swap_data.as_mut().unwrap().to_amount =
trade_info.base_amount_out;
}
UnifiedEvent::PumpSwapBuyEvent(trade_info)
}
} else if let Some(trade_info) = event.as_any_mut().downcast_mut::<PumpSwapBuyEvent>() {
if trade_info.metadata.swap_data.is_some() {
trade_info.metadata.swap_data.as_mut().unwrap().from_amount =
trade_info.user_quote_amount_in;
trade_info.metadata.swap_data.as_mut().unwrap().to_amount = trade_info.base_amount_out;
UnifiedEvent::PumpSwapSellEvent(mut trade_info) => {
if trade_info.metadata.swap_data.is_some() {
trade_info.metadata.swap_data.as_mut().unwrap().from_amount =
trade_info.base_amount_in;
trade_info.metadata.swap_data.as_mut().unwrap().to_amount =
trade_info.user_quote_amount_out;
}
UnifiedEvent::PumpSwapSellEvent(trade_info)
}
} else if let Some(trade_info) = event.as_any_mut().downcast_mut::<PumpSwapSellEvent>() {
if trade_info.metadata.swap_data.is_some() {
trade_info.metadata.swap_data.as_mut().unwrap().from_amount = trade_info.base_amount_in;
trade_info.metadata.swap_data.as_mut().unwrap().to_amount =
trade_info.user_quote_amount_out;
UnifiedEvent::BonkPoolCreateEvent(pool_info) => {
add_bonk_dev_address(&signature, pool_info.creator);
UnifiedEvent::BonkPoolCreateEvent(pool_info)
}
} else if let Some(pool_info) = event.as_any().downcast_ref::<BonkPoolCreateEvent>() {
add_bonk_dev_address(&signature, pool_info.creator);
} else if let Some(trade_info) = event.as_any_mut().downcast_mut::<BonkTradeEvent>() {
if is_bonk_dev_address_in_signature(&signature, &trade_info.payer) {
trade_info.is_dev_create_token_trade = true;
} else if Some(trade_info.payer) == bot_wallet {
trade_info.is_bot = true;
} else {
trade_info.is_dev_create_token_trade = false;
UnifiedEvent::BonkTradeEvent(mut trade_info) => {
if is_bonk_dev_address_in_signature(&signature, &trade_info.payer) {
trade_info.is_dev_create_token_trade = true;
} else if Some(trade_info.payer) == bot_wallet {
trade_info.is_bot = true;
} else {
trade_info.is_dev_create_token_trade = false;
}
UnifiedEvent::BonkTradeEvent(trade_info)
}
_ => event,
}
event
}
+169 -47
View File
@@ -1,59 +1,181 @@
use crate::streaming::event_parser::common::EventType;
use crate::streaming::event_parser::common::SwapData;
use solana_sdk::signature::Signature;
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::core::account_event_parser::{
NonceAccountEvent, TokenAccountEvent, TokenInfoEvent,
};
use crate::streaming::event_parser::protocols::block::block_meta_event::BlockMetaEvent;
use crate::streaming::event_parser::protocols::bonk::events::*;
use crate::streaming::event_parser::protocols::pumpfun::events::*;
use crate::streaming::event_parser::protocols::pumpswap::events::*;
use crate::streaming::event_parser::protocols::raydium_amm_v4::events::*;
use crate::streaming::event_parser::protocols::raydium_clmm::events::*;
use crate::streaming::event_parser::protocols::raydium_cpmm::events::*;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
/// Unified Event Interface - All protocol events must implement this trait
pub trait UnifiedEvent: Debug + Send + Sync {
/// Get event type
fn event_type(&self) -> EventType;
/// Unified Event Enum - Replaces the trait-based approach with a type-safe enum
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum UnifiedEvent {
// Bonk events
BonkTradeEvent(BonkTradeEvent),
BonkPoolCreateEvent(BonkPoolCreateEvent),
BonkMigrateToAmmEvent(BonkMigrateToAmmEvent),
BonkMigrateToCpswapEvent(BonkMigrateToCpswapEvent),
BonkPoolStateAccountEvent(BonkPoolStateAccountEvent),
BonkGlobalConfigAccountEvent(BonkGlobalConfigAccountEvent),
BonkPlatformConfigAccountEvent(BonkPlatformConfigAccountEvent),
/// Get transaction signature
fn signature(&self) -> &Signature;
// PumpFun events
PumpFunCreateTokenEvent(PumpFunCreateTokenEvent),
PumpFunTradeEvent(PumpFunTradeEvent),
PumpFunMigrateEvent(PumpFunMigrateEvent),
PumpFunBondingCurveAccountEvent(PumpFunBondingCurveAccountEvent),
PumpFunGlobalAccountEvent(PumpFunGlobalAccountEvent),
/// Get slot number
fn slot(&self) -> u64;
// PumpSwap events
PumpSwapBuyEvent(PumpSwapBuyEvent),
PumpSwapSellEvent(PumpSwapSellEvent),
PumpSwapCreatePoolEvent(PumpSwapCreatePoolEvent),
PumpSwapDepositEvent(PumpSwapDepositEvent),
PumpSwapWithdrawEvent(PumpSwapWithdrawEvent),
PumpSwapGlobalConfigAccountEvent(PumpSwapGlobalConfigAccountEvent),
PumpSwapPoolAccountEvent(PumpSwapPoolAccountEvent),
/// Get program received timestamp (milliseconds)
fn recv_us(&self) -> i64;
// Raydium AMM V4 events
RaydiumAmmV4SwapEvent(RaydiumAmmV4SwapEvent),
RaydiumAmmV4DepositEvent(RaydiumAmmV4DepositEvent),
RaydiumAmmV4WithdrawEvent(RaydiumAmmV4WithdrawEvent),
RaydiumAmmV4WithdrawPnlEvent(RaydiumAmmV4WithdrawPnlEvent),
RaydiumAmmV4Initialize2Event(RaydiumAmmV4Initialize2Event),
RaydiumAmmV4AmmInfoAccountEvent(RaydiumAmmV4AmmInfoAccountEvent),
/// Processing time consumption (milliseconds)
fn handle_us(&self) -> i64;
// Raydium CLMM events
RaydiumClmmSwapEvent(RaydiumClmmSwapEvent),
RaydiumClmmSwapV2Event(RaydiumClmmSwapV2Event),
RaydiumClmmClosePositionEvent(RaydiumClmmClosePositionEvent),
RaydiumClmmIncreaseLiquidityV2Event(RaydiumClmmIncreaseLiquidityV2Event),
RaydiumClmmDecreaseLiquidityV2Event(RaydiumClmmDecreaseLiquidityV2Event),
RaydiumClmmCreatePoolEvent(RaydiumClmmCreatePoolEvent),
RaydiumClmmOpenPositionWithToken22NftEvent(RaydiumClmmOpenPositionWithToken22NftEvent),
RaydiumClmmOpenPositionV2Event(RaydiumClmmOpenPositionV2Event),
RaydiumClmmAmmConfigAccountEvent(RaydiumClmmAmmConfigAccountEvent),
RaydiumClmmPoolStateAccountEvent(RaydiumClmmPoolStateAccountEvent),
RaydiumClmmTickArrayStateAccountEvent(RaydiumClmmTickArrayStateAccountEvent),
/// Set processing time consumption (milliseconds)
fn set_handle_us(&mut self, handle_us: i64);
// Raydium CPMM events
RaydiumCpmmSwapEvent(RaydiumCpmmSwapEvent),
RaydiumCpmmDepositEvent(RaydiumCpmmDepositEvent),
RaydiumCpmmWithdrawEvent(RaydiumCpmmWithdrawEvent),
RaydiumCpmmInitializeEvent(RaydiumCpmmInitializeEvent),
RaydiumCpmmAmmConfigAccountEvent(RaydiumCpmmAmmConfigAccountEvent),
RaydiumCpmmPoolStateAccountEvent(RaydiumCpmmPoolStateAccountEvent),
/// Convert event to Any for downcasting
fn as_any(&self) -> &dyn std::any::Any;
/// Convert event to mutable Any for downcasting
fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
/// Clone the event
fn clone_boxed(&self) -> Box<dyn UnifiedEvent>;
/// Merge events (optional implementation)
fn merge(&mut self, _other: &dyn UnifiedEvent) {
// Default implementation: no merging operation
}
/// Set swap data
fn set_swap_data(&mut self, swap_data: SwapData);
/// swap_data is parsed
fn swap_data_is_parsed(&self) -> bool;
/// Get index
fn outer_index(&self) -> i64;
fn inner_index(&self) -> Option<i64>;
/// Get transaction index in slot
fn transaction_index(&self) -> Option<u64>;
// Common events
TokenAccountEvent(TokenAccountEvent),
NonceAccountEvent(NonceAccountEvent),
TokenInfoEvent(TokenInfoEvent),
BlockMetaEvent(BlockMetaEvent),
}
// 为Box<dyn UnifiedEvent>实现Clone
impl Clone for Box<dyn UnifiedEvent> {
fn clone(&self) -> Self {
self.clone_boxed()
impl UnifiedEvent {
pub fn metadata(&self) -> &EventMetadata {
match self {
UnifiedEvent::BonkTradeEvent(e) => &e.metadata,
UnifiedEvent::BonkPoolCreateEvent(e) => &e.metadata,
UnifiedEvent::BonkMigrateToAmmEvent(e) => &e.metadata,
UnifiedEvent::BonkMigrateToCpswapEvent(e) => &e.metadata,
UnifiedEvent::BonkPoolStateAccountEvent(e) => &e.metadata,
UnifiedEvent::BonkGlobalConfigAccountEvent(e) => &e.metadata,
UnifiedEvent::BonkPlatformConfigAccountEvent(e) => &e.metadata,
UnifiedEvent::PumpFunCreateTokenEvent(e) => &e.metadata,
UnifiedEvent::PumpFunTradeEvent(e) => &e.metadata,
UnifiedEvent::PumpFunMigrateEvent(e) => &e.metadata,
UnifiedEvent::PumpFunBondingCurveAccountEvent(e) => &e.metadata,
UnifiedEvent::PumpFunGlobalAccountEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapBuyEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapSellEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapCreatePoolEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapDepositEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapWithdrawEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapGlobalConfigAccountEvent(e) => &e.metadata,
UnifiedEvent::PumpSwapPoolAccountEvent(e) => &e.metadata,
UnifiedEvent::RaydiumAmmV4SwapEvent(e) => &e.metadata,
UnifiedEvent::RaydiumAmmV4DepositEvent(e) => &e.metadata,
UnifiedEvent::RaydiumAmmV4WithdrawEvent(e) => &e.metadata,
UnifiedEvent::RaydiumAmmV4WithdrawPnlEvent(e) => &e.metadata,
UnifiedEvent::RaydiumAmmV4Initialize2Event(e) => &e.metadata,
UnifiedEvent::RaydiumAmmV4AmmInfoAccountEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmSwapEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmSwapV2Event(e) => &e.metadata,
UnifiedEvent::RaydiumClmmClosePositionEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmIncreaseLiquidityV2Event(e) => &e.metadata,
UnifiedEvent::RaydiumClmmDecreaseLiquidityV2Event(e) => &e.metadata,
UnifiedEvent::RaydiumClmmCreatePoolEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmOpenPositionWithToken22NftEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmOpenPositionV2Event(e) => &e.metadata,
UnifiedEvent::RaydiumClmmAmmConfigAccountEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmPoolStateAccountEvent(e) => &e.metadata,
UnifiedEvent::RaydiumClmmTickArrayStateAccountEvent(e) => &e.metadata,
UnifiedEvent::RaydiumCpmmSwapEvent(e) => &e.metadata,
UnifiedEvent::RaydiumCpmmDepositEvent(e) => &e.metadata,
UnifiedEvent::RaydiumCpmmWithdrawEvent(e) => &e.metadata,
UnifiedEvent::RaydiumCpmmInitializeEvent(e) => &e.metadata,
UnifiedEvent::RaydiumCpmmAmmConfigAccountEvent(e) => &e.metadata,
UnifiedEvent::RaydiumCpmmPoolStateAccountEvent(e) => &e.metadata,
UnifiedEvent::TokenAccountEvent(e) => &e.metadata,
UnifiedEvent::NonceAccountEvent(e) => &e.metadata,
UnifiedEvent::TokenInfoEvent(e) => &e.metadata,
UnifiedEvent::BlockMetaEvent(e) => &e.metadata,
}
}
pub fn metadata_mut(&mut self) -> &mut EventMetadata {
match self {
UnifiedEvent::BonkTradeEvent(e) => &mut e.metadata,
UnifiedEvent::BonkPoolCreateEvent(e) => &mut e.metadata,
UnifiedEvent::BonkMigrateToAmmEvent(e) => &mut e.metadata,
UnifiedEvent::BonkMigrateToCpswapEvent(e) => &mut e.metadata,
UnifiedEvent::BonkPoolStateAccountEvent(e) => &mut e.metadata,
UnifiedEvent::BonkGlobalConfigAccountEvent(e) => &mut e.metadata,
UnifiedEvent::BonkPlatformConfigAccountEvent(e) => &mut e.metadata,
UnifiedEvent::PumpFunCreateTokenEvent(e) => &mut e.metadata,
UnifiedEvent::PumpFunTradeEvent(e) => &mut e.metadata,
UnifiedEvent::PumpFunMigrateEvent(e) => &mut e.metadata,
UnifiedEvent::PumpFunBondingCurveAccountEvent(e) => &mut e.metadata,
UnifiedEvent::PumpFunGlobalAccountEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapBuyEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapSellEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapCreatePoolEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapDepositEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapWithdrawEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapGlobalConfigAccountEvent(e) => &mut e.metadata,
UnifiedEvent::PumpSwapPoolAccountEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumAmmV4SwapEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumAmmV4DepositEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumAmmV4WithdrawEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumAmmV4WithdrawPnlEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumAmmV4Initialize2Event(e) => &mut e.metadata,
UnifiedEvent::RaydiumAmmV4AmmInfoAccountEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmSwapEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmSwapV2Event(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmClosePositionEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmIncreaseLiquidityV2Event(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmDecreaseLiquidityV2Event(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmCreatePoolEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmOpenPositionWithToken22NftEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmOpenPositionV2Event(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmAmmConfigAccountEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmPoolStateAccountEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumClmmTickArrayStateAccountEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumCpmmSwapEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumCpmmDepositEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumCpmmWithdrawEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumCpmmInitializeEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumCpmmAmmConfigAccountEvent(e) => &mut e.metadata,
UnifiedEvent::RaydiumCpmmPoolStateAccountEvent(e) => &mut e.metadata,
UnifiedEvent::TokenAccountEvent(e) => &mut e.metadata,
UnifiedEvent::NonceAccountEvent(e) => &mut e.metadata,
UnifiedEvent::TokenInfoEvent(e) => &mut e.metadata,
UnifiedEvent::BlockMetaEvent(e) => &mut e.metadata,
}
}
}
+1 -35
View File
@@ -3,38 +3,4 @@ pub mod core;
pub mod protocols;
pub use core::traits::UnifiedEvent;
pub use protocols::types::Protocol;
/// 宏:简化 downcast_ref 模式匹配
///
/// # 使用示例
/// ```
/// use sol_trade_sdk::event_parser::match_event;
///
/// match_event!(event, {
/// PumpSwapCreatePoolEvent => |typed_event| {
/// println!("CreatePool event: {:?}", typed_event);
/// },
/// PumpSwapDepositEvent => |typed_event| {
/// // 处理存款事件
/// },
/// });
/// ```
#[macro_export]
macro_rules! match_event {
($event:expr, {
$($event_type:ty => $handler:expr),* $(,)?
}) => {
$(
if let Some(typed_event) = $event.as_any().downcast_ref::<$event_type>() {
$handler(typed_event.clone());
} else
)*
{
// 默认情况:什么都不做
}
};
}
// 重新导出宏以便于使用
pub use match_event;
pub use protocols::types::Protocol;
@@ -1,4 +1,3 @@
use crate::impl_unified_event;
use crate::streaming::event_parser::common::{types::EventType, EventMetadata};
use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
@@ -36,6 +35,3 @@ impl BlockMetaEvent {
Self { metadata, slot, block_hash }
}
}
// 使用macro生成UnifiedEvent实现
impl_unified_event!(BlockMetaEvent,);
@@ -1,4 +1,3 @@
use crate::impl_unified_event;
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::bonk::types::{
CurveParams, MintParams, PoolStatus, TradeDirection, VestingParams,
@@ -82,26 +81,26 @@ pub fn bonk_trade_event_log_decode(data: &[u8]) -> Option<BonkTradeEvent> {
}
// Macro to generate UnifiedEvent implementation, specifying the fields to be merged
impl_unified_event!(
BonkTradeEvent,
pool_state,
total_base_sell,
virtual_base,
virtual_quote,
real_base_before,
real_quote_before,
real_base_after,
real_quote_after,
amount_in,
amount_out,
protocol_fee,
platform_fee,
creator_fee,
share_fee,
trade_direction,
pool_status,
exact_in
);
// impl_unified_event!(
// BonkTradeEvent,
// pool_state,
// total_base_sell,
// virtual_base,
// virtual_quote,
// real_base_before,
// real_quote_before,
// real_base_after,
// real_quote_after,
// amount_in,
// amount_out,
// protocol_fee,
// platform_fee,
// creator_fee,
// share_fee,
// trade_direction,
// pool_status,
// exact_in
// );
/// Create pool event
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -141,16 +140,16 @@ pub fn bonk_pool_create_event_log_decode(data: &[u8]) -> Option<BonkPoolCreateEv
}
// Macro to generate UnifiedEvent implementation, specifying the fields to be merged
impl_unified_event!(
BonkPoolCreateEvent,
pool_state,
creator,
config,
base_mint_param,
curve_param,
vesting_param,
amm_fee_on
);
// impl_unified_event!(
// BonkPoolCreateEvent,
// pool_state,
// creator,
// config,
// base_mint_param,
// curve_param,
// vesting_param,
// amm_fee_on
// );
/// Create pool event
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -227,12 +226,12 @@ pub struct BonkMigrateToAmmEvent {
}
// Macro to generate UnifiedEvent implementation, specifying the fields to be merged
impl_unified_event!(
BonkMigrateToAmmEvent,
base_lot_size,
quote_lot_size,
market_vault_signer_nonce
);
// impl_unified_event!(
// BonkMigrateToAmmEvent,
// base_lot_size,
// quote_lot_size,
// market_vault_signer_nonce
// );
// Migrate to CP Swap event
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -270,9 +269,6 @@ pub struct BonkMigrateToCpswapEvent {
pub remaining_accounts: Vec<Pubkey>,
}
// Macro to generate UnifiedEvent implementation, specifying the fields to be merged
impl_unified_event!(BonkMigrateToCpswapEvent,);
/// 池状态
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct BonkPoolStateAccountEvent {
@@ -284,7 +280,6 @@ pub struct BonkPoolStateAccountEvent {
pub rent_epoch: u64,
pub pool_state: PoolState,
}
impl_unified_event!(BonkPoolStateAccountEvent,);
/// 全局配置
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -297,7 +292,6 @@ pub struct BonkGlobalConfigAccountEvent {
pub rent_epoch: u64,
pub global_config: GlobalConfig,
}
impl_unified_event!(BonkGlobalConfigAccountEvent,);
/// 平台配置
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -310,7 +304,6 @@ pub struct BonkPlatformConfigAccountEvent {
pub rent_epoch: u64,
pub platform_config: PlatformConfig,
}
impl_unified_event!(BonkPlatformConfigAccountEvent,);
/// Event discriminator constants
pub mod discriminators {
@@ -113,19 +113,16 @@ pub const CONFIGS: &[GenericEventParseConfig] = &[
fn parse_pool_create_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if let Some(event) = bonk_pool_create_event_log_decode(data) {
Some(Box::new(BonkPoolCreateEvent { metadata, ..event }))
Some(UnifiedEvent::BonkPoolCreateEvent(BonkPoolCreateEvent { metadata, ..event }))
} else {
None
}
}
/// Parse trade event
fn parse_trade_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_trade_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = bonk_trade_event_log_decode(data) {
if metadata.event_type == EventType::BonkBuyExactIn
|| metadata.event_type == EventType::BonkBuyExactOut
@@ -139,7 +136,7 @@ fn parse_trade_inner_instruction(
{
return None;
}
Some(Box::new(BonkTradeEvent { metadata, ..event }))
Some(UnifiedEvent::BonkTradeEvent(BonkTradeEvent { metadata, ..event }))
} else {
None
}
@@ -150,7 +147,7 @@ fn parse_buy_exact_in_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 18 {
return None;
}
@@ -159,7 +156,7 @@ fn parse_buy_exact_in_instruction(
let minimum_amount_out = read_u64_le(data, 8)?;
let share_fee_rate = read_u64_le(data, 16)?;
Some(Box::new(BonkTradeEvent {
Some(UnifiedEvent::BonkTradeEvent(BonkTradeEvent {
metadata,
amount_in,
minimum_amount_out,
@@ -188,7 +185,7 @@ fn parse_buy_exact_out_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 18 {
return None;
}
@@ -197,7 +194,7 @@ fn parse_buy_exact_out_instruction(
let maximum_amount_in = read_u64_le(data, 8)?;
let share_fee_rate = read_u64_le(data, 16)?;
Some(Box::new(BonkTradeEvent {
Some(UnifiedEvent::BonkTradeEvent(BonkTradeEvent {
metadata,
amount_out,
maximum_amount_in,
@@ -226,7 +223,7 @@ fn parse_sell_exact_in_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 18 {
return None;
}
@@ -235,7 +232,7 @@ fn parse_sell_exact_in_instruction(
let minimum_amount_out = read_u64_le(data, 8)?;
let share_fee_rate = read_u64_le(data, 16)?;
Some(Box::new(BonkTradeEvent {
Some(UnifiedEvent::BonkTradeEvent(BonkTradeEvent {
metadata,
amount_in,
minimum_amount_out,
@@ -264,7 +261,7 @@ fn parse_sell_exact_out_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 18 {
return None;
}
@@ -273,7 +270,7 @@ fn parse_sell_exact_out_instruction(
let maximum_amount_in = read_u64_le(data, 8)?;
let share_fee_rate = read_u64_le(data, 16)?;
Some(Box::new(BonkTradeEvent {
Some(UnifiedEvent::BonkTradeEvent(BonkTradeEvent {
metadata,
amount_out,
maximum_amount_in,
@@ -303,7 +300,7 @@ fn parse_initialize_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 {
return None;
}
@@ -313,7 +310,7 @@ fn parse_initialize_instruction(
let curve_param = parse_curve_params(data, &mut offset)?;
let vesting_param = parse_vesting_params(data, &mut offset)?;
Some(Box::new(BonkPoolCreateEvent {
Some(UnifiedEvent::BonkPoolCreateEvent(BonkPoolCreateEvent {
metadata,
payer: accounts[0],
creator: accounts[1],
@@ -336,7 +333,7 @@ fn parse_initialize_v2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 {
return None;
}
@@ -347,7 +344,7 @@ fn parse_initialize_v2_instruction(
let vesting_param = parse_vesting_params(data, &mut offset)?;
let amm_fee_on = data[offset];
Some(Box::new(BonkPoolCreateEvent {
Some(UnifiedEvent::BonkPoolCreateEvent(BonkPoolCreateEvent {
metadata,
payer: accounts[0],
creator: accounts[1],
@@ -375,7 +372,7 @@ fn parse_initialize_with_token_2022_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 {
return None;
}
@@ -386,7 +383,7 @@ fn parse_initialize_with_token_2022_instruction(
let vesting_param = parse_vesting_params(data, &mut offset)?;
let amm_fee_on = data[offset];
Some(Box::new(BonkPoolCreateEvent {
Some(UnifiedEvent::BonkPoolCreateEvent(BonkPoolCreateEvent {
metadata,
payer: accounts[0],
creator: accounts[1],
@@ -519,7 +516,7 @@ fn parse_migrate_to_amm_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 {
return None;
}
@@ -528,7 +525,7 @@ fn parse_migrate_to_amm_instruction(
let quote_lot_size = u64::from_le_bytes(data[8..16].try_into().unwrap());
let market_vault_signer_nonce = data[16];
Some(Box::new(BonkMigrateToAmmEvent {
Some(UnifiedEvent::BonkMigrateToAmmEvent(BonkMigrateToAmmEvent {
metadata,
base_lot_size,
quote_lot_size,
@@ -574,8 +571,8 @@ fn parse_migrate_to_cpswap_instruction(
_data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
Some(Box::new(BonkMigrateToCpswapEvent {
) -> Option<UnifiedEvent> {
Some(UnifiedEvent::BonkMigrateToCpswapEvent(BonkMigrateToCpswapEvent {
metadata,
payer: accounts[0],
base_mint: accounts[1],
@@ -132,15 +132,12 @@ pub fn pool_state_decode(data: &[u8]) -> Option<PoolState> {
borsh::from_slice::<PoolState>(&data[..POOL_STATE_SIZE]).ok()
}
pub fn pool_state_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn pool_state_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < POOL_STATE_SIZE + 8 {
return None;
}
if let Some(pool_state) = pool_state_decode(&account.data[8..POOL_STATE_SIZE + 8]) {
Some(Box::new(BonkPoolStateAccountEvent {
Some(UnifiedEvent::BonkPoolStateAccountEvent(BonkPoolStateAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -186,12 +183,12 @@ pub fn global_config_decode(data: &[u8]) -> Option<GlobalConfig> {
pub fn global_config_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if account.data.len() < GLOBAL_CONFIG_SIZE + 8 {
return None;
}
if let Some(global_config) = global_config_decode(&account.data[8..GLOBAL_CONFIG_SIZE + 8]) {
Some(Box::new(BonkGlobalConfigAccountEvent {
Some(UnifiedEvent::BonkGlobalConfigAccountEvent(BonkGlobalConfigAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -232,14 +229,14 @@ pub fn platform_config_decode(data: &[u8]) -> Option<PlatformConfig> {
pub fn platform_config_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if account.data.len() < PLATFORM_CONFIG_SIZE + 8 {
return None;
}
if let Some(platform_config) =
platform_config_decode(&account.data[8..PLATFORM_CONFIG_SIZE + 8])
{
Some(Box::new(BonkPlatformConfigAccountEvent {
Some(UnifiedEvent::BonkPlatformConfigAccountEvent(BonkPlatformConfigAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -2,7 +2,6 @@ use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
use solana_sdk::pubkey::Pubkey;
use crate::impl_unified_event;
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::pumpfun::types::{BondingCurve, Global};
@@ -37,18 +36,18 @@ pub fn pumpfun_create_token_event_log_decode(data: &[u8]) -> Option<PumpFunCreat
borsh::from_slice::<PumpFunCreateTokenEvent>(&data[..PUMPFUN_CREATE_TOKEN_EVENT_LOG_SIZE]).ok()
}
impl_unified_event!(
PumpFunCreateTokenEvent,
mint,
bonding_curve,
user,
creator,
timestamp,
virtual_token_reserves,
virtual_sol_reserves,
real_token_reserves,
token_total_supply
);
// impl_unified_event!(
// PumpFunCreateTokenEvent,
// mint,
// bonding_curve,
// user,
// creator,
// timestamp,
// virtual_token_reserves,
// virtual_sol_reserves,
// real_token_reserves,
// token_total_supply
// );
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct PumpFunTradeEvent {
@@ -126,25 +125,25 @@ pub fn pumpfun_trade_event_log_decode(data: &[u8]) -> Option<PumpFunTradeEvent>
borsh::from_slice::<PumpFunTradeEvent>(&data[..PUMPFUN_TRADE_EVENT_LOG_SIZE]).ok()
}
impl_unified_event!(
PumpFunTradeEvent,
mint,
sol_amount,
token_amount,
is_buy,
user,
timestamp,
virtual_sol_reserves,
virtual_token_reserves,
real_sol_reserves,
real_token_reserves,
fee_recipient,
fee_basis_points,
fee,
creator,
creator_fee_basis_points,
creator_fee
);
// impl_unified_event!(
// PumpFunTradeEvent,
// mint,
// sol_amount,
// token_amount,
// is_buy,
// user,
// timestamp,
// virtual_sol_reserves,
// virtual_token_reserves,
// real_sol_reserves,
// real_token_reserves,
// fee_recipient,
// fee_basis_points,
// fee,
// creator,
// creator_fee_basis_points,
// creator_fee
// );
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct PumpFunMigrateEvent {
@@ -211,17 +210,17 @@ pub fn pumpfun_migrate_event_log_decode(data: &[u8]) -> Option<PumpFunMigrateEve
borsh::from_slice::<PumpFunMigrateEvent>(&data[..PUMPFUN_MIGRATE_EVENT_LOG_SIZE]).ok()
}
impl_unified_event!(
PumpFunMigrateEvent,
user,
mint,
mint_amount,
sol_amount,
pool_migration_fee,
bonding_curve,
timestamp,
pool
);
// impl_unified_event!(
// PumpFunMigrateEvent,
// user,
// mint,
// mint_amount,
// sol_amount,
// pool_migration_fee,
// bonding_curve,
// timestamp,
// pool
// );
/// 铸币曲线
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -236,8 +235,6 @@ pub struct PumpFunBondingCurveAccountEvent {
pub bonding_curve: BondingCurve,
}
impl_unified_event!(PumpFunBondingCurveAccountEvent,);
/// 全局配置
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct PumpFunGlobalAccountEvent {
@@ -250,7 +247,6 @@ pub struct PumpFunGlobalAccountEvent {
pub rent_epoch: u64,
pub global: Global,
}
impl_unified_event!(PumpFunGlobalAccountEvent,);
/// 事件鉴别器常量
pub mod discriminators {
@@ -60,12 +60,9 @@ pub const CONFIGS: &[GenericEventParseConfig] = &[
];
/// 解析迁移事件
fn parse_migrate_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_migrate_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = pumpfun_migrate_event_log_decode(data) {
Some(Box::new(PumpFunMigrateEvent { metadata, ..event }))
Some(UnifiedEvent::PumpFunMigrateEvent(PumpFunMigrateEvent { metadata, ..event }))
} else {
None
}
@@ -75,21 +72,18 @@ fn parse_migrate_inner_instruction(
fn parse_create_token_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if let Some(event) = pumpfun_create_token_event_log_decode(data) {
Some(Box::new(PumpFunCreateTokenEvent { metadata, ..event }))
Some(UnifiedEvent::PumpFunCreateTokenEvent(PumpFunCreateTokenEvent { metadata, ..event }))
} else {
None
}
}
/// 解析交易事件
fn parse_trade_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_trade_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = pumpfun_trade_event_log_decode(data) {
Some(Box::new(PumpFunTradeEvent { metadata, ..event }))
Some(UnifiedEvent::PumpFunTradeEvent(PumpFunTradeEvent { metadata, ..event }))
} else {
None
}
@@ -100,7 +94,7 @@ fn parse_create_token_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 11 {
return None;
}
@@ -141,7 +135,7 @@ fn parse_create_token_instruction(
Pubkey::default()
};
Some(Box::new(PumpFunCreateTokenEvent {
Some(UnifiedEvent::PumpFunCreateTokenEvent(PumpFunCreateTokenEvent {
metadata,
name: name.to_string(),
symbol: symbol.to_string(),
@@ -161,13 +155,13 @@ fn parse_buy_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 13 {
return None;
}
let amount = u64::from_le_bytes(data[0..8].try_into().unwrap());
let max_sol_cost = u64::from_le_bytes(data[8..16].try_into().unwrap());
Some(Box::new(PumpFunTradeEvent {
Some(UnifiedEvent::PumpFunTradeEvent(PumpFunTradeEvent {
metadata,
global: accounts[0],
fee_recipient: accounts[1],
@@ -195,13 +189,13 @@ fn parse_sell_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 11 {
return None;
}
let amount = u64::from_le_bytes(data[0..8].try_into().unwrap());
let min_sol_output = u64::from_le_bytes(data[8..16].try_into().unwrap());
Some(Box::new(PumpFunTradeEvent {
Some(UnifiedEvent::PumpFunTradeEvent(PumpFunTradeEvent {
metadata,
global: accounts[0],
fee_recipient: accounts[1],
@@ -229,11 +223,11 @@ fn parse_migrate_instruction(
_data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if accounts.len() < 24 {
return None;
}
Some(Box::new(PumpFunMigrateEvent {
Some(UnifiedEvent::PumpFunMigrateEvent(PumpFunMigrateEvent {
metadata,
global: accounts[0],
withdraw_authority: accounts[1],
@@ -34,12 +34,12 @@ pub fn bonding_curve_decode(data: &[u8]) -> Option<BondingCurve> {
pub fn bonding_curve_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if account.data.len() < BONDING_CURVE_SIZE + 8 {
return None;
}
if let Some(bonding_curve) = bonding_curve_decode(&account.data[8..BONDING_CURVE_SIZE + 8]) {
Some(Box::new(PumpFunBondingCurveAccountEvent {
Some(UnifiedEvent::PumpFunBondingCurveAccountEvent(PumpFunBondingCurveAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -81,15 +81,12 @@ pub fn global_decode(data: &[u8]) -> Option<Global> {
borsh::from_slice::<Global>(&data[..GLOBAL_SIZE]).ok()
}
pub fn global_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn global_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < GLOBAL_SIZE + 8 {
return None;
}
if let Some(global) = global_decode(&account.data[8..GLOBAL_SIZE + 8]) {
Some(Box::new(PumpFunGlobalAccountEvent {
Some(UnifiedEvent::PumpFunGlobalAccountEvent(PumpFunGlobalAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -2,7 +2,6 @@ use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
use solana_sdk::pubkey::Pubkey;
use crate::impl_unified_event;
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::pumpswap::types::{GlobalConfig, Pool};
@@ -67,32 +66,32 @@ pub fn pump_swap_buy_event_log_decode(data: &[u8]) -> Option<PumpSwapBuyEvent> {
}
// 使用宏生成UnifiedEvent实现,指定需要合并的字段
impl_unified_event!(
PumpSwapBuyEvent,
timestamp,
base_amount_out,
max_quote_amount_in,
user_base_token_reserves,
user_quote_token_reserves,
pool_base_token_reserves,
pool_quote_token_reserves,
quote_amount_in,
lp_fee_basis_points,
lp_fee,
protocol_fee_basis_points,
protocol_fee,
quote_amount_in_with_lp_fee,
user_quote_amount_in,
pool,
user,
user_base_token_account,
user_quote_token_account,
protocol_fee_recipient,
protocol_fee_recipient_token_account,
coin_creator,
coin_creator_fee_basis_points,
coin_creator_fee
);
// impl_unified_event!(
// PumpSwapBuyEvent,
// timestamp,
// base_amount_out,
// max_quote_amount_in,
// user_base_token_reserves,
// user_quote_token_reserves,
// pool_base_token_reserves,
// pool_quote_token_reserves,
// quote_amount_in,
// lp_fee_basis_points,
// lp_fee,
// protocol_fee_basis_points,
// protocol_fee,
// quote_amount_in_with_lp_fee,
// user_quote_amount_in,
// pool,
// user,
// user_base_token_account,
// user_quote_token_account,
// protocol_fee_recipient,
// protocol_fee_recipient_token_account,
// coin_creator,
// coin_creator_fee_basis_points,
// coin_creator_fee
// );
/// 卖出事件
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -150,32 +149,32 @@ pub fn pump_swap_sell_event_log_decode(data: &[u8]) -> Option<PumpSwapSellEvent>
}
// 使用宏生成UnifiedEvent实现,指定需要合并的字段
impl_unified_event!(
PumpSwapSellEvent,
timestamp,
base_amount_in,
min_quote_amount_out,
user_base_token_reserves,
user_quote_token_reserves,
pool_base_token_reserves,
pool_quote_token_reserves,
quote_amount_out,
lp_fee_basis_points,
lp_fee,
protocol_fee_basis_points,
protocol_fee,
quote_amount_out_without_lp_fee,
user_quote_amount_out,
pool,
user,
user_base_token_account,
user_quote_token_account,
protocol_fee_recipient,
protocol_fee_recipient_token_account,
coin_creator,
coin_creator_fee_basis_points,
coin_creator_fee
);
// impl_unified_event!(
// PumpSwapSellEvent,
// timestamp,
// base_amount_in,
// min_quote_amount_out,
// user_base_token_reserves,
// user_quote_token_reserves,
// pool_base_token_reserves,
// pool_quote_token_reserves,
// quote_amount_out,
// lp_fee_basis_points,
// lp_fee,
// protocol_fee_basis_points,
// protocol_fee,
// quote_amount_out_without_lp_fee,
// user_quote_amount_out,
// pool,
// user,
// user_base_token_account,
// user_quote_token_account,
// protocol_fee_recipient,
// protocol_fee_recipient_token_account,
// coin_creator,
// coin_creator_fee_basis_points,
// coin_creator_fee
// );
/// 创建池子事件
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -219,29 +218,29 @@ pub fn pump_swap_create_pool_event_log_decode(data: &[u8]) -> Option<PumpSwapCre
borsh::from_slice::<PumpSwapCreatePoolEvent>(&data[..PUMP_SWAP_CREATE_POOL_EVENT_LOG_SIZE]).ok()
}
impl_unified_event!(
PumpSwapCreatePoolEvent,
timestamp,
index,
creator,
base_mint,
quote_mint,
base_mint_decimals,
quote_mint_decimals,
base_amount_in,
quote_amount_in,
pool_base_amount,
pool_quote_amount,
minimum_liquidity,
initial_liquidity,
lp_token_amount_out,
pool_bump,
pool,
lp_mint,
user_base_token_account,
user_quote_token_account,
coin_creator
);
// impl_unified_event!(
// PumpSwapCreatePoolEvent,
// timestamp,
// index,
// creator,
// base_mint,
// quote_mint,
// base_mint_decimals,
// quote_mint_decimals,
// base_amount_in,
// quote_amount_in,
// pool_base_amount,
// pool_quote_amount,
// minimum_liquidity,
// initial_liquidity,
// lp_token_amount_out,
// pool_bump,
// pool,
// lp_mint,
// user_base_token_account,
// user_quote_token_account,
// coin_creator
// );
/// 存款事件
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -283,25 +282,25 @@ pub fn pump_swap_deposit_event_log_decode(data: &[u8]) -> Option<PumpSwapDeposit
borsh::from_slice::<PumpSwapDepositEvent>(&data[..PUMP_SWAP_DEPOSIT_EVENT_LOG_SIZE]).ok()
}
impl_unified_event!(
PumpSwapDepositEvent,
timestamp,
lp_token_amount_out,
max_base_amount_in,
max_quote_amount_in,
user_base_token_reserves,
user_quote_token_reserves,
pool_base_token_reserves,
pool_quote_token_reserves,
base_amount_in,
quote_amount_in,
lp_mint_supply,
pool,
user,
user_base_token_account,
user_quote_token_account,
user_pool_token_account
);
// impl_unified_event!(
// PumpSwapDepositEvent,
// timestamp,
// lp_token_amount_out,
// max_base_amount_in,
// max_quote_amount_in,
// user_base_token_reserves,
// user_quote_token_reserves,
// pool_base_token_reserves,
// pool_quote_token_reserves,
// base_amount_in,
// quote_amount_in,
// lp_mint_supply,
// pool,
// user,
// user_base_token_account,
// user_quote_token_account,
// user_pool_token_account
// );
/// 提款事件
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -343,25 +342,25 @@ pub fn pump_swap_withdraw_event_log_decode(data: &[u8]) -> Option<PumpSwapWithdr
borsh::from_slice::<PumpSwapWithdrawEvent>(&data[..PUMP_SWAP_WITHDRAW_EVENT_LOG_SIZE]).ok()
}
impl_unified_event!(
PumpSwapWithdrawEvent,
timestamp,
lp_token_amount_in,
min_base_amount_out,
min_quote_amount_out,
user_base_token_reserves,
user_quote_token_reserves,
pool_base_token_reserves,
pool_quote_token_reserves,
base_amount_out,
quote_amount_out,
lp_mint_supply,
pool,
user,
user_base_token_account,
user_quote_token_account,
user_pool_token_account
);
// impl_unified_event!(
// PumpSwapWithdrawEvent,
// timestamp,
// lp_token_amount_in,
// min_base_amount_out,
// min_quote_amount_out,
// user_base_token_reserves,
// user_quote_token_reserves,
// pool_base_token_reserves,
// pool_quote_token_reserves,
// base_amount_out,
// quote_amount_out,
// lp_mint_supply,
// pool,
// user,
// user_base_token_account,
// user_quote_token_account,
// user_pool_token_account
// );
/// 全局配置
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -375,7 +374,6 @@ pub struct PumpSwapGlobalConfigAccountEvent {
pub rent_epoch: u64,
pub global_config: GlobalConfig,
}
impl_unified_event!(PumpSwapGlobalConfigAccountEvent,);
/// 池
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -389,7 +387,6 @@ pub struct PumpSwapPoolAccountEvent {
pub rent_epoch: u64,
pub pool: Pool,
}
impl_unified_event!(PumpSwapPoolAccountEvent,);
/// 事件鉴别器常量
pub mod discriminators {
@@ -70,24 +70,18 @@ pub const CONFIGS: &[GenericEventParseConfig] = &[
];
/// 解析买入日志事件
fn parse_buy_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_buy_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = pump_swap_buy_event_log_decode(data) {
Some(Box::new(PumpSwapBuyEvent { metadata, ..event }))
Some(UnifiedEvent::PumpSwapBuyEvent(PumpSwapBuyEvent { metadata, ..event }))
} else {
None
}
}
/// 解析卖出日志事件
fn parse_sell_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_sell_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = pump_swap_sell_event_log_decode(data) {
Some(Box::new(PumpSwapSellEvent { metadata, ..event }))
Some(UnifiedEvent::PumpSwapSellEvent(PumpSwapSellEvent { metadata, ..event }))
} else {
None
}
@@ -97,33 +91,27 @@ fn parse_sell_inner_instruction(
fn parse_create_pool_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if let Some(event) = pump_swap_create_pool_event_log_decode(data) {
Some(Box::new(PumpSwapCreatePoolEvent { metadata, ..event }))
Some(UnifiedEvent::PumpSwapCreatePoolEvent(PumpSwapCreatePoolEvent { metadata, ..event }))
} else {
None
}
}
/// 解析存款日志事件
fn parse_deposit_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_deposit_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = pump_swap_deposit_event_log_decode(data) {
Some(Box::new(PumpSwapDepositEvent { metadata, ..event }))
Some(UnifiedEvent::PumpSwapDepositEvent(PumpSwapDepositEvent { metadata, ..event }))
} else {
None
}
}
/// 解析提款日志事件
fn parse_withdraw_inner_instruction(
data: &[u8],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
fn parse_withdraw_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
if let Some(event) = pump_swap_withdraw_event_log_decode(data) {
Some(Box::new(PumpSwapWithdrawEvent { metadata, ..event }))
Some(UnifiedEvent::PumpSwapWithdrawEvent(PumpSwapWithdrawEvent { metadata, ..event }))
} else {
None
}
@@ -134,7 +122,7 @@ fn parse_buy_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 11 {
return None;
}
@@ -142,7 +130,7 @@ fn parse_buy_instruction(
let base_amount_out = read_u64_le(data, 0)?;
let max_quote_amount_in = read_u64_le(data, 8)?;
Some(Box::new(PumpSwapBuyEvent {
Some(UnifiedEvent::PumpSwapBuyEvent(PumpSwapBuyEvent {
metadata,
base_amount_out,
max_quote_amount_in,
@@ -169,7 +157,7 @@ fn parse_sell_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 11 {
return None;
}
@@ -177,7 +165,7 @@ fn parse_sell_instruction(
let base_amount_in = read_u64_le(data, 0)?;
let min_quote_amount_out = read_u64_le(data, 8)?;
Some(Box::new(PumpSwapSellEvent {
Some(UnifiedEvent::PumpSwapSellEvent(PumpSwapSellEvent {
metadata,
base_amount_in,
min_quote_amount_out,
@@ -204,7 +192,7 @@ fn parse_create_pool_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 18 || accounts.len() < 11 {
return None;
}
@@ -218,7 +206,7 @@ fn parse_create_pool_instruction(
Pubkey::default()
};
Some(Box::new(PumpSwapCreatePoolEvent {
Some(UnifiedEvent::PumpSwapCreatePoolEvent(PumpSwapCreatePoolEvent {
metadata,
index,
base_amount_in,
@@ -243,7 +231,7 @@ fn parse_deposit_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 11 {
return None;
}
@@ -252,7 +240,7 @@ fn parse_deposit_instruction(
let max_base_amount_in = u64::from_le_bytes(data[8..16].try_into().ok()?);
let max_quote_amount_in = u64::from_le_bytes(data[16..24].try_into().ok()?);
Some(Box::new(PumpSwapDepositEvent {
Some(UnifiedEvent::PumpSwapDepositEvent(PumpSwapDepositEvent {
metadata,
lp_token_amount_out,
max_base_amount_in,
@@ -275,7 +263,7 @@ fn parse_withdraw_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 11 {
return None;
}
@@ -284,7 +272,7 @@ fn parse_withdraw_instruction(
let min_base_amount_out = u64::from_le_bytes(data[8..16].try_into().ok()?);
let min_quote_amount_out = u64::from_le_bytes(data[16..24].try_into().ok()?);
Some(Box::new(PumpSwapWithdrawEvent {
Some(UnifiedEvent::PumpSwapWithdrawEvent(PumpSwapWithdrawEvent {
metadata,
lp_token_amount_in,
min_base_amount_out,
@@ -5,9 +5,7 @@ use solana_sdk::pubkey::Pubkey;
use crate::streaming::{
event_parser::{
common::EventMetadata,
protocols::pumpswap::{
PumpSwapGlobalConfigAccountEvent, PumpSwapPoolAccountEvent,
},
protocols::pumpswap::{PumpSwapGlobalConfigAccountEvent, PumpSwapPoolAccountEvent},
UnifiedEvent,
},
grpc::AccountPretty,
@@ -36,12 +34,12 @@ pub fn global_config_decode(data: &[u8]) -> Option<GlobalConfig> {
pub fn global_config_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if account.data.len() < GLOBAL_CONFIG_SIZE + 8 {
return None;
}
if let Some(config) = global_config_decode(&account.data[8..GLOBAL_CONFIG_SIZE + 8]) {
Some(Box::new(PumpSwapGlobalConfigAccountEvent {
Some(UnifiedEvent::PumpSwapGlobalConfigAccountEvent(PumpSwapGlobalConfigAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -78,15 +76,12 @@ pub fn pool_decode(data: &[u8]) -> Option<Pool> {
borsh::from_slice::<Pool>(&data[..POOL_SIZE]).ok()
}
pub fn pool_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn pool_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < POOL_SIZE + 8 {
return None;
}
if let Some(pool) = pool_decode(&account.data[8..POOL_SIZE + 8]) {
Some(Box::new(PumpSwapPoolAccountEvent {
Some(UnifiedEvent::PumpSwapPoolAccountEvent(PumpSwapPoolAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -1,6 +1,6 @@
use crate::streaming::event_parser::common::EventMetadata;
use crate::{
impl_unified_event, streaming::event_parser::protocols::raydium_amm_v4::types::AmmInfo,
streaming::event_parser::protocols::raydium_amm_v4::types::AmmInfo,
};
use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
@@ -38,8 +38,6 @@ pub struct RaydiumAmmV4SwapEvent {
pub user_source_owner: Pubkey,
}
impl_unified_event!(RaydiumAmmV4SwapEvent,);
/// 添加流动性
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct RaydiumAmmV4DepositEvent {
@@ -64,7 +62,6 @@ pub struct RaydiumAmmV4DepositEvent {
pub user_owner: Pubkey,
pub serum_event_queue: Pubkey,
}
impl_unified_event!(RaydiumAmmV4DepositEvent,);
/// 初始化
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -98,7 +95,6 @@ pub struct RaydiumAmmV4Initialize2Event {
pub user_token_pc: Pubkey,
pub user_lp_token_account: Pubkey,
}
impl_unified_event!(RaydiumAmmV4Initialize2Event,);
/// 移除流动性
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -130,7 +126,6 @@ pub struct RaydiumAmmV4WithdrawEvent {
pub serum_bids: Pubkey,
pub serum_asks: Pubkey,
}
impl_unified_event!(RaydiumAmmV4WithdrawEvent,);
/// 提现
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -156,7 +151,6 @@ pub struct RaydiumAmmV4WithdrawPnlEvent {
pub serum_pc_vault_account: Pubkey,
pub serum_vault_signer: Pubkey,
}
impl_unified_event!(RaydiumAmmV4WithdrawPnlEvent,);
/// 池信息
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -170,7 +164,6 @@ pub struct RaydiumAmmV4AmmInfoAccountEvent {
pub rent_epoch: u64,
pub amm_info: AmmInfo,
}
impl_unified_event!(RaydiumAmmV4AmmInfoAccountEvent,);
/// 事件鉴别器常量
pub mod discriminators {
@@ -82,12 +82,12 @@ fn parse_withdraw_pnl_instruction(
_data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if accounts.len() < 17 {
return None;
}
Some(Box::new(RaydiumAmmV4WithdrawPnlEvent {
Some(UnifiedEvent::RaydiumAmmV4WithdrawPnlEvent(RaydiumAmmV4WithdrawPnlEvent {
metadata,
token_program: accounts[0],
amm: accounts[1],
@@ -114,13 +114,13 @@ fn parse_withdraw_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 8 || accounts.len() < 22 {
return None;
}
let amount = read_u64_le(data, 0)?;
Some(Box::new(RaydiumAmmV4WithdrawEvent {
Some(UnifiedEvent::RaydiumAmmV4WithdrawEvent(RaydiumAmmV4WithdrawEvent {
metadata,
amount,
@@ -154,7 +154,7 @@ fn parse_initialize2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 25 || accounts.len() < 21 {
return None;
}
@@ -163,7 +163,7 @@ fn parse_initialize2_instruction(
let init_pc_amount = read_u64_le(data, 9)?;
let init_coin_amount = read_u64_le(data, 17)?;
Some(Box::new(RaydiumAmmV4Initialize2Event {
Some(UnifiedEvent::RaydiumAmmV4Initialize2Event(RaydiumAmmV4Initialize2Event {
metadata,
nonce,
open_time,
@@ -199,7 +199,7 @@ fn parse_deposit_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 14 {
return None;
}
@@ -207,7 +207,7 @@ fn parse_deposit_instruction(
let max_pc_amount = read_u64_le(data, 8)?;
let base_side = read_u64_le(data, 16)?;
Some(Box::new(RaydiumAmmV4DepositEvent {
Some(UnifiedEvent::RaydiumAmmV4DepositEvent(RaydiumAmmV4DepositEvent {
metadata,
max_coin_amount,
max_pc_amount,
@@ -235,7 +235,7 @@ fn parse_swap_base_output_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 17 {
return None;
}
@@ -249,7 +249,7 @@ fn parse_swap_base_output_instruction(
accounts.insert(4, Pubkey::default());
}
Some(Box::new(RaydiumAmmV4SwapEvent {
Some(UnifiedEvent::RaydiumAmmV4SwapEvent(RaydiumAmmV4SwapEvent {
metadata,
max_amount_in,
amount_out,
@@ -282,7 +282,7 @@ fn parse_swap_base_input_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 17 {
return None;
}
@@ -296,7 +296,7 @@ fn parse_swap_base_input_instruction(
accounts.insert(4, Pubkey::default());
}
Some(Box::new(RaydiumAmmV4SwapEvent {
Some(UnifiedEvent::RaydiumAmmV4SwapEvent(RaydiumAmmV4SwapEvent {
metadata,
amount_in,
minimum_amount_out,
@@ -86,15 +86,12 @@ pub fn amm_info_decode(data: &[u8]) -> Option<AmmInfo> {
borsh::from_slice::<AmmInfo>(&data[..AMM_INFO_SIZE]).ok()
}
pub fn amm_info_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn amm_info_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < AMM_INFO_SIZE {
return None;
}
if let Some(amm_info) = amm_info_decode(&account.data[..AMM_INFO_SIZE]) {
Some(Box::new(RaydiumAmmV4AmmInfoAccountEvent {
Some(UnifiedEvent::RaydiumAmmV4AmmInfoAccountEvent(RaydiumAmmV4AmmInfoAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -1,7 +1,7 @@
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::raydium_clmm::types::{PoolState, TickArrayState};
use crate::{
impl_unified_event, streaming::event_parser::protocols::raydium_clmm::types::AmmConfig,
streaming::event_parser::protocols::raydium_clmm::types::AmmConfig,
};
use serde::{Deserialize, Serialize};
use solana_sdk::pubkey::Pubkey;
@@ -27,7 +27,6 @@ pub struct RaydiumClmmSwapEvent {
pub remaining_accounts: Vec<Pubkey>,
}
impl_unified_event!(RaydiumClmmSwapEvent,);
/// 交易v2
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -52,7 +51,6 @@ pub struct RaydiumClmmSwapV2Event {
pub output_vault_mint: Pubkey,
pub remaining_accounts: Vec<Pubkey>,
}
impl_unified_event!(RaydiumClmmSwapV2Event,);
/// 关闭仓位
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -65,7 +63,6 @@ pub struct RaydiumClmmClosePositionEvent {
pub system_program: Pubkey,
pub token_program: Pubkey,
}
impl_unified_event!(RaydiumClmmClosePositionEvent,);
/// 减少流动性v2
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -92,7 +89,6 @@ pub struct RaydiumClmmDecreaseLiquidityV2Event {
pub vault1_mint: Pubkey,
pub remaining_accounts: Vec<Pubkey>,
}
impl_unified_event!(RaydiumClmmDecreaseLiquidityV2Event,);
/// 创建池
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -114,7 +110,6 @@ pub struct RaydiumClmmCreatePoolEvent {
pub system_program: Pubkey,
pub rent: Pubkey,
}
impl_unified_event!(RaydiumClmmCreatePoolEvent,);
/// 增加流动性v2
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -140,7 +135,6 @@ pub struct RaydiumClmmIncreaseLiquidityV2Event {
pub vault0_mint: Pubkey,
pub vault1_mint: Pubkey,
}
impl_unified_event!(RaydiumClmmIncreaseLiquidityV2Event,);
/// 打开仓位v2
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -177,7 +171,6 @@ pub struct RaydiumClmmOpenPositionWithToken22NftEvent {
pub vault0_mint: Pubkey,
pub vault1_mint: Pubkey,
}
impl_unified_event!(RaydiumClmmOpenPositionWithToken22NftEvent,);
/// 打开仓位V2
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -217,7 +210,6 @@ pub struct RaydiumClmmOpenPositionV2Event {
pub vault1_mint: Pubkey,
pub remaining_accounts: Vec<Pubkey>,
}
impl_unified_event!(RaydiumClmmOpenPositionV2Event,);
/// 池配置
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -230,7 +222,6 @@ pub struct RaydiumClmmAmmConfigAccountEvent {
pub rent_epoch: u64,
pub amm_config: AmmConfig,
}
impl_unified_event!(RaydiumClmmAmmConfigAccountEvent,);
/// 池状态
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -243,7 +234,6 @@ pub struct RaydiumClmmPoolStateAccountEvent {
pub rent_epoch: u64,
pub pool_state: PoolState,
}
impl_unified_event!(RaydiumClmmPoolStateAccountEvent,);
/// 池状态
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
@@ -256,7 +246,6 @@ pub struct RaydiumClmmTickArrayStateAccountEvent {
pub rent_epoch: u64,
pub tick_array_state: TickArrayState,
}
impl_unified_event!(RaydiumClmmTickArrayStateAccountEvent,);
/// 事件鉴别器常量
pub mod discriminators {
@@ -107,11 +107,11 @@ fn parse_open_position_v2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 51 || accounts.len() < 22 {
return None;
}
Some(Box::new(RaydiumClmmOpenPositionV2Event {
Some(UnifiedEvent::RaydiumClmmOpenPositionV2Event(RaydiumClmmOpenPositionV2Event {
metadata,
tick_lower_index: read_i32_le(data, 0)?,
tick_upper_index: read_i32_le(data, 4)?,
@@ -153,42 +153,44 @@ fn parse_open_position_with_token_22_nft_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 51 || accounts.len() < 20 {
return None;
}
Some(Box::new(RaydiumClmmOpenPositionWithToken22NftEvent {
metadata,
tick_lower_index: read_i32_le(data, 0)?,
tick_upper_index: read_i32_le(data, 4)?,
tick_array_lower_start_index: read_i32_le(data, 8)?,
tick_array_upper_start_index: read_i32_le(data, 12)?,
liquidity: read_u128_le(data, 16)?,
amount0_max: read_u64_le(data, 32)?,
amount1_max: read_u64_le(data, 40)?,
with_metadata: read_u8_le(data, 48)? == 1,
base_flag: read_option_bool(data, &mut 49)?,
payer: accounts[0],
position_nft_owner: accounts[1],
position_nft_mint: accounts[2],
position_nft_account: accounts[3],
pool_state: accounts[4],
protocol_position: accounts[5],
tick_array_lower: accounts[6],
tick_array_upper: accounts[7],
personal_position: accounts[8],
token_account0: accounts[9],
token_account1: accounts[10],
token_vault0: accounts[11],
token_vault1: accounts[12],
rent: accounts[13],
system_program: accounts[14],
token_program: accounts[15],
associated_token_program: accounts[16],
token_program2022: accounts[17],
vault0_mint: accounts[18],
vault1_mint: accounts[19],
}))
Some(UnifiedEvent::RaydiumClmmOpenPositionWithToken22NftEvent(
RaydiumClmmOpenPositionWithToken22NftEvent {
metadata,
tick_lower_index: read_i32_le(data, 0)?,
tick_upper_index: read_i32_le(data, 4)?,
tick_array_lower_start_index: read_i32_le(data, 8)?,
tick_array_upper_start_index: read_i32_le(data, 12)?,
liquidity: read_u128_le(data, 16)?,
amount0_max: read_u64_le(data, 32)?,
amount1_max: read_u64_le(data, 40)?,
with_metadata: read_u8_le(data, 48)? == 1,
base_flag: read_option_bool(data, &mut 49)?,
payer: accounts[0],
position_nft_owner: accounts[1],
position_nft_mint: accounts[2],
position_nft_account: accounts[3],
pool_state: accounts[4],
protocol_position: accounts[5],
tick_array_lower: accounts[6],
tick_array_upper: accounts[7],
personal_position: accounts[8],
token_account0: accounts[9],
token_account1: accounts[10],
token_vault0: accounts[11],
token_vault1: accounts[12],
rent: accounts[13],
system_program: accounts[14],
token_program: accounts[15],
associated_token_program: accounts[16],
token_program2022: accounts[17],
vault0_mint: accounts[18],
vault1_mint: accounts[19],
},
))
}
/// 解析增加流动性v2指令事件
@@ -196,11 +198,11 @@ fn parse_increase_liquidity_v2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 34 || accounts.len() < 15 {
return None;
}
Some(Box::new(RaydiumClmmIncreaseLiquidityV2Event {
Some(UnifiedEvent::RaydiumClmmIncreaseLiquidityV2Event(RaydiumClmmIncreaseLiquidityV2Event {
metadata,
liquidity: read_u128_le(data, 0)?,
amount0_max: read_u64_le(data, 16)?,
@@ -229,11 +231,11 @@ fn parse_create_pool_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 13 {
return None;
}
Some(Box::new(RaydiumClmmCreatePoolEvent {
Some(UnifiedEvent::RaydiumClmmCreatePoolEvent(RaydiumClmmCreatePoolEvent {
metadata,
sqrt_price_x64: read_u128_le(data, 0)?,
open_time: read_u64_le(data, 16)?,
@@ -258,11 +260,11 @@ fn parse_decrease_liquidity_v2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 32 || accounts.len() < 16 {
return None;
}
Some(Box::new(RaydiumClmmDecreaseLiquidityV2Event {
Some(UnifiedEvent::RaydiumClmmDecreaseLiquidityV2Event(RaydiumClmmDecreaseLiquidityV2Event {
metadata,
liquidity: read_u128_le(data, 0)?,
amount0_min: read_u64_le(data, 16)?,
@@ -292,11 +294,11 @@ fn parse_close_position_instruction(
_data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if accounts.len() < 6 {
return None;
}
Some(Box::new(RaydiumClmmClosePositionEvent {
Some(UnifiedEvent::RaydiumClmmClosePositionEvent(RaydiumClmmClosePositionEvent {
metadata,
nft_owner: accounts[0],
position_nft_mint: accounts[1],
@@ -312,7 +314,7 @@ fn parse_swap_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 33 || accounts.len() < 10 {
return None;
}
@@ -322,7 +324,7 @@ fn parse_swap_instruction(
let sqrt_price_limit_x64 = read_u128_le(data, 16)?;
let is_base_input = read_u8_le(data, 32)?;
Some(Box::new(RaydiumClmmSwapEvent {
Some(UnifiedEvent::RaydiumClmmSwapEvent(RaydiumClmmSwapEvent {
metadata,
amount,
other_amount_threshold,
@@ -346,7 +348,7 @@ fn parse_swap_v2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 33 || accounts.len() < 13 {
return None;
}
@@ -356,7 +358,7 @@ fn parse_swap_v2_instruction(
let sqrt_price_limit_x64 = read_u128_le(data, 16)?;
let is_base_input = read_u8_le(data, 32)?;
Some(Box::new(RaydiumClmmSwapV2Event {
Some(UnifiedEvent::RaydiumClmmSwapV2Event(RaydiumClmmSwapV2Event {
metadata,
amount,
other_amount_threshold,
@@ -37,15 +37,12 @@ pub fn amm_config_decode(data: &[u8]) -> Option<AmmConfig> {
borsh::from_slice::<AmmConfig>(&data[..AMM_CONFIG_SIZE]).ok()
}
pub fn amm_config_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn amm_config_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < AMM_CONFIG_SIZE + 8 {
return None;
}
if let Some(amm_config) = amm_config_decode(&account.data[8..AMM_CONFIG_SIZE + 8]) {
Some(Box::new(RaydiumClmmAmmConfigAccountEvent {
Some(UnifiedEvent::RaydiumClmmAmmConfigAccountEvent(RaydiumClmmAmmConfigAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -125,15 +122,12 @@ pub fn pool_state_decode(data: &[u8]) -> Option<PoolState> {
borsh::from_slice::<PoolState>(&data[..POOL_STATE_SIZE]).ok()
}
pub fn pool_state_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn pool_state_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < POOL_STATE_SIZE + 8 {
return None;
}
if let Some(pool_state) = pool_state_decode(&account.data[8..POOL_STATE_SIZE + 8]) {
Some(Box::new(RaydiumClmmPoolStateAccountEvent {
Some(UnifiedEvent::RaydiumClmmPoolStateAccountEvent(RaydiumClmmPoolStateAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -209,22 +203,24 @@ pub fn tick_array_state_decode(data: &[u8]) -> Option<TickArrayState> {
pub fn tick_array_state_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if account.data.len() < TICK_ARRAY_STATE_SIZE + 8 {
return None;
}
if let Some(tick_array_state) =
tick_array_state_decode(&account.data[8..TICK_ARRAY_STATE_SIZE + 8])
{
Some(Box::new(RaydiumClmmTickArrayStateAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
lamports: account.lamports,
owner: account.owner,
rent_epoch: account.rent_epoch,
tick_array_state: tick_array_state,
}))
Some(UnifiedEvent::RaydiumClmmTickArrayStateAccountEvent(
RaydiumClmmTickArrayStateAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
lamports: account.lamports,
owner: account.owner,
rent_epoch: account.rent_epoch,
tick_array_state: tick_array_state,
},
))
} else {
None
}
@@ -1,7 +1,7 @@
use crate::streaming::event_parser::common::EventMetadata;
use crate::streaming::event_parser::protocols::raydium_cpmm::types::PoolState;
use crate::{
impl_unified_event, streaming::event_parser::protocols::raydium_cpmm::types::AmmConfig,
streaming::event_parser::protocols::raydium_cpmm::types::AmmConfig,
};
use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
@@ -31,7 +31,6 @@ pub struct RaydiumCpmmSwapEvent {
pub observation_state: Pubkey,
}
impl_unified_event!(RaydiumCpmmSwapEvent,);
/// 存款
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -56,7 +55,6 @@ pub struct RaydiumCpmmDepositEvent {
pub vault1_mint: Pubkey,
pub lp_mint: Pubkey,
}
impl_unified_event!(RaydiumCpmmDepositEvent,);
/// 初始化
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -88,7 +86,6 @@ pub struct RaydiumCpmmInitializeEvent {
pub system_program: Pubkey,
pub rent: Pubkey,
}
impl_unified_event!(RaydiumCpmmInitializeEvent,);
/// 提款
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -114,7 +111,6 @@ pub struct RaydiumCpmmWithdrawEvent {
pub lp_mint: Pubkey,
pub memo_program: Pubkey,
}
impl_unified_event!(RaydiumCpmmWithdrawEvent,);
/// 池配置
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -128,7 +124,6 @@ pub struct RaydiumCpmmAmmConfigAccountEvent {
pub rent_epoch: u64,
pub amm_config: AmmConfig,
}
impl_unified_event!(RaydiumCpmmAmmConfigAccountEvent,);
/// 池状态
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -142,7 +137,6 @@ pub struct RaydiumCpmmPoolStateAccountEvent {
pub rent_epoch: u64,
pub pool_state: PoolState,
}
impl_unified_event!(RaydiumCpmmPoolStateAccountEvent,);
/// 事件鉴别器常量
pub mod discriminators {
@@ -73,11 +73,11 @@ fn parse_withdraw_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 14 {
return None;
}
Some(Box::new(RaydiumCpmmWithdrawEvent {
Some(UnifiedEvent::RaydiumCpmmWithdrawEvent(RaydiumCpmmWithdrawEvent {
metadata,
lp_token_amount: read_u64_le(data, 0)?,
minimum_token0_amount: read_u64_le(data, 8)?,
@@ -104,11 +104,11 @@ fn parse_initialize_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 20 {
return None;
}
Some(Box::new(RaydiumCpmmInitializeEvent {
Some(UnifiedEvent::RaydiumCpmmInitializeEvent(RaydiumCpmmInitializeEvent {
metadata,
init_amount0: read_u64_le(data, 0)?,
init_amount1: read_u64_le(data, 8)?,
@@ -141,11 +141,11 @@ fn parse_deposit_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 13 {
return None;
}
Some(Box::new(RaydiumCpmmDepositEvent {
Some(UnifiedEvent::RaydiumCpmmDepositEvent(RaydiumCpmmDepositEvent {
metadata,
lp_token_amount: read_u64_le(data, 0)?,
maximum_token0_amount: read_u64_le(data, 8)?,
@@ -171,7 +171,7 @@ fn parse_swap_base_input_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 13 {
return None;
}
@@ -179,7 +179,7 @@ fn parse_swap_base_input_instruction(
let amount_in = read_u64_le(data, 0)?;
let minimum_amount_out = read_u64_le(data, 8)?;
Some(Box::new(RaydiumCpmmSwapEvent {
Some(UnifiedEvent::RaydiumCpmmSwapEvent(RaydiumCpmmSwapEvent {
metadata,
amount_in,
minimum_amount_out,
@@ -204,7 +204,7 @@ fn parse_swap_base_output_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 13 {
return None;
}
@@ -212,7 +212,7 @@ fn parse_swap_base_output_instruction(
let max_amount_in = read_u64_le(data, 0)?;
let amount_out = read_u64_le(data, 8)?;
Some(Box::new(RaydiumCpmmSwapEvent {
Some(UnifiedEvent::RaydiumCpmmSwapEvent(RaydiumCpmmSwapEvent {
metadata,
max_amount_in,
amount_out,
@@ -36,15 +36,12 @@ pub fn amm_config_decode(data: &[u8]) -> Option<AmmConfig> {
borsh::from_slice::<AmmConfig>(&data[..AMM_CONFIG_SIZE]).ok()
}
pub fn amm_config_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn amm_config_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < AMM_CONFIG_SIZE + 8 {
return None;
}
if let Some(amm_config) = amm_config_decode(&account.data[8..AMM_CONFIG_SIZE + 8]) {
Some(Box::new(RaydiumCpmmAmmConfigAccountEvent {
Some(UnifiedEvent::RaydiumCpmmAmmConfigAccountEvent(RaydiumCpmmAmmConfigAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,
@@ -94,15 +91,12 @@ pub fn pool_state_decode(data: &[u8]) -> Option<PoolState> {
borsh::from_slice::<PoolState>(&data[..POOL_STATE_SIZE]).ok()
}
pub fn pool_state_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn pool_state_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < POOL_STATE_SIZE + 8 {
return None;
}
if let Some(pool_state) = pool_state_decode(&account.data[8..POOL_STATE_SIZE + 8]) {
Some(Box::new(RaydiumCpmmPoolStateAccountEvent {
Some(UnifiedEvent::RaydiumCpmmPoolStateAccountEvent(RaydiumCpmmPoolStateAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,