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
@@ -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,