subscribe gRPC Method - Yellowstone
Please note that this RPC method requires the Yellowstone gRPC add-on enabled on your QuickNode endpoint.
Parameters
This method does not accept any parameters
Returns
result
object
Loading...
Request
package main
import (
"context"
"crypto/tls"
"fmt"
"log"
"time"
"github.com/mr-tron/base58"
"encoding/json"
pb "yellowstone/proto"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/encoding/gzip"
"google.golang.org/grpc/keepalive"
)
// QuickNode endpoints consist of two crucial components: the endpoint name and the corresponding token
// For eg: QN Endpoint: https://docs-demo.solana-mainnet.quiknode.pro/abcde123456789
// endpoint will be: docs-demo.solana-mainnet.quiknode.pro:10000 {10000 is the port number for gRPC}
// token will be : abcde123456789
var (
endpoint = "YOUR_QN_ENDPOINT:10000"
token = "YOUR_TOKEN_NUMBER"
)
func main() {
opts := []grpc.DialOption{
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
grpc.WithKeepaliveParams(kacp),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1024*1024*1024), grpc.UseCompressor(gzip.Name)),
grpc.WithPerRPCCredentials(tokenAuth{token: token}),
}
conn, err := grpc.NewClient(endpoint, opts...)
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewGeyserClient(conn)
commitment := pb.CommitmentLevel_FINALIZED
subReq := &pb.SubscribeRequest{
Commitment: &commitment,
BlocksMeta: map[string]*pb.SubscribeRequestFilterBlocksMeta{
"blocks": {},
},
Slots: map[string]*pb.SubscribeRequestFilterSlots{
"slots": {},
},
}
d, _ := json.Marshal(subReq)
fmt.Printf("Subscription request: %s\n", string(d))
stream, err := client.Subscribe(context.Background())
if err != nil {
fmt.Printf("Failed to subscribe to yellowstone: %v\n", err)
return
}
if err = stream.Send(subReq); err != nil {
fmt.Printf("Failed to send subscription request: %v\n", err)
return
}
for {
m, err := stream.Recv()
if err != nil {
fmt.Printf("Failed to receive yellowstone message: %v\n", err)
return
}
switch {
case m.GetBlock() != nil:
fmt.Printf("Block: %d\n", m.GetBlock().GetBlockHeight())
case m.GetBlockMeta() != nil:
fmt.Printf("BlockMeta: %d\n", m.GetBlockMeta().GetBlockHeight())
case m.GetTransaction() != nil:
fmt.Printf("Transaction: %s\n", base58.Encode(m.GetTransaction().GetTransaction().GetSignature()))
case m.GetSlot() != nil:
fmt.Printf("Slot: %d\n", m.GetSlot().GetSlot())
}
}
}import Client, { CommitmentLevel, SubscribeRequest, SubscribeUpdate, SubscribeUpdateTransaction } from "@triton-one/yellowstone-grpc";
// QuickNode endpoints consist of two crucial components: the endpoint name and the corresponding token
// For eg: QN Endpoint: https://docs-demo.solana-mainnet.quiknode.pro/abcde123456789
// endpoint will be: docs-demo.solana-mainnet.quiknode.pro:10000 {10000 is the port number for gRPC}
// token will be : abcde123456789
const ENDPOINT = "YOUR_QN_ENDPOINT:10000";
const TOKEN = "YOUR_TOKEN_NUMBER";
async function main() {
const client = new Client(ENDPOINT, TOKEN, {});
const commitment = CommitmentLevel.CONFIRMED;
try {
const stream = await client.subscribe();
// Set up error and end handlers
stream.on("error", (error) => {
console.error("Stream error:", error);
stream.end();
});
stream.on("end", () => {
console.log("Stream ended");
});
// Handle incoming data
stream.on("data", (data: SubscribeUpdate) => {
handleSubscribeUpdate(data);
});
// Create subscription request
const request: SubscribeRequest = {
slots: { client: { filterByCommitment: true } },
transactions: {
client: {
vote: false,
failed: false,
signature: undefined,
accountInclude: [],
accountExclude: [],
accountRequired: [],
},
},
commitment: commitment,
accounts: {},
transactionsStatus: {},
entry: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
ping: undefined,
};
// Send subscription request
await new Promise<void>((resolve, reject) => {
stream.write(request, (err: Error | null | undefined) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
console.log("Subscription started. Waiting for events...");
// Keep the script running
await new Promise(() => {});
} catch (error) {
console.error("Error in subscription process:", error);
}
}
function handleSubscribeUpdate(data: SubscribeUpdate) {
if ("slot" in data) {
console.log("Slot update:", data.slot);
} else if ("transaction" in data) {
const transaction = data.transaction as SubscribeUpdateTransaction;
if (transaction && transaction.transaction) {
console.log("Transaction update:", {
signature: Buffer.from(transaction.transaction.signature).toString('base64'),
slot: transaction.slot,
});
}
} else {
console.log("Other update:", data);
}
}
main()
.catch((err) => {
console.error("Unhandled error:", err);
process.exit(1);
});Don't have an account yet?
Create your QuickNode endpoint in seconds and start building
Get started for free