Merge pull request #61 from Estereg/main

feat(pumpfun): align IDL, fix parser & update/cleanup dependencies
This commit is contained in:
Wood
2026-02-23 12:53:36 +08:00
committed by GitHub
5 changed files with 92 additions and 50 deletions
+18 -44
View File
@@ -14,64 +14,38 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
solana-sdk = "3.0.0"
solana-client = "3.1.4"
solana-client = "3.1.9"
solana-program = "3.0.0"
solana-rpc-client = "3.1.4"
solana-rpc-client-api = "3.1.4"
solana-transaction-status = "3.1.4"
solana-account-decoder = "3.1.4"
solana-hash = "4.0.1"
solana-entry = { version = "3.1.4", features = ["agave-unstable-api"] }
solana-rpc-client-nonce-utils = "3.1.4"
solana-perf = "3.1.4"
solana-metrics = "3.1.4"
spl-associated-token-account = "8.0.0"
solana-transaction-status = "3.1.9"
solana-account-decoder = "3.1.9"
solana-entry = { version = "3.1.9", features = ["agave-unstable-api"] }
borsh = { version = "1.6.0", features = ["derive"] }
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.134"
serde-big-array = "0.5.1"
futures = "0.3.31"
futures-util = "0.3.31"
base64 = "0.22.1"
rand = "0.9.2"
futures = "0.3.32"
bincode = "1.3"
anyhow = "1.0.90"
anyhow = "1.0.102"
yellowstone-grpc-client = { version = "10.2.0" }
yellowstone-grpc-proto = { version = "10.1.1" }
tokio = { version = "1.42.0", features = ["full", "rt-multi-thread"]}
tonic = { version = "0.14.2", features = ["transport"] }
rustls = { version = "0.23.35", features = ["ring"], default-features = false }
rustls-native-certs = "0.8.2"
tokio-rustls = "0.26.4"
tokio = { version = "1.49.0", features = ["full", "rt-multi-thread"]}
tonic = { version = "0.14.5", features = ["transport"] }
rustls = { version = "0.23.36", features = ["ring"], default-features = false }
log = "0.4.29"
chrono = "0.4.42"
regex = "1"
tracing = "0.1.43"
thiserror = "2.0.17"
async-trait = "0.1.86"
chrono = "0.4.43"
lazy_static = "1.5.0"
once_cell = "1.20.3"
once_cell = "1.21.3"
dashmap = "6.1.0"
prost = "0.14.1"
prost-types = "0.14.1"
num_enum = "0.7.5"
num-derive = "0.4.2"
num-traits = "0.2.19"
hex = "0.4.3"
bytemuck = { version = "1.24.0" }
arrayref = "0.3.6"
borsh-derive = "1.6.0"
indicatif = "0.18.3"
prost = "0.14.3"
prost-types = "0.14.3"
maplit = "1.0.2"
env_logger = "0.11.8"
crossbeam = "0.8.4"
env_logger = "0.11.9"
crossbeam-queue = "0.3.12"
parking_lot = "0.12.5"
wide = "1.1.0"
wide = "1.1.1"
spl-token = { version = "9.0.0", default-features = false, features = ["no-entrypoint"] }
spl-token-2022 = { version = "10.0.0", default-features = false, features = ["no-entrypoint"] }
solana-commitment-config = { version = "3.1.0", features = ["serde"] }
tonic-prost = "0.14.2"
solana-commitment-config = { version = "3.1.1", features = ["serde"] }
tonic-prost = "0.14.5"
[dev-dependencies]
criterion = { version = "0.8.1", features = ["html_reports"] }
criterion = { version = "0.8.2", features = ["html_reports"] }
@@ -21,6 +21,11 @@ pub fn merge(instruction_event: &mut DexEvent, cpi_log_event: DexEvent) {
e.creator = cpie.creator;
e.creator_fee_basis_points = cpie.creator_fee_basis_points;
e.creator_fee = cpie.creator_fee;
e.track_volume = cpie.track_volume;
e.total_unclaimed_tokens = cpie.total_unclaimed_tokens;
e.total_claimed_tokens = cpie.total_claimed_tokens;
e.current_sol_volume = cpie.current_sol_volume;
e.last_update_timestamp = cpie.last_update_timestamp;
e.ix_name = cpie.ix_name.clone();
e.mayhem_mode = cpie.mayhem_mode;
e.cashback_fee_basis_points = cpie.cashback_fee_basis_points;
@@ -147,6 +152,11 @@ pub fn merge(instruction_event: &mut DexEvent, cpi_log_event: DexEvent) {
e.coin_creator = cpie.coin_creator;
e.coin_creator_fee_basis_points = cpie.coin_creator_fee_basis_points;
e.coin_creator_fee = cpie.coin_creator_fee;
e.track_volume = cpie.track_volume;
e.total_unclaimed_tokens = cpie.total_unclaimed_tokens;
e.total_claimed_tokens = cpie.total_claimed_tokens;
e.current_sol_volume = cpie.current_sol_volume;
e.last_update_timestamp = cpie.last_update_timestamp;
}
_ => {}
},
@@ -32,6 +32,22 @@ pub struct PumpFunCreateTokenEvent {
pub mint_authority: Pubkey,
#[borsh(skip)]
pub associated_bonding_curve: Pubkey,
#[borsh(skip)]
pub global: Pubkey,
#[borsh(skip)]
pub mpl_token_metadata: Pubkey,
#[borsh(skip)]
pub metadata_account: Pubkey,
#[borsh(skip)]
pub system_program: Pubkey,
#[borsh(skip)]
pub associated_token_program: Pubkey,
#[borsh(skip)]
pub rent: Pubkey,
#[borsh(skip)]
pub event_authority: Pubkey,
#[borsh(skip)]
pub program: Pubkey,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -58,6 +74,26 @@ pub struct PumpFunCreateV2TokenEvent {
pub mint_authority: Pubkey,
#[borsh(skip)]
pub associated_bonding_curve: Pubkey,
#[borsh(skip)]
pub global: Pubkey,
#[borsh(skip)]
pub system_program: Pubkey,
#[borsh(skip)]
pub associated_token_program: Pubkey,
#[borsh(skip)]
pub mayhem_program_id: Pubkey,
#[borsh(skip)]
pub global_params: Pubkey,
#[borsh(skip)]
pub sol_vault: Pubkey,
#[borsh(skip)]
pub mayhem_state: Pubkey,
#[borsh(skip)]
pub mayhem_token_vault: Pubkey,
#[borsh(skip)]
pub event_authority: Pubkey,
#[borsh(skip)]
pub program: Pubkey,
}
pub fn pumpfun_create_v2_token_event_log_decode(data: &[u8]) -> Option<PumpFunCreateV2TokenEvent> {
@@ -275,10 +311,10 @@ pub struct PumpFunTradeEvent {
}
/// Borsh byte length of TradeEvent fixed fields (IDL order; excludes ix_name and following variable part).
/// Layout: mint(32)+sol_amount(8)+token_amount(8)+is_buy(1)+user(32)+timestamp(8)+virtual_sol(8)+virtual_token(8)+real_sol(8)+real_token(8)+fee_recipient(32)+fee_basis_points(8)+fee(8)+creator(32)+creator_fee_bps(8)+creator_fee(8)+track_volume(1)+total_unclaimed(8)+total_claimed(8)+current_sol_volume(8)+last_update_timestamp(8) = 274
pub const PUMPFUN_TRADE_EVENT_LOG_SIZE: usize = 274;
/// Layout: mint(32)+sol_amount(8)+token_amount(8)+is_buy(1)+user(32)+timestamp(8)+virtual_sol(8)+virtual_token(8)+real_sol(8)+real_token(8)+fee_recipient(32)+fee_basis_points(8)+fee(8)+creator(32)+creator_fee_bps(8)+creator_fee(8)+track_volume(1)+total_unclaimed(8)+total_claimed(8)+current_sol_volume(8)+last_update_timestamp(8) = 250
pub const PUMPFUN_TRADE_EVENT_LOG_SIZE: usize = 250;
/// Decode TradeEvent log; if data.len() > 274 then parse ix_name, mayhem_mode, cashback (IDL-aligned).
/// Decode TradeEvent log; if data.len() > 250 then parse ix_name, mayhem_mode, cashback (IDL-aligned).
pub fn pumpfun_trade_event_log_decode(data: &[u8]) -> Option<PumpFunTradeEvent> {
if data.len() < PUMPFUN_TRADE_EVENT_LOG_SIZE {
return None;
@@ -168,7 +168,16 @@ fn parse_create_token_instruction(
mint_authority: accounts[1],
bonding_curve: accounts[2],
associated_bonding_curve: accounts[3],
global: accounts[4],
mpl_token_metadata: accounts[5],
metadata_account: accounts[6],
user: accounts[7],
system_program: accounts[8],
token_program: accounts[9],
associated_token_program: accounts[10],
rent: accounts[11],
event_authority: accounts[12],
program: accounts[13],
..Default::default()
}))
}
@@ -231,7 +240,18 @@ fn parse_create_v2_token_instruction(
mint_authority: accounts[1],
bonding_curve: accounts[2],
associated_bonding_curve: accounts[3],
user: accounts[7],
global: accounts[4],
user: accounts[5],
system_program: accounts[6],
token_program: accounts[7],
associated_token_program: accounts[8],
mayhem_program_id: accounts[9],
global_params: accounts[10],
sol_vault: accounts[11],
mayhem_state: accounts[12],
mayhem_token_vault: accounts[13],
event_authority: accounts[14],
program: accounts[15],
..Default::default()
}))
}
@@ -21,9 +21,10 @@ pub struct BondingCurve {
pub complete: bool,
pub creator: Pubkey,
pub is_mayhem_mode: bool,
pub is_cashback_coin: bool,
}
pub const BONDING_CURVE_SIZE: usize = 8 * 5 + 1 + 32 + 1;
pub const BONDING_CURVE_SIZE: usize = 8 * 5 + 1 + 32 + 1 + 1;
pub fn bonding_curve_decode(data: &[u8]) -> Option<BondingCurve> {
if data.len() < BONDING_CURVE_SIZE {
@@ -78,9 +79,10 @@ pub struct Global {
pub reserved_fee_recipient: Pubkey,
pub mayhem_mode_enabled: bool,
pub reserved_fee_recipients: [Pubkey; 7],
pub is_cashback_enabled: bool,
}
pub const GLOBAL_SIZE: usize = 1 + 32 * 2 + 8 * 5 + 32 + 1 + 8 * 2 + 32 * 7 + 32 * 2 + 1 + 32 * 2 + 1 + 32 * 7;
pub const GLOBAL_SIZE: usize = 1 + 32 * 2 + 8 * 5 + 32 + 1 + 8 * 2 + 32 * 7 + 32 * 2 + 1 + 32 * 2 + 1 + 32 * 7 + 1;
pub fn global_decode(data: &[u8]) -> Option<Global> {
if data.len() < GLOBAL_SIZE {