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

# eth_newFilter + eth_getFilterChanges

In blockchain systems, **logs** are low-level events generated by contracts and system actions that can provide insights into on-chain activity.
Unlike block headers or pending transactions, logs can capture **specific events** or **state changes**, which are useful for debugging, monitoring, and analytics.

Using the JSON-RPC method `eth_newFilter`, you can create a filter on the node that watches for new log events. Then, by periodically calling `eth_getFilterChanges`, you can poll the
node for any new logs that match your filter criteria. This **push-poll model** (as opposed to a true push subscription) is especially useful when the node does not offer a native subscription for logs.

In the provided **boilerplate**:

* A **log filter** is created with the parameter `{ fromBlock: "latest" }` so that only logs from the current block onward are captured.
* The code then polls for changes every 5 seconds by calling **`eth_getFilterChanges`** with the filter ID.
* Each received log is then printed to the console.
* The boilerplate also includes error handling and a graceful shutdown routine that uninstalls the filter and disconnects the WebSocket provider.

## Prerequisites

* **Node.js Environment:** You are running this code in a Node.js environment.
* **Dependencies:** The following packages are installed:
  * `web3` (v4.x)
  * `web3-providers-ws`
  * `dotenv`
* **WebSocket Endpoint:** You are connecting to the peaq network via the WebSocket endpoint `https://quicknode.peaq.xyz`, configured via a `.env` file.
* **Basic Understanding:** You have a basic understanding of JSON‑RPC, WebSocket connections, and blockchain logs.

## Instructions

### 1. Setting Up the Environment

* **Install Dependencies:**
  Make sure you install the necessary packages:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npm install web3 dotenv web3-providers-ws
```

* **Set ESM Module:**
  Add the following to your `package.json` to alllow for ESM modules.

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
"type": "module",
```

* **Configure Environment Variables:**
  Create a `.env` file in your project directory with:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
PEAQ_WS_URL=wss://quicknode.peaq.xyz
```

### 2. Creating the Log Filter

* **Using eth\_newFilter:** The method `eth_newFilter` creates a filter on the node to watch for specific log events. In our boilerplate, we call it with parameters like `{ fromBlock: "latest" }` to capture logs from the most recent block onward. The node responds with a filter ID that uniquely identifies this filter.

### 3. Polling for Log Changes

* **Using eth\_getFilterChanges:** Once the filter is created, you poll for changes by calling `eth_getFilterChanges` with the **filter ID**. This method returns any logs that have been recorded since the last poll. The code uses a polling interval (5 seconds in this example) to check for new logs **continuously**.
* **Processing Logs:** Each new log returned by `eth_getFilterChanges` is iterated over and printed to the console. This allows your application to process each event as needed.

### 4. Error Handling

* **During Filter Creation and Polling:** Both the creation of the filter and the polling calls include error checks. If an error occurs (or if the node returns an error), the error is logged to the console. This ensures that issues such as network problems or incorrect parameters are surfaced immediately.

### 5. Graceful Shutdown

* **Uninstalling the Filter:** Upon receiving a **shutdown signal** (e.g., Ctrl+C), the code sends a JSON‑RPC request using **`eth_uninstallFilter`** with the filter ID. This uninstalls the filter from the node, ensuring that resources are freed.
* **Disconnecting the Provider:** After uninstalling the filter, the WebSocket provider is disconnected to cleanly close the connection before the process exits.

## Code Example

<CodeGroup>
  ```javascript JavaScript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
  // eth_filter_logs.js

  import dotenv from 'dotenv';
  dotenv.config();

  import Web3 from 'web3';
  import WSProvider from 'web3-providers-ws';

  const WS_URL = process.env.PEAQ_WS_URL;
  const provider = new WSProvider(WS_URL);
  const web3 = new Web3(provider);

  let logFilterId = null;

  // Create a log filter using a raw JSON-RPC call
  provider.send(
    {
      jsonrpc: "2.0",
      method: "eth_newFilter",
      params: [{ fromBlock: "latest" }],
      id: 1,
    },
    (error, response) => {
      if (error || response.error) {
        console.error("Error creating log filter:", error || response.error);
        return;
      }
      logFilterId = response.result;
      console.log("Created log filter with ID:", logFilterId);

      // Start polling for log changes every 5 seconds
      setInterval(() => {
        provider.send(
          {
            jsonrpc: "2.0",
            method: "eth_getFilterChanges",
            params: [logFilterId],
            id: 2,
          },
          (err, res) => {
            if (err || res.error) {
              console.error("Error polling log filter:", err || res.error);
              return;
            }
            if (res.result && res.result.length > 0) {
              res.result.forEach((log) => {
                console.log("Chain Log received:");
                console.log(log);
              });
            }
          }
        );
      }, 5000);
    }
  );

  // Graceful shutdown
  process.on('SIGINT', () => {
    console.log("\nGracefully shutting down...");
    if (logFilterId) {
      provider.send(
        {
          jsonrpc: "2.0",
          method: "eth_uninstallFilter",
          params: [logFilterId],
          id: 3,
        },
        (error, response) => {
          if (error || response.error) {
            console.error("Error uninstalling log filter:", error || response.error);
          } else {
            console.log("Uninstalled log filter:", logFilterId);
          }
          provider.disconnect();
          process.exit();
        }
      );
    } else {
      provider.disconnect();
      process.exit();
    }
  });

  console.log("Listening for chain logs on the peaq network (eth_newFilter + eth_getFilterChanges)...");

  ```
</CodeGroup>

### Example logs:

<img src="https://mintcdn.com/peaq/bfUMfJGiNN2sOYvn/assets/img/eth-new-filter-1.png?fit=max&auto=format&n=bfUMfJGiNN2sOYvn&q=85&s=cbf6329f627a168034e41d446daf874f" alt="eth-new-filter-1" width="1111" height="1326" data-path="assets/img/eth-new-filter-1.png" />

## Summary

This guide has demonstrated how to listen and parse chain log events on the peaq network using a combination of `eth_newFilter` and `eth_getFilterChanges`.

By using these methods, you can efficiently monitor **chain logs**, enabling real-time analysis and responsive applications on the peaq network.
This approach is especially useful when native log subscriptions are not available or when you prefer a controlled polling mechanism. Customize the provided boilerplate as needed to suit your application's requirements.
