visit
Decentralized Architecture
The decentralized nature of dRPC ensures a high availability because it’s available in different jurisdictions. Moreover, since it’s not run by a single entity, it has no single point of failure, i.e., if a node stops working, the infrastructure can automatically switch to other working nodes.
High Performance and Scalability
dRPC offers the ability to connect users' requests with the most efficient node for high performance and efficiency. The low latency and error probability allow requests to be processed quickly without error.
Analytical and Monitoring Dashboard
The dRPC platform offers a built-in analytical dashboard to monitor the features that allow developers to track the performance of their DApps in real-time. With this, you can optimize the RPC performance and discover, diagnose, and resolve issues quickly.
Note: For this project, we’ll be using VScode as our IDE
Node.JS: this is an open-source cross-platform JavaScript runtime environment used for executing JS codes on the server side. You can download and install Node.js from their official site. Installing it will include npm
, the node.js package manager you need for this project.
NPM (Node Package Manager): it’s a package manager for JavaScript runtime and provides an online repo for node.js packages/modules. It is usually automatically installed with node.js.
IDE (integrated development environment) like VScode, Notepad++, and Sublime Text. It’s a software app that lets developers write code efficiently.
Note: You need a basic understanding of JavaScript to use web3.js and dRPC.
npm init -y
The code above will initialize the node.js
package and create the package.json
file in the project directory.
cmd
or cmd.exe
in the run box and press the Enter key on your keyboard.
As we said above, web3.js
is a JavaScript library that makes it easier to interact with Ethereum and other EMV-compatible chains.
The dotenv
package is a zero-dependency module used to load the environmental variable .env
file you will create into the process.env
. The dotenv package helps keep your password, API key, and other sensitive information. When you store sensitive information outside your code base, dotenv
libraries ensure they are not checked into version control or mistakenly exposed.
Once the package.json
has been created, run the command below in your CLI to install dotenv
and web3.js
npm install web3 dotenv
This will add dotenv
and web3.js
to your project dependencies and create a node module directory. You can verify if the dependencies have been installed by going to the ‘package.json’ and checking the file under dependencies.
Configuring environmental variables is one of the most important best practices in software design and development. The .env
file helps protect your sensitive information. This file stores sensitive information like API keys outside the code base. You can create the .env
file through the Command Line Interface (CLI) or the IDE editor.
To create .env
file with the CLI:
.env
with the touch command.
Creating directly in the IDE editor:
Create a new file and name it .env
To get the environmental variable needed for this project,
Note: For this project, we’ll be using the Ethereum Mainnet Endpoint and the WebSocket connection, and here is how your environmental variables should look like:
DRPC_URL=wss://your-drpc-endpoint
API_KEY=your-api-key
require('dotenv').config();
This line of code above initializes the dotenv
package to load the environmental variable we saved in the .env
file into the process.env
.
const { Web3 } = require('web3');
Here, we create an InitWeb3
function that initializes and returns a configured web3 instance that connects to the Ethereum node using a WebSocket connection when called.
// Initialize Web3 with dRPC connection
function initWeb3() {
const drpcUrl = process.env.DRPC_URL;
const apiKey = process.env.API_KEY;
const web3 = new Web3(new Web3.providers.WebsocketProvider(drpcUrl, {
headers: {
'Authorization': `Bearer ${apiKey}`
}
}));
return web3;
}
Below is a breakdown of the codes:
const drpcUrl = process.env.DRPC_URL;
const apiKey = process.env.API_KEY;
The lines of code above allow us to access the .env
file through the dotenv library we downloaded earlier. With the dotenv library, we can access the variable stored in the .env
file and retrieve values associated with the dRPC Endpoint and API key.
const web3 = new Web3(new Web3.providers.WebsocketProvider(drpcUrl, {
headers: {
'Authorization': `Bearer ${apiKey}`
}
}));
This line of code configures the web3.js library to use dRPC. The web3.providers.WebsocketProvider
creates a new WebSocket provider for web3.js, connecting it to the dRPC endpoint. The headers
set up an authorization header for the WebSocket connection.
// Criteria to filter transactions
function criteria(tx) {
const web3 = new Web3(); // Utility instance for conversion functions like toWei
const minValue = web3.utils.toWei('10', 'ether'); // Minimum value to filter (10 Ether in this case)
return tx.value >= minValue;
}
The Criteria
function above takes in a single argument, the tx
argument. The tx
argument represents the transaction object, which is expected to have different properties needed to filter the blockchain data.
Here’s the breakdown of the function:
const web3 = new Web3(); // Utility instance for conversion functions like toWei
Here, we create a new instance of web3, the JavaScript library that interacts with the Ethereum nodes. This new instance is a utility instance used to access the conversion function provided by the web3.js
library.
const minValue = web3.utils.toWei('10', 'ether'); // Minimum value to filter (10 Ether in this case)
Here, the minValue
constructor converts 10ETH to wei, needed for the filtering process.
The Criteria
function checks whether the value property of the tx
object is greater than or equal to minValue.
Now that we’ve set up the criteria for monitoring transactions, we need to set up a listener that looks out for new blocks and listens for the new transaction in real time. We define an asynchronous function monitorTransaction
, which can handle asynchronous operations using await. The functions accept two parameters:
// Function to monitor transactions
async function monitorTransactions(criteria, callback) {
const web3 = initWeb3();
const subscription = await web3.eth.subscribe('newBlockHeaders');
subscription.on("data", async (newBlockHeaders) => {
console.log('New block received. Block #', parseInt(newBlockHeaders.number));
try {
// Get block details
const block = await web3.eth.getBlock(newBlockHeaders.hash, true);
if (block && block.transactions) {
block.transactions.forEach(tx => {
// Filtering transactions based on criteria
if (criteria(tx)) {
// If a transaction matches the criteria, display it
if (callback) callback(tx);
}
});
}
} catch (err) {
console.error('Error fetching block:', err);
}
});
subscription.on('error', console.error);
}
Here is the code breakdown below:
const subscription = await web3.eth.subscribe('newBlockHeaders');
subscription.on("data", async (newBlockHeaders) => {
console.log('New block received. Block #', parseInt(newBlockHeaders.number));
This web3.js
function subscribes to the newBlockHeader
event. This notifies the application whenever a new block is added to the blockchain and it’s used to create a subscription that will trigger an event every time a new block is received.
Once the new block is added, the event listener is triggered and the block number is logged with console.log
.
try {
// Get block details
const block = await web3.eth.getBlock(newBlockHeaders.hash, true);
This next line of code contains the web3.eth.getblock
function that’s used to retrieve the details of a block using the newBlockHeaders.hash
. The second argument, true
, makes sure that not only the block information was fetched but the transactions within the block were also fetched.
if (block && block.transactions) {
block.transactions.forEach(tx => {
// Filtering transactions based on criteria
if (criteria(tx)) {
// If a transaction matches the criteria, display it
if (callback) callback(tx);
}
});
}
The above code block shows us what will be done with the information received with the eth.getblock()
function. If the block and block information is retrieved successfully, the code will iterate through each transaction in the block and check if the transactions meet the criteria.
Handling Error
It’s important to log the error for proper handling if our code doesn’t go as planned.
catch (err) {
console.error('Error fetching block:', err);
}
});
If there is an error while we fetch the block details, this console.error
helps log the error.
subscription.on('error', console.error);
This last function helps us to display the information we retrieved from the blockchain in a more readable format. The DisplayTransactionData
function below takes a single argument, the transaction
argument. The transaction
argument contains the various details about a blockchain transaction.
// Function to display transaction data in a readable format
function displayTransactionData(transaction) {
console.log('--- New Transaction ---');
console.log(From: ${transaction.from});
console.log(To: ${transaction.to});
console.log(Value: ${Web3.utils.fromWei(transaction.value, 'ether')} ETH);
console.log(Gas Price: ${Web3.utils.fromWei(transaction.gasPrice, 'gwei')} Gwei);
console.log(Transaction Hash: ${transaction.hash});
console.log('------------------------');
}
The displayTransactionData
function is expected to display a header, sender and recipient address, transaction value in Ether, gas price in Gwei, transaction hash, and the footer.
With the displayTransactionData
, you can retrieve needed data in an easy-to-understand way.
Here is a of how the result looks in cmd
.