Skip to content

Commit

Permalink
setup test on ci, fix roi calculator (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
osipov-mit authored Dec 2, 2024
1 parent 4ea31fe commit 78a8619
Show file tree
Hide file tree
Showing 8 changed files with 574 additions and 438 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
pull_request:
branches: ["master"]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
SUBSCAN_KEY: ${{ secrets.SUBSCAN_KEY }}

jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: "Install: NodeJS 20.x"
uses: actions/setup-node@v4
with:
node-version: 20.x

- name: "Install: pkg dependencies"
run: yarn install

- name: "Run server"
env:
SUBSCAN_KEY: ${{ secrets.SUBSCAN_KEY }}
NETWORK_ADDRESSES: "wss://rpc.vara.network"
run: nohup yarn start &

- name: "Run tests"
run: yarn test
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
"type": "module",
"scripts": {
"start": "node src/main.js",
"watch": "node --watch src/main.js"
"watch": "node --watch src/main.js",
"test": "node test.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@polkadot/api": "^10.9.1",
"@polkadot/api": "^15.0.1",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2"
},
"devDependencies": {
"@polkadot/types": "^10.9.1",
"@polkadot/types": "^15.0.1",
"@types/express": "^4.17.17"
}
}
15 changes: 9 additions & 6 deletions src/calculators/staking-roi.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import { DECIMALS } from '../consts.js';
// era_payout = total_issuance * inflation_per_era

export async function stakingRoi() {
const lastEra = (await api.query.staking.currentEra()).toHuman();
const lastEra = (await api.query.staking.currentEra()).unwrap().toNumber();

const inflationPerEra = (await api.query.staking.erasValidatorReward(lastEra - 2)).toJSON();
const totalStaked = await api.query.staking.erasTotalStake(lastEra - 2);
const totalIssuance = await totalSupply();
const inflationPerEra = (await api.query.staking.erasValidatorReward(lastEra - 2)).unwrap().toBigInt();

const roi = (totalIssuance * (inflationPerEra / 10 ** DECIMALS)) / (totalStaked / 10 ** DECIMALS) * 730;
const totalStaked = (await api.query.staking.erasTotalStake(lastEra - 2)).toBigInt();

return (roi / 10 ** 8)
const totalIssuance = BigInt(await totalSupply());

const roi =
((totalIssuance * (inflationPerEra / BigInt(10 ** DECIMALS))) / (totalStaked / BigInt(10 ** DECIMALS))) * 730n;

return Number(roi / BigInt(10 ** 8));
}
89 changes: 43 additions & 46 deletions src/calculators/subscan.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import config from "../config.js";
import {api} from "../node.js";
import config from '../config.js';
import { api } from '../node.js';

const SUBSCAN_URL = 'https://vara.api.subscan.io'
const SUBSCAN_URL = 'https://vara.api.subscan.io';
const ONE_HOUR = 60 * 60 * 1000;
const PAGE_ROWS = 100;

Expand All @@ -26,36 +26,35 @@ const exchangeAddresses = [
'kGgvxgM2sJF7fWUze3fNWBWzy5momsyna7XF8MFzAWPhj2WpU',
'kGiVY7G1mJkqaAjKzLnRmwCy5GcvuGQvG5mUtojhVHdLfBd1P',
'kGga7DgxzLLTqn9WjtEZW5pkxYVnBPS4Rt6xK3Adqs1iKN42z',
]
];

function getVestExtrinsicPaginated(page, lastBlockNumber, type) {
return fetch(`${SUBSCAN_URL}/api/v2/scan/extrinsics`, {
method: 'POST',
headers: HEADERS,
body: JSON.stringify({
"module": "vesting",
"call": type,
"block_range": `${minBlock}-${lastBlockNumber}`,
"row": PAGE_ROWS,
"page": page,
})
})
.then(response => {
if (!response.ok) {
return response.json().then(err => {
throw err;
});
}
return response.json();
});
module: 'vesting',
call: type,
block_range: `${minBlock}-${lastBlockNumber}`,
row: PAGE_ROWS,
page: page,
}),
}).then((response) => {
if (!response.ok) {
return response.json().then((err) => {
throw err;
});
}
return response.json();
});
}

