Skip to content

How To Leverage Hedera Mirror Nodes for Data Applications

Node Series_Hedera How To Mirror Nodes

In the ever-changing world of blockchain and distributed ledger technologies, Hedera Hashgraph distinguishes itself with unique architectural choices and capabilities. Beyond its mainnet features of high throughput, fast finality, and low fees, Hedera offers a powerful feature known as Mirror Nodes. These nodes present a fascinating aspect of Hedera's ecosystem, offering robust functionalities for developers, enterprises, and users keen on blockchain data analysis and gathering insights.

What are Mirror Nodes?

Mirror Nodes play a pivotal role in the Hedera network by providing access to historical data and real-time events without burdening the main network. Unlike Consensus Nodes that participate in transaction processing and consensus, Mirror Nodes focus on data dissemination, allowing users to query historical transactions, account balances, smart contract results, and more. This architecture not only ensures data availability and transparency but also offloads the query load from the mainnet, maintaining its efficiency and speed. 

Validation Cloud partnered with Hedera to offer mirror-node-as-a-service to Hedera users. Learn more about this partnership here and keep reading to learn how you can get started with Hedera Mirror Nodes on Validation Cloud’s Node API. 

Why Utilize Validation Cloud’s Hedera Mirror Nodes?
  • Historical Data Access: For applications that require analysis of past transactions and account states, Mirror Nodes provide a gateway to extensive historical data. This is crucial for auditability, compliance, and analytics applications.

  • Real-time Monitoring: Developers can use Mirror Nodes to monitor network events in real-time. This capability is essential for applications that need to react promptly to changes on the ledger, such as payment processors or trading platforms.

  • Economical and Scalable: Accessing data through Mirror Nodes is cost-effective, as it avoids the transaction fees associated with altering state on the mainnet directly. This makes it scalable for applications that require frequent data retrieval.



Setting up your Mirror Node Querying Environment

Before you begin, ensure you have Node.js, along with the web3 node package installed on your machine. This will allow you to run JavaScript / TypeScript programs that interact with the Hedera network. You'll also need to set up an account on Validation Cloud to obtain your endpoint API key, which will work for both Mirror Nodes and the JSON-RPC relay. You can store this key and access it more securely by utilizing an environment (.env) file. The following are bash commands to easily set up your environment: 


mkdir validationcloud-mirror-app
cd validationcloud-mirror-app
yarn init -y
yarn add axios
yarn add dotenv
yarn add --dev typescript @types/node @types/axios
npx tsc --init

touch index.ts
touch .env
echo "HEDERA_API_KEY='<YOUR_VALIDATION_CLOUD_API_KEY>'" >> .env
echo "node_modules/" >> .gitignore
echo ".env" >> .gitignore

Example 1: Retrieving Account Information

Let’s start with retrieving some account data using TypeScript. This query can return an array of objects containing fields like the account address (0.0…), alias, balance, created_timestamp, evm_address, and other details relating to staking. For this example, we will specify an account ID that we created with a Hedera wallet, and have already funded it with testnet tokens so we can prove to ourselves that it is accurate.


import axios from 'axios';
import dotenv from 'dotenv';
dotenv.config();
const HEDERA_API_KEY = process.env.HEDERA_API_KEY;
const accountsBaseURL=
`https://testnet.hedera.validationcloud.io/v1/${HEDERA_API_KEY}/api/v1/accounts`
// Replace 'yourAccountId' with the actual account ID
const accountId = '0.0.2660....';

// Axios GET request
axios.get(`${accountsBaseURL}?account.id=${accountId}`)
 .then(response => {
   console.log('Success!',response.data);
 })
 .catch(error => {
   console.error('Error fetching transactions:', error);
 });

Example 2a: Get List of Transactions

Suppose you want to build an application to track balances or transactions over time for a given account. To access this data, we will query the “transactions” endpoint, passing in the accountID. It will return an array of transaction objects, each containing fee information, transaction hash, timestamps, NFT transfers, and other details.


import axios from 'axios';
import dotenv from 'dotenv';
dotenv.config();
const HEDERA_API_KEY = process.env.HEDERA_API_KEY;
const transactionsBaseURL = 
`https://testnet.hedera.validationcloud.io/v1/${HEDERA_API_KEY}/api/v1/transactions`;
// Replace 'yourAccountId' with the actual account ID
const accountId = '0.0.2660....';


axios.get(`${transactionsBaseURL}?account.id=${accountId}`)
 .then(response => {
   console.log('Success!',response.data);
 })
 .catch(error => {
   console.error('Error fetching transactions:', error);
 });

