I’m developing a small web3 app using Ethereum Sepolia testnet, nodejs v21, web3js v4 and Infura API. I have the following smart contrcat deployed, that emits events:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract testContract {
address public admin;
bool public paused = false;
event Paused(bool isPaused);
modifier onlyAdmin() {
require(msg.sender == admin, "Only admin can call this function");
_;
}
constructor() {
admin = msg.sender;
}
function togglePause() external onlyAdmin {
paused = !paused;
emit Paused(paused);
}
}
I can intercat normally with the contract and I can see the events using Etherscan or a similar tool. Then I Have the node js program, that basically only tries to subscribe to the events:
const path = require('path');
const dotenvPath = path.resolve(__dirname, 'file.env');
require('dotenv').config({ path: path.resolve(__dirname, 'file.env') });
const { Web3 } = require('web3');
const mqtt = require('mqtt');
const rpcURL = process.env.RPC_URL; // e.g., "https://sepolia.infura.io/v3/your_infura_project_id"
const contractAddress = process.env.CONTRACT_ADDRESS; // e.g., "0xYourContractAddressHere"
const mqttBrokerUrl = process.env.MQTT_BROKER_URL || 'mqtt://localhost';
const provider = new Web3.providers.WebsocketProvider(rpcURL, {
clientConfig: {
keepalive: true,
keepaliveInterval: 60000 // 60 seconds
},
reconnect: {
auto: true,
delay: 5000, // 5 seconds
maxAttempts: 5,
onTimeout: false
}
});
const web3 = new Web3(provider);
const abi = [Here goes the ABI]
const client = mqtt.connect(mqttBrokerUrl);
client.on('connect', () => {
console.log('MQTT client connected');
});
client.on('error', (error) => {
console.error('MQTT client error:', error);
process.exit(1); // Exit in case of MQTT connection error
});
provider.on('connect', () => {
console.log('WebSocket client connected');
subscribeToContractEvents().catch(console.error);
});
async function subscribeToContractEvents() {
try {
await contract.events.Paused({
fromBlock: 'latest'
})
.on('data', (event) => {
console.log("Event received:", event);
})
.on('error', console.error);
} catch (error) {
console.error('Error subscribing to events:', error);
}
}
provider.on('error', (error) => {
console.error('WebSocket error:', error);
});
provider.on('end', (error) => {
console.log('WebSocket connection ended:', error);
});
When I run the program i get the following error log when tries to subscribe to the event:
MQTT client connected
WebSocket client connected
Error subscribing to events: TypeError: Cannot read properties of undefined (reading 'on')
at subscribeToContractEvents (/home/rpi-blockchain/node/test1.js:60:9)
at EventEmitter.<anonymous> (/home/rpi-blockchain/node/test1.js:49:5)
at EventEmitter.emit (node:events:519:28)
at /home/rpi-blockchain/node/node_modules/web3-utils/lib/commonjs/web3_eip1193_provider.js:90:44
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
I have been around this for hours and can’t figure why I keep getting this error. I can even log the contract.events.Paused object that results in: [Function (anonymous)]