From 36b25c1fbe1e5ab0bc41828d3c14ab909e3e5f2c Mon Sep 17 00:00:00 2001 From: wood Date: Thu, 10 Jul 2025 23:27:40 +0800 Subject: [PATCH] update readme --- README.md | 104 ++++++++++++++++++++++------------ README_CN.md | 104 ++++++++++++++++++++++------------ src/common/bonding_curve.rs | 28 +++++---- src/main.rs | 91 ++++++++++++++++++++--------- src/trading/pumpfun/common.rs | 2 +- 5 files changed, 220 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 4289e42..b5dc220 100755 --- a/README.md +++ b/README.md @@ -215,50 +215,45 @@ use sol_trade_sdk::{ trading::{ core::params::PumpFunParams, factory::TradingProtocol, - pumpfun::common::get_bonding_curve_account_v2, }, }; -async fn test_pumpfun() -> AnyResult<()> { +async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + println!("Testing PumpFun trading..."); + // if not dev trade, return + if !trade_info.is_dev_create_token_trade { + return Ok(()); + } + let solana_trade_client = test_create_solana_trade_client().await?; - let creator = Pubkey::from_str("xxxxxx")?; // dev account - let buy_sol_cost = 100_000; // 0.0001 SOL + let mint_pubkey = trade_info.mint; + let creator = trade_info.creator; + let dev_sol_amount = trade_info.max_sol_cost; + let dev_token_amount = trade_info.token_amount; let slippage_basis_points = Some(100); let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?; - let mint_pubkey = Pubkey::from_str("xxxxxx")?; // token mint - - println!("Buying tokens from PumpFun..."); - // get bonding curve - let (bonding_curve, bonding_curve_pda) = - get_bonding_curve_account_v2(&solana_trade_client.rpc, &mint_pubkey).await?; - let virtual_token_reserves = bonding_curve.virtual_token_reserves; - let virtual_sol_reserves = bonding_curve.virtual_sol_reserves; - let real_token_reserves = bonding_curve.real_token_reserves; - let real_sol_reserves = bonding_curve.real_sol_reserves; - let bonding_curve = BondingCurveAccount { - discriminator: bonding_curve.discriminator, - account: bonding_curve_pda, - virtual_token_reserves: virtual_token_reserves, - virtual_sol_reserves: virtual_sol_reserves, - real_token_reserves: real_token_reserves, - real_sol_reserves: real_sol_reserves, - token_total_supply: TOKEN_TOTAL_SUPPLY, - complete: false, - creator: creator, - }; - // For sniping developers - // let bonding_curve = - // BondingCurveAccount::new(&mint_pubkey, dev_buy_token, dev_cost_sol, creator); - // buy + println!("Buying tokens from PumpFun..."); + + // By not using RPC to fetch the bonding curve, transaction time can be saved. + let bonding_curve = BondingCurveAccount::from_dev_trade( + &mint_pubkey, + dev_token_amount, + dev_sol_amount, + creator, + ); + + // my trade cost sol amount + let buy_sol_amount = 100_000; + solana_trade_client .buy( DexType::PumpFun, mint_pubkey, Some(creator), - buy_sol_cost, + buy_sol_amount, slippage_basis_points, recent_blockhash, None, @@ -268,10 +263,50 @@ async fn test_pumpfun() -> AnyResult<()> { })), ) .await?; - - // sell - println!("Selling tokens from PumpFun..."); - let amount_token = 0; // Enter the actual amount_token + + Ok(()) +} + +async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + + println!("Testing PumpFun trading..."); + + let solana_trade_client = test_create_solana_trade_client().await?; + + let mint_pubkey = trade_info.mint; + let creator = trade_info.creator; + let slippage_basis_points = Some(100); + let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?; + + println!("Buying tokens from PumpFun..."); + + // my trade cost sol amount + let buy_sol_amount = 100_000; + + // By not using RPC to fetch the bonding curve, transaction time can be saved. + let bonding_curve = BondingCurveAccount::from_trade(&trade_info); + + solana_trade_client + .buy( + DexType::PumpFun, + mint_pubkey, + Some(creator), + buy_sol_amount, + slippage_basis_points, + recent_blockhash, + None, + false, + Some(Box::new(PumpFunParams { + bonding_curve: Some(Arc::new(bonding_curve.clone())), + })), + ) + .await?; + + Ok(()) +} + +async fn test_pumpfun_sell(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + let amount_token = 100_000_000; solana_trade_client .sell( DexType::PumpFun, @@ -285,7 +320,6 @@ async fn test_pumpfun() -> AnyResult<()> { None, ) .await?; - Ok(()) } ``` diff --git a/README_CN.md b/README_CN.md index 9424610..c09ffde 100755 --- a/README_CN.md +++ b/README_CN.md @@ -215,50 +215,45 @@ use sol_trade_sdk::{ trading::{ core::params::PumpFunParams, factory::TradingProtocol, - pumpfun::common::get_bonding_curve_account_v2, }, }; -async fn test_pumpfun() -> AnyResult<()> { +async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + println!("Testing PumpFun trading..."); + // 如果不是开发者购买,则返回 + if !trade_info.is_dev_create_token_trade && !trade_info.is_buy { + return Ok(()); + } + let solana_trade_client = test_create_solana_trade_client().await?; - let creator = Pubkey::from_str("xxxxxx")?; // dev account - let buy_sol_cost = 100_000; // 0.0001 SOL + let mint_pubkey = trade_info.mint; + let creator = trade_info.creator; + let dev_sol_amount = trade_info.max_sol_cost; + let dev_token_amount = trade_info.token_amount; let slippage_basis_points = Some(100); let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?; - let mint_pubkey = Pubkey::from_str("xxxxxx")?; // token mint - - println!("Buying tokens from PumpFun..."); - // get bonding curve - let (bonding_curve, bonding_curve_pda) = - get_bonding_curve_account_v2(&solana_trade_client.rpc, &mint_pubkey).await?; - let virtual_token_reserves = bonding_curve.virtual_token_reserves; - let virtual_sol_reserves = bonding_curve.virtual_sol_reserves; - let real_token_reserves = bonding_curve.real_token_reserves; - let real_sol_reserves = bonding_curve.real_sol_reserves; - let bonding_curve = BondingCurveAccount { - discriminator: bonding_curve.discriminator, - account: bonding_curve_pda, - virtual_token_reserves: virtual_token_reserves, - virtual_sol_reserves: virtual_sol_reserves, - real_token_reserves: real_token_reserves, - real_sol_reserves: real_sol_reserves, - token_total_supply: TOKEN_TOTAL_SUPPLY, - complete: false, - creator: creator, - }; - // 如果是狙击开发者 - // let bonding_curve = - // BondingCurveAccount::new(&mint_pubkey, dev_buy_token, dev_cost_sol, creator); - // buy + println!("Buying tokens from PumpFun..."); + + // 不使用rpc调用获取bonding_curve,可以节约交易时间 + let bonding_curve = BondingCurveAccount::from_dev_trade( + &mint_pubkey, + dev_token_amount, + dev_sol_amount, + creator, + ); + + // 我本次交易所花的的sol金额 + let buy_sol_amount = 100_000; + solana_trade_client .buy( DexType::PumpFun, mint_pubkey, Some(creator), - buy_sol_cost, + buy_sol_amount, slippage_basis_points, recent_blockhash, None, @@ -268,10 +263,50 @@ async fn test_pumpfun() -> AnyResult<()> { })), ) .await?; - - // sell - println!("Selling tokens from PumpFun..."); - let amount_token = 0; // 写上真实的amount_token + + Ok(()) +} + +async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + + println!("Testing PumpFun trading..."); + + let solana_trade_client = test_create_solana_trade_client().await?; + + let mint_pubkey = trade_info.mint; + let creator = trade_info.creator; + let slippage_basis_points = Some(100); + let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?; + + println!("Buying tokens from PumpFun..."); + + // 我本次交易所花的的sol金额 + let buy_sol_amount = 100_000; + + // 不使用rpc调用获取bonding_curve,可以节约交易时间 + let bonding_curve = BondingCurveAccount::from_trade(&trade_info); + + solana_trade_client + .buy( + DexType::PumpFun, + mint_pubkey, + Some(creator), + buy_sol_amount, + slippage_basis_points, + recent_blockhash, + None, + false, + Some(Box::new(PumpFunParams { + bonding_curve: Some(Arc::new(bonding_curve.clone())), + })), + ) + .await?; + + Ok(()) +} + +async fn test_pumpfun_sell(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + let amount_token = 100_000_000; solana_trade_client .sell( DexType::PumpFun, @@ -285,7 +320,6 @@ async fn test_pumpfun() -> AnyResult<()> { None, ) .await?; - Ok(()) } ``` diff --git a/src/common/bonding_curve.rs b/src/common/bonding_curve.rs index 849f46c..59a214b 100755 --- a/src/common/bonding_curve.rs +++ b/src/common/bonding_curve.rs @@ -28,7 +28,7 @@ use serde::{Serialize, Deserialize}; use solana_sdk::pubkey::Pubkey; -use crate::{constants::pumpfun::global_constants::{INITIAL_REAL_TOKEN_RESERVES, INITIAL_VIRTUAL_SOL_RESERVES, INITIAL_VIRTUAL_TOKEN_RESERVES, TOKEN_TOTAL_SUPPLY}, trading::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}, streaming::event_parser::protocols::pumpfun::PumpFunTradeEvent, trading::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)] @@ -54,17 +54,7 @@ pub struct BondingCurveAccount { } impl BondingCurveAccount { - /// Creates a new bonding curve instance - /// - /// # Arguments - /// * `discriminator` - Unique identifier for the curve - /// * `virtual_token_reserves` - Virtual token reserves for price calculations - /// * `virtual_sol_reserves` - Virtual SOL reserves for price calculations - /// * `real_token_reserves` - Actual token reserves available - /// * `real_sol_reserves` - Actual SOL reserves available - /// * `token_total_supply` - Total supply of tokens - /// * `complete` - Whether the curve is complete - pub fn new(mint: &Pubkey, dev_buy_token: u64, dev_cost_sol: u64, creator: Pubkey) -> Self { + pub fn from_dev_trade(mint: &Pubkey, dev_buy_token: u64, dev_cost_sol: u64, creator: Pubkey) -> Self { Self { discriminator: 0, account: get_bonding_curve_pda(mint).unwrap(), @@ -78,6 +68,20 @@ impl BondingCurveAccount { } } + pub fn from_trade(event: &PumpFunTradeEvent) -> Self { + Self { + discriminator: 0, + account: get_bonding_curve_pda(&event.mint).unwrap(), + virtual_token_reserves: event.virtual_token_reserves, + virtual_sol_reserves: event.virtual_sol_reserves, + real_token_reserves: event.real_token_reserves, + real_sol_reserves: event.real_sol_reserves, + token_total_supply: TOKEN_TOTAL_SUPPLY, + complete: false, + creator: event.creator, + } + } + pub fn get_creator_vault_pda(&self) -> Pubkey { get_creator_vault_pda(&self.creator).unwrap() } diff --git a/src/main.rs b/src/main.rs index f612085..37bd89a 100755 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,6 @@ use std::{str::FromStr, sync::Arc}; use sol_trade_sdk::{ common::{bonding_curve::BondingCurveAccount, AnyResult, PriorityFee, TradeConfig}, - constants::pumpfun::global_constants::TOKEN_TOTAL_SUPPLY, match_event, streaming::{ event_parser::{ @@ -21,7 +20,6 @@ use sol_trade_sdk::{ swqos::{SwqosConfig, SwqosRegion}, trading::{ core::params::PumpFunParams, factory::DexType, - pumpfun::common::get_bonding_curve_account_v2, }, SolanaTrade, }; @@ -30,7 +28,6 @@ use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signature: #[tokio::main] async fn main() -> Result<(), Box> { test_create_solana_trade_client().await?; - test_pumpfun().await?; test_pumpswap().await?; test_bonk().await?; test_grpc().await?; @@ -70,7 +67,8 @@ async fn test_create_solana_trade_client() -> AnyResult { Ok(solana_trade_client) } -async fn test_pumpfun() -> AnyResult<()> { +async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + println!("Testing PumpFun trading..."); let solana_trade_client = test_create_solana_trade_client().await?; @@ -81,28 +79,69 @@ async fn test_pumpfun() -> AnyResult<()> { let mint_pubkey = Pubkey::from_str("xxxxxx")?; // token mint println!("Buying tokens from PumpFun..."); - // get bonding curve - let (bonding_curve, bonding_curve_pda) = - get_bonding_curve_account_v2(&solana_trade_client.rpc, &mint_pubkey).await?; - let virtual_token_reserves = bonding_curve.virtual_token_reserves; - let virtual_sol_reserves = bonding_curve.virtual_sol_reserves; - let real_token_reserves = bonding_curve.real_token_reserves; - let real_sol_reserves = bonding_curve.real_sol_reserves; - let bonding_curve = BondingCurveAccount { - discriminator: bonding_curve.discriminator, - account: bonding_curve_pda, - virtual_token_reserves: virtual_token_reserves, - virtual_sol_reserves: virtual_sol_reserves, - real_token_reserves: real_token_reserves, - real_sol_reserves: real_sol_reserves, - token_total_supply: TOKEN_TOTAL_SUPPLY, - complete: false, - creator: creator, - }; - // 如果是狙击开发者 - // let bonding_curve = - // BondingCurveAccount::new(&mint_pubkey, dev_buy_token, dev_cost_sol, creator); - // buy + + let bonding_curve = BondingCurveAccount::from_trade(&trade_info); + + solana_trade_client + .buy( + DexType::PumpFun, + mint_pubkey, + Some(creator), + buy_sol_cost, + slippage_basis_points, + recent_blockhash, + None, + false, + Some(Box::new(PumpFunParams { + bonding_curve: Some(Arc::new(bonding_curve.clone())), + })), + ) + .await?; + // sell + println!("Selling tokens from PumpFun..."); + let amount_token = 0; // 写上真实的amount_token + solana_trade_client + .sell( + DexType::PumpFun, + mint_pubkey, + Some(creator), + amount_token, + slippage_basis_points, + recent_blockhash, + None, + false, + None, + ) + .await?; + Ok(()) +} + +async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> { + + println!("Testing PumpFun trading..."); + + // if not dev trade, return + if !trade_info.is_dev_create_token_trade { + return Ok(()); + } + + let solana_trade_client = test_create_solana_trade_client().await?; + let mint_pubkey = trade_info.mint; + let creator = trade_info.creator; + let buy_sol_cost = trade_info.max_sol_cost; + let amount_token = trade_info.token_amount; + let slippage_basis_points = Some(100); + let recent_blockhash = solana_trade_client.rpc.get_latest_blockhash().await?; + + println!("Buying tokens from PumpFun..."); + + let bonding_curve = BondingCurveAccount::from_dev_trade( + &mint_pubkey, + amount_token, + buy_sol_cost, + creator, + ); + solana_trade_client .buy( DexType::PumpFun, diff --git a/src/trading/pumpfun/common.rs b/src/trading/pumpfun/common.rs index 3e5e5f6..95521b3 100755 --- a/src/trading/pumpfun/common.rs +++ b/src/trading/pumpfun/common.rs @@ -187,7 +187,7 @@ pub async fn init_bonding_curve_account( dev_sol_cost: u64, creator: Pubkey, ) -> Result, anyhow::Error> { - let bonding_curve = BondingCurveAccount::new(mint, dev_buy_token, dev_sol_cost, creator); + let bonding_curve = BondingCurveAccount::from_dev_trade(mint, dev_buy_token, dev_sol_cost, creator); let bonding_curve = Arc::new(bonding_curve); Ok(bonding_curve) }