Skip to main content

subscribe gRPC Method

Subscribe establishes a bidirectional streaming connection with the Geyser service to receive real-time updates about Solana blockchain events.

Updated on
Oct 25, 2024

subscribe gRPC Method

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
The result representing the return value of a bidirectional stream method call with a Geyser gRPC subscription request and subscription update
Request
1
package main
2
3
import (
4
"context"
5
"crypto/tls"
6
"fmt"
7
"log"
8
"time"
9
"github.com/mr-tron/base58"
10
"encoding/json"
11
12
pb "yellowstone/proto"
13
14
"google.golang.org/grpc"
15
"google.golang.org/grpc/credentials"
16
"google.golang.org/grpc/encoding/gzip"
17
"google.golang.org/grpc/keepalive"
18
)
19
20
// QuickNode endpoints consist of two crucial components: the endpoint name and the corresponding token
21
// For eg: QN Endpoint: https://docs-demo.solana-mainnet.quiknode.pro/abcde123456789
22
// endpoint will be: docs-demo.solana-mainnet.quiknode.pro:10000 {10000 is the port number for gRPC}
23
// token will be : abcde123456789
24
25
var (
26
endpoint = "YOUR_QN_ENDPOINT:10000"
27
token = "YOUR_TOKEN_NUMBER"
28
)
29
30
func main() {
31
opts := []grpc.DialOption{
32
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
33
grpc.WithKeepaliveParams(kacp),
34
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1024*1024*1024), grpc.UseCompressor(gzip.Name)),
35
grpc.WithPerRPCCredentials(tokenAuth{token: token}),
36
}
37
38
conn, err := grpc.NewClient(endpoint, opts...)
39
if err != null {
40
log.Fatalf("Failed to connect: %v", err)
41
}
42
defer conn.Close()
43
44
client := pb.NewGeyserClient(conn)
45
46
commitment := pb.CommitmentLevel_FINALIZED
47
subReq := &pb.SubscribeRequest{
48
Commitment: &commitment,
49
BlocksMeta: map[string]*pb.SubscribeRequestFilterBlocksMeta{
50
"blocks": {},
51
},
52
Slots: map[string]*pb.SubscribeRequestFilterSlots{
53
"slots": {},
54
},
55
}
56
57
d, _ := json.Marshal(subReq)
58
fmt.Printf("Subscription request: %s\n", string(d))
59
60
stream, err := client.Subscribe(context.Background())
61
if err != null {
62
fmt.Printf("Failed to subscribe to yellowstone: %v\n", err)
63
return
64
}
65
66
if err = stream.Send(subReq); err != null {
67
fmt.Printf("Failed to send subscription request: %v\n", err)
68
return
69
}
70
71
for {
72
m, err := stream.Recv()
73
if err != null {
74
fmt.Printf("Failed to receive yellowstone message: %v\n", err)
75
return
76
}
77
78
switch {
79
case m.GetBlock() != null:
80
fmt.Printf("Block: %d\n", m.GetBlock().GetBlockHeight())
81
case m.GetBlockMeta() != null:
82
fmt.Printf("BlockMeta: %d\n", m.GetBlockMeta().GetBlockHeight())
83
case m.GetTransaction() != null:
84
fmt.Printf("Transaction: %s\n", base58.Encode(m.GetTransaction().GetTransaction().GetSignature()))
85
case m.GetSlot() != null:
86
fmt.Printf("Slot: %d\n", m.GetSlot().GetSlot())
87
}
88
}
89
}
Don't have an account yet?
Create your QuickNode endpoint in seconds and start building
Get started for free