import React, { useState } from 'react'
import '../style.css';
import { Navigate } from "react-router-dom";
import { useSelector } from 'react-redux';
import { Accordion } from '@mantine/core';
import MonthlyStats from './MonthlyStats';
function updateClipboard(newClip) {
navigator.clipboard.writeText(newClip).then(
() => {
console.log("Copied!");
},
() => {
console.log("Copy failed!");
}
);
}
function copyLink(addr) {
navigator.permissions
.query({ name: "clipboard-write" })
.then((result) => {
if (result.state === "granted" || result.state === "prompt") {
updateClipboard(addr);
}
});
}
const Stats = (obj) => {
const livepeer = useSelector((state) => state.livepeerstate);
const [redirectToHome, setRedirectToHome] = useState(false);
const [showOnlyTranscoders, setShowOnlyTranscoders] = useState(true);
const getName = (address) => {
let thisDomain = null;
// Lookup domain in cache
if (livepeer.ensDomainMapping) {
for (const thisAddr of livepeer.ensDomainMapping) {
if (thisAddr.address === address) {
thisDomain = thisAddr;
break;
}
}
}
// Lookup current info in cache only if this addr has a mapped ENS domain
if (thisDomain && thisDomain.domain) {
for (const thisAddr of livepeer.ensInfoMapping) {
if (thisAddr.domain === thisDomain.domain) {
if (thisAddr.domain.length > 18) {
return thisAddr.domain;
}
return thisAddr.domain;
}
}
}
return address;
}
function getDataFor(year, month, data) {
let summary = month + " " + year + ": \r\n";
if (data.reactivationCount) {
summary += "🔌 " + data.reactivationCount + " orchestrators reactivated \r\n";
}
if (data.activationCount) {
summary += "🔧 " + data.activationCount + " orchestrators joined with an initial stake of " + data.activationInitialSum.toLocaleString({ maximumFractionDigits: 1 }) + " LPT \r\n";
}
if (data.bondCount) {
summary += "📈 " + data.bondCount + " accounts delegated for the first time for a total of " + data.bondStakeSum.toLocaleString({ maximumFractionDigits: 1 }) + " LPT \r\n";
}
if (data.unbondCount) {
summary += "📉 " + data.unbondCount + " delegators unbonded " + data.unbondStakeSum.toLocaleString({ maximumFractionDigits: 1 }) + " LPT \r\n";
}
if (data.withdrawStakeCount) {
summary += "💸 " + data.withdrawStakeAmountSum.toLocaleString({ maximumFractionDigits: 1 }) + " LPT worth of stake was withdrawn to the accounts of delegators \r\n";
}
if (data.withdrawFeesCount) {
summary += "💸 " + data.withdrawFeesAmountSum.toLocaleString({ maximumFractionDigits: 3 }) + " ETH worth of transcoding fees were withdrawn to the accounts of delegators \r\n";
}
if (data.moveStakeCount) {
summary += "🔄 " + data.moveStakeSum.toLocaleString({ maximumFractionDigits: 1 }) + " LPT worth of stake was moved directly between orchestrators in " + data.moveStakeCount + " transactions \r\n";
}
if (data.winningTicketsReceivedCount) {
summary += "🎫 " + data.winningTicketsReceivedCount + " winning tickets were sent out by " + data.winningTicketsSent.length + " broadcasters \r\n";
}
summary += "\r\n";
let winnerList = [...data.winningTicketsReceived] || [];
let stakeList = data.latestTotalStake || [];
// Count earners of more than 0.2 Eth
let luckyCount = 0;
let totalStakeSumEarners = 0;
for (const thisObj of winnerList) {
if (thisObj.sum > 0.2) {
luckyCount++;
}
for (const thisObjB of stakeList) {
if (thisObjB.address == thisObj.address) {
totalStakeSumEarners += thisObjB.totalStake;
}
}
}
if (data.winningTicketsReceived.length && data.winningTicketsReceivedSum) {
summary += data.winningTicketsReceived.length + " orchestrators earned " + data.winningTicketsReceivedSum.toFixed(3) + " Eth in transcoding fees \r\n";
}
summary += luckyCount + " of them received more than 0.2 Eth \r\n";
summary += "Top 25 earning orchestrators for this month are: \r\n";
// Find highest earner
const maxPrint = 25;
let currentPrinted = 0;
while (currentPrinted < maxPrint && winnerList.length) {
let ticketIdx2 = winnerList.length - 1;
let largestIdx = 0;
let largestValue = 0;
while (ticketIdx2 >= 0) {
const currentOrch = winnerList[ticketIdx2];
let thisVal;
for (const obj of winnerList) {
if (obj.address == currentOrch.address) {
thisVal = obj.sum;
}
}
if (!thisVal) {
ticketIdx2 -= 1;
continue;
}
if (thisVal > largestValue) {
largestIdx = ticketIdx2;
largestValue = thisVal;
}
ticketIdx2 -= 1;
}
currentPrinted++;
const largestObj = winnerList[largestIdx];
// Print highest earner info
const earningsPercentage = parseFloat((largestObj.sum / data.winningTicketsReceivedSum) * 100);
summary += "#" + currentPrinted + ": " + getName(largestObj.address) + " won " + largestObj.count + " tickets worth " + largestObj.sum.toFixed(3) + " Eth" + " (" + earningsPercentage.toFixed(2) + "%)";
// Add stake info if available
for (const thisObj of stakeList) {
if (thisObj.address == largestObj.address) {
const stakePercentage = parseFloat((thisObj.totalStake / totalStakeSumEarners) * 100);
summary += " with a stake of " + thisObj.totalStake.toFixed(1) + " LPT (" + stakePercentage.toFixed(2) + "%)";
}
}
summary += "\r\n";
// Remove from list
winnerList.splice(largestIdx, 1);
}
if (stakeList.length) {
summary += "\r\n(The percentage of stake excludes non-transcoding orchestrators)\r\n";
}
copyLink(summary);
}
console.log("Rendering Stats Viewer");
if (redirectToHome) {
return
Show non-transcoders?