> ## 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.

# Smart Contract Events

Contract events are a key feature of blockchain systems, enabling applications to react to specific state changes in an efficient manner. On peaq network, **chain events** can be emitted during contract execution and logged to the blockchain.
These events can be captured and parsed to **build responsive dApps**, **monitor activity**, or **trigger off-chain workflows**.

This guide provides step-by-step instructions on how to listen to and parse **smart contract events** on the peaq network.

## Prerequisites

1. You have a working knowledge of Ethereum-based networks and EVM-compatible smart contracts.
2. You have deployed a smart contract on the peaq network that emits events.
3. You are using **ethers.js** or **web3.js** in a JavaScript or Node.js environment.
4. You have access to a **peaq network RPC endpoint** (e.g., [https://quicknode.peaq.xyz](https://quicknode.peaq.xyz)).
5. You know the [**ABI**](https://www.alchemy.com/overviews/what-is-an-abi-of-a-smart-contract-examples-and-usage) of the contract you are monitoring and the address of the deployed contract.

## Instructions

### 1. Set Up Your Project

Ensure your environment is set up with the necessary libraries and RPC configuration:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
npm install ethers
```

### 2. Initialize Connection to the peaq Network

Connect to the peaq network using ethers.js:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider("https://quicknode.peaq.xyz");
```

### 3. Load the Smart Contract

To interact with the smart contract, load its address and ABI:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
const contractAddress = "0xYourContractAddress"; // Replace with your smart contract's address
const contractABI = [
  // Add your contract's ABI here or import with require() instead
];

const contract = new ethers.Contract(contractAddress, contractABI, provider);
```

### 4. Listen for Events

Using ethers.js, you can set up listeners for specific events emitted by the contract:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
contract.on("YourEventName", (param1, param2, event) => {
  console.log(`Event received:`);
  console.log(`Param 1: ${param1}`);
  console.log(`Param 2: ${param2}`);
  console.log(`Full Event:`, event);
});
```

### 5. Parse Events

Ethers.js provides the raw event log data, which can be parsed for additional details:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
provider.on("logs", (log) => {
  try {
    const parsedLog = contract.interface.parseLog(log);
    console.log("Parsed Log:", parsedLog);
  } catch (err) {
    console.log("Not a relevant event:", err);
  }
});
```

### 6. Filter Specific Events

To reduce overhead, use filters to listen for specific events:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
const filter = contract.filters.YourEventName(); // Add any indexed parameters if applicable

provider.on(filter, (log) => {
  const parsedLog = contract.interface.parseLog(log);
  console.log(`Filtered Event: ${parsedLog.name}`);
  console.log(`Event Data:`, parsedLog.args);
});
```

### 7. Testing the Listener

Trigger events in your smart contract (e.g., using a wallet or script) and ensure the listener captures them correctly.
**Example:** Emit an event in your smart contract:

```solidity theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
event YourEventName(address indexed user, uint256 value);
emit YourEventName(msg.sender, 1000);
```

Expected console output:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
Console Logs Example
...................
Event received:
Param 1: 0xYourWalletAddress
Param 2: 1000
Full Event: {...}
```

Example final boilerplate incorporating previous steps, best practices for environment variables, and  modular imports:

### Putting it all Together

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

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

  import { ethers } from "ethers";

  // Load environment variables
  const RPC_URL = process.env.PEAQ_RPC_URL || "https://quicknode.peaq.xyz"; // Replace with your preferred peaq RPC URL
  const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS; // Replace with your contract address
  import CONTRACT_ABI from "./contract_abi.json"; // Replace with the path to your contract ABI JSON file

  // Initialize provider and contract
  const provider = new ethers.JsonRpcProvider(RPC_URL);
  const contract = new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider);

  // Function to listen for events
  const listenForEvents = () => {
    console.log("Listening for events on contract:", CONTRACT_ADDRESS);

    // Replace "YourEventName" with the event name from your contract ABI
    contract.on("YourEventName", (param1, param2, event) => {
      console.log("Event Received:");
      console.log(`Param 1: ${param1}`);
      console.log(`Param 2: ${param2}`);
      console.log("Raw Event Data:", event);
    });

    // Add a generic log listener (optional)
    provider.on("logs", (log) => {
      try {
        const parsedLog = contract.interface.parseLog(log);
        console.log("Parsed Event Log:");
        console.log(parsedLog);
      } catch (error) {
        // Not a relevant event, ignore
      }
    });
  };

  // Error handling and script execution
  const main = async () => {
    try {
      listenForEvents();
    } catch (error) {
      console.error("Error in event listener:", error);
      process.exit(1);
    }
  };

  main();
  ```
</CodeGroup>

## **Tips**

1. **Error Handling**: Always handle potential errors (e.g., connectivity issues, unexpected logs).

2. **Batch Processing**: Use a combination of historical event fetching (`getLogs`) and real-time listeners to ensure no data loss.

3. **Indexed Parameters**: Use indexed parameters in your contract events to filter by specific values (e.g., filter by user address).
   **Example:**

   ```solidity theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
   event YourEventName(address indexed user, uint256 value);
   ```

   Then filter by the address:

   ```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
   const filter = contract.filters.YourEventName("0xSpecificAddress");
   ```

4. **Environment Variables**: Store sensitive information (e.g., RPC URLs) in environment variables using a `.env` file.

Congratulations! 🎉 You now have the ability to efficiently listen to and parse smart contract events on the peaq network, empowering your dApp to respond dynamically to on-chain activity.
