For the complete documentation index, see llms.txt. This page is also available as Markdown.

Go Example

Complete Go implementation for streaming Solana transactions from NextBlock's TX Stream API, optimized for trading bots and fast transaction detection.

The example is hosted at github.com/nextblock-ag/nextblock-stream-examples

Prerequisites

go mod init nextblock-tx-stream-example
go get github.com/gagliardetto/binary github.com/gagliardetto/solana-go
go get google.golang.org/grpc

# Generate the TX Stream proto client from the proto specification
# In the example repo, dependencies and the generated .go files are already available

Example

package main

import (
	"context"
	"fmt"
	"log"
	"math"
	"math/rand/v2"
	"time"

	bin "github.com/gagliardetto/binary"
	"github.com/gagliardetto/solana-go"
	"github.com/nextblock-stream-examples/golang-example/protos"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/keepalive"
)

/*
the auth message needs to be built clients-side.
it is a pipe-separated string made of:
1. domain that's being connected to (e.g. fra.stream.nextblock.io)
2. the publickey that sent the fee to strmuYvHKeA1qvHqooUpwUk2BFwaAmMbK9WXY9mh2GJ
3. a random nonce
4. the current unix timestamp

it is then signed by the supplied publickey.
*/

func buildAuthMessage(domain string, authenticatedPublicKey solana.PublicKey) string {
	return fmt.Sprintf("%s|%s|%d|%d", domain, authenticatedPublicKey.String(), rand.IntN(math.MaxInt64), time.Now().Unix())
}

func main() {
	ctx := context.Background()

	domain := "ny.stream.nextblock.io:22221"
	authenticationPrivateKey := solana.MustPrivateKeyFromBase58("YOUR_PRIVATE_KEY")
	authenticationPublicKey := authenticationPrivateKey.PublicKey()

	authenticationMessage := buildAuthMessage(domain, authenticationPrivateKey.PublicKey())
	authenticationSignature, err := authenticationPrivateKey.Sign([]byte(authenticationMessage))
	if err != nil {
		log.Fatalf("error signing authMessage: %v", err)
	}

	creds := insecure.NewCredentials()
	conn, err := grpc.NewClient(
		domain,
		grpc.WithTransportCredentials(creds),
		grpc.WithKeepaliveParams(keepalive.ClientParameters{
			Time:                5 * time.Second,
			Timeout:             time.Second,
			PermitWithoutStream: false,
		}),
	)
	if err != nil {
		log.Fatalf("error creating new grpc conn: %v", err)
	}

	client := protos.NewNextStreamServiceClient(conn)

	sub, err := client.SubscribeNextStream(
		ctx,
		&protos.NextStreamSubscription{
			AuthenticationPublickey: authenticationPublicKey.String(),
			AuthenticationMessage:   authenticationMessage,
			AuthenticationSignature: authenticationSignature.String(),
			Accounts:                []string{solana.MustPublicKeyFromBase58("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8").String()},
		},
	)
	if err != nil {
		log.Fatalf("error SubscribeNextStream: %v", err)
	}

	for {
		msg, err := sub.Recv()
		if err != nil {
			log.Fatalf("error receiving from sub: %v", err)
		}

		tx := new(solana.Transaction)
		err = tx.UnmarshalWithDecoder(bin.NewBinDecoder(msg.Packet.Transaction))
		if err != nil {
			log.Fatalf("error unmarshaslling tx: %v", err)
		}

		log.Printf("got new sig %s on slot %d", tx.Signatures[0], msg.Packet.Slot)
	}
}

Usage Examples

Available Endpoints

Choose the endpoint closest to your location:

  • Frankfurt: fra.stream.nextblock.io:22221

  • Amsterdam: amsterdam.stream.nextblock.io:22221

  • London: london.stream.nextblock.io:22221

  • Singapore: singapore.stream.nextblock.io:22221

  • Tokyo: tokyo.stream.nextblock.io:22221

  • New York: ny.stream.nextblock.io:22221

  • Salt Lake City: slc.stream.nextblock.io:22221

  • Dublin: dublin.stream.nextblock.io:22221

  • Vilnius: vilnius.stream.nextblock.io:22221

Best Practices for Trading Bots

  1. Match the endpoint requirements: Follow the transport settings shown in the example for the current TX Stream service

  2. Filter efficiently: Only subscribe to programs you need to reduce bandwidth

  3. Handle reconnections: Implement automatic reconnection logic

  4. Process quickly: Avoid blocking the stream receiver

  5. Monitor performance: Track processing latency and throughput

  6. Implement graceful shutdown: Handle interrupt signals properly

  7. Use multiple endpoints: Implement redundancy for critical applications

Last updated