From 0ad9238c749585407e34a289c3b88c6662222c9a Mon Sep 17 00:00:00 2001 From: Ankur Banerjee Date: Fri, 24 Nov 2023 10:26:11 +0000 Subject: [PATCH] npm run format --- src/api/bigDipperApi.ts | 39 ++-- src/api/marketMonitorApi.ts | 19 +- src/api/nodeApi.ts | 129 ++++++------- src/bindings.d.ts | 16 +- src/handlers/allArbitrageOpportunities.ts | 20 +- src/handlers/arbitrageOpportunities.ts | 38 ++-- src/handlers/circulatingSupply.ts | 15 +- src/handlers/liquidBalance.ts | 73 ++++---- src/handlers/totalBalance.ts | 8 +- src/handlers/totalStakedCoins.ts | 8 +- src/handlers/totalSupply.ts | 8 +- src/handlers/vestedBalance.ts | 29 ++- src/handlers/vestingBalance.ts | 29 ++- src/handlers/webhookTriggers.ts | 66 +++---- src/helpers/balance.ts | 217 ++++++++++------------ src/helpers/circulating.ts | 115 ++++++------ src/helpers/currency.ts | 6 +- src/helpers/graphql.ts | 33 ++-- src/helpers/kv.ts | 14 +- src/helpers/validate.ts | 11 +- src/helpers/vesting.ts | 82 ++++---- src/index.ts | 34 ++-- src/types/bigDipper.ts | 40 ++-- src/types/kv.ts | 4 +- src/types/marketMonitor.ts | 28 +-- src/types/node.ts | 162 ++++++++-------- 26 files changed, 578 insertions(+), 665 deletions(-) diff --git a/src/api/bigDipperApi.ts b/src/api/bigDipperApi.ts index 83b41126..e1a41a2c 100644 --- a/src/api/bigDipperApi.ts +++ b/src/api/bigDipperApi.ts @@ -1,40 +1,33 @@ import { GraphQLClient } from '../helpers/graphql'; -import { - TotalSupplyResponse, - TotalStakedCoinsResponse, - ActiveValidatorsResponse, -} from '../types/bigDipper'; +import { TotalSupplyResponse, TotalStakedCoinsResponse, ActiveValidatorsResponse } from '../types/bigDipper'; export class BigDipperApi { - constructor(public readonly graphql_client: GraphQLClient) {} + constructor(public readonly graphql_client: GraphQLClient) {} - async getTotalSupply(): Promise { - let query = `query TotalSupply { + async getTotalSupply(): Promise { + let query = `query TotalSupply { supply { coins } }`; - let resp = await this.graphql_client.query<{ - data: TotalSupplyResponse; - }>(query); + let resp = await this.graphql_client.query<{ + data: TotalSupplyResponse; + }>(query); - return Number( - resp.data.supply[0].coins.find((coin) => coin.denom === 'ncheq') - ?.amount || '0' - ); - } + return Number(resp.data.supply[0].coins.find((coin) => coin.denom === 'ncheq')?.amount || '0'); + } - getTotalStakedCoins = async (): Promise => { - let query = `query StakingInfo{ + getTotalStakedCoins = async (): Promise => { + let query = `query StakingInfo{ staking_pool { bonded_tokens } }`; - const resp = await this.graphql_client.query<{ - data: TotalStakedCoinsResponse; - }>(query); - return resp.data.staking_pool[0].bonded_tokens; - }; + const resp = await this.graphql_client.query<{ + data: TotalStakedCoinsResponse; + }>(query); + return resp.data.staking_pool[0].bonded_tokens; + }; } diff --git a/src/api/marketMonitorApi.ts b/src/api/marketMonitorApi.ts index 82300a55..555b4dd1 100644 --- a/src/api/marketMonitorApi.ts +++ b/src/api/marketMonitorApi.ts @@ -1,15 +1,12 @@ import { MarketMonitorData } from '../types/marketMonitor'; export class MarketMonitorApi { - constructor(public readonly base_market_monitor_api_url: string) {} + constructor(public readonly base_market_monitor_api_url: string) {} - async getMarketMonitoringData(): Promise { - const requestOptions = { - method: 'GET', - }; - const response = await fetch( - `${this.base_market_monitor_api_url}`, - requestOptions - ); - return (await response.json()) as MarketMonitorData; - } + async getMarketMonitoringData(): Promise { + const requestOptions = { + method: 'GET', + }; + const response = await fetch(`${this.base_market_monitor_api_url}`, requestOptions); + return (await response.json()) as MarketMonitorData; + } } diff --git a/src/api/nodeApi.ts b/src/api/nodeApi.ts index 4c05d623..dfa70a15 100644 --- a/src/api/nodeApi.ts +++ b/src/api/nodeApi.ts @@ -1,79 +1,56 @@ -import { - Account, - Coin, - DelegationsResponse, - UnbondingResponse, - RewardsResponse -} from '../types/node'; +import { Account, Coin, DelegationsResponse, UnbondingResponse, RewardsResponse } from '../types/node'; export class NodeApi { - constructor(public readonly base_rest_api_url: string) {} - - async getAccountInfo(address: string): Promise { - let resp = await fetch( - `${this.base_rest_api_url}/cosmos/auth/v1beta1/accounts/${address}` - ); - let respJson = (await resp.json()) as { account: Account }; - - return respJson.account; - } - - async getAvailableBalance(address: string): Promise { - let resp = await fetch( - `${this.base_rest_api_url}/cosmos/bank/v1beta1/balances/${address}` - ); - let respJson = (await resp.json()) as { balances: Coin[] }; - - return respJson.balances; - } - - async distributionGetRewards(address: string): Promise { - let resp = await fetch( - `${this.base_rest_api_url}/cosmos/distribution/v1beta1/delegators/${address}/rewards` - ); - let respJson = (await resp.json()) as RewardsResponse; - - return Number(respJson?.total?.[0]?.amount ?? '0'); - } - - async getAllDelegations( - address: string, - offset: number, - should_count_total: boolean, - limit?: number - ) { - // order of query params: count_total -> offset -> limit - const pagination_count_total = should_count_total - ? 'pagination.count_total=true' - : 'pagination.count_total=false'; - const pagination_limit = `pagination.limit=${ - limit ? limit : REST_API_PAGINATION_LIMIT - }`; - const pagination_offset = `pagination.offset=${offset}`; - // NOTE: be cautious of newlines or spaces. Might make the request URL malformed - const resp = await fetch( - `${this.base_rest_api_url}/cosmos/staking/v1beta1/delegations/${address}?${pagination_count_total}&${pagination_limit}&${pagination_offset}` - ); - - return (await resp.json()) as DelegationsResponse; - } - - async getAllUnbondingDelegations( - address: string, - offset: number, - should_count_total: boolean - ) { - // order of query params: count_total -> offset -> limit - const pagination_count_total = should_count_total - ? 'pagination.count_total=true' - : 'pagination.count_total=false'; - const pagination_limit = `pagination.limit=${REST_API_PAGINATION_LIMIT}`; - const pagination_offset = `pagination.offset=${offset}`; - // NOTE: be cautious of new lines or spaces. Might make the request URL malformed - const resp = await fetch( - `${this.base_rest_api_url}/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations?${pagination_count_total}&${pagination_limit}&${pagination_offset}` - ); - - return (await resp.json()) as UnbondingResponse; - } + constructor(public readonly base_rest_api_url: string) {} + + async getAccountInfo(address: string): Promise { + let resp = await fetch(`${this.base_rest_api_url}/cosmos/auth/v1beta1/accounts/${address}`); + let respJson = (await resp.json()) as { account: Account }; + + return respJson.account; + } + + async getAvailableBalance(address: string): Promise { + let resp = await fetch(`${this.base_rest_api_url}/cosmos/bank/v1beta1/balances/${address}`); + let respJson = (await resp.json()) as { balances: Coin[] }; + + return respJson.balances; + } + + async distributionGetRewards(address: string): Promise { + let resp = await fetch(`${this.base_rest_api_url}/cosmos/distribution/v1beta1/delegators/${address}/rewards`); + let respJson = (await resp.json()) as RewardsResponse; + + return Number(respJson?.total?.[0]?.amount ?? '0'); + } + + async getAllDelegations(address: string, offset: number, should_count_total: boolean, limit?: number) { + // order of query params: count_total -> offset -> limit + const pagination_count_total = should_count_total + ? 'pagination.count_total=true' + : 'pagination.count_total=false'; + const pagination_limit = `pagination.limit=${limit ? limit : REST_API_PAGINATION_LIMIT}`; + const pagination_offset = `pagination.offset=${offset}`; + // NOTE: be cautious of newlines or spaces. Might make the request URL malformed + const resp = await fetch( + `${this.base_rest_api_url}/cosmos/staking/v1beta1/delegations/${address}?${pagination_count_total}&${pagination_limit}&${pagination_offset}` + ); + + return (await resp.json()) as DelegationsResponse; + } + + async getAllUnbondingDelegations(address: string, offset: number, should_count_total: boolean) { + // order of query params: count_total -> offset -> limit + const pagination_count_total = should_count_total + ? 'pagination.count_total=true' + : 'pagination.count_total=false'; + const pagination_limit = `pagination.limit=${REST_API_PAGINATION_LIMIT}`; + const pagination_offset = `pagination.offset=${offset}`; + // NOTE: be cautious of new lines or spaces. Might make the request URL malformed + const resp = await fetch( + `${this.base_rest_api_url}/cosmos/staking/v1beta1/delegators/${address}/unbonding_delegations?${pagination_count_total}&${pagination_limit}&${pagination_offset}` + ); + + return (await resp.json()) as UnbondingResponse; + } } diff --git a/src/bindings.d.ts b/src/bindings.d.ts index 931a0958..b1d03a09 100644 --- a/src/bindings.d.ts +++ b/src/bindings.d.ts @@ -1,12 +1,12 @@ declare global { - const TOKEN_EXPONENT: number; - const REST_API: string; - const REST_API_PAGINATION_LIMIT: number; - const GRAPHQL_API: string; - const CIRCULATING_SUPPLY_WATCHLIST: KVNamespace; - const CIRCULATING_SUPPLY_GROUPS: number; - const MARKET_MONITORING_API: string; - const WEBHOOK_URL: string; + const TOKEN_EXPONENT: number; + const REST_API: string; + const REST_API_PAGINATION_LIMIT: number; + const GRAPHQL_API: string; + const CIRCULATING_SUPPLY_WATCHLIST: KVNamespace; + const CIRCULATING_SUPPLY_GROUPS: number; + const MARKET_MONITORING_API: string; + const WEBHOOK_URL: string; } export {}; diff --git a/src/handlers/allArbitrageOpportunities.ts b/src/handlers/allArbitrageOpportunities.ts index 6d1177f0..83adeb09 100644 --- a/src/handlers/allArbitrageOpportunities.ts +++ b/src/handlers/allArbitrageOpportunities.ts @@ -1,16 +1,14 @@ -import { MarketMonitorApi } from "../api/marketMonitorApi"; +import { MarketMonitorApi } from '../api/marketMonitorApi'; export async function fetchPrices() { - let market_monitor_api = new MarketMonitorApi( - `${MARKET_MONITORING_API}` - ); - return await market_monitor_api.getMarketMonitoringData(); + let market_monitor_api = new MarketMonitorApi(`${MARKET_MONITORING_API}`); + return await market_monitor_api.getMarketMonitoringData(); } export async function handler(request: Request): Promise { - const payload = await fetchPrices(); - return new Response(JSON.stringify(payload, null, 2), { - headers: { - "content-type": "application/json;charset=UTF-8", - }, - }); + const payload = await fetchPrices(); + return new Response(JSON.stringify(payload, null, 2), { + headers: { + 'content-type': 'application/json;charset=UTF-8', + }, + }); } diff --git a/src/handlers/arbitrageOpportunities.ts b/src/handlers/arbitrageOpportunities.ts index bc6cdede..d967d004 100644 --- a/src/handlers/arbitrageOpportunities.ts +++ b/src/handlers/arbitrageOpportunities.ts @@ -2,29 +2,25 @@ import { MarketMonitorApi } from '../api/marketMonitorApi'; import { ArbitrageOpportunity } from '../types/marketMonitor'; async function fetchPrices() { - let market_monitor_api = new MarketMonitorApi( - `${MARKET_MONITORING_API}` - ); - return await market_monitor_api.getMarketMonitoringData(); + let market_monitor_api = new MarketMonitorApi(`${MARKET_MONITORING_API}`); + return await market_monitor_api.getMarketMonitoringData(); } -export async function filterArbitrageOpportunities(): Promise< - ArbitrageOpportunity[] -> { - const payload = await fetchPrices(); - const arbitrage_opportunities = []; - for (let i = 0; i < payload.arbitrageOpportunities.length; i++) { - if (payload.arbitrageOpportunities[i].arbitragePossible) { - arbitrage_opportunities.push(payload.arbitrageOpportunities[i]); - } - } - return arbitrage_opportunities; +export async function filterArbitrageOpportunities(): Promise { + const payload = await fetchPrices(); + const arbitrage_opportunities = []; + for (let i = 0; i < payload.arbitrageOpportunities.length; i++) { + if (payload.arbitrageOpportunities[i].arbitragePossible) { + arbitrage_opportunities.push(payload.arbitrageOpportunities[i]); + } + } + return arbitrage_opportunities; } export async function handler(request: Request): Promise { - const arbitrage_opportunities = await filterArbitrageOpportunities(); - return new Response(JSON.stringify(arbitrage_opportunities, null, 2), { - headers: { - 'content-type': 'application/json;charset=UTF-8', - }, - }); + const arbitrage_opportunities = await filterArbitrageOpportunities(); + return new Response(JSON.stringify(arbitrage_opportunities, null, 2), { + headers: { + 'content-type': 'application/json;charset=UTF-8', + }, + }); } diff --git a/src/handlers/circulatingSupply.ts b/src/handlers/circulatingSupply.ts index bbf5fed2..6644a868 100644 --- a/src/handlers/circulatingSupply.ts +++ b/src/handlers/circulatingSupply.ts @@ -2,12 +2,11 @@ import { Request } from 'itty-router'; import { getCirculatingSupply } from '../helpers/circulating'; export async function handler(request: Request): Promise { - try { - let circulating_supply = await getCirculatingSupply(); - return new Response(circulating_supply); - } - catch (err: any) { - console.log(err); - throw new Error(err.message); - } + try { + let circulating_supply = await getCirculatingSupply(); + return new Response(circulating_supply); + } catch (err: any) { + console.log(err); + throw new Error(err.message); + } } diff --git a/src/handlers/liquidBalance.ts b/src/handlers/liquidBalance.ts index eb34969b..e86f687d 100644 --- a/src/handlers/liquidBalance.ts +++ b/src/handlers/liquidBalance.ts @@ -1,35 +1,44 @@ -import { Request } from "itty-router"; -import { isDelayedVestingAccount, isVestingAccount, isValidAddress } from "../helpers/validate"; -import { NodeApi } from "../api/nodeApi"; -import { calculateVesting } from "../helpers/vesting"; -import { convertToMainTokenDenom } from "../helpers/currency"; +import { Request } from 'itty-router'; +import { isDelayedVestingAccount, isVestingAccount, isValidAddress } from '../helpers/validate'; +import { NodeApi } from '../api/nodeApi'; +import { calculateVesting } from '../helpers/vesting'; +import { convertToMainTokenDenom } from '../helpers/currency'; export async function handler(request: Request): Promise { - const address = request.params?.['address']; - - if (!address || !isValidAddress(address)) { - throw new Error("No address specified or wrong address format."); - } - - let api = new NodeApi(REST_API); - const account = await api.getAccountInfo(address) - - if (!isVestingAccount(account["@type"])) { - throw new Error(`Only vesting accounts are supported. Accounts type '${account["@type"]}'.`) - } - - if(isDelayedVestingAccount(account?.["@type"])) { - let balance = account?.base_vesting_account?.base_account?.sequence !== '0' ? Number(await (await api.getAvailableBalance(address)).find(b => b.denom === "ncheq")?.amount ?? '0') : 0; - let rewards = Number(await (await api.distributionGetRewards(address)) ?? '0'); - let delegated = Number(account?.base_vesting_account?.delegated_free?.find(d => d.denom === "ncheq")?.amount ?? '0'); - - return new Response(convertToMainTokenDenom(balance + rewards + delegated)); - } - - let vested_coins = Number(calculateVesting(account)?.vested); - let balance = Number(await (await api.getAvailableBalance(address)).find(b => b.denom === "ncheq")?.amount ?? '0') - let rewards = Number(await (await api.distributionGetRewards(address)) ?? '0'); - let liquid_coins = vested_coins + balance + rewards; - - return new Response(convertToMainTokenDenom(liquid_coins)); + const address = request.params?.['address']; + + if (!address || !isValidAddress(address)) { + throw new Error('No address specified or wrong address format.'); + } + + let api = new NodeApi(REST_API); + const account = await api.getAccountInfo(address); + + if (!isVestingAccount(account['@type'])) { + throw new Error(`Only vesting accounts are supported. Accounts type '${account['@type']}'.`); + } + + if (isDelayedVestingAccount(account?.['@type'])) { + let balance = + account?.base_vesting_account?.base_account?.sequence !== '0' + ? Number( + (await (await api.getAvailableBalance(address)).find((b) => b.denom === 'ncheq')?.amount) ?? '0' + ) + : 0; + let rewards = Number((await await api.distributionGetRewards(address)) ?? '0'); + let delegated = Number( + account?.base_vesting_account?.delegated_free?.find((d) => d.denom === 'ncheq')?.amount ?? '0' + ); + + return new Response(convertToMainTokenDenom(balance + rewards + delegated)); + } + + let vested_coins = Number(calculateVesting(account)?.vested); + let balance = Number( + (await (await api.getAvailableBalance(address)).find((b) => b.denom === 'ncheq')?.amount) ?? '0' + ); + let rewards = Number((await await api.distributionGetRewards(address)) ?? '0'); + let liquid_coins = vested_coins + balance + rewards; + + return new Response(convertToMainTokenDenom(liquid_coins)); } diff --git a/src/handlers/totalBalance.ts b/src/handlers/totalBalance.ts index 28fd0892..e3f2bb0b 100644 --- a/src/handlers/totalBalance.ts +++ b/src/handlers/totalBalance.ts @@ -2,9 +2,7 @@ import { Request } from 'itty-router'; import { fetchAccountBalances } from '../helpers/balance'; export async function handler(request: Request): Promise { - const address = request.params?.['address']; - let account_balance_infos = await fetchAccountBalances( - address!! - ); - return new Response(account_balance_infos?.totalBalance.toString()); + const address = request.params?.['address']; + let account_balance_infos = await fetchAccountBalances(address!!); + return new Response(account_balance_infos?.totalBalance.toString()); } diff --git a/src/handlers/totalStakedCoins.ts b/src/handlers/totalStakedCoins.ts index cb7abf89..d0031e4d 100644 --- a/src/handlers/totalStakedCoins.ts +++ b/src/handlers/totalStakedCoins.ts @@ -4,10 +4,10 @@ import { convertToMainTokenDenom } from '../helpers/currency'; import { GraphQLClient } from '../helpers/graphql'; export async function handler(request: Request): Promise { - let gql_client = new GraphQLClient(GRAPHQL_API); - let bd_api = new BigDipperApi(gql_client); + let gql_client = new GraphQLClient(GRAPHQL_API); + let bd_api = new BigDipperApi(gql_client); - let total_staked_coins = await bd_api.getTotalStakedCoins(); + let total_staked_coins = await bd_api.getTotalStakedCoins(); - return new Response(convertToMainTokenDenom(Number(total_staked_coins))); + return new Response(convertToMainTokenDenom(Number(total_staked_coins))); } diff --git a/src/handlers/totalSupply.ts b/src/handlers/totalSupply.ts index 55c950b5..0eba2443 100644 --- a/src/handlers/totalSupply.ts +++ b/src/handlers/totalSupply.ts @@ -4,8 +4,8 @@ import { convertToMainTokenDenom } from '../helpers/currency'; import { GraphQLClient } from '../helpers/graphql'; export async function handler(request: Request): Promise { - let gql_client = new GraphQLClient(GRAPHQL_API); - let bd_api = new BigDipperApi(gql_client); - const total_supply = await bd_api.getTotalSupply(); - return new Response(convertToMainTokenDenom(total_supply)); + let gql_client = new GraphQLClient(GRAPHQL_API); + let bd_api = new BigDipperApi(gql_client); + const total_supply = await bd_api.getTotalSupply(); + return new Response(convertToMainTokenDenom(total_supply)); } diff --git a/src/handlers/vestedBalance.ts b/src/handlers/vestedBalance.ts index afb261fa..6f2a3414 100644 --- a/src/handlers/vestedBalance.ts +++ b/src/handlers/vestedBalance.ts @@ -1,29 +1,24 @@ import { Request } from 'itty-router'; -import { - isVestingAccount, - isValidAddress, -} from '../helpers/validate'; +import { isVestingAccount, isValidAddress } from '../helpers/validate'; import { NodeApi } from '../api/nodeApi'; import { calculateVesting } from '../helpers/vesting'; import { convertToMainTokenDenom } from '../helpers/currency'; export async function handler(request: Request): Promise { - const address = request.params?.['address']; + const address = request.params?.['address']; - if (!address || !isValidAddress(address)) { - throw new Error('No address specified or wrong address format.'); - } + if (!address || !isValidAddress(address)) { + throw new Error('No address specified or wrong address format.'); + } - let api = new NodeApi(REST_API); - const account = await api.getAccountInfo(address); + let api = new NodeApi(REST_API); + const account = await api.getAccountInfo(address); - if (!isVestingAccount(account['@type'])) { - throw new Error( - `Only vesting accounts are supported. Accounts type '${account['@type']}'.` - ); - } + if (!isVestingAccount(account['@type'])) { + throw new Error(`Only vesting accounts are supported. Accounts type '${account['@type']}'.`); + } - let vested_coins = calculateVesting(account)?.vested; + let vested_coins = calculateVesting(account)?.vested; - return new Response(convertToMainTokenDenom(vested_coins!!)); + return new Response(convertToMainTokenDenom(vested_coins!!)); } diff --git a/src/handlers/vestingBalance.ts b/src/handlers/vestingBalance.ts index cc34551e..211bcc43 100644 --- a/src/handlers/vestingBalance.ts +++ b/src/handlers/vestingBalance.ts @@ -1,29 +1,24 @@ import { Request } from 'itty-router'; -import { - isVestingAccount, - isValidAddress, -} from '../helpers/validate'; +import { isVestingAccount, isValidAddress } from '../helpers/validate'; import { NodeApi } from '../api/nodeApi'; import { calculateVesting } from '../helpers/vesting'; import { convertToMainTokenDenom } from '../helpers/currency'; export async function handler(request: Request): Promise { - const address = request.params?.['address']; + const address = request.params?.['address']; - if (!address || !isValidAddress(address)) { - throw new Error('No address specified or wrong address format.'); - } + if (!address || !isValidAddress(address)) { + throw new Error('No address specified or wrong address format.'); + } - let api = new NodeApi(REST_API); - const account = await api.getAccountInfo(address); + let api = new NodeApi(REST_API); + const account = await api.getAccountInfo(address); - if (!isVestingAccount(account['@type'])) { - throw new Error( - `Only vesting accounts are supported. Accounts type '${account['@type']}'.` - ); - } + if (!isVestingAccount(account['@type'])) { + throw new Error(`Only vesting accounts are supported. Accounts type '${account['@type']}'.`); + } - let vestingCoins = calculateVesting(account)?.vesting; + let vestingCoins = calculateVesting(account)?.vesting; - return new Response(convertToMainTokenDenom(vestingCoins!!)); + return new Response(convertToMainTokenDenom(vestingCoins!!)); } diff --git a/src/handlers/webhookTriggers.ts b/src/handlers/webhookTriggers.ts index 602d9cae..a81e6068 100644 --- a/src/handlers/webhookTriggers.ts +++ b/src/handlers/webhookTriggers.ts @@ -2,49 +2,49 @@ import { updateCirculatingSupply } from '../helpers/circulating'; import { filterArbitrageOpportunities } from './arbitrageOpportunities'; export async function webhookTriggers(event: ScheduledEvent) { - console.log('Triggering webhook...'); - await sendPriceDiscrepancies(); + console.log('Triggering webhook...'); + await sendPriceDiscrepancies(); - await updateCirculatingSupply(getHour()); + await updateCirculatingSupply(getHour()); } export async function sendPriceDiscrepancies() { - try { - console.log('Sending price discrepancies...'); + try { + console.log('Sending price discrepancies...'); - const arbitrageOpportunities = await filterArbitrageOpportunities(); - const hasArbitrageOpportunities = arbitrageOpportunities.length > 0; - if (hasArbitrageOpportunities) { - console.log('Arbitrage opportunities...'); - try { - const init = { - body: JSON.stringify({ - arbitrage_opportunities: arbitrageOpportunities, - }), - method: 'POST', - headers: { - 'content-type': 'application/json;charset=UTF-8', - }, - }; + const arbitrageOpportunities = await filterArbitrageOpportunities(); + const hasArbitrageOpportunities = arbitrageOpportunities.length > 0; + if (hasArbitrageOpportunities) { + console.log('Arbitrage opportunities...'); + try { + const init = { + body: JSON.stringify({ + arbitrage_opportunities: arbitrageOpportunities, + }), + method: 'POST', + headers: { + 'content-type': 'application/json;charset=UTF-8', + }, + }; - await fetch(WEBHOOK_URL, init); - } catch (err: any) { - console.log(err); - } - } - } catch (e) { - console.log('Error at: ', 'sendPriceDiscrepancies'); - } + await fetch(WEBHOOK_URL, init); + } catch (err: any) { + console.log(err); + } + } + } catch (e) { + console.log('Error at: ', 'sendPriceDiscrepancies'); + } } function getHour(): number { - // This function only works when CIRCULATING_SUPPLY_GROUPS is set to 24 - let hour = Number( (new Date().getHours()) + 1 ); // getHours() returns 0-23 - return hour; + // This function only works when CIRCULATING_SUPPLY_GROUPS is set to 24 + let hour = Number(new Date().getHours() + 1); // getHours() returns 0-23 + return hour; } function getRandomGroup(group: number): number { - let min = 1; - let max = Math.floor(group); - return Math.floor(Math.random() * (max - min + 1)) + min; + let min = 1; + let max = Math.floor(group); + return Math.floor(Math.random() * (max - min + 1)) + min; } diff --git a/src/helpers/balance.ts b/src/helpers/balance.ts index 656549c7..af8bfb8d 100644 --- a/src/helpers/balance.ts +++ b/src/helpers/balance.ts @@ -1,133 +1,106 @@ import { NodeApi } from '../api/nodeApi'; -import { - AccountBalanceInfos, - DelegationsResponse, - UnbondingResponse -} from '../types/node'; +import { AccountBalanceInfos, DelegationsResponse, UnbondingResponse } from '../types/node'; import { convertToMainTokenDenom } from './currency'; -import { } from '../types/node'; - -export async function fetchAccountBalances( - address: string -): Promise { - const node_api = new NodeApi(REST_API); - const available_balance = await node_api.getAvailableBalance(address); - - let available_balance_in_ncheq = 0; - if (available_balance.length > 0) { - available_balance_in_ncheq = Number(available_balance[0]?.amount); - } - - const reward_balance_in_ncheq = await node_api.distributionGetRewards( - address - ); - const total_delegation_balance_in_ncheq = - await calculateTotalDelegationBalance( - await node_api.getAllDelegations( - address, - 0, // first call - true - ), - Number(REST_API_PAGINATION_LIMIT) // second call - ); - - const total_unbonding_balance_in_ncheq = - await calculateTotalUnbondingBalance( - await node_api.getAllUnbondingDelegations( - address, - 0, // first call - true - ), - Number(REST_API_PAGINATION_LIMIT) // second call - ); - - return { - totalBalance: Number( - convertToMainTokenDenom( - available_balance_in_ncheq + - reward_balance_in_ncheq + - total_delegation_balance_in_ncheq + - total_unbonding_balance_in_ncheq - ) - ), - availableBalance: Number(convertToMainTokenDenom(available_balance_in_ncheq)), - rewards: Number(convertToMainTokenDenom(reward_balance_in_ncheq)), - delegated: Number(convertToMainTokenDenom(total_delegation_balance_in_ncheq)), - unbonding: Number(convertToMainTokenDenom(total_unbonding_balance_in_ncheq)), - timeUpdated: new Date().toUTCString(), - }; +import {} from '../types/node'; + +export async function fetchAccountBalances(address: string): Promise { + const node_api = new NodeApi(REST_API); + const available_balance = await node_api.getAvailableBalance(address); + + let available_balance_in_ncheq = 0; + if (available_balance.length > 0) { + available_balance_in_ncheq = Number(available_balance[0]?.amount); + } + + const reward_balance_in_ncheq = await node_api.distributionGetRewards(address); + const total_delegation_balance_in_ncheq = await calculateTotalDelegationBalance( + await node_api.getAllDelegations( + address, + 0, // first call + true + ), + Number(REST_API_PAGINATION_LIMIT) // second call + ); + + const total_unbonding_balance_in_ncheq = await calculateTotalUnbondingBalance( + await node_api.getAllUnbondingDelegations( + address, + 0, // first call + true + ), + Number(REST_API_PAGINATION_LIMIT) // second call + ); + + return { + totalBalance: Number( + convertToMainTokenDenom( + available_balance_in_ncheq + + reward_balance_in_ncheq + + total_delegation_balance_in_ncheq + + total_unbonding_balance_in_ncheq + ) + ), + availableBalance: Number(convertToMainTokenDenom(available_balance_in_ncheq)), + rewards: Number(convertToMainTokenDenom(reward_balance_in_ncheq)), + delegated: Number(convertToMainTokenDenom(total_delegation_balance_in_ncheq)), + unbonding: Number(convertToMainTokenDenom(total_unbonding_balance_in_ncheq)), + timeUpdated: new Date().toUTCString(), + }; } export async function calculateTotalDelegationBalance( - delegationsResp: DelegationsResponse, - current_offset: number + delegationsResp: DelegationsResponse, + current_offset: number ): Promise { - let total_delegation_balance_in_ncheq = 0; - const total_count = Number(delegationsResp.pagination.total); - - for (let i = 0; i < delegationsResp.delegation_responses.length; i++) { - total_delegation_balance_in_ncheq += Number( - delegationsResp.delegation_responses[i].balance.amount - ); - } - - if (current_offset < total_count) { - const node_api = new NodeApi(REST_API); - const delegator_address = - delegationsResp.delegation_responses[0].delegation.delegator_address; - - const resp = await node_api.getAllDelegations( - delegator_address, - current_offset, // our current offset will be updated by recursive call below - true // we count total again , since it's implemented recursively - ); - - total_delegation_balance_in_ncheq += - await calculateTotalDelegationBalance( - resp, - current_offset + Number(REST_API_PAGINATION_LIMIT) - ); - } - - return total_delegation_balance_in_ncheq; + let total_delegation_balance_in_ncheq = 0; + const total_count = Number(delegationsResp.pagination.total); + + for (let i = 0; i < delegationsResp.delegation_responses.length; i++) { + total_delegation_balance_in_ncheq += Number(delegationsResp.delegation_responses[i].balance.amount); + } + + if (current_offset < total_count) { + const node_api = new NodeApi(REST_API); + const delegator_address = delegationsResp.delegation_responses[0].delegation.delegator_address; + + const resp = await node_api.getAllDelegations( + delegator_address, + current_offset, // our current offset will be updated by recursive call below + true // we count total again , since it's implemented recursively + ); + + total_delegation_balance_in_ncheq += await calculateTotalDelegationBalance( + resp, + current_offset + Number(REST_API_PAGINATION_LIMIT) + ); + } + + return total_delegation_balance_in_ncheq; } export async function calculateTotalUnbondingBalance( - unbondingResp: UnbondingResponse, - current_offset: number + unbondingResp: UnbondingResponse, + current_offset: number ): Promise { - let total_unbonding_balance_in_ncheq = 0; - const total_count = Number(unbondingResp.pagination.total); - for (let i = 0; i < unbondingResp.unbonding_responses.length; i++) { - for ( - let j = 0; - j < unbondingResp.unbonding_responses[i].entries.length; - j++ - ) { - total_unbonding_balance_in_ncheq += Number( - unbondingResp.unbonding_responses[i].entries[j].balance - ); - } - } - - if (current_offset < total_count) { - const node_api = new NodeApi(REST_API); - const delegator_address = - unbondingResp.unbonding_responses[0].delegator_address; - - const resp = - await node_api.getAllUnbondingDelegations( - delegator_address, - current_offset, - true - ); - - total_unbonding_balance_in_ncheq += - await calculateTotalUnbondingBalance( - resp, - current_offset + Number(REST_API_PAGINATION_LIMIT) - ); - } - - return total_unbonding_balance_in_ncheq; + let total_unbonding_balance_in_ncheq = 0; + const total_count = Number(unbondingResp.pagination.total); + for (let i = 0; i < unbondingResp.unbonding_responses.length; i++) { + for (let j = 0; j < unbondingResp.unbonding_responses[i].entries.length; j++) { + total_unbonding_balance_in_ncheq += Number(unbondingResp.unbonding_responses[i].entries[j].balance); + } + } + + if (current_offset < total_count) { + const node_api = new NodeApi(REST_API); + const delegator_address = unbondingResp.unbonding_responses[0].delegator_address; + + const resp = await node_api.getAllUnbondingDelegations(delegator_address, current_offset, true); + + total_unbonding_balance_in_ncheq += await calculateTotalUnbondingBalance( + resp, + current_offset + Number(REST_API_PAGINATION_LIMIT) + ); + } + + return total_unbonding_balance_in_ncheq; } diff --git a/src/helpers/circulating.ts b/src/helpers/circulating.ts index cc274832..29c330c3 100644 --- a/src/helpers/circulating.ts +++ b/src/helpers/circulating.ts @@ -6,85 +6,74 @@ import { BigDipperApi } from '../api/bigDipperApi'; import { GraphQLClient } from '../helpers/graphql'; export async function updateCirculatingSupply(groupNumber: number) { - try { - const cached = await CIRCULATING_SUPPLY_WATCHLIST.list({ - prefix: `group_${groupNumber}:`, - }); + try { + const cached = await CIRCULATING_SUPPLY_WATCHLIST.list({ + prefix: `group_${groupNumber}:`, + }); - console.log( - `found ${cached.keys.length} cached accounts for group ${groupNumber}` - ); + console.log(`found ${cached.keys.length} cached accounts for group ${groupNumber}`); - for (const key of cached.keys) { - const parts = extractPrefixAndKey(key.name); - let addr = parts.address; - let grpN = parts.groupNumber; + for (const key of cached.keys) { + const parts = extractPrefixAndKey(key.name); + let addr = parts.address; + let grpN = parts.groupNumber; - const found = await CIRCULATING_SUPPLY_WATCHLIST.get( - `group_${grpN}:${addr}` - ); - if (found) { - console.log(`found ${key.name} (addr=${addr}) grp=${grpN}`); + const found = await CIRCULATING_SUPPLY_WATCHLIST.get(`group_${grpN}:${addr}`); + if (found) { + console.log(`found ${key.name} (addr=${addr}) grp=${grpN}`); - const account = await updateCachedBalance(addr, grpN); + const account = await updateCachedBalance(addr, grpN); - if (account !== null) { - console.log( - `updating account (group_${grpN}:${addr}) balance (${JSON.stringify( - account - )})` - ); - } - } - } - } catch (e) { - console.log('Error at: ', 'updateCirculatingSupply'); - } + if (account !== null) { + console.log(`updating account (group_${grpN}:${addr}) balance (${JSON.stringify(account)})`); + } + } + } + } catch (e) { + console.log('Error at: ', 'updateCirculatingSupply'); + } } export async function updateCachedBalance(addr: string, grpN: number) { - try { - const account_balance_infos = await fetchAccountBalances( - addr - ); + try { + const account_balance_infos = await fetchAccountBalances(addr); - const data = JSON.stringify(account_balance_infos); + const data = JSON.stringify(account_balance_infos); - await CIRCULATING_SUPPLY_WATCHLIST.put(`group_${grpN}:${addr}`, data); + await CIRCULATING_SUPPLY_WATCHLIST.put(`group_${grpN}:${addr}`, data); - console.log(`account "${addr}" balance updated. (${data})`); - } catch (e: any) { - console.log(`error updateCachedBalance: ${e}`); - } + console.log(`account "${addr}" balance updated. (${data})`); + } catch (e: any) { + console.log(`error updateCachedBalance: ${e}`); + } } export async function getCirculatingSupply(): Promise { - let gql_client = new GraphQLClient(GRAPHQL_API); - let bd_api = new BigDipperApi(gql_client); - let total_supply_ncheq = await bd_api.getTotalSupply(); - const total_supply = Number(convertToMainTokenDenom(total_supply_ncheq)); + let gql_client = new GraphQLClient(GRAPHQL_API); + let bd_api = new BigDipperApi(gql_client); + let total_supply_ncheq = await bd_api.getTotalSupply(); + const total_supply = Number(convertToMainTokenDenom(total_supply_ncheq)); - try { - const cached = await CIRCULATING_SUPPLY_WATCHLIST.list(); - console.log(`Total cached entries: ${cached.keys.length}`); - let shareholders_total_balance = Number(0); - for (const key of cached.keys) { - let data: AccountBalanceInfos | null = - await CIRCULATING_SUPPLY_WATCHLIST.get(key.name, { - type: 'json', - }); + try { + const cached = await CIRCULATING_SUPPLY_WATCHLIST.list(); + console.log(`Total cached entries: ${cached.keys.length}`); + let shareholders_total_balance = Number(0); + for (const key of cached.keys) { + let data: AccountBalanceInfos | null = await CIRCULATING_SUPPLY_WATCHLIST.get(key.name, { + type: 'json', + }); - if (data !== null && data.totalBalance !== null) { - shareholders_total_balance += Number(data.totalBalance); - } - } + if (data !== null && data.totalBalance !== null) { + shareholders_total_balance += Number(data.totalBalance); + } + } - console.log('Total supply', total_supply); - console.log(`Watchlist total balance: ${shareholders_total_balance}`); + console.log('Total supply', total_supply); + console.log(`Watchlist total balance: ${shareholders_total_balance}`); - let circulating_supply = total_supply - shareholders_total_balance; - return circulating_supply.toString(); - } catch (e: any) { - throw new Error(e.toString); - } + let circulating_supply = total_supply - shareholders_total_balance; + return circulating_supply.toString(); + } catch (e: any) { + throw new Error(e.toString); + } } diff --git a/src/helpers/currency.ts b/src/helpers/currency.ts index 560224e1..5f0349fa 100644 --- a/src/helpers/currency.ts +++ b/src/helpers/currency.ts @@ -1,9 +1,9 @@ -import { TOKEN_DECIMALS } from "./constants"; +import { TOKEN_DECIMALS } from './constants'; export function convertToLowestDenom(ncheq: number): number { - return ncheq / TOKEN_DECIMALS; + return ncheq / TOKEN_DECIMALS; } export function convertToMainTokenDenom(ncheq: number): string { - return convertToLowestDenom(ncheq).toFixed(0); + return convertToLowestDenom(ncheq).toFixed(0); } diff --git a/src/helpers/graphql.ts b/src/helpers/graphql.ts index bb9daab3..96ccfbf9 100644 --- a/src/helpers/graphql.ts +++ b/src/helpers/graphql.ts @@ -1,24 +1,23 @@ export class GraphQLClient { - constructor(public readonly base_url: string) { - } + constructor(public readonly base_url: string) {} - async query(query: string, variables: Object = {}): Promise { - let req = { - query, - variables, - } + async query(query: string, variables: Object = {}): Promise { + let req = { + query, + variables, + }; - let resp = await fetch(this.base_url, { - method: "POST", - body: JSON.stringify(req) - }) + let resp = await fetch(this.base_url, { + method: 'POST', + body: JSON.stringify(req), + }); - let json: { errors: any } = await resp.json() + let json: { errors: any } = await resp.json(); - if (json.errors) { - throw new Error(`Query failed: ${JSON.stringify(json.errors)}`) - } + if (json.errors) { + throw new Error(`Query failed: ${JSON.stringify(json.errors)}`); + } - return json as T; - } + return json as T; + } } diff --git a/src/helpers/kv.ts b/src/helpers/kv.ts index 722c4205..25b82ea5 100644 --- a/src/helpers/kv.ts +++ b/src/helpers/kv.ts @@ -1,9 +1,9 @@ export function extractPrefixAndKey(key: string) { - const parts = key.split(':'); - let addr = parts[1]; - let grpN = Number(parts[0].split('_')[1]); - return { - address: addr, - groupNumber: grpN, - }; + const parts = key.split(':'); + let addr = parts[1]; + let grpN = Number(parts[0].split('_')[1]); + return { + address: addr, + groupNumber: grpN, + }; } diff --git a/src/helpers/validate.ts b/src/helpers/validate.ts index aff5344a..dd87851e 100644 --- a/src/helpers/validate.ts +++ b/src/helpers/validate.ts @@ -1,16 +1,19 @@ // TODO: This doesn't take checksum into account export function isValidAddress(address: string): boolean { - return /^(cheqd)1[a-z0-9]{38}$/.test(address) + return /^(cheqd)1[a-z0-9]{38}$/.test(address); } export function isVestingAccount(account_type: string): boolean { - return account_type === '/cosmos.vesting.v1beta1.ContinuousVestingAccount' || account_type === '/cosmos.vesting.v1beta1.DelayedVestingAccount'; + return ( + account_type === '/cosmos.vesting.v1beta1.ContinuousVestingAccount' || + account_type === '/cosmos.vesting.v1beta1.DelayedVestingAccount' + ); } export function isContinuousVestingAccount(account_type: string): boolean { - return account_type === '/cosmos.vesting.v1beta1.ContinuousVestingAccount'; + return account_type === '/cosmos.vesting.v1beta1.ContinuousVestingAccount'; } export function isDelayedVestingAccount(account_type: string): boolean { - return account_type === '/cosmos.vesting.v1beta1.DelayedVestingAccount'; + return account_type === '/cosmos.vesting.v1beta1.DelayedVestingAccount'; } diff --git a/src/helpers/vesting.ts b/src/helpers/vesting.ts index a929ade5..f5b355a1 100644 --- a/src/helpers/vesting.ts +++ b/src/helpers/vesting.ts @@ -1,50 +1,42 @@ import { Account } from '../types/node'; -import { - isContinuousVestingAccount, - isDelayedVestingAccount, -} from './validate'; +import { isContinuousVestingAccount, isDelayedVestingAccount } from './validate'; // Taken from our wallet app export function calculateVesting(account: Account, t?: Date) { - if (!t) { - t = new Date(); - } - - if (isContinuousVestingAccount(account?.['@type'])) { - const startsAt = account.start_time; - const endsAt = account.base_vesting_account.end_time; - - const totalCoins = Number( - account.base_vesting_account.original_vesting[0]?.amount - ); - - const elapsed = t.getTime() - new Date(startsAt * 1000).getTime(); - const delta = - new Date(endsAt * 1000).getTime() - new Date(startsAt * 1000).getTime(); - - const doneRatio = Math.min(1.0, Math.max(0, elapsed / delta)); - const vested = Math.ceil(Number(totalCoins) * doneRatio); - const vesting = Math.ceil(Number(totalCoins) * (1.0 - doneRatio)); - - return { - vested, - vesting, - }; - } - if (isDelayedVestingAccount(account?.['@type'])) { - const endsAt = account.base_vesting_account.end_time; - - const originalVesting = Number( - account.base_vesting_account.original_vesting[0]?.amount - ); - - const doneRatio = t > new Date(endsAt) ? 1 : 0; - const vested = Math.ceil(Number(originalVesting) * doneRatio); - const vesting = Math.ceil(Number(originalVesting) * (1.0 - doneRatio)); - - return { - vested, - vesting, - }; - } + if (!t) { + t = new Date(); + } + + if (isContinuousVestingAccount(account?.['@type'])) { + const startsAt = account.start_time; + const endsAt = account.base_vesting_account.end_time; + + const totalCoins = Number(account.base_vesting_account.original_vesting[0]?.amount); + + const elapsed = t.getTime() - new Date(startsAt * 1000).getTime(); + const delta = new Date(endsAt * 1000).getTime() - new Date(startsAt * 1000).getTime(); + + const doneRatio = Math.min(1.0, Math.max(0, elapsed / delta)); + const vested = Math.ceil(Number(totalCoins) * doneRatio); + const vesting = Math.ceil(Number(totalCoins) * (1.0 - doneRatio)); + + return { + vested, + vesting, + }; + } + if (isDelayedVestingAccount(account?.['@type'])) { + const endsAt = account.base_vesting_account.end_time; + + const originalVesting = Number(account.base_vesting_account.original_vesting[0]?.amount); + + const doneRatio = t > new Date(endsAt) ? 1 : 0; + const vested = Math.ceil(Number(originalVesting) * doneRatio); + const vesting = Math.ceil(Number(originalVesting) * (1.0 - doneRatio)); + + return { + vested, + vesting, + }; + } } diff --git a/src/index.ts b/src/index.ts index 13d117ed..7a0d6277 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,31 +11,31 @@ import { handler as arbitrageOpportunitiesHandler } from './handlers/arbitrageOp import { webhookTriggers } from './handlers/webhookTriggers'; addEventListener('scheduled', (event: ScheduledEvent) => { - event.waitUntil(webhookTriggers(event)); + event.waitUntil(webhookTriggers(event)); }); addEventListener('fetch', (event: FetchEvent) => { - const router = Router(); - registerRoutes(router); - event.respondWith(router.handle(event.request).catch(handleError)); + const router = Router(); + registerRoutes(router); + event.respondWith(router.handle(event.request).catch(handleError)); }); function registerRoutes(router: Router) { - router.get('/', totalSupplyHandler); - router.get('/arbitrage', arbitrageOpportunitiesHandler); - router.get('/arbitrage/all', allArbitrageOpportunitiesHandler); - router.get('/balances/liquid/:address', liquidBalanceHandler); - router.get('/balances/total/:address', totalBalanceHandler); - router.get('/balances/vested/:address', vestedBalanceHandler); - router.get('/balances/vesting/:address', vestingBalanceHandler); - router.get('/supply/circulating', circulatingSupplyHandler); - router.get('/supply/staked', totalStakedCoinsHandler); - router.get('/supply/total', totalSupplyHandler); + router.get('/', totalSupplyHandler); + router.get('/arbitrage', arbitrageOpportunitiesHandler); + router.get('/arbitrage/all', allArbitrageOpportunitiesHandler); + router.get('/balances/liquid/:address', liquidBalanceHandler); + router.get('/balances/total/:address', totalBalanceHandler); + router.get('/balances/vested/:address', vestedBalanceHandler); + router.get('/balances/vesting/:address', vestingBalanceHandler); + router.get('/supply/circulating', circulatingSupplyHandler); + router.get('/supply/staked', totalStakedCoinsHandler); + router.get('/supply/total', totalSupplyHandler); - // 404 for all other requests - router.all('*', () => new Response('Not Found.', { status: 404 })); + // 404 for all other requests + router.all('*', () => new Response('Not Found.', { status: 404 })); } function handleError(error: Error): Response { - return new Response(error.message || 'Server Error', { status: 500 }); + return new Response(error.message || 'Server Error', { status: 500 }); } diff --git a/src/types/bigDipper.ts b/src/types/bigDipper.ts index 3e4a53bb..597b6a75 100644 --- a/src/types/bigDipper.ts +++ b/src/types/bigDipper.ts @@ -1,28 +1,28 @@ export interface TotalSupplyResponse { - supply: [ - { - coins: [ - { - denom: string; - amount: string; - } - ]; - } - ]; + supply: [ + { + coins: [ + { + denom: string; + amount: string; + }, + ]; + }, + ]; } export interface TotalStakedCoinsResponse { - staking_pool: [ - { - bonded_tokens: string; - } - ]; + staking_pool: [ + { + bonded_tokens: string; + }, + ]; } export interface ActiveValidatorsResponse { - validator_info: [ - { - operator_address: string; - } - ]; + validator_info: [ + { + operator_address: string; + }, + ]; } diff --git a/src/types/kv.ts b/src/types/kv.ts index f7277895..9e084c38 100644 --- a/src/types/kv.ts +++ b/src/types/kv.ts @@ -1,4 +1,4 @@ export interface ActiveValidatorsKV { - totalDelegatorsCount?: string; - updatedAt?: string; + totalDelegatorsCount?: string; + updatedAt?: string; } diff --git a/src/types/marketMonitor.ts b/src/types/marketMonitor.ts index d327789f..7e868eae 100644 --- a/src/types/marketMonitor.ts +++ b/src/types/marketMonitor.ts @@ -1,22 +1,22 @@ export interface Price { - price: number; - coinPair: string; - market: string; + price: number; + coinPair: string; + market: string; } export interface ArbitrageOpportunity { - marketPairId: string; - marketName1: string; - coinPair1: string; - coinPrice1: number; - marketName2: string; - coinPair2: string; - coinPrice2: number; - percentageDelta: number; - arbitragePossible: boolean; + marketPairId: string; + marketName1: string; + coinPair1: string; + coinPrice1: number; + marketName2: string; + coinPair2: string; + coinPrice2: number; + percentageDelta: number; + arbitragePossible: boolean; } export interface MarketMonitorData { - prices: Price[]; - arbitrageOpportunities: ArbitrageOpportunity[]; + prices: Price[]; + arbitrageOpportunities: ArbitrageOpportunity[]; } diff --git a/src/types/node.ts b/src/types/node.ts index d8f4287d..0d1320e8 100644 --- a/src/types/node.ts +++ b/src/types/node.ts @@ -1,108 +1,108 @@ export type Account = { - '@type': string; - start_time: number; - base_vesting_account: { - base_account: BaseAccount; - original_vesting: Coin[]; - delegated_free?: Coin[]; - delegated_vesting?: Coin[]; - end_time: number; - }; + '@type': string; + start_time: number; + base_vesting_account: { + base_account: BaseAccount; + original_vesting: Coin[]; + delegated_free?: Coin[]; + delegated_vesting?: Coin[]; + end_time: number; + }; }; export type BaseAccount = { - address: string; - pub_key: PublicKey; - account_number: string; - sequence: string; + address: string; + pub_key: PublicKey; + account_number: string; + sequence: string; }; export type PublicKey = { - '@type': string; - key: string; + '@type': string; + key: string; }; export class Coin { - public denom: string; - public amount: string; + public denom: string; + public amount: string; - constructor(denom: string, amount: string) { - this.denom = denom; - this.amount = amount; - } + constructor(denom: string, amount: string) { + this.denom = denom; + this.amount = amount; + } } export interface ValidatorDetailResponse { - delegation_responses: [ - { - delegation: { - delegator_address: string; - validator_address: string; - shares: string; - }; - balance: { - denom: string; - amount: string; - }; - } - ]; - pagination: { - next_key: string; - total: string; - }; + delegation_responses: [ + { + delegation: { + delegator_address: string; + validator_address: string; + shares: string; + }; + balance: { + denom: string; + amount: string; + }; + }, + ]; + pagination: { + next_key: string; + total: string; + }; } export interface AccountBalanceInfos { - totalBalance: number; - availableBalance: number; - rewards: number; - delegated: number; - unbonding: number; - timeUpdated: string; + totalBalance: number; + availableBalance: number; + rewards: number; + delegated: number; + unbonding: number; + timeUpdated: string; } export interface DelegationsResponse { - delegation_responses: [ - { - delegation: { - delegator_address: string; - validator_address: string; - shares: string; - }; - balance: { - denom: string; - amount: string; - }; - } - ]; - pagination: { - next_key: string; - total: string; - }; + delegation_responses: [ + { + delegation: { + delegator_address: string; + validator_address: string; + shares: string; + }; + balance: { + denom: string; + amount: string; + }; + }, + ]; + pagination: { + next_key: string; + total: string; + }; } export interface UnbondingResponse { - unbonding_responses: [ - { - delegator_address: string; - validator_address: string; - entries: [ - { - creation_height: string; - completion_time: string; - initial_balance: string; - balance: string; - } - ]; - } - ]; - pagination: { - next_key: string; - total: string; - }; + unbonding_responses: [ + { + delegator_address: string; + validator_address: string; + entries: [ + { + creation_height: string; + completion_time: string; + initial_balance: string; + balance: string; + }, + ]; + }, + ]; + pagination: { + next_key: string; + total: string; + }; } export interface RewardsResponse { - rewards: Record[]; - total: Coin[]; + rewards: Record[]; + total: Coin[]; }