StreamL2Book gRPC Method
Parameters
coin
string
Loading...
n_levels
uint32
Loading...
n_sig_figs
uint32
Loading...
mantissa
uint64
Loading...
Returns
stream
stream<L2BookUpdate>
Loading...
coin
string
Loading...
block_timestamp
uint64
Loading...
block_number
uint64
Loading...
bids
array<L2Level>
Loading...
asks
array<L2Level>
Loading...
Request
1// StreamL2Book Example - Stream aggregated orderbook data via gRPC2package main34import (5"context"6"flag"7"fmt"8"io"9"log"10"math"11"strings"12"time"1314"google.golang.org/grpc"15"google.golang.org/grpc/codes"16"google.golang.org/grpc/credentials"17"google.golang.org/grpc/metadata"18"google.golang.org/grpc/status"1920pb "hyperliquid-orderbook-example/proto"21)2223const (24grpcEndpoint = "your-endpoint.hype-mainnet.quiknode.pro:10000"25authToken = "your-auth-token"26maxRetries = 1027baseDelay = 2 * time.Second28)2930func streamL2Orderbook(coin string, nLevels uint32) error {31fmt.Println(strings.Repeat("=", 60))32fmt.Printf("Streaming L2 Orderbook for %s\n", coin)33fmt.Printf("Levels: %d\n", nLevels)34fmt.Println("Auto-reconnect: true")35fmt.Println(strings.Repeat("=", 60) + "\n")3637retryCount := 03839for retryCount < maxRetries {40creds := credentials.NewClientTLSFromCert(nil, "")41conn, err := grpc.Dial(grpcEndpoint,42grpc.WithTransportCredentials(creds),43grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(100*1024*1024)))44if err != nil {45return fmt.Errorf("failed to connect: %w", err)46}4748client := pb.NewOrderBookStreamingClient(conn)49ctx := metadata.AppendToOutgoingContext(context.Background(), "x-token", authToken)5051request := &pb.L2BookRequest{52Coin: coin,53NLevels: nLevels,54}5556if retryCount > 0 {57fmt.Printf("\nš Reconnecting (attempt %d/%d)...\n", retryCount+1, maxRetries)58} else {59fmt.Printf("Connecting to %s...\n", grpcEndpoint)60}6162stream, err := client.StreamL2Book(ctx, request)63if err != nil {64conn.Close()65return fmt.Errorf("failed to start stream: %w", err)66}6768msgCount := 069shouldRetry := false7071for {72update, err := stream.Recv()73if err == io.EOF {74break75}76if err != nil {77st, ok := status.FromError(err)78if ok && st.Code() == codes.DataLoss {79fmt.Printf("\nā ļø Server reinitialized: %s\n", st.Message())80retryCount++81if retryCount < maxRetries {82delay := baseDelay * time.Duration(math.Pow(2, float64(retryCount-1)))83fmt.Printf("ā³ Waiting %v before reconnecting...\n", delay)84time.Sleep(delay)85shouldRetry = true86break87} else {88fmt.Printf("\nā Max retries (%d) reached. Giving up.\n", maxRetries)89conn.Close()90return nil91}92}93conn.Close()94return fmt.Errorf("stream error: %w", err)95}9697msgCount++98if msgCount == 1 {99fmt.Println("ā First L2 update received!\n")100retryCount = 0 // Reset on success101}102103// Display orderbook104fmt.Println("\n" + strings.Repeat("ā", 60))105fmt.Printf("Block: %d | Time: %d | Coin: %s\n", update.BlockNumber, update.Time, update.Coin)106fmt.Println(strings.Repeat("ā", 60))107108// Display asks (reversed)109if len(update.Asks) > 0 {110fmt.Println("\n ASKS:")111askCount := len(update.Asks)112if askCount > 10 {113askCount = 10114}115for i := askCount - 1; i >= 0; i-- {116level := update.Asks[i]117fmt.Printf(" %12s | %12s | (%d orders)\n", level.Px, level.Sz, level.N)118}119}120121// Display spread122if len(update.Bids) > 0 && len(update.Asks) > 0 {123fmt.Println("\n " + strings.Repeat("ā", 44))124fmt.Printf(" SPREAD: (best bid: %s, best ask: %s)\n", update.Bids[0].Px, update.Asks[0].Px)125fmt.Println(" " + strings.Repeat("ā", 44))126}127128// Display bids129if len(update.Bids) > 0 {130fmt.Println("\n BIDS:")131bidCount := len(update.Bids)132if bidCount > 10 {133bidCount = 10134}135for i := 0; i < bidCount; i++ {136level := update.Bids[i]137fmt.Printf(" %12s | %12s | (%d orders)\n", level.Px, level.Sz, level.N)138}139}140141fmt.Printf("\n Messages received: %d\n", msgCount)142}143144conn.Close()145146if !shouldRetry {147break148}149}150151return nil152}153154func main() {155coin := flag.String("coin", "BTC", "Coin symbol to stream")156levels := flag.Uint("levels", 20, "Number of price levels")157158flag.Parse()159160fmt.Println("\n" + strings.Repeat("=", 60))161fmt.Println("Hyperliquid StreamL2Book Example")162fmt.Printf("Endpoint: %s\n", grpcEndpoint)163fmt.Println(strings.Repeat("=", 60))164165if err := streamL2Orderbook(*coin, uint32(*levels)); err != nil {166log.Fatal(err)167}168}169
1// StreamL2Book Example - Stream aggregated orderbook data via gRPC2package main34import (5"context"6"flag"7"fmt"8"io"9"log"10"math"11"strings"12"time"1314"google.golang.org/grpc"15"google.golang.org/grpc/codes"16"google.golang.org/grpc/credentials"17"google.golang.org/grpc/metadata"18"google.golang.org/grpc/status"1920pb "hyperliquid-orderbook-example/proto"21)2223const (24grpcEndpoint = "your-endpoint.hype-mainnet.quiknode.pro:10000"25authToken = "your-auth-token"26maxRetries = 1027baseDelay = 2 * time.Second28)2930func streamL2Orderbook(coin string, nLevels uint32) error {31fmt.Println(strings.Repeat("=", 60))32fmt.Printf("Streaming L2 Orderbook for %s\n", coin)33fmt.Printf("Levels: %d\n", nLevels)34fmt.Println("Auto-reconnect: true")35fmt.Println(strings.Repeat("=", 60) + "\n")3637retryCount := 03839for retryCount < maxRetries {40creds := credentials.NewClientTLSFromCert(nil, "")41conn, err := grpc.Dial(grpcEndpoint,42grpc.WithTransportCredentials(creds),43grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(100*1024*1024)))44if err != nil {45return fmt.Errorf("failed to connect: %w", err)46}4748client := pb.NewOrderBookStreamingClient(conn)49ctx := metadata.AppendToOutgoingContext(context.Background(), "x-token", authToken)5051request := &pb.L2BookRequest{52Coin: coin,53NLevels: nLevels,54}5556if retryCount > 0 {57fmt.Printf("\nš Reconnecting (attempt %d/%d)...\n", retryCount+1, maxRetries)58} else {59fmt.Printf("Connecting to %s...\n", grpcEndpoint)60}6162stream, err := client.StreamL2Book(ctx, request)63if err != nil {64conn.Close()65return fmt.Errorf("failed to start stream: %w", err)66}6768msgCount := 069shouldRetry := false7071for {72update, err := stream.Recv()73if err == io.EOF {74break75}76if err != nil {77st, ok := status.FromError(err)78if ok && st.Code() == codes.DataLoss {79fmt.Printf("\nā ļø Server reinitialized: %s\n", st.Message())80retryCount++81if retryCount < maxRetries {82delay := baseDelay * time.Duration(math.Pow(2, float64(retryCount-1)))83fmt.Printf("ā³ Waiting %v before reconnecting...\n", delay)84time.Sleep(delay)85shouldRetry = true86break87} else {88fmt.Printf("\nā Max retries (%d) reached. Giving up.\n", maxRetries)89conn.Close()90return nil91}92}93conn.Close()94return fmt.Errorf("stream error: %w", err)95}9697msgCount++98if msgCount == 1 {99fmt.Println("ā First L2 update received!\n")100retryCount = 0 // Reset on success101}102103// Display orderbook104fmt.Println("\n" + strings.Repeat("ā", 60))105fmt.Printf("Block: %d | Time: %d | Coin: %s\n", update.BlockNumber, update.Time, update.Coin)106fmt.Println(strings.Repeat("ā", 60))107108// Display asks (reversed)109if len(update.Asks) > 0 {110fmt.Println("\n ASKS:")111askCount := len(update.Asks)112if askCount > 10 {113askCount = 10114}115for i := askCount - 1; i >= 0; i-- {116level := update.Asks[i]117fmt.Printf(" %12s | %12s | (%d orders)\n", level.Px, level.Sz, level.N)118}119}120121// Display spread122if len(update.Bids) > 0 && len(update.Asks) > 0 {123fmt.Println("\n " + strings.Repeat("ā", 44))124fmt.Printf(" SPREAD: (best bid: %s, best ask: %s)\n", update.Bids[0].Px, update.Asks[0].Px)125fmt.Println(" " + strings.Repeat("ā", 44))126}127128// Display bids129if len(update.Bids) > 0 {130fmt.Println("\n BIDS:")131bidCount := len(update.Bids)132if bidCount > 10 {133bidCount = 10134}135for i := 0; i < bidCount; i++ {136level := update.Bids[i]137fmt.Printf(" %12s | %12s | (%d orders)\n", level.Px, level.Sz, level.N)138}139}140141fmt.Printf("\n Messages received: %d\n", msgCount)142}143144conn.Close()145146if !shouldRetry {147break148}149}150151return nil152}153154func main() {155coin := flag.String("coin", "BTC", "Coin symbol to stream")156levels := flag.Uint("levels", 20, "Number of price levels")157158flag.Parse()159160fmt.Println("\n" + strings.Repeat("=", 60))161fmt.Println("Hyperliquid StreamL2Book Example")162fmt.Printf("Endpoint: %s\n", grpcEndpoint)163fmt.Println(strings.Repeat("=", 60))164165if err := streamL2Orderbook(*coin, uint32(*levels)); err != nil {166log.Fatal(err)167}168}169
Don't have an account yet?
Create your Quicknode endpoint in seconds and start building
Get started for free