Example 2b: Get List of Transfers after Jan 1, 2024

Suppose you wanted to limit the responses only to transactions of the “transfer” type that occurred after a certain date. In our theoretical accounting application, it does not make sense to retrieve transfers from 2023 when filing taxes for 2024. The following illustrates passing in different parameters to the get request in order to achieve the desired output.


const accountId = '0.0.2660....';
const accountsBaseURL = 
`https://testnet.hedera.validationcloud.io/v1/${HEDERA_API_KEY}/api/v1/transactions`;

axios.get(`${transactionsBaseURL}?account.id=${accountId}&order=asc&timestamp=gt%3A${timestampForJan2024}&transactiontype=cryptotransfer`)
.then(response => {
  console.log('Success!',response.data);
   })
 .catch(error => {
   console.error('Error fetching transactions:', error);
 });
function getUnixTimestampForDate(year: number, month: number, day: number): number {
   const date = new Date(Date.UTC(year, month - 1, day, 0, 0, 0));
   return date.getTime() / 1000; 
}    

Example 3: Get Token Information

Another critical element of any web3 application is non-native tokens. The following simple query shows you how to retrieve token information, returning an object containing details like decimal count, total supply, treasury account ID, token type, custom fee mechanics, timestamp, and many other details.


const tokensBaseURL = 
`https://testnet.hedera.validationcloud.io/v1/${HEDERA_API_KEY}/api/v1/tokens`

async function getTokenInfo(tokenId: string) {
    const url = `${tokensBaseURL}/${tokenId}`;
    try {
     const response = await axios.get(url);
     console.log('Success! Token Info:',response.data);
    } catch (error) {
     console.error('Error fetching token information:', error);
    }
 }


// Replace with the actual ID of the token
getTokenInfo('0.0.3592573');    

Example 4: Analyzing Smart Contract Results

Much like the above example, analyzing smart contract results returns a similar spectrum of information about the contract you are specifying. It is also queried in a similar manner. Attempt to run the following code to see if you get a data rich response.


const contractsBaseURL = 
`https://testnet.hedera.validationcloud.io/v1/${HEDERA_API_KEY}/api/v1/contracts`


async function getContractResults(contractId: string) {
 try {
   const response = await axios.get(`${contractsBaseURL}/${contractId}/results`);
   console.log(response.data);
 } catch (error) {
   console.error('Error fetching smart contract results:', error);
 }
}


getContractResults('0.0.3592230');    

Example 5: Get Topic Results 

The last example covered here focuses on topics. In Hedera, a “topic” is used in the context of the Hedera Consensus Service. Topics are used to submit messages to the Hedera public ledger for time-stamping and ordering purposes. These messages can include important actionable information, events such as a money transfer settlement, user engagements in an advertising platform, tracking of provenance in a supply chain, and more. These ordered messages get submitted as messages to a topic, and will subsequently flow out to mirror nodes for archival storage.

In this example, we pick a topic ID at random from the Hedera block explorer to illustrate the passing in of that parameter to the Validation Cloud Node API endpoint. Sequencer number, chunk info, message hash, and payer account ID are some of the results returned from this query. 


const topicsBaseURL = 
`https://testnet.hedera.validationcloud.io/v1/${HEDERA_API_KEY}/api/v1/topics`


async function getTopicResults(topicId: string) {
 try {
   const response = await axios.get(`${topicsBaseURL}/${topicId}/messages`);
   console.log(response.data);
 } catch (error) {
   console.error('Error fetching topic results:', error);
}  }
getTopicResults('0.0.3592132');    

More information on getting started can be found on the Validation Cloud documentation pages: https://docs.validationcloud.io/v1/hedera/rest-mirror-node-api 

Start Building on Hedera

For developers seeking familiarity with high-performance blockchains, and highly accessible archival data access, Hedera Mirror nodes offer a unique opportunity. The developer-friendly approach through tools like Validation Cloud's Mirror Node REST API makes querying all types of information about the Hedera blockchain fast and nimble. Embrace the shift and explore what Hedera has to offer to your Web3 development journey. Get started with 50 million compute units for free at validationcloud.io.


About Validation Cloud

Validation Cloud is a Web3 data streaming and infrastructure company that connects organizations into Web3 through a fast, scalable, and intelligent platform. Headquartered in Zug, Switzerland, Validation Cloud offers highly performant and customizable products in staking, node, and data-as-a-service. Learn more at validationcloud.io| LinkedIn | X