Skip to content

Commit

Permalink
refactor: remove /validators/list call from preview pages
Browse files Browse the repository at this point in the history
  • Loading branch information
dawidsowardx committed Oct 1, 2024
1 parent 482875a commit b953b0b
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 124 deletions.
169 changes: 95 additions & 74 deletions apps/dashboard/src/lib/staking-card/StakedValidatorCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,89 +6,110 @@
import { formatXRDValue, formatTokenValue } from '@utils'
import BigNumber from 'bignumber.js'
import ValueBox from './ValueBox.svelte'
import ValidatorPlaceholder from '@icons/validator-placeholder.svg'
export let validatorStakes: any
</script>
import type { AccumulatedStakeInfo } from '../summary/summary'
import { onMount } from 'svelte'
import { validatorsCacheModule } from '@api/utils/validators-cache-module'
<div class="card validator-card">
<Accordion>
<div class="validator-header" slot="header">
<NftImage
url={validatorStakes.validator.metadata.expected.icon_url?.typed.value}
defaultImageUrl={ValidatorPlaceholder}
width={64}
height={64}
/>
<div class="validator-header-info">
<div class="validator-header-name">
<h4>
{validatorStakes.validator.metadata.expected.name?.typed.value ||
''}
</h4>
<Address
value={validatorStakes.validator.address}
autoShorten
--background="var(--theme-surface-3)"
/>
</div>
export let validatorStakes: AccumulatedStakeInfo
<div class="staked-header-info">
Staked {formatXRDValue(validatorStakes.accumulatedStakes)}
</div>
</div>
</div>
<svelte:fragment slot="content">
<div class="units-section">
<div class="content-section-header">
<TokenIcon
iconUrl="https://assets.radixdlt.com/icons/icon-liquid_stake_units.png"
/>
<span class="text">Liquid Stake Units</span>
<span class="value"
>{formatTokenValue(validatorStakes.accumulatedLiquidStakeUnits)
.displayValue}</span
>
</div>
let isLoading: boolean
<ValueBox
header="Worth"
address={validatorStakes.validator.stakeUnitResourceAddress}
value={validatorStakes.accumulatedStakes}
/>
</div>

