From fbbf52e131ec94c371413b69aba06003ca1eff57 Mon Sep 17 00:00:00 2001 From: Lucian Date: Tue, 14 Nov 2023 10:10:14 -0800 Subject: [PATCH] feat(ui): updating to use scorer backend instead of subgraph (#25) --- packages/react-app/.sample.env | 2 +- packages/react-app/src/types.ts | 5 +- .../react-app/src/views/StakeDashboard.tsx | 116 ++++++++++++------ 3 files changed, 84 insertions(+), 39 deletions(-) diff --git a/packages/react-app/.sample.env b/packages/react-app/.sample.env index 08368c7..66dc07c 100644 --- a/packages/react-app/.sample.env +++ b/packages/react-app/.sample.env @@ -1,8 +1,8 @@ # REACT_APP_PROVIDER=https://rinkeby.infura.io/v3/2717afb6bf164045b5d5468031b93f87 # REACT_APP_NETWORK_OPTIONS_NUMBER=1 -# REACT_APP_SUBGRAPH_URL= # REACT_APP_REQUIRE_USER_HAS_PASSPORT=true # REACT_APP_CURRENT_ROUND=1 +# REACT_APP_SCORER_URL=https://api.scorer.gitcoin.co # REACT_APP_INTERCOM_APP_ID=your_intercom_appID # REACT_APP_ALCHEMY_URL= # REACT_APP_INFURA_ID= diff --git a/packages/react-app/src/types.ts b/packages/react-app/src/types.ts index 2e2ca8d..98ece81 100644 --- a/packages/react-app/src/types.ts +++ b/packages/react-app/src/types.ts @@ -9,15 +9,14 @@ export type Stake = { stake: string; }; -export type XstakeAggregates = { +export type XstakeAggregate = { total: string; - id: string; }; export type IndexedStakeData = { user?: { xstakeTo?: XstakeTo[]; - xstakeAggregates?: XstakeAggregates[]; + xstakeAggregates?: XstakeAggregate[]; stakes?: Stake[]; }; }; diff --git a/packages/react-app/src/views/StakeDashboard.tsx b/packages/react-app/src/views/StakeDashboard.tsx index eef3a74..9d04104 100644 --- a/packages/react-app/src/views/StakeDashboard.tsx +++ b/packages/react-app/src/views/StakeDashboard.tsx @@ -1,11 +1,11 @@ -import React, { useEffect, useState, useContext } from "react"; +import React, { useEffect, useState, useContext, useCallback } from "react"; import { Button } from "antd"; -import { ethers } from "ethers"; +import { BigNumber, ethers } from "ethers"; import { Rounds, Navbar } from "../components"; import { useNavigate } from "react-router-dom"; import moment from "moment"; -import { gql, useLazyQuery } from "@apollo/client"; import { UsergroupAddOutlined, LockOutlined, InfoCircleOutlined } from "@ant-design/icons"; +import { IndexedStakeData } from "../types"; import { getAmountStakedOnMe, formatGtc } from "../components/StakingModal/utils"; import StakingDoneNotificationModal from "../components/StakingModal/StakingDoneNotificationModal"; @@ -15,6 +15,19 @@ import { Web3Context } from "../helpers/Web3Context"; // --- sdk import import { PassportReader } from "@gitcoinco/passport-sdk-reader"; +import axios from "axios"; + +type StakeData = { + id: number; + event_type: string; + round_id: number; + staker?: string; + address?: string; + amount: string; + staked: boolean; + block_number: number; + tx_hash: string; +}; // Update Passport on address change const reader = new PassportReader(); @@ -116,37 +129,66 @@ function StakeDashboard({ tx(writeContracts.IDStaking.migrateStake(id)); }; - // Populate Round Data - const query = gql(` - query User($address: String!, $round: BigInt!) { - user(id: $address) { - xstakeAggregates (where: { round: $round }) { - id - total - }, - stakes(where: { round: $round }) { - stake - round { - id - } - }, - xstakeTo(where: { round: $round }) { - amount, - to { - address + const [data, setData] = useState({ + user: { + xstakeAggregates: [], + stakes: [], + xstakeTo: [], + }, + }); + + const getData = useCallback(async () => { + if (address && roundInView) { + const stakes: StakeData[] = + ( + await axios.get( + `${process.env.REACT_APP_SCORER_URL}/registry/gtc-stake/${address.toLowerCase()}/${roundInView}`, + ) + ).data?.results || []; + + let stakedOnByOthersTotal = BigNumber.from(0); + let selfStakeTotal = BigNumber.from(0); + const xstakeToTotals: Record = {}; + + for (const stake of stakes) { + // These amounts come from the API as decimal strings with 18 decimal places + const stakeAmount = BigNumber.from(stake.amount.replace(".", "")); + const operation = stake.staked ? "add" : "sub"; + + if (stake.address?.toLowerCase() === address.toLowerCase()) { + stakedOnByOthersTotal = stakedOnByOthersTotal[operation](stakeAmount); + } else if (stake.staker?.toLowerCase() === address.toLowerCase()) { + if (stake.address) { + if (!xstakeToTotals[stake.address]) xstakeToTotals[stake.address] = BigNumber.from(0); + xstakeToTotals[stake.address] = xstakeToTotals[stake.address][operation](stakeAmount); + } else { + selfStakeTotal = selfStakeTotal[operation](stakeAmount); + } } } - } - } -`); - const [getData, { loading, data, error }] = useLazyQuery(query, { - variables: { - address: address.toLowerCase(), - round: roundInView, - }, - fetchPolicy: "network-only", - }); + setData({ + user: { + xstakeAggregates: [ + { + total: stakedOnByOthersTotal.toString(), + }, + ], + stakes: [ + { + stake: selfStakeTotal.toString(), + }, + ], + xstakeTo: Object.entries(xstakeToTotals).map(([address, total]) => ({ + to: { + address, + }, + amount: total.toString(), + })), + }, + }); + } + }, [address, roundInView]); useEffect(() => { address && getData(); @@ -299,15 +341,19 @@ function StakeDashboard({
-

- Prior Seasons & Unstaking Information: -

+

Prior Seasons & Unstaking Information:

- Season 18 concluded on August 31st. If you wish to manage stakes from previous seasons, including Alpha, Beta, and Season 18, scroll down to the Viewing Stake for section at the bottom of this page. You can select the relevant round to unstake or restake as needed. + Season 18 concluded on August 31st. If you wish to manage stakes from previous seasons, including + Alpha, Beta, and Season 18, scroll down to the{" "} + + Viewing Stake for + {" "} + section at the bottom of this page. You can select the relevant round to unstake or restake as + needed.