Yellowstone gRPC is a powerful, production-ready tool for real-time Solana data. But in real-world conditions, network issues or server outages can cause connection drops. Without a reconnect strategy, your app might miss critical updates from the blockchain. A reliable reconnect system ensures your app stays connected and continues receiving live data, even during temporary interruptions.
You can paste this code in Replit to see it in action, or simply run the Repl ↗.
import Client, {
CommitmentLevel,
SubscribeRequestAccountsDataSlice,
SubscribeRequestFilterAccounts,
SubscribeRequestFilterBlocks,
SubscribeRequestFilterBlocksMeta,
SubscribeRequestFilterEntry,
SubscribeRequestFilterSlots,
SubscribeRequestFilterTransactions,
} from "@triton-one/yellowstone-grpc";
import { SubscribeRequestPing } from "@triton-one/yellowstone-grpc/dist/grpc/geyser";
// Interface for the subscription request structure
interface SubscribeRequest {
accounts: { [key: string]: SubscribeRequestFilterAccounts };
slots: { [key: string]: SubscribeRequestFilterSlots };
transactions: { [key: string]: SubscribeRequestFilterTransactions };
transactionsStatus: { [key: string]: SubscribeRequestFilterTransactions };
blocks: { [key: string]: SubscribeRequestFilterBlocks };
blocksMeta: { [key: string]: SubscribeRequestFilterBlocksMeta };
entry: { [key: string]: SubscribeRequestFilterEntry };
commitment?: CommitmentLevel;
accountsDataSlice: SubscribeRequestAccountsDataSlice[];
ping?: SubscribeRequestPing;
}
const ADDRESS_TO_STREAM_FROM = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
async function handleStream(client: Client, args: SubscribeRequest) {
const stream = await client.subscribe();
// Promise that resolves when the stream ends or errors out
const streamClosed = new Promise<void>((resolve, reject) => {
stream.on("error", (error) => {
console.error("Stream error:", error);
reject(error);
stream.end();
});
stream.on("end", resolve);
stream.on("close", resolve);
});
// Handle incoming transaction data
stream.on("data", (data) => {
if (data?.transaction) {
console.log("Received Transaction:");
console.log(data?.transaction);
}
});
// Send the subscription request
await new Promise<void>((resolve, reject) => {
stream.write(args, (err: any) => {
err ? reject(err) : resolve();
});
}).catch((err) => {
console.error("Failed to send subscription request:", err);
throw err;
});
// Wait for the stream to close
await streamClosed;
}
/**
* The reconnection mechanism is implemented on the handle stream function
* If any error occurs, the stream will wait for 1000ms and call
* the handleStream function, which in-turn will restart the stream
*/
async function subscribeCommand(client: Client, args: SubscribeRequest) {
while (true) {
try {
await handleStream(client, args);
} catch (error) {
console.error("Stream error, retrying in 1 second...", error);
await new Promise((resolve) => setTimeout(resolve, 1000));
// the timeout can be changed here
}
}
}
// Instantiate Yellowstone gRPC client with env credentials
const client = new Client(
process.env.GRPC_URL, //Your Region specific gRPC URL
process.env.X_TOKEN, // your Access Token
undefined,
);
const req: SubscribeRequest = {
accounts: {},
slots: {},
transactions: {
pumpFun: {
vote: false,
failed: false,
signature: undefined,
accountInclude: [ADDRESS_TO_STREAM_FROM],
accountExclude: [],
accountRequired: [],
},
},
transactionsStatus: {},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
ping: undefined,
commitment: CommitmentLevel.CONFIRMED,
};
subscribeCommand(client, req);
In the above example, if the stream is interrupted, we restart it after waiting for 1000ms. This time can be configured as per your requirement.
The complete code of implementing a reconnection mechanism is available on and .