Skip to content

Commit

Permalink
fix: asset requested issue while currency is something other than USD
Browse files Browse the repository at this point in the history
closes #1588
  • Loading branch information
Nick-1979 committed Oct 22, 2024
1 parent b2ca99d commit ffe3bce
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<boolean>(false);

Expand Down Expand Up @@ -136,9 +127,9 @@ export default function ReferendumDescription ({ address, currentTreasuryApprova
value={
<ShowBalance
balance={new BN(referendum.requested)}
decimal={referendum?.decimal || decimal}
decimal={rDecimal}
decimalPoint={2}
token={referendum?.token || token}
token={rToken}
/>
}
valueStyle={{ fontSize: 16, fontWeight: 500, pl: '5px' }}
Expand All @@ -148,16 +139,16 @@ export default function ReferendumDescription ({ address, currentTreasuryApprova
<Grid item sx={{ opacity: theme.palette.mode === 'dark' ? 0.6 : 1 }}>
<FormatPrice
decimalPoint={2}
num={requestedInUSD || 0}
sign='$'
num={rAssetInCurrency || 0}
sign={rCurrencySign}
textColor={ theme.palette.mode === 'light' ? 'text.disabled' : undefined}
/>
</Grid>
</Grid>
</>
}
</Grid>
<Grid item sx={{ bgcolor: referendum?.status ? STATUS_COLOR[referendum.status] : undefined , border: '0.01px solid primary.main', borderRadius: '30px', color: 'white', fontSize: '16px', fontWeight: 400, lineHeight: '24px', mb: '5px', px: '10px', textAlign: 'center', width: 'fit-content' }}>
<Grid item sx={{ bgcolor: referendum?.status ? STATUS_COLOR[referendum.status] : undefined, border: '0.01px solid primary.main', borderRadius: '30px', color: 'white', fontSize: '16px', fontWeight: 400, lineHeight: '24px', mb: '5px', px: '10px', textAlign: 'center', width: 'fit-content' }}>
{pascalCaseToTitleCase(formalizedStatus(referendum?.status))}
</Grid>
</Grid>
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -181,9 +183,9 @@ export default function Metadata ({ address, decisionDepositPayer, referendum }:
style={{ justifyContent: 'flex-start' }}
value={<ShowBalance
balance={referendum?.call?.args?.['amount'] as string || referendum?.requested}
decimal={referendum?.decimal || decimal}
decimal={rDecimal}
decimalPoint={2}
token={referendum?.token || token}
token={rToken}
/>}
valueStyle={{ fontSize: 16, fontWeight: 500 }}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -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]);
}
33 changes: 22 additions & 11 deletions packages/extension-polkagate/src/hooks/useTokenPrice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,28 @@ 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();

/**
* @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 || '');

Expand All @@ -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]);
}
2 changes: 2 additions & 0 deletions packages/extension-polkagate/src/util/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,8 @@ export interface PricesInCurrencies {

export interface Price {
price: number;
decimal: number;
token: string;
priceChainName: string;
priceDate: number;
}
Expand Down

0 comments on commit ffe3bce

Please sign in to comment.