chore(deposits): formatting tweaks (#4648)

Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
This commit is contained in:
Art 2023-08-31 15:30:03 +02:00 committed by GitHub
parent 50959b4c50
commit de4c7926c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 147 additions and 23 deletions

View File

@ -133,11 +133,7 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
validateMarketDataRow(4, 'Decimals', '5');
validateMarketDataRow(5, 'Quantum', '1');
validateMarketDataRow(6, 'Status', 'Enabled');
validateMarketDataRow(
7,
'Contract address',
'0x0158031158Bb4dF2AD02eAA31e8963E84EA978a4'
);
validateMarketDataRow(7, 'Contract address', '0x0158…78a4');
validateMarketDataRow(8, 'Withdrawal threshold', '0.0005');
validateMarketDataRow(9, 'Lifetime limit', '1,230');
validateMarketDataRow(10, 'Infrastructure fee account balance', '0.00001');

View File

@ -43,11 +43,10 @@ describe('ethereum wallet', { tags: '@smoke', testIsolation: true }, () => {
// 0004-EWAL-005
// 0004-EWAL-006
const ethWalletAddress = Cypress.env('ETHEREUM_WALLET_ADDRESS');
cy.getByTestId('Deposits').click();
cy.getByTestId('deposit-button').click();
connectEthereumWallet('MetaMask');
cy.getByTestId('ethereum-address').should('have.text', ethWalletAddress);
cy.getByTestId('ethereum-address').should('have.text', '0xEe7D…d94F');
cy.getByTestId('disconnect-ethereum-wallet')
.should('have.text', 'Disconnect')
.click();

View File

@ -97,7 +97,7 @@ export const AssetDetailsDialog = ({
}}
>
{content}
<p className="text-sm my-4">
<p className="text-xs my-4">
{t(
'There is 1 unit of the settlement asset (%s) to every 1 quote unit.',
[assetSymbol]

View File

@ -3,7 +3,11 @@ import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type * as Schema from '@vegaprotocol/types';
import type { KeyValueTableRowProps } from '@vegaprotocol/ui-toolkit';
import { CopyWithTooltip, Icon } from '@vegaprotocol/ui-toolkit';
import {
CopyWithTooltip,
Icon,
truncateMiddle,
} from '@vegaprotocol/ui-toolkit';
import {
KeyValueTable,
KeyValueTableRow,
@ -56,7 +60,7 @@ export const rows: Rows = [
key: AssetDetail.ID,
label: t('ID'),
tooltip: '',
value: (asset) => asset.id,
value: (asset) => truncateMiddle(asset.id),
},
{
key: AssetDetail.TYPE,
@ -109,7 +113,9 @@ export const rows: Rows = [
return (
<>
<EtherscanLink address={asset.source.contractAddress} />{' '}
<EtherscanLink address={asset.source.contractAddress}>
{truncateMiddle(asset.source.contractAddress)}
</EtherscanLink>{' '}
<CopyWithTooltip text={asset.source.contractAddress}>
<button title={t('Copy address to clipboard')}>
<Icon size={3} name="duplicate" />

View File

@ -1,4 +1,4 @@
import { TradingOption } from '@vegaprotocol/ui-toolkit';
import { TradingOption, truncateMiddle } from '@vegaprotocol/ui-toolkit';
import type { AssetFieldsFragment } from './__generated__/Asset';
import classNames from 'classnames';
import { t } from '@vegaprotocol/i18n';
@ -45,7 +45,7 @@ export const AssetOption = ({ asset, balance }: AssetOptionProps) => {
{balance}
<div className="text-[12px] font-mono w-full text-left break-all">
<span className="text-vega-light-300 dark:text-vega-dark-300">
{asset.id}
{truncateMiddle(asset.id)}
</span>
</div>
</div>

View File

@ -2,7 +2,11 @@ import type { Asset } from '@vegaprotocol/assets';
import { EtherscanLink } from '@vegaprotocol/environment';
import { t } from '@vegaprotocol/i18n';
import { Intent, Notification } from '@vegaprotocol/ui-toolkit';
import { formatNumber } from '@vegaprotocol/utils';
import {
formatNumber,
getUnlimitedThreshold,
quantumDecimalPlaces,
} from '@vegaprotocol/utils';
import type { EthStoredTxState } from '@vegaprotocol/web3';
import { EthTxStatus, useEthTransactionStore } from '@vegaprotocol/web3';
import BigNumber from 'bignumber.js';
@ -188,6 +192,15 @@ const ApprovalTxFeedback = ({
}
if (tx.status === EthTxStatus.Confirmed) {
const approvedAllowanceValue = (
allowance || new BigNumber(0)
).isGreaterThan(getUnlimitedThreshold(selectedAsset.decimals))
? '∞'
: formatNumber(
allowance?.toString() || 0,
quantumDecimalPlaces(selectedAsset.quantum, selectedAsset.decimals)
);
return (
<div className="mb-4">
<Notification
@ -198,7 +211,7 @@ const ApprovalTxFeedback = ({
<p>
{t('You approved deposits of up to %s %s.', [
selectedAsset?.symbol,
formatNumber(allowance?.toString() || 0),
approvedAllowanceValue,
])}
</p>
{txLink && <p>{txLink}</p>}

View File

@ -15,6 +15,7 @@ import { useWeb3ConnectStore } from '@vegaprotocol/web3';
import { useWeb3React } from '@web3-react/core';
import type { AssetFieldsFragment } from '@vegaprotocol/assets';
import type { DepositBalances } from './use-deposit-balances';
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
jest.mock('@vegaprotocol/wallet');
jest.mock('@vegaprotocol/web3');
@ -90,7 +91,7 @@ describe('Deposit form', () => {
// Assert default values (including) from/to provided by useVegaWallet and useWeb3React
expect(screen.getByText('From (Ethereum address)')).toBeInTheDocument();
expect(screen.getByTestId('ethereum-address')).toHaveTextContent(
MOCK_ETH_ADDRESS
truncateMiddle(MOCK_ETH_ADDRESS)
);
expect(screen.getByLabelText('Asset')).toHaveValue('');
expect(screen.getByLabelText('To (Vega key)')).toHaveValue('');
@ -353,7 +354,7 @@ describe('Deposit form', () => {
).not.toBeInTheDocument();
expect(screen.getByText('From (Ethereum address)')).toBeInTheDocument();
expect(screen.getByTestId('ethereum-address')).toHaveTextContent(
MOCK_ETH_ADDRESS
truncateMiddle(MOCK_ETH_ADDRESS)
);
});

View File

@ -22,6 +22,7 @@ import {
Intent,
ButtonLink,
TradingSelect,
truncateMiddle,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useWeb3React } from '@web3-react/core';
@ -173,7 +174,7 @@ export const DepositForm = ({
return (
<div className="text-sm" aria-describedby="ethereum-address">
<p className="mb-1 break-all" data-testid="ethereum-address">
{account}
{truncateMiddle(account)}
</p>
<DisconnectEthereumButton
onDisconnect={() => {

View File

@ -7,7 +7,7 @@ import {
Tooltip,
} from '@vegaprotocol/ui-toolkit';
import type BigNumber from 'bignumber.js';
import { formatNumber } from '@vegaprotocol/utils';
import { formatNumber, quantumDecimalPlaces } from '@vegaprotocol/utils';
// Note: all of the values here are with correct asset's decimals
// See `libs/deposits/src/lib/use-deposit-balances.ts`
@ -35,7 +35,10 @@ export const DepositLimits = ({
label: t('Balance available'),
rawValue: balance,
value: balance ? (
<CompactNumber number={balance} decimals={asset.decimals} />
<CompactNumber
number={balance}
decimals={quantumDecimalPlaces(asset.quantum, asset.decimals)}
/>
) : (
'-'
),
@ -73,7 +76,7 @@ export const DepositLimits = ({
value: !exempt ? (
<CompactNumber
number={max.minus(deposited)}
decimals={asset.decimals}
decimals={quantumDecimalPlaces(asset.quantum, asset.decimals)}
/>
) : (
<div data-testid="exempt">{t('Exempt')}</div>
@ -97,7 +100,10 @@ export const DepositLimits = ({
),
rawValue: allowance,
value: allowance ? (
<CompactNumber number={allowance} decimals={asset.decimals} />
<CompactNumber
number={allowance}
decimals={quantumDecimalPlaces(asset.quantum, asset.decimals)}
/>
) : (
'-'
),

View File

@ -1,9 +1,14 @@
import { BigNumber } from 'bignumber.js';
import { getUserLocale, formatNumber } from '@vegaprotocol/utils';
import {
getUserLocale,
formatNumber,
getUnlimitedThreshold,
} from '@vegaprotocol/utils';
const INFINITY = '∞';
const DEFAULT_COMPACT_ABOVE = 1_000_000;
const DEFAULT_COMPACT_CAP = new BigNumber(1e24);
/**
* Compacts given number to human readable format.
* @param number
@ -35,6 +40,10 @@ export const CompactNumber = ({
const decimalPlaces =
(decimals === 'infer' ? number.decimalPlaces() : decimals) || 0;
if (number.isGreaterThan(getUnlimitedThreshold(decimalPlaces))) {
return <span data-testid={testId}>{INFINITY}</span>;
}
if (number.isLessThan(DEFAULT_COMPACT_ABOVE)) {
return (
<span data-testid={testId}>{formatNumber(number, decimalPlaces)}</span>

View File

@ -5,7 +5,9 @@ import {
addDecimalsFormatNumberQuantum,
formatNumber,
formatNumberPercentage,
getUnlimitedThreshold,
isNumeric,
quantumDecimalPlaces,
toDecimal,
toNumberParts,
} from './number';
@ -156,3 +158,63 @@ describe('number utils', () => {
});
});
});
describe('quantumDecimalPlaces', () => {
it.each([
['1', 1, 3],
['10', 1, 2],
['100', 1, 1],
['1000', 1, 0],
['1', 2, 4],
['10', 2, 3],
['100', 2, 2],
['1000', 2, 1],
['1', 3, 5],
['10', 3, 4],
['100', 3, 3],
['1000', 3, 2],
['1', 18, 20],
['1000000000', 18, 11],
['5000000000', 18, 11],
['1000000000000000000', 18, 2],
])(
'converts quantum %s of %d decimal places to %d quant. decimal places',
(quantum, decimals, output) => {
expect(quantumDecimalPlaces(quantum, decimals)).toEqual(output);
}
);
});
describe('getUnlimitedThreshold', () => {
it.each([
[
0,
'9.26336713898529563388567880069503262826159877325124512315660672063305037119488e+76',
],
[
1,
'9.26336713898529563388567880069503262826159877325124512315660672063305037119488e+75',
],
[
2,
'9.26336713898529563388567880069503262826159877325124512315660672063305037119488e+74',
],
[
3,
'9.26336713898529563388567880069503262826159877325124512315660672063305037119488e+73',
],
[
10,
'9.26336713898529563388567880069503262826159877325124512315660672063305037119488e+66',
],
[
18,
'9.26336713898529563388567880069503262826159877325124512315660672063305037119488e+58',
],
])(
'given %d decimal places it returns unlimited threshold %s',
(decimals, output) => {
expect(getUnlimitedThreshold(decimals).toString()).toEqual(output);
}
);
});

View File

@ -4,6 +4,18 @@ import memoize from 'lodash/memoize';
import { getUserLocale } from '../get-user-locale';
/**
* A raw unformatted value greater than this is considered and displayed
* as UNLIMITED.
*/
export const UNLIMITED_THRESHOLD = new BigNumber(2).pow(256).times(0.8);
/**
* Gets the unlimited threshold value for given decimal places.
* @param decimalPlaces the asset's decimal places
*/
export const getUnlimitedThreshold = (decimalPlaces: number) =>
UNLIMITED_THRESHOLD.dividedBy(Math.pow(10, decimalPlaces));
const MIN_FRACTION_DIGITS = 2;
const MAX_FRACTION_DIGITS = 20;
@ -90,6 +102,25 @@ export const formatNumberFixed = (
return getFixedNumberFormat(formatDecimals).format(Number(rawValue));
};
export const quantumDecimalPlaces = (
/** Raw asset's quantum value */
rawQuantum: number | string,
/** Asset's decimal places */
decimalPlaces: number
) => {
// if raw quantum value is an empty string then it'll evaluate to 0
// this check ignores NaNs and zeroes
const formatDecimals =
isNaN(Number(rawQuantum)) || Number(rawQuantum) === 0
? decimalPlaces
: Math.max(
0,
Math.log10(100 / Number(addDecimal(rawQuantum, decimalPlaces)))
);
return Math.ceil(formatDecimals);
};
export const addDecimalsFormatNumberQuantum = (
rawValue: string | number,
decimalPlaces: number,