From ffe3bceffbc169fd7d51181b0f7e69dd72f8407a Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 22 Oct 2024 12:09:52 +0330 Subject: [PATCH] fix: asset requested issue while currency is something other than USD closes #1588 --- .../governance/post/Description.tsx | 27 ++++------ .../fullscreen/governance/post/Metadata.tsx | 10 ++-- .../governance/post/useReferendaRequested.tsx | 52 +++++++++++++++++++ .../src/hooks/useTokenPrice.ts | 33 ++++++++---- .../extension-polkagate/src/util/types.ts | 2 + 5 files changed, 91 insertions(+), 33 deletions(-) create mode 100644 packages/extension-polkagate/src/fullscreen/governance/post/useReferendaRequested.tsx diff --git a/packages/extension-polkagate/src/fullscreen/governance/post/Description.tsx b/packages/extension-polkagate/src/fullscreen/governance/post/Description.tsx index 36ea11249..d3c0fa45b 100644 --- a/packages/extension-polkagate/src/fullscreen/governance/post/Description.tsx +++ b/packages/extension-polkagate/src/fullscreen/governance/post/Description.tsx @@ -15,12 +15,13 @@ import rehypeRaw from 'rehype-raw'; import { BN } from '@polkadot/util'; import { FormatPrice, Identity, ShowBalance, ShowValue } from '../../../components'; -import { useInfo, useTokenPrice, useTranslation } from '../../../hooks'; +import { useInfo, useTranslation } from '../../../hooks'; import useStyles from '../styles/styles'; import { LabelValue } from '../TrackStats'; import { STATUS_COLOR } from '../utils/consts'; import { formalizedStatus, formatRelativeTime, pascalCaseToTitleCase } from '../utils/util'; import { getBeneficiary } from './Metadata'; +import useReferendaRequested from './useReferendaRequested'; interface Props { address: string | undefined; @@ -33,21 +34,11 @@ const DEFAULT_CONTENT = 'This referendum does not have a description provided by export default function ReferendumDescription ({ address, currentTreasuryApprovalList, referendum }: Props): React.ReactElement { const { t } = useTranslation(); const theme = useTheme(); - const { api, chain, decimal, token } = useInfo(address); - const { price } = useTokenPrice(address); const style = useStyles(); - const requestedInUSD = useMemo(() => { - const STABLE_COIN_PRICE = 1; - const _decimal = referendum?.decimal || decimal; - const _price = referendum?.assetId ? STABLE_COIN_PRICE : price; + const { api, chain } = useInfo(address); - if (!referendum?.requested || !_decimal || !_price) { - return undefined; - } - - return (Number(referendum.requested) / 10 ** _decimal) * _price; - }, [decimal, price, referendum]); + const { rAssetInCurrency, rCurrencySign, rDecimal, rToken } = useReferendaRequested(address, referendum); const [expanded, setExpanded] = useState(false); @@ -136,9 +127,9 @@ export default function ReferendumDescription ({ address, currentTreasuryApprova value={ } valueStyle={{ fontSize: 16, fontWeight: 500, pl: '5px' }} @@ -148,8 +139,8 @@ export default function ReferendumDescription ({ address, currentTreasuryApprova @@ -157,7 +148,7 @@ export default function ReferendumDescription ({ address, currentTreasuryApprova } - + {pascalCaseToTitleCase(formalizedStatus(referendum?.status))} diff --git a/packages/extension-polkagate/src/fullscreen/governance/post/Metadata.tsx b/packages/extension-polkagate/src/fullscreen/governance/post/Metadata.tsx index d52e23195..9beb279c8 100644 --- a/packages/extension-polkagate/src/fullscreen/governance/post/Metadata.tsx +++ b/packages/extension-polkagate/src/fullscreen/governance/post/Metadata.tsx @@ -1,7 +1,6 @@ // Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors // SPDX-License-Identifier: Apache-2.0 -// @ts-nocheck /* eslint-disable react/jsx-max-props-per-line */ import type { Chain } from '@polkadot/extension-chains/types'; @@ -22,8 +21,9 @@ import { isValidAddress } from '../../../util/utils'; import useStyles from '../styles/styles'; import { LabelValue } from '../TrackStats'; import { pascalCaseToTitleCase } from '../utils/util'; +import useReferendaRequested from './useReferendaRequested'; -export function hexAddressToFormatted(hexString: string, chain: Chain | null | undefined): string | undefined { +export function hexAddressToFormatted (hexString: string, chain: Chain | null | undefined): string | undefined { try { if (!chain || !hexString) { return undefined; @@ -75,6 +75,8 @@ export default function Metadata ({ address, decisionDepositPayer, referendum }: const { api, chain, chainName, decimal, token } = useInfo(address); const style = useStyles(); + const { rDecimal, rToken } = useReferendaRequested(address, referendum); + const [expanded, setExpanded] = React.useState(false); const [showJson, setShowJson] = React.useState(false); @@ -181,9 +183,9 @@ export default function Metadata ({ address, decisionDepositPayer, referendum }: style={{ justifyContent: 'flex-start' }} value={} valueStyle={{ fontSize: 16, fontWeight: 500 }} /> diff --git a/packages/extension-polkagate/src/fullscreen/governance/post/useReferendaRequested.tsx b/packages/extension-polkagate/src/fullscreen/governance/post/useReferendaRequested.tsx new file mode 100644 index 000000000..14bd7147d --- /dev/null +++ b/packages/extension-polkagate/src/fullscreen/governance/post/useReferendaRequested.tsx @@ -0,0 +1,52 @@ +// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Referendum } from '../utils/types'; + +import { useMemo } from 'react'; + +import { useCurrency, useInfo, useTokenPrice } from '../../../hooks'; + +interface ReferendaRequested{ + rAssetInCurrency: number, + rCurrencySign: string, + rDecimal: number, + rToken: string +} + +const DEFAULT_OUTPUT = { + rAssetInCurrency: undefined, + rCurrencySign: undefined, + rDecimal: undefined, + rToken: undefined +}; + +export default function useReferendaRequested (address: string | undefined, referendum: Referendum | undefined): ReferendaRequested | typeof DEFAULT_OUTPUT { + const { chainName, decimal, token } = useInfo(address); + const currency = useCurrency(); + + const maybeAssetIdInNumber = referendum?.assetId ? Number(referendum.assetId) : undefined; + const maybeAssetHubs = referendum?.assetId + ? chainName?.includes('Polkadot') + ? 'polkadot asset hub' + : 'kusama asset hub' + : undefined; + const priceInfo = useTokenPrice(address, maybeAssetIdInNumber, maybeAssetHubs); + const _decimal = priceInfo?.decimal || referendum?.decimal || decimal; + const _token = priceInfo?.token || referendum?.token || token; + + return useMemo(() => { + if (!referendum?.requested || !currency || !_decimal || !_token || !priceInfo.price || !priceInfo.decimal) { + return DEFAULT_OUTPUT; + } + + const requestedAssetInCurrency = (Number(referendum.requested) / 10 ** priceInfo.decimal) * priceInfo.price; + + return { + rAssetInCurrency: requestedAssetInCurrency, + rCurrencySign: currency.sign, + rDecimal: _decimal, + rToken: _token + }; + }, [_decimal, _token, currency, priceInfo, referendum?.requested]); +} diff --git a/packages/extension-polkagate/src/hooks/useTokenPrice.ts b/packages/extension-polkagate/src/hooks/useTokenPrice.ts index 5a7c4444a..fe3e57164 100644 --- a/packages/extension-polkagate/src/hooks/useTokenPrice.ts +++ b/packages/extension-polkagate/src/hooks/useTokenPrice.ts @@ -13,9 +13,11 @@ import { getPriceIdByChainName } from '../util/utils'; import { useInfo, usePrices } from '.'; const DEFAULT_PRICE = { + decimal: undefined, price: undefined, priceChainName: undefined, - priceDate: undefined + priceDate: undefined, + token: undefined }; const assetsChains = createAssets(); @@ -23,13 +25,16 @@ const assetsChains = createAssets(); /** * @description retrieve the price of a token from local storage PRICES * @param address : accounts substrate address + * @param assetId : asset id on multi asset chains + * @param assetChainName : chain name to fetch asset id price from * @returns price : price of the token which the address is already switched to */ -export default function useTokenPrice (address: string | undefined, assetId?: number | string): Price | typeof DEFAULT_PRICE { - const { chainName, genesisHash } = useInfo(address); +export default function useTokenPrice (address: string | undefined, assetId?: number | string, assetChainName?: string): Price | typeof DEFAULT_PRICE { + const { chainName: addressChainName, decimal, genesisHash, token } = useInfo(address); const userAddedPriceId = useUserAddedPriceId(genesisHash); const pricesInCurrencies = usePrices(); - const maybeAssetsOnMultiAssetChains = assetsChains[toCamelCase(chainName || '')]; + const _chainName = assetChainName || addressChainName; + const maybeAssetsOnMultiAssetChains = assetsChains[toCamelCase(_chainName || '')]; const isAssetHub = ASSET_HUBS.includes(genesisHash || ''); @@ -42,21 +47,27 @@ export default function useTokenPrice (address: string | undefined, assetId?: nu , [assetId, isAssetHub]); return useMemo(() => { - if (!chainName || !pricesInCurrencies) { + if (!_chainName || !pricesInCurrencies || !token || !decimal) { return DEFAULT_PRICE; } // FixMe, on second fetch of asset id its type will get string which is weird!! - const priceId = _assetId !== undefined && ((typeof _assetId === 'number' && _assetId > NATIVE_TOKEN_ASSET_ID) || isAssetHub) - ? maybeAssetsOnMultiAssetChains?.find(({ id }) => id === Number(_assetId) || id === _assetId)?.priceId - : userAddedPriceId || getPriceIdByChainName(chainName); + const maybeAssetInfo = _assetId !== undefined && ((typeof _assetId === 'number' && _assetId > NATIVE_TOKEN_ASSET_ID) || isAssetHub) + ? maybeAssetsOnMultiAssetChains?.find(({ id }) => id === Number(_assetId) || id === _assetId) + : undefined; + + const priceId = maybeAssetInfo?.priceId || userAddedPriceId || getPriceIdByChainName(_chainName); const maybePriceValue = priceId ? pricesInCurrencies.prices?.[priceId]?.value || 0 : 0; + const _decimal = maybeAssetInfo?.decimal || decimal; + const _token = maybeAssetInfo?.symbol || token; return { + decimal: _decimal, price: maybePriceValue, - priceChainName: chainName?.toLocaleLowerCase(), - priceDate: pricesInCurrencies.date + priceChainName: _chainName?.toLocaleLowerCase(), + priceDate: pricesInCurrencies.date, + token: _token }; - }, [_assetId, chainName, isAssetHub, maybeAssetsOnMultiAssetChains, pricesInCurrencies, userAddedPriceId]); + }, [_assetId, _chainName, decimal, isAssetHub, maybeAssetsOnMultiAssetChains, pricesInCurrencies, token, userAddedPriceId]); } diff --git a/packages/extension-polkagate/src/util/types.ts b/packages/extension-polkagate/src/util/types.ts index dc59d61a5..699551ae7 100644 --- a/packages/extension-polkagate/src/util/types.ts +++ b/packages/extension-polkagate/src/util/types.ts @@ -614,6 +614,8 @@ export interface PricesInCurrencies { export interface Price { price: number; + decimal: number; + token: string; priceChainName: string; priceDate: number; }