Compare commits
5 Commits
develop
...
chore/remo
Author | SHA1 | Date | |
---|---|---|---|
|
7404157ec6 | ||
|
a90c5c3b0c | ||
|
9e2e6b7636 | ||
|
ab06c95468 | ||
|
7b4c5c0fab |
@ -4,5 +4,6 @@ tmp/*
|
||||
.dockerignore
|
||||
dockerfiles
|
||||
node_modules
|
||||
.git
|
||||
.github
|
||||
.vscode
|
||||
|
@ -10,7 +10,7 @@ import {
|
||||
addDecimalsFormatNumber,
|
||||
formatNumber,
|
||||
removePaginationWrapper,
|
||||
suitableForSyntaxHighlighter,
|
||||
validForSyntaxHighlighter,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { RouteTitle } from '../../components/route-title';
|
||||
@ -134,7 +134,7 @@ export const NetworkParameterRow = ({
|
||||
}: {
|
||||
row: { key: string; value: string };
|
||||
}) => {
|
||||
const isSyntaxRow = suitableForSyntaxHighlighter(value);
|
||||
const isSyntaxRow = validForSyntaxHighlighter(value);
|
||||
useDocumentTitle(['Network Parameters']);
|
||||
|
||||
return (
|
||||
|
@ -38,7 +38,6 @@ import { differenceInHours, format, formatDistanceToNowStrict } from 'date-fns';
|
||||
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
|
||||
import { MarketName } from '../proposal/market-name';
|
||||
import { Indicator } from '../proposal/indicator';
|
||||
import { type ProposalNode } from '../proposal/proposal-utils';
|
||||
|
||||
const ProposalTypeTags = ({
|
||||
proposal,
|
||||
@ -541,12 +540,10 @@ const BatchProposalStateText = ({
|
||||
|
||||
export const ProposalHeader = ({
|
||||
proposal,
|
||||
restData,
|
||||
isListItem = true,
|
||||
voteState,
|
||||
}: {
|
||||
proposal: Proposal | BatchProposal;
|
||||
restData?: ProposalNode | null;
|
||||
isListItem?: boolean;
|
||||
voteState?: VoteState | null;
|
||||
}) => {
|
||||
@ -598,7 +595,7 @@ export const ProposalHeader = ({
|
||||
)}
|
||||
</div>
|
||||
<ProposalDetails proposal={proposal} />
|
||||
<VoteBreakdown proposal={proposal} restData={restData} />
|
||||
<VoteBreakdown proposal={proposal} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -91,28 +91,6 @@ export type ProposalNode = {
|
||||
proposal: ProposalData;
|
||||
proposalType: ProposalNodeType;
|
||||
proposals: SubProposalData[];
|
||||
yes?: [
|
||||
{
|
||||
partyId: string;
|
||||
elsPerMarket?: [
|
||||
{
|
||||
marketId: string;
|
||||
els: string;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
no?: [
|
||||
{
|
||||
partyId: string;
|
||||
elsPerMarket?: [
|
||||
{
|
||||
marketId: string;
|
||||
els: string;
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
type SingleProposalNode = ProposalNode & {
|
||||
|
@ -48,7 +48,6 @@ export const Proposal = ({ proposal, restData }: ProposalProps) => {
|
||||
|
||||
<ProposalHeader
|
||||
proposal={proposal}
|
||||
restData={restData}
|
||||
isListItem={false}
|
||||
voteState={voteState}
|
||||
/>
|
||||
|
@ -17,7 +17,6 @@ import {
|
||||
import { useBatchVoteInformation } from '../../hooks/use-vote-information';
|
||||
import { MarketName } from '../proposal/market-name';
|
||||
import { Indicator } from '../proposal/indicator';
|
||||
import { type ProposalNode } from '../proposal/proposal-utils';
|
||||
|
||||
export const CompactVotes = ({ number }: { number: BigNumber }) => (
|
||||
<CompactNumber
|
||||
@ -111,64 +110,24 @@ const Status = ({ reached, threshold, text, testId }: StatusProps) => {
|
||||
|
||||
export const VoteBreakdown = ({
|
||||
proposal,
|
||||
restData,
|
||||
}: {
|
||||
proposal: Proposal | BatchProposal;
|
||||
restData?: ProposalNode | null;
|
||||
}) => {
|
||||
if (proposal.__typename === 'Proposal') {
|
||||
return <VoteBreakdownNormal proposal={proposal} />;
|
||||
}
|
||||
|
||||
if (proposal.__typename === 'BatchProposal') {
|
||||
return <VoteBreakdownBatch proposal={proposal} restData={restData} />;
|
||||
return <VoteBreakdownBatch proposal={proposal} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const VoteBreakdownBatch = ({
|
||||
proposal,
|
||||
restData,
|
||||
}: {
|
||||
proposal: BatchProposal;
|
||||
restData?: ProposalNode | null;
|
||||
}) => {
|
||||
const VoteBreakdownBatch = ({ proposal }: { proposal: BatchProposal }) => {
|
||||
const [fullBreakdown, setFullBreakdown] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
|
||||
const yesELS =
|
||||
restData?.yes?.reduce((all, y) => {
|
||||
if (y.elsPerMarket) {
|
||||
y.elsPerMarket.forEach((item) => {
|
||||
const share = Number(item.els);
|
||||
if (all[item.marketId]) {
|
||||
all[item.marketId].push(share);
|
||||
} else {
|
||||
all[item.marketId] = [share];
|
||||
}
|
||||
return all;
|
||||
});
|
||||
}
|
||||
return all;
|
||||
}, {} as Record<string, number[]>) || {};
|
||||
|
||||
const noELS =
|
||||
restData?.no?.reduce((all, y) => {
|
||||
if (y.elsPerMarket) {
|
||||
y.elsPerMarket.forEach((item) => {
|
||||
const share = Number(item.els);
|
||||
if (all[item.marketId]) {
|
||||
all[item.marketId].push(share);
|
||||
} else {
|
||||
all[item.marketId] = [share];
|
||||
}
|
||||
return all;
|
||||
});
|
||||
}
|
||||
return all;
|
||||
}, {} as Record<string, number[]>) || {};
|
||||
|
||||
const voteInfo = useBatchVoteInformation({
|
||||
terms: compact(
|
||||
proposal.subProposals ? proposal.subProposals.map((p) => p?.terms) : []
|
||||
@ -235,8 +194,6 @@ const VoteBreakdownBatch = ({
|
||||
proposal={proposal}
|
||||
votes={proposal.votes}
|
||||
terms={p.terms}
|
||||
yesELS={yesELS}
|
||||
noELS={noELS}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -297,8 +254,6 @@ const VoteBreakdownBatch = ({
|
||||
proposal={proposal}
|
||||
votes={proposal.votes}
|
||||
terms={p.terms}
|
||||
yesELS={yesELS}
|
||||
noELS={noELS}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -316,17 +271,17 @@ const VoteBreakdownBatchSubProposal = ({
|
||||
votes,
|
||||
terms,
|
||||
indicator,
|
||||
yesELS,
|
||||
noELS,
|
||||
}: {
|
||||
proposal: BatchProposal;
|
||||
votes: VoteFieldsFragment;
|
||||
terms: ProposalTermsFieldsFragment;
|
||||
indicator?: number;
|
||||
yesELS: Record<string, number[]>;
|
||||
noELS: Record<string, number[]>;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const voteInfo = useVoteInformation({
|
||||
votes,
|
||||
terms,
|
||||
});
|
||||
|
||||
const isProposalOpen = proposal?.state === ProposalState.STATE_OPEN;
|
||||
const isUpdateMarket = terms?.change?.__typename === 'UpdateMarket';
|
||||
@ -339,15 +294,6 @@ const VoteBreakdownBatchSubProposal = ({
|
||||
marketId = terms.change.market.id;
|
||||
}
|
||||
|
||||
const voteInfo = useVoteInformation({
|
||||
votes,
|
||||
terms,
|
||||
// yes votes ELS for this specific proposal (market)
|
||||
yesELS: marketId ? yesELS[marketId] : undefined,
|
||||
// no votes ELS for this specific proposal (market)
|
||||
noELS: marketId ? noELS[marketId] : undefined,
|
||||
});
|
||||
|
||||
const marketName = marketId ? (
|
||||
<>
|
||||
: <MarketName marketId={marketId} />
|
||||
|
@ -8,18 +8,13 @@ import {
|
||||
type VoteFieldsFragment,
|
||||
} from '../__generated__/Proposals';
|
||||
import { type ProposalChangeType } from '../types';
|
||||
import sum from 'lodash/sum';
|
||||
|
||||
export const useVoteInformation = ({
|
||||
votes,
|
||||
terms,
|
||||
yesELS,
|
||||
noELS,
|
||||
}: {
|
||||
votes: VoteFieldsFragment;
|
||||
terms: ProposalTermsFieldsFragment;
|
||||
yesELS?: number[];
|
||||
noELS?: number[];
|
||||
}) => {
|
||||
const {
|
||||
appState: { totalSupply, decimals },
|
||||
@ -36,9 +31,7 @@ export const useVoteInformation = ({
|
||||
paramsForChange,
|
||||
votes,
|
||||
totalSupply,
|
||||
decimals,
|
||||
yesELS,
|
||||
noELS
|
||||
decimals
|
||||
);
|
||||
};
|
||||
|
||||
@ -79,11 +72,7 @@ const getVoteData = (
|
||||
},
|
||||
votes: ProposalFieldsFragment['votes'],
|
||||
totalSupply: BigNumber,
|
||||
decimals: number,
|
||||
/** A list of ELS yes votes */
|
||||
yesELS?: number[],
|
||||
/** A list if ELS no votes */
|
||||
noELS?: number[]
|
||||
decimals: number
|
||||
) => {
|
||||
const requiredMajorityPercentage = params.requiredMajority
|
||||
? new BigNumber(params.requiredMajority).times(100)
|
||||
@ -97,31 +86,17 @@ const getVoteData = (
|
||||
addDecimal(votes.no.totalTokens ?? 0, decimals)
|
||||
);
|
||||
|
||||
let noEquityLikeShareWeight = !votes.no.totalEquityLikeShareWeight
|
||||
const noEquityLikeShareWeight = !votes.no.totalEquityLikeShareWeight
|
||||
? new BigNumber(0)
|
||||
: new BigNumber(votes.no.totalEquityLikeShareWeight).times(100);
|
||||
// there's no meaningful `totalEquityLikeShareWeight` in batch proposals,
|
||||
// it has to be deduced from `elsPerMarket` of `no` votes of given proposal
|
||||
// data. (by REST DATA)
|
||||
if (noELS != null) {
|
||||
const noTotalELS = sum(noELS);
|
||||
noEquityLikeShareWeight = new BigNumber(noTotalELS).times(100);
|
||||
}
|
||||
|
||||
const yesTokens = new BigNumber(
|
||||
addDecimal(votes.yes.totalTokens ?? 0, decimals)
|
||||
);
|
||||
|
||||
let yesEquityLikeShareWeight = !votes.yes.totalEquityLikeShareWeight
|
||||
const yesEquityLikeShareWeight = !votes.yes.totalEquityLikeShareWeight
|
||||
? new BigNumber(0)
|
||||
: new BigNumber(votes.yes.totalEquityLikeShareWeight).times(100);
|
||||
// there's no meaningful `totalEquityLikeShareWeight` in batch proposals,
|
||||
// it has to be deduced from `elsPerMarket` of `yes` votes of given proposal
|
||||
// data. (by REST DATA)
|
||||
if (noELS != null) {
|
||||
const yesTotalELS = sum(yesELS);
|
||||
yesEquityLikeShareWeight = new BigNumber(yesTotalELS).times(100);
|
||||
}
|
||||
|
||||
const totalTokensVoted = yesTokens.plus(noTokens);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { suitableForSyntaxHighlighter } from '@vegaprotocol/utils';
|
||||
import { validForSyntaxHighlighter } from '@vegaprotocol/utils';
|
||||
import { useNetworkParams } from '@vegaprotocol/network-parameters';
|
||||
import {
|
||||
getClosingTimestamp,
|
||||
@ -46,7 +46,7 @@ const SelectedNetworkParamCurrentValue = ({
|
||||
<div className="mb-4">
|
||||
<p className="text-sm text-white">{t('CurrentValue')}</p>
|
||||
|
||||
{suitableForSyntaxHighlighter(value) ? (
|
||||
{validForSyntaxHighlighter(value) ? (
|
||||
<SyntaxHighlighter data={JSON.parse(value)} />
|
||||
) : (
|
||||
<Input
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
doesValueEquateToParam,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
|
||||
import { useValidateJson } from '@vegaprotocol/utils';
|
||||
import { useValidateJson } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
doesValueEquateToParam,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
|
||||
import { useValidateJson } from '@vegaprotocol/utils';
|
||||
import { useValidateJson } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
RoundedWrapper,
|
||||
TextArea,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useValidateJson } from '@vegaprotocol/utils';
|
||||
import { useValidateJson } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
doesValueEquateToParam,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
|
||||
import { useValidateJson } from '@vegaprotocol/utils';
|
||||
import { useValidateJson } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
useProposalSubmit,
|
||||
} from '@vegaprotocol/proposals';
|
||||
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
|
||||
import { useValidateJson } from '@vegaprotocol/utils';
|
||||
import { useValidateJson } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { URL_REGEX, isValidVegaPublicKey } from '@vegaprotocol/utils';
|
||||
import { URL_REGEX, validVegaPublicKey } from '@vegaprotocol/utils';
|
||||
|
||||
import { type useReferralSetTransaction } from '../../lib/hooks/use-referral-set-transaction';
|
||||
import { useT } from '../../lib/use-t';
|
||||
@ -217,9 +217,7 @@ export const TeamForm = ({
|
||||
validate: {
|
||||
allowList: (value) => {
|
||||
const publicKeys = parseAllowListText(value);
|
||||
if (
|
||||
publicKeys.every((pk) => isValidVegaPublicKey(pk))
|
||||
) {
|
||||
if (publicKeys.every((pk) => validVegaPublicKey(pk))) {
|
||||
return true;
|
||||
}
|
||||
return t('Invalid public key found in allow list');
|
||||
|
@ -2,12 +2,11 @@ import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
import { DocsLinks, useEnvironment } from '@vegaprotocol/environment';
|
||||
import { ButtonLink, ExternalLink, Link } from '@vegaprotocol/ui-toolkit';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import { addDecimalsFormatNumber, fromNanoSeconds } from '@vegaprotocol/utils';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
fromNanoSeconds,
|
||||
getExpiryDate,
|
||||
useMarketExpiryDate,
|
||||
getMarketExpiryDate,
|
||||
} from '@vegaprotocol/utils';
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
Last24hPriceChange,
|
||||
Last24hVolume,
|
||||
@ -264,12 +263,13 @@ export const FundingCountdown = ({ marketId }: { marketId: string }) => {
|
||||
};
|
||||
|
||||
const ExpiryLabel = ({ market }: ExpiryLabelProps) => {
|
||||
const content = market.tradableInstrument.instrument.metadata.tags
|
||||
? getExpiryDate(
|
||||
const expiryDate = useMarketExpiryDate(
|
||||
market.tradableInstrument.instrument.metadata.tags,
|
||||
market.marketTimestamps.close,
|
||||
market.state
|
||||
)
|
||||
);
|
||||
const content = market.tradableInstrument.instrument.metadata.tags
|
||||
? expiryDate
|
||||
: '-';
|
||||
return <div data-testid="trading-expiry">{content}</div>;
|
||||
};
|
||||
|
@ -11,10 +11,8 @@ import { useMemo } from 'react';
|
||||
import type { Asset } from '@vegaprotocol/types';
|
||||
import type { ProductType } from '@vegaprotocol/types';
|
||||
import { MarketState, MarketStateMapping } from '@vegaprotocol/types';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
getMarketExpiryDate,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||
import { getMarketExpiryDate } from '@vegaprotocol/react-helpers';
|
||||
import { closedMarketsWithDataProvider, getAsset } from '@vegaprotocol/markets';
|
||||
import type { DataSourceFilterFragment } from '@vegaprotocol/markets';
|
||||
import { useAssetDetailsDialogStore } from '@vegaprotocol/assets';
|
||||
|
@ -7,11 +7,8 @@ import {
|
||||
useSuccessorMarket,
|
||||
type Market,
|
||||
} from '@vegaprotocol/markets';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
getMarketExpiryDate,
|
||||
isNumeric,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { addDecimalsFormatNumber, isNumeric } from '@vegaprotocol/utils';
|
||||
import { getMarketExpiryDate } from '@vegaprotocol/react-helpers';
|
||||
import { useT, ns } from '../../lib/use-t';
|
||||
import { Links } from '../../lib/links';
|
||||
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
import { useProfileDialogStore } from '../../stores/profile-dialog-store';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { useRequired } from '@vegaprotocol/utils';
|
||||
import { useRequired } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
useSimpleTransaction,
|
||||
type Status,
|
||||
|
@ -39,8 +39,6 @@ const nextConfig = {
|
||||
GIT_COMMIT: commitHash,
|
||||
GIT_TAG: tag,
|
||||
},
|
||||
basePath: '/apps/vegas', // Set the base path
|
||||
assetPrefix: '/apps/vegas', // Set the asset prefix
|
||||
};
|
||||
|
||||
module.exports = SENTRY_AUTH_TOKEN
|
||||
|
@ -1,13 +1,15 @@
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import {
|
||||
useMaxSafe,
|
||||
useRequired,
|
||||
useVegaPublicKey,
|
||||
addDecimal,
|
||||
toBigNum,
|
||||
removeDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
} from '@vegaprotocol/utils';
|
||||
import {
|
||||
useMaxSafe,
|
||||
useRequired,
|
||||
useVegaPublicKey,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { useT } from './use-t';
|
||||
import {
|
||||
TradingFormGroup,
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Controller, type Control } from 'react-hook-form';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import type { OrderFormValues } from '../../hooks/use-form-values';
|
||||
import { determinePriceStep, useValidateAmount } from '@vegaprotocol/utils';
|
||||
import { determinePriceStep } from '@vegaprotocol/utils';
|
||||
import { useValidateAmount } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
TradingFormGroup,
|
||||
Tooltip,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Controller, type Control } from 'react-hook-form';
|
||||
import type { Market } from '@vegaprotocol/markets';
|
||||
import type { OrderFormValues } from '../../hooks/use-form-values';
|
||||
import { useValidateAmount } from '@vegaprotocol/utils';
|
||||
import { useValidateAmount } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
TradingFormGroup,
|
||||
TradingInput,
|
||||
|
@ -8,8 +8,8 @@ import {
|
||||
formatForInput,
|
||||
formatValue,
|
||||
removeDecimal,
|
||||
useValidateAmount,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { useValidateAmount } from '@vegaprotocol/react-helpers';
|
||||
import { type Control, type UseFormWatch } from 'react-hook-form';
|
||||
import { useForm, Controller, useController } from 'react-hook-form';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
|
@ -31,10 +31,10 @@ import { useOpenVolume } from '@vegaprotocol/positions';
|
||||
import {
|
||||
toBigNum,
|
||||
removeDecimal,
|
||||
useValidateAmount,
|
||||
formatForInput,
|
||||
formatValue,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { useValidateAmount } from '@vegaprotocol/react-helpers';
|
||||
import { activeOrdersProvider } from '@vegaprotocol/orders';
|
||||
import {
|
||||
getAsset,
|
||||
|
@ -1,16 +1,18 @@
|
||||
import type { Asset, AssetFieldsFragment } from '@vegaprotocol/assets';
|
||||
import { AssetOption } from '@vegaprotocol/assets';
|
||||
import {
|
||||
addDecimal,
|
||||
isAssetTypeERC20,
|
||||
formatNumber,
|
||||
} from '@vegaprotocol/utils';
|
||||
import {
|
||||
useLocalStorage,
|
||||
useEthereumAddress,
|
||||
useRequired,
|
||||
useVegaPublicKey,
|
||||
useMinSafe,
|
||||
useMaxSafe,
|
||||
addDecimal,
|
||||
isAssetTypeERC20,
|
||||
formatNumber,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
TradingFormGroup,
|
||||
TradingInput,
|
||||
|
@ -16,6 +16,7 @@ import en_markets from './locales/en/markets.json';
|
||||
import en_web3 from './locales/en/web3.json';
|
||||
import en_proposals from './locales/en/proposals.json';
|
||||
import en_positions from './locales/en/positions.json';
|
||||
import en_react_helpers from './locales/en/react-helpers.json';
|
||||
import en_trades from './locales/en/trading.json';
|
||||
import en_ui_toolkit from './locales/en/ui-toolkit.json';
|
||||
import en_wallet from './locales/en/wallet.json';
|
||||
@ -39,6 +40,7 @@ export const locales = {
|
||||
web3: en_web3,
|
||||
positions: en_positions,
|
||||
proposals: en_proposals,
|
||||
react_helpers: en_react_helpers,
|
||||
trades: en_trades,
|
||||
'ui-toolkit': en_ui_toolkit,
|
||||
wallet: en_wallet,
|
||||
|
@ -27,8 +27,8 @@ import {
|
||||
formatNumber,
|
||||
formatNumberPercentage,
|
||||
getDateTimeFormat,
|
||||
getMarketExpiryDateFormatted,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { getMarketExpiryDateFormatted } from '@vegaprotocol/react-helpers';
|
||||
import type { Get } from 'type-fest';
|
||||
import { MarketInfoTable } from './info-key-value-table';
|
||||
import type {
|
||||
|
@ -3,10 +3,10 @@ import {
|
||||
getDateTimeFormat,
|
||||
addDecimal,
|
||||
addDecimalsFormatNumber,
|
||||
useValidateAmount,
|
||||
determinePriceStep,
|
||||
determineSizeStep,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { useValidateAmount } from '@vegaprotocol/react-helpers';
|
||||
import { Size } from '@vegaprotocol/datagrid';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import {
|
||||
|
@ -3,8 +3,8 @@ import {
|
||||
getDateTimeFormat,
|
||||
isNumeric,
|
||||
toBigNum,
|
||||
useFormatTrigger,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { useFormatTrigger } from '@vegaprotocol/react-helpers';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import {
|
||||
ActionsDropdown,
|
||||
|
@ -12,5 +12,8 @@ export * from './use-theme-switcher';
|
||||
export * from './use-storybook-theme-observer';
|
||||
export * from './use-yesterday';
|
||||
export * from './use-previous';
|
||||
export * from './use-validate';
|
||||
export * from './use-market-expiry-date';
|
||||
export { useScript } from './use-script';
|
||||
export { useUserAgent } from './use-user-agent';
|
||||
export { useFormatTrigger } from './use-format-trigger';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { type StopOrder, StopOrderTriggerDirection } from '@vegaprotocol/types';
|
||||
import { addDecimalsFormatNumber } from './number';
|
||||
import { useCallback } from 'react';
|
||||
import { useT } from '../use-t';
|
||||
import { type StopOrder, StopOrderTriggerDirection } from '@vegaprotocol/types';
|
||||
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
|
||||
import { useT } from './use-t';
|
||||
|
||||
export const useFormatTrigger = () => {
|
||||
const t = useT();
|
@ -1,42 +1,10 @@
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import { getDateTimeFormat } from '@vegaprotocol/utils';
|
||||
import { isValid, parseISO } from 'date-fns';
|
||||
import { getDateTimeFormat } from './format';
|
||||
import { useT } from './use-t';
|
||||
|
||||
export const getMarketExpiryDate = (
|
||||
tags?: ReadonlyArray<string> | null
|
||||
): Date | null => {
|
||||
if (tags) {
|
||||
const dateFound = tags.reduce<Date | null>((agg, tag) => {
|
||||
const parsed = parseISO(
|
||||
(tag.match(/^settlement.*:/) &&
|
||||
tag
|
||||
.split(':')
|
||||
.filter((item, i) => i)
|
||||
.join(':')) as string
|
||||
);
|
||||
if (isValid(parsed)) {
|
||||
agg = parsed;
|
||||
}
|
||||
return agg;
|
||||
}, null);
|
||||
return dateFound;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getMarketExpiryDateFormatted = (
|
||||
tags?: ReadonlyArray<string> | null
|
||||
): string | null => {
|
||||
if (tags) {
|
||||
const dateFound = getMarketExpiryDate(tags);
|
||||
return dateFound ? getDateTimeFormat().format(dateFound) : null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getExpiryDate = (
|
||||
tags: ReadonlyArray<string> | null,
|
||||
export const useMarketExpiryDate = (
|
||||
tags: ReadonlyArray<string> | null | undefined,
|
||||
close: string | null,
|
||||
state: MarketState
|
||||
): string => {
|
||||
@ -67,3 +35,35 @@ export const getExpiryDate = (
|
||||
}
|
||||
return content;
|
||||
};
|
||||
|
||||
export const getMarketExpiryDateFormatted = (
|
||||
tags?: ReadonlyArray<string> | null
|
||||
): string | null => {
|
||||
if (tags) {
|
||||
const dateFound = getMarketExpiryDate(tags);
|
||||
return dateFound ? getDateTimeFormat().format(dateFound) : null;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getMarketExpiryDate = (
|
||||
tags?: ReadonlyArray<string> | null
|
||||
): Date | null => {
|
||||
if (tags) {
|
||||
const dateFound = tags.reduce<Date | null>((agg, tag) => {
|
||||
const parsed = parseISO(
|
||||
(tag.match(/^settlement.*:/) &&
|
||||
tag
|
||||
.split(':')
|
||||
.filter((item, i) => i)
|
||||
.join(':')) as string
|
||||
);
|
||||
if (isValid(parsed)) {
|
||||
agg = parsed;
|
||||
}
|
||||
return agg;
|
||||
}, null);
|
||||
return dateFound;
|
||||
}
|
||||
return null;
|
||||
};
|
@ -1,3 +1,3 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
export const ns = 'utils';
|
||||
export const ns = 'react-helpers';
|
||||
export const useT = () => useTranslation(ns).t;
|
121
libs/react-helpers/src/hooks/use-validate.ts
Normal file
121
libs/react-helpers/src/hooks/use-validate.ts
Normal file
@ -0,0 +1,121 @@
|
||||
import { useCallback } from 'react';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as utils from '@vegaprotocol/utils';
|
||||
import { useT } from './use-t';
|
||||
|
||||
export const useRequired = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!utils.validRequired(value)) {
|
||||
return t('Required');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useEthereumAddress = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!utils.validEthAddress(value)) {
|
||||
return t('Invalid Ethereum address');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useVegaPublicKey = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!utils.validVegaPublicKey(value)) {
|
||||
return t('Invalid Vega key');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useMinSafe = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(min: BigNumber) => (value: string) => {
|
||||
if (utils.validMinSafe(value, min)) {
|
||||
return t('Value is below minimum');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useMaxSafe = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(max: BigNumber) => (value: string) => {
|
||||
if (utils.validMaxSafe(value, max)) {
|
||||
return t('Value is above maximum');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useValidateJson = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!utils.validJSON(value)) {
|
||||
return t('Must be valid JSON');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useValidateUrl = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!utils.validUrl(value)) {
|
||||
return t('Invalid URL');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
/** Used in deal ticket price/size amounts */
|
||||
export const useValidateAmount = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(step: number | string, field: string) => {
|
||||
return (value?: string) => {
|
||||
if (!utils.validStep(step, value)) {
|
||||
if (new BigNumber(step).isEqualTo(1)) {
|
||||
return t('{{field}} must be whole numbers for this market', {
|
||||
field,
|
||||
step,
|
||||
});
|
||||
}
|
||||
|
||||
return t('{{field}} must be a multiple of {{step}} for this market', {
|
||||
field,
|
||||
step,
|
||||
});
|
||||
}
|
||||
return true;
|
||||
};
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
@ -17,7 +17,8 @@ import {
|
||||
type SymbolQuery,
|
||||
type SymbolQueryVariables,
|
||||
} from './__generated__/Symbol';
|
||||
import { getMarketExpiryDate, toBigNum } from '@vegaprotocol/utils';
|
||||
import { toBigNum } from '@vegaprotocol/utils';
|
||||
import { getMarketExpiryDate } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
type IBasicDataFeed,
|
||||
type DatafeedConfiguration,
|
||||
|
@ -34,21 +34,6 @@
|
||||
"options": {
|
||||
"jestConfig": "libs/types/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"generate": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"commands": ["npx graphql-codegen --config=libs/types/codegen.yml"],
|
||||
"parallel": false
|
||||
}
|
||||
},
|
||||
"local-registry": {
|
||||
"executor": "@nx/js:verdaccio",
|
||||
"options": {
|
||||
"port": 4873,
|
||||
"config": ".verdaccio/config.yml",
|
||||
"storage": "tmp/local-registry/storage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*", "__generated__"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
@ -9,16 +9,18 @@
|
||||
"error",
|
||||
{
|
||||
"paths": [
|
||||
"error",
|
||||
"@apollo/client",
|
||||
"@ethersproject",
|
||||
"@vegaprotocol/data-provider",
|
||||
"ag-grid-react",
|
||||
"ag-grid-community",
|
||||
"ethers",
|
||||
"graphql",
|
||||
"graphql-tag",
|
||||
"graphql-ws",
|
||||
"ethers",
|
||||
"@ethersproject"
|
||||
"react",
|
||||
"react-dom",
|
||||
"react-i18next"
|
||||
],
|
||||
"patterns": ["@sentry/*"]
|
||||
}
|
||||
|
@ -7,10 +7,6 @@
|
||||
"date-fns": "^2.28.0",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "18.2.0",
|
||||
"react-i18next": "13.5.0"
|
||||
},
|
||||
"type": "module",
|
||||
"module": "./index.js"
|
||||
}
|
||||
|
@ -35,14 +35,6 @@
|
||||
"options": {
|
||||
"jestConfig": "libs/utils/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"local-registry": {
|
||||
"executor": "@nx/js:verdaccio",
|
||||
"options": {
|
||||
"port": 4873,
|
||||
"config": ".verdaccio/config.yml",
|
||||
"storage": "tmp/local-registry/storage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
|
@ -7,7 +7,6 @@ export * from './lib/helpers';
|
||||
export * from './lib/is-asset-erc20';
|
||||
export * from './lib/is-valid-url';
|
||||
export * from './lib/local-storage';
|
||||
export * from './lib/markets';
|
||||
export * from './lib/price-change';
|
||||
export * from './lib/remove-0x';
|
||||
export * from './lib/remove-pagination-wrapper';
|
||||
|
@ -3,5 +3,4 @@ export * from './number';
|
||||
export * from './range';
|
||||
export * from './size';
|
||||
export * from './strings';
|
||||
export * from './trigger';
|
||||
export * from './ether';
|
||||
|
@ -1,40 +1,66 @@
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import { useEthereumAddress, useVegaPublicKey } from './common';
|
||||
|
||||
it('ethereumAddress', () => {
|
||||
const result = renderHook(useEthereumAddress);
|
||||
const ethereumAddress = result.result.current;
|
||||
|
||||
const errorMessage = 'Invalid Ethereum address';
|
||||
import { validEthAddress, validVegaPublicKey, validStep } from './common';
|
||||
|
||||
it('validEthAddress', () => {
|
||||
const validAddress = '0x72c22822A19D20DE7e426fB84aa047399Ddd8853';
|
||||
expect(ethereumAddress(validAddress)).toEqual(true);
|
||||
expect(validEthAddress(validAddress)).toEqual(true);
|
||||
|
||||
const invalidChars = '0xzzc22822A19D20DE7e426fB84aa047399Ddd8853';
|
||||
expect(ethereumAddress(invalidChars)).toEqual(errorMessage);
|
||||
expect(validEthAddress(invalidChars)).toEqual(false);
|
||||
|
||||
const tooManyChars = '0x72c22822A19D20DE7e426fB84aa047399Ddd88531111111';
|
||||
expect(ethereumAddress(tooManyChars)).toEqual(errorMessage);
|
||||
expect(validEthAddress(tooManyChars)).toEqual(false);
|
||||
|
||||
const no0x = '1x72c22822A19D20DE7e426fB84aa047399Ddd8853';
|
||||
expect(ethereumAddress(no0x)).toEqual(errorMessage);
|
||||
expect(validEthAddress(no0x)).toEqual(false);
|
||||
});
|
||||
|
||||
it('vegaPublicKey', () => {
|
||||
const result = renderHook(useVegaPublicKey);
|
||||
const vegaPublicKey = result.result.current;
|
||||
|
||||
const errorMessage = 'Invalid Vega key';
|
||||
|
||||
it('validVegaPublicKey', () => {
|
||||
const validKey =
|
||||
'70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680';
|
||||
expect(vegaPublicKey(validKey)).toEqual(true);
|
||||
expect(validVegaPublicKey(validKey)).toEqual(true);
|
||||
|
||||
const invalidChars =
|
||||
'zzz14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680';
|
||||
expect(vegaPublicKey(invalidChars)).toEqual(errorMessage);
|
||||
expect(validVegaPublicKey(invalidChars)).toEqual(false);
|
||||
|
||||
const tooManyChars =
|
||||
'70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680111111';
|
||||
expect(vegaPublicKey(tooManyChars)).toEqual(errorMessage);
|
||||
expect(validVegaPublicKey(tooManyChars)).toEqual(false);
|
||||
});
|
||||
|
||||
describe('validateAgainstStep', () => {
|
||||
it('fails when step is an empty string', () => {
|
||||
expect(validStep('', '1234')).toEqual(false);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[0, 0],
|
||||
[1234567890, 0],
|
||||
[0.03, 0.03],
|
||||
[0.09, 0.03],
|
||||
[0.27, 0.03],
|
||||
[1, 1],
|
||||
[123, 1],
|
||||
[4, 2],
|
||||
[8, 2],
|
||||
])(
|
||||
'checks whether given value (%s) IS a multiple of given step (%s)',
|
||||
(value, step) => {
|
||||
expect(validStep(step, value)).toEqual(true);
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
[1, 2],
|
||||
[0.1, 0.003],
|
||||
[1.11, 0.1],
|
||||
[123.1, 1],
|
||||
[222, 221],
|
||||
[NaN, 1],
|
||||
])(
|
||||
'checks whether given value (%s) IS NOT a multiple of given step (%s)',
|
||||
(value, step) => {
|
||||
expect(validStep(step, value)).toEqual(false);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@ -1,77 +1,52 @@
|
||||
import BigNumber from 'bignumber.js';
|
||||
import { useT } from '../use-t';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
export const useRequired = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
export const validRequired = (value: string | number | undefined | null) => {
|
||||
if (value === null || value === undefined || value === '') {
|
||||
return t('Required');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const useEthereumAddress = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!/^0x[0-9a-fA-F]{40}$/i.test(value)) {
|
||||
return t('Invalid Ethereum address');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const VEGA_ID_REGEX = /^[A-Fa-f0-9]{64}$/i;
|
||||
export const isValidVegaPublicKey = (value: string) => {
|
||||
export const validVegaPublicKey = (value: string) => {
|
||||
return VEGA_ID_REGEX.test(value);
|
||||
};
|
||||
export const useVegaPublicKey = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!isValidVegaPublicKey(value)) {
|
||||
return t('Invalid Vega key');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
|
||||
export const URL_REGEX =
|
||||
/^(https?:\/\/)?([a-zA-Z0-9.-]+(\.[a-zA-Z]{2,})+)(:[0-9]{1,5})?(\/[^\s]*)?$/;
|
||||
export const validUrl = (value: string) => {
|
||||
return URL_REGEX.test(value);
|
||||
};
|
||||
|
||||
export const useMinSafe = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(min: BigNumber) => (value: string) => {
|
||||
if (new BigNumber(value).isLessThan(min)) {
|
||||
return t('Value is below minimum');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
export const ETH_ADDRESS = /^0x[0-9a-fA-F]{40}$/i;
|
||||
export const validEthAddress = (value: string) => {
|
||||
return ETH_ADDRESS.test(value);
|
||||
};
|
||||
|
||||
export const useMaxSafe = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(max: BigNumber) => (value: string) => {
|
||||
if (new BigNumber(value).isGreaterThan(max)) {
|
||||
return t('Value is above maximum');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
export const validMinSafe = (
|
||||
value: string | number | BigNumber,
|
||||
min: string | number | BigNumber
|
||||
) => {
|
||||
return new BigNumber(value).isLessThan(min);
|
||||
};
|
||||
|
||||
export const suitableForSyntaxHighlighter = (str: string) => {
|
||||
export const validMaxSafe = (
|
||||
value: string | number | BigNumber,
|
||||
max: string | number | BigNumber
|
||||
) => {
|
||||
return new BigNumber(value).isGreaterThan(max);
|
||||
};
|
||||
|
||||
export const validJSON = (value: string) => {
|
||||
try {
|
||||
JSON.parse(value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
export const validForSyntaxHighlighter = (str: string) => {
|
||||
try {
|
||||
const test = JSON.parse(str);
|
||||
return test && Object.keys(test).length > 0;
|
||||
@ -80,35 +55,17 @@ export const suitableForSyntaxHighlighter = (str: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const useValidateJson = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
try {
|
||||
JSON.parse(value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return t('Must be valid JSON');
|
||||
export const validStep = (step: string | number, input?: string | number) => {
|
||||
const stepValue = new BigNumber(step);
|
||||
if (stepValue.isNaN()) {
|
||||
// unable to check if step is not a number
|
||||
return false;
|
||||
}
|
||||
if (stepValue.isZero()) {
|
||||
// every number is valid when step is zero
|
||||
return true;
|
||||
}
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export const URL_REGEX =
|
||||
/^(https?:\/\/)?([a-zA-Z0-9.-]+(\.[a-zA-Z]{2,})+)(:[0-9]{1,5})?(\/[^\s]*)?$/;
|
||||
const isValidUrl = (value: string) => {
|
||||
return URL_REGEX.test(value);
|
||||
};
|
||||
export const useValidateUrl = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(value: string) => {
|
||||
if (!isValidUrl(value)) {
|
||||
return t('Invalid URL');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
[t]
|
||||
);
|
||||
const value = new BigNumber(input || '');
|
||||
return value.modulo(stepValue).isZero();
|
||||
};
|
||||
|
@ -1,2 +1 @@
|
||||
export * from './common';
|
||||
export * from './validate-amount';
|
||||
|
@ -1,38 +0,0 @@
|
||||
import { validateAgainstStep } from './validate-amount';
|
||||
|
||||
describe('validateAgainstStep', () => {
|
||||
it('fails when step is an empty string', () => {
|
||||
expect(validateAgainstStep('', '1234')).toEqual(false);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[0, 0],
|
||||
[1234567890, 0],
|
||||
[0.03, 0.03],
|
||||
[0.09, 0.03],
|
||||
[0.27, 0.03],
|
||||
[1, 1],
|
||||
[123, 1],
|
||||
[4, 2],
|
||||
[8, 2],
|
||||
])(
|
||||
'checks whether given value (%s) IS a multiple of given step (%s)',
|
||||
(value, step) => {
|
||||
expect(validateAgainstStep(step, value)).toEqual(true);
|
||||
}
|
||||
);
|
||||
|
||||
it.each([
|
||||
[1, 2],
|
||||
[0.1, 0.003],
|
||||
[1.11, 0.1],
|
||||
[123.1, 1],
|
||||
[222, 221],
|
||||
[NaN, 1],
|
||||
])(
|
||||
'checks whether given value (%s) IS NOT a multiple of given step (%s)',
|
||||
(value, step) => {
|
||||
expect(validateAgainstStep(step, value)).toEqual(false);
|
||||
}
|
||||
);
|
||||
});
|
@ -1,50 +0,0 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useT } from '../use-t';
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
export const useValidateAmount = () => {
|
||||
const t = useT();
|
||||
return useCallback(
|
||||
(step: number | string, field: string) => {
|
||||
return (value?: string) => {
|
||||
const isValid = validateAgainstStep(step, value);
|
||||
if (!isValid) {
|
||||
if (new BigNumber(step).isEqualTo(1)) {
|
||||
return t('{{field}} must be whole numbers for this market', {
|
||||
field,
|
||||
step,
|
||||
});
|
||||
}
|
||||
|
||||
return t('{{field}} must be a multiple of {{step}} for this market', {
|
||||
field,
|
||||
step,
|
||||
});
|
||||
}
|
||||
return true;
|
||||
};
|
||||
},
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
const isMultipleOf = (value: BigNumber, multipleOf: BigNumber) =>
|
||||
value.modulo(multipleOf).isZero();
|
||||
|
||||
export const validateAgainstStep = (
|
||||
step: string | number,
|
||||
input?: string | number
|
||||
) => {
|
||||
const stepValue = new BigNumber(step);
|
||||
if (stepValue.isNaN()) {
|
||||
// unable to check if step is not a number
|
||||
return false;
|
||||
}
|
||||
if (stepValue.isZero()) {
|
||||
// every number is valid when step is zero
|
||||
return true;
|
||||
}
|
||||
|
||||
const value = new BigNumber(input || '');
|
||||
return isMultipleOf(value, stepValue);
|
||||
};
|
@ -35,14 +35,6 @@
|
||||
"options": {
|
||||
"jestConfig": "libs/wallet/jest.config.ts"
|
||||
}
|
||||
},
|
||||
"local-registry": {
|
||||
"executor": "@nx/js:verdaccio",
|
||||
"options": {
|
||||
"port": 4873,
|
||||
"config": ".verdaccio/config.yml",
|
||||
"storage": "tmp/local-registry/storage"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { type StoreApi } from 'zustand';
|
||||
import { type Store, type Connector } from '../types';
|
||||
import { isValidVegaPublicKey } from '@vegaprotocol/utils';
|
||||
import { validVegaPublicKey } from '@vegaprotocol/utils';
|
||||
import {
|
||||
ConnectorError,
|
||||
chainIdError,
|
||||
@ -40,7 +40,7 @@ export class ViewPartyConnector implements Connector {
|
||||
throw userRejectedError();
|
||||
}
|
||||
|
||||
if (!isValidVegaPublicKey(value)) {
|
||||
if (!validVegaPublicKey(value)) {
|
||||
throw connectError('invalid public key');
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,9 @@ import {
|
||||
formatNumber,
|
||||
toBigNum,
|
||||
truncateByChars,
|
||||
useFormatTrigger,
|
||||
HALFMAXGOINT64,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { useFormatTrigger } from '@vegaprotocol/react-helpers';
|
||||
import { useAssetsMapProvider } from '@vegaprotocol/assets';
|
||||
import { useEthWithdrawApprovalsStore } from './use-ethereum-withdraw-approvals-store';
|
||||
import { DApp, EXPLORER_TX, useLinks } from '@vegaprotocol/environment';
|
||||
|
@ -1,13 +1,15 @@
|
||||
import type { Asset } from '@vegaprotocol/assets';
|
||||
import { AssetOption } from '@vegaprotocol/assets';
|
||||
import {
|
||||
useEthereumAddress,
|
||||
useRequired,
|
||||
useMinSafe,
|
||||
removeDecimal,
|
||||
isAssetTypeERC20,
|
||||
formatNumber,
|
||||
} from '@vegaprotocol/utils';
|
||||
import {
|
||||
useEthereumAddress,
|
||||
useRequired,
|
||||
useMinSafe,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import {
|
||||
TradingFormGroup,
|
||||
|
@ -241,5 +241,8 @@
|
||||
"graphql": "15.8.0",
|
||||
"//": "workaround storybook issue: https://github.com/storybookjs/storybook/issues/21642",
|
||||
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.cd77847.0"
|
||||
},
|
||||
"nx": {
|
||||
"includedScripts": []
|
||||
}
|
||||
}
|
||||
|
14
project.json
Normal file
14
project.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "nx-monorepo",
|
||||
"$schema": "node_modules/nx/schemas/project-schema.json",
|
||||
"targets": {
|
||||
"local-registry": {
|
||||
"executor": "@nx/js:verdaccio",
|
||||
"options": {
|
||||
"port": 4873,
|
||||
"config": ".verdaccio/config.yml",
|
||||
"storage": "tmp/local-registry/storage"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user