Skip to content

Commit

Permalink
feat: Historical pool rewards to Staking API, replace Subscan (#2376)
Browse files Browse the repository at this point in the history
  • Loading branch information
rossbulat authored Dec 22, 2024
1 parent b2a8af1 commit 9233131
Show file tree
Hide file tree
Showing 19 changed files with 380 additions and 361 deletions.
2 changes: 0 additions & 2 deletions packages/app/src/common-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import type { FastUnstakeQueueResult } from 'contexts/FastUnstake/types'
import type { Theme } from 'contexts/Themes/types'
import type { NotificationItem } from 'controllers/Notifications/types'
import type { OnlineStatusEvent } from 'controllers/OnlineStatus/types'
import type { PayoutType } from 'controllers/Subscan/types'
import type { SyncEvent } from 'controllers/Syncs/types'
import type { FC, FunctionComponent, SVGProps } from 'react'
import type { DetailActivePool } from 'types'
Expand Down Expand Up @@ -60,7 +59,6 @@ declare global {
'new-sync-status': CustomEvent<SyncEvent>
'new-external-account': CustomEvent<{ address: string }>
'new-account-balance': CustomEvent<ActiveBalance & { address: string }>
'subscan-data-updated': CustomEvent<{ keys: PayoutType[] }>
'new-tx-uid-status': CustomEvent<{ uids: TxSubmissionItem[] }>
}
}
Expand Down
7 changes: 1 addition & 6 deletions packages/app/src/contexts/Plugins/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,8 @@ export const PluginsProvider = ({ children }: { children: ReactNode }) => {

// Reset payouts on Subscan plugin not enabled. Otherwise fetch payouts.
useEffectIgnoreInitial(() => {
if (!plugins.includes('subscan')) {
Subscan.resetData()
} else if (isReady && !activeEra.index.isZero()) {
if (plugins.includes('subscan')) {
Subscan.network = network
if (activeAccount) {
Subscan.handleFetchPayouts(activeAccount)
}
}
}, [plugins.includes('subscan'), isReady, network, activeAccount, activeEra])

Expand Down
61 changes: 0 additions & 61 deletions packages/app/src/controllers/Subscan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import { poolMembersPerPage } from 'library/List/defaults'
import type { PoolMember } from 'types'
import type {
SubscanData,
SubscanEraPoints,
SubscanPoolClaim,
SubscanPoolClaimRaw,
SubscanPoolMember,
SubscanRequestBody,
} from './types'
Expand All @@ -17,15 +14,11 @@ export class Subscan {
static ENDPOINTS = {
eraStat: '/api/scan/staking/era_stat',
poolMembers: '/api/scan/nomination_pool/pool/members',
poolRewards: '/api/scan/nomination_pool/rewards',
}

// The network to use for Subscan API calls
static network: string

// Subscan payout data, keyed by address
static payoutData: Record<string, SubscanData> = {}

// Subscan pool data, keyed by `<network>-<poolId>-<key1>-<key2>...`
static poolData: Record<string, PoolMember[]> = {}

Expand All @@ -37,55 +30,6 @@ export class Subscan {
Subscan.network = network
}

// Handle fetching pool claims and set state in one render
static handleFetchPayouts = async (address: string): Promise<void> => {
try {
if (!this.payoutData[address]) {
const poolClaims = await this.fetchPoolClaims(address)
this.payoutData[address] = {
poolClaims,
}
document.dispatchEvent(
new CustomEvent('subscan-data-updated', {
detail: {
keys: ['poolClaims'],
},
})
)
}
} catch (e) {
// Silently fail request
}
}

// Fetch pool claims from Subscan, ensuring no payouts have block_timestamp of 0.
static fetchPoolClaims = async (
address: string
): Promise<SubscanPoolClaim[]> => {
try {
const result = await this.makeRequest(this.ENDPOINTS.poolRewards, {
address,
row: 100,
page: 0,
})
if (!result?.list) {
return []
}
// Remove claims with a `block_timestamp`
const poolClaims = result.list
.filter((l: SubscanPoolClaimRaw) => l.block_timestamp !== 0)
.map((l: SubscanPoolClaimRaw) => ({
...l,
reward: l.amount,
timestamp: l.block_timestamp,
type: 'pool',
}))
return poolClaims
} catch (e) {
return []
}
}

// Fetch a page of pool members from Subscan
static fetchPoolMembers = async (
poolId: number,
Expand Down Expand Up @@ -166,11 +110,6 @@ export class Subscan {
}
}

// Resets all received data from class.
static resetData = () => {
this.payoutData = {}
}

// Get the public Subscan endpoint.
static getEndpoint = () => `https://${this.network}.api.subscan.io`

Expand Down
54 changes: 4 additions & 50 deletions packages/app/src/controllers/Subscan/types.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import type { NominatorReward } from 'plugin-staking-api/types'
export type SubscanRequestBody = EraStatRequestBody | PoolDataRequestBody

export type PayoutType = 'poolClaims'

export type SubscanData = Partial<Record<PayoutType, SubscanResult>>

export interface SubscanPayoutData {
poolClaims: SubscanPoolClaim[]
}

export type PayoutsAndClaims = (NominatorReward | SubscanPoolClaim)[]

export type SubscanRequestBody =
| PoolRewardsRequestBody
| PoolMembersRequestBody
| PoolDetailsRequestBody

export type PoolRewardsRequestBody = SubscanRequestPagination & {
export type EraStatRequestBody = SubscanRequestPagination & {
address: string
claimed_filter?: 'claimed' | 'unclaimed'
}

export type PoolMembersRequestBody = SubscanRequestPagination & {
pool_id: number
}

export interface PoolDetailsRequestBody {
export type PoolDataRequestBody = SubscanRequestPagination & {
pool_id: number
}

Expand All @@ -36,33 +16,7 @@ export interface SubscanRequestPagination {
page: number
}

export type SubscanResult = SubscanPoolClaim[] | SubscanPoolMember[]

export interface SubscanPoolClaimBase {
account_display: {
address: string
display: string
judgements: number[]
identity: boolean
}
amount: string
block_timestamp: number
event_id: string
event_index: string
extrinsic_index: string
module_id: string
pool_id: number
}

export type SubscanPoolClaimRaw = SubscanPoolClaimBase & {
amount: string
block_timestamp: number
}

export type SubscanPoolClaim = SubscanPoolClaimBase & {
reward: string
timestamp: number
}
export type SubscanResult = SubscanPoolMember[]

export interface SubscanPoolMember {
pool_id: number
Expand Down
27 changes: 27 additions & 0 deletions packages/app/src/hooks/useInjectBlockTimestamp/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2024 @polkadot-cloud/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import { useApi } from 'contexts/Api'
import type { NominatorReward } from 'plugin-staking-api/types'
import { useErasToTimeLeft } from '../useErasToTimeLeft'

export const useInjectBlockTimestamp = () => {
const { activeEra } = useApi()
const { erasToSeconds } = useErasToTimeLeft()

// Inject timestamp for unclaimed payouts. We take the timestamp of the start of the
// following payout era - this is the time payouts become available to claim by validators
// NOTE: Not currently being used
const injectBlockTimestamp = (entries: NominatorReward[]) => {
entries.forEach((p) => {
p.timestamp = activeEra.start
.multipliedBy(0.001)
.minus(erasToSeconds(activeEra.index.minus(p.era).minus(1)))
.toNumber()
})
return entries
}
return {
injectBlockTimestamp,
}
}
74 changes: 0 additions & 74 deletions packages/app/src/hooks/useSubscanData/index.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion packages/app/src/library/Graphs/PayoutLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export const PayoutLine = ({
datasets: [
{
label: t('payout'),
data: combinedPayouts.map(({ reward }: { reward: string }) => reward),
data: combinedPayouts.map(({ reward }) => reward),
borderColor: color,
pointStyle: undefined,
pointRadius: 0,
Expand Down
Loading

0 comments on commit 9233131

Please sign in to comment.