async function getVestExtrinsic(type, lastBlockNumber) {
let page = 0;
let extrinsics = [];
let res = await getVestExtrinsicPaginated(page, lastBlockNumber, type);
while (res.data?.extrinsics?.length > 0) {
extrinsics.push(...res.data.extrinsics.map(s => s.extrinsic_index));
extrinsics.push(...res.data.extrinsics.map((s) => s.extrinsic_index));
page++;
res = await getVestExtrinsicPaginated(page, lastBlockNumber, type);
}
Expand All @@ -69,19 +68,17 @@ async function getExchangeAddresses(lastBlockNumber) {
method: 'POST',
headers: HEADERS,
body: JSON.stringify({
"address": address,
"direction": "all",
"order": "asc",
"include_total": true,
"page": 0,
"row": 1,
"block_range": `${minBlock}-${lastBlockNumber}`,
"success": true,
"token_category": [
"native"
]
})
}).then(response => response.json());
address: address,
direction: 'all',
order: 'asc',
include_total: true,
page: 0,
row: 1,
block_range: `${minBlock}-${lastBlockNumber}`,
success: true,
token_category: ['native'],
}),
}).then((response) => response.json());
sum += BigInt(res?.data?.total?.VARA?.sent ?? 0n);
}
return sum;
Expand All @@ -95,13 +92,12 @@ export async function getUnvested() {
}

async function updateUnvested() {
const lastBlockResult = await api.rpc.chain.getBlock()
const lastBlockResult = await api.rpc.chain.getBlock();
const lastBlockNumber = lastBlockResult.block.header.number.toBigInt();
const extrinsics = await Promise.all(
[
getVestExtrinsic("vest", lastBlockNumber),
getVestExtrinsic("vest_other", lastBlockNumber),
]).then(res => res.flat());
const extrinsics = await Promise.all([
getVestExtrinsic('vest', lastBlockNumber),
getVestExtrinsic('vest_other', lastBlockNumber),
]).then((res) => res.flat());
let unvested = cachedValue;
console.log('found extrinsics: ', extrinsics.length);
for (const extrinsicIndex of extrinsics) {
Expand All @@ -110,18 +106,19 @@ async function updateUnvested() {
method: 'POST',
headers: HEADERS,
body: JSON.stringify({
"extrinsic_index": extrinsicIndex,
extrinsic_index: extrinsicIndex,
}),
}).then(response => response.json());
const vestingEvents = extrinsicRes.data?.event?.filter(e => {
return e.module_id?.toLowerCase() === 'balances' && e.event_id?.toLowerCase() === 'unlocked';
}) ?? [];
}).then((response) => response.json());
const vestingEvents =
extrinsicRes.data?.event?.filter((e) => {
return e.module_id?.toLowerCase() === 'balances' && e.event_id?.toLowerCase() === 'unlocked';
}) ?? [];
for (let e of vestingEvents) {
try {
const params = JSON.parse(e.params) ?? [];
const unvestedParams = params.filter(p => p.name === "amount");
const unvestedParams = params.filter((p) => p.name === 'amount');
for (let un of unvestedParams) {
unvested += BigInt(un.value)
unvested += BigInt(un.value);
}
} catch (e) {
console.error(`failed to calculate unvested because of`, e);
Expand Down
2 changes: 1 addition & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ export default {
port: Number(getEnv('PORT', '3000')),
},
subscan: {
apiKey: getEnv('SUBSCSCAN_KEY'),
apiKey: getEnv('SUBSCAN_KEY'),
},
};
18 changes: 9 additions & 9 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
tokensSentFromInflationPool,
totalSupply,
totalVesting,
stakingRoi
stakingRoi,
} from './calculators/index.js';

const app = express();
Expand All @@ -32,14 +32,14 @@ app.get('/api/total', async (req, res) => {
});
});

app.get('/api/total-staking', async (req, res) => {
totalStaking()
.then((result) => res.json(result))
.catch((err) => {
console.error(err);
res.sendStatus(500);
});
});
// app.get('/api/total-staking', async (req, res) => {
// totalStaking()
// .then((result) => res.json(result))
// .catch((err) => {
// console.error(err);
// res.sendStatus(500);
// });
// });

app.get('/api/total-vesting', async (req, res) => {
totalVesting()
Expand Down
26 changes: 26 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const endpoints = ['/api/burned', '/api/total', '/api/total-vesting', '/api/circulating-supply', '/api/roi'];

const test = async () => {
for (const endpoint of endpoints) {
const res = await fetch(new URL(endpoint, 'http://127.0.0.1:3000'));

if (!res.ok) {
throw new Error(`Failed to fetch ${endpoint}`);
}

const data = await res.text();

if (Number(data) === NaN) {
throw new Error(`Failed to parse ${endpoint}. ${data}`);
}

console.log(endpoint, '- ok');
}
};

test()
.catch((e) => {
console.error(e);
process.exit(1);
})
.then(() => process.exit(0));
Loading

0 comments on commit 78a8619

Please sign in to comment.