Skip to content

Commit

Permalink
Merge pull request #70 from AudiusProject/jowlee-rewards
Browse files Browse the repository at this point in the history
Add estimated reward
  • Loading branch information
jowlee committed Mar 12, 2021
1 parent 9a29c46 commit e92b8b7
Show file tree
Hide file tree
Showing 26 changed files with 779 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'

import RewardStat from 'components/RewardStat'
import { useAnnualRewardRate } from 'hooks/useRewardRate'
import { Status } from 'types'

const messages = {
label: `ESTIMATED ANNUAL REWARD RATE`
}

interface EstimatedAnnualStatProps {
className?: string
}

const EstimatedAnnualStat: React.FC<EstimatedAnnualStatProps> = ({
className
}) => {
const claimRate = useAnnualRewardRate()
const value =
claimRate.status === Status.Success
? `${claimRate.rate!.toFixed(0)}%`
: null
return <RewardStat label={messages.label} stat={value} />
}

export default EstimatedAnnualStat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './EstimatedAnnualStat'
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'

import RewardStat from 'components/RewardStat'
import { Status } from 'types'
import { useWeeklyRewardRate } from 'hooks/useRewardRate'

const messages = {
label: `ESTIMATED WEEKLY REWARD RATE`
}

interface EstimatedWeeklyStatProps {
className?: string
}

const EstimatedWeeklyStat: React.FC<EstimatedWeeklyStatProps> = ({
className
}) => {
const claimRate = useWeeklyRewardRate()
const value =
claimRate.status === Status.Success
? `${claimRate.rate!.toFixed(3)}%`
: null
return (
<RewardStat className={className} label={messages.label} stat={value} />
)
}

export default EstimatedWeeklyStat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './EstimatedWeeklyStat'
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.container {
display: inline-flex;
flex-direction: column;
align-items: center;
padding: 0px;
width: 300px;
min-width: 300px;
}

.rowContainer {
display: inline-flex;
width: 100%;
justify-content: space-between;
margin-bottom: 2px;
}

.label {
font-weight: var(--font-bold);
font-size: var(--font-m);
letter-spacing: 0.01em;
text-transform: uppercase;
color: var(--neutral-light-4);
}

