From 63109713f4b471fe259307c78d09e119b79df85b Mon Sep 17 00:00:00 2001 From: sgxiang Date: Fri, 6 Jun 2025 22:13:19 +0800 Subject: [PATCH] refactor: organize code into multi-protocol architecture with PumpFun submodules --- src/accounts/bonding_curve.rs | 2 +- src/accounts/global.rs | 2 +- src/common/address_lookup.rs | 48 +++--- src/common/mod.rs | 6 +- src/common/{ => pumpfun}/logs_data.rs | 0 src/common/{ => pumpfun}/logs_events.rs | 2 +- src/common/{ => pumpfun}/logs_filters.rs | 4 +- src/common/{ => pumpfun}/logs_parser.rs | 2 +- src/common/{ => pumpfun}/logs_subscribe.rs | 4 +- src/common/pumpfun/mod.rs | 11 ++ src/common/types.rs | 2 +- src/constants/mod.rs | 176 +-------------------- src/constants/pumpfun/mod.rs | 174 ++++++++++++++++++++ src/grpc/shred_stream.rs | 6 +- src/grpc/yellow_stone.rs | 6 +- src/instruction/mod.rs | 12 +- src/lib.rs | 4 +- src/main.rs | 4 +- src/pumpfun/buy.rs | 4 +- src/pumpfun/common.rs | 20 +-- src/pumpfun/sell.rs | 2 +- src/swqos/mod.rs | 2 +- 22 files changed, 251 insertions(+), 242 deletions(-) rename src/common/{ => pumpfun}/logs_data.rs (100%) rename src/common/{ => pumpfun}/logs_events.rs (96%) rename src/common/{ => pumpfun}/logs_filters.rs (97%) rename src/common/{ => pumpfun}/logs_parser.rs (99%) rename src/common/{ => pumpfun}/logs_subscribe.rs (96%) create mode 100644 src/common/pumpfun/mod.rs mode change 100755 => 100644 src/constants/mod.rs create mode 100755 src/constants/pumpfun/mod.rs diff --git a/src/accounts/bonding_curve.rs b/src/accounts/bonding_curve.rs index 4e3d59a..2c7ef40 100755 --- a/src/accounts/bonding_curve.rs +++ b/src/accounts/bonding_curve.rs @@ -28,7 +28,7 @@ use serde::{Serialize, Deserialize}; use solana_sdk::pubkey::Pubkey; -use crate::{constants::global_constants::{INITIAL_REAL_TOKEN_RESERVES, INITIAL_VIRTUAL_SOL_RESERVES, INITIAL_VIRTUAL_TOKEN_RESERVES, TOKEN_TOTAL_SUPPLY}, pumpfun::common::{get_bonding_curve_pda, get_creator_vault_pda}}; +use crate::{constants::pumpfun::global_constants::{INITIAL_REAL_TOKEN_RESERVES, INITIAL_VIRTUAL_SOL_RESERVES, INITIAL_VIRTUAL_TOKEN_RESERVES, TOKEN_TOTAL_SUPPLY}, pumpfun::common::{get_bonding_curve_pda, get_creator_vault_pda}}; /// Represents the global configuration account for token pricing and fees #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/accounts/global.rs b/src/accounts/global.rs index b424a63..3a5c414 100755 --- a/src/accounts/global.rs +++ b/src/accounts/global.rs @@ -26,7 +26,7 @@ use solana_sdk::pubkey::Pubkey; use serde::{Serialize, Deserialize}; -use crate::constants::global_constants::*; +use crate::constants::pumpfun::global_constants::*; /// Represents the global configuration account for token pricing and fees #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/common/address_lookup.rs b/src/common/address_lookup.rs index ffbc5be..10af7e4 100755 --- a/src/common/address_lookup.rs +++ b/src/common/address_lookup.rs @@ -351,14 +351,14 @@ pub async fn extend_pumpfun_address_to_lookup_table( pub fn get_pumpfun_addresses(payer: Pubkey, include_addresses: Vec) -> Vec { let mut addresses = vec![ payer, - constants::accounts::PUMPFUN, - constants::accounts::SYSTEM_PROGRAM, - constants::accounts::TOKEN_PROGRAM, - constants::accounts::RENT, - constants::accounts::EVENT_AUTHORITY, - constants::accounts::ASSOCIATED_TOKEN_PROGRAM, - constants::global_constants::GLOBAL_ACCOUNT, - constants::global_constants::FEE_RECIPIENT, + constants::pumpfun::accounts::PUMPFUN, + constants::pumpfun::accounts::SYSTEM_PROGRAM, + constants::pumpfun::accounts::TOKEN_PROGRAM, + constants::pumpfun::accounts::RENT, + constants::pumpfun::accounts::EVENT_AUTHORITY, + constants::pumpfun::accounts::ASSOCIATED_TOKEN_PROGRAM, + constants::pumpfun::global_constants::GLOBAL_ACCOUNT, + constants::pumpfun::global_constants::FEE_RECIPIENT, ]; addresses.extend(include_addresses); @@ -369,22 +369,22 @@ pub fn get_pumpfun_addresses(payer: Pubkey, include_addresses: Vec) -> V pub fn get_pumpfun_filtered_addresses(payer: Pubkey, include_addresses: Vec) -> Vec { let mut addresses = vec![ payer, - constants::accounts::PUMPFUN, - constants::accounts::SYSTEM_PROGRAM, - constants::accounts::TOKEN_PROGRAM, - constants::accounts::RENT, - constants::accounts::EVENT_AUTHORITY, - constants::accounts::ASSOCIATED_TOKEN_PROGRAM, - constants::global_constants::GLOBAL_ACCOUNT, - constants::global_constants::FEE_RECIPIENT, - constants::global_constants::PUMPFUN_AMM_FEE_1, - constants::global_constants::PUMPFUN_AMM_FEE_2, - constants::global_constants::PUMPFUN_AMM_FEE_3, - constants::global_constants::PUMPFUN_AMM_FEE_4, - constants::global_constants::PUMPFUN_AMM_FEE_5, - constants::global_constants::PUMPFUN_AMM_FEE_6, - constants::global_constants::PUMPFUN_AMM_FEE_7, - // constants::global_constants::PUMPFUN_AMM_FEE_8, + constants::pumpfun::accounts::PUMPFUN, + constants::pumpfun::accounts::SYSTEM_PROGRAM, + constants::pumpfun::accounts::TOKEN_PROGRAM, + constants::pumpfun::accounts::RENT, + constants::pumpfun::accounts::EVENT_AUTHORITY, + constants::pumpfun::accounts::ASSOCIATED_TOKEN_PROGRAM, + constants::pumpfun::global_constants::GLOBAL_ACCOUNT, + constants::pumpfun::global_constants::FEE_RECIPIENT, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_1, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_2, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_3, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_4, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_5, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_6, + constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_7, + // constants::pumpfun::global_constants::PUMPFUN_AMM_FEE_8, ]; addresses.extend(include_addresses); diff --git a/src/common/mod.rs b/src/common/mod.rs index d4c5dfe..89da297 100755 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1,8 +1,4 @@ -pub mod logs_data; -pub mod logs_parser; -pub mod logs_filters; -pub mod logs_subscribe; -pub mod logs_events; +pub mod pumpfun; pub mod address_lookup; pub mod nonce_cache; pub mod tip_cache; diff --git a/src/common/logs_data.rs b/src/common/pumpfun/logs_data.rs similarity index 100% rename from src/common/logs_data.rs rename to src/common/pumpfun/logs_data.rs diff --git a/src/common/logs_events.rs b/src/common/pumpfun/logs_events.rs similarity index 96% rename from src/common/logs_events.rs rename to src/common/pumpfun/logs_events.rs index e4c3d63..a57bb1d 100755 --- a/src/common/logs_events.rs +++ b/src/common/pumpfun/logs_events.rs @@ -1,7 +1,7 @@ use base64::engine::general_purpose; use base64::Engine; use regex::Regex; -use crate::common::logs_data::{CreateTokenInfo, TradeInfo, EventTrait, TransferInfo, TipInfo}; +use crate::common::pumpfun::logs_data::{CreateTokenInfo, TradeInfo, EventTrait, TransferInfo, TipInfo}; pub const PROGRAM_DATA: &str = "Program data: "; diff --git a/src/common/logs_filters.rs b/src/common/pumpfun/logs_filters.rs similarity index 97% rename from src/common/logs_filters.rs rename to src/common/pumpfun/logs_filters.rs index d0b6c96..74705e5 100755 --- a/src/common/logs_filters.rs +++ b/src/common/pumpfun/logs_filters.rs @@ -1,5 +1,5 @@ -use crate::common::logs_data::DexInstruction; -use crate::common::logs_parser::{parse_create_token_data, parse_trade_data, parse_instruction_create_token_data, parse_instruction_trade_data}; +use crate::common::pumpfun::logs_data::DexInstruction; +use crate::common::pumpfun::logs_parser::{parse_create_token_data, parse_trade_data, parse_instruction_create_token_data, parse_instruction_trade_data}; use crate::error::ClientResult; pub struct LogFilter; use solana_sdk::pubkey::Pubkey; diff --git a/src/common/logs_parser.rs b/src/common/pumpfun/logs_parser.rs similarity index 99% rename from src/common/logs_parser.rs rename to src/common/pumpfun/logs_parser.rs index 7832f74..dd5dd7d 100755 --- a/src/common/logs_parser.rs +++ b/src/common/pumpfun/logs_parser.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use base64::{Engine as _, engine::general_purpose::STANDARD as BASE64}; use crate::error::{ClientError, ClientResult}; -use crate::common::{ +use crate::common::pumpfun::{ logs_data::{DexInstruction, CreateTokenInfo, TradeInfo}, logs_filters::LogFilter }; diff --git a/src/common/logs_subscribe.rs b/src/common/pumpfun/logs_subscribe.rs similarity index 96% rename from src/common/logs_subscribe.rs rename to src/common/pumpfun/logs_subscribe.rs index 8578e7b..3b4ac5d 100755 --- a/src/common/logs_subscribe.rs +++ b/src/common/pumpfun/logs_subscribe.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use tokio::sync::mpsc; use tokio::task::JoinHandle; use futures::StreamExt; -use crate::{constants, common::{ +use crate::{constants, common::pumpfun::{ logs_data::DexInstruction, logs_events::DexEvent, logs_filters::LogFilter }}; @@ -41,7 +41,7 @@ pub async fn tokens_subscription( where F: Fn(PumpfunEvent) + Send + Sync + 'static, { - let program_address = constants::accounts::PUMPFUN.to_string(); + let program_address = constants::pumpfun::accounts::PUMPFUN.to_string(); let logs_filter = RpcTransactionLogsFilter::Mentions(vec![program_address]); let logs_config = RpcTransactionLogsConfig { diff --git a/src/common/pumpfun/mod.rs b/src/common/pumpfun/mod.rs new file mode 100644 index 0000000..8de9d17 --- /dev/null +++ b/src/common/pumpfun/mod.rs @@ -0,0 +1,11 @@ +pub mod logs_data; +pub mod logs_parser; +pub mod logs_filters; +pub mod logs_subscribe; +pub mod logs_events; + +pub use logs_data::*; +pub use logs_parser::*; +pub use logs_filters::*; +pub use logs_subscribe::*; +pub use logs_events::*; \ No newline at end of file diff --git a/src/common/types.rs b/src/common/types.rs index 4dfd3d9..47095a4 100755 --- a/src/common/types.rs +++ b/src/common/types.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use solana_client::rpc_client::RpcClient; use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signature::Keypair}; use serde::Deserialize; -use crate::{constants::trade::{DEFAULT_BUY_TIP_FEE, DEFAULT_COMPUTE_UNIT_LIMIT, DEFAULT_COMPUTE_UNIT_PRICE, DEFAULT_SELL_TIP_FEE}, swqos::FeeClient}; +use crate::{constants::pumpfun::trade::{DEFAULT_BUY_TIP_FEE, DEFAULT_COMPUTE_UNIT_LIMIT, DEFAULT_COMPUTE_UNIT_PRICE, DEFAULT_SELL_TIP_FEE}, swqos::FeeClient}; #[derive(Debug, Clone, PartialEq)] pub enum FeeType { diff --git a/src/constants/mod.rs b/src/constants/mod.rs old mode 100755 new mode 100644 index 762b3be..5dc92e6 --- a/src/constants/mod.rs +++ b/src/constants/mod.rs @@ -1,174 +1,2 @@ -//! Constants used by the crate. -//! -//! This module contains various constants used throughout the crate, including: -//! -//! - Seeds for deriving Program Derived Addresses (PDAs) -//! - Program account addresses and public keys -//! -//! The constants are organized into submodules for better organization: -//! -//! - `seeds`: Contains seed values used for PDA derivation -//! - `accounts`: Contains important program account addresses - -/// Constants used as seeds for deriving PDAs (Program Derived Addresses) -pub mod seeds { - /// Seed for the global state PDA - pub const GLOBAL_SEED: &[u8] = b"global"; - - /// Seed for the mint authority PDA - pub const MINT_AUTHORITY_SEED: &[u8] = b"mint-authority"; - - /// Seed for bonding curve PDAs - pub const BONDING_CURVE_SEED: &[u8] = b"bonding-curve"; - - /// Seed for creator vault PDAs - pub const CREATOR_VAULT_SEED: &[u8] = b"creator-vault"; - - /// Seed for metadata PDAs - pub const METADATA_SEED: &[u8] = b"metadata"; -} - -pub mod global_constants { - use solana_sdk::{pubkey, pubkey::Pubkey}; - - pub const INITIAL_VIRTUAL_TOKEN_RESERVES: u64 = 1_073_000_000_000_000; - - pub const INITIAL_VIRTUAL_SOL_RESERVES: u64 = 30_000_000_000; - - pub const INITIAL_REAL_TOKEN_RESERVES: u64 = 793_100_000_000_000; - - pub const TOKEN_TOTAL_SUPPLY: u64 = 1_000_000_000_000_000; - - pub const FEE_BASIS_POINTS: u64 = 95; - - pub const ENABLE_MIGRATE: bool = false; - - pub const POOL_MIGRATION_FEE: u64 = 15_000_001; - - pub const CREATOR_FEE: u64 = 5; - - pub const SCALE: u64 = 1_000_000; // 10^6 for token decimals - - pub const LAMPORTS_PER_SOL: u64 = 1_000_000_000; // 10^9 for solana lamports - - pub const TOTAL_SUPPLY: u64 = 1_000_000_000 * SCALE; // 1 billion tokens - - pub const BONDING_CURVE_SUPPLY: u64 = 793_100_000 * SCALE; // total supply of bonding curve tokens - - pub const COMPLETION_LAMPORTS: u64 = 85 * LAMPORTS_PER_SOL; // ~ 85 SOL - - /// Public key for the fee recipient - pub const FEE_RECIPIENT: Pubkey = pubkey!("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"); - - /// Public key for the global PDA - pub const GLOBAL_ACCOUNT: Pubkey = pubkey!("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"); - - /// Public key for the authority - pub const AUTHORITY: Pubkey = pubkey!("FFWtrEQ4B4PKQoVuHYzZq8FabGkVatYzDpEVHsK5rrhF"); - - /// Public key for the withdraw authority - pub const WITHDRAW_AUTHORITY: Pubkey = pubkey!("39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg"); - - pub const PUMPFUN_AMM_FEE_1: Pubkey = pubkey!("7VtfL8fvgNfhz17qKRMjzQEXgbdpnHHHQRh54R9jP2RJ"); // Pump.fun AMM: Protocol Fee 1 - pub const PUMPFUN_AMM_FEE_2: Pubkey = pubkey!("7hTckgnGnLQR6sdH7YkqFTAA7VwTfYFaZ6EhEsU3saCX"); // Pump.fun AMM: Protocol Fee 2 - pub const PUMPFUN_AMM_FEE_3: Pubkey = pubkey!("9rPYyANsfQZw3DnDmKE3YCQF5E8oD89UXoHn9JFEhJUz"); // Pump.fun AMM: Protocol Fee 3 - pub const PUMPFUN_AMM_FEE_4: Pubkey = pubkey!("AVmoTthdrX6tKt4nDjco2D775W2YK3sDhxPcMmzUAmTY"); // Pump.fun AMM: Protocol Fee 4 - pub const PUMPFUN_AMM_FEE_5: Pubkey = pubkey!("CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM"); // Pump.fun AMM: Protocol Fee 5 - pub const PUMPFUN_AMM_FEE_6: Pubkey = pubkey!("FWsW1xNtWscwNmKv6wVsU1iTzRN6wmmk3MjxRP5tT7hz"); // Pump.fun AMM: Protocol Fee 6 - pub const PUMPFUN_AMM_FEE_7: Pubkey = pubkey!("G5UZAVbAf46s7cKWoyKu8kYTip9DGTpbLZ2qa9Aq69dP"); // Pump.fun AMM: Protocol Fee 7 - -} - -/// Constants related to program accounts and authorities -pub mod accounts { - use solana_sdk::{pubkey, pubkey::Pubkey}; - - /// Public key for the Pump.fun program - pub const PUMPFUN: Pubkey = pubkey!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"); - - /// Public key for the MPL Token Metadata program - pub const MPL_TOKEN_METADATA: Pubkey = pubkey!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); - - /// Authority for program events - pub const EVENT_AUTHORITY: Pubkey = pubkey!("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"); - - /// System Program ID - pub const SYSTEM_PROGRAM: Pubkey = pubkey!("11111111111111111111111111111111"); - - /// Token Program ID - pub const TOKEN_PROGRAM: Pubkey = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); - - /// Associated Token Program ID - pub const ASSOCIATED_TOKEN_PROGRAM: Pubkey = pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"); - - /// Rent Sysvar ID - pub const RENT: Pubkey = pubkey!("SysvarRent111111111111111111111111111111111"); - - pub const JITO_TIP_ACCOUNTS: [&str; 8] = [ - "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5", - "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe", - "Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY", - "ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49", - "DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh", - "ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt", - "DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL", - "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT", - ]; - - /// Tip accounts - pub const NEXTBLOCK_TIP_ACCOUNTS: &[&str] = &[ - "NextbLoCkVtMGcV47JzewQdvBpLqT9TxQFozQkN98pE", - "NexTbLoCkWykbLuB1NkjXgFWkX9oAtcoagQegygXXA2", - "NeXTBLoCKs9F1y5PJS9CKrFNNLU1keHW71rfh7KgA1X", - "NexTBLockJYZ7QD7p2byrUa6df8ndV2WSd8GkbWqfbb", - "neXtBLock1LeC67jYd1QdAa32kbVeubsfPNTJC1V5At", - "nEXTBLockYgngeRmRrjDV31mGSekVPqZoMGhQEZtPVG", - "NEXTbLoCkB51HpLBLojQfpyVAMorm3zzKg7w9NFdqid", - "nextBLoCkPMgmG8ZgJtABeScP35qLa2AMCNKntAP7Xc" - ]; - - pub const ZEROSLOT_TIP_ACCOUNTS: &[&str] = &[ - "Eb2KpSC8uMt9GmzyAEm5Eb1AAAgTjRaXWFjKyFXHZxF3", - "FCjUJZ1qozm1e8romw216qyfQMaaWKxWsuySnumVCCNe", - "ENxTEjSQ1YabmUpXAdCgevnHQ9MHdLv8tzFiuiYJqa13", - "6rYLG55Q9RpsPGvqdPNJs4z5WTxJVatMB8zV3WJhs5EK", - "Cix2bHfqPcKcM233mzxbLk14kSggUUiz2A87fJtGivXr", - ]; - - pub const NOZOMI_TIP_ACCOUNTS: &[&str] = &[ - "TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq", - "noz3jAjPiHuBPqiSPkkugaJDkJscPuRhYnSpbi8UvC4", - "noz3str9KXfpKknefHji8L1mPgimezaiUyCHYMDv1GE", - "noz6uoYCDijhu1V7cutCpwxNiSovEwLdRHPwmgCGDNo", - "noz9EPNcT7WH6Sou3sr3GGjHQYVkN3DNirpbvDkv9YJ", - "nozc5yT15LazbLTFVZzoNZCwjh3yUtW86LoUyqsBu4L", - "nozFrhfnNGoyqwVuwPAW4aaGqempx4PU6g6D9CJMv7Z", - "nozievPk7HyK1Rqy1MPJwVQ7qQg2QoJGyP71oeDwbsu", - "noznbgwYnBLDHu8wcQVCEw6kDrXkPdKkydGJGNXGvL7", - "nozNVWs5N8mgzuD3qigrCG2UoKxZttxzZ85pvAQVrbP", - "nozpEGbwx4BcGp6pvEdAh1JoC2CQGZdU6HbNP1v2p6P", - "nozrhjhkCr3zXT3BiT4WCodYCUFeQvcdUkM7MqhKqge", - "nozrwQtWhEdrA6W8dkbt9gnUaMs52PdAv5byipnadq3", - "nozUacTVWub3cL4mJmGCYjKZTnE9RbdY5AP46iQgbPJ", - "nozWCyTPppJjRuw2fpzDhhWbW355fzosWSzrrMYB1Qk", - "nozWNju6dY353eMkMqURqwQEoM3SFgEKC6psLCSfUne", - "nozxNBgWohjR75vdspfxR5H9ceC7XXH99xpxhVGt3Bb" - ]; - - pub const AMM_PROGRAM: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"); -} - -pub mod trade { - pub const TRADER_TIP_AMOUNT: f64 = 0.0001; - pub const DEFAULT_SLIPPAGE: u64 = 1000; // 10% - pub const DEFAULT_COMPUTE_UNIT_LIMIT: u32 = 78000; - pub const DEFAULT_COMPUTE_UNIT_PRICE: u64 = 500000; - pub const DEFAULT_BUY_TIP_FEE: f64 = 0.0006; - pub const DEFAULT_SELL_TIP_FEE: f64 = 0.0001; -} - -pub struct Symbol; - -impl Symbol { - pub const SOLANA: &'static str = "solana"; -} +pub mod pumpfun; +pub use pumpfun::*; \ No newline at end of file diff --git a/src/constants/pumpfun/mod.rs b/src/constants/pumpfun/mod.rs new file mode 100755 index 0000000..762b3be --- /dev/null +++ b/src/constants/pumpfun/mod.rs @@ -0,0 +1,174 @@ +//! Constants used by the crate. +//! +//! This module contains various constants used throughout the crate, including: +//! +//! - Seeds for deriving Program Derived Addresses (PDAs) +//! - Program account addresses and public keys +//! +//! The constants are organized into submodules for better organization: +//! +//! - `seeds`: Contains seed values used for PDA derivation +//! - `accounts`: Contains important program account addresses + +/// Constants used as seeds for deriving PDAs (Program Derived Addresses) +pub mod seeds { + /// Seed for the global state PDA + pub const GLOBAL_SEED: &[u8] = b"global"; + + /// Seed for the mint authority PDA + pub const MINT_AUTHORITY_SEED: &[u8] = b"mint-authority"; + + /// Seed for bonding curve PDAs + pub const BONDING_CURVE_SEED: &[u8] = b"bonding-curve"; + + /// Seed for creator vault PDAs + pub const CREATOR_VAULT_SEED: &[u8] = b"creator-vault"; + + /// Seed for metadata PDAs + pub const METADATA_SEED: &[u8] = b"metadata"; +} + +pub mod global_constants { + use solana_sdk::{pubkey, pubkey::Pubkey}; + + pub const INITIAL_VIRTUAL_TOKEN_RESERVES: u64 = 1_073_000_000_000_000; + + pub const INITIAL_VIRTUAL_SOL_RESERVES: u64 = 30_000_000_000; + + pub const INITIAL_REAL_TOKEN_RESERVES: u64 = 793_100_000_000_000; + + pub const TOKEN_TOTAL_SUPPLY: u64 = 1_000_000_000_000_000; + + pub const FEE_BASIS_POINTS: u64 = 95; + + pub const ENABLE_MIGRATE: bool = false; + + pub const POOL_MIGRATION_FEE: u64 = 15_000_001; + + pub const CREATOR_FEE: u64 = 5; + + pub const SCALE: u64 = 1_000_000; // 10^6 for token decimals + + pub const LAMPORTS_PER_SOL: u64 = 1_000_000_000; // 10^9 for solana lamports + + pub const TOTAL_SUPPLY: u64 = 1_000_000_000 * SCALE; // 1 billion tokens + + pub const BONDING_CURVE_SUPPLY: u64 = 793_100_000 * SCALE; // total supply of bonding curve tokens + + pub const COMPLETION_LAMPORTS: u64 = 85 * LAMPORTS_PER_SOL; // ~ 85 SOL + + /// Public key for the fee recipient + pub const FEE_RECIPIENT: Pubkey = pubkey!("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV"); + + /// Public key for the global PDA + pub const GLOBAL_ACCOUNT: Pubkey = pubkey!("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"); + + /// Public key for the authority + pub const AUTHORITY: Pubkey = pubkey!("FFWtrEQ4B4PKQoVuHYzZq8FabGkVatYzDpEVHsK5rrhF"); + + /// Public key for the withdraw authority + pub const WITHDRAW_AUTHORITY: Pubkey = pubkey!("39azUYFWPz3VHgKCf3VChUwbpURdCHRxjWVowf5jUJjg"); + + pub const PUMPFUN_AMM_FEE_1: Pubkey = pubkey!("7VtfL8fvgNfhz17qKRMjzQEXgbdpnHHHQRh54R9jP2RJ"); // Pump.fun AMM: Protocol Fee 1 + pub const PUMPFUN_AMM_FEE_2: Pubkey = pubkey!("7hTckgnGnLQR6sdH7YkqFTAA7VwTfYFaZ6EhEsU3saCX"); // Pump.fun AMM: Protocol Fee 2 + pub const PUMPFUN_AMM_FEE_3: Pubkey = pubkey!("9rPYyANsfQZw3DnDmKE3YCQF5E8oD89UXoHn9JFEhJUz"); // Pump.fun AMM: Protocol Fee 3 + pub const PUMPFUN_AMM_FEE_4: Pubkey = pubkey!("AVmoTthdrX6tKt4nDjco2D775W2YK3sDhxPcMmzUAmTY"); // Pump.fun AMM: Protocol Fee 4 + pub const PUMPFUN_AMM_FEE_5: Pubkey = pubkey!("CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM"); // Pump.fun AMM: Protocol Fee 5 + pub const PUMPFUN_AMM_FEE_6: Pubkey = pubkey!("FWsW1xNtWscwNmKv6wVsU1iTzRN6wmmk3MjxRP5tT7hz"); // Pump.fun AMM: Protocol Fee 6 + pub const PUMPFUN_AMM_FEE_7: Pubkey = pubkey!("G5UZAVbAf46s7cKWoyKu8kYTip9DGTpbLZ2qa9Aq69dP"); // Pump.fun AMM: Protocol Fee 7 + +} + +/// Constants related to program accounts and authorities +pub mod accounts { + use solana_sdk::{pubkey, pubkey::Pubkey}; + + /// Public key for the Pump.fun program + pub const PUMPFUN: Pubkey = pubkey!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"); + + /// Public key for the MPL Token Metadata program + pub const MPL_TOKEN_METADATA: Pubkey = pubkey!("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"); + + /// Authority for program events + pub const EVENT_AUTHORITY: Pubkey = pubkey!("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"); + + /// System Program ID + pub const SYSTEM_PROGRAM: Pubkey = pubkey!("11111111111111111111111111111111"); + + /// Token Program ID + pub const TOKEN_PROGRAM: Pubkey = pubkey!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"); + + /// Associated Token Program ID + pub const ASSOCIATED_TOKEN_PROGRAM: Pubkey = pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL"); + + /// Rent Sysvar ID + pub const RENT: Pubkey = pubkey!("SysvarRent111111111111111111111111111111111"); + + pub const JITO_TIP_ACCOUNTS: [&str; 8] = [ + "96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5", + "HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe", + "Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY", + "ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49", + "DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh", + "ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt", + "DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL", + "3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT", + ]; + + /// Tip accounts + pub const NEXTBLOCK_TIP_ACCOUNTS: &[&str] = &[ + "NextbLoCkVtMGcV47JzewQdvBpLqT9TxQFozQkN98pE", + "NexTbLoCkWykbLuB1NkjXgFWkX9oAtcoagQegygXXA2", + "NeXTBLoCKs9F1y5PJS9CKrFNNLU1keHW71rfh7KgA1X", + "NexTBLockJYZ7QD7p2byrUa6df8ndV2WSd8GkbWqfbb", + "neXtBLock1LeC67jYd1QdAa32kbVeubsfPNTJC1V5At", + "nEXTBLockYgngeRmRrjDV31mGSekVPqZoMGhQEZtPVG", + "NEXTbLoCkB51HpLBLojQfpyVAMorm3zzKg7w9NFdqid", + "nextBLoCkPMgmG8ZgJtABeScP35qLa2AMCNKntAP7Xc" + ]; + + pub const ZEROSLOT_TIP_ACCOUNTS: &[&str] = &[ + "Eb2KpSC8uMt9GmzyAEm5Eb1AAAgTjRaXWFjKyFXHZxF3", + "FCjUJZ1qozm1e8romw216qyfQMaaWKxWsuySnumVCCNe", + "ENxTEjSQ1YabmUpXAdCgevnHQ9MHdLv8tzFiuiYJqa13", + "6rYLG55Q9RpsPGvqdPNJs4z5WTxJVatMB8zV3WJhs5EK", + "Cix2bHfqPcKcM233mzxbLk14kSggUUiz2A87fJtGivXr", + ]; + + pub const NOZOMI_TIP_ACCOUNTS: &[&str] = &[ + "TEMPaMeCRFAS9EKF53Jd6KpHxgL47uWLcpFArU1Fanq", + "noz3jAjPiHuBPqiSPkkugaJDkJscPuRhYnSpbi8UvC4", + "noz3str9KXfpKknefHji8L1mPgimezaiUyCHYMDv1GE", + "noz6uoYCDijhu1V7cutCpwxNiSovEwLdRHPwmgCGDNo", + "noz9EPNcT7WH6Sou3sr3GGjHQYVkN3DNirpbvDkv9YJ", + "nozc5yT15LazbLTFVZzoNZCwjh3yUtW86LoUyqsBu4L", + "nozFrhfnNGoyqwVuwPAW4aaGqempx4PU6g6D9CJMv7Z", + "nozievPk7HyK1Rqy1MPJwVQ7qQg2QoJGyP71oeDwbsu", + "noznbgwYnBLDHu8wcQVCEw6kDrXkPdKkydGJGNXGvL7", + "nozNVWs5N8mgzuD3qigrCG2UoKxZttxzZ85pvAQVrbP", + "nozpEGbwx4BcGp6pvEdAh1JoC2CQGZdU6HbNP1v2p6P", + "nozrhjhkCr3zXT3BiT4WCodYCUFeQvcdUkM7MqhKqge", + "nozrwQtWhEdrA6W8dkbt9gnUaMs52PdAv5byipnadq3", + "nozUacTVWub3cL4mJmGCYjKZTnE9RbdY5AP46iQgbPJ", + "nozWCyTPppJjRuw2fpzDhhWbW355fzosWSzrrMYB1Qk", + "nozWNju6dY353eMkMqURqwQEoM3SFgEKC6psLCSfUne", + "nozxNBgWohjR75vdspfxR5H9ceC7XXH99xpxhVGt3Bb" + ]; + + pub const AMM_PROGRAM: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"); +} + +pub mod trade { + pub const TRADER_TIP_AMOUNT: f64 = 0.0001; + pub const DEFAULT_SLIPPAGE: u64 = 1000; // 10% + pub const DEFAULT_COMPUTE_UNIT_LIMIT: u32 = 78000; + pub const DEFAULT_COMPUTE_UNIT_PRICE: u64 = 500000; + pub const DEFAULT_BUY_TIP_FEE: f64 = 0.0006; + pub const DEFAULT_SELL_TIP_FEE: f64 = 0.0001; +} + +pub struct Symbol; + +impl Symbol { + pub const SOLANA: &'static str = "solana"; +} diff --git a/src/grpc/shred_stream.rs b/src/grpc/shred_stream.rs index 1e1a52b..657a352 100755 --- a/src/grpc/shred_stream.rs +++ b/src/grpc/shred_stream.rs @@ -10,9 +10,9 @@ use solana_sdk::transaction::VersionedTransaction; use crate::common::AnyResult; use solana_sdk::pubkey::Pubkey; -use crate::common::logs_data::DexInstruction; -use crate::common::logs_events::PumpfunEvent; -use crate::common::logs_filters::LogFilter; +use crate::common::pumpfun::logs_data::DexInstruction; +use crate::common::pumpfun::logs_events::PumpfunEvent; +use crate::common::pumpfun::logs_filters::LogFilter; use crate::swqos::jito_grpc::shredstream::shredstream_proxy_client::ShredstreamProxyClient; use crate::swqos::jito_grpc::shredstream::SubscribeEntriesRequest; diff --git a/src/grpc/yellow_stone.rs b/src/grpc/yellow_stone.rs index b9fb663..85ebaba 100755 --- a/src/grpc/yellow_stone.rs +++ b/src/grpc/yellow_stone.rs @@ -15,9 +15,9 @@ use solana_transaction_status::{ option_serializer::OptionSerializer, EncodedTransactionWithStatusMeta, UiTransactionEncoding, }; -use crate::common::logs_data::{DexInstruction, TransferInfo}; -use crate::common::logs_events::{PumpfunEvent, SystemEvent}; -use crate::common::logs_filters::LogFilter; +use crate::common::pumpfun::logs_data::{DexInstruction, TransferInfo}; +use crate::common::pumpfun::logs_events::{PumpfunEvent, SystemEvent}; +use crate::common::pumpfun::logs_filters::LogFilter; use crate::common::AnyResult; type TransactionsFilterMap = HashMap; diff --git a/src/instruction/mod.rs b/src/instruction/mod.rs index 135c246..d730878 100755 --- a/src/instruction/mod.rs +++ b/src/instruction/mod.rs @@ -196,21 +196,21 @@ pub fn sell( ) -> Instruction { let bonding_curve: Pubkey = get_bonding_curve_pda(mint).unwrap(); Instruction::new_with_bytes( - constants::accounts::PUMPFUN, + constants::pumpfun::accounts::PUMPFUN, &args.data(), vec![ - AccountMeta::new_readonly(constants::global_constants::GLOBAL_ACCOUNT, false), + AccountMeta::new_readonly(constants::pumpfun::global_constants::GLOBAL_ACCOUNT, false), AccountMeta::new(*fee_recipient, false), AccountMeta::new_readonly(*mint, false), AccountMeta::new(bonding_curve, false), AccountMeta::new(get_associated_token_address(&bonding_curve, mint), false), AccountMeta::new(get_associated_token_address(&payer.pubkey(), mint), false), AccountMeta::new(payer.pubkey(), true), - AccountMeta::new_readonly(constants::accounts::SYSTEM_PROGRAM, false), + AccountMeta::new_readonly(constants::pumpfun::accounts::SYSTEM_PROGRAM, false), AccountMeta::new(*creator_vault_pda, false), - AccountMeta::new_readonly(constants::accounts::TOKEN_PROGRAM, false), - AccountMeta::new_readonly(constants::accounts::EVENT_AUTHORITY, false), - AccountMeta::new_readonly(constants::accounts::PUMPFUN, false), + AccountMeta::new_readonly(constants::pumpfun::accounts::TOKEN_PROGRAM, false), + AccountMeta::new_readonly(constants::pumpfun::accounts::EVENT_AUTHORITY, false), + AccountMeta::new_readonly(constants::pumpfun::accounts::PUMPFUN, false), ], ) } diff --git a/src/lib.rs b/src/lib.rs index 1163c08..344674f 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,8 +19,8 @@ use solana_sdk::{ signature::{Keypair, Signer}, }; -use common::{logs_data::TradeInfo, logs_events::PumpfunEvent, logs_subscribe, Cluster, PriorityFee, SolanaRpcClient}; -use common::logs_subscribe::SubscriptionHandle; +use common::{pumpfun::logs_data::TradeInfo, pumpfun::logs_events::PumpfunEvent, pumpfun::logs_subscribe, Cluster, PriorityFee, SolanaRpcClient}; +use common::pumpfun::logs_subscribe::SubscriptionHandle; use ipfs::TokenMetadataIPFS; pub struct PumpFun { diff --git a/src/main.rs b/src/main.rs index 1c12a22..2c19723 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use pumpfun_sdk::{common::{ - logs_events::PumpfunEvent, - logs_subscribe::{stop_subscription, tokens_subscription}, AnyResult + pumpfun::logs_events::PumpfunEvent, + pumpfun::logs_subscribe::{stop_subscription, tokens_subscription}, AnyResult }, grpc::ShredStreamGrpc}; use solana_sdk::{commitment_config::CommitmentConfig, transaction::VersionedTransaction}; diff --git a/src/pumpfun/buy.rs b/src/pumpfun/buy.rs index 26335e2..5f73de7 100755 --- a/src/pumpfun/buy.rs +++ b/src/pumpfun/buy.rs @@ -15,7 +15,7 @@ use crate::{ PriorityFee, SolanaRpcClient }, - constants::{self, global_constants::FEE_RECIPIENT}, + constants::{self, pumpfun::global_constants::FEE_RECIPIENT}, instruction, swqos::{ClientType, FeeClient, TradeType} }; @@ -387,7 +387,7 @@ pub async fn build_buy_instructions( &payer.pubkey(), &payer.pubkey(), &mint, - &constants::accounts::TOKEN_PROGRAM, + &constants::pumpfun::accounts::TOKEN_PROGRAM, )); instructions.push(instruction::buy( diff --git a/src/pumpfun/common.rs b/src/pumpfun/common.rs index dd72456..27f268a 100755 --- a/src/pumpfun/common.rs +++ b/src/pumpfun/common.rs @@ -7,7 +7,7 @@ use solana_sdk::{ compute_budget::ComputeBudgetInstruction, instruction::Instruction, pubkey::Pubkey, signature::Keypair, signer::Signer, system_instruction, transaction::Transaction }; use spl_associated_token_account::get_associated_token_address; -use crate::{accounts::{self, BondingCurveAccount}, common::{logs_data::TradeInfo, PriorityFee, SolanaRpcClient}, constants::{self, global_constants::{CREATOR_FEE, FEE_BASIS_POINTS}, trade::DEFAULT_SLIPPAGE}}; +use crate::{accounts::{self, BondingCurveAccount}, common::{pumpfun::logs_data::TradeInfo, PriorityFee, SolanaRpcClient}, constants::{self, pumpfun::{self, global_constants::{CREATOR_FEE, FEE_BASIS_POINTS}, trade::DEFAULT_SLIPPAGE}}}; lazy_static::lazy_static! { static ref ACCOUNT_CACHE: RwLock>> = RwLock::new(HashMap::new()); @@ -142,7 +142,7 @@ pub async fn get_sol_balance(rpc: &SolanaRpcClient, account: &Pubkey) -> Result< #[inline] pub fn get_global_pda() -> Pubkey { static GLOBAL_PDA: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| { - Pubkey::find_program_address(&[constants::seeds::GLOBAL_SEED], &constants::accounts::PUMPFUN).0 + Pubkey::find_program_address(&[constants::pumpfun::seeds::GLOBAL_SEED], &constants::pumpfun::accounts::PUMPFUN).0 }); *GLOBAL_PDA } @@ -150,23 +150,23 @@ pub fn get_global_pda() -> Pubkey { #[inline] pub fn get_mint_authority_pda() -> Pubkey { static MINT_AUTHORITY_PDA: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| { - Pubkey::find_program_address(&[constants::seeds::MINT_AUTHORITY_SEED], &constants::accounts::PUMPFUN).0 + Pubkey::find_program_address(&[constants::pumpfun::seeds::MINT_AUTHORITY_SEED], &constants::pumpfun::accounts::PUMPFUN).0 }); *MINT_AUTHORITY_PDA } #[inline] pub fn get_bonding_curve_pda(mint: &Pubkey) -> Option { - let seeds: &[&[u8]; 2] = &[constants::seeds::BONDING_CURVE_SEED, mint.as_ref()]; - let program_id: &Pubkey = &constants::accounts::PUMPFUN; + let seeds: &[&[u8]; 2] = &[constants::pumpfun::seeds::BONDING_CURVE_SEED, mint.as_ref()]; + let program_id: &Pubkey = &constants::pumpfun::accounts::PUMPFUN; let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id); pda.map(|pubkey| pubkey.0) } #[inline] pub fn get_creator_vault_pda(creator: &Pubkey) -> Option { - let seeds: &[&[u8]; 2] = &[constants::seeds::CREATOR_VAULT_SEED, creator.as_ref()]; - let program_id: &Pubkey = &constants::accounts::PUMPFUN; + let seeds: &[&[u8]; 2] = &[constants::pumpfun::seeds::CREATOR_VAULT_SEED, creator.as_ref()]; + let program_id: &Pubkey = &constants::pumpfun::accounts::PUMPFUN; let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id); pda.map(|pubkey| pubkey.0) } @@ -175,11 +175,11 @@ pub fn get_creator_vault_pda(creator: &Pubkey) -> Option { pub fn get_metadata_pda(mint: &Pubkey) -> Pubkey { Pubkey::find_program_address( &[ - constants::seeds::METADATA_SEED, - constants::accounts::MPL_TOKEN_METADATA.as_ref(), + constants::pumpfun::seeds::METADATA_SEED, + constants::pumpfun::accounts::MPL_TOKEN_METADATA.as_ref(), mint.as_ref(), ], - &constants::accounts::MPL_TOKEN_METADATA + &constants::pumpfun::accounts::MPL_TOKEN_METADATA ).0 } diff --git a/src/pumpfun/sell.rs b/src/pumpfun/sell.rs index 5d17972..96130f5 100755 --- a/src/pumpfun/sell.rs +++ b/src/pumpfun/sell.rs @@ -8,7 +8,7 @@ use spl_token::instruction::close_account; use tokio::task::JoinHandle; use std::{str::FromStr, sync::Arc, time::Instant}; -use crate::{common::{address_lookup_cache::get_address_lookup_table_account, PriorityFee, SolanaRpcClient}, constants::{global_constants::FEE_RECIPIENT}, instruction, swqos::{FeeClient, TradeType, ClientType}}; +use crate::{common::{address_lookup_cache::get_address_lookup_table_account, PriorityFee, SolanaRpcClient}, constants::pumpfun::{global_constants::FEE_RECIPIENT}, instruction, swqos::{FeeClient, TradeType, ClientType}}; use super::common::get_creator_vault_pda; diff --git a/src/swqos/mod.rs b/src/swqos/mod.rs index ff40e7d..8a92dab 100755 --- a/src/swqos/mod.rs +++ b/src/swqos/mod.rs @@ -24,7 +24,7 @@ use anyhow::{anyhow, Result}; use rand::{rng, seq::{IndexedRandom, IteratorRandom}}; use solana_sdk::transaction::VersionedTransaction; -use crate::{common::SolanaRpcClient, constants::accounts::{JITO_TIP_ACCOUNTS, NEXTBLOCK_TIP_ACCOUNTS, ZEROSLOT_TIP_ACCOUNTS, NOZOMI_TIP_ACCOUNTS}}; +use crate::{common::SolanaRpcClient, constants::pumpfun::accounts::{JITO_TIP_ACCOUNTS, NEXTBLOCK_TIP_ACCOUNTS, ZEROSLOT_TIP_ACCOUNTS, NOZOMI_TIP_ACCOUNTS}}; pub mod api; pub mod common;