Yellowstone gRPC Overview
cubestech provides access to the Yellowstone Dragon's Mouth gRPC interface - a high-performance streaming API built on Solana's Geyser plugin architecture.
Yellowstone gRPC enables real-time streaming of accounts, transactions, slots, blocks, and entries with advanced filtering, significantly outperforming traditional WebSocket and polling-based approaches.
Endpoint
geyser.sol.cubestech.online:443:443Authenticate with the x-api-key header on every request.
Key Advantages
- Low latency - direct Geyser plugin access, data arrives before RPC processing
- Rich filtering - filter by account, owner, program, transaction participants, and more
- Bidirectional streaming - update subscription filters without reconnecting
- Typed data - Protocol Buffers provide strict typing and efficient serialization
Service Definition
The Geyser service exposes two bidirectional streaming RPCs and several unary methods:
service Geyser {
// Bidirectional streaming subscriptions
rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate) {}
rpc SubscribeDeshred(stream SubscribeDeshredRequest) returns (stream SubscribeUpdateDeshred) {}
// Unary methods
rpc SubscribeReplayInfo(SubscribeReplayInfoRequest) returns (SubscribeReplayInfoResponse) {}
rpc Ping(PingRequest) returns (PongResponse) {}
rpc GetLatestBlockhash(GetLatestBlockhashRequest) returns (GetLatestBlockhashResponse) {}
rpc GetBlockHeight(GetBlockHeightRequest) returns (GetBlockHeightResponse) {}
rpc GetSlot(GetSlotRequest) returns (GetSlotResponse) {}
rpc IsBlockhashValid(IsBlockhashValidRequest) returns (IsBlockhashValidResponse) {}
rpc GetVersion(GetVersionRequest) returns (GetVersionResponse) {}
}Commitment Levels
enum CommitmentLevel {
PROCESSED = 0;
CONFIRMED = 1;
FINALIZED = 2;
}| Level | Value | Description |
|---|---|---|
PROCESSED | 0 | Processed by the connected node (fastest, may be reverted) |
CONFIRMED | 1 | Confirmed by supermajority vote |
FINALIZED | 2 | Finalized by supermajority (most reliable) |
Connection Keep-Alive
Some load balancers terminate gRPC connections if the client is idle. The server sends Ping messages every 15 seconds - reply with a SubscribeRequest containing a ping message with an id field (any int32 value) to keep the connection alive.
Subscribe
The Subscribe RPC is a bidirectional stream. The client sends SubscribeRequest messages to set or update filters, and the server responds with a continuous stream of SubscribeUpdate messages.
rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeUpdate) {}SubscribeRequest
map<string, SubscribeRequestFilterAccounts>Named account subscription filters. See Account Filters.
map<string, SubscribeRequestFilterSlots>Named slot subscription filters. See Slot Filters.
map<string, SubscribeRequestFilterTransactions>Named transaction subscription filters. See Transaction Filters.
map<string, SubscribeRequestFilterTransactions>Same filters as transactions, but only returns status (no full transaction data).
map<string, SubscribeRequestFilterBlocks>Named block subscription filters. See Block Filters.
map<string, SubscribeRequestFilterBlocksMeta>Block metadata filters. See Block Metadata Filters.
map<string, SubscribeRequestFilterEntry>Entry subscription filters. See Entry Filters.
CommitmentLevelCommitment level: PROCESSED (0), CONFIRMED (1), FINALIZED (2).
arrayArray of { offset: uint64, length: uint64 } objects to receive only specific slices of account data.
SubscribeRequestPingSend a ping to keep the connection alive. Contains a single field: id (int32) - set to any integer value. The server responds with a Pong echoing the same id.
uint64Start streaming from this slot (replay support).
SubscribeUpdate
Each update contains the matched filter names and exactly one update type:
filtersarrayNames of the filters that matched this update.
update_oneofoneofUpdate types
accountSubscribeUpdateAccountslotSubscribeUpdateSlottransactionSubscribeUpdateTransactiontransaction_statusSubscribeUpdateTransactionStatusblockSubscribeUpdateBlockblock_metaSubscribeUpdateBlockMetaentrySubscribeUpdateEntrypingSubscribeUpdatePingpongSubscribeUpdatePongcreated_atTimestampServer-side timestamp when the update was created.
Example: Subscribe to All Slots
import Client, { CommitmentLevel } from "@triton-one/yellowstone-grpc";
// The SDK sends its token argument through x-token metadata
const client = new Client("geyser.sol.cubestech.online:443:443", "YOUR_API_KEY", {
grpcMaxDecodingMessageSize: 64 * 1024 * 1024,
});
await client.connect();
const stream = await client.subscribe();
stream.on("data", (data) => {
if (data.slot) {
console.log(`Slot: ${data.slot.slot}, Status: ${data.slot.status}`);
}
});
// Send subscription request
const request = {
slots: {
mySlots: { filterByCommitment: true },
},
commitment: CommitmentLevel.CONFIRMED,
accounts: {},
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
};
stream.write(request);import grpc
import geyser_pb2
import geyser_pb2_grpc
# Auth plugin - sends x-api-key as gRPC metadata
class KeyAuth(grpc.AuthMetadataPlugin):
def __init__(self, api_key):
self.api_key = api_key
def __call__(self, context, callback):
callback([("x-api-key", self.api_key)], None)
ssl_creds = grpc.ssl_channel_credentials()
call_creds = grpc.metadata_call_credentials(KeyAuth("YOUR_API_KEY"))
combined_creds = grpc.composite_channel_credentials(ssl_creds, call_creds)
channel = grpc.secure_channel("geyser.sol.cubestech.online:443:443", credentials=combined_creds)
stub = geyser_pb2_grpc.GeyserStub(channel)
# Create subscription request
request = geyser_pb2.SubscribeRequest(
slots={"mySlots": geyser_pb2.SubscribeRequestFilterSlots(
filter_by_commitment=True
)},
commitment=geyser_pb2.CONFIRMED,
)
# Subscribe and process updates
for update in stub.Subscribe(iter([request])):
if update.HasField("slot"):
print(f"Slot: {update.slot.slot}, Status: {update.slot.status}")Updating Filters
Since Subscribe is bidirectional, you can send a new SubscribeRequest at any time to update your filters without reconnecting:
// Initial subscription for slots
stream.write({
slots: { mySlots: {} },
accounts: {},
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
commitment: CommitmentLevel.CONFIRMED,
});
// Later: add account subscription without reconnecting
stream.write({
slots: { mySlots: {} },
accounts: {
myAccounts: {
account: ["vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36NKPTg"],
},
},
transactions: {},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
commitment: CommitmentLevel.CONFIRMED,
});Each new SubscribeRequest completely replaces the previous filters. Include all desired filters in every request.