Merge pull request #67 from HelvetiCrypt/feat/shared-infrastructure

Add shared_infrastructure example and update documentation
This commit is contained in:
Wood
2026-01-06 15:01:55 +08:00
committed by GitHub
5 changed files with 174 additions and 34 deletions
+1
View File
@@ -17,6 +17,7 @@ readme = "README.md"
[workspace]
members = [
"examples/trading_client",
"examples/shared_infrastructure",
"examples/middleware_system",
"examples/pumpfun_copy_trading",
"examples/pumpfun_sniper_trading",
+18 -13
View File
@@ -71,6 +71,7 @@
8. **Concurrent Trading**: Send transactions using multiple MEV services simultaneously; the fastest succeeds while others fail
9. **Unified Trading Interface**: Use unified trading protocol enums for trading operations
10. **Middleware System**: Support for custom instruction middleware to modify, add, or remove instructions before transaction execution
11. **Shared Infrastructure**: Share expensive RPC and SWQOS clients across multiple wallets for reduced resource usage
## 📦 Installation
@@ -105,6 +106,7 @@ sol-trade-sdk = "3.3.6"
You can refer to [Example: Create TradingClient Instance](examples/trading_client/src/main.rs).
**Method 1: Simple (single wallet)**
```rust
// Wallet
let payer = Keypair::from_base58_string("use_your_payer_keypair_here");
@@ -116,27 +118,29 @@ let swqos_configs: Vec<SwqosConfig> = vec![
SwqosConfig::Default(rpc_url.clone()),
SwqosConfig::Jito("your uuid".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Bloxroute("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::ZeroSlot("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Temporal("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::FlashBlock("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Node1("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::BlockRazor("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Astralane("your api_token".to_string(), SwqosRegion::Frankfurt, None),
];
// Create TradeConfig instance
let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment);
// Optional: Customize WSOL ATA and Seed optimization settings
// let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment)
// .with_wsol_ata_config(
// true, // create_wsol_ata_on_startup: Check and create WSOL ATA on startup (default: true)
// true // use_seed_optimize: Enable seed optimization globally for all ATA operations (default: true)
// );
// Create TradingClient
let client = TradingClient::new(Arc::new(payer), trade_config).await;
```
**Method 2: Shared infrastructure (multiple wallets)**
For multi-wallet scenarios, create the infrastructure once and share it across wallets.
See [Example: Shared Infrastructure](examples/shared_infrastructure/src/main.rs).
```rust
// Create infrastructure once (expensive)
let infra_config = InfrastructureConfig::new(rpc_url, swqos_configs, commitment);
let infrastructure = Arc::new(TradingInfrastructure::new(infra_config).await);
// Create multiple clients sharing the same infrastructure (fast)
let client1 = TradingClient::from_infrastructure(Arc::new(payer1), infrastructure.clone(), true);
let client2 = TradingClient::from_infrastructure(Arc::new(payer2), infrastructure.clone(), true);
```
#### 2. Configure Gas Fee Strategy
For detailed information about Gas Fee Strategy, see the [Gas Fee Strategy Reference](docs/GAS_FEE_STRATEGY.md).
@@ -197,6 +201,7 @@ Please ensure that the parameters your trading logic depends on are available in
| Description | Run Command | Source Code |
|-------------|-------------|-------------|
| Create and configure TradingClient instance | `cargo run --package trading_client` | [examples/trading_client](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/trading_client/src/main.rs) |
| Share infrastructure across multiple wallets | `cargo run --package shared_infrastructure` | [examples/shared_infrastructure](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/shared_infrastructure/src/main.rs) |
| PumpFun token sniping trading | `cargo run --package pumpfun_sniper_trading` | [examples/pumpfun_sniper_trading](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/pumpfun_sniper_trading/src/main.rs) |
| PumpFun token copy trading | `cargo run --package pumpfun_copy_trading` | [examples/pumpfun_copy_trading](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/pumpfun_copy_trading/src/main.rs) |
| PumpSwap trading operations | `cargo run --package pumpswap_trading` | [examples/pumpswap_trading](https://github.com/0xfnzero/sol-trade-sdk/tree/main/examples/pumpswap_trading/src/main.rs) |
+10
View File
@@ -0,0 +1,10 @@
[package]
name = "shared_infrastructure"
version = "0.1.0"
edition = "2021"
[dependencies]
sol-trade-sdk = { path = "../.." }
solana-sdk = "3.0.0"
solana-commitment-config = { version = "3.0.0", features = ["serde"] }
tokio = { version = "1", features = ["full"] }
@@ -0,0 +1,72 @@
//! Shared Infrastructure Example
//!
//! This example demonstrates how to share expensive infrastructure (RPC client, SWQOS clients)
//! across multiple wallets, significantly reducing resource usage and initialization time.
//!
//! Use this pattern when:
//! - Running a trading service with multiple wallets
//! - All wallets use the same RPC endpoint and SWQOS configuration
//! - You want to minimize memory usage and connection overhead
//!
//! Benefits:
//! - First wallet: Full async initialization (~200-500ms)
//! - Additional wallets: Fast sync initialization (~1-2ms)
//! - Shared RPC connection pool and SWQOS clients
use sol_trade_sdk::{
common::InfrastructureConfig,
swqos::{SwqosConfig, SwqosRegion},
TradingClient, TradingInfrastructure,
};
use solana_commitment_config::CommitmentConfig;
use solana_sdk::signature::Keypair;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Configuration (same for all wallets)
let rpc_url = "https://mainnet.helius-rpc.com/?api-key=xxxxxx".to_string();
let commitment = CommitmentConfig::processed();
let swqos_configs: Vec<SwqosConfig> = vec![
SwqosConfig::Default(rpc_url.clone()),
SwqosConfig::Jito("your_uuid".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Bloxroute("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
];
// Step 1: Create shared infrastructure (expensive, do once)
println!("Creating shared infrastructure...");
let infra_config = InfrastructureConfig::new(rpc_url, swqos_configs, commitment);
let infrastructure = Arc::new(TradingInfrastructure::new(infra_config).await);
println!("Infrastructure created with {} SWQOS clients", infrastructure.swqos_clients.len());
// Step 2: Create multiple TradingClients sharing the same infrastructure (fast)
let wallet_keys = vec![
"wallet1_base58_private_key_here",
"wallet2_base58_private_key_here",
"wallet3_base58_private_key_here",
];
let mut clients = Vec::new();
for (i, key) in wallet_keys.iter().enumerate() {
println!("Creating client for wallet {}...", i + 1);
let payer = Arc::new(Keypair::from_base58_string(key));
// Fast: reuses existing infrastructure
let client = TradingClient::from_infrastructure(
payer,
infrastructure.clone(),
true, // use_seed_optimize
);
clients.push(client);
println!(" Client {} created (shares infrastructure)", i + 1);
}
println!("\nCreated {} clients sharing 1 infrastructure instance", clients.len());
println!(" - 1 RPC client (shared)");
println!(" - {} SWQOS clients (shared)", infrastructure.swqos_clients.len());
// All clients can now trade concurrently using shared resources
// Example: clients[0].buy(buy_params).await?;
Ok(())
}
+73 -21
View File
@@ -1,7 +1,16 @@
//! TradingClient Creation Example
//!
//! This example demonstrates two ways to create a TradingClient:
//!
//! 1. Simple method: `TradingClient::new()` - creates client with its own infrastructure
//! 2. Shared method: `TradingClient::from_infrastructure()` - reuses existing infrastructure
//!
//! For multi-wallet scenarios, see the `shared_infrastructure` example.
use sol_trade_sdk::{
common::{AnyResult, TradeConfig},
common::{AnyResult, InfrastructureConfig, TradeConfig},
swqos::{SwqosConfig, SwqosRegion},
SolanaTrade,
TradingClient, TradingInfrastructure,
};
use solana_commitment_config::CommitmentConfig;
use solana_sdk::signature::Keypair;
@@ -9,32 +18,75 @@ use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let _ = create_solana_trade_client().await?;
println!("Successfully created SolanaTrade client!");
// Method 1: Simple - TradingClient::new() (recommended for single wallet)
let client = create_trading_client_simple().await?;
println!("Method 1: Created TradingClient with new()");
println!(" Wallet: {}", client.get_payer_pubkey());
// Method 2: From infrastructure (recommended for multiple wallets)
let client2 = create_trading_client_from_infrastructure().await?;
println!("\nMethod 2: Created TradingClient with from_infrastructure()");
println!(" Wallet: {}", client2.get_payer_pubkey());
Ok(())
}
/// Create SolanaTrade client
/// Initializes a new SolanaTrade client with configuration
async fn create_solana_trade_client() -> AnyResult<SolanaTrade> {
println!("Creating SolanaTrade client...");
/// Method 1: Create TradingClient using TradeConfig (simple, self-contained)
///
/// Use this when you have a single wallet or don't need to share infrastructure.
async fn create_trading_client_simple() -> AnyResult<TradingClient> {
let payer = Keypair::from_base58_string("use_your_payer_keypair_here");
let rpc_url = "https://mainnet.helius-rpc.com/?api-key=xxxxxx".to_string();
println!("rpc_url: {}", rpc_url);
let commitment = CommitmentConfig::processed();
let swqos_configs: Vec<SwqosConfig> = vec![
SwqosConfig::Default(rpc_url.clone()),
SwqosConfig::Jito("your uuid".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Bloxroute("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::ZeroSlot("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Temporal("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::FlashBlock("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Node1("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::BlockRazor("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Astralane("your api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Jito("your_uuid".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Bloxroute("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::ZeroSlot("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Temporal("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::FlashBlock("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Node1("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::BlockRazor("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
SwqosConfig::Astralane("your_api_token".to_string(), SwqosRegion::Frankfurt, None),
];
let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment);
let solana_trade_client = SolanaTrade::new(Arc::new(payer), trade_config).await;
println!("SolanaTrade client created successfully!");
Ok(solana_trade_client)
// Optional: Customize WSOL ATA and Seed optimization settings
let trade_config = TradeConfig::new(rpc_url, swqos_configs, commitment)
.with_wsol_ata_config(
true, // create_wsol_ata_on_startup: Check and create WSOL ATA on startup
true, // use_seed_optimize: Enable seed optimization for all ATA operations
);
// Creates new infrastructure internally
let client = TradingClient::new(Arc::new(payer), trade_config).await;
Ok(client)
}
/// Method 2: Create TradingClient from shared infrastructure
///
/// Use this when you have multiple wallets sharing the same configuration.
/// The infrastructure (RPC client, SWQOS clients) is created once and shared.
async fn create_trading_client_from_infrastructure() -> AnyResult<TradingClient> {
let payer = Keypair::from_base58_string("use_your_payer_keypair_here");
let rpc_url = "https://mainnet.helius-rpc.com/?api-key=xxxxxx".to_string();
let commitment = CommitmentConfig::processed();
let swqos_configs: Vec<SwqosConfig> = vec![
SwqosConfig::Default(rpc_url.clone()),
SwqosConfig::Jito("your_uuid".to_string(), SwqosRegion::Frankfurt, None),
];
// Create infrastructure separately (can be shared across multiple wallets)
let infra_config = InfrastructureConfig::new(rpc_url, swqos_configs, commitment);
let infrastructure = Arc::new(TradingInfrastructure::new(infra_config).await);
// Create client from existing infrastructure (fast, no async needed)
let client = TradingClient::from_infrastructure(
Arc::new(payer),
infrastructure,
true, // use_seed_optimize
);
Ok(client)
}