diff --git a/dumps/orchInfo.json b/dumps/orchInfo.json
new file mode 100644
index 0000000..ebe560b
--- /dev/null
+++ b/dumps/orchInfo.json
@@ -0,0 +1,57 @@
+{
+ "id": "0x1a196b031ea1a74a53ecbe6148772648e02f9d51",
+ "activationRound": "2467",
+ "deactivationRound": "57896044618658097711785492504343953926634992332820282019728792003956564819967",
+ "active": true,
+ "status": "Registered",
+ "lastRewardRound": {
+ "id": "2535",
+ "length": "5760",
+ "startBlock": "14601600",
+ "endBlock": "14607360",
+ "mintableTokens": "6289.390217651615209644",
+ "volumeETH": "0",
+ "volumeUSD": "0",
+ "totalActiveStake": "12660572.689057253001431262",
+ "totalSupply": "25315641.406774142960762968",
+ "participationRate": "0.5001087069304688888807674462863896",
+ "movedStake": "0",
+ "newStake": "0"
+ },
+ "rewardCut": "2500",
+ "feeShare": "100000",
+ "pendingFeeShare": "0",
+ "pendingRewardCut": "0",
+ "totalStake": "10359.571442424819689212",
+ "totalVolumeETH": "0",
+ "totalVolumeUSD": "0",
+ "serviceURI": "https://lpt.4v1.in:8935",
+ "delegators": [
+ {
+ "id": "0x1a196b031ea1a74a53ecbe6148772648e02f9d51",
+ "bondedAmount": "33.050240717610249021",
+ "startRound": "2467"
+ },
+ {
+ "id": "0x683fc3000a300575657713124fcf84adc53f9f90",
+ "bondedAmount": "11.81774",
+ "startRound": "2468"
+ },
+ {
+ "id": "0x9785c9c3258573810c69ddf93221b6a8dea1c777",
+ "bondedAmount": "0.000000000000000001",
+ "startRound": "2467"
+ },
+ {
+ "id": "0xfb9849b0b53f66b747bfa47396964a3fa22400a0",
+ "bondedAmount": "10071.316871799952124909",
+ "startRound": "2487"
+ }
+ ],
+ "delegator": {
+ "id": "0x1a196b031ea1a74a53ecbe6148772648e02f9d51",
+ "bondedAmount": "33.050240717610249021",
+ "startRound": "2467"
+ },
+ "lastGet": 1650188936614
+}
\ No newline at end of file
diff --git a/src/actions/livepeer.js b/src/actions/livepeer.js
index 66dbdfd..e2fcb28 100644
--- a/src/actions/livepeer.js
+++ b/src/actions/livepeer.js
@@ -159,13 +159,13 @@ export const getEvents = () => async dispatch => {
tmpAmount.toFixed(2) + " LPT stake",
"round " + tmpWhen
]
- eventDescription =
+ eventDescription =
} else {
const subtext = "reactivated";
const descriptions = [
"round " + tmpWhen
]
- eventDescription =
+ eventDescription =
}
}
// Lone Unbond => Unbond Event
@@ -178,7 +178,7 @@ export const getEvents = () => async dispatch => {
"round " + tmpWhen
]
eventDescription =
-
+
}
// Lone Bond => Stake Event
else if (eventContainsBond) {
@@ -194,7 +194,7 @@ export const getEvents = () => async dispatch => {
tmpAmount.toFixed(2) + " LPT"
]
eventDescription =
-
+
}
// Fill description of Stake Event if it wasn't set yet
@@ -205,7 +205,7 @@ export const getEvents = () => async dispatch => {
tmpAmount.toFixed(2) + " LPT"
]
eventDescription =
-
+
} else if (eventFrom === eventTo) {
eventFrom = "";
const subtext = "changed stake";
@@ -213,14 +213,14 @@ export const getEvents = () => async dispatch => {
tmpAmount.toFixed(2) + " LPT"
]
eventDescription =
-
+
} else {
const subtext = "moved stake";
const descriptions = [
tmpAmount.toFixed(2) + " LPT"
]
eventDescription =
-
+
}
}
@@ -277,7 +277,7 @@ export const getEvents = () => async dispatch => {
"round " + eventObj.data.withdrawRound
]
const txt =
-
+
finalEventList.push({
eventType: "Withdraw",
eventDescription: txt,
@@ -301,7 +301,7 @@ export const getEvents = () => async dispatch => {
amount.toFixed(4) + " Eth"
]
const txt =
-
+
finalEventList.push({
eventType: "Withdraw",
eventDescription: txt,
@@ -327,7 +327,7 @@ export const getEvents = () => async dispatch => {
amount2.toFixed(2) + "% on transcoding fees"
]
const txt =
-
+
finalEventList.push({
eventType: "Update",
eventDescription: txt,
@@ -357,7 +357,7 @@ export const getEvents = () => async dispatch => {
"+" + amount2.toFixed(4) + " Eth fees"
]
let txt =
-
+
finalEventList.push({
eventType: "Claim",
eventDescription: txt,
@@ -381,7 +381,7 @@ export const getEvents = () => async dispatch => {
"+" + amount1.toFixed(2) + " LPT" + (Math.floor(amount1) == 69 ? "... Nice!" : "")
]
const txt =
-
+
finalEventList.push({
eventType: "Reward",
eventDescription: txt,
@@ -483,7 +483,7 @@ export const getTickets = () => async dispatch => {
"+" + amount.toFixed(4) + " Eth"
]
const txt =
-
+
finalTicketList.push({
eventType: "RedeemTicket",
eventDescription: txt,
@@ -535,12 +535,21 @@ export const getCurrentOrchestratorInfo = () => async dispatch => {
return dispatch(receiveErrors(data));
};
+export const getOrchestratorInfoSilent = (orchAddr) => async dispatch => {
+ const response = await apiUtil.getOrchestratorInfo(orchAddr);
+ const data = await response.json();
+ if (response.ok) {
+ if (data && data.id) {
+ return dispatch(cacheNewOrch(data));
+ }
+ }
+};
+
export const getOrchestratorInfo = (orchAddr) => async dispatch => {
const response = await apiUtil.getOrchestratorInfo(orchAddr);
const data = await response.json();
if (response.ok) {
if (data && data.id) {
- console.log(data);
dispatch(cacheNewOrch(data));
return dispatch(setOrchestratorInfo(data));
} else {
@@ -598,7 +607,9 @@ export const getAllThreeBoxInfo = () => async dispatch => {
export const getThreeBoxInfo = async (addr) => {
const response = await apiUtil.getThreeBox(addr);
- const data = await response.json();
+ if (response.ok) {
+ const data = await response.json();
+ }
};
export const getOrchestratorScores = (year, month) => async dispatch => {
diff --git a/src/components/TicketViewer.js b/src/components/TicketViewer.js
index 9b73110..22e4963 100644
--- a/src/components/TicketViewer.js
+++ b/src/components/TicketViewer.js
@@ -17,7 +17,7 @@ const Ticket = (obj) => {
{obj.descriptions.map(function (thisTextItem, i) {
return (
-
+
{thisTextItem}
)
diff --git a/src/components/WinnerMonth.js b/src/components/WinnerMonth.js
index 34d1a71..3d56dff 100644
--- a/src/components/WinnerMonth.js
+++ b/src/components/WinnerMonth.js
@@ -90,10 +90,11 @@ const WinnerMonth = (obj) => {
return (
+
Top Earners
{
const dispatch = useDispatch();
const livepeer = useSelector((state) => state.livepeerstate);
const [hasRefreshed, setRefresh] = useState(false);
+ const [hasENS, setHasENS] = useState(false);
+ const [hasThreeBox, setHasThreeBox] = useState(false);
const [hasThreeBoxRefreshed, setThreeBoxRefresh] = useState(false);
- let thisDomain = null;
- let thisInfo = null;
- let hasENS = false;
- let hasThreeBox = false;
+ const [hasOrchInfo, setHasOrchInfo] = useState(false);
+ const [orchInfo, setOrchInfo] = useState(null);
const now = new Date().getTime();
- // Lookup domain in cache
- if (livepeer.ensDomainMapping) {
- for (const thisAddr of livepeer.ensDomainMapping) {
- if (thisAddr.address === obj.address) {
- thisDomain = thisAddr;
- // Check timeout
- if (now - thisAddr.timestamp < 86400000) {
- break;
- }
- // Is outdated
- if (!hasRefreshed) {
- getEnsInfo(obj.address);
- setRefresh(true);
- }
- break;
- }
- }
- // If it was not cached at all
- if (thisDomain == null && !hasRefreshed) {
- setRefresh(true);
- getEnsInfo(obj.address);
- }
- }
- // 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) {
- thisInfo = thisAddr;
- hasENS = true;
- // Check timeout
- if (now - thisAddr.timestamp < 86400000) {
- break;
- }
- // Is outdated
- if (!hasRefreshed) {
- getEnsInfo(obj.address);
- setRefresh(true);
- }
- break;
- }
- }
- // If it was not cached at all
- if (thisInfo == null && !hasRefreshed) {
- getEnsInfo(obj.address);
- setRefresh(true);
- }
- }
-
- // Ugly shit, but temporary for now to quickly enable threebox. Sorry!
- if (!hasENS) {
- if (livepeer.threeBoxInfo) {
- for (const thisAddr of livepeer.threeBoxInfo) {
+
+ useEffect(() => {
+ let thisInfo = null;
+ let thisDomain = null;
+ // Lookup domain in cache
+ if (livepeer.ensDomainMapping && !hasRefreshed) {
+ for (const thisAddr of livepeer.ensDomainMapping) {
if (thisAddr.address === obj.address) {
- thisInfo = thisAddr;
- hasThreeBox = true;
+ thisDomain = thisAddr;
// Check timeout
if (now - thisAddr.timestamp < 86400000) {
break;
}
// Is outdated
- if (!hasThreeBoxRefreshed) {
- getThreeBoxInfo(obj.address);
- setThreeBoxRefresh(true);
+ if (!hasRefreshed) {
+ getEnsInfo(obj.address);
+ setRefresh(true);
}
break;
}
}
// If it was not cached at all
- if (thisDomain == null && !hasThreeBoxRefreshed) {
- setThreeBoxRefresh(true);
- getThreeBoxInfo(obj.address);
+ if (thisDomain == null && !hasRefreshed) {
+ setRefresh(true);
+ getEnsInfo(obj.address);
}
}
- }
+ // Lookup current info in cache only if this addr has a mapped ENS domain
+ if (thisDomain && thisDomain.domain && !hasRefreshed) {
+ for (const thisAddr of livepeer.ensInfoMapping) {
+ if (thisAddr.domain === thisDomain.domain) {
+ thisInfo = thisAddr;
+ setHasENS(true);
+ // Check timeout
+ if (now - thisAddr.timestamp < 86400000) {
+ break;
+ }
+ // Is outdated
+ if (!hasRefreshed) {
+ getEnsInfo(obj.address);
+ setRefresh(true);
+ }
+ break;
+ }
+ }
+ // If it was not cached at all
+ if (thisInfo == null && !hasRefreshed) {
+ getEnsInfo(obj.address);
+ setRefresh(true);
+ }
+ }
+
+ // Ugly shit, but temporary for now to quickly enable threebox. Sorry!
+ if (!hasENS && !hasThreeBoxRefreshed) {
+ if (livepeer.threeBoxInfo) {
+ for (const thisAddr of livepeer.threeBoxInfo) {
+ if (thisAddr.address === obj.address) {
+ thisInfo = thisAddr;
+ setHasThreeBox(true);
+ // Check timeout
+ if (now - thisAddr.timestamp < 86400000) {
+ break;
+ }
+ // Is outdated
+ if (!hasThreeBoxRefreshed) {
+ getThreeBoxInfo(obj.address);
+ setThreeBoxRefresh(true);
+ }
+ break;
+ }
+ }
+ // If it was not cached at all
+ if (thisDomain == null && !hasThreeBoxRefreshed) {
+ setThreeBoxRefresh(true);
+ getThreeBoxInfo(obj.address);
+ }
+ }
+ }
+ if (thisInfo && thisInfo != orchInfo){
+ setOrchInfo(thisInfo);
+ }
+ }, [livepeer.ensDomainMapping, livepeer.threeBoxInfo, hasRefreshed, hasENS, hasThreeBoxRefreshed]);
+
+ useEffect(() => {
+ // Check if cached as an orchestrator
+ if (livepeer.orchInfo && !hasOrchInfo) {
+ for (const thisOrch of livepeer.orchInfo) {
+ if (thisOrch.id === obj.address) {
+ setHasOrchInfo(true);
+ break;
+ }
+ }
+ // Preload Orch info
+ if (!hasOrchInfo) {
+ dispatch(getOrchestratorInfoSilent(obj.address));
+ setHasOrchInfo(true);
+ }
+ }
+ }, [livepeer.orchInfo, hasOrchInfo]);
let thisName;
let thisIcon;
if (hasENS) {
- thisName = {thisInfo.domain}
;
- if (thisInfo.avatar) {
+ thisName = {orchInfo.domain}
;
+ if (orchInfo.avatar) {
thisIcon =
-
-
+
+
}
} else if (hasThreeBox) {
- if (thisInfo.name) {
- thisName = {thisInfo.name}
;
+ if (orchInfo.name) {
+ thisName = {orchInfo.name}
;
} else {
thisName = {obj.address};
}
- if (thisInfo.image) {
- thisIcon =
+ if (orchInfo.image) {
+ thisIcon =
} else {
thisIcon = null;
}
diff --git a/src/pages/tickets.js b/src/pages/tickets.js
index cb9de52..b49f173 100644
--- a/src/pages/tickets.js
+++ b/src/pages/tickets.js
@@ -5,11 +5,13 @@ import { useSelector, useDispatch } from 'react-redux';
import { Accordion } from '@mantine/core';
import ScrollContainer from 'react-indiana-drag-scroll';
import WinnerMonth from '../components/WinnerMonth';
+import { VictoryPie } from 'victory';
const Tickets = (obj) => {
const livepeer = useSelector((state) => state.livepeerstate);
const [ticketsPerMonth, setTicketsPerMonth] = useState([]);
const [redirectToHome, setRedirectToHome] = useState(false);
+ const [removeOnlyStakers, setRemoveOnlyStakers] = useState(false);
console.log("Rendering Winning Ticket Viewer");
@@ -138,6 +140,117 @@ const Tickets = (obj) => {
return ;
}
+ 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) {
+ return thisAddr.domain;
+ }
+ }
+ }
+
+ if (livepeer.threeBoxInfo) {
+ for (const thisAddr of livepeer.threeBoxInfo) {
+ if (thisAddr.address === address) {
+ if (thisAddr.name) {
+ return thisAddr.name;
+ } else {
+ return (address.substring(0, 10) + "..");
+ }
+ break;
+ }
+ }
+ }
+
+ return (address.substring(0, 10) + "..");
+ }
+
+ let pieList = [];
+ let otherSum = 0;
+ let pieObj = null;
+ if (livepeer.orchInfo) {
+ let orchIdx = livepeer.orchInfo.length - 1;
+ // calc sum of stake
+ let totalStake = 0;
+ while (orchIdx >= 0) {
+ const thisOrch = livepeer.orchInfo[orchIdx];
+ orchIdx -= 1;
+ if (removeOnlyStakers && !parseInt(thisOrch.totalVolumeUSD)) {
+ continue;
+ }
+ totalStake += parseInt(thisOrch.totalStake);
+ }
+ // create slices
+ orchIdx = livepeer.orchInfo.length - 1;
+ while (orchIdx >= 0) {
+ const thisOrch = livepeer.orchInfo[orchIdx];
+ orchIdx -= 1;
+ if (removeOnlyStakers && !parseInt(thisOrch.totalVolumeUSD)) {
+ continue;
+ }
+ if ((thisOrch.totalStake / totalStake) < 0.04) {
+ otherSum += thisOrch.totalStake;
+ } else {
+ pieList.push({
+ address: getName(thisOrch.id),
+ sum: thisOrch.totalStake
+ });
+ }
+ }
+ pieList.push({
+ address: "Other",
+ sum: otherSum
+ });
+ pieObj =
+
Active Orchestrators by Stake
+
+
Show non-transcoding Orchestrators?
+
setRemoveOnlyStakers(!removeOnlyStakers)}>
+
+ {removeOnlyStakers ? "Show" : "Hide"}
+
+
+
+
+
+ }
+
return (