Skip to content

Commit

Permalink
small backend for snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
akorchyn committed Apr 2, 2024
1 parent db70a7f commit ec43b5c
Show file tree
Hide file tree
Showing 9 changed files with 1,265 additions and 2 deletions.
11 changes: 10 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@
"dependencies": {
"@supercharge/promise-pool": "^2.3.2",
"big.js": "^6.1.1",
"bn-sqrt": "^1.0.0",
"commander": "^12.0.0",
"dotenv": "^16.3.1",
"fs": "^0.0.1security",
"near-api-js": "3.0.4",
"near-api-js": "^3.0.4",
"p-retry": "^6.2.0",
"pg": "^8.11.3",
"secp256k1": "^5.0.0",
Expand Down
12 changes: 12 additions & 0 deletions snapshotter/server/api/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import express from "express";
import cors from "cors";
import { corsConfig } from "./config/cors.config.js";
import { routes } from "./routes.js";

export const app = express();

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(cors(corsConfig));

app.use("/api", routes);
9 changes: 9 additions & 0 deletions snapshotter/server/api/config/cors.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const corsConfig = {
origin: [
"http://localhost:3000",
"https://near.org",
"https://near.social",
],
methods: "GET,OPTION,HEAD",
optionsSuccessStatus: 200,
};
8 changes: 8 additions & 0 deletions snapshotter/server/api/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from "express";
import { GetSnapshot } from "./snapshot.js";

const routes = express.Router();

routes.get("/snapshot", GetSnapshot);

export { routes };
91 changes: 91 additions & 0 deletions snapshotter/server/api/snapshot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { parseNearAmount } from "near-api-js/lib/utils/format.js";
import { snapshot } from "../index.js";
import { BN } from 'bn.js';

const NEAR_THRESHOLD = new BN(parseNearAmount('1000'));
const NEAR_TO_YOCTO = new BN(parseNearAmount('1'));

const stakePower = (stakeStr) => {
const stake = new BN(stakeStr);

let stake_power = stake.div(NEAR_TO_YOCTO).toNumber();

if (stake.gt(NEAR_THRESHOLD)) {
stake_power = 1000;
stake_power += Math.floor(Math.sqrt(stake.sub(NEAR_THRESHOLD).div(NEAR_TO_YOCTO).toNumber()));
}
return stake_power;

}

const activityPower = (activeMonths) => {
return activeMonths * 20;
}

const userToVotePower = (user) => {
const activeMonthsPower = activityPower(user.active_months);
const stake_power = stakePower(user.stake);

return activeMonthsPower + stake_power;
}

export const GetSnapshot = (req, res) => {
const { page = 0, limit = 100, sortBy = "name", sortOrder = "asc", prefix = "" } = req.query;

// Convert page and limit to numbers
const pageNumber = parseInt(page);
const limitNumber = parseInt(limit);

let filteredSnapshot = snapshot;
if (prefix) {
filteredSnapshot = snapshot.filter((item) => item.account_id.startsWith(prefix));
}

// Sort the snapshot data based on the sortBy and sortOrder parameters
let sortedSnapshot = [...filteredSnapshot];
switch (sortBy) {
case "name":
sortedSnapshot.sort((a, b) => a.account_id.localeCompare(b.account_id));
break;
case "stake":
sortedSnapshot.sort((a, b) => {
const stakeA = new BN(a.stake);
const stakeB = new BN(b.stake);
return stakeA.cmp(stakeB);
});
break;
case "active_months":
sortedSnapshot.sort((a, b) => a.active_months - b.active_months);
break;
case "vote_power":
sortedSnapshot = sortedSnapshot.map(a => ({ power: userToVotePower(a), ...a })).sort((a, b) => a.power - b.power);
break;
case "stake_power":
sortedSnapshot = sortedSnapshot.map(a => ({ power: stakePower(a.stake), ...a })).sort((a, b) => a.power - b.power);
break;
case "activity_power":
sortedSnapshot = sortedSnapshot.map(a => ({ power: activityPower(a.active_months), ...a })).sort((a, b) => a.power - b.power);
break;
default:
res.status(400).send(`Invalid sortBy parameter: ${sortBy}`);
break;
}

if (sortOrder === "desc") {
sortedSnapshot.reverse();
}

const startIndex = pageNumber * limitNumber;
const endIndex = startIndex + limitNumber;
const paginatedData = sortedSnapshot.slice(startIndex, endIndex);

// Prepare the response
const response = {
data: paginatedData,
currentPage: pageNumber + 1,
totalPages: Math.ceil(sortedSnapshot.length / limitNumber),
totalItems: sortedSnapshot.length,
};

res.json(response);
};
18 changes: 18 additions & 0 deletions snapshotter/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { app } from "./api/app.js";
import fs from 'fs';

const port = process.env.SERVER_PORT || 3000;

const configFile = process.env.SNAPSHOT_FILE || 'snapshot.json';
export let snapshot = {}

function loadSnapshot() {
const data = JSON.parse(fs.readFileSync(configFile, 'utf-8')).data;
snapshot = data;
}

app.listen(port, () => {
loadSnapshot();
console.log(`Dashboard server running on port :${port}`);
console.log(`------------------`);
});
Loading

0 comments on commit ec43b5c

Please sign in to comment.