瀏覽代碼

Solved conflict issue

mkbeefcake 1 年之前
父節點
當前提交
b0ef1013b8
共有 4 個文件被更改,包括 321 次插入323 次删除
  1. 275 310
      src/App.tsx
  2. 15 7
      src/components/Dashboard/Validation.tsx
  3. 12 6
      src/lib/election.ts
  4. 19 0
      src/lib/validation.ts

+ 275 - 310
src/App.tsx

@@ -1,7 +1,6 @@
+import React from "react";
 import "bootstrap/dist/css/bootstrap.min.css";
 import "./index.css";
-
-import React, { useEffect, useState } from "react";
 import { Modals, Routes, Loading, Footer, Status } from "./components";
 
 import * as get from "./lib/getters";
@@ -20,248 +19,150 @@ import {
   getValidatorStakes,
   getEraRewardPoints,
   getLastReward,
-  getTotalStake,
+  // getTotalStake,
 } from "./lib/validators";
+
+import {
+  getCountForValidators,
+  getTotalMinted,
+  getTotalStake
+} from './lib/validation';
+
 import { apiLocation, wsLocation, historyDepth } from "./config";
 import { initialState } from "./state";
 import axios from "axios";
 
-import { useElectedCouncils } from '@/hooks';
-import { ElectedCouncil } from "@/types";
-
 // types
-// import { Api, IState } from "./types";
+import { Api, IState } from "./types";
 // import { types } from "@joystream/types";
 import { ApiPromise, WsProvider } from "@polkadot/api";
 import { Header } from "@polkadot/types/interfaces";
 
