| Crates.io | orca_tx_sender |
| lib.rs | orca_tx_sender |
| version | 2.1.0 |
| created_at | 2025-03-28 20:05:46.629041+00 |
| updated_at | 2025-08-11 16:40:24.688956+00 |
| description | Solana Transaction Sender for building and sending transactions with priority fees |
| homepage | https://orca.so |
| repository | https://github.com/orca-so/whirlpools |
| max_upload_size | |
| id | 1610216 |
| size | 184,179 |
A Rust crate for building and sending Solana transactions with priority fees and Jito tips.
Add the following to your Cargo.toml:
[dependencies]
orca_tx_sender = { version = "0.1.0" }
Below is an example of how to use the per-function configuration for build_and_send_transaction_with_config. However, you can also use the per-function configuration for the build and send steps separately using the following functions: build_transaction_with_config and send_transaction_with_config.
use orca_tx_sender::{
build_and_send_transaction_with_config,
PriorityFeeStrategy, Percentile,
set_priority_fee_strategy
};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signer};
use solana_sdk::system_instruction;
use solana_sdk::commitment_config::CommitmentLevel;
use std::error::Error;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let rpc_client = RpcClient::new("https://api.mainnet-beta.solana.com");
// Use the cluster URL to create a new instance of RpcConfig. You can also create the struct manually.
let rpc_config = RpcConfig::new(rpc_client.url());
// Configure the fee config with priority fees
let fee_config = FeeConfig {
priority_fee_strategy: PriorityFeeStrategy::Dynamic {
percentile: Percentile::P95,
max_lamports: 10_000,
},
..Default::default()
};
// Create a keypair for signing
let payer = Keypair::new();
println!("Using keypair: {}", payer.pubkey());
// Check balance
let balance = client.get_balance(&payer.pubkey()).await?;
println!("Account balance: {} lamports", balance);
// Jupiter Program address as an example recipient
let recipient = Pubkey::from_str("JUP2jxvXaqu7NQY1GmNF4m1vodw12LVXYxbFL2uJvfo").unwrap();
// Create transfer instruction
let transfer_ix = system_instruction::transfer(
&payer.pubkey(),
&recipient,
1_000_000, // 0.001 SOL
);
// Build and send transaction
println!("Sending transaction...");
let signature = build_and_send_transaction_with_config(
vec![transfer_ix],
&[&payer],
Some(CommitmentLevel::Confirmed),
None, // No address lookup tables
&rpc_client,
&rpc_config,
&fee_config,
).await?;
println!("Transaction sent: {}", signature);
Ok(())
}
use orca_tx_sender::{
build_and_send_transaction,
PriorityFeeStrategy, Percentile,
set_priority_fee_strategy, set_rpc, get_rpc_client
};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signer};
use solana_sdk::system_instruction;
use solana_sdk::commitment_config::CommitmentLevel;
use std::error::Error;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Initialize RPC configuration (required!)
set_rpc("https://api.mainnet-beta.solana.com").await?;
// Check connection
let client = get_rpc_client()?;
println!("Connected to Solana");
// Configure priority fees
set_priority_fee_strategy(PriorityFeeStrategy::Dynamic {
percentile: Percentile::P95,
max_lamports: 10_000,
})?;
// Create a keypair for signing
let payer = Keypair::new();
println!("Using keypair: {}", payer.pubkey());
// Check balance
let balance = client.get_balance(&payer.pubkey()).await?;
println!("Account balance: {} lamports", balance);
// Jupiter Program address as an example recipient
let recipient = Pubkey::from_str("JUP2jxvXaqu7NQY1GmNF4m1vodw12LVXYxbFL2uJvfo").unwrap();
// Create transfer instruction
let transfer_ix = system_instruction::transfer(
&payer.pubkey(),
&recipient,
1_000_000, // 0.001 SOL
);
// Build and send transaction
println!("Sending transaction...");
let signature = build_and_send_transaction(
vec![transfer_ix],
&[&payer],
Some(CommitmentLevel::Confirmed),
None, // No address lookup tables
).await?;
println!("Transaction sent: {}", signature);
Ok(())
}
use orca_tx_sender::{
build_and_send_transaction,
JitoFeeStrategy, Percentile, JitoPercentile, PriorityFeeStrategy, SendOptions,
set_priority_fee_strategy, set_jito_fee_strategy, set_compute_unit_margin_multiplier,
set_jito_block_engine_url, set_rpc, get_rpc_client
};
use solana_sdk::pubkey::Pubkey;
use solana_sdk::signature::{Keypair, Signer};
use solana_sdk::system_instruction;
use solana_sdk::commitment_config::CommitmentLevel;
use std::error::Error;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// Initialize RPC configuration (required!)
set_rpc("https://api.mainnet-beta.solana.com").await?;
// Check connection
let client = get_rpc_client()?;
println!("Connected to Solana");
// Configure fee settings with dynamic priority fees and Jito fees
let compute_multiplier = 1.1;
let jito_url = "https://bundles.jito.wtf".to_string();
// Set individual configuration options
set_priority_fee_strategy(PriorityFeeStrategy::Dynamic {
percentile: Percentile::P95,
max_lamports: 10_000,
})?;
set_jito_fee_strategy(JitoFeeStrategy::Dynamic {
percentile: JitoPercentile::P95,
max_lamports: 10_000,
})?;
set_compute_unit_margin_multiplier(compute_multiplier)?;
set_jito_block_engine_url(jito_url.clone())?;
// Create a keypair for signing
let payer = Keypair::new();
println!("Using keypair: {}", payer.pubkey());
// Check balance
let balance = client.get_balance(&payer.pubkey()).await?;
println!("Account balance: {} lamports", balance);
// Jupiter Program address as an example recipient
let recipient = Pubkey::from_str("JUP2jxvXaqu7NQY1GmNF4m1vodw12LVXYxbFL2uJvfo").unwrap();
// Create transfer instruction
let transfer_ix = system_instruction::transfer(
&payer.pubkey(),
&recipient,
1_000_000, // 0.001 SOL
);
// Build and send transaction
println!("Sending transaction with priority fees and Jito fees...");
let signature = build_and_send_transaction(
vec![transfer_ix],
&[&payer],
Some(CommitmentLevel::Confirmed),
None, // No address lookup tables
).await?;
println!("Transaction sent: {}", signature);
Ok(())
}
// Must be explicitly set before sending transactions
set_rpc("https://api.mainnet-beta.solana.com").await?;
// Dynamic priority fees based on network conditions
set_priority_fee_strategy(PriorityFeeStrategy::Dynamic {
percentile: Percentile::P95,
max_lamports: 1_000_000, // 1 SOL
})?;
// Fixed priority fee
// set_priority_fee_strategy(PriorityFeeStrategy::Exact(10_000))?;
// No priority fee
// set_priority_fee_strategy(PriorityFeeStrategy::Disabled)?;
// Configure Jito tips
set_jito_fee_strategy(JitoFeeStrategy::Dynamic {
percentile: JitoPercentile::P50,
max_lamports: 500_000, // 0.5 SOL
})?;
// Set compute unit margin multiplier (default: 1.1)
set_compute_unit_margin_multiplier(1.2)?;
Transaction options can be provided directly when sending:
// Use with global configuration
let signature = build_and_send_transaction(
instructions,
signers,
Some(CommitmentLevel::Confirmed),
None, // No address lookup tables
).await?;
// With address lookup tables for account compression
let signature = build_and_send_transaction(
instructions,
signers,
Some(CommitmentLevel::Processed),
Some(address_lookup_tables), // With ALTs
).await?;
// Use default commitment level by passing None
let signature = build_and_send_transaction(
instructions,
signers,
None,
None,
).await?;
All testing and example code is located in the examples directory. You can run the examples directly:
# Priority fees only (no Jito fees)
cargo run --example priority_only_test "https://api.devnet.solana.com"
# With Jito fees
cargo run --example with_jito_test "https://api.mainnet-beta.solana.com"
# With address lookup tables
cargo run --example with_lookup_tables "https://api.mainnet-beta.solana.com"
You can provide any custom RPC URL as a command-line argument. If no URL is provided, the examples will default to using the Solana devnet URL.
Orca License
See LICENSE for details.