> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chainstack.com/llms.txt
> Use this file to discover all available pages before exploring further.

# subscribe ("syncing") | Avalanche

> Monitor Avalanche node sync status in real time with web3.js. Subscribe to syncing updates to track block download progress and chain synchronization.

## Parameters

* `string` — a keyword identifying the type of event to subscribe to, `logs` in this case.
* `function` — (optional) a callback function that will be called every time a new event of the specified type is received. This function takes two parameters: `error` and `result`. The error parameter contains any error that occurred while subscribing to the event, and the result parameter contains the data for the event that was received.

## Response

* `object` — the following sync object when the node is currently syncing:

  * `startingBlock` — the block number from which the node began syncing.
  * `currentBlock` — the latest block number the node has synced to.
  * `highestBlock` — the estimated highest block number that needs to be synced.
  * `pulledStates` — the number of state entries that have already been downloaded.
  * `knownStates` — the estimated number of state entries to be downloaded during the sync.

* `boolean` — returns `False` when the node is already in sync.

## `subscribe("syncing")` code example

<Info>
  Note that subscriptions require a WebSocket connection. Use a `WebSocketProvider` with ethers.js.
</Info>

ethers.js does not expose a dedicated `syncing` event, so use the WebSocketProvider to send the raw `eth_subscribe` request and listen for `eth_subscription` notifications on the underlying socket:

* `eth_subscription` notification — fires for each new syncing event.
* `error` — fires if an error is detected during the subscription.
* the subscription ID — returned by `eth_subscribe` after the subscription is successfully created.
* `eth_unsubscribe` — removes the subscription and returns `true` if successful.

<CodeGroup>
  ```javascript index.js theme={"system"}
  const { ethers } = require("ethers");
  const NODE_URL = "CHAINSTACK_WSS_URL";
  const provider = new ethers.WebSocketProvider(NODE_URL);

  async function subscribeToSync() {
      try {
          // Create a new subscription to the 'syncing' event
          const subscriptionId = await provider.send("eth_subscribe", ["syncing"]);
          handleConnected(subscriptionId);

          // Listen for subscription notifications on the underlying WebSocket
          provider.websocket.onmessage = (message) => {
              const payload = JSON.parse(message.data);
              if (payload.method === "eth_subscription" && payload.params.subscription === subscriptionId) {
                  handleSync(payload.params.result);
              }
          };

          provider.websocket.onerror = handleError;

      } catch (error) {
          console.error(`Error subscribing to sync: ${error}`);
      }
  }

  /* Fallback functions to react to the different events */

  // Event listener that logs a message when there is a new syncing event
  function handleConnected(subscriptionId) {
      console.log(`New subscription: ${subscriptionId}`);
  }

  // Event listener that logs the filtered events
  async function handleSync(sync) {
      console.log(sync)
  }

  // Event listener that logs any errors that occur
  function handleError(error) {
      console.error(`Error: ${error}`);
  }

  subscribeToSync();
  ```
</CodeGroup>

## Use case

A practical use case for `subscribe("syncing")` is a DApp that continuously listens for the status of a node and notifies the developer if the node falls behind a certain number of blocks.

The following is an implementation of this concept using ethers.js subscriptions, this program will leave a notification in the console if the node falls more than 100 blocks behind.

<CodeGroup>
  ```javascript index.js theme={"system"}
  const { ethers } = require("ethers");
  const NODE_URL = "CHAINSTACK_WSS_URL";
  const provider = new ethers.WebSocketProvider(NODE_URL);

  async function subscribeToSync() {
      try {
          // Create a new subscription to the 'syncing' event
          const subscriptionId = await provider.send("eth_subscribe", ["syncing"]);
          handleConnected(subscriptionId);

          // Listen for subscription notifications on the underlying WebSocket
          provider.websocket.onmessage = (message) => {
              const payload = JSON.parse(message.data);
              if (payload.method === "eth_subscription" && payload.params.subscription === subscriptionId) {
                  handleSync(payload.params.result);
              }
          };

          provider.websocket.onerror = handleError;

      } catch (error) {
          console.error(`Error: ${error}`);
      }
  }

  /* Fallback functions to react to the different events */

  // Event listener that logs a message when there is a new syncing event
  function handleConnected(subscriptionId) {
      console.log(`New subscription: ${subscriptionId}`);
  }

  // Event listener that logs the filtered events
  async function handleSync(sync) {
      let currentBlock;
      let highestBlock;
      const status = sync.status;

      for (const property in status) {
        if (property === 'CurrentBlock') {
          currentBlock = status[property];

        } else if (property === 'HighestBlock') {
          highestBlock = status[property];
        }
      }

      if (currentBlock !== undefined && highestBlock !== undefined) {
        const blocksBehind = highestBlock - currentBlock;
        console.log(`The node is ${blocksBehind} blocks behind the network.`);

        if (blocksBehind > 1000) {
          alert(`The node is ${blocksBehind} blocks behind the network. Please check your connection.`);
        }
      }
    }

  // Event listener that logs any errors that occur
  function handleError(error) {
      console.error(`Error receiving new blocks: ${error}`);
  }

  subscribeToSync();
  ```
</CodeGroup>

This code creates a new subscription to the `syncing` event using the `eth_subscribe` request sent through the `WebSocketProvider`. This returns a subscription ID that is used to match incoming notifications on the underlying WebSocket.

The code defines three event listener functions: `handleConnected`, `handleSync`, and `handleError`. The `handleConnected` function is called when the subscription is created, and it logs a message with the subscription ID. The `handleSync` function is called when a new syncing notification arrives, extracts the `CurrentBlock` and the `HighestBlock` field, and then compares them. If the node is more than 1,000 blocks behind, the user will receive an alert.

The `handleError` function is called when an error occurs, and it logs an error message.

Finally, the code calls the `subscribeToSync` function, which creates the subscription and attaches the event listeners. When a new event is received, the `handleSync` function is called to extract the data and log it to the console.