-const App = (props: {}) => {
-
-  const [stars, setStars] = useState(initialState.stars);
-  const [editKpi, setEditKpi] = useState(initialState.editKpi);
-  const [showStatus, setShowStatus] = useState(initialState.showStatus);
-  const [hideFooter, setHideFooter] = useState(initialState.hideFooter);
-  const [members, setMembers] = useState(initialState.members);
-  const [connected, setConnected] = useState(initialState.connected);
-  const [fetching, setFetching] = useState(initialState.fetching);
-  const [status, setStatus] = useState(initialState.status);
-  const [assets, setAssets] = useState(initialState.assets);
-  const [providers, setProviders] = useState(initialState.providers);
-  const [councils, setCouncils] = useState(initialState.councils);
-  const [council, setCouncil] = useState<ElectedCouncil | undefined>(undefined);
-  const [election, setElection] = useState(initialState.election);
-  const [workers, setWorkers] = useState([]);
-  const [categories, setCategories] = useState(initialState.categories);
-  const [channels, setChannels] = useState(initialState.channels);
-  const [proposals, setProposals] = useState(initialState.proposals);
-  const [posts, setPosts] = useState(initialState.posts);
-  const [threads, setThreads] = useState(initialState.threads);
-  const [mints, setMints] = useState(initialState.mints);
-  const [openings, setOpenings] = useState(initialState.openings);
-  const [tokenomics, setTokenomics] = useState({});
-  const [transactions, setTransactions] = useState([]);
-  const [reports, setReports] = useState(initialState.reports);
-  const [validators, setValidators] = useState(initialState.validators);
-  const [nominators, setNominators] = useState(initialState.nominators);
-  const [stashes, setStashes] = useState(initialState.stashes);
-  const [stakes, setStakes] = useState(initialState.stakes);
-  const [rewardPoints, setRewardPoints] = useState(initialState.rewardPoints);
-  const [blocks, setBlocks] = useState(initialState.blocks);
-
-  const [initialized, setInitialized] = useState(false);
-
-  const childProps = {
-    stars,
-    editKpi,
-    showStatus,
-    hideFooter,
-    members,
-    connected,
-    fetching,
-    status,
-    assets,
-    providers,    
-    councils,
-    council,
-    election,
-    workers,
-    categories,
-    channels,
-    proposals,
-    posts,
-    threads,
-    mints,
-    openings,
-    tokenomics,
-    transactions,
-    reports,
-    validators,
-    nominators,
-    stashes,
-    stakes,
-    rewardPoints
-  }
-
-  // ----------------------------------------------
-  // Loading progress
-  // ----------------------------------------------
-  const { data } = useElectedCouncils({});
-
-	useEffect(() => {
-		if (!data) 
-      return
-
-    if (council && council.electionCycleId == data[0].electionCycleId) 
-      return
-
-    console.log(`App.ts`, data)
-    setCouncil(data[0]) 
-	}, [data])
-
-  useEffect(() => {
-    loadData();
-    joyApi();
-  }, [])
-
-
-  // ----------------------------------------------
-  // Joystream Chain API
-  // ----------------------------------------------
-  const joyApi = () => {
-    console.debug(`Connecting to ${wsLocation}`);
-    const provider = new WsProvider(wsLocation);
-
-    ApiPromise.create({ provider }).then(async (api) => {
-      await api.isReady;
-      console.log(`Connected to ${wsLocation}`);
-      
-      setConnected(true);
-      // this.updateWorkingGroups(api);
-
-      api.rpc.chain.subscribeNewHeads(async (header: Header) => {
-        const id = header.number.toNumber();
-
-        // period call per 1 min for updates
-        const elapsedOneMin = id % 10 === 0;
-        if (elapsedOneMin /*|| status.block.id + 10 < id*/) {
-          updateStatus(api, id);
-        } 
-
-        // if (blocks.find((b) => b.id === id)) 
-        //   return;
-
-        // const timestamp = (await api.query.timestamp.now()).toNumber();
-        // const duration = status.block
-        //   ? timestamp - status.block.timestamp
-        //   : 6000;
-        // status.block = { id, timestamp, duration };
-        // this.save("status", status);
-
-        // blocks = blocks.filter((i) => i.id !== id).concat(status.block);
-        // this.setState({ blocks });
-      });
-    });    
-  }
-
-  const loadData = async () => {
-    console.debug(`Loading data`)
-    setStars(load("stars"))
-    setEditKpi(load("editKpi"))
-    setShowStatus(load("showStatus"))
-    setHideFooter(load("hideFooter"))
-    setMembers(load("members"))
-    setConnected(load("connected"))
-    setFetching(load("fetching"))
-    setStatus(load("status"))
-    setAssets(load("assets"))
-    setProviders(load("providers"))
-    setCouncils(load("councils"))
-    setCouncil(load("council"))
-    setElection(load("election"))
-    setWorkers(load("workers"))
-    setCategories(load("categories"))
-    setChannels(load("channels"))
-    setProposals(load("proposals"))
-    setPosts(load("posts"))
-    setThreads(load("threads"))
-    setMints(load("mints"))
-    setOpenings(load("openings"))
-    setTokenomics(load("tokenomics"))
-    setTransactions(load("transactions"))
-    setReports(load("reports"))
-    setValidators(load("validators"))
-    setNominators(load("nominators"))
-    setStashes(load("stashes"))
-    setStakes(load("stakes"))
-    setRewardPoints(load("rewardPoints"))
-
-    // getTokenomics().then((tokenomics) => this.save(`tokenomics`, tokenomics));
-    // bootstrap(this.save); // axios requests
-    // this.updateCouncils();
-  }
-
-  // ---------------------------------------------------
-  // Polkadot api functions
-  // --------------------------------------------------
-  const updateStatus = async (api: ApiPromise, id: number): Promise<any> => {
+interface IProps {}
+
+class App extends React.Component<IProps, IState> {
+  // initializeSocket() {
+  //   socket.on("disconnect", () => setTimeout(this.initializeSocket, 1000));
+  //   socket.on("connect", () => {
+  //     if (!socket.id) return console.log("no websocket connection");
+  //     console.log("my socketId:", socket.id);
+  //     socket.emit("get posts", this.state.posts.length);
+  //   });
+  //   socket.on("posts", (posts: Post[]) => {
+  //     console.log(`received ${posts.length} posts`);
+  //     this.setState({ posts });
+  //   });
+  // }
+
+  // sync via joystream-api
+
+  async updateStatus(api: ApiPromise, id: number): Promise<typeof Status> {
     console.debug(`#${id}: Updating status`);
+    this.updateActiveProposals();
+    getMints(api).then((mints) => this.save(`mints`, mints));
+    getTokenomics().then((tokenomics) => this.save(`tokenomics`, tokenomics));
+
+    let { status, councils } = this.state;
+    status.election = await updateElection(api);
+    if (status.election?.stage) this.getElectionStatus(api);
+    councils.forEach((c) => {
+      if (c?.round > status.council) status.council = c;
+    });
 
-    // updateActiveProposals();
-    // getMints(api).then((mints) => {
-    //   setMints(mints) 
-    //   save(`mints`, mints) 
-    // });
-    // getTokenomics().then((tokenomics) => save(`tokenomics`, tokenomics));
-
-    // let { status, councils } = this.state;
-    // status.election = await updateElection(api);
-    // if (status.election?.stage) getElectionStatus(api);
-    // councils.forEach((c) => {
-    //   if (c?.round > status.council) status.council = c;
-    // });
-
-    // let hash: string = await api.rpc.chain.getBlockHash(1);
-    // if (hash)
-    //   status.startTime = (await api.query.timestamp.now.at(hash)).toNumber();
+    let hash: string = await api.rpc.chain.getBlockHash(1);
+    if (hash)
+      status.startTime = (await api.query.timestamp.now.at(hash)).toNumber();
 
     const nextMemberId = await await api.query.members.nextMemberId();
-    // setMembers(nextMemberId - 1);
-    setProposals(await get.proposalCount(api));
-    setPosts(await get.currentPostId(api));
-    setThreads(await get.currentThreadId(api));
-    setCategories(await get.currentCategoryId(api));
-    // status.proposalPosts = await api.query.proposalsDiscussion.postCount();
-
-    await updateEra(api, status.era).then(async (era) => {
-      let _status = {era: 0, lastReward:0, validatorStake: 0}
-      _status.era = era;
-      _status.lastReward = await getLastReward(api, era);
-      _status.validatorStake = await getTotalStake(api, era);
-      
-      setStatus(_status)
-      save("status", _status);
+    status.members = nextMemberId - 1;
+    status.proposals = await get.proposalCount(api);
+    status.posts = await get.currentPostId(api);
+    status.threads = await get.currentThreadId(api);
+    status.categories = await get.currentCategoryId(api);
+    status.proposalPosts = await api.query.proposalsDiscussion.postCount();
+    await this.updateEra(api, status.era).then(async (era) => {
+      status.era = era;
+      status.lastReward = await getLastReward(api, era);
+      status.validatorStake = await getTotalStake(api, era);
+      this.save("status", status);
+    });
+    return status;
+  }
 
+  async getElectionStatus(api: ApiPromise): Promise<IElectionState> {
+    getCouncilSize(api).then((councilSize) => {
+      let election = this.state.election;
+      election.councilSize = councilSize;
+      this.save("election", election);
+    });
+    getVotes(api).then((votes) => {
+      let election = this.state.election;
+      election.votes = votes;
+      this.save("election", election);
     });
+    getCouncilApplicants(api).then((applicants) => {
+      let election = this.state.election;
+      election.applicants = applicants;
+      this.save("election", election);
+    });
+  }
 
-     // return status;
-  }  
+  updateActiveProposals() {
+    const active = this.state.proposals.filter((p) => p.result === "Pending");
+    if (!active.length) return;
+    const s = active.length > 1 ? `s` : ``;
+    console.log(`Updating ${active.length} active proposal${s}`);
+    active.forEach(async (a) => {
+      const { data } = await axios.get(`${apiLocation}/v2/proposals/${a.id}`);
+      if (!data || data.error)
+        return console.error(`failed to fetch proposal from API`);
+      this.save(
+        "proposals",
+        this.state.proposals.map((p) => (p.id === a.id ? data : p))
+      );
+    });
+  }
 
-  const updateEra = async (api: ApiPromise, old: number) => {
+  async updateEra(api: Api, old: number) {
+    const { status, validators } = this.state;
     const era = Number(await api.query.staking.currentEra());
-    if (era === old) 
-      return era;
+    if (era === old) return era;
+    this.updateWorkingGroups(api);
+    this.updateValidatorPoints(api, status.era);
+    if (era > status.era || !validators.length) this.updateValidators(api);
+    return era;
+  }
 
-    // this.updateWorkingGroups(api);
-    updateValidatorPoints(api, era);
-    
-    if (era > status.era || !validators.length) 
-      updateValidators(api);
+  async updateWorkingGroups(api: ApiPromise) {
+    const { members, openings, workers } = this.state;
+    updateWorkers(api, workers, members).then((workers) => {
+      this.save("workers", workers);
+      updateOpenings(api, openings, members).then((openings) =>
+        this.save("openings", openings)
+      );
+    });
+    return this.save("council", await api.query.council.activeCouncil());
+  }
 
-    return era;
+  updateValidators(api: ApiPromise) {
+    getValidators(api).then((validators) => {
+      this.save("validators", validators);
+      getNominators(api).then((nominators) => {
+        this.save("nominators", nominators);
+        getStashes(api).then((stashes) => {
+          this.save("stashes", stashes);
+          const { status, members } = this.state;
+          const { era } = status;
+          getValidatorStakes(api, era, stashes, members, this.save).then(
+            (stakes) => this.save("stakes", stakes)
+          );
+        });
+      });
+    });
   }
 
-  const updateValidatorPoints = async (api: ApiPromise, currentEra: number) => {
-    let points = rewardPoints;
+  async updateValidatorPoints(api: ApiPromise, currentEra: number) {
+    let points = this.state.rewardPoints;
 
     const updateTotal = (eraTotals) => {
       let total = 0;
@@ -270,56 +171,150 @@ const App = (props: {}) => {
     };
 
     for (let era = currentEra; era > currentEra - historyDepth; --era) {
-      if (era < 0 || (era < currentEra && points.eraTotals[era]))
-        continue;
-
-      const eraPoints = await getEraRewardPoints(api, era);
-      points.eraTotals[era] = eraPoints.total;
-      Object.keys(eraPoints.individual).forEach((validator: string) => {
-        if (!points.validators[validator]) points.validators[validator] = {};
-        points.validators[validator][era] = eraPoints.individual[validator];
+      if (era < currentEra && points.eraTotals[era]) continue;
+      getEraRewardPoints(api, era).then((eraPoints) => {
+        console.debug(`era ${era}: ${eraPoints.total} points`);
+        points.eraTotals[era] = eraPoints.total;
+        points.total = updateTotal(points.eraTotals);
+        Object.keys(eraPoints.individual).forEach((validator: string) => {
+          if (!points.validators[validator]) points.validators[validator] = {};
+          points.validators[validator][era] = eraPoints.individual[validator];
+        });
+        this.save("rewardPoints", points);
       });
     }
+  }
 
-    points.total = updateTotal(points.eraTotals);
-    console.debug(`Reward Points: ${points.total} points`);
+  async updateCouncils() {
+    queryJstats(`v1/councils`).then((councils) => {
+      this.save(`councils`, councils);
 
-    setRewardPoints(points);
-    save("rewardPoints", points);
+      // TODO OPTIMIZE find max round
+      let council = { round: 0 };
+      councils.forEach((c) => {
+        if (c.round > council.round) council = c;
+      });
+      let { status } = this.state;
+      status.council = council; // needed by dashboard
+      this.save("status", status);
+    });
+  }
+
+  // interface interactions
 
+  toggleStar(account: string) {
+    let { stars } = this.state;
+    stars[account] = !stars[account];
+    this.save("stars", stars);
   }
 
-  const updateValidators = (api: ApiPromise) => {
-    getValidators(api).then((validators) => {
+  toggleEditKpi(editKpi) {
+    this.setState({ editKpi });
+  }
+  toggleShowStatus() {
+    this.setState({ showStatus: !this.state.showStatus });
+  }
+  toggleFooter() {
+    this.setState({ hideFooter: !this.state.hideFooter });
+  }
+
+  getMember(handle: string) {
+    const { members } = this.state;
+    const member = members.find((m) => m.handle === handle);
+    if (member) return member;
+    return members.find((m) => m.rootKey === handle);
+  }
+
+  render() {
+    const { connected, fetching, loading, hideFooter } = this.state;
+    if (loading) return <Loading />;
+
+    return (
+      <>
+        <Routes
+          toggleEditKpi={this.toggleEditKpi}
+          toggleFooter={this.toggleFooter}
+          toggleStar={this.toggleStar}
+          getMember={this.getMember}
+          {...this.state}
+        />
+
+        <Modals
+          toggleEditKpi={this.toggleEditKpi}
+          toggleShowStatus={this.toggleShowStatus}
+          {...this.state}
+        />
+
+        <Footer show={!hideFooter} toggleHide={this.toggleFooter} />
+
+        <Status
+          toggleShowStatus={this.toggleShowStatus}
+          connected={connected}
+          fetching={fetching}
+        />
+      </>
+    );
+  }
+
+  async getStakesForValidators(api: ApiPromise) {
+    const era = Number(await api.query.staking.currentEra());
+    console.log('Era: ', era);
+
+    // added by mkblockchaindev
+    let validation = {count: 0, minted: 0, stakes: 0}
+    validation.count = await getCountForValidators(api);
+    validation.minted = await getTotalMinted(api);
+    validation.stakes = await getTotalStake(api, era);
+    this.save("validation", validation);
+
+    // await this.updateValidatorPoints(api, era);
+    // await this.updateValidators(api);
+    // console.log('LastReward', await getLastReward(api, era));
+    // console.log('getTotalStake', await getTotalStake(api, era));
+  }
+
+  // startup from bottom up
+  joyApi() {
+    console.debug(`Connecting to ${wsLocation}`);
+    const provider = new WsProvider(wsLocation);
+
+    ApiPromise.create({ provider/*, types*/ }).then(async (api) => {
+      await api.isReady;
+      console.log(`Connected to ${wsLocation}`);
       
-      setValidators(validators);
-      save("validators", validators);
+      this.setState({ connected: true });
+      // this.updateWorkingGroups(api);
 
-      getNominators(api).then((nominators) => {
-        
-        setNominators(nominators);
-        save("nominators", nominators);
+      // For getting Reward
+      await this.getStakesForValidators(api);
+  
+      api.rpc.chain.subscribeNewHeads(async (header: Header) => {
+        let { blocks, status } = this.state;
+        const id = header.number.toNumber();
 
-        getStashes(api).then((stashes) => {
-          
-          setStashes(stashes);
-          save("stashes", stashes);
+        // console.log(`api.rpc.chain.subscribeNewHeads: ${id}`)
 
-          const { era } = status;
-          getValidatorStakes(api, era, stashes, members, save).then(
-            (stakes) => { 
-              setStakes(stakes)
-              save("stakes", stakes)
-            }
-          );
-        });
+        const isEven = id / 50 === Math.floor(id / 50);
+        if (isEven || status.block?.id + 50 < id) { 
+          this.updateStatus(api, id);
+        }
+
+        if (blocks.find((b) => b.id === id)) return;
+        const timestamp = (await api.query.timestamp.now()).toNumber();
+        const duration = status.block
+          ? timestamp - status.block.timestamp
+          : 6000;
+        status.block = { id, timestamp, duration };
+        this.save("status", status);
+
+        blocks = blocks.filter((i) => i.id !== id).concat(status.block);
+        this.setState({ blocks });
       });
     });
   }
 
-
-  // Save & Load data to local storage
-  const save = (key: string, data: any) => {
+  save(key: string, data: any) {
+    this.setState({ [key]: data });
     const value = JSON.stringify(data);
     try {
       localStorage.setItem(key, value);
@@ -330,77 +325,47 @@ const App = (props: {}) => {
     return data;
   }
 
-  const load = (key: string) => {
+  load(key: string) {
     try {
       const data = localStorage.getItem(key);
       if (!data) return;
       const size = data.length;
       if (size > 10240)
         console.debug(` -${key}: ${(size / 1024).toFixed(1)} KB`);
-
+      this.setState({ [key]: JSON.parse(data) });
       return JSON.parse(data);
     } catch (e) {
       console.warn(`Failed to load ${key}`, e);
     }
-  }  
-
-  // Trigger functions
-  const toggleStar = (account: string) => {
-    let temp = stars;  
-    temp[account] = !temp[account];
-    setStars(temp);
-    save("stars", temp);
   }
 
-  const toggleEditKpi = (_editKpi: boolean) => {
-    setEditKpi(_editKpi);
+  async loadData() {
+    console.debug(`Loading data`);
+    "status members assets providers councils council election workers categories channels proposals posts threads mints openings tokenomics transactions reports validators nominators staches stakes rewardPoints stars"
+      .split(" ")
+      .map((key) => this.load(key));
+    getTokenomics().then((tokenomics) => this.save(`tokenomics`, tokenomics));
+    bootstrap(this.save); // axios requests
+    this.updateCouncils();
   }
 
-  const toggleShowStatus = () => {
-    setShowStatus(!showStatus);
-  }
-  
-  const toggleFooter = () => {
-    setHideFooter(!hideFooter);
+  componentDidMount() {
+    // this.loadData(); // local storage + bootstrap
+    this.joyApi(); // joystream rpc connection
+    //this.initializeSocket() // jsstats socket.io
   }
 
-  const getMember = (handle: string) => {    
-    const member = members.find((m) => m.handle === handle);
-    if (member) return member;
-    return members.find((m) => m.rootKey === handle);
+  constructor(props: IProps) {
+    super(props);
+    this.state = initialState;
+    this.save = this.save.bind(this);
+    this.load = this.load.bind(this);
+    this.toggleEditKpi = this.toggleEditKpi.bind(this);
+    this.toggleStar = this.toggleStar.bind(this);
+    this.toggleFooter = this.toggleFooter.bind(this);
+    this.toggleShowStatus = this.toggleShowStatus.bind(this);
+    this.getMember = this.getMember.bind(this);
   }
-
-  // const { connected, fetching, loading, hideFooter } = this.state;
-  // if (loading) 
-  //   return <Loading />;
-
-  return (
-    <>
-      <Routes
-        toggleEditKpi={toggleEditKpi}
-        toggleFooter={toggleFooter}
-        toggleStar={toggleStar}
-        getMember={getMember}
-        {...childProps}
-      />
-
-      <Modals
-        toggleEditKpi={toggleEditKpi}
-        toggleShowStatus={toggleShowStatus}
-        {...childProps}
-      />
-
-      <Footer show={!hideFooter} toggleHide={toggleFooter} />
-
-      <Status
-        toggleShowStatus={toggleShowStatus}
-        connected={connected}
-        fetching={fetching}
-      />
-    </>
-  );
-
-
 }
 
 export default App;

+ 15 - 7
src/components/Dashboard/Validation.tsx

@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
 import SubBlock from "./ui/SubBlock";
 import Line from "./ui/Line";
 import { ElectedCouncil } from "@/queries";
@@ -6,17 +6,25 @@ import { useValidation } from "@/hooks";
 
 const Validation = (props: { council: ElectedCouncil | undefined }) => {
   const { council } = props;
-  const { validator, stake, mint, loading, error } = useValidation({ council });
+  const [validation, setValidation] = useState({count: 0, minted: 0, stakes: 0});
 
-  console.log("validation", validator, stake, mint, loading)
+  // const { validator, stake, mint, loading, error } = useValidation({ council });
+  // console.log("validation", validator, stake, mint, loading)
+
+  useEffect(() => {
+    const data = localStorage.getItem("validation");
+    if (!data) return;
+
+    setValidation(JSON.parse(data));
+  }, [])
 
   return (
     <SubBlock title="Validation">
-      { !loading && (
+      {(
         <>
-          <Line content={"Count"} value={validator} />
-          <Line content={"Minted"} value={mint} />
-          <Line content={"Staked"} value={stake} />
+          <Line content={"Count"} value={validation.count} />
+          <Line content={"Minted"} value={validation.minted} />
+          <Line content={"Staked"} value={validation.stakes} />
         </>
       )}
     </SubBlock>

+ 12 - 6
src/lib/election.ts

@@ -13,14 +13,20 @@ export const finalizedBlockHeight = async (api: ApiPromise) => {
 export const finalizedHash = (api: ApiPromise) =>
   api.rpc.chain.getFinalizedHead();
 
-export const getCouncilSize = async (api: ApiPromise): Promise<number> =>
-  Number((await api.query.councilElection.councilSize()).toJSON());
+export const getCouncilSize = async (api: ApiPromise): Promise<number> => {
+  const councilSize: any = await api.query.councilElection.councilSize();
+  return councilSize.toJSON() || 0;
+}
 
-export const getCouncilRound = async (api: ApiPromise): Promise<Number> =>
-  Number((await api.query.councilElection.round()).toJSON());
+export const getCouncilRound = async (api: ApiPromise): Promise<number> =>{
+  const councilRound: any = await api.query.councilElection.round();
+  return councilRound.toJSON() || 0;
+}
 
-export const getTermEndsAt = async (api: ApiPromise): Promise<Number> =>
-  Number((await api.query.council.termEndsAt()).toJSON());
+export const getTermEndsAt = async (api: ApiPromise): Promise<number> => {
+  const termsEndsAt: any = await api.query.council.termEndsAt();
+  return termsEndsAt.toJSON() || 0;
+}
 
 export const getElectionStage = async (
   api: ApiPromise

+ 19 - 0
src/lib/validation.ts

@@ -0,0 +1,19 @@
+import { ApiPromise } from "@polkadot/api";
+
+// get validator count
+export const getCountForValidators = async (api: ApiPromise): Promise<number> =>{
+	const count: any = await api.query.staking.counterForValidators();
+	return count.toJSON() || 0;
+}
+  
+// get minted value
+export const getTotalMinted = async (api: ApiPromise): Promise<number> =>{
+	const minted: any = await api.query.balances.totalIssuance();
+	return minted.toJSON() || 0;
+}
+
+// get total stakes
+export const getTotalStake = async (api: ApiPromise, era: number): Promise<number> => {
+	const total: any = await api.query.staking.erasTotalStake(era);
+	return total.toJSON() || 0;
+}