update trade config and swqos
This commit is contained in:
+6
-46
@@ -3,71 +3,32 @@ 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::pumpfun::trade::{DEFAULT_BUY_TIP_FEE, DEFAULT_COMPUTE_UNIT_LIMIT, DEFAULT_COMPUTE_UNIT_PRICE, DEFAULT_RPC_UNIT_LIMIT, DEFAULT_RPC_UNIT_PRICE, DEFAULT_SELL_TIP_FEE}, swqos::SwqosClient};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum SwqosType {
|
||||
Jito,
|
||||
NextBlock,
|
||||
ZeroSlot,
|
||||
Nozomi,
|
||||
Rpc,
|
||||
}
|
||||
use crate::{constants::pumpfun::trade::{DEFAULT_BUY_TIP_FEE, DEFAULT_COMPUTE_UNIT_LIMIT, DEFAULT_COMPUTE_UNIT_PRICE, DEFAULT_RPC_UNIT_LIMIT, DEFAULT_RPC_UNIT_PRICE, DEFAULT_SELL_TIP_FEE}, swqos::{SwqosClient, SwqosConfig, SwqosRegion}};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Cluster {
|
||||
pub struct TradeConfig {
|
||||
pub rpc_url: String,
|
||||
pub block_engine_url: String,
|
||||
pub nextblock_url: String,
|
||||
pub nextblock_auth_token: String,
|
||||
pub zeroslot_url: String,
|
||||
pub zeroslot_auth_token: String,
|
||||
pub nozomi_url: String,
|
||||
pub nozomi_auth_token: String,
|
||||
pub use_jito: bool,
|
||||
pub use_nextblock: bool,
|
||||
pub use_zeroslot: bool,
|
||||
pub use_nozomi: bool,
|
||||
pub swqos_configs: Vec<SwqosConfig>,
|
||||
pub priority_fee: PriorityFee,
|
||||
pub commitment: CommitmentConfig,
|
||||
pub lookup_table_key: Option<Pubkey>,
|
||||
pub use_rpc: bool,
|
||||
}
|
||||
|
||||
impl Cluster {
|
||||
impl TradeConfig {
|
||||
pub fn new(
|
||||
rpc_url: String,
|
||||
block_engine_url:
|
||||
String, nextblock_url:
|
||||
String, nextblock_auth_token:
|
||||
String, zeroslot_url: String,
|
||||
zeroslot_auth_token: String,
|
||||
nozomi_url: String,
|
||||
nozomi_auth_token: String,
|
||||
swqos_configs: Vec<SwqosConfig>,
|
||||
priority_fee: PriorityFee,
|
||||
commitment: CommitmentConfig,
|
||||
use_jito: bool,
|
||||
use_nextblock: bool,
|
||||
use_zeroslot: bool,
|
||||
use_nozomi: bool,
|
||||
lookup_table_key: Option<Pubkey>,
|
||||
use_rpc: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
rpc_url,
|
||||
block_engine_url,
|
||||
nextblock_url,
|
||||
nextblock_auth_token,
|
||||
zeroslot_url,
|
||||
zeroslot_auth_token,
|
||||
nozomi_url,
|
||||
nozomi_auth_token,
|
||||
swqos_configs,
|
||||
priority_fee,
|
||||
commitment,
|
||||
use_jito,
|
||||
use_nextblock,
|
||||
use_zeroslot,
|
||||
use_nozomi,
|
||||
lookup_table_key,
|
||||
use_rpc,
|
||||
}
|
||||
@@ -117,4 +78,3 @@ impl MethodArgs {
|
||||
}
|
||||
|
||||
pub type AnyResult<T> = anyhow::Result<T>;
|
||||
|
||||
|
||||
+87
-80
@@ -22,17 +22,18 @@ use solana_sdk::{
|
||||
signature::{Keypair, Signer},
|
||||
};
|
||||
|
||||
use common::{pumpfun::logs_data::TradeInfo, pumpfun::logs_events::PumpfunEvent, pumpfun::logs_subscribe, Cluster, PriorityFee, SolanaRpcClient};
|
||||
use common::{pumpfun::logs_data::TradeInfo, pumpfun::logs_events::PumpfunEvent, pumpfun::logs_subscribe, TradeConfig, PriorityFee, SolanaRpcClient};
|
||||
use common::pumpfun::logs_subscribe::SubscriptionHandle;
|
||||
|
||||
use constants::trade_type::{COPY_BUY, SNIPER_BUY};
|
||||
use constants::trade_platform::{PUMPFUN, PUMPFUN_SWAP, RAYDIUM};
|
||||
use constants::trade_platform::{PUMPFUN, PUMPFUN_SWAP};
|
||||
use accounts::BondingCurveAccount;
|
||||
|
||||
use crate::swqos::SwqosType;
|
||||
use crate::swqos::jito::JitoClient;
|
||||
use crate::swqos::nextblock::NextBlockClient;
|
||||
use crate::swqos::nozomi::NozomiClient;
|
||||
use crate::swqos::solana_rpc::SolRpcClient;
|
||||
use crate::swqos::temporal::TemporalClient;
|
||||
use crate::swqos::zeroslot::ZeroSlotClient;
|
||||
use crate::trading::core::params::PumpFunParams;
|
||||
use crate::trading::core::params::PumpFunSellParams;
|
||||
@@ -46,7 +47,7 @@ pub struct SolanaTrade {
|
||||
pub rpc: Arc<SolanaRpcClient>,
|
||||
pub swqos_clients: Vec<Arc<SwqosClient>>,
|
||||
pub priority_fee: PriorityFee,
|
||||
pub cluster: Cluster,
|
||||
pub trade_config: TradeConfig,
|
||||
}
|
||||
|
||||
static INSTANCE: Mutex<Option<Arc<SolanaTrade>>> = Mutex::new(None);
|
||||
@@ -58,7 +59,7 @@ impl Clone for SolanaTrade {
|
||||
rpc: self.rpc.clone(),
|
||||
swqos_clients: self.swqos_clients.clone(),
|
||||
priority_fee: self.priority_fee.clone(),
|
||||
cluster: self.cluster.clone(),
|
||||
trade_config: self.trade_config.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,7 +68,7 @@ impl SolanaTrade {
|
||||
#[inline]
|
||||
pub async fn new(
|
||||
payer: Arc<Keypair>,
|
||||
cluster: &Cluster,
|
||||
trade_config: TradeConfig,
|
||||
) -> Self {
|
||||
if CryptoProvider::get_default().is_none() {
|
||||
let _ = default_provider()
|
||||
@@ -75,62 +76,68 @@ impl SolanaTrade {
|
||||
.map_err(|e| anyhow::anyhow!("Failed to install crypto provider: {:?}", e));
|
||||
}
|
||||
|
||||
let rpc_url = trade_config.rpc_url.clone();
|
||||
let swqos_configs = trade_config.swqos_configs.clone();
|
||||
let priority_fee = trade_config.priority_fee.clone();
|
||||
let commitment = trade_config.commitment.clone();
|
||||
|
||||
let rpc = SolanaRpcClient::new_with_commitment(
|
||||
cluster.clone().rpc_url,
|
||||
cluster.clone().commitment
|
||||
rpc_url.clone(),
|
||||
commitment
|
||||
);
|
||||
let rpc = Arc::new(rpc);
|
||||
|
||||
let mut swqos_clients: Vec<Arc<SwqosClient>> = vec![];
|
||||
if cluster.clone().use_jito {
|
||||
let jito_client = JitoClient::new(
|
||||
cluster.clone().rpc_url,
|
||||
cluster.clone().block_engine_url
|
||||
).await.expect("Failed to create Jito client");
|
||||
|
||||
swqos_clients.push(Arc::new(jito_client));
|
||||
}
|
||||
|
||||
if cluster.clone().use_zeroslot {
|
||||
let zeroslot_client = ZeroSlotClient::new(
|
||||
cluster.clone().rpc_url,
|
||||
cluster.clone().zeroslot_url,
|
||||
cluster.clone().zeroslot_auth_token
|
||||
);
|
||||
|
||||
swqos_clients.push(Arc::new(zeroslot_client));
|
||||
}
|
||||
|
||||
if cluster.clone().use_nozomi {
|
||||
let nozomi_client = NozomiClient::new(
|
||||
cluster.clone().rpc_url,
|
||||
cluster.clone().nozomi_url,
|
||||
cluster.clone().nozomi_auth_token
|
||||
);
|
||||
|
||||
swqos_clients.push(Arc::new(nozomi_client));
|
||||
}
|
||||
|
||||
if cluster.clone().use_nextblock {
|
||||
let nextblock_client = NextBlockClient::new(
|
||||
cluster.clone().rpc_url,
|
||||
cluster.clone().nextblock_url,
|
||||
cluster.clone().nextblock_auth_token
|
||||
);
|
||||
|
||||
swqos_clients.push(Arc::new(nextblock_client));
|
||||
}
|
||||
|
||||
if cluster.clone().use_rpc {
|
||||
let rpc_client = SolRpcClient::new(rpc.clone());
|
||||
swqos_clients.push(Arc::new(rpc_client));
|
||||
for swqos in swqos_configs {
|
||||
match swqos.swqos_type {
|
||||
SwqosType::Jito => {
|
||||
let jito_client = JitoClient::new(
|
||||
rpc_url.clone(),
|
||||
swqos.endpoint,
|
||||
).await.expect("Failed to create Jito client");
|
||||
swqos_clients.push(Arc::new(jito_client));
|
||||
}
|
||||
SwqosType::NextBlock => {
|
||||
let nextblock_client = NextBlockClient::new(
|
||||
rpc_url.clone(),
|
||||
swqos.endpoint,
|
||||
swqos.auth_token
|
||||
);
|
||||
swqos_clients.push(Arc::new(nextblock_client));
|
||||
}
|
||||
SwqosType::ZeroSlot => {
|
||||
let zeroslot_client = ZeroSlotClient::new(
|
||||
rpc_url.clone(),
|
||||
swqos.endpoint,
|
||||
swqos.auth_token
|
||||
);
|
||||
swqos_clients.push(Arc::new(zeroslot_client));
|
||||
}
|
||||
SwqosType::Temporal => {
|
||||
let temporal_client = TemporalClient::new(
|
||||
rpc_url.clone(),
|
||||
swqos.endpoint,
|
||||
swqos.auth_token
|
||||
);
|
||||
swqos_clients.push(Arc::new(temporal_client));
|
||||
}
|
||||
SwqosType::Rpc => {
|
||||
let rpc_client = SolRpcClient::new(rpc.clone());
|
||||
swqos_clients.push(Arc::new(rpc_client));
|
||||
}
|
||||
_ => {
|
||||
println!("Unsupported swqos type: {:?}", swqos.swqos_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let instance = Self {
|
||||
payer,
|
||||
rpc,
|
||||
swqos_clients,
|
||||
priority_fee: cluster.clone().priority_fee,
|
||||
cluster: cluster.clone(),
|
||||
priority_fee,
|
||||
trade_config: trade_config.clone(),
|
||||
};
|
||||
|
||||
let mut current = INSTANCE.lock().unwrap();
|
||||
@@ -168,7 +175,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
bonding_curve,
|
||||
SNIPER_BUY.to_string(),
|
||||
@@ -194,7 +201,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
bonding_curve,
|
||||
COPY_BUY.to_string(),
|
||||
@@ -208,7 +215,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
None,
|
||||
None,
|
||||
@@ -249,7 +256,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.bonding_curve.clone(),
|
||||
COPY_BUY.to_string(),
|
||||
@@ -266,7 +273,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.pool.clone(),
|
||||
protocol_params.pool_base_token_account.clone(),
|
||||
@@ -304,7 +311,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
bonding_curve,
|
||||
SNIPER_BUY.to_string(),
|
||||
@@ -338,7 +345,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.bonding_curve.clone(),
|
||||
COPY_BUY.to_string(),
|
||||
@@ -356,7 +363,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.pool.clone(),
|
||||
protocol_params.pool_base_token_account.clone(),
|
||||
@@ -395,7 +402,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
bonding_curve,
|
||||
COPY_BUY.to_string(),
|
||||
@@ -410,7 +417,7 @@ impl SolanaTrade {
|
||||
buy_sol_cost,
|
||||
slippage_basis_points,
|
||||
priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
None,
|
||||
None,
|
||||
@@ -439,7 +446,7 @@ impl SolanaTrade {
|
||||
creator,
|
||||
amount_token,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
}
|
||||
@@ -463,7 +470,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
amount_token,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if trade_platform == PUMPFUN_SWAP {
|
||||
@@ -475,7 +482,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
None,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
None,
|
||||
None,
|
||||
@@ -505,7 +512,7 @@ impl SolanaTrade {
|
||||
creator,
|
||||
amount,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if trade_platform == PUMPFUN_SWAP {
|
||||
@@ -517,7 +524,7 @@ impl SolanaTrade {
|
||||
amount,
|
||||
None,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
None,
|
||||
None,
|
||||
@@ -549,7 +556,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
amount_token,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if trade_platform == PUMPFUN_SWAP {
|
||||
@@ -562,7 +569,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
None,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
None,
|
||||
None,
|
||||
@@ -592,7 +599,7 @@ impl SolanaTrade {
|
||||
creator,
|
||||
amount,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if trade_platform == PUMPFUN_SWAP {
|
||||
@@ -605,7 +612,7 @@ impl SolanaTrade {
|
||||
amount,
|
||||
None,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
None,
|
||||
None,
|
||||
@@ -634,7 +641,7 @@ impl SolanaTrade {
|
||||
creator,
|
||||
amount_token,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
}
|
||||
@@ -664,7 +671,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
amount_token.unwrap_or(0),
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if let Some(protocol_params) = sell_params
|
||||
@@ -679,7 +686,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
None,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.pool.clone(),
|
||||
protocol_params.pool_base_token_account.clone(),
|
||||
@@ -712,7 +719,7 @@ impl SolanaTrade {
|
||||
creator,
|
||||
amount.unwrap_or(0),
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if let Some(protocol_params) = sell_params
|
||||
@@ -727,7 +734,7 @@ impl SolanaTrade {
|
||||
amount.unwrap_or(0),
|
||||
None,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.pool.clone(),
|
||||
protocol_params.pool_base_token_account.clone(),
|
||||
@@ -762,7 +769,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
amount_token.unwrap_or(0),
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if let Some(protocol_params) = sell_params
|
||||
@@ -778,7 +785,7 @@ impl SolanaTrade {
|
||||
percent,
|
||||
sell_params.slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.pool.clone(),
|
||||
protocol_params.pool_base_token_account.clone(),
|
||||
@@ -811,7 +818,7 @@ impl SolanaTrade {
|
||||
creator,
|
||||
amount.unwrap_or(0),
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
).await
|
||||
} else if let Some(protocol_params) = sell_params
|
||||
@@ -827,7 +834,7 @@ impl SolanaTrade {
|
||||
amount.unwrap_or(0),
|
||||
sell_params.slippage_basis_points,
|
||||
self.priority_fee.clone(),
|
||||
self.cluster.clone().lookup_table_key,
|
||||
self.trade_config.lookup_table_key,
|
||||
recent_blockhash,
|
||||
protocol_params.pool.clone(),
|
||||
protocol_params.pool_base_token_account.clone(),
|
||||
@@ -871,7 +878,7 @@ impl SolanaTrade {
|
||||
|
||||
#[inline]
|
||||
pub async fn get_token_balance(&self, payer: &Pubkey, mint: &Pubkey) -> Result<u64, anyhow::Error> {
|
||||
println!("get_token_balance payer: {}, mint: {}, cluster: {}", payer, mint, self.cluster.rpc_url);
|
||||
println!("get_token_balance payer: {}, mint: {}, rpc_url: {}", payer, mint, self.trade_config.rpc_url);
|
||||
pumpfun::common::get_token_balance(&self.rpc, payer, mint).await
|
||||
}
|
||||
|
||||
|
||||
+44
-65
@@ -1,23 +1,8 @@
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
|
||||
use sol_trade_sdk::{
|
||||
accounts::BondingCurveAccount, common::{
|
||||
pumpfun::{
|
||||
self,
|
||||
logs_events::PumpfunEvent,
|
||||
logs_subscribe::{stop_subscription, tokens_subscription}, TradeInfo,
|
||||
},
|
||||
pumpswap::{self, PumpSwapEvent},
|
||||
raydium::{self, RaydiumEvent},
|
||||
AnyResult, Cluster, PriorityFee,
|
||||
}, constants::pumpfun::global_constants::TOKEN_TOTAL_SUPPLY, grpc::{ShredStreamGrpc, YellowstoneGrpc}, pumpfun::common::get_bonding_curve_pda, SolanaTrade
|
||||
};
|
||||
use sol_trade_sdk::{accounts::BondingCurveAccount, common::{pumpfun::PumpfunEvent, pumpswap::PumpSwapEvent, raydium::RaydiumEvent, AnyResult, PriorityFee, TradeConfig}, constants::pumpfun::global_constants::TOKEN_TOTAL_SUPPLY, grpc::{ShredStreamGrpc, YellowstoneGrpc}, pumpfun::common::get_bonding_curve_pda, swqos::{SwqosConfig, SwqosRegion, SwqosType}, SolanaTrade};
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_hash::Hash;
|
||||
use solana_sdk::{
|
||||
commitment_config::CommitmentConfig, pubkey::Pubkey, signature::Keypair,
|
||||
transaction::VersionedTransaction,
|
||||
};
|
||||
use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signature::Keypair};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
@@ -259,31 +244,28 @@ async fn test_raydium_with_grpc() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
async fn test_pumpfun_sniper() -> AnyResult<()> {
|
||||
let payer = Keypair::new();
|
||||
let swqos_configs = vec![
|
||||
SwqosConfig::new(None, Some("your auth_token for jito".to_string()), SwqosType::Jito, SwqosRegion::Frankfurt),
|
||||
SwqosConfig::new(None, Some("your auth_token for zeroslot".to_string()), SwqosType::ZeroSlot, SwqosRegion::Frankfurt),
|
||||
SwqosConfig::new(None, Some("your auth_token for temporal".to_string()), SwqosType::Temporal, SwqosRegion::Frankfurt),
|
||||
];
|
||||
|
||||
let rpc_url = "https://mainnet.helius-rpc.com/?api-key=xxxxxx".to_string();
|
||||
|
||||
// Define cluster configuration
|
||||
let cluster = Cluster {
|
||||
rpc_url: "https://mainnet.helius-rpc.com/?api-key=f2f194bb-6bd6-4f20-9a94-7fe0799ade0b"
|
||||
.to_string(),
|
||||
let trade_config = TradeConfig {
|
||||
rpc_url: rpc_url.clone(),
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
priority_fee: PriorityFee::default(),
|
||||
use_jito: false,
|
||||
use_zeroslot: false,
|
||||
use_nozomi: false,
|
||||
use_nextblock: false,
|
||||
block_engine_url: "".to_string(),
|
||||
zeroslot_url: "".to_string(),
|
||||
zeroslot_auth_token: "".to_string(),
|
||||
nozomi_url: "".to_string(),
|
||||
nozomi_auth_token: "".to_string(),
|
||||
nextblock_url: "".to_string(),
|
||||
nextblock_auth_token: "".to_string(),
|
||||
swqos_configs,
|
||||
lookup_table_key: None,
|
||||
use_rpc: true,
|
||||
};
|
||||
let solana_trade_client = SolanaTrade::new(Arc::new(payer), &cluster).await;
|
||||
let solana_trade_client = SolanaTrade::new(Arc::new(payer), trade_config).await;
|
||||
let creator = Pubkey::from_str("xxx")?; // dev account
|
||||
let buy_sol_cost = 500_000; // 0.0005 SOL
|
||||
let slippage_basis_points = Some(100);
|
||||
let rpc = RpcClient::new(cluster.rpc_url);
|
||||
let rpc = RpcClient::new(rpc_url);
|
||||
let recent_blockhash = rpc.get_latest_blockhash().unwrap();
|
||||
let mint_pubkey = Pubkey::from_str("xxx")?; // token mint
|
||||
println!("Sniping buy tokens from PumpFun...");
|
||||
@@ -306,31 +288,30 @@ async fn test_pumpfun_sniper() -> AnyResult<()> {
|
||||
|
||||
async fn test_pumpfun() -> AnyResult<()> {
|
||||
let payer = Keypair::new();
|
||||
|
||||
let swqos_configs = vec![
|
||||
SwqosConfig::new(None, Some("your auth_token for jito".to_string()), SwqosType::Jito, SwqosRegion::Frankfurt),
|
||||
SwqosConfig::new(None, Some("your auth_token for zeroslot".to_string()), SwqosType::ZeroSlot, SwqosRegion::Frankfurt),
|
||||
SwqosConfig::new(None, Some("your auth_token for temporal".to_string()), SwqosType::Temporal, SwqosRegion::Frankfurt),
|
||||
];
|
||||
|
||||
let rpc_url = "https://mainnet.helius-rpc.com/?api-key=xxxxxx".to_string();
|
||||
|
||||
// Define cluster configuration
|
||||
let cluster = Cluster {
|
||||
rpc_url: "https://mainnet.helius-rpc.com/?api-key=f2f194bb-6bd6-4f20-9a94-7fe0799ade0b"
|
||||
.to_string(),
|
||||
let trade_config = TradeConfig {
|
||||
rpc_url: rpc_url.clone(),
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
priority_fee: PriorityFee::default(),
|
||||
use_jito: false,
|
||||
use_zeroslot: false,
|
||||
use_nozomi: false,
|
||||
use_nextblock: false,
|
||||
block_engine_url: "".to_string(),
|
||||
zeroslot_url: "".to_string(),
|
||||
zeroslot_auth_token: "".to_string(),
|
||||
nozomi_url: "".to_string(),
|
||||
nozomi_auth_token: "".to_string(),
|
||||
nextblock_url: "".to_string(),
|
||||
nextblock_auth_token: "".to_string(),
|
||||
swqos_configs,
|
||||
lookup_table_key: None,
|
||||
use_rpc: true,
|
||||
};
|
||||
let solana_trade_client = SolanaTrade::new(Arc::new(payer), &cluster).await;
|
||||
|
||||
let solana_trade_client = SolanaTrade::new(Arc::new(payer), trade_config).await;
|
||||
let creator = Pubkey::from_str("xxx")?; // dev account
|
||||
let buy_sol_cost = 500_000; // 0.0005 SOL
|
||||
let slippage_basis_points = Some(100);
|
||||
let rpc = RpcClient::new(cluster.rpc_url);
|
||||
let rpc = RpcClient::new(rpc_url);
|
||||
let recent_blockhash = rpc.get_latest_blockhash().unwrap();
|
||||
let trade_platform = "pumpfun".to_string();
|
||||
let mint_pubkey = Pubkey::from_str("xxx")?; // token mint
|
||||
@@ -379,31 +360,29 @@ async fn test_pumpfun() -> AnyResult<()> {
|
||||
|
||||
async fn test_pumpswap() -> AnyResult<()> {
|
||||
let payer = Keypair::new();
|
||||
|
||||
let swqos_configs = vec![
|
||||
SwqosConfig::new(None, Some("your auth_token for jito".to_string()), SwqosType::Jito, SwqosRegion::Frankfurt),
|
||||
SwqosConfig::new(None, Some("your auth_token for zeroslot".to_string()), SwqosType::ZeroSlot, SwqosRegion::Frankfurt),
|
||||
SwqosConfig::new(None, Some("your auth_token for temporal".to_string()), SwqosType::Temporal, SwqosRegion::Frankfurt),
|
||||
];
|
||||
|
||||
let rpc_url = "https://mainnet.helius-rpc.com/?api-key=xxxxxx".to_string();
|
||||
|
||||
// Define cluster configuration
|
||||
let cluster = Cluster {
|
||||
rpc_url: "https://mainnet.helius-rpc.com/?api-key=f2f194bb-6bd6-4f20-9a94-7fe0799ade0b"
|
||||
.to_string(),
|
||||
let trade_config = TradeConfig {
|
||||
rpc_url: rpc_url.clone(),
|
||||
commitment: CommitmentConfig::confirmed(),
|
||||
priority_fee: PriorityFee::default(),
|
||||
use_jito: false,
|
||||
use_zeroslot: false,
|
||||
use_nozomi: false,
|
||||
use_nextblock: false,
|
||||
block_engine_url: "".to_string(),
|
||||
zeroslot_url: "".to_string(),
|
||||
zeroslot_auth_token: "".to_string(),
|
||||
nozomi_url: "".to_string(),
|
||||
nozomi_auth_token: "".to_string(),
|
||||
nextblock_url: "".to_string(),
|
||||
nextblock_auth_token: "".to_string(),
|
||||
swqos_configs,
|
||||
lookup_table_key: None,
|
||||
use_rpc: true,
|
||||
};
|
||||
let solana_trade_client = SolanaTrade::new(Arc::new(payer), &cluster).await;
|
||||
let solana_trade_client = SolanaTrade::new(Arc::new(payer), trade_config).await;
|
||||
let creator = Pubkey::from_str("11111111111111111111111111111111")?; // dev account
|
||||
let buy_sol_cost = 500_000; // 0.0005 SOL
|
||||
let slippage_basis_points = Some(100);
|
||||
let rpc = RpcClient::new(cluster.rpc_url);
|
||||
let rpc = RpcClient::new(rpc_url);
|
||||
let recent_blockhash = rpc.get_latest_blockhash().unwrap();
|
||||
let trade_platform = "pumpswap".to_string();
|
||||
let mint_pubkey = Pubkey::from_str("2zMMhcVQEXDtdE6vsFS7S7D5oUodfJHE8vd1gnBouauv")?; // token mint
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
pub const SWQOS_ENDPOINTS_JITO: [&str; 3] = [
|
||||
"https://ny.mainnet.block-engine.jito.wtf/api/v1/bundles",
|
||||
"https://ams.block-engine.jito.wtf/api/v1/bundles",
|
||||
"https://frankfurt.mainnet.block-engine.jito.wtf/api/v1/bundles",
|
||||
];
|
||||
|
||||
pub const SWQOS_ENDPOINTS_NEXTBLOCK: [&str; 3] = [
|
||||
"https://fra.nextblock.io",
|
||||
"https://ams.nextblock.io",
|
||||
"https://ny.nextblock.io",
|
||||
];
|
||||
|
||||
pub const SWQOS_ENDPOINTS_ZERO_SLOT: [&str; 3] = [
|
||||
"http://de1.0slot.trade",
|
||||
"http://ams.0slot.trade",
|
||||
"http://ny.0slot.trade",
|
||||
];
|
||||
|
||||
pub const SWQOS_ENDPOINTS_TEMPORAL: [&str; 3] = [
|
||||
"http://fra2.nozomi.temporal.xyz",
|
||||
"http://ams2.nozomi.temporal.xyz",
|
||||
"http://ny2.nozomi.temporal.xyz",
|
||||
];
|
||||
+3
-3
@@ -8,7 +8,7 @@ use std::sync::Arc;
|
||||
use solana_sdk::{transaction::VersionedTransaction, signature::Signature};
|
||||
use crate::protos::searcher::searcher_service_client::SearcherServiceClient;
|
||||
use crate::protos::searcher_client::{self, get_searcher_client_no_auth, send_bundle_with_confirmation};
|
||||
use crate::swqos::{ClientType, TradeType};
|
||||
use crate::swqos::{SwqosType, TradeType};
|
||||
use crate::swqos::SwqosClientTrait;
|
||||
|
||||
use crate::{common::SolanaRpcClient, constants::pumpfun::accounts::JITO_TIP_ACCOUNTS};
|
||||
@@ -37,8 +37,8 @@ impl SwqosClientTrait for JitoClient {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_client_type(&self) -> ClientType {
|
||||
ClientType::Jito
|
||||
fn get_swqos_type(&self) -> SwqosType {
|
||||
SwqosType::Jito
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+38
-6
@@ -4,8 +4,8 @@ pub mod solana_rpc;
|
||||
pub mod jito;
|
||||
pub mod nextblock;
|
||||
pub mod zeroslot;
|
||||
pub mod nozomi;
|
||||
pub mod types;
|
||||
pub mod temporal;
|
||||
pub mod define;
|
||||
|
||||
use solana_sdk::signature::Signature;
|
||||
use solana_sdk::transaction::VersionedTransaction;
|
||||
@@ -13,6 +13,8 @@ use tokio::sync::RwLock;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::swqos::define::{SWQOS_ENDPOINTS_JITO, SWQOS_ENDPOINTS_NEXTBLOCK, SWQOS_ENDPOINTS_TEMPORAL, SWQOS_ENDPOINTS_ZERO_SLOT};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref TIP_ACCOUNT_CACHE: RwLock<Vec<String>> = RwLock::new(Vec::new());
|
||||
}
|
||||
@@ -37,12 +39,12 @@ impl std::fmt::Display for TradeType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum ClientType {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum SwqosType {
|
||||
Jito,
|
||||
NextBlock,
|
||||
ZeroSlot,
|
||||
Nozomi,
|
||||
Temporal,
|
||||
Rpc,
|
||||
}
|
||||
|
||||
@@ -53,5 +55,35 @@ pub trait SwqosClientTrait {
|
||||
async fn send_transaction(&self, trade_type: TradeType, transaction: &VersionedTransaction) -> Result<Signature>;
|
||||
async fn send_transactions(&self, trade_type: TradeType, transactions: &Vec<VersionedTransaction>) -> Result<Vec<Signature>>;
|
||||
fn get_tip_account(&self) -> Result<String>;
|
||||
fn get_client_type(&self) -> ClientType;
|
||||
fn get_swqos_type(&self) -> SwqosType;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum SwqosRegion {
|
||||
NewYork,
|
||||
Amsterdam,
|
||||
Frankfurt,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SwqosConfig {
|
||||
pub endpoint: String,
|
||||
pub auth_token: String,
|
||||
pub swqos_type: SwqosType,
|
||||
}
|
||||
|
||||
impl SwqosConfig {
|
||||
pub fn new(endpoint: Option<String>, auth_token: Option<String>, swqos_type: SwqosType, region: SwqosRegion) -> Self {
|
||||
let endpoint = endpoint.unwrap_or_else(|| match swqos_type {
|
||||
SwqosType::Jito => SWQOS_ENDPOINTS_JITO[region as usize].to_string(),
|
||||
SwqosType::NextBlock => SWQOS_ENDPOINTS_NEXTBLOCK[region as usize].to_string(),
|
||||
SwqosType::ZeroSlot => SWQOS_ENDPOINTS_ZERO_SLOT[region as usize].to_string(),
|
||||
SwqosType::Temporal => SWQOS_ENDPOINTS_TEMPORAL[region as usize].to_string(),
|
||||
SwqosType::Rpc => "".to_string(),
|
||||
});
|
||||
|
||||
let auth_token = auth_token.unwrap();
|
||||
|
||||
Self { endpoint, auth_token, swqos_type }
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ use tonic::transport::ClientTlsConfig;
|
||||
|
||||
use anyhow::Result;
|
||||
use solana_sdk::transaction::VersionedTransaction;
|
||||
use crate::swqos::{ClientType, TradeType};
|
||||
use crate::swqos::{SwqosType, TradeType};
|
||||
use crate::swqos::SwqosClientTrait;
|
||||
|
||||
use crate::{common::SolanaRpcClient, constants::pumpfun::accounts::NEXTBLOCK_TIP_ACCOUNTS};
|
||||
@@ -67,8 +67,8 @@ impl SwqosClientTrait for NextBlockClient {
|
||||
Ok(tip_account.to_string())
|
||||
}
|
||||
|
||||
fn get_client_type(&self) -> ClientType {
|
||||
ClientType::NextBlock
|
||||
fn get_swqos_type(&self) -> SwqosType {
|
||||
SwqosType::NextBlock
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use solana_sdk::{
|
||||
};
|
||||
use solana_transaction_status::UiTransactionEncoding;
|
||||
|
||||
use crate::{common::SolanaRpcClient, swqos::{common::poll_transaction_confirmation, ClientType, TradeType}};
|
||||
use crate::{common::SolanaRpcClient, swqos::{common::poll_transaction_confirmation, SwqosType, TradeType}};
|
||||
use crate::swqos::SwqosClientTrait;
|
||||
use anyhow::Result;
|
||||
|
||||
@@ -52,8 +52,8 @@ impl SwqosClientTrait for SolRpcClient {
|
||||
Ok("".to_string())
|
||||
}
|
||||
|
||||
fn get_client_type(&self) -> ClientType {
|
||||
ClientType::Rpc
|
||||
fn get_swqos_type(&self) -> SwqosType {
|
||||
SwqosType::Rpc
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ use solana_transaction_status::UiTransactionEncoding;
|
||||
|
||||
use anyhow::Result;
|
||||
use solana_sdk::transaction::VersionedTransaction;
|
||||
use crate::swqos::{ClientType, TradeType};
|
||||
use crate::swqos::{SwqosType, TradeType};
|
||||
use crate::swqos::SwqosClientTrait;
|
||||
|
||||
use crate::{common::SolanaRpcClient, constants::pumpfun::accounts::NOZOMI_TIP_ACCOUNTS};
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NozomiClient {
|
||||
pub struct TemporalClient {
|
||||
pub rpc_client: Arc<SolanaRpcClient>,
|
||||
pub endpoint: String,
|
||||
pub auth_token: String,
|
||||
@@ -27,7 +27,7 @@ pub struct NozomiClient {
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SwqosClientTrait for NozomiClient {
|
||||
impl SwqosClientTrait for TemporalClient {
|
||||
async fn send_transaction(&self, trade_type: TradeType, transaction: &VersionedTransaction) -> Result<Signature> {
|
||||
self.send_transaction(trade_type, transaction).await
|
||||
}
|
||||
@@ -41,12 +41,12 @@ impl SwqosClientTrait for NozomiClient {
|
||||
Ok(tip_account.to_string())
|
||||
}
|
||||
|
||||
fn get_client_type(&self) -> ClientType {
|
||||
ClientType::Nozomi
|
||||
fn get_swqos_type(&self) -> SwqosType {
|
||||
SwqosType::Temporal
|
||||
}
|
||||
}
|
||||
|
||||
impl NozomiClient {
|
||||
impl TemporalClient {
|
||||
pub fn new(rpc_url: String, endpoint: String, auth_token: String) -> Self {
|
||||
let rpc_client = SolanaRpcClient::new(rpc_url);
|
||||
let http_client = Client::builder()
|
||||
@@ -10,7 +10,7 @@ use solana_transaction_status::UiTransactionEncoding;
|
||||
use anyhow::Result;
|
||||
use solana_sdk::signature::Signature;
|
||||
use solana_sdk::transaction::VersionedTransaction;
|
||||
use crate::swqos::{ClientType, TradeType};
|
||||
use crate::swqos::{SwqosType, TradeType};
|
||||
use crate::swqos::SwqosClientTrait;
|
||||
|
||||
use crate::{common::SolanaRpcClient, constants::pumpfun::accounts::ZEROSLOT_TIP_ACCOUNTS};
|
||||
@@ -39,8 +39,8 @@ impl SwqosClientTrait for ZeroSlotClient {
|
||||
Ok(tip_account.to_string())
|
||||
}
|
||||
|
||||
fn get_client_type(&self) -> ClientType {
|
||||
ClientType::ZeroSlot
|
||||
fn get_swqos_type(&self) -> SwqosType {
|
||||
SwqosType::ZeroSlot
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use tokio::task::JoinHandle;
|
||||
|
||||
use crate::{
|
||||
common::PriorityFee,
|
||||
swqos::{ClientType, SwqosClient, TradeType},
|
||||
swqos::{SwqosType, SwqosClient, TradeType},
|
||||
trading::common::{
|
||||
build_rpc_transaction, build_sell_tip_transaction_with_priority_fee,
|
||||
build_sell_transaction, build_tip_transaction_with_priority_fee,
|
||||
@@ -37,7 +37,7 @@ pub async fn parallel_execute_with_tips(
|
||||
let handle = tokio::spawn(async move {
|
||||
core_affinity::set_for_current(core_id);
|
||||
let transaction = if matches!(trade_type, TradeType::Sell)
|
||||
&& swqos_client.get_client_type() == ClientType::Rpc
|
||||
&& swqos_client.get_swqos_type() == SwqosType::Rpc
|
||||
{
|
||||
build_sell_transaction(
|
||||
payer,
|
||||
@@ -48,7 +48,7 @@ pub async fn parallel_execute_with_tips(
|
||||
)
|
||||
.await?
|
||||
} else if matches!(trade_type, TradeType::Sell)
|
||||
&& swqos_client.get_client_type() != ClientType::Rpc
|
||||
&& swqos_client.get_swqos_type() != SwqosType::Rpc
|
||||
{
|
||||
let tip_account = swqos_client.get_tip_account()?;
|
||||
let tip_account = Arc::new(Pubkey::from_str(&tip_account).map_err(|e| anyhow!(e))?);
|
||||
@@ -61,7 +61,7 @@ pub async fn parallel_execute_with_tips(
|
||||
recent_blockhash,
|
||||
)
|
||||
.await?
|
||||
} else if swqos_client.get_client_type() == ClientType::Rpc {
|
||||
} else if swqos_client.get_swqos_type() == SwqosType::Rpc {
|
||||
build_rpc_transaction(
|
||||
payer,
|
||||
&priority_fee,
|
||||
|
||||
Reference in New Issue
Block a user