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 (
{/* {
/>
+
);
};