Skip to content

Commit

Permalink
fix: dont use sapi for displaying balances (#1744)
Browse files Browse the repository at this point in the history
* feat: subtensor staking hotkeys in balances

* feat: read subtensor validator from balance meta

* fix: layout shift and positioning of shimmer

* chore: changeset

* chore: yeet

* feat: distinct balance values for each hotkey

* fix: unbond buttons read hotkey from meta

* feat: change hook to read stake by hotkey from balance instead of chain

* fix: isEnabled

* fix: isEnabled

* feat: read hotkey from balance
  • Loading branch information
0xKheops authored Dec 12, 2024
1 parent fd7f109 commit 998e610
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 329 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-crabs-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/balances": minor
---

subtensor hotkey in balance meta
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,18 @@ const AssetState = ({
<div className="shrink-0 whitespace-nowrap font-bold text-white">{title}</div>
{/* show description next to title when address is set */}
{description && address && <div className="grow truncate text-sm">{description}</div>}
{!description && address && isLoading && (
<div className="bg-grey-800 rounded-xs h-[1.4rem] w-60 animate-pulse" />
)}
</div>
{address && (
<div className="text-sm">
<PortfolioAccount address={address} />
</div>
)}
{/* show description below title when address is not set */}
{isLoading && !description && locked && (
<div className="bg-grey-700 rounded-xs h-[1.6rem] w-80 animate-pulse" />
{isLoading && !description && !address && locked && (
<div className="bg-grey-800 rounded-xs h-[1.6rem] w-60 animate-pulse" />
)}
{description && !address && (
<div className="flex-shrink-0 truncate text-sm">{description}</div>
Expand Down Expand Up @@ -297,7 +300,7 @@ const LockedExtra: FC<{
tokenId: TokenId
address?: string // this is only set when browsing all accounts
isLoading: boolean
rowMeta: { poolId?: number; unbonding?: boolean }
rowMeta: { poolId?: number; unbonding?: boolean; hotkey?: string }
}> = ({ tokenId, address, rowMeta, isLoading }) => {
const { t } = useTranslation()
const { data } = useNomPoolStakingStatus(tokenId)
Expand Down Expand Up @@ -348,7 +351,7 @@ const LockedExtra: FC<{
tokenId={tokenId}
address={rowAddress}
variant="large"
poolId={rowMeta.poolId}
poolId={rowMeta.poolId ?? rowMeta.hotkey}
/>
) : null}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ const ChainTokenBalancesDetailRow = ({
<PortfolioAccount address={row.address} />
</div>
)}
{row.isLoading && !row.description && row.locked && (
<div className="bg-grey-700 rounded-xs h-[1.6rem] max-w-48 animate-pulse" />
{!row.address && row.isLoading && !row.description && row.locked && (
<div className="bg-grey-800 rounded-xs h-[1.4rem] max-w-48 animate-pulse" />
)}
{!row.address && row.description && (
<div className="overflow-hidden text-ellipsis whitespace-nowrap text-xs">
Expand Down Expand Up @@ -258,7 +258,7 @@ const LockedExtra: FC<{
tokenId: TokenId
address?: string // this is only set when browsing all accounts
isLoading: boolean
rowMeta: { poolId?: number; unbonding?: boolean }
rowMeta: { poolId?: number; unbonding?: boolean; hotkey?: string }
}> = ({ tokenId, address, rowMeta, isLoading }) => {
const { t } = useTranslation()
const { data } = useNomPoolStakingStatus(tokenId)
Expand Down Expand Up @@ -313,7 +313,7 @@ const LockedExtra: FC<{
tokenId={tokenId}
address={rowAddress}
variant="small"
poolId={rowMeta.poolId}
poolId={rowMeta.poolId ?? rowMeta.hotkey}
/>
) : null}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useTranslation } from "react-i18next"
import { Address, Balances } from "@extension/core"
import { sortBigBy } from "@talisman/util/bigHelper"
import { cleanupNomPoolName } from "@ui/domains/Staking/helpers"
import { useCombineBittensorStakeInfo } from "@ui/domains/Staking/hooks/bittensor/useCombineBittensorStakeInfo"
import { useGetBittensorValidators } from "@ui/domains/Staking/hooks/bittensor/useGetBittensorValidator"
import { useBalancesStatus } from "@ui/hooks/useBalancesStatus"
import { useNetworkCategory } from "@ui/hooks/useNetworkCategory"
import { useChain, useSelectedCurrency } from "@ui/state"
Expand All @@ -33,20 +33,14 @@ type ChainTokenBalancesParams = {
}

export const useChainTokenBalances = ({ chainId, balances }: ChainTokenBalancesParams) => {
const { t } = useTranslation()
const currency = useSelectedCurrency()
const chain = useChain(chainId)

const { selectedAccount: account } = usePortfolioNavigation()
const { summary, tokenBalances, token } = useTokenBalancesSummary(balances)
const { t } = useTranslation()

const currency = useSelectedCurrency()

const { combinedStakeInfo: subtensor } = useCombineBittensorStakeInfo({
address: account?.address,
balances: balances,
})

const detailRows = useMemo((): DetailRow[] => {
const rawDetailRows = useMemo((): DetailRow[] => {
if (!summary) return []

// AVAILABLE
Expand Down Expand Up @@ -130,10 +124,28 @@ export const useChainTokenBalances = ({ chainId, balances }: ChainTokenBalancesP
})),
)

// BITTENSOR
const subtensor = tokenBalances.each.flatMap((b) =>
b.subtensor.map((subtensor, index) => ({
key: `${b.id}-subtensor-${index}`,
title: getLockTitle({ label: "subtensor-staking" }),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
description: (subtensor.meta as any)?.description ?? undefined,
tokens: BigNumber(subtensor.amount.tokens),
fiat: subtensor.amount.fiat(currency),
locked: true,
// only show address when we're viewing balances for all accounts
address: account ? undefined : b.address,
meta: subtensor.meta,
})),
)

return [...available, ...locked, ...reserved, ...staked, ...crowdloans, ...subtensor]
.filter((row) => row && row.tokens.gt(0))
.sort(sortBigBy("tokens", true))
}, [summary, account, t, tokenBalances.each, subtensor, currency])
}, [summary, account, t, tokenBalances, currency])

const detailRows = useEnhanceDetailRows(rawDetailRows)

const { evmNetwork } = balances.sorted[0]
const relay = useChain(chain?.relay?.id)
Expand All @@ -153,3 +165,30 @@ export const useChainTokenBalances = ({ chainId, balances }: ChainTokenBalancesP
chainOrNetwork: chain || evmNetwork,
}
}

const useEnhanceDetailRows = (detailRows: DetailRow[]) => {
// fetch the validator name for each subtensor staking lock, so we can display it in the description
const hotkeys = useMemo(() => {
return detailRows
.filter((row) => row.meta?.type === "subtensor-staking" && !!row.meta?.hotkey)
.map((row) => row.meta?.hotkey as string)
}, [detailRows])

const { data: validators, isLoading: isLoadingValidators } = useGetBittensorValidators({
hotkeys,
isEnabled: !!hotkeys.length,
})

return useMemo(() => {
return detailRows.map((row) => {
if (row.meta?.type === "subtensor-staking")
return {
...row,
description: validators?.find((v) => v?.hotkey.ss58 === row.meta.hotkey)?.name,
isLoading: isLoadingValidators,
} as DetailRow

return row
})
}, [detailRows, isLoadingValidators, validators])
}
37 changes: 16 additions & 21 deletions apps/extension/src/ui/domains/Staking/Bond/useBondButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { MouseEventHandler, useCallback, useMemo } from "react"
import { useAnalytics } from "@ui/hooks/useAnalytics"
import { useAccounts, useRemoteConfig, useToken } from "@ui/state"

import { useGetBittensorStakeHotkeys } from "../hooks/bittensor/useGetBittensorStakeHotkeys"
import { useBondModal } from "./useBondModal"

export const useBondButton = ({
Expand Down Expand Up @@ -38,15 +37,11 @@ export const useBondButton = ({

const address = sorted[0]?.address

const { data: hotkeys } = useGetBittensorStakeHotkeys({ chainId: token?.chain?.id, address })

const [openArgs, isNomPoolStaking] = useMemo<[Parameters<typeof open>[0] | null, boolean]>(() => {
if (!balances || !tokenId || !token?.chain || token?.type !== "substrate-native")
return [null, false]
try {
let isNomPoolStaking = false

let poolId =
const poolId =
remoteConfig.stakingPools[token.chain.id]?.[0] ||
remoteConfig.nominationPools[token.chain.id]?.[0]

Expand All @@ -57,32 +52,32 @@ export const useBondButton = ({

// lookup existing poolId for that account
for (const balance of sorted.filter((b) => b.address === address)) {
type Meta = { poolId?: number }
let pool
let meta
switch (token.chain.id) {
case "bittensor":
poolId = hotkeys?.[0] ?? poolId
case "bittensor": {
type SubtensorMeta = { hotkeys?: string[] }
const entry = balance.subtensor.find((b) => !!(b.meta as SubtensorMeta).hotkeys?.length)
const meta = entry?.meta as SubtensorMeta | undefined
if (meta?.hotkeys?.[0]) return [{ tokenId, address, poolId: meta?.hotkeys[0] }, false]
break
default:
pool = balance.nompools.find((np) => !!(np.meta as Meta).poolId)
meta = pool?.meta as Meta | undefined
if (meta?.poolId) {
poolId = meta.poolId
isNomPoolStaking = true
break
}
}
default: {
// assume nomination pool staking, but there will be more in the future
type NomPoolMeta = { poolId?: number }
const entry = balance.nompools.find((b) => !!(b.meta as NomPoolMeta).poolId)
const meta = entry?.meta as NomPoolMeta | undefined
if (meta?.poolId) return [{ tokenId, address, poolId: meta.poolId }, true]
break
}
}
}

return [{ tokenId, address, poolId }, isNomPoolStaking]
return [{ tokenId, address, poolId }, false]
} catch (err) {
log.error("Failed to compute staking modal open args", err)
}

return [null, false]
}, [balances, remoteConfig, tokenId, token?.chain, token?.type, hotkeys, address, sorted])
}, [balances, remoteConfig, tokenId, token?.chain, token?.type, address, sorted])

const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(
(e) => {
Expand Down

This file was deleted.

Loading

0 comments on commit 998e610

Please sign in to comment.