Solana Yellowstone gRPC enables real-time streaming of transactions, accounts, slots, and blocks without polling.
Solana Yellowstone gRPC establishes a persistent stream and pushes data to your application as events occur on-chain. It is a strong fit for systems that need fresh Solana data immediately, such as trading infrastructure, indexers, real-time analytics, wallets, and monitoring services.
With Tatum’s Yellowstone gRPC endpoint, you can retrieve:
- Account updates
- Transactions
- Slots
- Blocks
- Block metadata
- And more
Solana Mainnet gRPC endpoint
Yellowstone gRPC (Mainnet)
For JSON-RPC, Devnet, and the full network list, see Solana RPC.
Test Solana in Postman
Use the collections below to try gRPC streaming against Tatum’s Solana gateway.
Solana Mainnet gRPC Postman collection
- Get your API key: Same Tatum API key as REST/JSON-RPC; gRPC uses the
x-tokenheader (see Authentication below) - Import the collection: Open Postman using the button below
- Configure variables: Set host and API key per the collection’s instructions
- Start testing: Call Yellowstone-style methods (for example
GetVersion) and subscriptions as provided in the collection
Endpoint validation toolkit
If you need to verify behavior across reconnects, keepalive, resubscribe, and concurrency scenarios, use the open-source test suite:
Getting Started
Set Up Your Environment
This guide uses Node.js with TypeScript and the official Yellowstone gRPC client on macOS. Before writing code, install Node.js and (optionally) grpcurl for endpoint smoke testing.
-
Install
Node.js(version 18+)brew install node node -v -
Install
grpcurl(optional)grpcurlhelps verify your endpoint and API key before you run app code.brew install grpcurl -
Create your project and install dependencies:
mkdir tatum-grpc-test cd tatum-grpc-test npm init -y npm install @triton-one/yellowstone-grpc npm install -D tsx typescript @types/nodeNoteUse tsx instead of ts-node to run TypeScript files directly. It's faster and requires no additional tsconfig.json setup.
-
Download the Yellowstone proto files (required for
grpcurlsmoke tests):curl -o geyser.proto https://raw.githubusercontent.com/rpcpool/yellowstone-grpc/master/yellowstone-grpc-proto/proto/geyser.proto curl -o solana-storage.proto https://raw.githubusercontent.com/rpcpool/yellowstone-grpc/master/yellowstone-grpc-proto/proto/solana-storage.proto # Your project folder should now look like this: tatum-grpc-test/ ├── geyser.proto ├── solana-storage.proto ├── node_modules/ ├── package.json └── get-block.ts // ← your script goes here -
Verify your connection with
grpcurlbefore writing app code.- Tatum-specific: The gRPC endpoint is
solana-mainnet-grpc.gateway.tatum.io:443(Mainnet). - Authentication uses the
x-tokenheader. This is your Tatum API key (x-api-key) sent under Yellowstone's expected header name.
grpcurl \ -proto geyser.proto \ -import-path . \ -H "x-token: YOUR_API_KEY" \ solana-mainnet-grpc.gateway.tatum.io:443 \ geyser.Geyser/GetVersionExpected response format:
{ "version": "{\"version\":{\"package\":\"yellowstone-grpc-geyser\",\"version\":\"12.1.0+solana.3.1.10\",\"proto\":\"12.1.0+solana.3.1.10\",\"solana\":\"3.1.10\",\"git\":\"f0ae884\",\"rustc\":\"1.86.0\",\"buildts\":\"2026-03-12T09:16:09.772120954Z\"},\"extra\":{\"hostname\":\"relevant-marten\"}}" }Attention- If you see a version response, your endpoint and API key are working.
- If this step fails, no amount of Node.js code will fix it. Confirm your environment setup and credentials
- Tatum-specific: The gRPC endpoint is
Quick start checklist
Before opening a stream, confirm:
- You can call
GetVersionsuccessfully withgrpcurl - Your API key has access to the endpoint
- Your service can keep long-lived outbound connections
- You have a reconnect strategy for network interruptions
- You selected the correct network endpoint for your environment (Mainnet vs Devnet JSON-RPC)
Authentication in Yellowstone gRPC client
- Get the Solana gRPC URL.
- Create an API Key in your Tatum Dashboard.
- Configure your client with the endpoint and token:
import Client, {
CommitmentLevel,
} from "@triton-one/yellowstone-grpc";
const ENDPOINT = "https://solana-mainnet-grpc.gateway.tatum.io";
const X_TOKEN = "YOUR_API_KEY";Example Requests
AttentionThese are minimal examples. For production systems, implement reconnection handling, checkpointing, and idempotent downstream processing.
End-to-end stream example (transactions)
The following script opens a stream and subscribes to all finalized, non-vote, non-failed transactions.
import Client, {
CommitmentLevel,
SubscribeRequest,
} from "@triton-one/yellowstone-grpc";
const ENDPOINT = "https://solana-mainnet-grpc.gateway.tatum.io";
const X_TOKEN = "YOUR_API_KEY";
async function main() {
const client = new Client(ENDPOINT, X_TOKEN);
const stream = await client.subscribe();
stream.on("data", (message) => {
if (message.transaction) {
const slot = message.transaction.slot;
const signature = Buffer.from(
message.transaction.transaction.signature,
).toString("base64");
console.log(`tx received: slot=${slot} signature=${signature}`);
}
});
stream.on("error", (error) => {
console.error("stream error:", error);
});
stream.on("end", () => {
console.log("stream closed");
});
const request: SubscribeRequest = {
slots: {},
accounts: {},
transactions: {
alltxs: {
vote: false,
failed: false,
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.FINALIZED,
entry: {},
transactionsStatus: {},
};
stream.write(request);
console.log("subscription started");
}
main().catch((error) => {
console.error(error);
process.exit(1);
});Run it with:
npx tsx get-transactions.tsTroubleshooting
If streaming does not start, check:
- Auth failures: ensure
x-tokencontains a valid Tatum API key - Wrong interface/network: verify you are using Mainnet gRPC endpoint (not Devnet JSON-RPC endpoint)
- No data received: verify your subscription filter is broad enough
- Frequent disconnects: add retries with exponential backoff and jitter
- Consumer overload: add buffering/queueing and process messages asynchronously
Retrieve an account
import { CommitmentLevel } from "@triton-one/yellowstone-grpc";
const request = {
"slots": {
"slots": {}
},
"accounts": {
"wsol/usdc": {
"account": ["8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6"]
}
},
"transactions": {},
"blocks": {},
"blocksMeta": {},
"accountsDataSlice": [],
"commitment": CommitmentLevel.CONFIRMED,
"entry": {},
"transactionsStatus": {}
};Use this request when you need account-level state changes for a known address.
Retrieve all finalized non-vote and non-failed transactions
import { CommitmentLevel } from "@triton-one/yellowstone-grpc";
const request = {
"slots": {
"slots": {}
},
"accounts": {},
"transactions": {
"alltxs": {
"vote": false,
"failed": false
}
},
"blocks": {},
"blocksMeta": {},
"accountsDataSlice": [],
"commitment": CommitmentLevel.FINALIZED,
"entry": {},
"transactionsStatus": {}
};Use this request to monitor finalized transaction flow while excluding vote and failed transactions.
Retrieve slots
const request = {
"slots": {
"incoming_slots": {}
},
"accounts": {},
"transactions": {},
"blocks": {},
"blocksMeta": {},
"accountsDataSlice": [],
"entry": {},
"transactionsStatus": {}
};Use this request for slot-level progression and liveness monitoring.
Retrieve blocks
const request = {
"slots": {},
"accounts": {},
"transactions": {},
"blocks": {
"blocks": {}
},
"blocksMeta": {},
"accountsDataSlice": [],
"entry": {},
"transactionsStatus": {}
};Use this request for block-by-block ingestion pipelines.
Retrieve block metadata
const request = {
"slots": {},
"accounts": {},
"transactions": {},
"blocks": {},
"blocksMeta": {
"blockmetadata": {}
},
"accountsDataSlice": [],
"entry": {},
"transactionsStatus": {}
};Use this request when you only need block headers and metadata, not full block payloads.