So this serves as an introduction on how to read info from hive-engine api's to create a functional website: Our plan is to create a table that shows the top 20 holders of a certain token.
First we create an index.html file with the following code:
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
Now we need to set the skeleton for our table adding these few lines between the body tags:
<main>
<table>
<thead>
<tr>
<th>Users</th>
<th>BUDS</th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
</main>
Then finally:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<main>
<table>
<thead>
<tr>
<th>Users</th>
<th>BUDS</th>
</tr>
</thead>
<tbody id="tableBody">
</tbody>
</table>
</main>
</body>
</html>
We can open the file in a browser and check everything is okay:
Now we need to get our data from hive's api: one way to do that is using the fetch function: We need to create a source.js file and add these few lines of code:
async function findData() {
const response = await fetch("https://api.hive-engine.com/rpc/contracts", {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
method: "find",
params: {
contract: "tokens",
table: "balance",
query: {},
},
id: 1,
}),
});
const responseJson = await response.json();
const data = responseJson.result
console.log(data);
}
findData()
Basically it's a an async/await function that contains a fetch method which allows us to do get and post requests to the api.
Now we need to link the index file to our html file before the body tag:
<script type="text/javascript" src="index.js"> </script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="source.js"> </script>
<title>Document</title>
</head>
<body>
<main>
<table>
<thead>
<tr>
<th>Users</th>
<th>BUDS</th>
</tr>
</thead>
<tbody id="tablebody">
</tbody>
</table>
</main>
</body>
</html>
Now we will go back to the javascript file and replace the query for:
query: {"symbol":"BUDS", 'balance': { '$ne' : "0" }},
So we can get fillter out from the data those who have 0 buds:
Well now we have the data, but we need to insert it into the DOM. So we will add some DOM manipulation functions to our main asynchronic function
const tableBody = document.getElementById("tablebody"); //finds the element with the id "tablebody"
Then we are gonna need to create some rows for every user in the top 20
we can solve this by using a for loop:
for (i = 0; i < data.length; i++) {
const row = document.createElement("tr"); //creates a row
const user = document.createElement("td"); //creates a cell
const balance = document.createElement("td"); //creates a cell
}
Then these lines add text to the cell:
//these lines add text to the cells
user.textContent = data[i].account;
balance.textContent = data[i].balance;
Then we have:
for (i = 0; i < data.length; i++) {
const row = document.createElement("tr"); //creates a row
const user = document.createElement("td"); //creates a cell inside the row
const balance = document.createElement("td"); //creates a cell
user.textContent = data[i].account;
balance.textContent = data[i].balance;
}
Then we append the elements we created to the table:
row.append(user);
row.append(balance);
tableBody.append(row);
Which results in:
const tableBody = document.getElementById("tablebody");
for (i = 0; i < 20; i++) {
const row = document.createElement("tr"); //creates a row
const user = document.createElement("td"); //creates a cell inside the row
const balance = document.createElement("td"); //creates a cell
user.textContent = data[i].account;
balance.textContent = data[i].balance;
row.append(user);
row.append(balance);
tableBody.append(row);
}
Finally:
async function findData() {
const response = await fetch("https://api.hive-engine.com/rpc/contracts", {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
method: "find",
params: {
contract: "tokens",
table: "balances",
query: {"symbol":"BUDS", 'balance': { '$ne' : "0" }},
},
id: 1,
}),
});
const responseJson = await response.json();
const data = responseJson.result
console.log(data);
const tableBody = document.getElementById("tablebody");
for (i = 0; i < 20; i++) {
const row = document.createElement("tr"); //creates a row
const user = document.createElement("td"); //creates a cell inside the row
const balance = document.createElement("td"); //creates a cell
user.textContent = data[i].account;
balance.textContent = data[i].balance;
row.append(user);
row.append(balance);
tableBody.append(row);
}
}
findData()
Then we get:
As you can see we got "20" BUDS holders but they aren't ordered from highest to lowest... we aren't filtering the data, this is easily solved anyway:
we had this variable
const data = responseJson.result
we can change it to
let data = responseJson.result
data = data.sort((a, b) => b.balance - a.balance);
data.sort((a, b) => b.balance - a.balance)
this javascript method orders the elements in the array comparing the balances in each of them.
Then finally:
To learn more about what information can you get (and how) from hive-engine's api you can check this:
https://hive-engine.github.io/engine-docs/tables/#tables-tokens
Here's another way to do this applying sscjs instead of the fetch function:
https://peakd.com/hive-104341/@fefe99/how-to-use-sscjs-library-to-find-info-in-hive-engine
Another way would be to use axios or an XMLhttprequest.