@Maxpeinas, that's correct, you have to use websocket provider in order to subscribe to events in web3.js 1.0 via myContract.events.MyEvent()
So, if you are using local TestRPC go with
const web3 = new Web3('ws://127.0.0.1:8545');
If you are using remote endpoint - change it to ws, for example - Infura already have working websocket endpoints for the main and the test networks, you can use them like this:
const web3 = new Web3('wss://ropsten.infura.io/ws');
I would guess that this will be the main 'problem' for developers which have used 0.2 with regular httpProvider and .watch()
, since nowhere in the official web3.js 1.0 documentation for the event methods is not yet mentioned that you will need connect to websocket endpoint in order to subscribe for the EventEmitter.
If you are more experienced maybe you will be able to think of it, as the recommended provider in 1.0.0 docs is ws://127.0.0.1 instead of http://127.0.0.1, however there will be people that will wonder why their http event subscriber doesn't work.
Note: As opposed to myContract.events.myEvent()
, you are able to use myContract.getPastEvents()
with regular http provider with no problems, since it only fetches old logs and doesn't wait for new ones.
You can use the NodeJS script below for testing whether or not your Parity node is synced and ready to receive requests.
Run it as a process next to your Parity process (i.e., on the same machine).
This process is essentially an HTTP server, which communicates with the Parity process on one port, and with your HTTP client (e.g., browser) on another port.
Execution: run node check.js SERVER_PORT NODE_ADDRESS ETHERSCAN_KEY SYNC_THRESHOLD
.
You can generate your ETHERSCAN_KEY
as follows:
By the way, this key is good for both Ropsten (test-net) and Homestead (main-net).
For SYNC_THRESHOLD
, you can use 10 for now, and figure out later the best value to use. This parameter indicates the permitted difference between the Parity node's current block and the highest block on the chain (which we obtain from etherscan.io). If the difference between these two values is SYNC_THRESHOLD
or less, then the Parity node is ready to receive requests, and the server will return 200. Otherwise, the Parity node is not ready to receive requests, and the server will return 500.
let Web3 = require("web3");
let http = require("http");
let request = require("request");
let SERVER_PORT = process.argv[2];
let NODE_ADDRESS = process.argv[3];
let ETHERSCAN_KEY = process.argv[4];
let SYNC_THRESHOLD = process.argv[5];
let server = http.createServer(async function(externalRequest, externalResponse) {
request.get("https://api-ropsten.etherscan.io/api?module=proxy&action=eth_blockNumber&apikey=" + ETHERSCAN_KEY, async function (error, response, body) {
let externalResponseCode;
let externalResponseBody;
if (error) {
externalResponseCode = 500;
externalResponseBody = "error: " + error;
}
else if (!response) {
externalResponseCode = 500;
externalResponseBody = "no response";
}
else if (response.statusCode != 200) {
externalResponseCode = 500;
externalResponseBody = "bad response";
}
else {
let web3 = new Web3(NODE_ADDRESS);
let currentBlock = await web3.eth.getBlockNumber();
let highestBlock = parseInt(JSON.parse(body).result);
if (web3.currentProvider.constructor.name == "WebsocketProvider")
web3.currentProvider.connection.close();
externalResponseCode = highestBlock - currentBlock > parseInt(SYNC_THRESHOLD) ? 500 : 200;
externalResponseBody = `currentBlock = ${currentBlock}, highestBlock = ${highestBlock}`;
}
console.log(externalResponseCode, externalResponseBody);
externalResponse.statusCode = externalResponseCode;
externalResponse.end(externalResponseBody);
});
});
server.listen(SERVER_PORT, async function(error) {
if (error)
return console.log(error);
console.log(`server is listening on port ${SERVER_PORT}`);
});
Best Answer
In order to subscribe to events, you need a Websocket endpoint. This is your code updated to use WSS:
Also, if you want to list pending transactions, you can use something like this:
You can use Chainstack to get HTTP and WSS endpoints to multiple blockchain protocols.