Skip to content

Commit

Permalink
Merge pull request #141 from dappforce/creator-rewards-claim
Browse files Browse the repository at this point in the history
Add creator rewards claim button
  • Loading branch information
olehmell authored Feb 5, 2024
2 parents 501b73d + 532d481 commit 3f1611f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,25 @@ import { fetchEraStakes } from 'src/rtk/features/creatorStaking/eraStake/eraStak
import { fetchBackerLedger } from 'src/rtk/features/creatorStaking/backerLedger/backerLedgerHooks'
import { useSendEvent } from '@/components/providers/AnalyticContext'
import { useResponsiveSize } from '@/components/responsive'
import { fetchCreatorRewards } from '@/rtk/features/creatorStaking/creatorRewards/creatorRewardsHooks'
import { isEmptyArray } from '@subsocial/utils'

type ClaimRewardsTxButtonProps = {
backerClaimsCount?: Record<string, string>
creatorClaimsCount?: Record<string, string[]>
rewardsSpaceIds: string[]
totalRewards: string
availableClaimsBySpaceId?: Record<string, string>
restake: boolean
label: React.ReactNode
}

const ClaimRewardsTxButton = ({
rewardsSpaceIds,
backerClaimsCount = {},
creatorClaimsCount = {},
totalRewards,
availableClaimsBySpaceId,
restake,
label
label,
}: ClaimRewardsTxButtonProps) => {
const dispatch = useAppDispatch()
const myAddress = useMyAddress()
Expand All @@ -48,6 +52,11 @@ const ClaimRewardsTxButton = ({
fetchGeneralEraInfo(dispatch)

if (myAddress) {
fetchCreatorRewards(
dispatch,
myAddress || '',
Object.keys(creatorClaimsCount)
)
fetchBackerRewards(dispatch, myAddress, rewardsSpaceIds)
fetchBackerLedger(dispatch, myAddress)
}
Expand All @@ -62,8 +71,47 @@ const ClaimRewardsTxButton = ({
}
}

const buildParams = async (api: ApiPromise) => {
if (!myAddress || !availableClaimsBySpaceId) return []
const buildCreatorParams = async (api: ApiPromise) => {
if (!myAddress || !creatorClaimsCount) return []

const rewardsSpaceIds = Object.keys(creatorClaimsCount)
const era = creatorClaimsCount[rewardsSpaceIds[0]][0]

const calculatedMaxClaimCount = await calculateMaxTxCountInBatch(
api,
api.tx.creatorStaking.claimCreatorReward(rewardsSpaceIds[0], era),
myAddress
)

if (!calculatedMaxClaimCount) return []

const txs: any[] = []
let maxClaimCount = calculatedMaxClaimCount

Object.entries(creatorClaimsCount).forEach(([ spaceId, availableClaims ]) => {
if (new BN(availableClaims.length).lt(maxClaimCount)) {
availableClaims.forEach((era) => {
const claimTx = api.tx.creatorStaking.claimCreatorReward(spaceId, era)

txs.push(claimTx)
})
maxClaimCount = maxClaimCount.minus(availableClaims.length)
} else {
const claimsCount = availableClaims.slice(0, maxClaimCount.toNumber())

claimsCount.forEach((era) => {
const claimTx = api.tx.creatorStaking.claimCreatorReward(spaceId, era)

txs.push(claimTx)
})
}
})

return [ txs ]
}

const buildBackersParams = async (api: ApiPromise) => {
if (!myAddress || !backerClaimsCount) return []

const calculatedMaxClaimCount = await calculateMaxTxCountInBatch(
api,
Expand All @@ -77,7 +125,7 @@ const ClaimRewardsTxButton = ({

let claimsToDo: Record<string, string> = {}

Object.entries(availableClaimsBySpaceId).forEach(
Object.entries(backerClaimsCount).forEach(
([ spaceId, availableClaimCount ]) => {
if (new BN(availableClaimCount).lt(maxClaimCount)) {
claimsToDo[spaceId] = availableClaimCount
Expand Down Expand Up @@ -107,6 +155,8 @@ const ClaimRewardsTxButton = ({

const disableButton = !myAddress || new BN(totalRewards).isZero() || loading

const isCreatorRewards = !isEmptyArray(Object.keys(creatorClaimsCount))

return (
<LazyTxButton
network='subsocial'
Expand All @@ -115,7 +165,7 @@ const ClaimRewardsTxButton = ({
disabled={disableButton}
onClick={() => sendEvent('cs_claim', { restake })}
component={Component}
params={buildParams}
params={isCreatorRewards ? buildCreatorParams : buildBackersParams}
onFailed={showParsedErrorMessage}
onSuccess={onSuccess}
/>
Expand Down
55 changes: 46 additions & 9 deletions src/components/creatorsStaking/ClaimSections/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import ValueOrSkeleton from '../utils/ValueOrSkeleton'
import BN from 'bignumber.js'
import NewStakingVersionSection from '../utils/NewStakingVersionSection'
import { useFetchBackerInfoBySpaces } from '@/rtk/features/creatorStaking/backerInfo/backerInfoHooks'
import {
useCreatorRewards,
useFetchCreatorRewards,
} from '../../../rtk/features/creatorStaking/creatorRewards/creatorRewardsHooks'
import { isEmptyArray } from '@subsocial/utils'
import { toGenericAccountId } from '@/rtk/app/util'

const ClaimSection = () => {
const myAddress = useMyAddress()
Expand All @@ -32,19 +38,45 @@ const ClaimSection = () => {
myAddress,
myCreatorsIds.length ? myCreatorsIds : creatorsSpaceIds
)

const creators = creatorsList?.filter(
(item) => toGenericAccountId(item.creator.stakeholder) === myAddress
)

useFetchCreatorRewards(
myAddress,
creators?.map((item) => item.id)
)

const backerRewards = useBackerRewards(myAddress)
const creatorRewards = useCreatorRewards(myAddress)

const { data: rewardsData, loading: rewardsLoading } = backerRewards || {}
const { data: creatorRewardsData, loading: creatorRewardsLoading } =
creatorRewards || {}
const { data: backerRewardsData, loading: backerRewardsLoading } =
backerRewards || {}

const { rewards, availableClaimsBySpaceId } = rewardsData || {}
const { rewards: creatorRewardsValue, availableClaims: creatorClaimsCount } =
creatorRewardsData || {}
const { rewards, availableClaimsBySpaceId: backerClaimsCount } =
backerRewardsData || {}

const { totalRewards } = rewards || {}

if (new BN(totalRewards || '0').isZero()) return null
const creatorRewardsBN = new BN(creatorRewardsValue || '0')
const stakerRewardsBN = new BN(totalRewards || '0')

if (creatorRewardsBN.isZero() && stakerRewardsBN.isZero()) return null

const isCreatorRewards = !isEmptyArray(Object.keys(creatorClaimsCount || {}))

const myRewardsValue = (
<FormatBalance
value={totalRewards?.toString() || '0'}
value={
isCreatorRewards
? creatorRewardsBN.toString()
: stakerRewardsBN.toString()
}
decimals={decimal}
currency={symbol}
isGrayDecimal={false}
Expand All @@ -54,7 +86,7 @@ const ClaimSection = () => {
const myRewards = (
<ValueOrSkeleton
value={myRewardsValue}
loading={rewardsLoading}
loading={isCreatorRewards ? creatorRewardsLoading : backerRewardsLoading}
skeletonClassName='h-[24px]'
/>
)
Expand All @@ -68,13 +100,18 @@ const ClaimSection = () => {
👉 Next steps
</div>
<div className='text-slate-900 text-lg font-normal text-center leading-[26px]'>
You have staking rewards of{' '}
You have {isCreatorRewards ? 'creators' : 'staking'} rewards of{' '}
<span className='font-semibold'>{myRewards}</span> available to claim:
</div>
<ClaimRewardsTxButton
rewardsSpaceIds={Object.keys(availableClaimsBySpaceId || {}) || []}
totalRewards={totalRewards || '0'}
availableClaimsBySpaceId={availableClaimsBySpaceId}
rewardsSpaceIds={Object.keys(backerClaimsCount || {}) || []}
totalRewards={
isCreatorRewards
? creatorRewardsBN.toString()
: stakerRewardsBN.toString()
}
backerClaimsCount={backerClaimsCount}
creatorClaimsCount={creatorClaimsCount}
restake={false}
label={<>Claim {myRewards}</>}
/>
Expand Down

0 comments on commit 3f1611f

Please sign in to comment.