Compare commits

...
18 changed files with 113 additions and 77 deletions
@@ -36,13 +36,13 @@ describe('ProposalReferralProgramDetails helper functions', () => {
it('should format referral discount factor correctly', () => {
const input = '0.05';
const formatted = formatReferralDiscountFactor(input);
expect(formatted).toBe('5.00%');
expect(formatted).toBe('5%');
});
it('should format referral reward factor correctly', () => {
const input = '0.1';
const formatted = formatReferralRewardFactor(input);
expect(formatted).toBe('10.00%');
expect(formatted).toBe('10%');
});
it('should format minimum staked tokens correctly', () => {
@@ -112,6 +112,8 @@ const USE_ACCOUNT_TYPES = [
AccountType.ACCOUNT_TYPE_FEES_LIQUIDITY,
AccountType.ACCOUNT_TYPE_FEES_MAKER,
AccountType.ACCOUNT_TYPE_PENDING_TRANSFERS,
AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
AccountType.ACCOUNT_TYPE_VESTING_REWARDS,
];
const getAssetIds = (data: Account[]) =>
+11 -9
View File
@@ -42,15 +42,17 @@ export const TransferContainer = ({ assetId }: { assetId?: string }) => {
? data.filter((account) => ALLOWED_ACCOUNTS.includes(account.type))
: [];
const assets = accounts.map((account) => ({
id: account.asset.id,
symbol: account.asset.symbol,
name: account.asset.name,
decimals: account.asset.decimals,
balance: addDecimal(account.balance, account.asset.decimals),
}));
if (data === null) return null;
const assets = accounts
// Theres only one general account for each asset, this will give us a list
// of assets the user has accounts for
.filter((a) => a.type === Schema.AccountType.ACCOUNT_TYPE_GENERAL)
.map((account) => ({
id: account.asset.id,
symbol: account.asset.symbol,
name: account.asset.name,
decimals: account.asset.decimals,
balance: addDecimal(account.balance, account.asset.decimals),
}));
return (
<>
+21 -10
View File
@@ -5,6 +5,7 @@ import {
vegaPublicKey,
addDecimal,
formatNumber,
addDecimalsFormatNumber,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import {
@@ -47,7 +48,8 @@ interface TransferFormProps {
assets: Array<Asset>;
accounts: Array<{
type: AccountType;
asset: { id: string; symbol: string };
balance: string;
asset: { id: string; symbol: string; decimals: number };
}>;
assetId?: string;
feeFactor: string | null;
@@ -79,6 +81,7 @@ export const TransferForm = ({
const selectedPubKey = watch('toAddress');
const amount = watch('amount');
const assetId = watch('asset');
const asset = assets.find((a) => a.id === assetId);
const [includeFee, setIncludeFee] = useState(false);
@@ -100,10 +103,6 @@ export const TransferForm = ({
);
}, [amount, includeFee, transferAmount, feeFactor]);
const asset = useMemo(() => {
return assets.find((a) => a.id === assetId);
}, [assets, assetId]);
const onSubmit = useCallback(
(fields: FormFields) => {
if (!asset) {
@@ -147,6 +146,13 @@ export const TransferForm = ({
}
}, [setValue, pubKey]);
// General account for the selected asset
const generalAccount = accounts.find((a) => {
return (
a.asset.id === assetId && a.type === AccountType.ACCOUNT_TYPE_GENERAL
);
});
return (
<form
onSubmit={handleSubmit(onSubmit)}
@@ -272,7 +278,9 @@ export const TransferForm = ({
.map((a) => {
return (
<option value={a.type} key={`${a.type}-${a.asset.id}`}>
{AccountTypeMapping[a.type]} ({a.asset.symbol})
{AccountTypeMapping[a.type]} (
{addDecimalsFormatNumber(a.balance, a.asset.decimals)}{' '}
{a.asset.symbol})
</option>
);
})}
@@ -289,10 +297,13 @@ export const TransferForm = ({
defaultValue={AccountType.ACCOUNT_TYPE_GENERAL}
>
<option value={AccountType.ACCOUNT_TYPE_GENERAL}>
{asset
? `${AccountTypeMapping[AccountType.ACCOUNT_TYPE_GENERAL]} (${
asset.symbol
})`
{generalAccount
? `${
AccountTypeMapping[AccountType.ACCOUNT_TYPE_GENERAL]
} (${addDecimalsFormatNumber(
generalAccount.balance,
generalAccount.asset.decimals
)} ${generalAccount.asset.symbol})`
: AccountTypeMapping[AccountType.ACCOUNT_TYPE_GENERAL]}
</option>
</TradingSelect>
+5 -1
View File
@@ -20,7 +20,11 @@ query Candles($marketId: ID!, $interval: Interval!, $since: String!) {
code
}
}
candlesConnection(interval: $interval, since: $since) {
candlesConnection(
interval: $interval
since: $since
pagination: { last: 5000 }
) {
edges {
node {
...CandleFields
+1 -1
View File
@@ -46,7 +46,7 @@ export const CandlesDocument = gql`
code
}
}
candlesConnection(interval: $interval, since: $since) {
candlesConnection(interval: $interval, since: $since, pagination: {last: 5000}) {
edges {
node {
...CandleFields
+1 -1
View File
@@ -32,7 +32,7 @@ export const Pagination = ({
{false}
{showRetentionMessage &&
t(
'Depending on data node retention you may not be able see the "full" history'
'Depending on data node retention you may not be able see the full history'
)}
</div>
<div className="flex items-center text-xs">
@@ -79,7 +79,7 @@ export const DealTicketFeeDetails = ({
}
formattedValue={
<>
{totalDiscountFactor && (
{totalDiscountFactor ? (
<Pill size="xxs" intent={Intent.Warning} className="mr-1">
-
{formatNumberPercentage(
@@ -87,14 +87,14 @@ export const DealTicketFeeDetails = ({
2
)}
</Pill>
)}
) : null}
{totalDiscountedFeeAmount &&
`~${formatValue(totalDiscountedFeeAmount, assetDecimals, quantum)}`}
</>
}
labelDescription={
<>
<p className="mb-2">
<div className="flex flex-col gap-2">
<p>
{t(
`An estimate of the most you would be expected to pay in fees, in the market's settlement asset ${assetSymbol}. Fees estimated are "taker" fees and will only be payable if the order trades aggressively. Rebate equal to the maker portion will be paid to the trader if the order trades passively.`
)}
@@ -108,7 +108,7 @@ export const DealTicketFeeDetails = ({
symbol={assetSymbol}
decimals={assetDecimals}
/>
</>
</div>
}
symbol={assetSymbol}
/>
@@ -0,0 +1,36 @@
import { render, screen } from '@testing-library/react';
import { FeesBreakdown } from './fees-breakdown';
describe('FeesBreakdown', () => {
it('formats fee factors correctly', () => {
const feeFactors = {
makerFee: '0.00005',
infrastructureFee: '0.001',
liquidityFee: '0.5',
};
const fees = {
makerFee: '100',
infrastructureFee: '100',
liquidityFee: '100',
};
const props = {
totalFeeAmount: '100',
fees,
feeFactors,
symbol: 'USD',
decimals: 2,
referralDiscountFactor: '0.01',
volumeDiscountFactor: '0.01',
};
render(<FeesBreakdown {...props} />);
expect(screen.getByText('Maker fee').nextElementSibling).toHaveTextContent(
'0.005%'
);
expect(
screen.getByText('Infrastructure fee').nextElementSibling
).toHaveTextContent('0.1%');
expect(
screen.getByText('Liquidity fee').nextElementSibling
).toHaveTextContent('50%');
});
});
@@ -33,7 +33,7 @@ const FeesBreakdownItem = ({
<dt className="col-span-2">{label}</dt>
{factor && (
<dd className="text-right col-span-1">
{formatNumberPercentage(new BigNumber(factor).times(100), 2)}
{formatNumberPercentage(new BigNumber(factor).times(100))}
</dd>
)}
<dd className="text-right col-span-3">
+1 -1
View File
@@ -37,7 +37,7 @@ export const MarketCandlesDocument = gql`
marketsConnection(id: $marketId) {
edges {
node {
candlesConnection(interval: $interval, since: $since) {
candlesConnection(interval: $interval, since: $since, pagination: {last: 1000}) {
edges {
node {
...MarketCandlesFields
+1 -1
View File
@@ -19,7 +19,7 @@ export const MarketsCandlesDocument = gql`
edges {
node {
id
candlesConnection(interval: $interval, since: $since) {
candlesConnection(interval: $interval, since: $since, pagination: {last: 1000}) {
edges {
node {
...MarketCandlesFields
+5 -1
View File
@@ -11,7 +11,11 @@ query MarketCandles($interval: Interval!, $since: String!, $marketId: ID!) {
marketsConnection(id: $marketId) {
edges {
node {
candlesConnection(interval: $interval, since: $since) {
candlesConnection(
interval: $interval
since: $since
pagination: { last: 1000 }
) {
edges {
node {
...MarketCandlesFields
+4 -4
View File
@@ -72,10 +72,10 @@ describe('totalFeesFactorsPercentage', () => {
makerFee: f[2].toString(),
});
it.each([
{ i: createFee(0, 0, 1), o: '100.00%' },
{ i: createFee(0, 1, 0), o: '100.00%' },
{ i: createFee(1, 0, 0), o: '100.00%' },
{ i: createFee(0.01, 0.02, 0.003), o: '3.30%' },
{ i: createFee(0, 0, 1), o: '100%' },
{ i: createFee(0, 1, 0), o: '100%' },
{ i: createFee(1, 0, 0), o: '100%' },
{ i: createFee(0.01, 0.02, 0.003), o: '3.3%' },
{ i: createFee(0.01, 0.056782, 0.003), o: '6.9782%' },
{ i: createFee(0.01, 0.056782, 0), o: '6.6782%' },
])('adds fees correctly', ({ i, o }) => {
+5 -1
View File
@@ -12,7 +12,11 @@ query MarketsCandles($interval: Interval!, $since: String!) {
edges {
node {
id
candlesConnection(interval: $interval, since: $since) {
candlesConnection(
interval: $interval
since: $since
pagination: { last: 1000 }
) {
edges {
node {
...MarketCandlesFields
+9 -36
View File
@@ -3,10 +3,7 @@ import { tradesWithMarketProvider } from './trades-data-provider';
import { TradesTable } from './trades-table';
import { useDealTicketFormValues } from '@vegaprotocol/deal-ticket';
import { t } from '@vegaprotocol/i18n';
import { Pagination } from '@vegaprotocol/datagrid';
import type { useDataGridEvents } from '@vegaprotocol/datagrid';
import { useCallback, useState } from 'react';
import type { AgGridReact } from 'ag-grid-react';
interface TradesContainerProps {
marketId: string;
@@ -19,43 +16,19 @@ export const TradesManager = ({
}: TradesContainerProps) => {
const update = useDealTicketFormValues((state) => state.updateAll);
const { data, error, load, pageInfo } = useDataProvider({
const { data, error } = useDataProvider({
dataProvider: tradesWithMarketProvider,
variables: { marketId },
});
const [hasDisplayedRow, setHasDisplayedRow] = useState<boolean | undefined>(
undefined
);
const { onFilterChanged, ...props } = gridProps || {};
const onRowDataUpdated = useCallback(
({ api }: { api: AgGridReact['api'] }) => {
setHasDisplayedRow(!!api.getDisplayedRowCount());
},
[]
);
return (
<div className="flex flex-col h-full">
<TradesTable
rowData={data}
onClick={(price?: string) => {
update(marketId, { price });
}}
onFilterChanged={(event) => {
onRowDataUpdated(event);
onFilterChanged(event);
}}
onRowDataUpdated={onRowDataUpdated}
overlayNoRowsTemplate={error ? error.message : t('No trades')}
{...props}
/>
<Pagination
count={data?.length || 0}
pageInfo={pageInfo}
onLoad={load}
hasDisplayedRows={hasDisplayedRow || false}
showRetentionMessage={true}
/>
</div>
<TradesTable
rowData={data}
onClick={(price?: string) => {
update(marketId, { price });
}}
overlayNoRowsTemplate={error ? error.message : t('No trades')}
{...gridProps}
/>
);
};
+2 -2
View File
@@ -77,8 +77,8 @@ describe('number utils', () => {
{ v: new BigNumber(123.123), d: 3, o: '123.123%' },
{ v: new BigNumber(123.123), d: 6, o: '123.123%' },
{ v: new BigNumber(123.123), d: 0, o: '123%' },
{ v: new BigNumber(123), d: undefined, o: '123.00%' }, // it default to 2 decimal places
{ v: new BigNumber(30000), d: undefined, o: '30,000.00%' },
{ v: new BigNumber(123), d: undefined, o: '123%' }, // it default to 2 decimal places
{ v: new BigNumber(30000), d: undefined, o: '30,000%' },
{ v: new BigNumber(3.000001), d: undefined, o: '3.000001%' },
])('formats given number correctly', ({ v, d, o }) => {
expect(formatNumberPercentage(v, d)).toStrictEqual(o);
+1 -1
View File
@@ -158,7 +158,7 @@ export const addDecimalsFixedFormatNumber = (
export const formatNumberPercentage = (value: BigNumber, decimals?: number) => {
const decimalPlaces =
typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals;
typeof decimals === 'undefined' ? value.dp() || 0 : decimals;
return `${formatNumber(value, decimalPlaces)}%`;
};