import { Broadcast } from "@phosphor-icons/react/dist/ssr/Broadcast";
import { Confetti } from "@phosphor-icons/react/dist/ssr/Confetti";
import { Network } from "@phosphor-icons/react/dist/ssr/Network";
import { SmileySad } from "@phosphor-icons/react/dist/ssr/SmileySad";
import { Badge } from "@pythnetwork/component-library/Badge";
import { Card } from "@pythnetwork/component-library/Card";
import { Link } from "@pythnetwork/component-library/Link";
import { Table } from "@pythnetwork/component-library/Table";
import { lookup } from "@pythnetwork/known-publishers";
import { notFound } from "next/navigation";
import { getPriceFeeds } from "./get-price-feeds";
import styles from "./performance.module.scss";
import { TopFeedsTable } from "./top-feeds-table";
import { getPublishers } from "../../services/clickhouse";
import { Cluster } from "../../services/pyth";
import { Status } from "../../status";
import {
ExplainActive,
ExplainInactive,
ExplainAverage,
} from "../Explanations";
import { NoResults } from "../NoResults";
import { PriceFeedTag } from "../PriceFeedTag";
import { PublisherIcon } from "../PublisherIcon";
import { PublisherTag } from "../PublisherTag";
import { Ranking } from "../Ranking";
import { Score } from "../Score";
const PUBLISHER_SCORE_WIDTH = 24;
type Props = {
params: Promise<{
key: string;
}>;
};
export const Performance = async ({ params }: Props) => {
const { key } = await params;
const [publishers, priceFeeds] = await Promise.all([
getPublishers(),
getPriceFeeds(Cluster.Pythnet, key),
]);
const slicedPublishers = sliceAround(
publishers,
(publisher) => publisher.key === key,
2,
);
return slicedPublishers === undefined ? (
notFound()
) : (
} title="Publishers Ranking">
ACTIVE FEEDS
>
),
alignment: "center",
width: 30,
},
{
id: "inactiveFeeds",
name: (
<>
INACTIVE FEEDS
>
),
alignment: "center",
width: 30,
},
{
id: "averageScore",
name: (
<>
AVERAGE SCORE
>
),
alignment: "right",
width: PUBLISHER_SCORE_WIDTH,
},
]}
rows={slicedPublishers.map((publisher) => {
const knownPublisher = lookup(publisher.key);
return {
id: publisher.key,
data: {
ranking: (
{publisher.rank}
),
activeFeeds: (
{publisher.activeFeeds}
),
inactiveFeeds: (
{publisher.inactiveFeeds}
),
averageScore: (
),
name: (
,
})}
/>
),
},
...(publisher.key !== key && {
href: `/publishers/${publisher.key}`,
}),
};
})}
/>
} title="High-Performing Feeds">
}
header="Oh no!"
body="This publisher has no high performing feeds"
variant="error"
/>
}
rows={getFeedRows(
priceFeeds
.filter((feed) => hasRanking(feed))
.filter(({ ranking }) => ranking.final_score > 0.9)
.sort((a, b) => b.ranking.final_score - a.ranking.final_score),
)}
/>
} title="Low-Performing Feeds">
}
header="Looking good!"
body="This publisher has no low performing feeds"
variant="success"
/>
}
rows={getFeedRows(
priceFeeds
.filter((feed) => hasRanking(feed))
.filter(({ ranking }) => ranking.final_score < 0.7)
.sort((a, b) => a.ranking.final_score - b.ranking.final_score),
)}
/>
);
};
const getFeedRows = (
priceFeeds: (Omit<
Awaited>,
"ranking"
>[number] & {
ranking: NonNullable<
Awaited>[number]["ranking"]
>;
})[],
) =>
priceFeeds
.filter((feed) => feed.status === Status.Active)
.slice(0, 20)
.map(({ feed, ranking }) => ({
id: ranking.symbol,
data: {
asset: ,
assetClass: (
{feed.product.asset_type.toUpperCase()}
),
score: (
),
},
}));
const sliceAround = (
arr: T[],
predicate: (elem: T) => boolean,
count: number,
): T[] | undefined => {
const index = arr.findIndex((item) => predicate(item));
if (index === -1) {
return undefined;
} else {
const min = Math.max(
0,
index - count - Math.max(0, index + count + 1 - arr.length),
);
const max = Math.min(arr.length, min + count * 2 + 1);
return arr.slice(min, max);
}
};
const hasRanking = (feed: {
ranking: T | undefined;
}): feed is { ranking: T } => feed.ranking !== undefined;