Skip to main content

Calculations and Scripting

We will be using a simple fromula given below to calculate and trace the real-time balance changes. To execute this formula through code we will build two files (namely balance.js and index.js).

Current Balance = sum(all_balance_updates) + steam_balance_updates

Initialise and Installing Dependencies​

To initiate the project run the following command.

npm init -y

Before going further make sure that all the dependencies are installed. The dependencies are listed below:

  • axios
  • dotenv
  • express
  • ws

Use the following command to install these dependencies.

npm install axios dotenv express ws

Create Balance Script​

This script will calculate the summation of all the Balance Updates till yet, giving the current balance of a particular currency (Ethereum in this example) for the wallet. Follow the steps given below to build the script

  1. Import the dependencies
const axios = require('axios');

require('dotenv').config()

NOTE: Make sure to create a .env file and create a AUTH_TOKEN variable to store your Bitquery Access Token. To know more about the access token click here.

  1. Create a standard config for the getBalance function. This includes the API url we are trying to hit, access token to authenticate the request, and the request body as data.

let data = JSON.stringify({
"query": "{\n EVM(dataset: combined, network: eth) {\n BalanceUpdates(\n where: {BalanceUpdate: {Address: {is: \"\"}}, Currency: {SmartContract: {is: \"0x\"}}}\n ) {\n sum(of: BalanceUpdate_Amount)\n }\n }\n}\n",
"variables": "{}"
});

let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://streaming.bitquery.io/graphql',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': 'BQYuTITWanwYGz0YLGdcWSADO74o5RTX',
'Authorization': `Bearer ${process.env.AUTH_TOKEN}`
},
data : data
};

Please note that the data part is a standard case, but will be modified upon the user input.

  1. Create the asynchronous getBalance function.
const getBalance = async (config) => {
try {
const response = await axios.request(config);
// console.log(response.data.data.EVM.BalanceUpdates[0].sum)
return response.data.data.EVM.BalanceUpdates[0].sum;
} catch (error) {
return error;
}

}
  1. Export the requirements from the file.
module.exports = {getBalance, config};

Create Index Script​

In this file we will write code to:

  • Get Balance using the getBalance function from balance.js.
  • Create an express server so that we can render a simple UI.
  • Run a websoket connection to get real-time balance updates.
  1. Import the requirements.
const express = require('express');
const path = require('path');
const { getBalance, config } = require('./balance.js');
require('dotenv').config();
  1. Initiate the express server and declare the address variable.
const app = express();
app.use(express.static(path.join(__dirname)));
app.use(express.json());

let currentAddress = ''; // Default address if none provided
  1. Creating the endpoint to handle address input from frontend.
app.post('/track-balance', (req, res) => {
const { address } = req.body;
if (!address) {
return res.status(400).json({ success: false, message: 'Address required' });
}
currentAddress = address;
res.json({ success: true });
});
  1. Creating the endpoint to get the balance from getBalance function.
app.get('/get-balance', async (req, res) => {
try {
// Update the address in the config dynamically
config.data = JSON.stringify({
"query": `{\n EVM(dataset: combined, network: eth) {\n BalanceUpdates(\n where: {BalanceUpdate: {Address: {is: \"${currentAddress}\"}}, Currency: {SmartContract: {is: \"0x\"}}}\n ) {\n sum(of: BalanceUpdate_Amount)\n }\n }\n}\n`,
"variables": "{}"
});

const balance = await getBalance(config);
res.json({ balance: balance || '0' });
} catch (error) {
console.error('Error fetching balance:', error);
res.status(500).json({ error: 'Error fetching balance' });
}
});
  1. Start WebSocket connection for real-time updates.
const { WebSocket } = require("ws");

const bitqueryConnection = new WebSocket(
"wss://streaming.bitquery.io/graphql?token=" + process.env.AUTH_TOKEN,
["graphql-ws"],
);

bitqueryConnection.on("open", () => {
console.log("Connected to Bitquery.");

const initMessage = JSON.stringify({ type: "connection_init" });
bitqueryConnection.send(initMessage);
});

bitqueryConnection.on("message", async (data) => {
const response = JSON.parse(data);

if (response.type === "connection_ack") {
const subscriptionMessage = JSON.stringify({
type: "start",
id: "1",
payload: {
query: `
subscription {
EVM{
BalanceUpdates(
where: {
BalanceUpdate: {
Address: {
is: "${currentAddress}"
}
},
Currency: {SmartContract: {is: "0x"}}
}
) {
BalanceUpdate {
Amount
}
}
}
}`,
},
});

bitqueryConnection.send(subscriptionMessage);
console.log("Subscription message sent.");
}
});

bitqueryConnection.on("error", (error) => {
console.error("WebSocket Error:", error);
});
  1. Start the Express server.
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

Now we need to build a simple UI using HTML, CSS and Javascript to make this project inituitive.