mirror of
https://github.com/stronk-dev/LivepeerEvents.git
synced 2025-07-05 10:45:10 +02:00
Now with fancy Orchestrator Viewer
This commit is contained in:
parent
485b75cad2
commit
0f15927376
@ -44,52 +44,12 @@ let claimTicketCostL2 = 0;
|
|||||||
let withdrawFeeCostL1 = 0;
|
let withdrawFeeCostL1 = 0;
|
||||||
let withdrawFeeCostL2 = 0;
|
let withdrawFeeCostL2 = 0;
|
||||||
|
|
||||||
// Update info from thegraph every 5 minutes
|
// Update O info from thegraph every 1 minute
|
||||||
const timeoutTheGraph = 300000;
|
const timeoutTheGraph = 60000;
|
||||||
let theGraphGet = 0;
|
|
||||||
// Address of O info we are want to display
|
// Address of O info we are want to display
|
||||||
const orchQuery = gql`
|
const defaultOrch = "0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e";
|
||||||
{
|
// Will contain addr, lastGet, and obj of any requested O's
|
||||||
transcoders(where: {id: "0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e"}) {
|
let orchestratorCache = [];
|
||||||
activationRound
|
|
||||||
deactivationRound
|
|
||||||
active
|
|
||||||
lastRewardRound {
|
|
||||||
id
|
|
||||||
length
|
|
||||||
startBlock
|
|
||||||
endBlock
|
|
||||||
mintableTokens
|
|
||||||
volumeETH
|
|
||||||
volumeUSD
|
|
||||||
totalActiveStake
|
|
||||||
totalSupply
|
|
||||||
participationRate
|
|
||||||
movedStake
|
|
||||||
newStake
|
|
||||||
}
|
|
||||||
rewardCut
|
|
||||||
feeShare
|
|
||||||
pendingFeeShare
|
|
||||||
pendingRewardCut
|
|
||||||
totalStake
|
|
||||||
totalVolumeETH
|
|
||||||
totalVolumeUSD
|
|
||||||
serviceURI
|
|
||||||
delegators {
|
|
||||||
id
|
|
||||||
bondedAmount
|
|
||||||
startRound
|
|
||||||
}
|
|
||||||
delegator {
|
|
||||||
id
|
|
||||||
bondedAmount
|
|
||||||
startRound
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
let orchestratorCache = {};
|
|
||||||
|
|
||||||
// Listen to smart contract emitters. Resync with DB every 5 minutes
|
// Listen to smart contract emitters. Resync with DB every 5 minutes
|
||||||
const timeoutEvents = 300000;
|
const timeoutEvents = 300000;
|
||||||
@ -279,14 +239,96 @@ apiRouter.get("/getEvents", async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const parseOrchestrator = async function (reqAddr) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
// Default assume it's the first time we request this Orchestrator
|
||||||
|
let wasCached = false;
|
||||||
|
let needsUpdate = true;
|
||||||
|
let orchestratorObj = {};
|
||||||
|
// First get cached object
|
||||||
|
for (var orch of orchestratorCache) {
|
||||||
|
if (orch.addr == reqAddr) {
|
||||||
|
wasCached = true;
|
||||||
|
orchestratorObj = orch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (wasCached) {
|
||||||
|
if (now - orch.lastGet < timeoutTheGraph) {
|
||||||
|
needsUpdate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!wasCached || needsUpdate) {
|
||||||
|
const orchQuery = gql`{
|
||||||
|
transcoders(where: {id: "${reqAddr}"}) {
|
||||||
|
activationRound
|
||||||
|
deactivationRound
|
||||||
|
active
|
||||||
|
lastRewardRound {
|
||||||
|
id
|
||||||
|
length
|
||||||
|
startBlock
|
||||||
|
endBlock
|
||||||
|
mintableTokens
|
||||||
|
volumeETH
|
||||||
|
volumeUSD
|
||||||
|
totalActiveStake
|
||||||
|
totalSupply
|
||||||
|
participationRate
|
||||||
|
movedStake
|
||||||
|
newStake
|
||||||
|
}
|
||||||
|
rewardCut
|
||||||
|
feeShare
|
||||||
|
pendingFeeShare
|
||||||
|
pendingRewardCut
|
||||||
|
totalStake
|
||||||
|
totalVolumeETH
|
||||||
|
totalVolumeUSD
|
||||||
|
serviceURI
|
||||||
|
delegators {
|
||||||
|
id
|
||||||
|
bondedAmount
|
||||||
|
startRound
|
||||||
|
}
|
||||||
|
delegator {
|
||||||
|
id
|
||||||
|
bondedAmount
|
||||||
|
startRound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
orchestratorObj = JSON.stringify(await request("https://api.thegraph.com/subgraphs/name/livepeer/arbitrum-one", orchQuery));
|
||||||
|
if (wasCached) {
|
||||||
|
for (var orch of orchestratorCache) {
|
||||||
|
if (orch.addr == requestedOrchestrator) {
|
||||||
|
orch = orchestratorObj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
orchestratorCache.push(orchestratorObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(orchestratorObj);
|
||||||
|
return orchestratorObj;
|
||||||
|
}
|
||||||
|
|
||||||
apiRouter.get("/getOrchestrator", async (req, res) => {
|
apiRouter.get("/getOrchestrator", async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const now = new Date().getTime();
|
const reqObj = await parseOrchestrator(defaultOrch);
|
||||||
// Update cmc once their data has expired
|
res.send(reqObj);
|
||||||
if (now - theGraphGet > timeoutTheGraph) {
|
} catch (err) {
|
||||||
orchestratorCache = JSON.stringify(await request("https://api.thegraph.com/subgraphs/name/livepeer/arbitrum-one", orchQuery));
|
console.log(err);
|
||||||
}
|
res.status(400).send(err);
|
||||||
res.send(orchestratorCache);
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
apiRouter.post("/getOrchestrator", async (req, res) => {
|
||||||
|
try {
|
||||||
|
const reqObj = await parseOrchestrator(req.body.orchAddr);
|
||||||
|
res.send(reqObj);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.status(400).send(err);
|
res.status(400).send(err);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { receiveErrors } from "./error";
|
|||||||
export const RECEIVE_QUOTES = "RECEIVE_QUOTES";
|
export const RECEIVE_QUOTES = "RECEIVE_QUOTES";
|
||||||
export const RECEIVE_BLOCKCHAIN_DATA = "RECEIVE_BLOCKCHAIN_DATA";
|
export const RECEIVE_BLOCKCHAIN_DATA = "RECEIVE_BLOCKCHAIN_DATA";
|
||||||
export const RECEIVE_EVENTS = "RECEIVE_EVENTS";
|
export const RECEIVE_EVENTS = "RECEIVE_EVENTS";
|
||||||
|
export const RECEIVE_CURRENT_ORCHESTRATOR = "RECEIVE_CURRENT_ORCHESTRATOR";
|
||||||
export const RECEIVE_ORCHESTRATOR = "RECEIVE_ORCHESTRATOR";
|
export const RECEIVE_ORCHESTRATOR = "RECEIVE_ORCHESTRATOR";
|
||||||
|
|
||||||
const setQuotes = message => ({
|
const setQuotes = message => ({
|
||||||
@ -16,6 +17,9 @@ const setEvents = message => ({
|
|||||||
type: RECEIVE_EVENTS, message
|
type: RECEIVE_EVENTS, message
|
||||||
});
|
});
|
||||||
const setCurrentOrchestratorInfo = message => ({
|
const setCurrentOrchestratorInfo = message => ({
|
||||||
|
type: RECEIVE_CURRENT_ORCHESTRATOR, message
|
||||||
|
});
|
||||||
|
const setOrchestratorInfo = message => ({
|
||||||
type: RECEIVE_ORCHESTRATOR, message
|
type: RECEIVE_ORCHESTRATOR, message
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -53,4 +57,13 @@ export const getCurrentOrchestratorInfo = () => async dispatch => {
|
|||||||
return dispatch(setCurrentOrchestratorInfo(data));
|
return dispatch(setCurrentOrchestratorInfo(data));
|
||||||
}
|
}
|
||||||
return dispatch(receiveErrors(data));
|
return dispatch(receiveErrors(data));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOrchestratorInfo = (orchAddr) => async dispatch => {
|
||||||
|
const response = await apiUtil.getOrchestratorInfo(orchAddr);
|
||||||
|
const data = await response.json();
|
||||||
|
if (response.ok) {
|
||||||
|
return dispatch(setOrchestratorInfo(data));
|
||||||
|
}
|
||||||
|
return dispatch(receiveErrors(data));
|
||||||
};
|
};
|
@ -7,6 +7,7 @@ import { connect } from "react-redux";
|
|||||||
import {
|
import {
|
||||||
getQuotes, getCurrentOrchestratorInfo
|
getQuotes, getCurrentOrchestratorInfo
|
||||||
} from "./actions/livepeer";
|
} from "./actions/livepeer";
|
||||||
|
import Orchestrator from "./orchestratorViewer";
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
return {
|
return {
|
||||||
@ -51,47 +52,6 @@ class Grafana extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(this.props.livepeer);
|
|
||||||
|
|
||||||
let rewardCut = 0;
|
|
||||||
let feeCut = 0;
|
|
||||||
let totalStake = 0;
|
|
||||||
let totalVolumeETH = 0;
|
|
||||||
let totalVolumeUSD = 0;
|
|
||||||
let delegators = [];
|
|
||||||
let delegatorsTotalStake = 0;
|
|
||||||
let selfStake = 0;
|
|
||||||
let selfStakeRatio = 0;
|
|
||||||
if (this.props.livepeer.thisOrchestrator) {
|
|
||||||
if (this.props.livepeer.thisOrchestrator.rewardCut) {
|
|
||||||
rewardCut = (this.props.livepeer.thisOrchestrator.rewardCut / 10000).toFixed(2);
|
|
||||||
}
|
|
||||||
if (this.props.livepeer.thisOrchestrator.feeShare) {
|
|
||||||
feeCut = (100 - (this.props.livepeer.thisOrchestrator.feeShare / 10000)).toFixed(2);
|
|
||||||
}
|
|
||||||
if (this.props.livepeer.thisOrchestrator.totalStake) {
|
|
||||||
totalStake = parseFloat(this.props.livepeer.thisOrchestrator.totalStake).toFixed(2);
|
|
||||||
}
|
|
||||||
if (this.props.livepeer.thisOrchestrator.totalVolumeETH) {
|
|
||||||
totalVolumeETH = parseFloat(this.props.livepeer.thisOrchestrator.totalVolumeETH * 1).toFixed(4);
|
|
||||||
}
|
|
||||||
if (this.props.livepeer.thisOrchestrator.totalVolumeUSD) {
|
|
||||||
totalVolumeUSD = parseFloat(this.props.livepeer.thisOrchestrator.totalVolumeUSD * 1).toFixed(2);
|
|
||||||
}
|
|
||||||
if (this.props.livepeer.thisOrchestrator.delegators && this.props.livepeer.thisOrchestrator.delegator) {
|
|
||||||
delegators = this.props.livepeer.thisOrchestrator.delegators;
|
|
||||||
selfStake = parseFloat(this.props.livepeer.thisOrchestrator.delegator.bondedAmount);
|
|
||||||
{
|
|
||||||
delegators.map((delObj, idx) => {
|
|
||||||
delegatorsTotalStake += parseFloat(delObj.bondedAmount);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
selfStakeRatio = ((selfStake / delegatorsTotalStake) * 100).toFixed(2);
|
|
||||||
delegatorsTotalStake = delegatorsTotalStake.toFixed(2);
|
|
||||||
selfStake = selfStake.toFixed(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="stroke" style={{ margin: 0, padding: 0 }}>
|
<div className="stroke" style={{ margin: 0, padding: 0 }}>
|
||||||
<div className="row" style={{ margin: 0, padding: 0 }}>
|
<div className="row" style={{ margin: 0, padding: 0 }}>
|
||||||
@ -106,43 +66,22 @@ class Grafana extends React.Component {
|
|||||||
<div className="stroke" style={{ marginTop: 0, marginBottom: 5, paddingBottom: 0 }}>
|
<div className="stroke" style={{ marginTop: 0, marginBottom: 5, paddingBottom: 0 }}>
|
||||||
<div className="stroke roundedOpaque" style={{}}>
|
<div className="stroke roundedOpaque" style={{}}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<h2> <img alt="" src="livepeer.png" width="30" height="30" /> <a href="https://explorer.livepeer.org/accounts/0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e/">Livepeer Orchestrator</a></h2>
|
<div className="row">
|
||||||
|
<img alt="" src="livepeer.png" width="30" height="30" />
|
||||||
|
<p>${lptPrice}</p>
|
||||||
|
<p>({lptPriceChange24h}%)</p>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<h2> <a href="https://explorer.livepeer.org/accounts/0x847791cbf03be716a7fe9dc8c9affe17bd49ae5e/">Livepeer Orchestrator</a></h2>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<img alt="" src="eth.png" width="30" height="30" />
|
||||||
|
<p>${ethPrice}</p>
|
||||||
|
<p>({ethPriceChange24h}%)</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="stroke roundedOpaque" style={{ borderRadius: "1em", backgroundColor: "#111217" }}>
|
<div className="stroke roundedOpaque" style={{ borderRadius: "1em", backgroundColor: "#111217" }}>
|
||||||
<div className="hostInfo" style={{ margin: 0, padding: 0 }}>
|
<Orchestrator thisOrchestrator={this.props.livepeer.thisOrchestrator} />
|
||||||
<div className="stroke" style={{ margin: 0, padding: 0 }}>
|
|
||||||
<div className="row">
|
|
||||||
<h3>Price Info</h3>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<img alt="" src="livepeer.png" width="30" height="30" />
|
|
||||||
<p>${lptPrice}</p>
|
|
||||||
<p>({lptPriceChange24h}%)</p>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<img alt="" src="eth.png" width="30" height="30" />
|
|
||||||
<p>${ethPrice}</p>
|
|
||||||
<p>({ethPriceChange24h}%)</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="stroke" style={{ margin: 0, padding: 0 }}>
|
|
||||||
<div className="row">
|
|
||||||
<h3>Orchestrator Info</h3>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<p>Reward Cut {rewardCut}%</p>
|
|
||||||
<p>Fee Cut {feeCut}%</p>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<p>Total Stake {totalStake} LPT</p>
|
|
||||||
<p>Earned fees {totalVolumeETH} Eth (${totalVolumeUSD})</p>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<p>Self stake {selfStake} LPT (Ratio of {selfStakeRatio}%)</p>
|
|
||||||
<p>Total stake {delegatorsTotalStake} LPT</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flexContainer" style={{ justifyContent: "center" }}>
|
<div className="flexContainer" style={{ justifyContent: "center" }}>
|
||||||
<iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572077" height="400" frameBorder="0"></iframe>
|
<iframe className="fullGrafana" src="https://grafana.stronk.tech/d-solo/71b6OZ0Gz/orchestrator-overview?orgId=1&refresh=5s&theme=dark&panelId=23763572077" height="400" frameBorder="0"></iframe>
|
||||||
</div>
|
</div>
|
||||||
|
72
src/orchestratorViewer.js
Normal file
72
src/orchestratorViewer.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Orchestrator = (obj) => {
|
||||||
|
let rewardCut = 0;
|
||||||
|
let feeCut = 0;
|
||||||
|
let totalStake = 0;
|
||||||
|
let totalVolumeETH = 0;
|
||||||
|
let totalVolumeUSD = 0;
|
||||||
|
let delegators = [];
|
||||||
|
let selfStake = 0;
|
||||||
|
let selfStakeRatio = 0;
|
||||||
|
if (obj.thisOrchestrator) {
|
||||||
|
if (obj.thisOrchestrator.rewardCut) {
|
||||||
|
rewardCut = (obj.thisOrchestrator.rewardCut / 10000).toFixed(2);
|
||||||
|
}
|
||||||
|
if (obj.thisOrchestrator.feeShare) {
|
||||||
|
feeCut = (100 - (obj.thisOrchestrator.feeShare / 10000)).toFixed(2);
|
||||||
|
}
|
||||||
|
if (obj.thisOrchestrator.totalStake) {
|
||||||
|
totalStake = parseFloat(obj.thisOrchestrator.totalStake).toFixed(2);
|
||||||
|
}
|
||||||
|
if (obj.thisOrchestrator.totalVolumeETH) {
|
||||||
|
totalVolumeETH = parseFloat(obj.thisOrchestrator.totalVolumeETH * 1).toFixed(4);
|
||||||
|
}
|
||||||
|
if (obj.thisOrchestrator.totalVolumeUSD) {
|
||||||
|
totalVolumeUSD = parseFloat(obj.thisOrchestrator.totalVolumeUSD * 1).toFixed(2);
|
||||||
|
}
|
||||||
|
if (obj.thisOrchestrator.delegators && obj.thisOrchestrator.delegator) {
|
||||||
|
delegators = obj.thisOrchestrator.delegators;
|
||||||
|
selfStake = parseFloat(obj.thisOrchestrator.delegator.bondedAmount);
|
||||||
|
selfStakeRatio = ((selfStake / totalStake) * 100).toFixed(2);
|
||||||
|
selfStake = selfStake.toFixed(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="hostInfo" style={{ margin: 0, padding: 0 }}>
|
||||||
|
<div className="stroke" style={{ margin: 0, padding: 0 }}>
|
||||||
|
<div className="rowAlignLeft">
|
||||||
|
<h3>Orchestrator Info</h3>
|
||||||
|
</div>
|
||||||
|
<div className="rowAlignLeft">
|
||||||
|
<p>Reward Cut {rewardCut}%</p>
|
||||||
|
<p>Fee Cut {feeCut}%</p>
|
||||||
|
</div>
|
||||||
|
<div className="rowAlignLeft">
|
||||||
|
<p>Total Stake {totalStake} LPT</p>
|
||||||
|
</div>
|
||||||
|
<div className="rowAlignLeft">
|
||||||
|
<p>Self stake {selfStake} LPT ({selfStakeRatio}%)</p>
|
||||||
|
</div>
|
||||||
|
<div className="rowAlignLeft">
|
||||||
|
<p>Earned fees {totalVolumeETH} Eth (${totalVolumeUSD})</p>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
delegators.map((delObj, idx) => {
|
||||||
|
return (
|
||||||
|
<div className="rowAlignLeft">
|
||||||
|
<a href={"https://explorer.livepeer.org/accounts/" + delObj.id}>
|
||||||
|
<img alt="" src="livepeer.png" width="30" height="30" />
|
||||||
|
</a>
|
||||||
|
<p>{parseFloat(delObj.bondedAmount).toFixed(2)} LPT since round {delObj.startRound}</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Orchestrator;
|
@ -2,7 +2,8 @@ import {
|
|||||||
RECEIVE_QUOTES,
|
RECEIVE_QUOTES,
|
||||||
RECEIVE_BLOCKCHAIN_DATA,
|
RECEIVE_BLOCKCHAIN_DATA,
|
||||||
RECEIVE_EVENTS,
|
RECEIVE_EVENTS,
|
||||||
RECEIVE_ORCHESTRATOR
|
RECEIVE_ORCHESTRATOR,
|
||||||
|
RECEIVE_CURRENT_ORCHESTRATOR
|
||||||
} from "../../actions/livepeer";
|
} from "../../actions/livepeer";
|
||||||
|
|
||||||
export default (state = {}, { type, message }) => {
|
export default (state = {}, { type, message }) => {
|
||||||
@ -14,8 +15,10 @@ export default (state = {}, { type, message }) => {
|
|||||||
return { ...state, blockchains: message };
|
return { ...state, blockchains: message };
|
||||||
case RECEIVE_EVENTS:
|
case RECEIVE_EVENTS:
|
||||||
return { ...state, events: message };
|
return { ...state, events: message };
|
||||||
case RECEIVE_ORCHESTRATOR:
|
case RECEIVE_CURRENT_ORCHESTRATOR:
|
||||||
return { ...state, thisOrchestrator: message.transcoders[0] };
|
return { ...state, thisOrchestrator: message.transcoders[0] };
|
||||||
|
case RECEIVE_ORCHESTRATOR:
|
||||||
|
return { ...state, selectedOrchestrator: message.transcoders[0] };
|
||||||
default:
|
default:
|
||||||
return { ...state };
|
return { ...state };
|
||||||
}
|
}
|
||||||
|
@ -256,6 +256,19 @@ svg {
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rowAlignLeft {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.flexItem {
|
.flexItem {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
@ -34,4 +34,14 @@ export const getCurrentOrchestratorInfo = () => (
|
|||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
export const getOrchestratorInfo = (orchAddr) => (
|
||||||
|
fetch("api/livepeer/getOrchestrator", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(orchAddr),
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
})
|
||||||
);
|
);
|
Loading…
x
Reference in New Issue
Block a user