.value {
font-weight: var(--font-bold);
font-size: var(--font-m);

text-align: right;
letter-spacing: 0.01em;
text-transform: uppercase;
color: var(--neutral);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { ReactNode } from 'react'

import Paper from 'components/Paper'
import styles from './MyEstimatedRewards.module.css'
import { TICKER } from 'utils/consts'
import { Address, Status } from 'types'
import {
useUserAnnualRewardRate,
useUserWeeklyRewards
} from 'store/cache/rewards/hooks'
import Loading from 'components/Loading'
import DisplayAudio from 'components/DisplayAudio'

const messages = {
staked: `Staked ${TICKER}`,
estAnnualRewards: 'Est. Annual Reward',
estWeeklyRewards: 'Est. Weekly Reward'
}

type RowStatProps = {
label: string
value: ReactNode
}
const RowStat: React.FC<RowStatProps> = ({ label, value }) => {
return (
<div className={styles.rowContainer}>
<div className={styles.label}>{label}</div>
<div className={styles.value}>{value}</div>
</div>
)
}

type OwnProps = {
wallet: Address
}

type MyEstimatedRewardsProps = OwnProps

/**
* Shows stats about staking. Lives on the SP page
*/
const MyEstimatedRewards: React.FC<MyEstimatedRewardsProps> = ({ wallet }) => {
const weeklyRewards = useUserWeeklyRewards({ wallet })
const annualRewards = useUserAnnualRewardRate({ wallet })
const isLoading =
weeklyRewards.status === Status.Loading ||
annualRewards.status === Status.Loading
const annual = annualRewards.reward ? (
<DisplayAudio amount={annualRewards.reward} />
) : null

const weekly =
'reward' in weeklyRewards ? (
<DisplayAudio amount={weeklyRewards.reward} />
) : null

return (
<Paper className={styles.container}>
{isLoading ? (
<Loading />
) : (
<>
<RowStat label={messages.estAnnualRewards} value={annual} />
<RowStat label={messages.estWeeklyRewards} value={weekly} />
</>
)}
</Paper>
)
}

export default MyEstimatedRewards
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './MyEstimatedRewards'
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Stats Container */

.container {
padding: 0px 16px;
display: inline-flex;
flex-direction: column;
justify-content: center;
min-width: 228px;
min-height: 150px;
box-sizing: border-box;
align-items: center;
}

.stat {
font-family: var(--font-family);
font-weight: 900;
font-size: 64px;
height: 76px;
text-align: center;
display: inline;
background: -webkit-linear-gradient(315deg, #7652CC 2.04%, #B05CE6 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}

.label,
.description {
font-family: var(--font-family);
font-weight: var(--font-bold);
font-size: var(--font-l);
line-height: 22px;
text-align: center;
letter-spacing: 0.04em;
text-transform: uppercase;
color: #BEC5E0;
user-select: none;
}

.loadingContainer {
height: 62px;
display: flex;
align-items: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { ReactNode } from 'react'

import Paper from 'components/Paper'
import styles from './RewardStat.module.css'
import Loading from 'components/Loading'
import Error from 'components/Error'
import clsx from 'clsx'

type OwnProps = {
className?: string
stat: ReactNode
label: string
error?: boolean
}

type RewardStatProps = OwnProps

const RewardStat: React.FC<RewardStatProps> = ({
className,
stat,
label,
error
}) => {
return (
<Paper className={clsx(styles.container, { [className!]: className })}>
{error ? (
<div className={styles.stat}>
<Error />
</div>
) : stat !== null ? (
<div className={styles.stat}>{stat}</div>
) : (
<div className={styles.loadingContainer}>
<Loading className={styles.loading} />
</div>
)}
<div className={styles.label}>{label}</div>
</Paper>
)
}

export default RewardStat
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './RewardStat'
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.statsChip {
padding: 24px 0px 16px;
padding: 24px 0px;
display: inline-flex;
flex-direction: column;
justify-content: center;
min-width: 228px;
box-sizing: border-box;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.userInfo {
position: relative;
flex: 1;
padding: 24px 0px;
padding: 24px 0px 18px;
display: inline-flex;
flex-direction: column;
align-items: center;
Expand Down Expand Up @@ -55,17 +55,18 @@
text-align: center;

color: #BEC5E0;
margin-bottom: 8px
}

.userName {
font-size: var(--font-2xl);
min-height: var(--font-2xl);
margin-bottom: 8px
}


.userWallet {
font-size: var(--font-s);
margin-bottom: 24px
}

.buttonContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useModalControls } from 'utils/hooks'
import { TICKER } from 'utils/consts'
import { formatAud } from 'utils/format'
import Loading from 'components/Loading'
import MyEstimatedRewards from 'components/MyEstimatedRewards'

import desktopStyles from './UserInfo.module.css'
import mobileStyles from './UserInfoMobile.module.css'
Expand Down Expand Up @@ -183,6 +184,7 @@ const UserInfo = ({
<img className={styles.userImg} src={image} alt={'User Profile'} />
<div className={styles.userName}>{name}</div>
<div className={styles.userWallet}>{wallet}</div>
<MyEstimatedRewards wallet={wallet} />
</>
)
}
Expand Down
14 changes: 14 additions & 0 deletions packages/protocol-dashboard/src/containers/Home/Home.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@
margin-right: 8px;
}

.rewards {
margin-bottom: 16px;
margin-left: -8px;
margin-right: -8px;
display: flex;
align-items: stretch;
}

.rewards > * {
flex-grow: 1;
margin-left: 8px;
margin-right: 8px;
}

.proposals {
flex-direction: column;
box-sizing: border-box;
Expand Down
7 changes: 6 additions & 1 deletion packages/protocol-dashboard/src/containers/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { GOVERNANCE } from 'utils/routes'
import TotalStakedStat from 'components/TotalStakedStat'
import ApiCallsStat from 'components/ApiCallsStat'
import UniqueUsersStat from 'components/UniqueUsersStat'
import EstimatedWeeklyStat from 'components/EstimatedWeeklyStat'
import EstimatedAnnualStat from 'components/EstimatedAnnualStat'

import desktopStyles from './Home.module.css'
import mobileStyles from './HomeMobile.module.css'
Expand Down Expand Up @@ -47,7 +49,10 @@ const Home: React.FC<HomeProps> = (props: HomeProps) => {
<ApiCallsStat />
<UniqueUsersStat />
</div>

<div className={styles.rewards}>
<EstimatedWeeklyStat />
<EstimatedAnnualStat />
</div>
{isLoggedIn && <ManageService />}

<Paper className={styles.proposals}>
Expand Down
31 changes: 31 additions & 0 deletions packages/protocol-dashboard/src/hooks/useRewardRate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import AudiusClient from 'services/Audius'
import useTotalStaked from './useTotalStaked'
import { useFundsPerRound } from 'store/cache/claims/hooks'
import { Status } from 'types'

export const useWeeklyRewardRate = () => {
const fundsPerRound = useFundsPerRound()
const totalActiveStake = useTotalStaked()
if (
fundsPerRound.status === Status.Success &&
totalActiveStake.status === Status.Success
) {
const percentage =
AudiusClient.getBNPercentage(
fundsPerRound.amount!,
totalActiveStake.total!,
4
) * 100
return { status: Status.Success, rate: percentage }
}
return { status: Status.Loading }
}

export const useAnnualRewardRate = () => {
const weeklyClaim = useWeeklyRewardRate()
if (weeklyClaim.status === Status.Success) {
const rate = weeklyClaim.rate! * 52
return { status: Status.Success, rate }
}
return { status: Status.Loading }
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export default class Claim {
// Get the amount funded per round in wei
async getFundsPerRound(): Promise<BN> {
await this.aud.hasPermissions()
const info = await this.getContract().getFundsPerRound()
return info
const claimAmount = await this.getContract().getFundsPerRound()
return new BN(claimAmount)
}

// Get the total amount claimed in the current round
Expand Down
Loading

0 comments on commit e92b8b7

Please sign in to comment.