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;