From e1216aef72656d103fbccbd5cc0d5d073a18b040 Mon Sep 17 00:00:00 2001 From: Usame Algan <5880855+usame-algan@users.noreply.github.com> Date: Wed, 28 Sep 2022 14:38:00 +0200 Subject: [PATCH] fix: Display total allocation instead of balance in safe token widget (#4081) * fix: Display total allocation instead of balance in safe token widget * fix: Add function return type * chore: bump version to 3.31.1 --- package.json | 2 +- .../components/SafeTokenWidget/index.tsx | 13 ++-- .../SafeTokenWidget/useSafeTokenAllocation.ts | 66 +++++++++++++++++++ 3 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/components/AppLayout/Header/components/SafeTokenWidget/useSafeTokenAllocation.ts diff --git a/package.json b/package.json index ad4ff7097f..98630bca18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "safe-react", - "version": "3.31.0", + "version": "3.31.1", "description": "Allowing crypto users manage funds in a safer way", "website": "https://github.com/gnosis/safe-react#readme", "bugs": { diff --git a/src/components/AppLayout/Header/components/SafeTokenWidget/index.tsx b/src/components/AppLayout/Header/components/SafeTokenWidget/index.tsx index 9b0bcd9443..6b29960034 100644 --- a/src/components/AppLayout/Header/components/SafeTokenWidget/index.tsx +++ b/src/components/AppLayout/Header/components/SafeTokenWidget/index.tsx @@ -14,6 +14,8 @@ import styled from 'styled-components' import Track from 'src/components/Track' import { OVERVIEW_EVENTS } from 'src/utils/events/overview' import { useAppList } from 'src/routes/safe/components/Apps/hooks/appList/useAppList' +import useSafeTokenAllocation from 'src/components/AppLayout/Header/components/SafeTokenWidget/useSafeTokenAllocation' +import { fromTokenUnit } from 'src/logic/tokens/utils/humanReadableValue' const isStaging = !IS_PRODUCTION && !isProdGateway() export const CLAIMING_APP_ID = isStaging ? '61' : '95' @@ -46,6 +48,7 @@ const buttonStyle = { const SafeTokenWidget = (): JSX.Element | null => { const safeTokens = useSelector(extendedSafeTokensSelector) + const allocation = useSafeTokenAllocation() const { allApps } = useAppList() const claimingApp = allApps.find((app) => app.id === CLAIMING_APP_ID) @@ -69,12 +72,12 @@ const SafeTokenWidget = (): JSX.Element | null => { const url = `${appsPath}?appUrl=${encodeURI(claimingApp.url)}` - const safeBalance = safeTokens.find((balanceItem) => { - return balanceItem.address === tokenAddress + const safeToken = safeTokens.find((token) => { + return token.address === tokenAddress }) - const safeBalanceDecimals = Number(safeBalance?.balance?.tokenBalance || 0) - const flooredSafeBalance = formatAmount(safeBalanceDecimals.toFixed(2)) + const totalAllocation = Number(fromTokenUnit(allocation, safeToken?.decimals || 18)) + const flooredTotalAllocation = formatAmount(totalAllocation.toFixed(2)) return ( @@ -83,7 +86,7 @@ const SafeTokenWidget = (): JSX.Element | null => { Safe token - {flooredSafeBalance} + {flooredTotalAllocation} diff --git a/src/components/AppLayout/Header/components/SafeTokenWidget/useSafeTokenAllocation.ts b/src/components/AppLayout/Header/components/SafeTokenWidget/useSafeTokenAllocation.ts new file mode 100644 index 0000000000..46c6116c41 --- /dev/null +++ b/src/components/AppLayout/Header/components/SafeTokenWidget/useSafeTokenAllocation.ts @@ -0,0 +1,66 @@ +import { useEffect, useState } from 'react' +import useAsync from 'src/logic/hooks/useAsync' +import { useSelector } from 'react-redux' +import { currentChainId } from 'src/logic/config/store/selectors' +import useSafeAddress from 'src/logic/currentSession/hooks/useSafeAddress' +import { BigNumber } from 'bignumber.js' + +export const VESTING_URL = 'https://safe-claiming-app-data.gnosis-safe.io/allocations/' + +export type VestingData = { + tag: 'user' | 'ecosystem' + account: string + chainId: number + contract: string + vestingId: string + durationWeeks: number + startDate: number + amount: string + curve: 0 | 1 + proof: string[] +} + +const fetchAllocation = async (chainId: string, safeAddress: string) => { + try { + const response = await fetch(`${VESTING_URL}${chainId}/${safeAddress}.json`) + + if (response.ok) { + return response.json() as Promise + } + + if (response.status === 404) { + // No file exists => the safe is not part of any vesting + return Promise.resolve([]) as Promise + } + } catch (err) { + throw Error(`Error fetching vestings: ${err}`) + } +} + +const useSafeTokenAllocation = (): string => { + const [allocation, setAllocation] = useState('0') + const chainId = useSelector(currentChainId) + const { safeAddress } = useSafeAddress() + + const [allocationData] = useAsync( + () => fetchAllocation(chainId, safeAddress), + [chainId, safeAddress], + ) + + useEffect(() => { + if (!allocationData) return + + const userAllocation = allocationData.find((data) => data.tag === 'user') + const ecosystemAllocation = allocationData.find((data) => data.tag === 'ecosystem') + + const totalAllocation = new BigNumber(userAllocation?.amount || '0') + .plus(ecosystemAllocation?.amount || '0') + .toString() + + setAllocation(totalAllocation) + }, [allocationData]) + + return allocation +} + +export default useSafeTokenAllocation