Guide: Subscribing to the Latest Solana Blocks for Automated Trading in Rust
Simple Rust Solana Block Subscription Example
The Solana blockchain averages a block time less than 0.5 seconds and one of the best methods for processing Solana blocks as they are produced via a subscription method such as the blockSubscribe web socket method. While hosting a Solana RPC node may be expensive due to the high hardware requirements, RPC providers such as Quicknode allow for quick and reliable access to the block subscription method.
Rust Environment Configuration
Rust Installation
Rust is easy to install and configure with the following in most environments. Rust is the preferred language for this example due to its rapid processing capabilities and memory-safe features.
Create Rust Environment
Initialize the Rust configuration
cargo init solana-subscription-example
cd solana-subscription-example
Install Rust Dependencies
The Rust dependencies for the project will be controlled by the Cargo.toml
. Add the following dependencies:
[dependencies]
solana-client = "1.18.12"
solana-sdk = "1.18.12"
solana-transaction-status = "1.18.12"
tokio = "1.37.0"
Solana Block Subscription Method
The source file for Rust projects will default in the main.rs
located at ./src/main.rs
.
Import Dependencies
At the top of the file, we’ll include imports of the dependencies that we previously added in the Cargo.toml
.
use solana_client::{
pubsub_client::PubsubClient,
rpc_config::{RpcBlockSubscribeConfig, RpcBlockSubscribeFilter},
};
use solana_transaction_status::{TransactionDetails, UiTransactionEncoding};
use solana_sdk::{commitment_config::CommitmentConfig};
RPC Endpoint
Depending on the RPC endpoint, the URL will be added as a const &str
to be referenced. Quicknode allows for cheap and easy solutions to get your project started.
const SOLANA_RPC_URL_WS: &'static str = "wss://<RPC Endpoint>";
Default Main Function
The main()
function will be called when we compile and run the Rust project. A main function with a generalized subscription loop with the Tokio
decorator as follows:
#[tokio::main]
async fn main() {
println!("Solana Subscription Example!");
// obtain full transactions for confirmed blocks
let config = RpcBlockSubscribeConfig {
commitment: Some(CommitmentConfig::confirmed()),
encoding: Some(UiTransactionEncoding::Base64),
transaction_details: Some(TransactionDetails::Full),
show_rewards: Some(false),
max_supported_transaction_version: Some(0),
..Default::default()
};
// create the subscription with the defined configuration
let (_tx_confirmed_block, rx_confirmed_block) = PubsubClient::block_subscribe(&SOLANA_RPC_URL_WS, RpcBlockSubscribeFilter::All, Some(config)).unwrap();
// loop through the subscription responses and print the block slot
loop {
match rx_confirmed_block.recv() {
Ok(response) => {
println!("{}", response.value.slot.to_string());
}
Err(e) => {
println!("Block Subscription Error: {:?}", e);
break;
}
}
}
}
he subscription settings are specified in the RpcBlockSubscribeConfig
struct, which uses a block commitment configuration for Confirmed blocks that includes complete transaction details. Depending on how you plan to use the subscription method, the configuration can vary; however, the provided example covers all necessary details for creating a trading or arbitrage bot on Solana.
The loop consistently monitors for the arrival of a confirmed block and uses pattern matching to assess the validity of the response. Although the given example merely outputs the block's slot number, it can be adapted to perform a variety of tasks.
The project may be built and run as follows:
cargo run --release
Resulting in the println
macro printing to the terminal:
>> cargo run --release
Compiling solana-subscription-example v0.1.0
Finished `release` profile [optimized] target(s) in 0.63s
Running `target/release/solana-subscription-example`
Solana Subscription Example!
263591942
263591943
263591944
263591945
263591946
263591947
The blocks are received and processed as soon as the RPC returns the block data via the subscription method!
Conclusion
Implementing the block subscription method in Rust is straightforward and can be customized for diverse applications, such as trading or arbitrage bots on Solana. By utilizing block data complete with detailed transaction information, users can effectively track blockchain activities and gain the upper hand in trading. This approach not only demonstrates the practical use of blockchain data in real-world scenarios but also offers a solid base for developers to expand and tailor to their specific requirements.
Happy programming!