Skip to main content

Overview

Yellowstone gRPC provides several unary (request-response) methods for querying current blockchain state without establishing a streaming connection. These methods are useful for one-time queries or health checks.

Ping

Test server connectivity and measure round-trip latency.
rpc Ping(PingRequest) returns (PongResponse) {}

Request

count
int32
An arbitrary integer that will be echoed back in the response. Useful for matching requests to responses.

Response

count
int32
The same count value from the request.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let response = client.ping(42).await?;
    println!("Pong: count={}", response.count);

    Ok(())
}

GetLatestBlockhash

Retrieve the latest blockhash and the last valid block height for transaction construction.
rpc GetLatestBlockhash(GetLatestBlockhashRequest) returns (GetLatestBlockhashResponse) {}

Request

commitment
CommitmentLevel
Commitment level: PROCESSED (0), CONFIRMED (1), or FINALIZED (2). If not specified, defaults to FINALIZED.

Response

slot
uint64
Slot number where this blockhash was observed.
blockhash
string
The latest blockhash (base58 encoded).
last_valid_block_height
uint64
The last block height at which this blockhash will be valid for transaction inclusion.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::CommitmentLevel;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let response = client
        .get_latest_blockhash(Some(CommitmentLevel::Finalized))
        .await?;
    
    println!("Slot: {}", response.slot);
    println!("Blockhash: {}", response.blockhash);
    println!("Last valid block height: {}", response.last_valid_block_height);

    Ok(())
}

GetBlockHeight

Retrieve the current block height.
rpc GetBlockHeight(GetBlockHeightRequest) returns (GetBlockHeightResponse) {}

Request

commitment
CommitmentLevel
Commitment level: PROCESSED (0), CONFIRMED (1), or FINALIZED (2). If not specified, defaults to FINALIZED.

Response

block_height
uint64
The current block height.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::CommitmentLevel;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let response = client
        .get_block_height(Some(CommitmentLevel::Confirmed))
        .await?;
    
    println!("Block height: {}", response.block_height);

    Ok(())
}

GetSlot

Retrieve the current slot number.
rpc GetSlot(GetSlotRequest) returns (GetSlotResponse) {}

Request

commitment
CommitmentLevel
Commitment level: PROCESSED (0), CONFIRMED (1), or FINALIZED (2). If not specified, defaults to FINALIZED.

Response

slot
uint64
The current slot number.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::CommitmentLevel;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let response = client
        .get_slot(Some(CommitmentLevel::Processed))
        .await?;
    
    println!("Current slot: {}", response.slot);

    Ok(())
}

IsBlockhashValid

Check if a blockhash is still valid for transaction inclusion.
rpc IsBlockhashValid(IsBlockhashValidRequest) returns (IsBlockhashValidResponse) {}

Request

blockhash
string
required
The blockhash to validate (base58 encoded).
commitment
CommitmentLevel
Commitment level: PROCESSED (0), CONFIRMED (1), or FINALIZED (2). If not specified, defaults to FINALIZED.

Response

slot
uint64
The slot at which the validation was performed.
valid
bool
Whether the blockhash is still valid for transaction inclusion.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::CommitmentLevel;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let blockhash = "EkSnNWid2cvwEVnVx9aBqawnmiCNiDgp3gUdkDPTKN1N".to_string();
    let response = client
        .is_blockhash_valid(blockhash, Some(CommitmentLevel::Finalized))
        .await?;
    
    println!("Slot: {}", response.slot);
    println!("Valid: {}", response.valid);

    Ok(())
}

GetVersion

Retrieve the server version information.
rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {}

Request

Empty request (no parameters).

Response

version
string
The server version string.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let response = client.get_version().await?;
    println!("Server version: {}", response.version);

    Ok(())
}

SubscribeReplayInfo

Retrieves replay information from the server, specifically the first available slot that can be replayed. This is useful for clients that want to start streaming from historical data.

Request

request
SubscribeReplayInfoRequest
Empty request message.

Response

first_available
uint64
The first slot number available for replay. If not set, historical replay is not available.

Examples

use yellowstone_grpc_client::GeyserGrpcClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = GeyserGrpcClient::build_from_shared("http://127.0.0.1:10000")?
        .x_token(Some("your-token-here"))?
        .connect()
        .await?;

    let response = client.subscribe_replay_info().await?;
    
    if let Some(first_slot) = response.first_available {
        println!("First available slot for replay: {}", first_slot);
    } else {
        println!("Historical replay not available");
    }

    Ok(())
}

Use Cases

Health Checks

Use Ping and GetVersion to verify server connectivity and compatibility.

Transaction Construction

Use GetLatestBlockhash to get a recent blockhash for building transactions.

Blockchain Progress

Use GetSlot and GetBlockHeight to monitor blockchain progress and sync status.

Transaction Validation

Use IsBlockhashValid to check if a transaction can still be submitted.

Commitment Levels

Most methods accept an optional commitment level parameter:
  • PROCESSED (0): Latest processed slot (may be rolled back)
  • CONFIRMED (1): Slot confirmed by supermajority of the cluster (low rollback risk)
  • FINALIZED (2): Slot finalized by the cluster (no rollback risk)
Choose based on your application’s tolerance for reorgs:
// Use PROCESSED for real-time data (highest risk of rollback)
let slot = client.get_slot(Some(CommitmentLevel::Processed)).await?;

// Use CONFIRMED for most applications (balanced)
let slot = client.get_slot(Some(CommitmentLevel::Confirmed)).await?;

// Use FINALIZED for critical operations (no rollback)
let slot = client.get_slot(Some(CommitmentLevel::Finalized)).await?;

Error Handling

All methods return standard gRPC status codes:
  • OK (0): Request succeeded
  • UNAVAILABLE (14): Server is temporarily unavailable
  • UNAUTHENTICATED (16): Invalid or missing authentication token
  • DEADLINE_EXCEEDED (4): Request timeout
match client.get_slot(Some(CommitmentLevel::Finalized)).await {
    Ok(response) => println!("Slot: {}", response.slot),
    Err(e) => eprintln!("Error: {:?}", e),
}

Best Practices

  • Cache responses: Don’t query every millisecond; cache results for a reasonable duration
  • Handle timeouts: Set appropriate timeouts based on your use case
  • Use appropriate commitment: Choose commitment level based on your tolerance for reorgs
  • Health checks: Implement periodic Ping calls to detect connection issues early
  • Version compatibility: Check GetVersion on startup to ensure compatibility

Build docs developers (and LLMs) love