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 995cc3263a..4ae7f55ce2 100644 --- a/explorer-nextjs/src/app/(pages)/nym-node/[id]/page.tsx +++ b/explorer-nextjs/src/app/(pages)/nym-node/[id]/page.tsx @@ -1,6 +1,10 @@ import type NodeData from "@/app/api/types"; import type { IObservatoryNode } from "@/app/api/types"; -import { DATA_OBSERVATORY_NODES_URL, NYM_NODES } from "@/app/api/urls"; +import { + CURRENT_EPOCH_REWARDS, + DATA_OBSERVATORY_NODES_URL, + NYM_NODES, +} from "@/app/api/urls"; import BlogArticlesCards from "@/components/blogs/BlogArticleCards"; import ExplorerCard from "@/components/cards/ExplorerCard"; import { ContentLayout } from "@/components/contentLayout/ContentLayout"; @@ -128,7 +132,10 @@ export default async function NymNode({ md: 4, }} > - + {delegations && ( diff --git a/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx b/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx index cefa43dee0..7afffceab5 100644 --- a/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx +++ b/explorer-nextjs/src/components/nymNodePageComponents/NodeMetricsCard.tsx @@ -1,14 +1,56 @@ -import type { NodeDescription } from "@/app/api/types"; +import type { ExplorerData } from "@/app/api"; +import type { IObservatoryNode, NodeDescription } from "@/app/api/types"; +import { CURRENT_EPOCH_REWARDS } from "@/app/api/urls"; import ExplorerCard from "../cards/ExplorerCard"; import ExplorerListItem from "../list/ListItem"; interface INodeMetricsCardProps { nodeDescription: NodeDescription; nodeId: number; + nodeInfo?: IObservatoryNode; } -export const NodeMetricsCard = (props: INodeMetricsCardProps) => { - const { nodeDescription, nodeId } = props; +export const NodeMetricsCard = async (props: INodeMetricsCardProps) => { + const { nodeDescription, nodeId, 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(); + + function getActiveSetProbability( + 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; + + if (ratio > 70) { + return "High"; + } + if (ratio >= 40 && ratio <= 70) { + return "Medium"; + } + return "Low"; + } + + const activeSetProb = + nodeInfo && epochRewardsData + ? getActiveSetProbability( + nodeInfo.total_stake, + epochRewardsData.interval.stake_saturation_point, + ) + : ""; return ( @@ -34,7 +76,9 @@ export const NodeMetricsCard = (props: INodeMetricsCardProps) => { /> )} - + {epochRewardsData && ( + + )} ); }; diff --git a/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx b/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx index a674393381..efa36d5839 100644 --- a/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx +++ b/explorer-nextjs/src/components/nymNodePageComponents/NodeRewardsCard.tsx @@ -29,24 +29,24 @@ export const NodeRewardsCard = (props: INodeRewardsCardProps) => { return ( - + /> */} - + /> */} { )); - console.log("activeRoles :>> ", nodeDescription.declared_role); + function calculateQualityOfServiceStars(quality: number): number { + if (quality < 0.2) { + return 1; + } + if (quality < 0.4) { + return 2; + } + if (quality < 0.6) { + return 3; + } + if (quality < 0.7) { + return 4; + } + return 5; + } + const qualityOfServiceStars = nodeInfo?.uptime + ? calculateQualityOfServiceStars(nodeInfo?.uptime) + : 1; + + const nodeIsMixNodeOnly = + NodeRoles.length === 1 && nodeRoles[0] === "Mix Node"; return ( @@ -62,20 +82,24 @@ export const QualityIndicatorsCard = (props: IQualityIndicatorsCardProps) => { row divider label="Quality of service" - value={} - /> - } - /> - } + value={} /> + {!nodeIsMixNodeOnly && ( + } + /> + )} + {!nodeIsMixNodeOnly && ( + } + /> + )} ); };