-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
45266c0
commit 67c1a4f
Showing
23 changed files
with
364 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './useGetGaugesFunction' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { GaugeAbi } from '@/lib/abis/v2/GaugeAbi' | ||
import { Address } from 'viem' | ||
import { useReadContracts } from 'wagmi' | ||
import { AVERAGE_BLOCKTIME } from '@/lib/constants' | ||
import { useMemo } from 'react' | ||
import { AbiFunction } from 'viem' | ||
|
||
type FunctionEntry = Extract<(typeof GaugeAbi)[number], AbiFunction> | ||
type FunctionName = Extract< | ||
FunctionEntry['name'], | ||
'earned' | 'claimedBackerRewards' | 'estimatedBackerRewards' | 'totalAllocation' | ||
> | ||
type FunctionParams = FunctionEntry['inputs'] | ||
|
||
//TODO: Add the correct return type | ||
export const useGaugesGetFunction = <FunctionResult>( | ||
gauges: Address[], | ||
functionName: FunctionName, | ||
functionParams?: FunctionParams, | ||
) => { | ||
const contractCalls = gauges.map(gauge => { | ||
return { | ||
address: gauge, | ||
abi: GaugeAbi, | ||
functionName, | ||
args: functionParams, | ||
} as const | ||
}) | ||
|
||
const { | ||
data: contractResults, | ||
isLoading, | ||
error, | ||
} = useReadContracts<bigint[]>({ | ||
contracts: contractCalls, | ||
query: { | ||
refetchInterval: AVERAGE_BLOCKTIME, | ||
}, | ||
}) | ||
|
||
const gaugesMap = useMemo( | ||
() => | ||
gauges.reduce<Record<Address, FunctionResult>>((acc, gauge, index) => { | ||
if (!contractResults) { | ||
return {} as Record<Address, FunctionResult> | ||
} | ||
|
||
if (contractResults[index].error) { | ||
throw contractResults[index].error | ||
} | ||
|
||
const result = contractResults[index].result as FunctionResult | ||
acc[gauge] = result | ||
|
||
return acc | ||
}, {}), | ||
[gauges, contractResults], | ||
) | ||
|
||
return { | ||
data: gaugesMap, | ||
isLoading, | ||
error, | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
src/app/collective-rewards/metrics/AllTimeRewardsMetrics.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { Address } from 'viem' | ||
import { | ||
MetricsCard, | ||
MetricsCardTitle, | ||
useGetGaugesNotifyReward, | ||
Token, | ||
TokenMetricsCardRow, | ||
formatMetrics, | ||
} from '@/app/collective-rewards/rewards' | ||
import { FC } from 'react' | ||
import { useHandleErrors } from '@/app/collective-rewards/utils' | ||
import { withSpinner } from '@/components/LoadingSpinner/withLoadingSpinner' | ||
import { formatBalanceToHuman } from '@/app/user/Balances/balanceUtils' | ||
import { usePricesContext } from '@/shared/context/PricesContext' | ||
|
||
type TokenRewardsMetricsProps = { | ||
gauges: Address[] | ||
currency?: string | ||
token: Token | ||
} | ||
|
||
const TokenRewardsMetrics: FC<TokenRewardsMetricsProps> = ({ | ||
gauges, | ||
token: { symbol, address }, | ||
currency = 'USD', | ||
}) => { | ||
const { data, isLoading, error } = useGetGaugesNotifyReward(gauges, address) | ||
|
||
useHandleErrors({ error, title: 'Error loading all time rewards' }) | ||
|
||
const { prices } = usePricesContext() | ||
|
||
const totalRewards = Object.values(data).reduce( | ||
(acc, events) => | ||
acc + | ||
events.reduce( | ||
(acc, { args: { backersAmount_, builderAmount_ } }) => acc + backersAmount_ + builderAmount_, | ||
0n, | ||
), | ||
0n, | ||
) | ||
|
||
const totalRewardsInHuman = Number(formatBalanceToHuman(totalRewards)) | ||
const price = prices[symbol]?.price ?? 0 | ||
|
||
const { amount, fiatAmount } = formatMetrics(totalRewardsInHuman, price, symbol, currency) | ||
|
||
return withSpinner( | ||
TokenMetricsCardRow, | ||
'min-h-0 grow-0', | ||
)({ | ||
amount, | ||
fiatAmount, | ||
isLoading, | ||
}) | ||
} | ||
|
||
type AllTimeRewardsProps = { | ||
gauges: Address[] | ||
tokens: { | ||
[token: string]: Token | ||
} | ||
} | ||
|
||
export const AllTimeRewardsMetrics: FC<AllTimeRewardsProps> = ({ gauges, tokens: { rif, rbtc } }) => { | ||
return ( | ||
<MetricsCard borderless> | ||
<MetricsCardTitle title="All time rewards" data-testid="AllTimeRewards" /> | ||
<TokenRewardsMetrics gauges={gauges} token={rif} /> | ||
<TokenRewardsMetrics gauges={gauges} token={rbtc} /> | ||
</MetricsCard> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { MetricsCard } from '@/components/MetricsCard' | ||
import { useCycleContext } from '@/app/collective-rewards/metrics' | ||
import { Duration, DateTime } from 'luxon' | ||
import { useEffect, useState } from 'react' | ||
|
||
let timeout: NodeJS.Timeout | ||
|
||
export const CycleMetrics = () => { | ||
const [timeRemaining, setTimeRemaining] = useState<Duration>(Duration.fromObject({ minutes: 0 })) | ||
let { | ||
data: { cycleDuration, cycleNext }, | ||
} = useCycleContext() | ||
|
||
const duration = | ||
cycleDuration.as('days') < 1 ? cycleDuration.shiftTo('hours') : cycleDuration.shiftTo('days') | ||
|
||
useEffect(() => { | ||
if (timeRemaining.as('minutes') > 0) { | ||
timeout = setTimeout(() => { | ||
setTimeRemaining(state => state.minus({ minutes: 1 })) | ||
}, 60000) // every minute | ||
} else { | ||
clearTimeout(timeout) | ||
} | ||
|
||
return () => clearTimeout(timeout) | ||
}, [timeRemaining.minutes]) | ||
|
||
useEffect(() => { | ||
const now = DateTime.now() | ||
let diff = cycleNext.diff(now, ['days']).mapUnits(unit => Math.floor(unit)) | ||
|
||
if (diff.as('days') < 1) { | ||
diff = cycleNext.diff(now, ['hours', 'minutes']).mapUnits(unit => Math.floor(unit)) | ||
} | ||
|
||
setTimeRemaining(diff) | ||
}, [cycleNext]) | ||
|
||
return ( | ||
<MetricsCard | ||
title="Current cycle" | ||
amount={`${timeRemaining?.toHuman()}`} | ||
fiatAmount={`out of ${duration.toHuman()}. Ends ${cycleNext.toFormat('EEE, dd MMM')}`} | ||
borderless | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { useGetGaugesArray, withBuilderButton } from '@/app/collective-rewards/user' | ||
import { HeaderTitle } from '@/components/Typography' | ||
import { | ||
TotalAllocationsMetrics, | ||
CycleMetrics, | ||
CycleContextProvider, | ||
TotalActiveBuildersMetrics, | ||
AllTimeRewardsMetrics, | ||
} from '@/app/collective-rewards/metrics' | ||
import { getAddress } from 'viem' | ||
import { tokenContracts } from '@/lib/contracts' | ||
import { getCoinbaseAddress } from '@/app/collective-rewards/utils' | ||
import { PricesContextProvider } from '@/shared/context/PricesContext' | ||
|
||
const HeaderWithBuilderButton = withBuilderButton(HeaderTitle) | ||
|
||
export const Metrics = () => { | ||
const { data: activeGauges } = useGetGaugesArray('active') | ||
const gauges = activeGauges ?? [] | ||
|
||
const tokens = { | ||
rif: { | ||
address: getAddress(tokenContracts.RIF), | ||
symbol: 'RIF', | ||
}, | ||
rbtc: { | ||
address: getCoinbaseAddress(), | ||
symbol: 'RBTC', | ||
}, | ||
} | ||
|
||
return ( | ||
<div> | ||
<HeaderWithBuilderButton>Metrics</HeaderWithBuilderButton> | ||
<PricesContextProvider> | ||
<CycleContextProvider> | ||
<div className="flex gap-4 w-full"> | ||
<div className="flex gap-4 h-min w-3/4"> | ||
<CycleMetrics /> | ||
<TotalActiveBuildersMetrics /> | ||
|
||
<TotalAllocationsMetrics gauges={gauges} token={tokens.rif} /> | ||
</div> | ||
<div className="w-1/4"> | ||
<AllTimeRewardsMetrics gauges={gauges} tokens={tokens} /> | ||
</div> | ||
</div> | ||
</CycleContextProvider> | ||
</PricesContextProvider> | ||
</div> | ||
) | ||
} |
This file was deleted.
Oops, something went wrong.
17 changes: 17 additions & 0 deletions
17
src/app/collective-rewards/metrics/TotalActiveBuildersMetrics.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { MetricsCardWithSpinner } from '@/components/MetricsCard/MetricsCard' | ||
import { useGetGaugesLength } from '../user' | ||
import { useHandleErrors } from '@/app/collective-rewards/utils' | ||
|
||
export const TotalActiveBuildersMetrics = () => { | ||
const { data, isLoading, error } = useGetGaugesLength('active') | ||
useHandleErrors({ error, title: 'Error loading active builders' }) | ||
|
||
return ( | ||
<MetricsCardWithSpinner | ||
title="Total active builders" | ||
amount={Number(data || 0n).toFixed()} | ||
isLoading={isLoading} | ||
borderless | ||
/> | ||
) | ||
} |
41 changes: 41 additions & 0 deletions
41
src/app/collective-rewards/metrics/TotalAllocationsMetrics.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { useGaugesGetFunction } from '@/app/collective-rewards/hooks' | ||
import { Address } from 'viem' | ||
import { useHandleErrors } from '@/app/collective-rewards/utils' | ||
import { MetricsCardWithSpinner } from '@/components/MetricsCard/MetricsCard' | ||
import { FC } from 'react' | ||
import { usePricesContext } from '@/shared/context/PricesContext' | ||
import { Token } from '@/app/collective-rewards/rewards' | ||
import { formatCurrency } from '@/lib/utils' | ||
import { formatBalanceToHuman } from '@/app/user/Balances/balanceUtils' | ||
|
||
type TotalAllocationsProps = { | ||
gauges: Address[] | ||
currency?: string | ||
token: Token | ||
} | ||
|
||
export const TotalAllocationsMetrics: FC<TotalAllocationsProps> = ({ | ||
gauges, | ||
token: { symbol }, | ||
currency = 'USD', | ||
}) => { | ||
const { prices } = usePricesContext() | ||
const { data, isLoading, error } = useGaugesGetFunction<bigint>(gauges, 'totalAllocation', []) | ||
useHandleErrors({ error, title: 'Error loading total allocations' }) | ||
|
||
const price = prices[symbol]?.price ?? 0 | ||
|
||
const totalAllocations = Object.values(data).reduce((acc, allocation) => acc + allocation, 0n) | ||
const totalAllocationsInHuman = Number(formatBalanceToHuman(totalAllocations)) | ||
const fiatAmount = `= ${currency} ${formatCurrency(totalAllocationsInHuman * price, currency)}` | ||
|
||
return ( | ||
<MetricsCardWithSpinner | ||
title="Total allocations" | ||
amount={`${totalAllocationsInHuman} STRIF`} | ||
fiatAmount={fiatAmount} | ||
isLoading={isLoading} | ||
borderless | ||
/> | ||
) | ||
} |
23 changes: 0 additions & 23 deletions
23
src/app/collective-rewards/metrics/components/CycleMetrics.tsx
This file was deleted.
Oops, something went wrong.
29 changes: 0 additions & 29 deletions
29
src/app/collective-rewards/metrics/components/WhitelistedBuildersLengthMetrics.tsx
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.