From dcfd8304079ea1ddfd6e4d81fceb2948aa88f2fb Mon Sep 17 00:00:00 2001 From: Yana Date: Wed, 15 Jan 2025 15:43:30 +0200 Subject: [PATCH] Add node saturation point --- .../src/app/(pages)/nym-node/[id]/page.tsx | 21 +++++++++-- .../nymNodePageComponents/NodeMetricsCard.tsx | 14 ++------ .../nymNodePageComponents/NodeRewardsCard.tsx | 35 +++++++++++++++++-- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/explorer-nextjs/src/app/(pages)/nym-node/[id]/page.tsx b/explorer-nextjs/src/app/(pages)/nym-node/[id]/page.tsx index b6afe70752..f48fe4c491 100644 --- a/explorer-nextjs/src/app/(pages)/nym-node/[id]/page.tsx +++ b/explorer-nextjs/src/app/(pages)/nym-node/[id]/page.tsx @@ -1,5 +1,9 @@ +import type { ExplorerData } from "@/app/api"; import type { IObservatoryNode } from "@/app/api/types"; -import { DATA_OBSERVATORY_NODES_URL } from "@/app/api/urls"; +import { + CURRENT_EPOCH_REWARDS, + DATA_OBSERVATORY_NODES_URL, +} from "@/app/api/urls"; import BlogArticlesCards from "@/components/blogs/BlogArticleCards"; import ExplorerCard from "@/components/cards/ExplorerCard"; import { ContentLayout } from "@/components/contentLayout/ContentLayout"; @@ -21,6 +25,15 @@ export default async function NymNode({ params: Promise<{ id: string }>; }) { try { + const epochRewards = await fetch(CURRENT_EPOCH_REWARDS, { + headers: { + Accept: "application/json", + "Content-Type": "application/json; charset=utf-8", + }, + }); + const epochRewardsData: ExplorerData["currentEpochRewardsData"] = + await epochRewards.json(); + const id = Number((await params).id); const observatoryResponse = await fetch(DATA_OBSERVATORY_NODES_URL, { @@ -130,6 +143,7 @@ export default async function NymNode({ )} @@ -140,7 +154,10 @@ export default async function NymNode({ md: 6, }} > - + )} {delegations && ( diff --git a/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx b/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx index 7ef86b4b51..8f85c2aef5 100644 --- a/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx +++ b/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx @@ -1,25 +1,15 @@ import type { ExplorerData } from "@/app/api"; import type { IObservatoryNode } from "@/app/api/types"; -import { CURRENT_EPOCH_REWARDS } from "@/app/api/urls"; import ExplorerCard from "../cards/ExplorerCard"; import ExplorerListItem from "../list/ListItem"; interface INodeMetricsCardProps { nodeInfo: IObservatoryNode; + epochRewardsData: ExplorerData["currentEpochRewardsData"]; } export const NodeMetricsCard = async (props: INodeMetricsCardProps) => { - const { nodeInfo } = props; - - const epochRewards = await fetch(CURRENT_EPOCH_REWARDS, { - headers: { - Accept: "application/json", - "Content-Type": "application/json; charset=utf-8", - }, - }); - - const epochRewardsData: ExplorerData["currentEpochRewardsData"] = - await epochRewards.json(); + const { nodeInfo, epochRewardsData } = props; function getActiveSetProbability( totalStake: number, diff --git a/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx b/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx index 7e97c1ce54..d4b5ee5cf5 100644 --- a/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx +++ b/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx @@ -1,3 +1,4 @@ +import type { ExplorerData } from "@/app/api"; import type { IObservatoryNode, RewardingDetails } from "@/app/api/types"; import ExplorerCard from "../cards/ExplorerCard"; import ExplorerListItem from "../list/ListItem"; @@ -5,10 +6,11 @@ import ExplorerListItem from "../list/ListItem"; interface INodeRewardsCardProps { rewardDetails: RewardingDetails; nodeInfo?: IObservatoryNode; + epochRewardsData: ExplorerData["currentEpochRewardsData"]; } export const NodeRewardsCard = (props: INodeRewardsCardProps) => { - const { rewardDetails } = props; + const { rewardDetails, epochRewardsData, nodeInfo } = props; const operatorRewards = Number(rewardDetails.operator) / 1000000; const operatorRewardsFormated = `${operatorRewards} NYM`; @@ -22,6 +24,29 @@ export const NodeRewardsCard = (props: INodeRewardsCardProps) => { Number(rewardDetails.cost_params.interval_operating_cost.amount) / 1000000; const operatingCostsFormated = `${operatingCosts.toString()} NYM`; + function getNodeSaturationPoint( + totalStake: number, + stakeSaturationPoint: string, + ): string { + const saturation = Number.parseFloat(stakeSaturationPoint); + + if (Number.isNaN(saturation) || saturation <= 0) { + throw new Error("Invalid stake saturation point provided"); + } + + const ratio = (totalStake / saturation) * 100; + + return `${ratio.toFixed()}%`; + } + + const nodeSaturationPoint = + nodeInfo && epochRewardsData + ? getNodeSaturationPoint( + nodeInfo.total_stake, + epochRewardsData.interval.stake_saturation_point, + ) + : "N/A"; + return ( {/* { /> + ); };