{#if validatorStakes.unstaking.length || validatorStakes.readyToClaim.length}
<div class="units-section">
<div class="content-section-header">
<NftImage
url="https://assets.radixdlt.com/icons/icon-stake_claim_NFTs.png"
width={44}
height={44}
/>
onMount(() => {
const subscription = validatorsCacheModule.isLoading$.subscribe((data) => {
isLoading = data
})
return () => {
subscription.unsubscribe()
}
})
</script>

<span class="text">Stake Claims</span>
{#key isLoading}
{#if validatorsCacheModule}
{@const validator = validatorsCacheModule.validators.get(
validatorStakes.validatorAddress
)}
<div class="card validator-card">
<Accordion>
<div class="validator-header" slot="header">
<NftImage
url={validator?.iconUrl}
defaultImageUrl={ValidatorPlaceholder}
width={64}
height={64}
/>
<div class="validator-header-info">
<div class="validator-header-name">
<h4>
{validator?.name || ''}
</h4>
<Address
value={validatorStakes.validatorAddress}
autoShorten
--background="var(--theme-surface-3)"
/>
</div>

<div class="staked-header-info">
Staked {formatXRDValue(validatorStakes.accumulatedStakes)}
</div>
</div>
{#each validatorStakes.unstaking as stakeEntry}
<ValueBox
header="Unstaking"
address={validatorStakes.validator.stakeUnitResourceAddress}
value={BigNumber(stakeEntry.xrdAmount)}
/>
{/each}
</div>
<svelte:fragment slot="content">
<div class="units-section">
<div class="content-section-header">
<TokenIcon
iconUrl="https://assets.radixdlt.com/icons/icon-liquid_stake_units.png"
/>
<span class="text">Liquid Stake Units</span>
<span class="value"
>{formatTokenValue(validatorStakes.accumulatedLiquidStakeUnits)
.displayValue}</span
>
</div>

{#each validatorStakes.readyToClaim as stakeEntry}
<ValueBox
header="Ready to Claim"
address={stakeEntry.claimNft.address.nonFungibleAddress}
value={BigNumber(stakeEntry.xrdAmount)}
header="Worth"
address={validator?.poolUnitResourceAddress || ''}
value={validatorStakes.accumulatedStakes}
/>
{/each}
</div>
{/if}
</svelte:fragment>
</Accordion>
</div>
</div>

{#if validatorStakes.unstaking.length || validatorStakes.readyToClaim.length}
<div class="units-section">
<div class="content-section-header">
<NftImage
url="https://assets.radixdlt.com/icons/icon-stake_claim_NFTs.png"
width={44}
height={44}
/>

<span class="text">Stake Claims</span>
</div>
{#each validatorStakes.unstaking as stakeEntry}
<ValueBox
header="Unstaking"
address={validator?.poolUnitResourceAddress || ''}
value={BigNumber(stakeEntry.xrdAmount)}
/>
{/each}

{#each validatorStakes.readyToClaim as stakeEntry}
<ValueBox
header="Ready to Claim"
address={stakeEntry.claimNft.address.nonFungibleAddress}
value={BigNumber(stakeEntry.xrdAmount)}
/>
{/each}
</div>
{/if}
</svelte:fragment>
</Accordion>
</div>
{/if}
{/key}

<style lang="scss">
.validator-card {
Expand Down
46 changes: 18 additions & 28 deletions apps/dashboard/src/lib/summary/summary.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { callApi } from '@api/gateway'
import type { Component } from '@api/utils/entities/component'
import type { Account } from '@api/utils/entities/component/account'
import { getValidators } from '@api/utils/entities/component/validator'
import { transformFungibleResource } from '@api/utils/entities/resource/fungible'
import { getPoolUnits } from '@api/utils/entities/resource/fungible/pool-unit'
import { transformNonFungibleResource } from '@api/utils/entities/resource/non-fungible'
import { handleGatewayResult } from '@dashboard/utils'
import { andThen, flatten, map, pipe } from 'ramda'
import {
getStakedInfo,
getUnstakeAndClaimInfo,
getUnstakeAndClaimInfoV2,
type ReadyToClaimInfo,
type StakedInfo,
type StakeInfo,
Expand All @@ -20,7 +19,6 @@ import {
transformPool
} from '@api/utils/entities/component/pool'

import { type ValidatorListItem } from '@api/utils/entities/component/validator'
import { ResultAsync } from 'neverthrow'
import { transformNft } from '@api/utils/nfts'

Expand All @@ -33,7 +31,7 @@ import { errorPage } from '@dashboard/stores'
const ERROR_MSG = 'Failed to load entity data.'

export type AccumulatedStakeInfo = {
validator: ValidatorListItem
validatorAddress: string
staked: StakedInfo[]
unstaking: UnstakingInfo[]
readyToClaim: ReadyToClaimInfo[]
Expand Down Expand Up @@ -165,13 +163,13 @@ const getPoolUnitData =
export const produceSummary = (
account: Promise<Account | Component<unknown, typeof standardMetadata>>
) => {
const validatorResponse = pipe(
() => getValidators(undefined, false, false),
(result) => handleGatewayResult((_) => ERROR_MSG)(result)
)()

const stateVersion = validatorResponse.then(
(response) => response.ledger_state.state_version
const ledgerState = handleGatewayResult(
() => "Couldn't fetch current ledger state"
)(
callApi('getCurrent').map((result) => ({
stateVersion: result.ledger_state.state_version,
epoch: result.ledger_state.epoch
}))
)

const fungibleResources = account.then((acc) =>
Expand Down Expand Up @@ -238,19 +236,11 @@ export const produceSummary = (
)()
)

const stakeInfo = Promise.all([
validatorResponse,
account,
fungibleResources,
nfts
])
.then(([response, accountData, fungibles, nonFungibles]) => {
const stakeInfo = Promise.all([ledgerState, account, fungibleResources, nfts])
.then(([ledgerState, accountData, fungibles, nonFungibles]) => {
return [
getStakedInfo(response.validators, fungibles)(accountData),
getUnstakeAndClaimInfo(response.validators)(nonFungibles)(
accountData,
response.ledger_state.epoch
)
getStakedInfo(fungibles)(accountData),
getUnstakeAndClaimInfoV2(nonFungibles)(accountData, ledgerState.epoch)
] as const
})
.then(([staked, unstakeAndClaim]) => {
Expand All @@ -266,11 +256,11 @@ export const produceSummary = (
]

for (const stake of stakeInfo) {
const validator = stake.validator.address
const validator = stake.validatorAddress

if (!accumulatedStakes[validator]) {
accumulatedStakes[validator] = {
validator: stake.validator,
validatorAddress: stake.validatorAddress,
staked: [],
unstaking: [],
readyToClaim: [],
Expand Down Expand Up @@ -311,8 +301,8 @@ export const produceSummary = (
})

const poolData = pipe(
() => Promise.all([account, fungibleResources, stateVersion]),
andThen(([account, fungibles, stateVersion]) =>
() => Promise.all([account, fungibleResources, ledgerState]),
andThen(([account, fungibles, { stateVersion }]) =>
pipe(() => {
return getPoolUnits(
fungibles,
Expand All @@ -329,6 +319,6 @@ export const produceSummary = (
fungibleResources,
nonFungibleResources,
nfts,
stateVersion
stateVersion: ledgerState.then((ledgerState) => ledgerState.stateVersion)
}
}
11 changes: 11 additions & 0 deletions apps/dashboard/src/lib/token-pages/StakingPageWrapper.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import StakedValidatorCard from '@dashboard/lib/staking-card/StakedValidatorCard.svelte'
import type { LayoutDataStakeInfo } from '../summary/summary'
import NoTokens from './NoTokens.svelte'
import { validatorsCacheModule } from '@api/utils/validators-cache-module'
export let stakeInfo: Promise<LayoutDataStakeInfo>
export let withSummary: boolean
Expand All @@ -21,6 +22,16 @@
values.slice(splitPoint, values.length)
] as const
})
$: {
stakeInfo.then((data) => {
validatorsCacheModule.queryValidators(
Object.values(data.accumulatedStakes).map(
(stake) => stake.validatorAddress
)
)
})
}
</script>

{#if withSummary}
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/routes/(search-pages)/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const getLookupEntity = (
[address],
options || {
dappTwoWayLinks: true,
nativeResourceDetails: true,
nativeResourceDetails: true
},
ledgerState
).andThen((entities) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
<script lang="ts">
import { validatorsCacheModule } from '@api/utils/validators-cache-module'
import type { PageData } from './$types'
import SkeletonLoader from '@components/_base/skeleton-loader/SkeletonLoader.svelte'
import StakedValidatorCard from '@dashboard/lib/staking-card/StakedValidatorCard.svelte'
export let data: PageData
$: {
data.promises.stakeInfo.then((data) => {
validatorsCacheModule.queryValidators(
Object.values(data.accumulatedStakes).map(
(stake) => stake.validatorAddress
)
)
})
}
</script>

<div class="validators">
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/api/utils/entities/resource/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
import { transformNonFungibleResource } from './non-fungible'
import {
createStandardMetadata,
type ExpectedMetadata,
type ExpectedMetadata
} from '@api/utils/metadata'

type ResourceType = 'fungible' | 'non-fungible'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const getEntityDetails = (address: string) =>
callApi('getEntityDetailsVaultAggregated', [address])

export const isClaimNftCollection = (
resourceEntity: StateEntityDetailsVaultResponseItem,
resourceEntity: StateEntityDetailsVaultResponseItem
) => {
return (
resourceEntity.details?.type === 'NonFungibleResource' &&
Expand Down
4 changes: 3 additions & 1 deletion packages/ui/src/api/utils/nfts/claim-nft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export const systemNftData = createSystemNftData({
claim_epoch: 'String'
})

export type ClaimNft = _NonFungible<'claimNft', typeof systemNftData>
export type ClaimNft = _NonFungible<'claimNft', typeof systemNftData> & {
validatorAddress: string
}

export const isUnstakeData = (
data: StateNonFungibleDetailsResponseItem['data']
Expand Down
Loading

0 comments on commit b953b0b

Please sign in to comment.