Compare commits

...
18 changed files with 350 additions and 108 deletions
@@ -8,6 +8,7 @@ import { ENV } from '../../config';
import noIcon from '../../images/token-no-icon.png';
import vegaBlack from '../../images/vega_black.png';
import vegaVesting from '../../images/vega_vesting.png';
import { BigNumber } from '../../lib/bignumber';
import type { WalletCardAssetProps } from '../wallet-card';
import { useVegaWallet } from '@vegaprotocol/wallet';
@@ -102,7 +103,10 @@ export const usePollForDelegations = () => {
setAccounts(
accounts
.filter(
(a) => a.type === Schema.AccountType.ACCOUNT_TYPE_GENERAL
(a) =>
a.type === Schema.AccountType.ACCOUNT_TYPE_GENERAL ||
a.type === Schema.AccountType.ACCOUNT_TYPE_VESTED_REWARDS ||
a.type === Schema.AccountType.ACCOUNT_TYPE_VESTING_REWARDS
)
.map((a) => {
const isVega =
@@ -115,14 +119,23 @@ export const usePollForDelegations = () => {
subheading: isVega ? t('collateral') : a.asset.symbol,
symbol: a.asset.symbol,
decimals: a.asset.decimals,
assetId: a.asset.id,
balance: new BigNumber(
addDecimal(a.balance, a.asset.decimals)
),
image: isVega ? vegaBlack : noIcon,
image: isVega
? vegaBlack
: a.type ===
Schema.AccountType.ACCOUNT_TYPE_VESTED_REWARDS ||
a.type ===
Schema.AccountType.ACCOUNT_TYPE_VESTING_REWARDS
? vegaVesting
: noIcon,
border: isVega,
address: isAssetTypeERC20(a.asset)
? a.asset.source.contractAddress
: undefined,
type: a.type,
};
})
.sort((a, b) => {
@@ -1,9 +1,18 @@
import React from 'react';
import React, { useMemo } from 'react';
import { Link } from 'react-router-dom';
import { useAnimateValue } from '../../hooks/use-animate-value';
import type { BigNumber } from '../../lib/bignumber';
import { useNumberParts } from '@vegaprotocol/react-helpers';
import * as Schema from '@vegaprotocol/types';
import { useTranslation } from 'react-i18next';
import { AnchorButton, Tooltip } from '@vegaprotocol/ui-toolkit';
import {
CONSOLE_TRANSFER_ASSET,
DApp,
useLinks,
} from '@vegaprotocol/environment';
import { useNetworkParam } from '@vegaprotocol/network-parameters';
interface WalletCardProps {
children: React.ReactNode;
@@ -100,8 +109,10 @@ export interface WalletCardAssetProps {
symbol: string;
balance: BigNumber;
decimals: number;
assetId?: string;
border?: boolean;
subheading?: string;
type?: Schema.AccountType;
}
export const WalletCardAsset = ({
@@ -110,16 +121,37 @@ export const WalletCardAsset = ({
symbol,
balance,
decimals,
assetId,
border,
subheading,
type,
}: WalletCardAssetProps) => {
const [integers, decimalsPlaces, separator] = useNumberParts(
balance,
decimals
);
const { t } = useTranslation();
const consoleLink = useLinks(DApp.Console);
const transferAssetLink = (assetId: string) =>
consoleLink(CONSOLE_TRANSFER_ASSET.replace(':assetId', assetId));
const { param: baseRate } = useNetworkParam('rewards_vesting_baseRate');
const isRedeemable =
type === Schema.AccountType.ACCOUNT_TYPE_VESTED_REWARDS && assetId;
const accountTypeTooltip = useMemo(() => {
if (type === Schema.AccountType.ACCOUNT_TYPE_VESTED_REWARDS) {
return t('VestedRewardsTooltip');
}
if (type === Schema.AccountType.ACCOUNT_TYPE_VESTING_REWARDS && baseRate) {
return t('VestingRewardsTooltip', { baseRate });
}
return null;
}, [baseRate, t, type]);
return (
<div className="flex flex-nowrap mt-2 mb-4">
<div className="flex flex-nowrap gap-2 mt-2 mb-4">
<img
alt="Vega"
src={image}
@@ -129,15 +161,37 @@ export const WalletCardAsset = ({
/>
<div>
<div
className="flex align-center text-base"
className="flex align-center items-baseline text-base gap-2"
data-testid="currency-title"
>
<div className="mb-0 px-2 uppercase">{name}</div>
<div className="mb-0 uppercase">{name}</div>
<div className="mb-0 uppercase text-neutral-400">
{subheading || symbol}
</div>
</div>
<div className="px-2 basis-full font-mono" data-testid="currency-value">
{type ? (
<div className="mb-[2px] flex gap-2 items-baseline">
<Tooltip description={accountTypeTooltip}>
<span className="px-2 py-1 leading-none text-xs bg-vega-cdark-700 rounded">
{Schema.AccountTypeMapping[type]}
</span>
</Tooltip>
{isRedeemable ? (
<Tooltip description={t('RedeemRewardsTooltip')}>
<AnchorButton
variant="primary"
size="xs"
href={transferAssetLink(assetId)}
target="_blank"
className="px-2 py-1 leading-none text-xs bg-vega-yellow text-black rounded"
>
{t('Redeem')}
</AnchorButton>
</Tooltip>
) : null}
</div>
) : null}
<div className="basis-full font-mono" data-testid="currency-value">
<span>
{integers}
{separator}
@@ -953,5 +953,8 @@
"ACCOUNT_TYPE_REWARD_RELATIVE_RETURN": "Relative return reward account",
"ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY": "Return volatility reward account",
"ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING": "Validator ranking reward account",
"ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD": "Pending fee referral reward account"
"ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD": "Pending fee referral reward account",
"VestingRewardsTooltip": "Vesting rewards will be moved to vested account at a rate of {{baseRate}} per epoch.",
"VestedRewardsTooltip": "Vested rewards can be redeemed using Console",
"RedeemRewardsTooltip": "Click to redeem vested rewards in Console"
}
@@ -22,6 +22,7 @@ const colUpdatedAt = '[col-id="updatedAt"] button';
const headers = [
'Party',
'Status',
'Commitment (tDAI)',
'Obligation',
'Fee',
@@ -34,7 +35,6 @@ const headers = [
'Last time on the book',
'Last fee penalty',
'Last bond penalty',
'Status',
'Created',
'Updated',
];
@@ -8,7 +8,7 @@ jest.mock('@vegaprotocol/accounts', () => ({
),
}));
jest.mock('../../components/welcome-dialog/get-started.ts', () => ({
jest.mock('../../components/welcome-dialog/get-started', () => ({
GetStarted: () => <div>GetStarted</div>,
}));
@@ -8,7 +8,7 @@ jest.mock('../../components/withdraw-container', () => ({
),
}));
jest.mock('../../components/welcome-dialog/get-started.ts', () => ({
jest.mock('../../components/welcome-dialog/get-started', () => ({
GetStarted: () => <div>GetStarted</div>,
}));
+23 -6
View File
@@ -1,11 +1,28 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import BigNumber from 'bignumber.js';
import { AddressField, TransferFee, TransferForm } from './transfer-form';
import {
AddressField,
TransferFee,
TransferForm,
type TransferFormProps,
} from './transfer-form';
import { AccountType } from '@vegaprotocol/types';
import { removeDecimal } from '@vegaprotocol/utils';
import { MockedProvider } from '@apollo/client/testing';
describe('TransferForm', () => {
const renderComponent = (props: TransferFormProps) => {
return render(
// Wrap with mock provider as the form will make queries to fetch the selected
// toVegaKey accounts. We don't test this for now but we need to wrap so that
// the component has access to the client
<MockedProvider>
<TransferForm {...props} />
</MockedProvider>
);
};
const submit = async () => {
await userEvent.click(
screen.getByRole('button', { name: 'Confirm transfer' })
@@ -66,7 +83,7 @@ describe('TransferForm', () => {
// 1003-TRAN-017
// 1003-TRAN-018
// 1003-TRAN-019
render(<TransferForm {...props} />);
renderComponent(props);
// Select a pubkey
await userEvent.selectOptions(
screen.getByLabelText('To Vega key'),
@@ -113,7 +130,7 @@ describe('TransferForm', () => {
// 1003-TRAN-012
// 1003-TRAN-013
// 1003-TRAN-004
render(<TransferForm {...props} />);
renderComponent(props);
await submit();
expect(await screen.findAllByText('Required')).toHaveLength(3); // pubkey is set as default value
const toggle = screen.getByText('Enter manually');
@@ -139,7 +156,7 @@ describe('TransferForm', () => {
// 1002-WITH-010
// 1003-TRAN-011
// 1003-TRAN-014
render(<TransferForm {...props} />);
renderComponent(props);
// check current pubkey not shown
const keySelect = screen.getByLabelText<HTMLSelectElement>('To Vega key');
@@ -206,7 +223,7 @@ describe('TransferForm', () => {
describe('IncludeFeesCheckbox', () => {
it('validates fields and submits when checkbox is checked', async () => {
const mockSubmit = jest.fn();
render(<TransferForm {...props} submitTransfer={mockSubmit} />);
renderComponent({ ...props, submitTransfer: mockSubmit });
// check current pubkey not shown
const keySelect = screen.getByLabelText<HTMLSelectElement>('To Vega key');
@@ -275,7 +292,7 @@ describe('TransferForm', () => {
});
it('validates fields when checkbox is not checked', async () => {
render(<TransferForm {...props} />);
renderComponent(props);
// check current pubkey not shown
const keySelect: HTMLSelectElement = screen.getByLabelText('To Vega key');
+50 -14
View File
@@ -27,6 +27,8 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { AssetOption, Balance } from '@vegaprotocol/assets';
import { AccountType, AccountTypeMapping } from '@vegaprotocol/types';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { accountsDataProvider } from './accounts-data-provider';
interface FormFields {
toVegaKey: string;
@@ -35,7 +37,7 @@ interface FormFields {
fromAccount: AccountType;
}
interface TransferFormProps {
export interface TransferFormProps {
pubKey: string | null;
pubKeys: string[] | null;
accounts: Array<{
@@ -72,8 +74,28 @@ export const TransferForm = ({
const assets = sortBy(
accounts
.filter((a) => a.type === AccountType.ACCOUNT_TYPE_GENERAL)
.filter(
(a) =>
a.type === AccountType.ACCOUNT_TYPE_GENERAL ||
a.type === AccountType.ACCOUNT_TYPE_VESTED_REWARDS
)
// Sum the general and vested account balances so the value shown in the asset
// dropdown is correct for all transferable accounts
.reduce((merged, account) => {
const existing = merged.findIndex(
(m) => m.asset.id === account.asset.id
);
if (existing > -1) {
const balance = new BigNumber(merged[existing].balance)
.plus(new BigNumber(account.balance))
.toString();
merged[existing] = { ...merged[existing], balance };
return merged;
}
return [...merged, account];
}, [] as typeof accounts)
.map((account) => ({
key: account.asset.id,
...account.asset,
balance: addDecimal(account.balance, account.asset.decimals),
})),
@@ -87,18 +109,30 @@ export const TransferForm = ({
const asset = assets.find((a) => a.id === assetId);
const { data: toAccounts } = useDataProvider({
dataProvider: accountsDataProvider,
variables: {
partyId: selectedPubKey,
},
skip: !selectedPubKey,
});
const account = accounts.find(
(a) => a.asset.id === assetId && a.type === fromAccount
);
const accountBalance =
account && addDecimal(account.balance, account.asset.decimals);
// General account for the selected asset
const generalAccount = accounts.find((a) => {
return (
a.asset.id === assetId && a.type === AccountType.ACCOUNT_TYPE_GENERAL
);
});
// The general account of the selected pubkey. You can only transfer
// to general accounts, either when redeeming vested rewards or just
// during normal general -> general transfers
const toGeneralAccount =
toAccounts &&
toAccounts.find((a) => {
return (
a.asset.id === assetId && a.type === AccountType.ACCOUNT_TYPE_GENERAL
);
});
const [includeFee, setIncludeFee] = useState(false);
@@ -226,7 +260,7 @@ export const TransferForm = ({
>
{assets.map((a) => (
<AssetOption
key={a.id}
key={a.key}
asset={a}
balance={
<Balance
@@ -296,14 +330,16 @@ export const TransferForm = ({
defaultValue={AccountType.ACCOUNT_TYPE_GENERAL}
>
<option value={AccountType.ACCOUNT_TYPE_GENERAL}>
{generalAccount
{toGeneralAccount
? `${
AccountTypeMapping[AccountType.ACCOUNT_TYPE_GENERAL]
} (${addDecimalsFormatNumber(
generalAccount.balance,
generalAccount.asset.decimals
)} ${generalAccount.asset.symbol})`
: AccountTypeMapping[AccountType.ACCOUNT_TYPE_GENERAL]}
toGeneralAccount.balance,
toGeneralAccount.asset.decimals
)} ${toGeneralAccount.asset.symbol})`
: `${AccountTypeMapping[AccountType.ACCOUNT_TYPE_GENERAL]} ${
asset ? `(0 ${asset.symbol})` : ''
}`}
</option>
</TradingSelect>
</TradingFormGroup>
@@ -72,15 +72,11 @@ export const DealTicketFeeDetails = ({
return (
<KeyValue
label={t('Fees')}
value={
totalDiscountedFeeAmount &&
`~${formatValue(totalDiscountedFeeAmount, assetDecimals)}`
}
formattedValue={
label={
<>
{t('Fees')}
{totalDiscountFactor ? (
<Pill size="xxs" intent={Intent.Warning} className="mr-1">
<Pill size="xxs" intent={Intent.Info} className="ml-1">
-
{formatNumberPercentage(
new BigNumber(totalDiscountFactor).multipliedBy(100),
@@ -88,10 +84,16 @@ export const DealTicketFeeDetails = ({
)}
</Pill>
) : null}
{totalDiscountedFeeAmount &&
`~${formatValue(totalDiscountedFeeAmount, assetDecimals, quantum)}`}
</>
}
value={
totalDiscountedFeeAmount &&
`~${formatValue(totalDiscountedFeeAmount, assetDecimals)}`
}
formattedValue={
totalDiscountedFeeAmount &&
`~${formatValue(totalDiscountedFeeAmount, assetDecimals, quantum)}`
}
labelDescription={
<div className="flex flex-col gap-2">
<p>
@@ -79,7 +79,11 @@ export const FeesBreakdown = ({
volumeDiscountFactor
);
const { volumeDiscount, referralDiscount } = getDiscountedFee(
const {
discountedFee: discountedTotalFeeAmount,
volumeDiscount,
referralDiscount,
} = getDiscountedFee(
totalFeeAmount,
referralDiscountFactor,
volumeDiscountFactor
@@ -131,7 +135,7 @@ export const FeesBreakdown = ({
<FeesBreakdownItem
label={t('Total fees')}
factor={feeFactors ? sumFeesFactors(feeFactors)?.toString() : undefined}
value={totalFeeAmount}
value={discountedTotalFeeAmount}
symbol={symbol}
decimals={decimals}
/>
+5
View File
@@ -126,6 +126,11 @@ export const useEtherscanLink = () => {
return link;
};
// Console pages
export const CONSOLE_TRANSFER = '#/portfolio/assets/transfer';
export const CONSOLE_TRANSFER_ASSET =
'#/portfolio/assets/transfer?assetId=:assetId';
// Governance pages
export const TOKEN_NEW_MARKET_PROPOSAL = '/proposals/propose/new-market';
export const TOKEN_NEW_NETWORK_PARAM_PROPOSAL =
+22 -9
View File
@@ -289,17 +289,30 @@ describe('FeesDiscountBreakdownTooltip', () => {
const { container } = render(<FeesDiscountBreakdownTooltip {...props} />);
const dt = container.querySelectorAll('dt');
const dd = container.querySelectorAll('dd');
const expected = [
{ label: 'Infrastructure Fee Referral Discount', value: '0.05 BTC' },
{ label: 'Infrastructure Fee Volume Discount', value: '0.06 BTC' },
{ label: 'Liquidity Fee Referral Discount', value: '0.01 BTC' },
{ label: 'Liquidity Fee Volume Discount', value: '0.02 BTC' },
{ label: 'Maker Fee Referral Discount', value: '0.03 BTC' },
{ label: 'Maker Fee Volume Discount', value: '0.04 BTC' },
const expectedDt = [
'Infrastructure Fee',
'Referral Discount',
'Volume Discount',
'Liquidity Fee',
'Referral Discount',
'Volume Discount',
'Maker Fee',
'Referral Discount',
'Volume Discount',
];
expected.forEach(({ label, value }, i) => {
const expectedDD = [
'0.05 BTC',
'0.06 BTC',
'0.01 BTC',
'0.02 BTC',
'0.03 BTC',
'0.04 BTC',
];
expectedDt.forEach((label, i) => {
expect(dt[i]).toHaveTextContent(label);
expect(dd[i]).toHaveTextContent(value);
});
expectedDD.forEach((label, i) => {
expect(dd[i]).toHaveTextContent(label);
});
});
});
+20 -7
View File
@@ -391,7 +391,7 @@ const FeesDiscountBreakdownTooltipItem = ({
label: string;
asset: ReturnType<typeof getAsset>;
}) =>
value ? (
value && value !== '0' ? (
<>
<dt className="col-span-1">{label}</dt>
<dd className="text-right col-span-1">
@@ -418,34 +418,47 @@ export const FeesDiscountBreakdownTooltip = ({
className="max-w-sm bg-vega-light-100 dark:bg-vega-dark-100 border border-vega-light-200 dark:border-vega-dark-200 px-4 py-2 z-20 rounded text-sm break-word text-black dark:text-white"
>
<dl className="grid grid-cols-2 gap-x-1">
{(fees.infrastructureFeeReferralDiscount || '0') !== '0' ||
(fees.infrastructureFeeVolumeDiscount || '0') !== '0' ? (
<dt className="col-span-2">{t('Infrastructure Fee')}</dt>
) : null}
<FeesDiscountBreakdownTooltipItem
value={fees.infrastructureFeeReferralDiscount}
label={t('Infrastructure Fee Referral Discount')}
label={t('Referral Discount')}
asset={asset}
/>
<FeesDiscountBreakdownTooltipItem
value={fees.infrastructureFeeVolumeDiscount}
label={t('Infrastructure Fee Volume Discount')}
label={t('Volume Discount')}
asset={asset}
/>
{(fees.liquidityFeeReferralDiscount || '0') !== '0' ||
(fees.liquidityFeeVolumeDiscount || '0') !== '0' ? (
<dt className="col-span-2">{t('Liquidity Fee')}</dt>
) : null}
<FeesDiscountBreakdownTooltipItem
value={fees.liquidityFeeReferralDiscount}
label={t('Liquidity Fee Referral Discount')}
label={t('Referral Discount')}
asset={asset}
/>
<FeesDiscountBreakdownTooltipItem
value={fees.liquidityFeeVolumeDiscount}
label={t('Liquidity Fee Volume Discount')}
label={t('Volume Discount')}
asset={asset}
/>
{(fees.makerFeeReferralDiscount || '0') !== '0' ||
(fees.makerFeeVolumeDiscount || '0') !== '0' ? (
<dt className="col-span-2">{t('Maker Fee')}</dt>
) : null}
<FeesDiscountBreakdownTooltipItem
value={fees.makerFeeReferralDiscount}
label={t('Maker Fee Referral Discount')}
label={t('Referral Discount')}
asset={asset}
/>
<FeesDiscountBreakdownTooltipItem
value={fees.makerFeeVolumeDiscount}
label={t('Maker Fee Volume Discount')}
label={t('Volume Discount')}
asset={asset}
/>
</dl>
@@ -49,6 +49,7 @@ describe('LiquidityTable', () => {
undefined,
undefined,
'Party',
'Status',
'Commitment ()',
'Obligation',
'Fee',
@@ -61,7 +62,6 @@ describe('LiquidityTable', () => {
'Last time on the book',
'Last fee penalty',
'Last bond penalty',
'Status',
'Created',
'Updated',
];
+125 -44
View File
@@ -8,7 +8,7 @@ import {
import { t } from '@vegaprotocol/i18n';
import type {
TypedDataAgGrid,
VegaValueFormatterParams,
VegaICellRendererParams,
} from '@vegaprotocol/datagrid';
import { AgGrid } from '@vegaprotocol/datagrid';
import {
@@ -183,6 +183,36 @@ export const LiquidityTable = ({
headerName: t('Commitment details'),
marryChildren: true,
children: [
{
headerName: t('Status'),
headerTooltip: t('The current status of this liquidity provision.'),
field: 'status',
cellRenderer: ({
data,
value,
}: VegaICellRendererParams<LiquidityProvisionData, 'status'>) => {
if (!value) return value;
if (
data?.status === LiquidityProvisionStatus.STATUS_PENDING &&
(data?.currentCommitmentAmount || data?.currentFee)
) {
return (
<span className="text-warning">
{t('Updating next epoch')}
</span>
);
}
return (
<span>
{
LiquidityProvisionStatusMapping[
value as LiquidityProvisionStatus
]
}
</span>
);
},
},
{
headerName: t(`Commitment (${symbol})`),
field: 'commitmentAmount',
@@ -190,30 +220,46 @@ export const LiquidityTable = ({
headerTooltip: t(
'The amount committed to the market by this liquidity provider.'
),
valueFormatter: ({
cellRenderer: ({
data,
value,
}: VegaValueFormatterParams<
}: VegaICellRendererParams<
LiquidityProvisionData,
'commitmentAmount'
>) => {
if (!value) return '-';
const formattedCommitmentAmount = addDecimalsFormatNumberQuantum(
value,
assetDecimalPlaces ?? 0,
quantum ?? 0
);
if (
data?.currentCommitmentAmount &&
data?.currentCommitmentAmount !== value
) {
return `${addDecimalsFormatNumberQuantum(
data.currentCommitmentAmount,
const currentCommitmentAmount = data?.currentCommitmentAmount;
const pendingCommitmentAmount = value;
const formattedPendingCommitmentAmount =
addDecimalsFormatNumberQuantum(
pendingCommitmentAmount,
assetDecimalPlaces ?? 0,
quantum ?? 0
)}/${formattedCommitmentAmount}`;
);
if (
currentCommitmentAmount &&
currentCommitmentAmount !== pendingCommitmentAmount
) {
const formattedCurrentCommitmentAmount =
addDecimalsFormatNumberQuantum(
currentCommitmentAmount,
assetDecimalPlaces ?? 0,
quantum ?? 0
);
return (
<>
<span>{formattedCurrentCommitmentAmount}</span> (
<span className="text-warning">
{formattedPendingCommitmentAmount}
</span>
)
</>
);
} else {
return formattedCommitmentAmount;
return formattedPendingCommitmentAmount;
}
},
tooltipValueGetter: assetDecimalsFormatter,
@@ -223,9 +269,58 @@ export const LiquidityTable = ({
field: 'commitmentAmount',
type: 'rightAligned',
headerTooltip: t(
`The liquidity provider's obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_volume network parameter to convert into units of liquidity volume. The obligation can be met by a combination of LP orders and limit orders on the order book.`
`The liquidity provider's obligation to the market, calculated as the liquidity commitment amount multiplied by the value of the stake_to_ccy_volume network parameter to convert into units of liquidity volume.`
),
valueFormatter: stakeToCcyVolumeQuantumFormatter,
cellRenderer: ({
data,
value,
}: VegaICellRendererParams<
LiquidityProvisionData,
'commitmentAmount'
>) => {
if (!value) return '-';
const currentCommitmentAmount = data?.currentCommitmentAmount
? new BigNumber(data?.currentCommitmentAmount)
.times(Number(stakeToCcyVolume) || 1)
.toString()
: undefined;
const pendingCommitmentAmount = new BigNumber(value)
.times(Number(stakeToCcyVolume) || 1)
.toString();
const formattedPendingCommitmentAmount =
addDecimalsFormatNumberQuantum(
pendingCommitmentAmount,
assetDecimalPlaces ?? 0,
quantum ?? 0
);
if (
currentCommitmentAmount &&
currentCommitmentAmount !== pendingCommitmentAmount
) {
const formattedCurrentCommitmentAmount =
addDecimalsFormatNumberQuantum(
currentCommitmentAmount,
assetDecimalPlaces ?? 0,
quantum ?? 0
);
return (
<>
<span>{formattedCurrentCommitmentAmount}</span> (
<span className="text-warning">
{formattedPendingCommitmentAmount}
</span>
)
</>
);
} else {
return formattedPendingCommitmentAmount;
}
},
tooltipValueGetter: stakeToCcyVolumeFormatter,
},
{
@@ -235,21 +330,27 @@ export const LiquidityTable = ({
),
field: 'fee',
type: 'rightAligned',
valueFormatter: ({
cellRenderer: ({
data,
value,
}: ValueFormatterParams<LiquidityProvisionData, 'fee'>) => {
}: VegaICellRendererParams<LiquidityProvisionData, 'fee'>) => {
if (!value) return '-';
const formattedValue =
const formattedPendingFee =
formatNumberPercentage(new BigNumber(value).times(100), 2) ||
'-';
if (data?.currentFee && data?.currentFee !== value) {
return `${formatNumberPercentage(
const formattedCurrentFee = formatNumberPercentage(
new BigNumber(data.currentFee).times(100),
2
)}/${formattedValue}`;
);
return (
<>
<span>{formattedCurrentFee}</span> (
<span className="text-warning">{formattedPendingFee}</span>)
</>
);
}
return formattedValue;
return formattedPendingFee;
},
},
{
@@ -367,26 +468,6 @@ export const LiquidityTable = ({
headerName: '',
marryChildren: true,
children: [
{
headerName: t('Status'),
headerTooltip: t('The current status of this liquidity provision.'),
field: 'status',
valueFormatter: ({
data,
value,
}: ValueFormatterParams<LiquidityProvisionData, 'status'>) => {
if (!value) return value;
if (
data?.status === LiquidityProvisionStatus.STATUS_PENDING &&
(data?.currentCommitmentAmount || data?.currentFee)
) {
return t('Updating next epoch');
}
return LiquidityProvisionStatusMapping[
value as LiquidityProvisionStatus
];
},
},
{
headerName: t('Created'),
headerTooltip: t(
@@ -12,6 +12,7 @@ export const NetworkParams = {
'rewards_marketCreationQuantumMultiple',
reward_staking_delegation_payoutDelay:
'reward_staking_delegation_payoutDelay',
rewards_vesting_baseRate: 'rewards_vesting_baseRate',
governance_proposal_market_minVoterBalance:
'governance_proposal_market_minVoterBalance',
governance_proposal_market_minClose: 'governance_proposal_market_minClose',
+1 -1
View File
@@ -71,7 +71,7 @@
"jsondiffpatch": "^0.4.1",
"lodash": "^4.17.21",
"next": "13.3.0",
"pennant": "1.14.0",
"pennant": "^1.14.1",
"react": "18.2.0",
"react-copy-to-clipboard": "^5.0.4",
"react-dom": "18.2.0",
+4 -4
View File
@@ -20500,10 +20500,10 @@ pend@~1.2.0:
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
pennant@1.14.0:
version "1.14.0"
resolved "https://registry.yarnpkg.com/pennant/-/pennant-1.14.0.tgz#4100c25a6d836d6f0ff425181fb6f812f9fe5778"
integrity sha512-9H0zWzFUSbD1BlDXnHFmKwkAxXGb1xTxjkUD+RwaMygtSwPXzQEyk2ScVyMqxdcz0RuJmI5HCVmZTOjdr1NwuA==
pennant@^1.14.1:
version "1.14.1"
resolved "https://registry.yarnpkg.com/pennant/-/pennant-1.14.1.tgz#8e7a53256095e398b03397af31c831b02a56032b"
integrity sha512-rjzo/tlFanO96OKhJiyjQtjug7sY6pjVZqVbieD3Tf4zt20bqIb6m4L2JfwOXEe0jqP/yddgCNPY+vlkVuJW1Q==
dependencies:
"@babel/runtime" "^7.13.10"
"@d3fc/d3fc-technical-indicator" "^8.0.1"