Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

feat(bot): Add missing keys of interest to StateRelayerBot #134

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 94 additions & 7 deletions packages/walletkit-bot/src/api/StateRelayerBot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,79 @@ import { BigNumber } from "bignumber.js";

import { getWhaleClient } from "./DeFiChainCore";

type TokenSymbolStringPair = { [tokenSymbol: string]: string };

type PairData = {
[pairSymbol: string]: {
primaryTokenPrice: string;
volume24H: string;
totalLiquidity: string;
apr: string;
pooledTokensCount: TokenSymbolStringPair;
conversationRate: TokenSymbolStringPair;
rewards: string;
commission: string;
};
};

type VaultData = {
totalVaults: number;
totalLoanValue: number;
totalCollateralValue: number;
totalCollateralizationRatio: number;
activeAuctions: number;
};

type MasternodesData = {
totalValueLocked: number;
zeroYearLocked: number;
fiveYearsLocked: number;
tenYearsLocked: number;
};

type BurnData = {
totalDFIburned: number;
};

type DataStore = {
// /dex
totalValueLockInPoolPair: string;
total24HVolume: string;
pair: PairData;
vaults: VaultData;
masternodes: MasternodesData;
burns: BurnData;
};

type StateRelayerHandlerProps = {
urlNetwork: string;
envNetwork: EnvironmentNetwork;
previousBlockHeight?: number;
};

const DENOMINATION = "USDT";

export async function handler(
props: StateRelayerHandlerProps
): Promise<DataStore | undefined> {
const { urlNetwork, envNetwork } = props;
const { urlNetwork, envNetwork, previousBlockHeight } = props;
const dataStore = {} as DataStore;
try {
// TODO: Check if Function should run (blockHeight > 30 from previous)
// Get Data from OCEAN API
const client = getWhaleClient(urlNetwork, envNetwork);
const statsData = await client.stats.get();

// Check if Function should run (blockHeight > 30 from previous)
if (
previousBlockHeight &&
statsData.count.blocks - previousBlockHeight <= 30
) {
throw new Error("Less than 30 blocks have passed since last query");
return; // Do we want to return nothing, cached data or an error?
}

jordankzf marked this conversation as resolved.
Show resolved Hide resolved
const rawPoolpairData = await client.poolpairs.list(200);

const dexPriceData = await client.poolpairs.listDexPrices(DENOMINATION);

// sanitise response data
Expand All @@ -51,7 +90,7 @@ export async function handler(

// total24HVolume
const total24HVolume = poolpairData.reduce(
(acc, currPair) => acc + (currPair.volume?.h24 ?? 0),
(acc, currPair) => acc + (currPair.volume?.h24 ?? 0), // This is not accurate due to rounding, is it fine for volume?
jordankzf marked this conversation as resolved.
Show resolved Hide resolved
0
);
dataStore.total24HVolume = total24HVolume.toString();
Expand All @@ -72,18 +111,66 @@ export async function handler(
return {
...acc,
[currPair.displaySymbol]: {
// Overview
primaryTokenPrice: tokenPrice.toString(),
volume24H: currPair?.volume?.h24.toString() ?? "0",
totalLiquidity: currPair.totalLiquidity.usd ?? "0",
apr: currPair?.apr?.total.toString(),
// Detail
pooledTokensCount: {
[currPair.tokenA.displaySymbol]: currPair.tokenA.reserve,
[currPair.tokenB.displaySymbol]: currPair.tokenB.reserve,
},
conversionRate: {
[currPair.tokenA.displaySymbol]: currPair.priceRatio.ab,
[currPair.tokenB.displaySymbol]: currPair.priceRatio.ba,
},
rewards: (currPair.apr?.reward
? currPair.apr.reward * 100
jordankzf marked this conversation as resolved.
Show resolved Hide resolved
: 0
).toString(),
commission: (currPair.apr?.commission
? currPair.apr.commission * 100
: 0
).toString(),
},
} as PairData;
}, {} as PairData);
dataStore.pair = pair;
// TODO: Get Data from /dex/[pool-pair]
// TODO: Get Data from /vaults
// TODO: Get Data from /masternodes
// TODO: Get Data from all burns in ecosystem

const loanData = statsData.loan;
// Get Data from /vaults
const vaults = {
totalVaults: loanData.count.openVaults,
totalLoanValue: loanData.value.loan,
totalCollateralValue: loanData.value.collateral,
totalCollateralizationRatio:
(loanData.value.collateral / loanData.value.loan) * 100,
activeAuctions: loanData.count.openAuctions,
};
dataStore.vaults = vaults;

// Get Data from /masternodes
const lockedMasternodes = statsData.masternodes.locked;

const masternodes = {
totalValueLocked: statsData.tvl.masternodes, // Alternatively, can reduce lockedMasternodes to derive this data
zeroYearLocked: lockedMasternodes.find((m) => m.weeks === 0)?.count ?? 0, // Can technically access element at 0 index for speed
fiveYearsLocked:
lockedMasternodes.find((m) => m.weeks === 260)?.count ?? 0,
tenYearsLocked:
lockedMasternodes.find((m) => m.weeks === 520)?.count ?? 0,
};
dataStore.masternodes = masternodes;

// Get Data from all burns in ecosystem
const burns = {
// Other keys in burned such as address, auction, emission,
// fee, and payback do not seem to be used in scan.
totalDFIburned: statsData.burned.total,
jordankzf marked this conversation as resolved.
Show resolved Hide resolved
};
dataStore.burns = burns;

// Interfacing with SC
// TODO: Connect with SC
// TODO: Call SC Function to update Collated Data
Expand Down