mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-16 18:38:05 +00:00
feat: support Pump.fun V2 (Mayhem Mode) and update protocol structures for Nov 11 breaking changes
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use crate::streaming::event_parser::{
|
||||
common::{EventMetadata, EventType},
|
||||
protocols::pumpfun::{
|
||||
discriminators, pumpfun_create_token_event_log_decode, pumpfun_migrate_event_log_decode,
|
||||
pumpfun_trade_event_log_decode, PumpFunCreateTokenEvent, PumpFunMigrateEvent,
|
||||
PumpFunTradeEvent,
|
||||
discriminators, pumpfun_create_token_event_log_decode, pumpfun_create_v2_token_event_log_decode,
|
||||
pumpfun_migrate_event_log_decode, pumpfun_trade_event_log_decode, PumpFunCreateTokenEvent,
|
||||
PumpFunCreateV2TokenEvent, PumpFunMigrateEvent, PumpFunTradeEvent,
|
||||
},
|
||||
DexEvent,
|
||||
};
|
||||
@@ -26,6 +26,9 @@ pub fn parse_pumpfun_instruction_data(
|
||||
discriminators::CREATE_TOKEN_IX => {
|
||||
parse_create_token_instruction(data, accounts, metadata)
|
||||
}
|
||||
discriminators::CREATE_V2_TOKEN_IX => {
|
||||
parse_create_v2_token_instruction(data, accounts, metadata)
|
||||
}
|
||||
discriminators::BUY_IX => {
|
||||
parse_buy_instruction(data, accounts, metadata)
|
||||
}
|
||||
@@ -179,6 +182,69 @@ fn parse_create_token_instruction(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 解析创建 V2 代币指令事件 (SPL-22 Token, Mayhem Mode)
|
||||
fn parse_create_v2_token_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
mut metadata: EventMetadata,
|
||||
) -> Option<DexEvent> {
|
||||
metadata.event_type = EventType::PumpFunCreateV2Token;
|
||||
|
||||
if data.len() < 16 || accounts.len() < 11 {
|
||||
return None;
|
||||
}
|
||||
let mut offset = 0;
|
||||
if offset + 4 > data.len() {
|
||||
return None;
|
||||
}
|
||||
let name_len = u32::from_le_bytes(data[offset..offset + 4].try_into().unwrap()) as usize;
|
||||
offset += 4;
|
||||
if offset + name_len > data.len() {
|
||||
return None;
|
||||
}
|
||||
let name = String::from_utf8_lossy(&data[offset..offset + name_len]);
|
||||
offset += name_len;
|
||||
if offset + 4 > data.len() {
|
||||
return None;
|
||||
}
|
||||
let symbol_len = u32::from_le_bytes(data[offset..offset + 4].try_into().unwrap()) as usize;
|
||||
offset += 4;
|
||||
if offset + symbol_len > data.len() {
|
||||
return None;
|
||||
}
|
||||
let symbol = String::from_utf8_lossy(&data[offset..offset + symbol_len]);
|
||||
offset += symbol_len;
|
||||
if offset + 4 > data.len() {
|
||||
return None;
|
||||
}
|
||||
let uri_len = u32::from_le_bytes(data[offset..offset + 4].try_into().unwrap()) as usize;
|
||||
offset += 4;
|
||||
if offset + uri_len > data.len() {
|
||||
return None;
|
||||
}
|
||||
let uri = String::from_utf8_lossy(&data[offset..offset + uri_len]);
|
||||
offset += uri_len;
|
||||
let creator = if offset + 32 <= data.len() {
|
||||
Pubkey::new_from_array(data[offset..offset + 32].try_into().ok()?)
|
||||
} else {
|
||||
Pubkey::default()
|
||||
};
|
||||
|
||||
Some(DexEvent::PumpFunCreateV2TokenEvent(PumpFunCreateV2TokenEvent {
|
||||
metadata,
|
||||
name: name.to_string(),
|
||||
symbol: symbol.to_string(),
|
||||
uri: uri.to_string(),
|
||||
creator,
|
||||
mint: accounts[0],
|
||||
mint_authority: accounts[1],
|
||||
bonding_curve: accounts[2],
|
||||
associated_bonding_curve: accounts[3],
|
||||
user: accounts[7],
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
|
||||
// 解析买入指令事件
|
||||
fn parse_buy_instruction(
|
||||
data: &[u8],
|
||||
@@ -187,7 +253,7 @@ fn parse_buy_instruction(
|
||||
) -> Option<DexEvent> {
|
||||
metadata.event_type = EventType::PumpFunBuy;
|
||||
|
||||
if data.len() < 16 || accounts.len() < 13 {
|
||||
if data.len() < 16 || accounts.len() < 16 {
|
||||
return None;
|
||||
}
|
||||
let amount = u64::from_le_bytes(data[0..8].try_into().unwrap());
|
||||
@@ -208,6 +274,8 @@ fn parse_buy_instruction(
|
||||
program: accounts[11],
|
||||
global_volume_accumulator: accounts[12],
|
||||
user_volume_accumulator: accounts[13],
|
||||
fee_config: accounts[14],
|
||||
fee_program: accounts[15],
|
||||
max_sol_cost,
|
||||
amount,
|
||||
is_buy: true,
|
||||
@@ -223,7 +291,7 @@ fn parse_sell_instruction(
|
||||
) -> Option<DexEvent> {
|
||||
metadata.event_type = EventType::PumpFunSell;
|
||||
|
||||
if data.len() < 16 || accounts.len() < 11 {
|
||||
if data.len() < 16 || accounts.len() < 14 {
|
||||
return None;
|
||||
}
|
||||
let amount = u64::from_le_bytes(data[0..8].try_into().unwrap());
|
||||
@@ -242,8 +310,10 @@ fn parse_sell_instruction(
|
||||
token_program: accounts[9],
|
||||
event_authority: accounts[10],
|
||||
program: accounts[11],
|
||||
global_volume_accumulator: *accounts.get(12).unwrap_or(&Pubkey::default()),
|
||||
user_volume_accumulator: *accounts.get(13).unwrap_or(&Pubkey::default()),
|
||||
global_volume_accumulator: Pubkey::default(),
|
||||
user_volume_accumulator: Pubkey::default(),
|
||||
fee_config: accounts[12],
|
||||
fee_program: accounts[13],
|
||||
min_sol_output,
|
||||
amount,
|
||||
is_buy: false,
|
||||
|
||||
Reference in New Issue
Block a user