Skip to main content

Subscribe GetNodes

Since we are connected successfully to the Watchtower service, we can stream down available nodes from the HCS. See the protobuf definition.

Payload Static Reference
export interface FileID {  'shardNum'?: (number | string | Long);  'realmNum'?: (number | string | Long);  'fileNum'?: (number | string | Long);}export interface GetNodesQuery {  'fileId'?: (FileID | null);  'limit'?: (number);}export interface SubscribeGetNodesPayload {  subscribe: string;  body: GetNodesQuery;}const subscribeTopicRoute = `/com.hedera.mirror.api.proto.NetworkService/getNodes`;const payloadBody: GetNodesQuery = {  fileId: {    fileNum: '101' // The ID of the address book file on the network. Can be either 101 or 102.  },  limit: 100 // The maximum number of node addresses to receive before stopping. If not set or set to zero it will return all node addresses in the database.}const payload: SubscribeGetNodesPayload = {  subscribe: subscribeTopicRoute,  body: payloadBody}
Payload breakdown

To subscribe this stream, our payload should match reference protobuf definition.

View Definition
/** * Request object to query an address book for its list of nodes */message AddressBookQuery {    /**     * The ID of the address book file on the network. Can be either 0.0.101 or 0.0.102.     */    .proto.FileID file_id = 1;    /**     * The maximum number of node addresses to receive before stopping. If not set or set to zero it will return all node addresses in the database.     */    int32 limit = 2;}

By looking into the defination, we can see that we need to provide a FileID and limit (optional) to get the latest messages.

For forming the payload, we should also be aware of basic_types.proto used in the defination.

View Definition
//** * The ID for a file  */message FileID {    /**     * The shard number (nonnegative)     */    int64 shardNum = 1;    /**     * The realm number (nonnegative)     */    int64 realmNum = 2;    /**     * A nonnegative File number unique within its realm     */    int64 fileNum = 3;}

All we need is to build a payload as below:

import React, { useEffect, useState } from "react";import io from 'socket.io-client';function StreamingInit () {  // Make sure you match the url for testnet/mainnet   const demoFileId = `102`; // The ID of the address book file on the network. Can be either 101 or 102.  const watchtowerURL = `wss://<WATCHTOWER_URL>?api_key=<ARKHIA_API_KEY>`;  const socket = io(watchtowerURL);  const [socketStatus, setSocketStatus] = useState(``);  const [socketConnect, setSocketConnect] = useState(false);  // Available services in page 2 of these docs  const subscribeGetNodesRoute = `/com.hedera.mirror.api.proto.NetworkService/getNodes`;  const getSubscriptionPayload =  (file_id: string, limit: string) => {      const subscriptionPayload = {          subscribe: subscribeGetNodesRoute,          body: {              fileId: {                  fileNum: file_id // The ID of the address book file on the network. Can be either 101 or 102.              },              limit // The maximum number of node addresses to receive before stopping. If not set or set to zero it will return all node addresses in the database.          }      };  };  const subscribeGetNodes = () => {      const requestPayload =  getSubscriptionPayload(demoFileId , `100`); // get latest 100      socket.emit(`subscribe`, requestPayload, (msg: any) => {                     console.log(`GetNodes streaming down...`);          socket.on(msg.listeners.data, function (message: any) {              console.log(message)          });          socket.on(msg.listeners.error, function (message: any) {              setSocketError(message);              console.log(`Error`);              console.log(message)          });      });  };  useEffect(() => {      socket.on(`connect`, () => {          setSocketConnect(true);          socket.on(`status`, (msg) => {              console.log(`status`, msg);              setSocketStatus(`Watchtower is successfully connected`);          });          socket.emit(`list-services`, (services: any) => {              console.log(`Listing available services`, services);          });      });      socket.on(`disconnect`, (msg: any) => {          setSocketConnect(false);          setSocketStatus(`Watchtower is disconnected.`)          console.log(`Disconnected.`)      });      socket.on(`error`, (message: any) => {          setSocketConnect(false);          console.error(message);          setSocketStatus(message)      })  }, [socket]);  return (      <>          <div>              {                  socketStatus && (                      <>                          <h6>Watchtower status</h6>                          <div>{socketStatus}</div>                      </>                  )              }              {                  socketConnect &&  (                      <>                         <button onClick={subscribeGetNodes}>                      </>                  )              }          </div>      </>  );}export default StreamingInit;