StreamData gRPC Method
Please note that this method is metered based on data consumption at 0.1 MB = 10 API credits. Concurrent stream caps and filter limits vary by plan - see the Streaming Limits table.
Parameters
request
object
Loading...
Loading...
Loading...
Returns
stream
stream<SubscribeUpdate>
Loading...
data
StreamResponse
Loading...
data.data - TRADES
array
Loading...
data.data - ORDERS
array
Loading...
data.data - BOOK_UPDATES
array
Loading...
data.data - TWAP
array
Loading...
data.data - EVENTS
array
Loading...
data.data - WRITER_ACTIONS
array
Loading...
data.data - BLOCKS
object
Loading...
data.data - MEMPOOL_TXS
array
Loading...
pong
Pong
Loading...
Request
1package main23import (4"context"5"crypto/tls"6"encoding/json"7"fmt"8"io"9"log"10"time"1112"google.golang.org/grpc"13"google.golang.org/grpc/credentials"14"google.golang.org/grpc/metadata"1516pb "hyperliquid-grpc-go/pb"17)1819const (20// Using Quicknode endpoint21grpcEndpoint = "your-endpoint.hype-mainnet.quiknode.pro:10000"22authToken = "your-auth-token"23)2425// Create gRPC connection with TLS26func createConnection() (*grpc.ClientConn, error) {27tlsConfig := &tls.Config{28InsecureSkipVerify: false, // Set to true only for testing29}30creds := credentials.NewTLS(tlsConfig)3132conn, err := grpc.Dial(33grpcEndpoint,34grpc.WithTransportCredentials(creds),35grpc.WithDefaultCallOptions(36grpc.MaxCallRecvMsgSize(100*1024*1024), // 100MB37),38)3940return conn, err41}4243// Create context with auth metadata44func createContext() context.Context {45md := metadata.Pairs("x-token", authToken)46return metadata.NewOutgoingContext(context.Background(), md)47}484950// Stream trades51func streamTrades(client pb.StreamingClient) error {52ctx := createContext()5354stream, err := client.StreamData(ctx)55if err != nil {56return fmt.Errorf("failed to create stream: %v", err)57}5859// Send subscription request60// Empty Filters means receive all events for this stream type61err = stream.Send(&pb.SubscribeRequest{62Request: &pb.SubscribeRequest_Subscribe{63Subscribe: &pb.StreamSubscribe{64StreamType: pb.StreamType_TRADES,65StartBlock: 0,66Filters: map[string]*pb.FilterValues{},67},68},69})70if err != nil {71return fmt.Errorf("failed to subscribe: %v", err)72}7374// Start ping goroutine75go func() {76ticker := time.NewTicker(30 * time.Second)77defer ticker.Stop()7879for range ticker.C {80err := stream.Send(&pb.SubscribeRequest{81Request: &pb.SubscribeRequest_Ping{82Ping: &pb.Ping{83Timestamp: time.Now().UnixMilli(),84},85},86})87if err != nil {88log.Printf("Failed to send ping: %v", err)89return90}91}92}()9394// Receive messages95log.Println("š Starting trades stream...")96for {97msg, err := stream.Recv()98if err == io.EOF {99log.Println("Stream ended")100break101}102if err != nil {103return fmt.Errorf("receive error: %v", err)104}105106switch update := msg.Update.(type) {107case *pb.SubscribeUpdate_Data:108var data map[string]interface{}109if err := json.Unmarshal([]byte(update.Data.Data), &data); err != nil {110log.Printf("ā ļø Failed to parse data: %v", err)111continue112}113114trades, ok := data["trades"].([]interface{})115tradesCount := 0116if ok {117tradesCount = len(trades)118}119120log.Printf("š Block %d: %d trades", update.Data.BlockNumber, tradesCount)121122// Pretty print first trade if available123if tradesCount > 0 {124firstTrade := trades[0]125tradeJSON, _ := json.MarshalIndent(firstTrade, " ", " ")126fmt.Printf(" Example trade:\n%s\n", tradeJSON)127}128129case *pb.SubscribeUpdate_Pong:130log.Printf("š Pong received: %d", update.Pong.Timestamp)131}132}133134return nil135}136137// Stream filtered trades138func streamFilteredTrades(client pb.StreamingClient, coins []string) error {139ctx := createContext()140141stream, err := client.StreamData(ctx)142if err != nil {143return fmt.Errorf("failed to create stream: %v", err)144}145146// Send filtered subscription147err = stream.Send(&pb.SubscribeRequest{148Request: &pb.SubscribeRequest_Subscribe{149Subscribe: &pb.StreamSubscribe{150StreamType: pb.StreamType_TRADES,151StartBlock: 0,152Filters: map[string]*pb.FilterValues{153"coin": {Values: coins},154},155},156},157})158if err != nil {159return fmt.Errorf("failed to subscribe: %v", err)160}161162log.Printf("š Starting filtered trades stream for coins: %v", coins)163164// Receive messages165for {166msg, err := stream.Recv()167if err == io.EOF {168log.Println("Filtered stream ended")169break170}171if err != nil {172return fmt.Errorf("receive error: %v", err)173}174175switch update := msg.Update.(type) {176case *pb.SubscribeUpdate_Data:177var data map[string]interface{}178if err := json.Unmarshal([]byte(update.Data.Data), &data); err != nil {179log.Printf("ā ļø Failed to parse data: %v", err)180continue181}182183if trades, ok := data["trades"].([]interface{}); ok && len(trades) > 0 {184log.Printf("š Filtered Block %d: %d trades", update.Data.BlockNumber, len(trades))185prettyJSON, _ := json.MarshalIndent(data, "", " ")186fmt.Println(string(prettyJSON))187}188}189}190191return nil192}193194// Stream orders195func streamOrders(client pb.StreamingClient) error {196ctx := createContext()197198stream, err := client.StreamData(ctx)199if err != nil {200return fmt.Errorf("failed to create stream: %v", err)201}202203// Send subscription request for orders204err = stream.Send(&pb.SubscribeRequest{205Request: &pb.SubscribeRequest_Subscribe{206Subscribe: &pb.StreamSubscribe{207StreamType: pb.StreamType_ORDERS,208StartBlock: 0,209Filters: map[string]*pb.FilterValues{},210},211},212})213if err != nil {214return fmt.Errorf("failed to subscribe: %v", err)215}216217log.Println("š Starting orders stream...")218219// Receive messages220for {221msg, err := stream.Recv()222if err == io.EOF {223log.Println("Orders stream ended")224break225}226if err != nil {227return fmt.Errorf("receive error: %v", err)228}229230switch update := msg.Update.(type) {231case *pb.SubscribeUpdate_Data:232var data map[string]interface{}233if err := json.Unmarshal([]byte(update.Data.Data), &data); err != nil {234log.Printf("ā ļø Failed to parse order data: %v", err)235continue236}237238log.Printf("š Orders Block %d:", update.Data.BlockNumber)239prettyJSON, _ := json.MarshalIndent(data, "", " ")240fmt.Println(string(prettyJSON))241}242}243244return nil245}246247248// Interactive menu249func runInteractiveMenu(conn *grpc.ClientConn) {250client := pb.NewStreamingClient(conn)251252fmt.Println("\nš Connected successfully!")253fmt.Println("\nAvailable streams:")254fmt.Println("1. All trades")255fmt.Println("2. Filtered trades (BTC, ETH)")256fmt.Println("3. Orders")257fmt.Println("4. Exit")258259for {260fmt.Print("\nSelect stream (1-4): ")261var choice string262fmt.Scanln(&choice)263264switch choice {265case "1":266if err := streamTrades(client); err != nil {267log.Printf("ā Stream error: %v", err)268}269case "2":270if err := streamFilteredTrades(client, []string{"BTC", "ETH"}); err != nil {271log.Printf("ā Filtered stream error: %v", err)272}273case "3":274if err := streamOrders(client); err != nil {275log.Printf("ā Orders stream error: %v", err)276}277case "4":278fmt.Println("š Goodbye!")279return280default:281fmt.Println("ā Invalid choice. Please select 1-4.")282}283}284}285286func main() {287// Create connection288conn, err := createConnection()289if err != nil {290log.Fatalf("ā Failed to connect: %v", err)291}292defer conn.Close()293294fmt.Printf("Connected to: %s\n", grpcEndpoint)295296// Run interactive menu297runInteractiveMenu(conn)298}
1package main23import (4"context"5"crypto/tls"6"encoding/json"7"fmt"8"io"9"log"10"time"1112"google.golang.org/grpc"13"google.golang.org/grpc/credentials"14"google.golang.org/grpc/metadata"1516pb "hyperliquid-grpc-go/pb"17)1819const (20// Using Quicknode endpoint21grpcEndpoint = "your-endpoint.hype-mainnet.quiknode.pro:10000"22authToken = "your-auth-token"23)2425// Create gRPC connection with TLS26func createConnection() (*grpc.ClientConn, error) {27tlsConfig := &tls.Config{28InsecureSkipVerify: false, // Set to true only for testing29}30creds := credentials.NewTLS(tlsConfig)3132conn, err := grpc.Dial(33grpcEndpoint,34grpc.WithTransportCredentials(creds),35grpc.WithDefaultCallOptions(36grpc.MaxCallRecvMsgSize(100*1024*1024), // 100MB37),38)3940return conn, err41}4243// Create context with auth metadata44func createContext() context.Context {45md := metadata.Pairs("x-token", authToken)46return metadata.NewOutgoingContext(context.Background(), md)47}484950// Stream trades51func streamTrades(client pb.StreamingClient) error {52ctx := createContext()5354stream, err := client.StreamData(ctx)55if err != nil {56return fmt.Errorf("failed to create stream: %v", err)57}5859// Send subscription request60// Empty Filters means receive all events for this stream type61err = stream.Send(&pb.SubscribeRequest{62Request: &pb.SubscribeRequest_Subscribe{63Subscribe: &pb.StreamSubscribe{64StreamType: pb.StreamType_TRADES,65StartBlock: 0,66Filters: map[string]*pb.FilterValues{},67},68},69})70if err != nil {71return fmt.Errorf("failed to subscribe: %v", err)72}7374// Start ping goroutine75go func() {76ticker := time.NewTicker(30 * time.Second)77defer ticker.Stop()7879for range ticker.C {80err := stream.Send(&pb.SubscribeRequest{81Request: &pb.SubscribeRequest_Ping{82Ping: &pb.Ping{83Timestamp: time.Now().UnixMilli(),84},85},86})87if err != nil {88log.Printf("Failed to send ping: %v", err)89return90}91}92}()9394// Receive messages95log.Println("š Starting trades stream...")96for {97msg, err := stream.Recv()98if err == io.EOF {99log.Println("Stream ended")100break101}102if err != nil {103return fmt.Errorf("receive error: %v", err)104}105106switch update := msg.Update.(type) {107case *pb.SubscribeUpdate_Data:108var data map[string]interface{}109if err := json.Unmarshal([]byte(update.Data.Data), &data); err != nil {110log.Printf("ā ļø Failed to parse data: %v", err)111continue112}113114trades, ok := data["trades"].([]interface{})115tradesCount := 0116if ok {117tradesCount = len(trades)118}119120log.Printf("š Block %d: %d trades", update.Data.BlockNumber, tradesCount)121122// Pretty print first trade if available123if tradesCount > 0 {124firstTrade := trades[0]125tradeJSON, _ := json.MarshalIndent(firstTrade, " ", " ")126fmt.Printf(" Example trade:\n%s\n", tradeJSON)127}128129case *pb.SubscribeUpdate_Pong:130log.Printf("š Pong received: %d", update.Pong.Timestamp)131}132}133134return nil135}136137// Stream filtered trades138func streamFilteredTrades(client pb.StreamingClient, coins []string) error {139ctx := createContext()140141stream, err := client.StreamData(ctx)142if err != nil {143return fmt.Errorf("failed to create stream: %v", err)144}145146// Send filtered subscription147err = stream.Send(&pb.SubscribeRequest{148Request: &pb.SubscribeRequest_Subscribe{149Subscribe: &pb.StreamSubscribe{150StreamType: pb.StreamType_TRADES,151StartBlock: 0,152Filters: map[string]*pb.FilterValues{153"coin": {Values: coins},154},155},156},157})158if err != nil {159return fmt.Errorf("failed to subscribe: %v", err)160}161162log.Printf("š Starting filtered trades stream for coins: %v", coins)163164// Receive messages165for {166msg, err := stream.Recv()167if err == io.EOF {168log.Println("Filtered stream ended")169break170}171if err != nil {172return fmt.Errorf("receive error: %v", err)173}174175switch update := msg.Update.(type) {176case *pb.SubscribeUpdate_Data:177var data map[string]interface{}178if err := json.Unmarshal([]byte(update.Data.Data), &data); err != nil {179log.Printf("ā ļø Failed to parse data: %v", err)180continue181}182183if trades, ok := data["trades"].([]interface{}); ok && len(trades) > 0 {184log.Printf("š Filtered Block %d: %d trades", update.Data.BlockNumber, len(trades))185prettyJSON, _ := json.MarshalIndent(data, "", " ")186fmt.Println(string(prettyJSON))187}188}189}190191return nil192}193194// Stream orders195func streamOrders(client pb.StreamingClient) error {196ctx := createContext()197198stream, err := client.StreamData(ctx)199if err != nil {200return fmt.Errorf("failed to create stream: %v", err)201}202203// Send subscription request for orders204err = stream.Send(&pb.SubscribeRequest{205Request: &pb.SubscribeRequest_Subscribe{206Subscribe: &pb.StreamSubscribe{207StreamType: pb.StreamType_ORDERS,208StartBlock: 0,209Filters: map[string]*pb.FilterValues{},210},211},212})213if err != nil {214return fmt.Errorf("failed to subscribe: %v", err)215}216217log.Println("š Starting orders stream...")218219// Receive messages220for {221msg, err := stream.Recv()222if err == io.EOF {223log.Println("Orders stream ended")224break225}226if err != nil {227return fmt.Errorf("receive error: %v", err)228}229230switch update := msg.Update.(type) {231case *pb.SubscribeUpdate_Data:232var data map[string]interface{}233if err := json.Unmarshal([]byte(update.Data.Data), &data); err != nil {234log.Printf("ā ļø Failed to parse order data: %v", err)235continue236}237238log.Printf("š Orders Block %d:", update.Data.BlockNumber)239prettyJSON, _ := json.MarshalIndent(data, "", " ")240fmt.Println(string(prettyJSON))241}242}243244return nil245}246247248// Interactive menu249func runInteractiveMenu(conn *grpc.ClientConn) {250client := pb.NewStreamingClient(conn)251252fmt.Println("\nš Connected successfully!")253fmt.Println("\nAvailable streams:")254fmt.Println("1. All trades")255fmt.Println("2. Filtered trades (BTC, ETH)")256fmt.Println("3. Orders")257fmt.Println("4. Exit")258259for {260fmt.Print("\nSelect stream (1-4): ")261var choice string262fmt.Scanln(&choice)263264switch choice {265case "1":266if err := streamTrades(client); err != nil {267log.Printf("ā Stream error: %v", err)268}269case "2":270if err := streamFilteredTrades(client, []string{"BTC", "ETH"}); err != nil {271log.Printf("ā Filtered stream error: %v", err)272}273case "3":274if err := streamOrders(client); err != nil {275log.Printf("ā Orders stream error: %v", err)276}277case "4":278fmt.Println("š Goodbye!")279return280default:281fmt.Println("ā Invalid choice. Please select 1-4.")282}283}284}285286func main() {287// Create connection288conn, err := createConnection()289if err != nil {290log.Fatalf("ā Failed to connect: %v", err)291}292defer conn.Close()293294fmt.Printf("Connected to: %s\n", grpcEndpoint)295296// Run interactive menu297runInteractiveMenu(conn)298}
1const grpc = require('@grpc/grpc-js');2const protoLoader = require('@grpc/proto-loader');3const path = require('path');45// Configuration6const GRPC_ENDPOINT = 'your-endpoint.hype-mainnet.quiknode.pro:10000';7const AUTH_TOKEN = 'your-auth-token';89// Load proto file10const packageDefinition = protoLoader.loadSync(11path.join(__dirname, 'proto/streaming.proto'),12{13keepCase: true,14longs: String,15enums: String,16defaults: true,17oneofs: true,18}19);2021const hyperliquidProto = grpc.loadPackageDefinition(packageDefinition).hyperliquid;2223// Create gRPC client with TLS24function createClient() {25const credentials = grpc.credentials.createSsl();2627const client = new hyperliquidProto.Streaming(28GRPC_ENDPOINT,29credentials,30{31'grpc.max_receive_message_length': 100 * 1024 * 1024, // 100MB32}33);3435return client;36}3738// Create metadata with auth token39function createMetadata() {40const metadata = new grpc.Metadata();41metadata.add('x-token', AUTH_TOKEN);42return metadata;43}4445// Test connectivity with ping46function testPing(client) {47return new Promise((resolve, reject) => {48const metadata = createMetadata();4950client.Ping({ count: 1 }, metadata, (error, response) => {51if (error) {52reject(new Error(`Ping failed: ${error.message}`));53return;54}5556console.log('ā Ping successful:', response);57resolve(response);58});59});60}6162// Stream trades data63function streamTrades(client) {64return new Promise((resolve, reject) => {65const metadata = createMetadata();6667const stream = client.StreamData(metadata);6869// Handle incoming messages70stream.on('data', (response) => {71if (response.data) {72try {73const data = JSON.parse(response.data.data);74const trades = data.trades || [];7576console.log(`š Block ${response.data.block_number}: ${trades.length} trades`);7778// Pretty print first trade if available79if (trades.length > 0) {80console.log(' Example trade:', JSON.stringify(trades[0], null, 2));81}82} catch (error) {83console.log('ā ļø Failed to parse data:', error.message);84}85} else if (response.pong) {86console.log('š Pong received:', response.pong.timestamp);87}88});8990stream.on('error', (error) => {91console.error('ā Stream error:', error.message);92reject(error);93});9495stream.on('end', () => {96console.log('Stream ended');97resolve();98});99100// Send subscription request101// Empty filters means receive all events for this stream type102stream.write({103subscribe: {104stream_type: 'TRADES',105filters: {}106}107});108109// Start ping interval to keep connection alive110const pingInterval = setInterval(() => {111stream.write({112ping: {113timestamp: Date.now()114}115});116}, 30000);117118// Clean up on exit119const cleanup = () => {120clearInterval(pingInterval);121stream.end();122};123124process.on('SIGINT', cleanup);125process.on('SIGTERM', cleanup);126127console.log('š Starting trades stream...');128});129}130131// Stream orders data132function streamOrders(client) {133return new Promise((resolve, reject) => {134const metadata = createMetadata();135136const stream = client.StreamData(metadata);137138stream.on('data', (response) => {139if (response.data) {140try {141const data = JSON.parse(response.data.data);142console.log(`š Orders Block ${response.data.block_number}:`);143console.log(JSON.stringify(data, null, 2));144} catch (error) {145console.log('ā ļø Failed to parse order data:', error.message);146}147}148});149150stream.on('error', (error) => {151console.error('ā Stream error:', error.message);152reject(error);153});154155stream.on('end', () => {156console.log('Orders stream ended');157resolve();158});159160// Send subscription request for orders161stream.write({162subscribe: {163stream_type: 'ORDERS',164filters: {}165}166});167168console.log('š Starting orders stream...');169});170}171172// Interactive menu173function showMenu() {174console.log('\nš Connected successfully!');175console.log('\nAvailable streams:');176console.log('1. All trades');177console.log('2. Filtered trades (BTC, ETH)');178console.log('3. Orders');179console.log('4. Test ping');180console.log('5. Exit');181182const readline = require('readline');183const rl = readline.createInterface({184input: process.stdin,185output: process.stdout186});187188return new Promise((resolve) => {189rl.question('\nSelect stream (1-5): ', (choice) => {190rl.close();191resolve(choice);192});193});194}195196// Stream filtered trades197function streamFilteredTrades(client, coins) {198return new Promise((resolve, reject) => {199const metadata = createMetadata();200201const stream = client.StreamData(metadata);202203stream.on('data', (response) => {204if (response.data) {205try {206const data = JSON.parse(response.data.data);207const trades = data.trades || [];208209if (trades.length > 0) {210console.log(`š Filtered Block ${response.data.block_number}: ${trades.length} trades`);211console.log(JSON.stringify(data, null, 2));212}213} catch (error) {214console.log('ā ļø Failed to parse data:', error.message);215}216}217});218219stream.on('error', (error) => {220console.error('ā Stream error:', error.message);221reject(error);222});223224stream.on('end', () => {225console.log('Filtered stream ended');226resolve();227});228229// Send filtered subscription230stream.write({231subscribe: {232stream_type: 'TRADES',233filters: {234coin: { values: coins }235}236}237});238239console.log(`š Starting filtered trades stream for coins: ${coins.join(', ')}`);240});241}242243// Main function244async function main() {245try {246console.log(`Testing connection to: ${GRPC_ENDPOINT}`);247248// Create client249const client = createClient();250251// Test initial connectivity252await testPing(client);253254// Show interactive menu255while (true) {256const choice = await showMenu();257258switch (choice) {259case '1':260await streamTrades(client);261break;262case '2':263await streamFilteredTrades(client, ['BTC', 'ETH']);264break;265case '3':266await streamOrders(client);267break;268case '4':269await testPing(client);270break;271case '5':272console.log('š Goodbye!');273client.close();274return;275default:276console.log('ā Invalid choice. Please select 1-5.');277}278}279280} catch (error) {281console.error('ā Error:', error.message);282process.exit(1);283}284}285286// Run the application287main();
1const grpc = require('@grpc/grpc-js');2const protoLoader = require('@grpc/proto-loader');3const path = require('path');45// Configuration6const GRPC_ENDPOINT = 'your-endpoint.hype-mainnet.quiknode.pro:10000';7const AUTH_TOKEN = 'your-auth-token';89// Load proto file10const packageDefinition = protoLoader.loadSync(11path.join(__dirname, 'proto/streaming.proto'),12{13keepCase: true,14longs: String,15enums: String,16defaults: true,17oneofs: true,18}19);2021const hyperliquidProto = grpc.loadPackageDefinition(packageDefinition).hyperliquid;2223// Create gRPC client with TLS24function createClient() {25const credentials = grpc.credentials.createSsl();2627const client = new hyperliquidProto.Streaming(28GRPC_ENDPOINT,29credentials,30{31'grpc.max_receive_message_length': 100 * 1024 * 1024, // 100MB32}33);3435return client;36}3738// Create metadata with auth token39function createMetadata() {40const metadata = new grpc.Metadata();41metadata.add('x-token', AUTH_TOKEN);42return metadata;43}4445// Test connectivity with ping46function testPing(client) {47return new Promise((resolve, reject) => {48const metadata = createMetadata();4950client.Ping({ count: 1 }, metadata, (error, response) => {51if (error) {52reject(new Error(`Ping failed: ${error.message}`));53return;54}5556console.log('ā Ping successful:', response);57resolve(response);58});59});60}6162// Stream trades data63function streamTrades(client) {64return new Promise((resolve, reject) => {65const metadata = createMetadata();6667const stream = client.StreamData(metadata);6869// Handle incoming messages70stream.on('data', (response) => {71if (response.data) {72try {73const data = JSON.parse(response.data.data);74const trades = data.trades || [];7576console.log(`š Block ${response.data.block_number}: ${trades.length} trades`);7778// Pretty print first trade if available79if (trades.length > 0) {80console.log(' Example trade:', JSON.stringify(trades[0], null, 2));81}82} catch (error) {83console.log('ā ļø Failed to parse data:', error.message);84}85} else if (response.pong) {86console.log('š Pong received:', response.pong.timestamp);87}88});8990stream.on('error', (error) => {91console.error('ā Stream error:', error.message);92reject(error);93});9495stream.on('end', () => {96console.log('Stream ended');97resolve();98});99100// Send subscription request101// Empty filters means receive all events for this stream type102stream.write({103subscribe: {104stream_type: 'TRADES',105filters: {}106}107});108109// Start ping interval to keep connection alive110const pingInterval = setInterval(() => {111stream.write({112ping: {113timestamp: Date.now()114}115});116}, 30000);117118// Clean up on exit119const cleanup = () => {120clearInterval(pingInterval);121stream.end();122};123124process.on('SIGINT', cleanup);125process.on('SIGTERM', cleanup);126127console.log('š Starting trades stream...');128});129}130131// Stream orders data132function streamOrders(client) {133return new Promise((resolve, reject) => {134const metadata = createMetadata();135136const stream = client.StreamData(metadata);137138stream.on('data', (response) => {139if (response.data) {140try {141const data = JSON.parse(response.data.data);142console.log(`š Orders Block ${response.data.block_number}:`);143console.log(JSON.stringify(data, null, 2));144} catch (error) {145console.log('ā ļø Failed to parse order data:', error.message);146}147}148});149150stream.on('error', (error) => {151console.error('ā Stream error:', error.message);152reject(error);153});154155stream.on('end', () => {156console.log('Orders stream ended');157resolve();158});159160// Send subscription request for orders161stream.write({162subscribe: {163stream_type: 'ORDERS',164filters: {}165}166});167168console.log('š Starting orders stream...');169});170}171172// Interactive menu173function showMenu() {174console.log('\nš Connected successfully!');175console.log('\nAvailable streams:');176console.log('1. All trades');177console.log('2. Filtered trades (BTC, ETH)');178console.log('3. Orders');179console.log('4. Test ping');180console.log('5. Exit');181182const readline = require('readline');183const rl = readline.createInterface({184input: process.stdin,185output: process.stdout186});187188return new Promise((resolve) => {189rl.question('\nSelect stream (1-5): ', (choice) => {190rl.close();191resolve(choice);192});193});194}195196// Stream filtered trades197function streamFilteredTrades(client, coins) {198return new Promise((resolve, reject) => {199const metadata = createMetadata();200201const stream = client.StreamData(metadata);202203stream.on('data', (response) => {204if (response.data) {205try {206const data = JSON.parse(response.data.data);207const trades = data.trades || [];208209if (trades.length > 0) {210console.log(`š Filtered Block ${response.data.block_number}: ${trades.length} trades`);211console.log(JSON.stringify(data, null, 2));212}213} catch (error) {214console.log('ā ļø Failed to parse data:', error.message);215}216}217});218219stream.on('error', (error) => {220console.error('ā Stream error:', error.message);221reject(error);222});223224stream.on('end', () => {225console.log('Filtered stream ended');226resolve();227});228229// Send filtered subscription230stream.write({231subscribe: {232stream_type: 'TRADES',233filters: {234coin: { values: coins }235}236}237});238239console.log(`š Starting filtered trades stream for coins: ${coins.join(', ')}`);240});241}242243// Main function244async function main() {245try {246console.log(`Testing connection to: ${GRPC_ENDPOINT}`);247248// Create client249const client = createClient();250251// Test initial connectivity252await testPing(client);253254// Show interactive menu255while (true) {256const choice = await showMenu();257258switch (choice) {259case '1':260await streamTrades(client);261break;262case '2':263await streamFilteredTrades(client, ['BTC', 'ETH']);264break;265case '3':266await streamOrders(client);267break;268case '4':269await testPing(client);270break;271case '5':272console.log('š Goodbye!');273client.close();274return;275default:276console.log('ā Invalid choice. Please select 1-5.');277}278}279280} catch (error) {281console.error('ā Error:', error.message);282process.exit(1);283}284}285286// Run the application287main();
1import grpc2import json3import time4import signal5import sys6import threading7from pb import streaming_pb2, streaming_pb2_grpc89# Configuration10GRPC_ENDPOINT = 'your-endpoint.hype-mainnet.quiknode.pro:10000'11AUTH_TOKEN = 'your-auth-token'1213def create_channel():14"""Create gRPC channel with TLS"""15credentials = grpc.ssl_channel_credentials()16channel = grpc.secure_channel(17GRPC_ENDPOINT,18credentials,19options=[20('grpc.max_receive_message_length', 100 * 1024 * 1024), # 100MB21('grpc.max_send_message_length', 100 * 1024 * 1024), # 100MB22]23)24return channel2526def create_metadata():27"""Create metadata with auth token"""28return [('x-token', AUTH_TOKEN)]2930def test_ping(stub):31"""Test connectivity with ping"""32try:33metadata = create_metadata()34request = streaming_pb2.PingRequest(count=1)3536response = stub.Ping(request, metadata=metadata)37print(f"ā Ping successful: {response}")38return True39except grpc.RpcError as e:40print(f"ā Ping failed: {e.details()}")41return False4243def stream_trades(stub):44"""Stream trades data"""45try:46metadata = create_metadata()4748print("š Starting trades stream...")4950# Create request generator for bidirectional stream51def request_generator():52# Send initial subscription request53subscribe_request = streaming_pb2.SubscribeRequest()54subscribe_request.subscribe.stream_type = streaming_pb2.StreamType.TRADES55# An empty filters map means receive all events for this stream type56yield subscribe_request5758# Keep sending pings to maintain connection59while True:60time.sleep(30)61ping_request = streaming_pb2.SubscribeRequest()62ping_request.ping.timestamp = int(time.time() * 1000)63yield ping_request6465# Create bidirectional stream66stream = stub.StreamData(request_generator(), metadata=metadata)6768# Handle stream responses69for response in stream:70try:71if response.HasField('data'):72data = json.loads(response.data.data)73trades = data.get('trades', [])7475print(f"š Block {response.data.block_number}: {len(trades)} trades")7677# Pretty print first trade if available78if trades:79print(f" Example trade: {json.dumps(trades[0], indent=2)}")8081elif response.HasField('pong'):82print(f"š Pong received: {response.pong.timestamp}")8384except json.JSONDecodeError as e:85print(f"ā ļø Failed to parse data: {e}")86except KeyboardInterrupt:87print("\nā¹ļø Stream interrupted by user")88break8990except grpc.RpcError as e:91print(f"ā Stream error: {e.details()}")92except KeyboardInterrupt:93print("\nā¹ļø Stream interrupted by user")9495def stream_orders(stub):96"""Stream orders data"""97try:98metadata = create_metadata()99100print("š Starting orders stream...")101102# Create request generator for bidirectional stream103def request_generator():104# Send initial subscription request for orders105subscribe_request = streaming_pb2.SubscribeRequest()106subscribe_request.subscribe.stream_type = streaming_pb2.StreamType.ORDERS107yield subscribe_request108109# Keep sending pings to maintain connection110while True:111time.sleep(30)112ping_request = streaming_pb2.SubscribeRequest()113ping_request.ping.timestamp = int(time.time() * 1000)114yield ping_request115116# Create bidirectional stream117stream = stub.StreamData(request_generator(), metadata=metadata)118119# Handle stream responses120for response in stream:121try:122if response.HasField('data'):123data = json.loads(response.data.data)124print(f"š Orders Block {response.data.block_number}:")125print(json.dumps(data, indent=2))126127except json.JSONDecodeError as e:128print(f"ā ļø Failed to parse order data: {e}")129except KeyboardInterrupt:130print("\nā¹ļø Stream interrupted by user")131break132133except grpc.RpcError as e:134print(f"ā Stream error: {e.details()}")135except KeyboardInterrupt:136print("\nā¹ļø Stream interrupted by user")137138def stream_filtered_trades(stub, coins):139"""Stream filtered trades for specific coins"""140try:141metadata = create_metadata()142143print(f"š Starting filtered trades stream for coins: {', '.join(coins)}")144145# Create request generator for bidirectional stream146def request_generator():147# Send filtered subscription request148subscribe_request = streaming_pb2.SubscribeRequest()149subscribe_request.subscribe.stream_type = streaming_pb2.StreamType.TRADES150subscribe_request.subscribe.filters["coin"].values.extend(coins)151yield subscribe_request152153# Keep sending pings to maintain connection154while True:155time.sleep(30)156ping_request = streaming_pb2.SubscribeRequest()157ping_request.ping.timestamp = int(time.time() * 1000)158yield ping_request159160# Create bidirectional stream161stream = stub.StreamData(request_generator(), metadata=metadata)162163# Handle stream responses164for response in stream:165try:166if response.HasField('data'):167data = json.loads(response.data.data)168trades = data.get('trades', [])169170if trades:171print(f"š Filtered Block {response.data.block_number}: {len(trades)} trades")172print(json.dumps(data, indent=2))173174except json.JSONDecodeError as e:175print(f"ā ļø Failed to parse data: {e}")176except KeyboardInterrupt:177print("\nā¹ļø Stream interrupted by user")178break179180except grpc.RpcError as e:181print(f"ā Stream error: {e.details()}")182except KeyboardInterrupt:183print("\nā¹ļø Stream interrupted by user")184185186def show_menu():187"""Display interactive menu"""188print("\nš Connected successfully!")189print("\nAvailable streams:")190print("1. All trades")191print("2. Filtered trades (BTC, ETH)")192print("3. Orders")193print("4. Test ping")194print("5. Exit")195196while True:197try:198choice = input("\nSelect stream (1-5): ").strip()199if choice in ['1', '2', '3', '4', '5']:200return choice201else:202print("ā Invalid choice. Please select 1-5.")203except KeyboardInterrupt:204return '5'205206def main():207"""Main function"""208try:209print(f"Testing connection to: {GRPC_ENDPOINT}")210211# Create channel and stub212channel = create_channel()213streaming_stub = streaming_pb2_grpc.StreamingStub(channel)214215# Test initial connectivity216if not test_ping(streaming_stub):217print("ā Connection test failed!")218return219220# Interactive menu loop221while True:222choice = show_menu()223224if choice == '1':225stream_trades(streaming_stub)226elif choice == '2':227stream_filtered_trades(streaming_stub, ['BTC', 'ETH'])228elif choice == '3':229stream_orders(streaming_stub)230elif choice == '4':231test_ping(streaming_stub)232elif choice == '5':233print("š Goodbye!")234break235236# Close channel237channel.close()238239except KeyboardInterrupt:240print("\nš Goodbye!")241except Exception as e:242print(f"ā Error: {e}")243sys.exit(1)244245if __name__ == "__main__":246main()
1import grpc2import json3import time4import signal5import sys6import threading7from pb import streaming_pb2, streaming_pb2_grpc89# Configuration10GRPC_ENDPOINT = 'your-endpoint.hype-mainnet.quiknode.pro:10000'11AUTH_TOKEN = 'your-auth-token'1213def create_channel():14"""Create gRPC channel with TLS"""15credentials = grpc.ssl_channel_credentials()16channel = grpc.secure_channel(17GRPC_ENDPOINT,18credentials,19options=[20('grpc.max_receive_message_length', 100 * 1024 * 1024), # 100MB21('grpc.max_send_message_length', 100 * 1024 * 1024), # 100MB22]23)24return channel2526def create_metadata():27"""Create metadata with auth token"""28return [('x-token', AUTH_TOKEN)]2930def test_ping(stub):31"""Test connectivity with ping"""32try:33metadata = create_metadata()34request = streaming_pb2.PingRequest(count=1)3536response = stub.Ping(request, metadata=metadata)37print(f"ā Ping successful: {response}")38return True39except grpc.RpcError as e:40print(f"ā Ping failed: {e.details()}")41return False4243def stream_trades(stub):44"""Stream trades data"""45try:46metadata = create_metadata()4748print("š Starting trades stream...")4950# Create request generator for bidirectional stream51def request_generator():52# Send initial subscription request53subscribe_request = streaming_pb2.SubscribeRequest()54subscribe_request.subscribe.stream_type = streaming_pb2.StreamType.TRADES55# An empty filters map means receive all events for this stream type56yield subscribe_request5758# Keep sending pings to maintain connection59while True:60time.sleep(30)61ping_request = streaming_pb2.SubscribeRequest()62ping_request.ping.timestamp = int(time.time() * 1000)63yield ping_request6465# Create bidirectional stream66stream = stub.StreamData(request_generator(), metadata=metadata)6768# Handle stream responses69for response in stream:70try:71if response.HasField('data'):72data = json.loads(response.data.data)73trades = data.get('trades', [])7475print(f"š Block {response.data.block_number}: {len(trades)} trades")7677# Pretty print first trade if available78if trades:79print(f" Example trade: {json.dumps(trades[0], indent=2)}")8081elif response.HasField('pong'):82print(f"š Pong received: {response.pong.timestamp}")8384except json.JSONDecodeError as e:85print(f"ā ļø Failed to parse data: {e}")86except KeyboardInterrupt:87print("\nā¹ļø Stream interrupted by user")88break8990except grpc.RpcError as e:91print(f"ā Stream error: {e.details()}")92except KeyboardInterrupt:93print("\nā¹ļø Stream interrupted by user")9495def stream_orders(stub):96"""Stream orders data"""97try:98metadata = create_metadata()99100print("š Starting orders stream...")101102# Create request generator for bidirectional stream103def request_generator():104# Send initial subscription request for orders105subscribe_request = streaming_pb2.SubscribeRequest()106subscribe_request.subscribe.stream_type = streaming_pb2.StreamType.ORDERS107yield subscribe_request108109# Keep sending pings to maintain connection110while True:111time.sleep(30)112ping_request = streaming_pb2.SubscribeRequest()113ping_request.ping.timestamp = int(time.time() * 1000)114yield ping_request115116# Create bidirectional stream117stream = stub.StreamData(request_generator(), metadata=metadata)118119# Handle stream responses120for response in stream:121try:122if response.HasField('data'):123data = json.loads(response.data.data)124print(f"š Orders Block {response.data.block_number}:")125print(json.dumps(data, indent=2))126127except json.JSONDecodeError as e:128print(f"ā ļø Failed to parse order data: {e}")129except KeyboardInterrupt:130print("\nā¹ļø Stream interrupted by user")131break132133except grpc.RpcError as e:134print(f"ā Stream error: {e.details()}")135except KeyboardInterrupt:136print("\nā¹ļø Stream interrupted by user")137138def stream_filtered_trades(stub, coins):139"""Stream filtered trades for specific coins"""140try:141metadata = create_metadata()142143print(f"š Starting filtered trades stream for coins: {', '.join(coins)}")144145# Create request generator for bidirectional stream146def request_generator():147# Send filtered subscription request148subscribe_request = streaming_pb2.SubscribeRequest()149subscribe_request.subscribe.stream_type = streaming_pb2.StreamType.TRADES150subscribe_request.subscribe.filters["coin"].values.extend(coins)151yield subscribe_request152153# Keep sending pings to maintain connection154while True:155time.sleep(30)156ping_request = streaming_pb2.SubscribeRequest()157ping_request.ping.timestamp = int(time.time() * 1000)158yield ping_request159160# Create bidirectional stream161stream = stub.StreamData(request_generator(), metadata=metadata)162163# Handle stream responses164for response in stream:165try:166if response.HasField('data'):167data = json.loads(response.data.data)168trades = data.get('trades', [])169170if trades:171print(f"š Filtered Block {response.data.block_number}: {len(trades)} trades")172print(json.dumps(data, indent=2))173174except json.JSONDecodeError as e:175print(f"ā ļø Failed to parse data: {e}")176except KeyboardInterrupt:177print("\nā¹ļø Stream interrupted by user")178break179180except grpc.RpcError as e:181print(f"ā Stream error: {e.details()}")182except KeyboardInterrupt:183print("\nā¹ļø Stream interrupted by user")184185186def show_menu():187"""Display interactive menu"""188print("\nš Connected successfully!")189print("\nAvailable streams:")190print("1. All trades")191print("2. Filtered trades (BTC, ETH)")192print("3. Orders")193print("4. Test ping")194print("5. Exit")195196while True:197try:198choice = input("\nSelect stream (1-5): ").strip()199if choice in ['1', '2', '3', '4', '5']:200return choice201else:202print("ā Invalid choice. Please select 1-5.")203except KeyboardInterrupt:204return '5'205206def main():207"""Main function"""208try:209print(f"Testing connection to: {GRPC_ENDPOINT}")210211# Create channel and stub212channel = create_channel()213streaming_stub = streaming_pb2_grpc.StreamingStub(channel)214215# Test initial connectivity216if not test_ping(streaming_stub):217print("ā Connection test failed!")218return219220# Interactive menu loop221while True:222choice = show_menu()223224if choice == '1':225stream_trades(streaming_stub)226elif choice == '2':227stream_filtered_trades(streaming_stub, ['BTC', 'ETH'])228elif choice == '3':229stream_orders(streaming_stub)230elif choice == '4':231test_ping(streaming_stub)232elif choice == '5':233print("š Goodbye!")234break235236# Close channel237channel.close()238239except KeyboardInterrupt:240print("\nš Goodbye!")241except Exception as e:242print(f"ā Error: {e}")243sys.exit(1)244245if __name__ == "__main__":246main()
Don't have an account yet?
Create your Quicknode endpoint in seconds and start building
Get started for free