Compare commits

..
Author SHA1 Message Date
asiaznik 55f8829655 feat(trading): copy apply referral link from code tile 2023-11-22 16:35:07 +01:00
Art 87807d2088 chore(governance): sensible vote numbers (#5332) 2023-11-22 15:30:16 +01:00
m.rayandbwallacee a5f2533a66 feat(trading): market list snags and disable column removal (#5324)
Co-authored-by: bwallacee <ben@vega.xyz>
2023-11-22 13:51:39 +00:00
Ben 1e9251c9c0 chore(trading): python tests update vega version (#5313) 2023-11-22 09:39:40 +00:00
Ben 2a27e124d7 chore(ci): increase number of tests in parallel (#5322) 2023-11-22 08:17:22 +00:00
Ben 4ee85720ab chore(ci): specific ganache image (#5321) 2023-11-22 08:02:47 +00:00
BenandBartłomiej Głownia a19da4c408 chore(trading): cypress to python tests (#5319)
Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
2023-11-21 14:44:41 +00:00
BenandMatthew Russell 65ad4fffda chore(trading): migrate LP cypress tests (#5286)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-21 14:36:02 +00:00
Bartłomiej GłowniaandMatthew Russell 11317cdb2e feat(withdraws): use i18next (#5285)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-21 13:49:10 +00:00
Bartłomiej GłowniaandMatthew Russell c98870f27d feat(wallet): use i18next (#5299)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-21 13:48:53 +00:00
Bartłomiej Głowniaandbwallacee c0c56e4c48 feat(trading): fix markets i18n namespace, add missing label, preload all namespaces (#5312)
Co-authored-by: bwallacee <ben@vega.xyz>
2023-11-21 12:08:33 +01:00
Bartłomiej GłowniaandMatthew Russell a9ca215276 feat(proposals): use i18next (#5284)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-19 21:49:39 -08:00
Bartłomiej GłowniaandMatthew Russell 61a9eb2f5c feat(ui-toolkit): use i18next (#5289)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-19 15:27:52 -08:00
Bartłomiej GłowniaandMatthew Russell bb47747501 feat(utils): use i18next (#5269)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-19 14:00:45 -08:00
Bartłomiej GłowniaandMatthew Russell 5827b87f89 feat(trades): use i18next (#5268)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-19 13:51:08 -08:00
Bartłomiej Głownia 19b95832c4 feat(market-depth): use i18next (#5267) 2023-11-19 13:13:03 -08:00
Bartłomiej GłowniaandMatthew Russell 48e4ab53a1 feat(orders): use i18next (#5263)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2023-11-19 13:12:35 -08:00
Bartłomiej Głownia cefcff040f feat(positions): use i18next (#5266) 2023-11-17 19:49:19 -08:00
Bartłomiej Głownia c3ef639daf feat(web3): use i18next (#5256) 2023-11-17 16:44:30 -08:00
Bartłomiej Głownia b6052bc3e5 feat(markets): use i18next (#5255) 2023-11-17 12:01:18 -08:00
Bartłomiej Głownia 6e8894936e feat(ledger): use i18next (#5248) 2023-11-17 11:55:10 -08:00
Bartłomiej Głownia 66f55855ae feat(liquidity): use i18next (#5247) 2023-11-17 11:54:17 -08:00
Matthew Russell 5725b824ad Merge pull request #5309 from vegaprotocol/chore/sync-main
chore(governance,trading): sync with mainnet fixes
2023-11-17 11:51:03 -08:00
Matthew Russell 9344a2abc0 fix: no t function 2023-11-17 11:10:18 -08:00
Matthew Russell fae66ca4ce Merge branch 'main' into chore/sync-main 2023-11-17 10:56:19 -08:00
Matthew Russell 4b7338ed94 chore(deal-ticket,markets): dont show margin estimate for perps (#5305) 2023-11-17 10:33:24 -08:00
Edd 2983c6c6ba feat(governance): enable volume discount update view (#5304) (#5307) 2023-11-17 10:25:30 -08:00
Edd 31524ac7a7 feat(governance): enable volume discount update view (#5304) 2023-11-17 17:29:42 +00:00
Matthew Russellandasiaznik 70f42c1c7e fix(trading): fees page fixes for mainnet (#5303)
Co-authored-by: asiaznik <artur@vegaprotocol.io>
2023-11-17 08:53:21 -08:00
m.ray 2304ce9763 fix(proposals): perpetual proposed markets (#5290) 2023-11-17 12:00:19 +00:00
m.ray 79a16b8562 fix(trading): show deal ticket in sidebar by default (#5292) 2023-11-16 09:08:20 -08:00
Matthew Russell 5661b74082 fix(trading): do not use stakeToCcyVolume to format fees value (#5280) 2023-11-16 09:34:38 +00:00
m.ray 22703d937e fix(trading): fix percentage formatter rounding in liquidity table (#5250) 2023-11-13 16:14:18 +00:00
209 changed files with 3217 additions and 2388 deletions
+2 -2
View File
@@ -10,7 +10,7 @@ on:
inputs:
console-test-branch:
type: choice
description: 'main: v0.72.14, develop: v0.73.4'
description: 'main: v0.73.5, develop: v0.73.5'
options:
- main
- develop
@@ -205,7 +205,7 @@ jobs:
# run tests
#----------------------------------------------
- name: Run tests
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 4 --dist loadfile --durations=15
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 6 --dist loadfile --durations=15
working-directory: apps/trading/e2e
#----------------------------------------------
# upload traces
+19 -14
View File
@@ -1,3 +1,4 @@
import '../i18n';
import {
NetworkLoader,
NodeFailure,
@@ -28,20 +29,24 @@ function App() {
);
return (
<TendermintWebsocketProvider>
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
<NodeGuard
skeleton={<div>{t('Loading')}</div>}
failure={<NodeFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />}
>
<Suspense fallback={splashLoading}>
<RouterProvider router={router} fallbackElement={splashLoading} />
</Suspense>
</NodeGuard>
<NodeSwitcherDialog
open={nodeSwitcherOpen}
setOpen={setNodeSwitcherOpen}
/>
</NetworkLoader>
<Suspense fallback={splashLoading}>
<NetworkLoader cache={DEFAULT_CACHE_CONFIG}>
<NodeGuard
skeleton={<div>{t('Loading')}</div>}
failure={
<NodeFailure title={t(`Node: ${VEGA_URL} is unsuitable`)} />
}
>
<Suspense fallback={splashLoading}>
<RouterProvider router={router} fallbackElement={splashLoading} />
</Suspense>
</NodeGuard>
<NodeSwitcherDialog
open={nodeSwitcherOpen}
setOpen={setNodeSwitcherOpen}
/>
</NetworkLoader>
</Suspense>
</TendermintWebsocketProvider>
);
}
+14
View File
@@ -3,6 +3,9 @@
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
import { locales } from '@vegaprotocol/i18n';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
Object.defineProperty(window, 'ResizeObserver', {
writable: false,
@@ -13,3 +16,14 @@ Object.defineProperty(window, 'ResizeObserver', {
disconnect: jest.fn(),
})),
});
// Set up i18n instance so that components have the correct default
// en translations
i18n.use(initReactI18next).init({
// we init with resources
resources: locales,
fallbackLng: 'en',
nsSeparator: false,
ns: ['explorer'],
defaultNS: 'explorer',
});
+1
View File
@@ -0,0 +1 @@
../../../../libs/i18n/src/locales
+45
View File
@@ -0,0 +1,45 @@
import type { Module } from 'i18next';
import i18n from 'i18next';
import HttpBackend from 'i18next-http-backend';
import LocizeBackend from 'i18next-locize-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
const isInDev = process.env.NODE_ENV === 'development';
const useLocize = isInDev && !!process.env.NX_USE_LOCIZE;
const backend = useLocize
? {
projectId: '96ac1231-4bdd-455a-b9d7-f5322a2e7430',
apiKey: process.env.NX_LOCIZE_API_KEY,
referenceLng: 'en',
}
: {
loadPath: '/assets/locales/{{lng}}/{{ns}}.json',
};
const Backend: Module = useLocize ? LocizeBackend : HttpBackend;
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
lng: 'en',
fallbackLng: 'en',
supportedLngs: ['en'],
load: 'languageOnly',
debug: isInDev,
// have a common namespace used around the full app
ns: ['explorer'],
defaultNS: 'explorer',
keySeparator: false, // we use content as keys
nsSeparator: false,
backend,
saveMissing: useLocize && !!process.env.NX_LOCIZE_API_KEY,
interpolation: {
escapeValue: false,
},
});
export default i18n;
@@ -133,7 +133,7 @@ export const proposalsData = {
instrument: {
name: 'UNIDAI Monthly (Dec 2022)',
code: 'UNIDAI.MF21',
futureProduct: {
product: {
settlementAsset: { symbol: 'tDAI', __typename: 'Asset' },
__typename: 'FutureProduct',
},
@@ -240,7 +240,7 @@ export const proposalsData = {
instrument: {
name: 'ETHBTC Quarterly (Feb 2023)',
code: 'ETHBTC.QM21',
futureProduct: {
product: {
settlementAsset: { symbol: 'tBTC', __typename: 'Asset' },
__typename: 'FutureProduct',
},
@@ -77,7 +77,7 @@ describe('Proposal header', () => {
__typename: 'InstrumentConfiguration',
name: 'Some market',
code: 'FX:BTCUSD/DEC99',
futureProduct: {
product: {
__typename: 'FutureProduct',
settlementAsset: {
__typename: 'Asset',
@@ -39,6 +39,18 @@ export const ProposalHeader = ({
const titleContent = shorten(title ?? '', 100);
const getAsset = (proposal: ProposalQuery['proposal']) => {
const terms = proposal?.terms;
if (
terms?.change.__typename === 'NewMarket' &&
(terms.change.instrument.product?.__typename === 'FutureProduct' ||
terms.change.instrument.product?.__typename === 'PerpetualProduct')
) {
return terms.change.instrument.product.settlementAsset;
}
return undefined;
};
switch (change?.__typename) {
case 'NewMarket': {
proposalType =
@@ -54,10 +66,10 @@ export const ProposalHeader = ({
<span>
{t('Code')}: {change.instrument.code}.
</span>{' '}
{change.instrument.futureProduct?.settlementAsset.symbol ? (
{proposal?.terms && getAsset(proposal)?.symbol ? (
<>
<span className="font-semibold">
{change.instrument.futureProduct.settlementAsset.symbol}
{getAsset(proposal)?.symbol}
</span>{' '}
{t('settled future')}.
</>
@@ -1,7 +1,7 @@
import {
getProposalDialogIcon,
getProposalDialogIntent,
getProposalDialogTitle,
useGetProposalDialogTitle,
} from '@vegaprotocol/proposals';
import type { ProposalEventFieldsFragment } from '@vegaprotocol/proposals';
import type { DialogProps } from '@vegaprotocol/proposals';
@@ -15,6 +15,7 @@ export const ProposalFormTransactionDialog = ({
finalizedProposal,
TransactionDialog,
}: ProposalFormTransactionDialogProps) => {
const title = useGetProposalDialogTitle(finalizedProposal?.state);
// Render a custom complete UI if the proposal was rejected otherwise
// pass undefined so that the default vega transaction dialog UI gets used
const completeContent = finalizedProposal?.rejectionReason ? (
@@ -24,7 +25,7 @@ export const ProposalFormTransactionDialog = ({
return (
<div data-testid="proposal-transaction-dialog">
<TransactionDialog
title={getProposalDialogTitle(finalizedProposal?.state)}
title={title}
intent={getProposalDialogIntent(finalizedProposal?.state)}
icon={getProposalDialogIcon(finalizedProposal?.state)}
content={{
@@ -8,7 +8,7 @@ import {
networkParamsQueryMock,
nextWeek,
} from '../../test-helpers/mocks';
import { VoteBreakdown } from './vote-breakdown';
import { CompactVotes, VoteBreakdown } from './vote-breakdown';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { MockedResponse } from '@apollo/client/testing';
import {
@@ -346,3 +346,22 @@ describe('VoteBreakdown', () => {
expect(style.width).toBe(`${expectedProgress}%`);
});
});
describe('CompactVotes', () => {
it.each([
[0, '0'],
[1, '1'],
[12, '12'],
[123, '123'],
[1234, '1.2K'],
[12345, '12.3K'],
[123456, '123.5K'],
[1234567, '1.2M'],
[12345678, '12.3M'],
[123456789, '123.5M'],
[1234567890, '1.2B'],
])('compacts %s to %s', (input, output) => {
const { getByTestId } = render(<CompactVotes number={BigNumber(input)} />);
expect(getByTestId('compact-number').textContent).toBe(output);
});
});
@@ -3,11 +3,21 @@ import BigNumber from 'bignumber.js';
import { useTranslation } from 'react-i18next';
import { useVoteInformation } from '../../hooks';
import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit';
import { formatNumber, toBigNum } from '@vegaprotocol/utils';
import { formatNumber } from '@vegaprotocol/utils';
import { ProposalState } from '@vegaprotocol/types';
import type { ReactNode } from 'react';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { CompactNumber } from '@vegaprotocol/react-helpers';
export const CompactVotes = ({ number }: { number: BigNumber }) => (
<CompactNumber
number={number}
decimals={number.isGreaterThan(1000) ? 1 : 0}
compactAbove={1000}
compactDisplay="short"
/>
);
interface VoteBreakdownProps {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
@@ -198,10 +208,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
)}
>
<button>
{yesEquityLikeShareWeight
.dividedBy(toBigNum(10 ** 6, 0))
.toFixed(1)}
M
<CompactVotes number={yesEquityLikeShareWeight} />
</button>
</Tooltip>
<span>
@@ -226,10 +233,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
)}
>
<button>
{noEquityLikeShareWeight
.dividedBy(toBigNum(10 ** 6, 0))
.toFixed(1)}
M
<CompactVotes number={noEquityLikeShareWeight} />
</button>
</Tooltip>
<span>
@@ -279,10 +283,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
)}
>
<button>
{totalEquityLikeShareWeight
.dividedBy(toBigNum(10 ** 6, 0))
.toFixed(1)}
M
<CompactVotes number={totalEquityLikeShareWeight} />
</button>
</Tooltip>
<span>
@@ -321,7 +322,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
<span>{t('tokenVotesFor')}:</span>
<Tooltip description={formatNumber(yesTokens, defaultDP)}>
<button data-testid="num-votes-for">
{yesTokens.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
<CompactVotes number={yesTokens} />
</button>
</Tooltip>
<span>
@@ -341,7 +342,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
<span>{t('tokenVotesAgainst')}:</span>
<Tooltip description={formatNumber(noTokens, defaultDP)}>
<button data-testid="num-votes-against">
{noTokens.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
<CompactVotes number={noTokens} />
</button>
</Tooltip>
<span>
@@ -384,7 +385,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
<span>{t('totalTokensVoted')}:</span>
<Tooltip description={formatNumber(totalTokensVoted, defaultDP)}>
<button data-testid="total-voted">
{totalTokensVoted.dividedBy(toBigNum(10 ** 6, 0)).toFixed(1)}M
<CompactVotes number={totalTokensVoted} />
</button>
</Tooltip>
<span data-testid="total-voted-percentage">
@@ -130,46 +130,25 @@ query Proposal(
instrument {
name
code
futureProduct {
settlementAsset {
id
name
symbol
decimals
quantum
}
quoteName
dataSourceSpecForSettlementData {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
operator
value
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
product {
... on FutureProduct {
settlementAsset {
id
name
symbol
decimals
quantum
}
quoteName
dataSourceSpecBinding {
settlementDataProperty
tradingTerminationProperty
}
dataSourceSpecForSettlementData {
sourceType {
... on DataSourceDefinitionInternal {
sourceType {
... on DataSourceSpecConfigurationTime {
conditions {
operator
value
@@ -177,52 +156,44 @@ query Proposal(
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
conditions {
operator
value
}
}
}
}
}
}
}
}
# dataSourceSpecForTradingTermination {
# sourceType {
# ... on DataSourceDefinitionInternal {
# sourceType {
# ... on DataSourceSpecConfigurationTime {
# conditions {
# operator
# value
# }
# }
# }
# }
# ... on DataSourceDefinitionExternal {
# sourceType {
# ... on DataSourceSpecConfiguration {
# signers {
# signer {
# ... on PubKey {
# key
# }
# ... on ETHAddress {
# address
# }
# }
# }
# filters {
# key {
# name
# type
# }
# conditions {
# operator
# value
# }
# }
# }
# }
# }
# }
# }
dataSourceSpecBinding {
settlementDataProperty
tradingTerminationProperty
... on PerpetualProduct {
settlementAsset {
id
name
symbol
decimals
quantum
}
quoteName
}
}
}
File diff suppressed because one or more lines are too long
@@ -101,9 +101,16 @@ fragment ProposalFields on Proposal {
instrument {
name
code
futureProduct {
settlementAsset {
symbol
product {
... on FutureProduct {
settlementAsset {
symbol
}
}
... on PerpetualProduct {
settlementAsset {
symbol
}
}
}
}
@@ -11,7 +11,7 @@ export type UpdateReferralProgramsFragment = { __typename?: 'Proposal', terms: {
export type UpdateVolumeDiscountProgramsFragment = { __typename?: 'Proposal', terms: { __typename?: 'ProposalTerms', change: { __typename?: 'CancelTransfer' } | { __typename?: 'NewAsset' } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket' } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset' } | { __typename?: 'UpdateMarket' } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter' } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } } };
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } };
export type ProposalFieldsFragment = { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, product?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename?: 'PerpetualProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename?: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState' } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram' } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram' } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } };
export type ProposalsQueryVariables = Types.Exact<{
includeNewMarketProductFields: Types.Scalars['Boolean'];
@@ -20,7 +20,7 @@ export type ProposalsQueryVariables = Types.Exact<{
}>;
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, futureProduct?: { __typename?: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | null, product?: { __typename: 'FutureProduct' } | { __typename: 'PerpetualProduct' } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', windowLength: number, endOfProgram: any, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
export type ProposalsQuery = { __typename?: 'Query', proposalsConnection?: { __typename?: 'ProposalsConnection', edges?: Array<{ __typename?: 'ProposalEdge', node: { __typename?: 'Proposal', id?: string | null, reference: string, state: Types.ProposalState, datetime: any, rejectionReason?: Types.ProposalRejectionReason | null, errorDetails?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string }, party: { __typename?: 'Party', id: string }, terms: { __typename?: 'ProposalTerms', closingDatetime: any, enactmentDatetime?: any | null, change: { __typename?: 'CancelTransfer' } | { __typename: 'NewAsset', name: string, symbol: string, decimals: number, quantum: string, source: { __typename?: 'BuiltinAsset', maxFaucetAmountMint: string } | { __typename?: 'ERC20', contractAddress: string, withdrawThreshold: string, lifetimeLimit: string } } | { __typename?: 'NewFreeform' } | { __typename?: 'NewMarket', instrument: { __typename?: 'InstrumentConfiguration', name: string, code: string, product?: { __typename: 'FutureProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename: 'PerpetualProduct', settlementAsset: { __typename?: 'Asset', symbol: string } } | { __typename: 'SpotProduct' } | null } } | { __typename?: 'NewSpotMarket' } | { __typename?: 'NewTransfer' } | { __typename?: 'UpdateAsset', quantum: string, assetId: string, source: { __typename?: 'UpdateERC20', lifetimeLimit: string, withdrawThreshold: string } } | { __typename?: 'UpdateMarket', marketId: string } | { __typename?: 'UpdateMarketState', updateType: Types.MarketUpdateType, price?: string | null, market: { __typename?: 'Market', decimalPlaces: number, id: string, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', name: string, code: string, product: { __typename: 'Future', quoteName: string } | { __typename: 'Perpetual', quoteName: string } | { __typename: 'Spot' } } } } } | { __typename?: 'UpdateNetworkParameter', networkParameter: { __typename?: 'NetworkParameter', key: string, value: string } } | { __typename?: 'UpdateReferralProgram', windowLength: number, endOfProgram: any, benefitTiers: Array<{ __typename?: 'BenefitTier', minimumEpochs: number, minimumRunningNotionalTakerVolume: string, referralDiscountFactor: string, referralRewardFactor: string }>, stakingTiers: Array<{ __typename?: 'StakingTier', minimumStakedTokens: string, referralRewardMultiplier: string }> } | { __typename?: 'UpdateSpotMarket' } | { __typename?: 'UpdateVolumeDiscountProgram', endOfProgramTimestamp: any, windowLength: number, benefitTiers: Array<{ __typename?: 'VolumeBenefitTier', minimumRunningNotionalTakerVolume: string, volumeDiscountFactor: string }> } }, votes: { __typename?: 'ProposalVotes', yes: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string }, no: { __typename?: 'ProposalVoteSide', totalTokens: string, totalNumber: string, totalEquityLikeShareWeight: string } } } } | null> | null } | null };
export const NewMarketProductFieldsFragmentDoc = gql`
fragment NewMarketProductFields on Proposal {
@@ -130,9 +130,16 @@ export const ProposalFieldsFragmentDoc = gql`
instrument {
name
code
futureProduct {
settlementAsset {
symbol
product {
... on FutureProduct {
settlementAsset {
symbol
}
}
... on PerpetualProduct {
settlementAsset {
symbol
}
}
}
}
@@ -8,7 +8,7 @@ import {
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useValidateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -41,6 +41,7 @@ export interface NewAssetProposalFormFields {
const DOCS_LINK = '/new-asset-proposal';
export const ProposeNewAsset = () => {
const validateJson = useValidateJson();
const {
params,
loading: networkParamsLoading,
@@ -7,7 +7,7 @@ import {
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useValidateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -39,6 +39,7 @@ export interface NewMarketProposalFormFields {
const DOCS_LINK = '/new-market-proposal';
export const ProposeNewMarket = () => {
const validateJson = useValidateJson();
const {
params,
loading: networkParamsLoading,
@@ -14,7 +14,7 @@ import {
RoundedWrapper,
TextArea,
} from '@vegaprotocol/ui-toolkit';
import { validateJson } from '@vegaprotocol/utils';
import { useValidateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -31,6 +31,7 @@ export interface RawProposalFormFields {
}
export const ProposeRaw = () => {
const validateJson = useValidateJson();
const {
params,
loading: networkParamsLoading,
@@ -7,7 +7,7 @@ import {
doesValueEquateToParam,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useValidateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -39,6 +39,7 @@ export interface UpdateAssetProposalFormFields {
const DOCS_LINK = '/update-asset-proposal';
export const ProposeUpdateAsset = () => {
const validateJson = useValidateJson();
const {
params,
loading: networkParamsLoading,
@@ -8,7 +8,7 @@ import {
useProposalSubmit,
} from '@vegaprotocol/proposals';
import { useEnvironment, DocsLinks } from '@vegaprotocol/environment';
import { validateJson } from '@vegaprotocol/utils';
import { useValidateJson } from '@vegaprotocol/utils';
import {
NetworkParams,
useNetworkParams,
@@ -53,6 +53,7 @@ export interface UpdateMarketProposalFormFields {
const DOCS_LINK = '/update-market-proposal';
export const ProposeUpdateMarket = () => {
const validateJson = useValidateJson();
const {
params,
loading: networkParamsLoading,
@@ -260,7 +261,7 @@ export const ProposeUpdateMarket = () => {
</FormGroup>
{selectedMarket && (
<div className="mt-[-20px] mb-6">
<div className="mb-6 mt-[-20px]">
<KeyValueTable data-testid="update-market-details">
<KeyValueTableRow>
{t('MarketName')}
@@ -1,204 +0,0 @@
const marketInfoBtn = 'Info';
const marketInfoSubtitle = 'accordion-title';
const marketSummaryBlock = 'header-summary';
const marketExpiry = 'market-expiry';
const marketPrice = 'market-price';
const marketChange = 'market-change';
const marketVolume = 'market-volume';
const marketMode = 'market-trading-mode';
const marketSettlement = 'market-settlement-asset';
const percentageValue = 'price-change-percentage';
const priceChangeValue = 'price-change';
const itemHeader = 'item-header';
const itemValue = 'item-value';
const marketListContent = 'popover-content';
describe(
'Console - market info - live env',
{ tags: '@live', testIsolation: true },
() => {
before(() => {
cy.visit('/');
cy.contains('Loading market data...').should('not.exist');
cy.getByTestId('link').should('be.visible');
cy.getByTestId('dialog-close').click();
cy.getByTestId(marketInfoBtn).click();
});
const titles = ['Market data', 'Market specification', 'Market governance'];
const subtitles = [
'Current fees',
'Market price',
'Market volume',
'Insurance pool',
'Key details',
'Instrument',
'Settlement asset',
'Metadata',
'Risk model',
'Risk parameters',
'Risk factors',
'Price monitoring bounds 1',
'Liquidity monitoring parameters',
'Liquidity',
'Liquidity price range',
'Oracle',
'Proposal',
];
it('market info titles are displayed', () => {
cy.getByTestId('split-view-view')
.find('.text-lg')
.each((element, index) => {
cy.wrap(element).should('have.text', titles[index]);
});
});
it('market info subtitles are displayed', () => {
cy.getByTestId('popover-trigger').click();
cy.contains('Loading market data...').should('not.exist');
cy.contains('[data-testid="link"]', 'AAVEDAI.MF21').click();
cy.getByTestId(marketInfoBtn).click();
cy.getByTestId(marketInfoSubtitle).each((element, index) => {
cy.wrap(element).should('have.text', subtitles[index]);
});
});
it('renders correctly liquidity in trading tab', () => {
cy.getByTestId('Liquidity').click();
cy.contains('Loading').should('not.exist');
cy.contains('Something went wrong').should('not.exist');
cy.contains('Application error').should('not.exist');
cy.getByTestId('tab-liquidity').within(() => {
cy.get('[col-id="partyId"]').eq(1).should('not.be.empty');
});
});
}
);
describe(
'Console - market summary - live env',
{ tags: '@live', testIsolation: true },
() => {
before(() => {
cy.visit('/');
cy.getByTestId('dialog-close').click();
cy.getByTestId(marketSummaryBlock).should('be.visible');
});
it('must display market name', () => {
cy.getByTestId('popover-trigger').should('not.be.empty');
});
it('must see market expiry', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketExpiry).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Expiry');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
it('must see market price', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketPrice).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Price');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
it('must see market change', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketChange).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Change (24h)');
cy.getByTestId(percentageValue).should('not.be.empty');
cy.getByTestId(priceChangeValue).should('not.be.empty');
});
});
});
it('must see market volume', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketVolume).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Volume (24h)');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
it('must see market mode', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketMode).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Trading mode');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
it('must see market settlement', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketSettlement).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Settlement asset');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
}
);
describe(
'Console - markets table - live env',
{ tags: '@live', testIsolation: true },
() => {
beforeEach(() => {
cy.visit('/');
});
it('renders markets correctly', () => {
cy.get('[data-testid^="market-link-"]').should('not.be.empty');
cy.getByTestId('price').invoke('text').should('not.be.empty');
cy.getByTestId('settlement-asset').should('not.be.empty');
cy.getByTestId('price-change-percentage').should('not.be.empty');
cy.getByTestId('price-change').should('not.be.empty');
cy.getByTestId('sparkline-svg').should('be.visible');
});
it('renders market list drop down', () => {
openMarketDropDown();
cy.getByTestId(marketListContent)
.find('[data-testid="price"]')
.invoke('text')
.should('not.be.empty');
cy.getByTestId(marketListContent)
.find('[data-testid="trading-mode-col"]')
.should('not.be.empty');
cy.getByTestId(marketListContent)
.find('[data-testid="taker-fee"]')
.should('contain.text', '%');
cy.getByTestId(marketListContent)
.find('[data-testid="market-volume"]')
.should('not.be.empty');
cy.getByTestId(marketListContent)
.find('[data-testid="market-name"]')
.should('not.be.empty');
});
it('Able to select market from dropdown', () => {
cy.getByTestId('popover-trigger')
.invoke('text')
.then((marketName) => {
openMarketDropDown();
cy.get('[data-testid^=market-link]').eq(1).click();
cy.getByTestId('popover-trigger').should('not.be.equal', marketName);
});
});
}
);
function openMarketDropDown() {
cy.contains('Loading...').should('not.exist');
cy.getByTestId('link').should('be.visible');
cy.getByTestId('dialog-close').click();
cy.getByTestId('popover-trigger').click();
cy.contains('Loading market data...').should('not.exist');
}
@@ -1,311 +0,0 @@
import { checkSorting } from '@vegaprotocol/cypress';
import * as Schema from '@vegaprotocol/types';
const liquidityTab = 'Liquidity';
const rowSelector =
'[data-testid="tab-liquidity"] .ag-center-cols-container .ag-row';
const rowSelectorLiquidityActive =
'[data-testid="tab-active"] .ag-center-cols-container .ag-row';
const rowSelectorLiquidityInactive =
'[data-testid="tab-inactive"] .ag-center-cols-container .ag-row';
const marketSummaryBlock = 'header-summary';
const itemValue = 'item-value';
const itemHeader = 'item-header';
const colCommitmentAmount = '[col-id="commitmentAmount"]';
const colEquityLikeShare = '[col-id="feeShare.equityLikeShare"]';
const colFee = '[col-id="fee"]';
const colCommitmentAmount_1 = '[col-id="commitmentAmount_1"]';
const colBalance = '[col-id="balance"]';
const colStatus = '[col-id="status"]';
const colCreatedAt = '[col-id="createdAt"] button';
const colUpdatedAt = '[col-id="updatedAt"] button';
const headers = [
'Party',
'Status',
'Commitment (tDAI)',
'Obligation',
'Fee',
'Adjusted stake share',
'Share',
'Live supplied liquidity',
'Fees accrued this epoch',
'Live time on book',
'Live liquidity quality score (%)',
'Last time on the book',
'Last fee penalty',
'Last bond penalty',
'Created',
'Updated',
];
describe('liquidity table - trading', { tags: '@smoke' }, () => {
before(() => {
cy.setOnBoardingViewed();
cy.mockSubscription();
cy.mockTradingPage(
Schema.MarketState.STATE_ACTIVE,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET
);
cy.visit('/#/markets/market-0');
cy.wait('@MarketData');
cy.getByTestId(liquidityTab).click();
cy.wait('@LiquidityProvisions');
});
it('can see table headers', () => {
// 5002-LIQP-001
cy.getByTestId('tab-liquidity').within(($headers) => {
cy.wrap($headers)
.get('.ag-header-cell-text')
.each(($header, i) => {
cy.wrap($header).should('have.text', headers[i]);
});
});
});
it('renders liquidity table correctly', () => {
// 5002-LIQP-002
cy.get(rowSelector)
.first()
.find('[col-id="partyId"]')
.should('have.text', '69464e…dc6f');
cy.get(rowSelector)
.first()
.find(colCommitmentAmount)
.should('have.text', '4,000.00');
cy.get(rowSelector)
.first()
.find(colEquityLikeShare)
.should('have.text', '100.00%');
cy.get(rowSelector).first().find(colFee).should('have.text', '0.09%');
cy.get(rowSelector)
.first()
.find(colCommitmentAmount_1)
.should('have.text', '4,000.00');
cy.get(rowSelector)
.first()
.find(colBalance)
.scrollIntoView()
.should('have.text', '4,000.00');
cy.get(rowSelector).first().find(colStatus).should('have.text', 'Active');
cy.get(rowSelector).first().find(colCreatedAt).should('not.be.empty');
cy.get(rowSelector).first().find(colUpdatedAt).should('not.be.empty');
});
it('liquidity status column should be sorted properly', () => {
// 5002-LIQP-003
const liquidityColDefault = ['Active', 'Pending'];
const liquidityColAsc = ['Active', 'Pending'];
const liquidityColDesc = ['Pending', 'Active'];
checkSorting(
'status',
liquidityColDefault,
liquidityColAsc,
liquidityColDesc
);
});
});
describe('liquidity table view', { tags: '@smoke' }, () => {
before(() => {
cy.setOnBoardingViewed();
cy.mockSubscription();
cy.mockTradingPage(
Schema.MarketState.STATE_ACTIVE,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET
);
cy.visit('/#/liquidity/market-0');
cy.wait('@LiquidityProvisions');
});
it('can see header title', () => {
// 5002-LIQP-004
// 5002-LIQP-005
cy.getByTestId('header-title').should(
'contain.text',
'BTCUSD.MF21 liquidity provision'
);
});
it('can see target stake', () => {
// 5002-LIQP-006
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId('target-stake').within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Target stake');
cy.getByTestId(itemValue).should('have.text', '10.00 tDAI').realHover();
});
});
cy.getByTestId('tooltip-content').should(
'contain.text',
`The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.`
);
});
it('can see supplied stake', () => {
// 5002-LIQP-007
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId('supplied-stake').within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Supplied stake');
cy.getByTestId(itemValue).should('have.text', '0.01 tDAI').realHover();
});
});
cy.getByTestId('tooltip-content').should(
'contain.text',
'The current amount of liquidity supplied for this market.'
);
});
it('can see liquidity supplied', () => {
// 5002-LIQP-008
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId('liquidity-supplied').within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Liquidity supplied');
cy.getByTestId('indicator').should('be.visible');
cy.getByTestId(itemValue).should('have.text', ' 0.10%').realHover();
});
});
});
it('can see market id', () => {
// 5002-LIQP-009
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId('liquidity-market-id').within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Market ID');
cy.getByTestId(itemValue).should('have.text', 'market-0');
});
});
});
it('can see market id', () => {
// 5002-LIQP-010
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId('liquidity-learn-more').within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Learn more');
cy.getByTestId(itemValue).should('have.text', 'Providing liquidity');
cy.getByTestId('external-link')
.should('have.attr', 'href')
.and(
'include',
'https://docs.vega.xyz/testnet/concepts/liquidity/provision'
);
});
});
});
describe('liquidity table view', { tags: '@smoke' }, () => {
it('can see table headers', () => {
cy.getByTestId('tab-active').within(($headers) => {
cy.wrap($headers)
.get('.ag-header-cell-text')
.each(($header, i) => {
cy.wrap($header).should('have.text', headers[i]);
});
});
});
it('renders liquidity active table correctly', () => {
// 5002-LIQP-011
cy.get(rowSelectorLiquidityActive)
.first()
.find('[col-id="partyId"]')
.should('have.text', '69464e…dc6f');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colCommitmentAmount)
.should('have.text', '4,000.00');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colEquityLikeShare)
.should('have.text', '100.00%');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colFee)
.should('have.text', '0.09%');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colCommitmentAmount_1)
.should('have.text', '4,000.00');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colBalance)
.should('have.text', '4,000.00');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colStatus)
.should('have.text', 'Active');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colCreatedAt)
.should('not.be.empty');
cy.get(rowSelectorLiquidityActive)
.first()
.find(colUpdatedAt)
.should('not.be.empty');
});
it('renders liquidity inactive table correctly', () => {
// 5002-LIQP-012
cy.getByTestId('Inactive').click();
cy.get(rowSelectorLiquidityInactive)
.first()
.find('[col-id="partyId"]')
.should('have.text', 'cc464e…dc6f');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colCommitmentAmount)
.should('have.text', '4,000.00');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colEquityLikeShare)
.should('have.text', '100.00%');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colFee)
.should('have.text', '0.40%');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colCommitmentAmount_1)
.should('have.text', '4,000.00');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colBalance)
.should('have.text', '2,000.00');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colStatus)
.should('have.text', 'Pending');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colCreatedAt)
.should('not.be.empty');
cy.get(rowSelectorLiquidityInactive)
.first()
.find(colUpdatedAt)
.should('not.be.empty');
});
});
});
@@ -1,47 +0,0 @@
import { aliasGQLQuery } from '@vegaprotocol/cypress';
import { proposalListQuery, marketUpdateProposal } from '@vegaprotocol/mock';
import * as Schema from '@vegaprotocol/types';
const marketSummaryBlock = 'header-summary';
describe('Market proposal notification', { tags: '@smoke' }, () => {
before(() => {
cy.setVegaWallet();
cy.mockTradingPage(
Schema.MarketState.STATE_ACTIVE,
Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY_TARGET_NOT_MET
);
cy.mockGQL((req) => {
aliasGQLQuery(
req,
'ProposalsList',
proposalListQuery({
proposalsConnection: {
edges: [{ node: marketUpdateProposal }],
},
})
);
});
cy.mockSubscription();
cy.visit('/#/markets/market-0');
cy.wait('@MarketData');
cy.getByTestId(marketSummaryBlock).should('be.visible');
});
it('should display market proposal notification if proposal found', () => {
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId('market-proposal-notification').should(
'contain.text',
'Changes have been proposed for this market'
);
cy.getByTestId('market-proposal-notification').within(() => {
cy.getByTestId('external-link').should(
'have.attr',
'href',
`${Cypress.env('VEGA_TOKEN_URL')}/proposals/123`
);
});
});
});
});
@@ -14,7 +14,6 @@ const marketMode = 'market-trading-mode';
const marketName = 'header-title';
const marketPrice = 'market-price';
const marketSettlement = 'market-settlement-asset';
const marketState = 'market-state';
const marketSummaryBlock = 'header-summary';
const marketVolume = 'market-volume';
const percentageValue = 'price-change-percentage';
@@ -85,30 +84,6 @@ describe('Market trading page', () => {
});
});
it('must see market mode', () => {
// 6002-MDET-006
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketMode).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Trading mode');
cy.getByTestId(itemValue).should(
'have.text',
'Monitoring auction - liquidity (target not met)'
);
});
});
});
it('must see market status', () => {
// 6002-MDET-007
// 7002-SORD-061
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(marketState).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Status');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
it('must see market settlement', () => {
// 6002-MDET-008
cy.getByTestId(marketSummaryBlock).within(() => {
@@ -118,15 +93,6 @@ describe('Market trading page', () => {
});
});
});
it('must see market liquidity supplied', () => {
// 6002-MDET-009
cy.getByTestId(marketSummaryBlock).within(() => {
cy.getByTestId(liquiditySupplied).within(() => {
cy.getByTestId(itemHeader).should('have.text', 'Liquidity supplied');
cy.getByTestId(itemValue).should('not.be.empty');
});
});
});
});
describe('Market tooltips', { tags: '@smoke' }, () => {
+1 -1
View File
@@ -114,7 +114,7 @@ export const MarketPage = () => {
</p>
<p className="justify-center text-sm">
<Trans
defaults="Please choose another market from the <0>market list<0>"
defaults="Please choose another market from the <0>market list</0>"
ns={ns}
components={[
<ExternalLink
@@ -1,7 +1,14 @@
import type { TypedDataAgGrid } from '@vegaprotocol/datagrid';
import { AgGrid, PriceFlashCell } from '@vegaprotocol/datagrid';
import {
AgGrid,
PriceFlashCell,
useDataGridEvents,
} from '@vegaprotocol/datagrid';
import type { MarketMaybeWithData } from '@vegaprotocol/markets';
import { useColumnDefs } from './use-column-defs';
import type { DataGridStore } from '../../stores/datagrid-store-slice';
import { type StateCreator, create } from 'zustand';
import { persist } from 'zustand/middleware';
export const getRowId = ({ data }: { data: { id: string } }) => data.id;
@@ -18,8 +25,37 @@ const components = {
type Props = TypedDataAgGrid<MarketMaybeWithData>;
export type DataGridSlice = {
gridStore: DataGridStore;
updateGridStore: (gridStore: DataGridStore) => void;
};
export const createDataGridSlice: StateCreator<DataGridSlice> = (set) => ({
gridStore: {},
updateGridStore: (newStore) => {
set((curr) => ({
gridStore: {
...curr.gridStore,
...newStore,
},
}));
},
});
const useMarketsStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_market_list_store',
})
);
export const MarketListTable = (props: Props) => {
const columnDefs = useColumnDefs();
const gridStore = useMarketsStore((store) => store.gridStore);
const updateGridStore = useMarketsStore((store) => store.updateGridStore);
const gridStoreCallbacks = useDataGridEvents(gridStore, (colState) => {
updateGridStore(colState);
});
return (
<AgGrid
@@ -28,6 +64,7 @@ export const MarketListTable = (props: Props) => {
columnDefs={columnDefs}
components={components}
rowHeight={45}
{...gridStoreCallbacks}
{...props}
/>
);
@@ -1,6 +1,4 @@
import { Route, Routes, useParams } from 'react-router-dom';
import { MarketState } from '@vegaprotocol/types';
import { useMarket } from '@vegaprotocol/markets';
import { Route, Routes } from 'react-router-dom';
import { VegaIconNames } from '@vegaprotocol/ui-toolkit';
import {
SidebarButton,
@@ -12,12 +10,7 @@ import { useT } from '../../lib/use-t';
export const MarketsSidebar = () => {
const t = useT();
const { marketId } = useParams();
const currentRouteId = useGetCurrentRouteId();
const { data } = useMarket(marketId);
const active =
data &&
[MarketState.STATE_ACTIVE, MarketState.STATE_PENDING].includes(data.state);
return (
<>
@@ -45,14 +38,12 @@ export const MarketsSidebar = () => {
element={
<>
<SidebarDivider />
{active && (
<SidebarButton
view={ViewType.Order}
icon={VegaIconNames.TICKET}
tooltip={t('Order')}
routeId={currentRouteId}
/>
)}
<SidebarButton
view={ViewType.Order}
icon={VegaIconNames.TICKET}
tooltip={t('Order')}
routeId={currentRouteId}
/>
<SidebarButton
view={ViewType.Info}
icon={VegaIconNames.BREAKDOWN}
@@ -51,6 +51,29 @@ export const useColumnDefs = () => {
headerName: t('Description'),
field: 'tradableInstrument.instrument.name',
},
{
headerName: t('Settlement asset'),
field: 'tradableInstrument.instrument.product.settlementAsset.symbol',
cellRenderer: ({
data,
}: VegaICellRendererParams<
MarketMaybeWithData,
'tradableInstrument.instrument.product.settlementAsset.symbol'
>) => {
const value = data && getAsset(data);
return value ? (
<ButtonLink
onClick={(e) => {
openAssetDetailsDialog(value.id, e.target as HTMLElement);
}}
>
{value.symbol}
</ButtonLink>
) : (
''
);
},
},
{
headerName: t('Trading mode'),
field: 'tradingMode',
@@ -142,27 +165,21 @@ export const useColumnDefs = () => {
},
},
{
headerName: t('Settlement asset'),
field: 'tradableInstrument.instrument.product.settlementAsset.symbol',
cellRenderer: ({
headerName: t('Open Interest'),
field: 'data.openInterest',
type: 'rightAligned',
valueFormatter: ({
data,
}: VegaICellRendererParams<
}: VegaValueFormatterParams<
MarketMaybeWithData,
'tradableInstrument.instrument.product.settlementAsset.symbol'
>) => {
const value = data && getAsset(data);
return value ? (
<ButtonLink
onClick={(e) => {
openAssetDetailsDialog(value.id, e.target as HTMLElement);
}}
>
{value.symbol}
</ButtonLink>
) : (
''
);
},
'data.openInterest'
>) =>
data?.data?.openInterest === undefined
? '-'
: addDecimalsFormatNumber(
data?.data?.openInterest,
data?.positionDecimalPlaces
),
},
{
headerName: t('Spread'),
@@ -152,8 +152,8 @@ export const ApplyCodeForm = () => {
// show "code applied" message when successfully applied
if (status === 'successful') {
return (
<div className="w-1/2 mx-auto">
<h3 className="mb-5 text-xl text-center uppercase calt flex flex-row gap-2 justify-center items-center">
<div className="mx-auto w-1/2">
<h3 className="calt mb-5 flex flex-row items-center justify-center gap-2 text-center text-xl uppercase">
<span className="text-vega-green-500">
<VegaIcon name={VegaIconNames.TICK} size={20} />
</span>{' '}
@@ -205,15 +205,15 @@ export const ApplyCodeForm = () => {
return (
<>
<div className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg">
<h3 className="mb-4 text-2xl text-center calt">
<div className="bg-vega-clight-800 dark:bg-vega-cdark-800 mx-auto w-2/3 max-w-md rounded-lg p-8">
<h3 className="calt mb-4 text-center text-2xl">
{t('Apply a referral code')}
</h3>
<p className="mb-4 text-center text-base">
{t('Enter a referral code to get trading discounts.')}
</p>
<form
className={classNames('w-full flex flex-col gap-4', {
className={classNames('flex w-full flex-col gap-4', {
'animate-shake': Boolean(errors.code),
})}
onSubmit={handleSubmit(onSubmit)}
@@ -227,13 +227,13 @@ export const ApplyCodeForm = () => {
validate: (value) => validateCode(value, t),
})}
placeholder="Enter a code"
className="mb-2 bg-vega-clight-900 dark:bg-vega-cdark-700"
className="bg-vega-clight-900 dark:bg-vega-cdark-700 mb-2"
/>
</label>
<RainbowButton variant="border" {...getButtonProps()} />
</form>
{errors.code && (
<InputError className="break-words overflow-auto">
<InputError className="overflow-auto break-words">
{errors.code.message?.toString()}
</InputError>
)}
@@ -245,10 +245,10 @@ export const ApplyCodeForm = () => {
) : null}
{previewData ? (
<div className="mt-10">
<h2 className="text-2xl mb-5">
<h2 className="mb-5 text-2xl">
{t(
'You are joining the group shown, but will not have access to benefits until you have completed at least %s epochs.',
[nextBenefitTierEpochsValue.toString()]
'You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs.',
{ count: nextBenefitTierEpochsValue }
)}
</h2>
<Statistics data={previewData} program={program} as="referee" />
+26 -2
View File
@@ -8,6 +8,9 @@ import classNames from 'classnames';
import type { HTMLAttributes, ReactNode } from 'react';
import { Button } from './buttons';
import { useT } from '../../lib/use-t';
import { Routes } from '../../lib/links';
import { DApp, useLinks } from '@vegaprotocol/environment';
import truncate from 'lodash/truncate';
export const Tile = ({
className,
@@ -63,6 +66,10 @@ export const CodeTile = ({
className?: string;
}) => {
const t = useT();
const consoleLink = useLinks(DApp.Console);
const applyCodeLink = consoleLink(
`#${Routes.REFERRALS_APPLY_CODE}?code=${code}`
);
return (
<StatTile
title={t('Your referral code')}
@@ -89,10 +96,27 @@ export const CodeTile = ({
{code}
</div>
</Tooltip>
<CopyWithTooltip text={code}>
<CopyWithTooltip text={code} description={t('Copy referral code')}>
<Button className="text-sm no-underline !py-0 !px-0 h-fit !bg-transparent">
<span className="sr-only">{t('Copy')}</span>
<VegaIcon size={24} name={VegaIconNames.COPY} />
<VegaIcon size={20} name={VegaIconNames.COPY} />
</Button>
</CopyWithTooltip>
<CopyWithTooltip
text={applyCodeLink}
description={
<>
{t('Copy shareable apply code link')}
{': '}
<a className="text-vega-blue-500 underline" href={applyCodeLink}>
{truncate(applyCodeLink, { length: 32 })}
</a>
</>
}
>
<Button className="text-sm no-underline !py-0 !px-0 h-fit !bg-transparent">
<span className="sr-only">{t('Copy')}</span>
<VegaIcon size={20} name={VegaIconNames.OPEN_EXTERNAL} />
</Button>
</CopyWithTooltip>
</div>
@@ -1,7 +1,8 @@
import { t } from '@vegaprotocol/i18n';
import { useT } from '../../lib/use-t';
import { RewardsContainer } from '../../components/rewards-container';
export const Rewards = () => {
const t = useT();
return (
<div className="container mx-auto p-4">
<h1 className="px-4 pb-4 text-2xl">{t('Rewards')}</h1>
@@ -1,6 +1,6 @@
import {
getAsset,
tooltipMapping,
useTooltipMapping,
useMarket,
useStaticMarketData,
} from '@vegaprotocol/markets';
@@ -27,6 +27,7 @@ import { useT } from '../../lib/use-t';
export const LiquidityHeader = () => {
const t = useT();
const tooltipMapping = useTooltipMapping();
const { marketId } = useParams();
const { data: market } = useMarket(marketId);
const { data: marketData } = useStaticMarketData(marketId);
@@ -122,7 +123,7 @@ export const LiquidityHeader = () => {
<CopyWithTooltip text={marketId}>
<button
data-testid="copy-eth-oracle-address"
className="uppercase text-right"
className="text-right uppercase"
>
<span className="flex gap-1">
{truncateMiddle(marketId)}
@@ -1,7 +1,6 @@
import groupBy from 'lodash/groupBy';
import type { Account } from '@vegaprotocol/accounts';
import { useAccounts } from '@vegaprotocol/accounts';
import { t } from '@vegaprotocol/i18n';
import {
NetworkParams,
useNetworkParams,
@@ -31,8 +30,10 @@ import { addDecimalsFormatNumberQuantum } from '@vegaprotocol/utils';
import { ViewType, useSidebar } from '../sidebar';
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
import { RewardsHistoryContainer } from './rewards-history';
import { useT } from '../../lib/use-t';
export const RewardsContainer = () => {
const t = useT();
const { pubKey } = useVegaWallet();
const { params, loading: paramsLoading } = useNetworkParams([
NetworkParams.reward_asset,
@@ -121,7 +122,9 @@ export const RewardsContainer = () => {
return (
<Card
key={assetId}
title={t('%s Reward pot', asset.symbol)}
title={t('{{assetSymbol}} Reward pot', {
assetSymbol: asset.symbol,
})}
className="lg:col-span-3 xl:col-span-2"
loading={loading}
>
@@ -167,6 +170,7 @@ export const RewardPot = ({
assetId,
vestingBalancesSummary,
}: RewardPotProps) => {
const t = useT();
// TODO: Opening the sidebar for the first time works, but then clicking on redeem
// for a different asset does not update the form
const currentRouteId = useGetCurrentRouteId();
@@ -242,7 +246,9 @@ export const RewardPot = ({
<CardTable>
<tr>
<CardTableTH className="flex items-center gap-1">
{t(`Locked ${rewardAsset.symbol}`)}
{t('Locked {{assetSymbol}}', {
assetSymbol: rewardAsset.symbol,
})}
<VegaIcon name={VegaIconNames.LOCK} size={12} />
</CardTableTH>
<CardTableTD>
@@ -254,7 +260,11 @@ export const RewardPot = ({
</CardTableTD>
</tr>
<tr>
<CardTableTH>{t(`Vesting ${rewardAsset.symbol}`)}</CardTableTH>
<CardTableTH>
{t('Vesting {{assetSymbol}}', {
assetSymbol: rewardAsset.symbol,
})}
</CardTableTH>
<CardTableTD>
{addDecimalsFormatNumberQuantum(
totalVesting.toString(),
@@ -309,6 +319,7 @@ export const Vesting = ({
baseRate: string;
multiplier?: string;
}) => {
const t = useT();
const rate = new BigNumber(baseRate).times(multiplier);
const rateFormatted = formatPercentage(Number(rate));
const baseRateFormatted = formatPercentage(Number(baseRate));
@@ -341,6 +352,7 @@ export const Multipliers = ({
streakMultiplier?: string;
hoarderMultiplier?: string;
}) => {
const t = useT();
const combinedMultiplier = new BigNumber(streakMultiplier).times(
hoarderMultiplier
);
@@ -16,12 +16,12 @@ import {
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import {
useRewardsHistoryQuery,
type RewardsHistoryQuery,
} from './__generated__/Rewards';
import { useRewardsRowData } from './use-reward-row-data';
import { useT } from '../../lib/use-t';
export const RewardsHistoryContainer = ({
epoch,
@@ -140,6 +140,7 @@ export const RewardHistoryTable = ({
onEpochChange: (epochVariables: { from: number; to: number }) => void;
loading: boolean;
}) => {
const t = useT();
const [isParty, setIsParty] = useState(false);
const rowData = useRewardsRowData({
+1 -1
View File
@@ -1,2 +1,2 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
VEGA_VERSION=v0.73.4
VEGA_VERSION=v0.73.5
+1 -1
View File
@@ -1,2 +1,2 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:develop
VEGA_VERSION=v0.73.4
VEGA_VERSION=v0.73.5
+1 -1
View File
@@ -1,2 +1,2 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:main
VEGA_VERSION=v0.73.4
VEGA_VERSION=v0.73.5
+11 -1
View File
@@ -34,4 +34,14 @@ def next_epoch(vega: VegaServiceNull):
"Epoch not started after forwarding the duration of two epochs."
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
vega.wait_for_total_catchup()
def truncate_middle(market_id, start=6, end=4):
if len(market_id) < 11:
return market_id
return market_id[:start] + '\u2026' + market_id[-end:]
def change_keys(page: Page, vega:VegaServiceNull, key_name):
page.get_by_test_id("manage-vega-wallet").click()
page.get_by_test_id("key-" + vega.wallet.public_key(key_name)).click()
page.reload()
+1 -14
View File
@@ -1,26 +1,13 @@
from collections import namedtuple
from vega_sim.service import VegaService
from actions.vega import submit_multiple_orders, submit_order, submit_liquidity
from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET, wallets
import logging
logger = logging.getLogger()
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
mint_amount: float = 10e5
market_name = "BTC:DAI_2023"
def setup_simple_market(
vega: VegaService,
approve_proposal=True,
@@ -1,16 +1,9 @@
import pytest
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from actions.vega import submit_order
from actions.utils import wait_for_toast_confirmation
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
notional = "deal-ticket-fee-notional"
fees = "deal-ticket-fee-fees"
margin_required = "deal-ticket-fee-margin-required"
@@ -1,5 +1,4 @@
import pytest
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from actions.vega import submit_order
@@ -7,14 +6,6 @@ from datetime import datetime, timedelta
from conftest import init_vega
from fixtures.market import setup_continuous_market
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
stop_order_btn = "order-type-Stop"
stop_limit_order_btn = "order-type-StopLimit"
stop_market_order_btn = "order-type-StopMarket"
@@ -1,19 +1,11 @@
import pytest
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from actions.vega import submit_order
from conftest import init_vega
from fixtures.market import setup_continuous_market
from actions.utils import wait_for_toast_confirmation
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET, wallets
stop_order_btn = "order-type-Stop"
stop_limit_order_btn = "order-type-StopLimit"
@@ -1,7 +1,7 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from actions.utils import wait_for_toast_confirmation
from actions.utils import change_keys
from conftest import init_vega
from fixtures.market import setup_continuous_market
@@ -39,9 +39,7 @@ def test_should_display_info_and_button_for_deposit(continuous_market, vega: Veg
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
vega.create_key("key_empty")
page.get_by_test_id("manage-vega-wallet").click()
page.locator('[role="menuitemradio"]').nth(4).click()
page.reload()
change_keys(page, vega, "key_empty")
page.get_by_test_id(order_size).fill("200")
page.get_by_test_id(order_price).fill("20")
# 7002-SORD-060
@@ -4,8 +4,8 @@ import json
from vega_sim.service import VegaService
from fixtures.market import setup_simple_market
from conftest import init_vega
from collections import namedtuple
from actions.vega import submit_order
from wallet_config import MM_WALLET, TERMINATE_WALLET, wallets
import logging
logger = logging.getLogger()
@@ -74,16 +74,6 @@ class TestGetStarted:
page.reload()
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
mint_amount: float = 10e5
for wallet in wallets:
@@ -1,22 +1,10 @@
import pytest
from collections import namedtuple
from playwright.sync_api import expect, Page
from vega_sim.service import VegaService
from actions.vega import submit_order
from conftest import init_vega
from fixtures.market import setup_continuous_market
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
from wallet_config import MM_WALLET2
def hover_and_assert_tooltip(page: Page, element_text):
element = page.get_by_text(element_text)
@@ -52,7 +40,7 @@ class TestIcebergOrdersValidations:
vega.wait_fn(1)
vega.wait_for_total_catchup()
expect(page.get_by_test_id("toast-content")).to_have_text(
"Order filledYour transaction has been confirmed View in block explorerSubmit order - filledBTC:DAI_2023+3 @ 107.00 tDAI"
"Order filledYour transaction has been confirmedView in block explorerSubmit order - filledBTC:DAI_2023+3 @ 107.00 tDAI"
)
page.get_by_test_id("All").click()
expect(
@@ -3,7 +3,8 @@ from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from conftest import init_vega
from fixtures.market import setup_continuous_market
from actions.utils import next_epoch
from actions.utils import next_epoch, truncate_middle, change_keys
@pytest.fixture(scope="module")
def vega(request):
@@ -20,19 +21,28 @@ def continuous_market(vega):
def test_liquidity_provision_amendment(continuous_market, vega: VegaService, page: Page):
# TODO Refactor asserting the grid
page.goto(f"/#/liquidity/{continuous_market}")
page.get_by_test_id("manage-vega-wallet").click()
#TODO Rename "mm" to "marketMaker" so that we don't have to specify where to click when switching wallets
# Currently the default click will click the middle of the element which will click the copy wallet key button
page.locator('[role="menuitemradio"] >> .mr-2.uppercase').nth(1).click(position={ "x": 0, "y": 0}, force=True)
page.reload()
change_keys(page, vega, "market_maker")
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Active"
)
# 5002-LIQP-006
expect(page.get_by_test_id("target-stake")).to_have_text("Target stake5.82757 tDAI")
# 5002-LIQP-007
expect(page.get_by_test_id("supplied-stake")).to_have_text("Supplied stake10,000.00 tDAI")
# 5002-LIQP-008
expect(page.get_by_test_id("liquidity-supplied")).to_have_text("Liquidity supplied 171,598.11%")
expect(page.get_by_test_id("fees-paid")).to_have_text("Fees paid-")
# 5002-LIQP-009
expect(page.get_by_test_id("liquidity-market-id")).to_have_text("Market ID" + truncate_middle(continuous_market))
expect(page.get_by_test_id("liquidity-learn-more")).to_have_text("Learn moreProviding liquidity")
# 002-LIQP-010
expect(page.get_by_test_id("liquidity-learn-more").get_by_test_id("external-link")).to_have_attribute("href", "https://docs.vega.xyz/testnet/concepts/liquidity/provision")
vega.submit_simple_liquidity(
key_name="mm",
key_name="market_maker",
market_id=continuous_market,
commitment_amount=100,
commitment_amount=1,
fee=0.001,
is_amendment=True,
)
@@ -46,7 +56,30 @@ def test_liquidity_provision_amendment(continuous_market, vega: VegaService, pag
)
next_epoch(vega=vega)
page.reload()
expect(page.get_by_test_id("supplied-stake")).to_have_text("Supplied stake1.00001 tDAI")
expect(page.get_by_test_id("liquidity-supplied")).to_have_text("Liquidity supplied 17.16%")
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Active"
)
)
@pytest.mark.skip("Waiting for the ability to cancel LP")
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_liquidity_provision_inactive(continuous_market, vega: VegaService, page: Page):
# TODO Refactor asserting the grid
page.goto(f"/#/liquidity/{continuous_market}")
change_keys(page,vega, "market_maker")
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Active"
)
vega.submit_simple_liquidity(
key_name="market_maker",
market_id=continuous_market,
commitment_amount=0,
fee=0,
is_amendment=False,
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
+4 -14
View File
@@ -1,23 +1,12 @@
import pytest
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService, PeggedOrder
from vega_sim.service import VegaService
from actions.vega import submit_order
from wallet_config import MM_WALLET, MM_WALLET2
import logging
logger = logging.getLogger()
# Wallet Configurations
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
table_row_selector = (
'[data-testid="tab-open-markets"] .ag-center-cols-container .ag-row'
)
@@ -85,7 +74,7 @@ def test_price_monitoring(simple_market, vega: VegaService, page: Page):
time_in_force="TIME_IN_FORCE_GTC",
volume=99,
)
#6002-MDET-009
expect(
page.get_by_test_id(liquidity_supplied).get_by_test_id(item_value)
).to_have_text("0.00 (0.00%)")
@@ -203,6 +192,7 @@ def test_price_monitoring(simple_market, vega: VegaService, page: Page):
# commented out because we have an issue #4233
# expect(page.get_by_text("Opening auction")).to_be_hidden()
#6002-MDET-009
expect(
page.get_by_test_id(liquidity_supplied).get_by_test_id(item_value)
).to_have_text("50.00 (>100%)")
@@ -25,15 +25,15 @@ def test_table_headers(page: Page, create_markets):
headers = [
"Market",
"Description",
"Settlement asset",
"Trading mode",
"Status",
"Mark price",
"24h volume",
"Settlement asset",
"Open Interest",
"Spread",
"",
]
page.wait_for_selector('[data-testid="tab-open-markets"]', state="visible")
page_headers = (
page.get_by_test_id("tab-open-markets").locator(".ag-header-cell-text").all()
@@ -157,4 +157,4 @@ def test_drag_and_drop_column(page: Page, create_markets):
page.locator(col_instrument_code).drag_to(
page.locator('.ag-header-row [col-id="data.bestBidPrice"]')
)
expect(page.locator(col_instrument_code)).to_have_attribute("aria-colindex", "8")
expect(page.locator(col_instrument_code)).to_have_attribute("aria-colindex", "9")
@@ -1,24 +1,11 @@
from math import exp
import pytest
import vega_sim.api.governance as governance
import re
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from conftest import init_vega
from fixtures.market import setup_simple_market
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET, wallets
row_selector = '[data-testid="tab-proposed-markets"] .ag-center-cols-container .ag-row'
col_market_id = '[col-id="market"] [data-testid="stack-cell-primary"]'
@@ -29,7 +16,6 @@ def vega(request):
with init_vega(request) as vega:
yield vega
@pytest.fixture(scope="module")
def proposed_market(vega: VegaService):
# setup market without liquidity provided
@@ -54,7 +40,6 @@ def test_can_see_table_headers(proposed_market, page: Page):
"Settlement asset",
"State",
"Parent market",
"Voting",
"Closing date",
"Enactment date",
"",
@@ -83,10 +68,6 @@ def test_renders_markets_correctly(proposed_market, page: Page):
row.locator('[col-id="terms.change.successorConfiguration.parentMarketId"]')
).to_have_text("-")
# 6001-MARK-054
# 6001-MARK-055
expect(row.get_by_test_id("vote-progress-bar-against")).to_be_visible()
# 6001-MARK-056
expect(row.locator('[col-id="closing-date"]')).not_to_be_empty()
@@ -124,8 +105,8 @@ def test_can_drag_and_drop_columns(proposed_market, page: Page):
page.goto("/#/markets/all")
page.click('[data-testid="Proposed markets"]')
col_market = page.locator('[col-id="market"]').first
col_vote = page.locator('[col-id="voting"]').first
col_market.drag_to(col_vote)
col_state = page.locator('[col-id="state"]').first
col_market.drag_to(col_state)
# Check the attribute of the dragged element
attribute_value = col_market.get_attribute("aria-colindex")
@@ -1,23 +1,11 @@
import pytest
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from actions.vega import submit_order
from fixtures.market import setup_simple_market
from conftest import init_vega
from actions.utils import wait_for_toast_confirmation
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET]
from wallet_config import MM_WALLET, MM_WALLET2
@pytest.fixture(scope="module")
def vega(request):
@@ -1,27 +1,11 @@
import pytest
import vega_sim.api.governance as governance
import re
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService, PeggedOrder
import vega_sim.proto.vega as vega_protos
import vega_sim.api.governance as governance
from actions.vega import submit_order
from fixtures.market import setup_continuous_market
from datetime import datetime
from datetime import timedelta
from vega_sim.service import MarketStateUpdateType
from wallet_config import MM_WALLET, MM_WALLET2, GOVERNANCE_WALLET
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
GOVERNANCE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, GOVERNANCE_WALLET]
@pytest.mark.usefixtures("vega", "page", "proposed_market", "risk_accepted")
@@ -36,6 +20,9 @@ def test_market_lifecycle(proposed_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{market_id}")
# check that market is in proposed state
# 6002-MDET-006
# 6002-MDET-007
# 7002-SORD-061
expect(trading_mode).to_have_text("No trading")
expect(market_state).to_have_text("Proposed")
@@ -135,7 +122,7 @@ def test_market_closing_banners(page: Page, continuous_market, vega: VegaService
page.goto(f"/#/markets/{market_id}")
proposalID = vega.update_market_state(
continuous_market,
"mm",
"market_maker",
MarketStateUpdateType.Terminate,
approve_proposal=False,
vote_enactment_time = datetime.now() + timedelta(weeks=1),
@@ -148,7 +135,7 @@ def test_market_closing_banners(page: Page, continuous_market, vega: VegaService
vega.update_market_state(
continuous_market,
"mm",
"market_maker",
MarketStateUpdateType.Terminate,
approve_proposal=False,
vote_enactment_time = datetime.now() + timedelta(weeks=1),
@@ -161,7 +148,7 @@ def test_market_closing_banners(page: Page, continuous_market, vega: VegaService
governance.approve_proposal(
proposal_id=proposalID,
wallet=vega.wallet,
key_name="mm"
key_name="market_maker"
)
vega.forward("60s")
@@ -1,19 +1,10 @@
import pytest
from collections import namedtuple
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from typing import List
from actions.vega import submit_order, submit_liquidity, submit_multiple_orders
from conftest import init_vega
from fixtures.market import setup_simple_market
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("mm", "pin")
MM_WALLET2 = WalletConfig("mm2", "pin2")
from wallet_config import MM_WALLET, MM_WALLET2
@pytest.fixture(scope="module")
def vega():
+7 -9
View File
@@ -2,6 +2,7 @@ import pytest
from playwright.sync_api import Page
from vega_sim.service import VegaService
from actions.vega import submit_order
from actions.utils import change_keys
def check_pnl_color_value(element, expected_color, expected_value):
color = element.evaluate("element => getComputedStyle(element).color")
@@ -29,18 +30,16 @@ def test_pnl(continuous_market, vega: VegaService, page: Page):
check_pnl_color_value(unrealised_pnl, "rgb(236, 0, 60)", "-4.00")
# profit Trading unrealised
page.get_by_test_id("manage-vega-wallet").click()
page.locator('[role="menuitemradio"] >> .mr-2.uppercase').nth(1).click(position={ "x": 0, "y": 0}, force=True)
change_keys(page, vega, "market_maker")
check_pnl_color_value(realised_pnl, "rgb(0, 0, 0)", "0.00")
check_pnl_color_value(unrealised_pnl, "rgb(1, 145, 75)", "4.00")
# neutral Trading unrealised
page.locator('[role="menuitemradio"] >> .mr-2.uppercase').nth(2).click(position={ "x": 0, "y": 0}, force=True)
change_keys(page, vega, "market_maker_2")
check_pnl_color_value(realised_pnl, "rgb(0, 0, 0)", "0.00")
check_pnl_color_value(unrealised_pnl, "rgb(0, 0, 0)", "0.00")
# Portfolio Unrealised
page.get_by_test_id("manage-vega-wallet").click(force=True)
page.get_by_role("link", name="Portfolio").click()
page.get_by_test_id("Positions").click()
page.wait_for_selector(
@@ -52,10 +51,10 @@ def test_pnl(continuous_market, vega: VegaService, page: Page):
'//div[@role="row" and .//div[@col-id="partyId"]/div/span[text()="Key 1"]]'
)
key_mm = page.query_selector(
'//div[@role="row" and .//div[@col-id="partyId"]/div/span[text()="mm"]]'
'//div[@role="row" and .//div[@col-id="partyId"]/div/span[text()="market_maker"]]'
)
key_mm2 = page.query_selector(
'//div[@role="row" and .//div[@col-id="partyId"]/div/span[text()="mm2"]]'
'//div[@role="row" and .//div[@col-id="partyId"]/div/span[text()="market_maker_2"]]'
)
key_1_unrealised_pnl = key_1.query_selector('xpath=./div[@col-id="unrealisedPNL"]')
@@ -101,12 +100,11 @@ def test_pnl(continuous_market, vega: VegaService, page: Page):
check_pnl_color_value(unrealised_pnl, "rgb(0, 0, 0)", "0.00")
# profit trading realised
page.get_by_test_id("manage-vega-wallet").click()
page.locator('[role="menuitemradio"] >> .mr-2.uppercase').nth(1).click(position={ "x": 0, "y": 0}, force=True)
change_keys(page, vega, "market_maker")
check_pnl_color_value(realised_pnl, "rgb(1, 145, 75)", "8.00")
check_pnl_color_value(unrealised_pnl, "rgb(0, 0, 0)", "0.00")
# loss trading realised
page.locator('[role="menuitemradio"] >> .mr-2.uppercase').nth(0).click(position={ "x": 0, "y": 0}, force=True)
change_keys(page, vega, "Key 1")
check_pnl_color_value(realised_pnl, "rgb(236, 0, 60)", "-8.00")
check_pnl_color_value(unrealised_pnl, "rgb(0, 0, 0)", "0.00")
@@ -32,12 +32,12 @@ def test_share_usage_data(page: Page):
# Define a mapping of icon selectors to toast selectors
ICON_TO_TOAST = {
'aria-label="arrow-top-left icon"': 'class="group absolute z-20 top-0 left-0 max-w-full max-h-full overflow-x-hidden overflow-y-auto p-4"',
'aria-label="arrow-up icon"': 'class="group absolute z-20 top-0 left-[50%] translate-x-[-50%] max-w-full max-h-full overflow-x-hidden overflow-y-auto p-4"',
'aria-label="arrow-top-right icon"': 'class="group absolute z-20 top-0 right-0 max-w-full max-h-full overflow-x-hidden overflow-y-auto p-4"',
'aria-label="arrow-bottom-left icon"': 'class="group absolute z-20 bottom-0 left-0 max-w-full max-h-full overflow-x-hidden overflow-y-auto p-4"',
'aria-label="arrow-down icon"': 'class="group absolute z-20 bottom-0 left-[50%] translate-x-[-50%] max-w-full max-h-full overflow-x-hidden overflow-y-auto p-4"',
'aria-label="arrow-bottom-right icon"': 'class="group absolute z-20 bottom-0 right-0 max-w-full max-h-full overflow-x-hidden overflow-y-auto p-4"',
'aria-label="arrow-top-left icon"': 'class="relative flex-1 overflow-auto p-4 pr-[40px] [&>p]:mb-[2.5px]"',
'aria-label="arrow-up icon"': 'class="relative flex-1 overflow-auto p-4 pr-[40px] [&>p]:mb-[2.5px]"',
'aria-label="arrow-top-right icon"': 'class="relative flex-1 overflow-auto p-4 pr-[40px] [&>p]:mb-[2.5px]"',
'aria-label="arrow-bottom-left icon"': 'class="relative flex-1 overflow-auto p-4 pr-[40px] [&>p]:mb-[2.5px]"',
'aria-label="arrow-down icon"': 'class="relative flex-1 overflow-auto p-4 pr-[40px] [&>p]:mb-[2.5px]"',
'aria-label="arrow-bottom-right icon"': 'class="relative flex-1 overflow-auto p-4 pr-[40px] [&>p]:mb-[2.5px]"',
}
@@ -18,8 +18,8 @@
# page.goto(f"/#/markets/{continuous_market}")
# vega.forward("24h")
# vega.wait_for_total_catchup()
# submit_order(vega, "mm", continuous_market, "SIDE_SELL", 1, 101.50000)
# submit_order(vega, "mm2", continuous_market, "SIDE_SELL", 1, 101.50000)
# submit_order(vega, "market_maker", continuous_market, "SIDE_SELL", 1, 101.50000)
# submit_order(vega, "market_maker_2", continuous_market, "SIDE_SELL", 1, 101.50000)
# vega.forward("10s")
# vega.wait_for_total_catchup()
@@ -2,7 +2,7 @@ import pytest
import re
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from actions.utils import wait_for_toast_confirmation, create_and_faucet_wallet, WalletConfig, next_epoch
from actions.utils import wait_for_toast_confirmation, create_and_faucet_wallet, WalletConfig, next_epoch, change_keys
import vega_sim.proto.vega as vega_protos
LIQ = WalletConfig("liq", "liq")
@@ -42,7 +42,7 @@ def test_transfer_submit(continuous_market, vega: VegaService, page: Page):
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
expected_confirmation_text = re.compile(r"Transfer completeYour transaction has been confirmed View in block explorerTransferTo .{6}….{6}1\.00 tDAI")
expected_confirmation_text = re.compile(r"Transfer completeYour transaction has been confirmedView in block explorerTransferTo .{6}….{6}1\.00 tDAI")
actual_confirmation_text = page.get_by_test_id('toast-content').text_content()
assert expected_confirmation_text.search(actual_confirmation_text), f"Expected pattern not found in {actual_confirmation_text}"
@@ -50,7 +50,7 @@ def test_transfer_submit(continuous_market, vega: VegaService, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_transfer_vesting_below_minimum(continuous_market, vega: VegaService, page: Page):
vega.update_network_parameter(
"mm", parameter="transfer.minTransferQuantumMultiple", new_value="100000"
"market_maker", parameter="transfer.minTransferQuantumMultiple", new_value="100000"
)
vega.wait_for_total_catchup()
@@ -97,9 +97,7 @@ def test_transfer_vesting_below_minimum(continuous_market, vega: VegaService, pa
page.goto('/#/portfolio')
expect(page.get_by_test_id('transfer-form')).to_be_visible
page.get_by_test_id("manage-vega-wallet").click()
page.locator('[role="menuitemradio"]').nth(5).click()
page.reload()
change_keys(page, vega, "party_b")
page.get_by_test_id('select-asset').click()
page.get_by_test_id('rich-select-option').click()
@@ -129,6 +127,6 @@ def test_transfer_vesting_below_minimum(continuous_market, vega: VegaService, pa
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
expected_confirmation_text = re.compile(r"Transfer completeYour transaction has been confirmed View in block explorerTransferTo .{6}….{6}0\.00001 tDAI")
expected_confirmation_text = re.compile(r"Transfer completeYour transaction has been confirmedView in block explorerTransferTo .{6}….{6}0\.00001 tDAI")
actual_confirmation_text = page.get_by_test_id('toast-content').text_content()
assert expected_confirmation_text.search(actual_confirmation_text), f"Expected pattern not found in {actual_confirmation_text}"
+12
View File
@@ -0,0 +1,12 @@
from collections import namedtuple
# Defined namedtuples
WalletConfig = namedtuple("WalletConfig", ["name", "passphrase"])
# Wallet Configurations
MM_WALLET = WalletConfig("market_maker", "pin")
MM_WALLET2 = WalletConfig("market_maker_2", "pin2")
TERMINATE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
GOVERNANCE_WALLET = WalletConfig("FJMKnwfZdd48C8NqvYrG", "bY3DxwtsCstMIIZdNpKs")
wallets = [MM_WALLET, MM_WALLET2, TERMINATE_WALLET, GOVERNANCE_WALLET]
+11
View File
@@ -66,7 +66,18 @@ i18n
'environment',
'fills',
'funding-payments',
'ledger',
'liquidity',
'market-depth',
'markets',
'orders',
'positions',
'trades',
'trading',
'ui-toolkit',
'utils',
'wallet',
'web3',
],
defaultNS: 'trading',
nsSeparator: false,
+9 -6
View File
@@ -1,8 +1,8 @@
import sortBy from 'lodash/sortBy';
import {
maxSafe,
required,
vegaPublicKey,
useMaxSafe,
useRequired,
useVegaPublicKey,
addDecimal,
formatNumber,
addDecimalsFormatNumber,
@@ -67,6 +67,9 @@ export const TransferForm = ({
minQuantumMultiple,
}: TransferFormProps) => {
const t = useT();
const maxSafe = useMaxSafe();
const required = useRequired();
const vegaPublicKey = useVegaPublicKey();
const {
control,
register,
@@ -415,7 +418,7 @@ export const TransferForm = ({
{accountBalance && (
<button
type="button"
className="absolute top-0 right-0 ml-auto text-xs underline"
className="absolute right-0 top-0 ml-auto text-xs underline"
onClick={() =>
setValue('amount', parseFloat(accountBalance).toString(), {
shouldValidate: true,
@@ -491,7 +494,7 @@ export const TransferFee = ({
const totalValue = new BigNumber(transferAmount).plus(fee).toString();
return (
<div className="flex flex-col mb-4 text-xs gap-2">
<div className="mb-4 flex flex-col gap-2 text-xs">
<div className="flex flex-wrap items-center justify-between gap-1">
<Tooltip
description={t(
@@ -560,7 +563,7 @@ export const AddressField = ({
<button
type="button"
onClick={onChange}
className="absolute top-0 right-0 ml-auto text-xs underline"
className="absolute right-0 top-0 ml-auto text-xs underline"
>
{isInput ? t('Select from wallet') : t('Enter manually')}
</button>
@@ -39,6 +39,7 @@ export const AgGridThemed = ({
ref={gridRef}
overlayLoadingTemplate={t('Loading...')}
overlayNoRowsTemplate={t('No data')}
suppressDragLeaveHidesColumns
{...defaultProps}
{...props}
/>
@@ -1,5 +1,5 @@
import { useCallback, useState } from 'react';
import { getAsset, getQuoteName } from '@vegaprotocol/markets';
import { getAsset, getProductType, getQuoteName } from '@vegaprotocol/markets';
import type { OrderSubmissionBody } from '@vegaprotocol/wallet';
import { useVegaWallet } from '@vegaprotocol/wallet';
@@ -297,120 +297,134 @@ export const DealTicketMarginDetails = ({
);
const quoteName = getQuoteName(market);
const productType = getProductType(market);
return (
<div className="flex flex-col w-full gap-2">
<Accordion>
<AccordionPanel
itemId="margin"
trigger={
<AccordionPrimitive.Trigger
data-testid="accordion-toggle"
className={classNames(
'w-full pt-2',
'flex items-center gap-2 text-xs',
'group'
)}
>
<div
data-testid={`deal-ticket-fee-margin-required`}
key={'value-dropdown'}
className="flex items-center justify-between w-full gap-2"
>
<div className="flex items-center text-left gap-1">
<Tooltip
description={t(
'MARGIN_DIFF_TOOLTIP_TEXT',
MARGIN_DIFF_TOOLTIP_TEXT,
{ assetSymbol }
)}
>
<span className="text-muted">{t('Margin required')}</span>
</Tooltip>
<div className="flex flex-col w-full gap-2 pt-2">
{/*
TODO: remove this conditional check once the following PRs are deployed
and the estimatePosition query is working for perps
<AccordionChevron size={10} />
</div>
<Tooltip
description={
formatRange(
marginRequiredBestCase,
marginRequiredWorstCase,
assetDecimals
) ?? '-'
}
- https://github.com/vegaprotocol/vega/pull/10119
- https://github.com/vegaprotocol/vega/pull/10122
*/}
{productType === 'Future' && (
<>
<Accordion>
<AccordionPanel
itemId="margin"
trigger={
<AccordionPrimitive.Trigger
data-testid="accordion-toggle"
className={classNames(
'w-full',
'flex items-center gap-2 text-xs',
'group'
)}
>
<div className="font-mono text-right">
{formatValue(
marginRequiredWorstCase,
assetDecimals,
quantum
)}{' '}
{assetSymbol || ''}
<div
data-testid={`deal-ticket-fee-margin-required`}
key={'value-dropdown'}
className="flex items-center justify-between w-full gap-2"
>
<div className="flex items-center text-left gap-1">
<Tooltip
description={t(
'MARGIN_DIFF_TOOLTIP_TEXT',
MARGIN_DIFF_TOOLTIP_TEXT,
{ assetSymbol }
)}
>
<span className="text-muted">
{t('Margin required')}
</span>
</Tooltip>
<AccordionChevron size={10} />
</div>
<Tooltip
description={
formatRange(
marginRequiredBestCase,
marginRequiredWorstCase,
assetDecimals
) ?? '-'
}
>
<div className="font-mono text-right">
{formatValue(
marginRequiredWorstCase,
assetDecimals,
quantum
)}{' '}
{assetSymbol || ''}
</div>
</Tooltip>
</div>
</Tooltip>
</div>
</AccordionPrimitive.Trigger>
}
>
<div className="flex flex-col w-full gap-2">
<KeyValue
label={t('Total margin available')}
indent
value={formatValue(totalMarginAvailable, assetDecimals)}
formattedValue={formatValue(
totalMarginAvailable,
assetDecimals,
quantum
)}
symbol={assetSymbol}
labelDescription={t(
'TOTAL_MARGIN_AVAILABLE',
TOTAL_MARGIN_AVAILABLE,
{
generalAccountBalance: formatValue(
generalAccountBalance,
</AccordionPrimitive.Trigger>
}
>
<div className="flex flex-col w-full gap-2">
<KeyValue
label={t('Total margin available')}
indent
value={formatValue(totalMarginAvailable, assetDecimals)}
formattedValue={formatValue(
totalMarginAvailable,
assetDecimals,
quantum
),
marginAccountBalance: formatValue(
)}
symbol={assetSymbol}
labelDescription={t(
'TOTAL_MARGIN_AVAILABLE',
TOTAL_MARGIN_AVAILABLE,
{
generalAccountBalance: formatValue(
generalAccountBalance,
assetDecimals,
quantum
),
marginAccountBalance: formatValue(
marginAccountBalance,
assetDecimals,
quantum
),
marginMaintenance: formatValue(
currentMargins?.maintenanceLevel,
assetDecimals,
quantum
),
assetSymbol,
}
)}
/>
{deductionFromCollateral}
<KeyValue
label={t('Current margin allocation')}
indent
onClick={
generalAccountBalance
? () => setBreakdownDialog(true)
: undefined
}
value={formatValue(marginAccountBalance, assetDecimals)}
symbol={assetSymbol}
labelDescription={t(
'MARGIN_ACCOUNT_TOOLTIP_TEXT',
MARGIN_ACCOUNT_TOOLTIP_TEXT
)}
formattedValue={formatValue(
marginAccountBalance,
assetDecimals,
quantum
),
marginMaintenance: formatValue(
currentMargins?.maintenanceLevel,
assetDecimals,
quantum
),
assetSymbol,
}
)}
/>
{deductionFromCollateral}
<KeyValue
label={t('Current margin allocation')}
indent
onClick={
generalAccountBalance
? () => setBreakdownDialog(true)
: undefined
}
value={formatValue(marginAccountBalance, assetDecimals)}
symbol={assetSymbol}
labelDescription={t(
'MARGIN_ACCOUNT_TOOLTIP_TEXT',
MARGIN_ACCOUNT_TOOLTIP_TEXT
)}
formattedValue={formatValue(
marginAccountBalance,
assetDecimals,
quantum
)}
/>
</div>
</AccordionPanel>
</Accordion>
{projectedMargin}
)}
/>
</div>
</AccordionPanel>
</Accordion>
{projectedMargin}
</>
)}
<KeyValue
label={t('Liquidation')}
value={liquidationPriceEstimateRange}
@@ -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 { toDecimal, validateAmount } from '@vegaprotocol/utils';
import { toDecimal, useValidateAmount } from '@vegaprotocol/utils';
import {
TradingFormGroup,
TradingInput,
@@ -28,6 +28,7 @@ export const DealTicketSizeIceberg = ({
peakSize,
}: DealTicketSizeIcebergProps) => {
const t = useT();
const validateAmount = useValidateAmount();
const sizeStep = toDecimal(market?.positionDecimalPlaces);
const renderPeakSizeError = () => {
@@ -9,7 +9,7 @@ import {
formatValue,
removeDecimal,
toDecimal,
validateAmount,
useValidateAmount,
} from '@vegaprotocol/utils';
import { type Control, type UseFormWatch } from 'react-hook-form';
import { useForm, Controller, useController } from 'react-hook-form';
@@ -36,7 +36,6 @@ import {
} from '@vegaprotocol/markets';
import { ExpirySelector } from './expiry-selector';
import { SideSelector } from './side-selector';
import { timeInForceLabel } from '@vegaprotocol/orders';
import {
NoWalletWarning,
REDUCE_ONLY_TOOLTIP,
@@ -110,6 +109,7 @@ const Trigger = ({
decimalPlaces: number;
}) => {
const t = useT();
const validateAmount = useValidateAmount();
const triggerType = watch(oco ? 'ocoTriggerType' : 'triggerType');
const triggerDirection = watch('triggerDirection');
const isPriceTrigger = triggerType === 'price';
@@ -342,6 +342,7 @@ const Size = ({
assetUnit?: string;
}) => {
const t = useT();
const validateAmount = useValidateAmount();
return (
<Controller
name={oco ? 'ocoSize' : 'size'}
@@ -402,6 +403,7 @@ const Price = ({
oco?: boolean;
}) => {
const t = useT();
const validateAmount = useValidateAmount();
if (watch(oco ? 'ocoType' : 'type') === Schema.OrderType.TYPE_MARKET) {
return null;
}
@@ -479,13 +481,13 @@ const TimeInForce = ({
key={Schema.OrderTimeInForce.TIME_IN_FORCE_IOC}
value={Schema.OrderTimeInForce.TIME_IN_FORCE_IOC}
>
{timeInForceLabel(Schema.OrderTimeInForce.TIME_IN_FORCE_IOC)}
{t(Schema.OrderTimeInForce.TIME_IN_FORCE_IOC)}
</option>
<option
key={Schema.OrderTimeInForce.TIME_IN_FORCE_FOK}
value={Schema.OrderTimeInForce.TIME_IN_FORCE_FOK}
>
{timeInForceLabel(Schema.OrderTimeInForce.TIME_IN_FORCE_FOK)}
{t(Schema.OrderTimeInForce.TIME_IN_FORCE_FOK)}
</option>
</Select>
</FormGroup>
@@ -1181,7 +1183,9 @@ export const StopOrder = ({ market, marketPrice, submit }: StopOrderProps) => {
testId={'stop-order-warning-limit'}
message={t(
'There is a limit of {{maxNumberOfOrders}} active stop orders per market. Orders submitted above the limit will be immediately rejected.',
{ maxNumberOfOrders: MAX_NUMBER_OF_ACTIVE_STOP_ORDERS.toString() }
{
maxNumberOfOrders: MAX_NUMBER_OF_ACTIVE_STOP_ORDERS.toString(),
}
)}
/>
</div>
@@ -495,12 +495,15 @@ describe('DealTicket', () => {
Array.from(screen.getByTestId('order-tif').children).map(
(o) => o.textContent
)
).toEqual(['Fill or Kill (FOK)', 'Immediate or Cancel (IOC)']);
).toEqual([
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK,
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC,
]);
// IOC should be default
// 7002-SORD-030
expect(screen.getByTestId('order-tif')).toHaveDisplayValue(
'Immediate or Cancel (IOC)'
Schema.OrderTimeInForce.TIME_IN_FORCE_IOC
);
// Select FOK - FOK should be selected
@@ -509,7 +512,7 @@ describe('DealTicket', () => {
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK
);
expect(screen.getByTestId('order-tif')).toHaveDisplayValue(
'Fill or Kill (FOK)'
Schema.OrderTimeInForce.TIME_IN_FORCE_FOK
);
// Switch to type limit order -> all TIF options should be shown
@@ -28,7 +28,7 @@ import { useOpenVolume } from '@vegaprotocol/positions';
import {
toBigNum,
removeDecimal,
validateAmount,
useValidateAmount,
toDecimal,
formatForInput,
formatValue,
@@ -140,6 +140,7 @@ export const DealTicket = ({
onDeposit,
}: DealTicketProps) => {
const t = useT();
const validateAmount = useValidateAmount();
const { pubKey, isReadOnly } = useVegaWallet();
const setType = useDealTicketFormValues((state) => state.setType);
const storedFormValues = useDealTicketFormValues(
@@ -6,7 +6,6 @@ import {
SimpleGrid,
} from '@vegaprotocol/ui-toolkit';
import * as Schema from '@vegaprotocol/types';
import { timeInForceLabel } from '@vegaprotocol/orders';
import { compileGridData } from '../trading-mode-tooltip';
import { MarketModeValidationType } from '../../constants';
import type { Market, StaticMarketData } from '@vegaprotocol/markets';
@@ -119,9 +118,7 @@ export const TimeInForceSelector = ({
hasError={!!errorMessage}
>
{options.map(([key, value]) => (
<option key={key} value={value}>
{timeInForceLabel(value)}
</option>
<TimeInForceOption key={key} value={value} />
))}
</TradingSelect>
{errorMessage && (
@@ -133,3 +130,8 @@ export const TimeInForceSelector = ({
</div>
);
};
const TimeInForceOption = ({ value }: { value: Schema.OrderTimeInForce }) => {
const t = useT();
return <option value={value}>{t(value)}</option>;
};
+12 -7
View File
@@ -1,11 +1,11 @@
import type { Asset, AssetFieldsFragment } from '@vegaprotocol/assets';
import { AssetOption } from '@vegaprotocol/assets';
import {
ethereumAddress,
required,
vegaPublicKey,
minSafe,
maxSafe,
useEthereumAddress,
useRequired,
useVegaPublicKey,
useMinSafe,
useMaxSafe,
addDecimal,
isAssetTypeERC20,
formatNumber,
@@ -85,6 +85,11 @@ export const DepositForm = ({
isFaucetable,
}: DepositFormProps) => {
const t = useT();
const ethereumAddress = useEthereumAddress();
const required = useRequired();
const vegaPublicKey = useVegaPublicKey();
const minSafe = useMinSafe();
const maxSafe = useMaxSafe();
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
const openDialog = useWeb3ConnectStore((store) => store.open);
const { isActive, account } = useWeb3React();
@@ -459,7 +464,7 @@ const UseButton = (props: UseButtonProps) => {
<button
{...props}
type="button"
className="absolute top-0 right-0 ml-auto text-sm underline"
className="absolute right-0 top-0 ml-auto text-sm underline"
/>
);
};
@@ -519,7 +524,7 @@ export const AddressField = ({
setIsInput((curr) => !curr);
onChange();
}}
className="absolute top-0 right-0 ml-auto text-sm underline"
className="absolute right-0 top-0 ml-auto text-sm underline"
data-testid="enter-pubkey-manually"
>
{isInput ? t('Select from wallet') : t('Enter manually')}
+15
View File
@@ -1,4 +1,5 @@
export * from './lib/i18n';
import en_accounts from './locales/en/accounts.json';
import en_assets from './locales/en/assets.json';
import en_candles_chart from './locales/en/candles-chart.json';
@@ -10,6 +11,13 @@ import en_fills from './locales/en/fills.json';
import en_funding_payments from './locales/en/funding-payments.json';
import en_governance from './locales/en/governance.json';
import en_trading from './locales/en/trading.json';
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_trades from './locales/en/trading.json';
import en_ui_toolkit from './locales/en/ui-toolkit.json';
import en_wallet from './locales/en/wallet.json';
export const locales = {
en: {
@@ -24,5 +32,12 @@ export const locales = {
'funding-payments': en_funding_payments,
governance: en_governance,
trading: en_trading,
markets: en_markets,
web3: en_web3,
positions: en_positions,
proposals: en_proposals,
trades: en_trades,
'ui-toolkit': en_ui_toolkit,
wallet: en_wallet,
},
};
+7 -1
View File
@@ -128,5 +128,11 @@
"You need to connect your own wallet to start trading on this market": "You need to connect your own wallet to start trading on this market",
"You need to provide a minimum visible size": "You need to provide a minimum visible size",
"You need to provide a peak size": "You need to provide a peak size",
"You need to provide a size": "You need to provide a size"
"You need to provide a size": "You need to provide a size",
"TIME_IN_FORCE_FOK": "Fill or Kill (FOK)",
"TIME_IN_FORCE_GFA": "Good for Auction (GFA)",
"TIME_IN_FORCE_GFN": "Good for Normal (GFN)",
"TIME_IN_FORCE_GTC": "Good 'til Cancelled (GTC)",
"TIME_IN_FORCE_GTT": "Good 'til Time (GTT)",
"TIME_IN_FORCE_IOC": "Immediate or Cancel (IOC)"
}
+1
View File
@@ -0,0 +1 @@
{}
+18
View File
@@ -0,0 +1,18 @@
{
"Date from": "Date from",
"Date to": "Date to",
"Download": "Download",
"Download all to .csv file": "Download all to .csv file",
"Download has been started": "Download has been started",
"Downloading for {{asset}} from {{startDate}} till {{endDate}}": "Downloading for {{asset}} from {{startDate}} till {{endDate}}",
"Export ledger entries": "Export ledger entries",
"Get file here": "Get file here",
"Please note this can take several minutes.": "Please note this can take several minutes.",
"Select asset": "Select asset",
"Something went wrong": "Something went wrong",
"Still in progress": "Still in progress",
"The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC{{offset}}.": "The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC{{offset}}.",
"Try again later": "Try again later",
"You will be notified here when your file is ready.": "You will be notified here when your file is ready.",
"Your file is ready": "Your file is ready"
}
+41
View File
@@ -0,0 +1,41 @@
{
"Adjusted stake share": "Adjusted stake share",
"Commitment ({{symbol}})": "Commitment ({{symbol}})",
"Commitment details": "Commitment details",
"Created": "Created",
"Current epoch fraction of time on the book.": "Current epoch fraction of time on the book.",
"Fee": "Fee",
"Fees accrued this epoch": "Fees accrued this epoch",
"Last bond penalty": "Last bond penalty",
"Last epoch bond penalty.": "Last epoch bond penalty.",
"Last epoch fee penalty.": "Last epoch fee penalty.",
"Last epoch fraction of time on the book.": "Last epoch fraction of time on the book.",
"Last epoch SLA details": "Last epoch SLA details",
"Last fee penalty": "Last fee penalty",
"Last time on the book": "Last time on the book",
"Live liquidity data": "Live liquidity data",
"Live liquidity quality score (%)": "Live liquidity quality score (%)",
"Live supplied liquidity": "Live supplied liquidity",
"Live time on book": "Live time on book",
"No liquidity provisions": "No liquidity provisions",
"Obligation": "Obligation",
"Party": "Party",
"Share": "Share",
"Status": "Status",
"The amount committed to the market by this liquidity provider.": "The amount committed to the market by this liquidity provider.",
"The amount of liquidity volume supplied by the LP order in order to meet the obligation. If the obligation is already met in full by other limit orders from the same Vega key the LP order is not required and this value will be zero. Also note if the target stake for the market is less than the obligation the full value of the obligation may not be required.": "The amount of liquidity volume supplied by the LP order in order to meet the obligation. If the obligation is already met in full by other limit orders from the same Vega key the LP order is not required and this value will be zero. Also note if the target stake for the market is less than the obligation the full value of the obligation may not be required.",
"The average score of the liquidity provider.": "The average score of the liquidity provider.",
"The current status of this liquidity provision.": "The current status of this liquidity provision.",
"The date and time this liquidity provision was created.": "The date and time this liquidity provision was created.",
"The date and time this liquidity provision was last updated.": "The date and time this liquidity provision was last updated.",
"The equity-like share of liquidity of the market used to determine allocation of LP fees. Calculated based on share of total liquidity, with a premium added for length of commitment.": "The equity-like share of liquidity of the market used to determine allocation of LP fees. Calculated based on share of total liquidity, with a premium added for length of commitment.",
"The fee percentage (per trade) proposed by each liquidity provider.": "The fee percentage (per trade) proposed by each liquidity provider.",
"The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.": "The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.",
"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 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 public key of the party making this commitment.": "The public key of the party making this commitment.",
"The virtual stake of the liquidity provider.": "The virtual stake of the liquidity provider.",
"This LP's time on the book in the current epoch ({{currentEpoch}}) is less than 100%, so they could lose some fees to a better performing LP.": "This LP's time on the book in the current epoch ({{currentEpoch}}) is less than 100%, so they could lose some fees to a better performing LP.",
"This LP's time on the book in the current epoch ({{currentEpoch}}) is less than the minimum required ({{minimumRequired}}), so they could lose all fee revenue for this epoch.": "This LP's time on the book in the current epoch ({{currentEpoch}}) is less than the minimum required ({{minimumRequired}}), so they could lose all fee revenue for this epoch.",
"Updated": "Updated",
"Updating next epoch": "Updating next epoch"
}
@@ -0,0 +1,5 @@
{
"Last traded price": "Last traded price",
"No open orders": "No open orders",
"Spread": "Spread"
}
+143
View File
@@ -0,0 +1,143 @@
{
"{{liquidityPriceRange}} of mid price": "{{liquidityPriceRange}} of mid price",
"{{probability}} probability price bounds": "{{probability}} probability price bounds",
"24 hour change is unavailable at this time. The price change in the last 120 hours is:": "24 hour change is unavailable at this time. The price change in the last 120 hours is:",
"24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}}": "24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}}",
"A concept derived from traditional markets. It is a calculated value for the current market price on a market.": "A concept derived from traditional markets. It is a calculated value for the current market price on a market.",
"A number that will be calculated by an appropriate stochastic risk model, dependent on the type of risk model used and its parameters.": "A number that will be calculated by an appropriate stochastic risk model, dependent on the type of risk model used and its parameters.",
"A sliding penalty for how much an LP bond is slashed if an LP fails to reach the minimum SLA. This is a network parameter.": "A sliding penalty for how much an LP bond is slashed if an LP fails to reach the minimum SLA. This is a network parameter.",
"ABI specification": "ABI specification",
"Added": "Added",
"Address": "Address",
"All fees are paid by price takers and are a % of the trade notional value. Fees are not paid during auction uncrossing.": "All fees are paid by price takers and are a % of the trade notional value. Fees are not paid during auction uncrossing.",
"Auction extension duration in seconds, should the price breach its theoretical level over the specified horizon at the specified probability level.": "Auction extension duration in seconds, should the price breach its theoretical level over the specified horizon at the specified probability level.",
"Block explorer": "Block explorer",
"Conditions": "Conditions",
"Could not load market": "Could not load market",
"Current fees": "Current fees",
"Data about the sector. Example: 'automotive' for a market based on value of Tesla shares.": "Data about the sector. Example: 'automotive' for a market based on value of Tesla shares.",
"Details": "Details",
"Determines how the probability of trading is scaled from the risk model, and is used to measure the relative competitiveness of an LP's supplied volume. This is a network parameter.": "Determines how the probability of trading is scaled from the risk model, and is used to measure the relative competitiveness of an LP's supplied volume. This is a network parameter.",
"Ethereum Oracle": "Ethereum Oracle",
"every {{duration}}": "every {{duration}}",
"every {{duration}} from {{initialTime}}": "every {{duration}} from {{initialTime}}",
"Fees paid to validators as a reward for running the infrastructure of the network.": "Fees paid to validators as a reward for running the infrastructure of the network.",
"Filters": "Filters",
"For liquidity orders to count towards a commitment, they must be within the liquidity monitoring bounds.": "For liquidity orders to count towards a commitment, they must be within the liquidity monitoring bounds.",
"Funding": "Funding",
"How big the smallest order / position on the market can be.": "How big the smallest order / position on the market can be.",
"How long an epoch is. LP rewards from liquidity fees are paid out once per epoch. How much they receive depends on whether they met the liquidity SLA and their previous performance in recent epochs. This is a network parameter.": "How long an epoch is. LP rewards from liquidity fees are paid out once per epoch. How much they receive depends on whether they met the liquidity SLA and their previous performance in recent epochs. This is a network parameter.",
"How often the quality of liquidity supplied by each liquidity provider is evaluated and the fees arising from that period are earmarked for specific providers. This is a market parameter. ": "How often the quality of liquidity supplied by each liquidity provider is evaluated and the fees arising from that period are earmarked for specific providers. This is a market parameter. ",
"Instrument": "Instrument",
"Insurance pool": "Insurance pool",
"Internal conditions": "Internal conditions",
"Invalid data source": "Invalid data source",
"involvedInMarkets_other": "Involved in {{count}} markets",
"involvedInMarkets_one": "Involved in {{count}} market",
"Key": "Key",
"Key details": "Key details",
"Liquidity": "Liquidity",
"Liquidity monitoring parameters": "Liquidity monitoring parameters",
"Liquidity portion of the fee is paid to liquidity providers, and is transferred to the liquidity fee pool for the market.": "Liquidity portion of the fee is paid to liquidity providers, and is transferred to the liquidity fee pool for the market.",
"Liquidity price range": "Liquidity price range",
"Liquidity SLA protocol": "Liquidity SLA protocol",
"Maker portion of the fee is transferred to the non-aggressive, or passive party in the trade (the maker, as opposed to the taker).": "Maker portion of the fee is transferred to the non-aggressive, or passive party in the trade (the maker, as opposed to the taker).",
"Margin scaling factors": "Margin scaling factors",
"Market": "Market",
"Market data": "Market data",
"Market governance": "Market governance",
"Market ID": "Market ID",
"Market price": "Market price",
"Market specification": "Market specification",
"Market volume": "Market volume",
"Maximum fraction of an LP's accrued fees that an LP would lose to liquidity providers that achieved a higher SLA performance than them. This is a market parameter.": "Maximum fraction of an LP's accrued fees that an LP would lose to liquidity providers that achieved a higher SLA performance than them. This is a market parameter.",
"Maximum value that a proposed fee amount can be, which is submitted as part of the LP commitment transaction. Note that a value of 0.05 = 5%. This is a network parameter.": "Maximum value that a proposed fee amount can be, which is submitted as part of the LP commitment transaction. Note that a value of 0.05 = 5%. This is a network parameter.",
"Metadata": "Metadata",
"moreProofs_one": "And {{count}} more proof",
"moreProofs_other": "And {{count}} more proofs",
"Multiplier used to translate an LP's commitment amount to their liquidity obligation. This is a network parameter.": "Multiplier used to translate an LP's commitment amount to their liquidity obligation. This is a network parameter.",
"No data": "No data",
"No oracle proof for settlement data": "No oracle proof for settlement data",
"No oracle proof for termination": "No oracle proof for termination",
"No oracle spec for trading termination. Internal timestamp used": "No oracle spec for trading termination. Internal timestamp used",
"Normalisers": "Normalisers",
"Not verified": "Not verified",
"Number of epochs over which past performance will continue to affect rewards. This is a market parameter.": "Number of epochs over which past performance will continue to affect rewards. This is a market parameter.",
"Oracle": "Oracle",
"Oracle repository": "Oracle repository",
"Oracle status for this market is <0>{{status}}</0>. {{description}} <1>Show more</1>": "Oracle status for this market is <0>{{status}}</0>. {{description}} <1>Show more</1>",
"Oracle status: {{status}}. {{description}}": "Oracle status: {{status}}. {{description}}",
"oracleInMarkets_one": "Oracle in {{count}} market",
"oracleInMarkets_other": "Oracle in {{count}} markets",
"Price monitoring bounds {{index}}": "Price monitoring bounds {{index}}",
"Probability level for price projection, e.g. value of 0.95 will result in a price range such that over the specified projection horizon, the prices observed in the market should be in that range 95% of the time.": "Probability level for price projection, e.g. value of 0.95 will result in a price range such that over the specified projection horizon, the prices observed in the market should be in that range 95% of the time.",
"Probability level used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short": "Probability level used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short",
"Projection horizon measured as a year fraction used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short": "Projection horizon measured as a year fraction used in <0>Expected Shortfall</0> calculation when obtaining Risk Factor Long and Risk Factor Short",
"proofsOfOwnership_one": "{{count}} proof of ownership",
"proofsOfOwnership_other": "{{count}} proofs of ownership",
"Proposal": "Proposal",
"Propose a change to market": "Propose a change to market",
"Read more": "Read more",
"Results in {{auctionExtensionSecs}} seconds auction if breached": "Results in {{auctionExtensionSecs}} seconds auction if breached",
"Risk factors": "Risk factors",
"Risk model": "Risk model",
"Settlement": "Settlement",
"Settlement asset": "Settlement asset",
"Settlement oracle": "Settlement oracle",
"Settlement schedule oracle": "Settlement schedule oracle",
"Show less": "Show less",
"SLA protocol = a part of the Vega protocol that creates similar incentives within the decentralised system to those achieved by a Service Level Agreement between parties in traditional finance. The SLA protocol involves no discussion, agreement, or contracts between parties but instead relies upon rules and an economic mechanism implemented in code running on the network": "SLA protocol = a part of the Vega protocol that creates similar incentives within the decentralised system to those achieved by a Service Level Agreement between parties in traditional finance. The SLA protocol involves no discussion, agreement, or contracts between parties but instead relies upon rules and an economic mechanism implemented in code running on the network",
"Specifications": "Specifications",
"Specifies the minimum fraction of time LPs must spend 'on the book' providing their committed liquidity. This is a market parameter.": "Specifies the minimum fraction of time LPs must spend 'on the book' providing their committed liquidity. This is a market parameter.",
"Status": "Status",
"Succession line": "Succession line",
"Termination": "Termination",
"Termination oracle": "Termination oracle",
"The aggregated volume being bid at the best bid price on the market.": "The aggregated volume being bid at the best bid price on the market.",
"The aggregated volume being bid at the best static bid price on the market.": "The aggregated volume being bid at the best static bid price on the market.",
"The aggregated volume being offered at the best offer price on the market.": "The aggregated volume being offered at the best offer price on the market.",
"The aggregated volume being offered at the best static offer price on the market.": "The aggregated volume being offered at the best static offer price on the market.",
"The classification of the product. Examples: shares, commodities, crypto, FX.": "The classification of the product. Examples: shares, commodities, crypto, FX.",
"The current amount of liquidity supplied for this market.": "The current amount of liquidity supplied for this market.",
"The current state of the market": "The current state of the market",
"The first currency in a pair for a currency-based derivatives market.": "The first currency in a pair for a currency-based derivatives market.",
"The fraction of the insurance pool balance that is carried over from the parent market to the successor.": "The fraction of the insurance pool balance that is carried over from the parent market to the successor.",
"The ID of the market this market succeeds.": "The ID of the market this market succeeds.",
"The length of time over which open interest is measured.": "The length of time over which open interest is measured.",
"The liquidity price range is a {{{liquidityPriceRange}} difference from the mid price.": "The liquidity price range is a {{{liquidityPriceRange}} difference from the mid price.",
"The lower bound for the probability of trading calculation, used to measure liquidity available on a market to determine if LPs are meeting their commitment. This is a network parameter.": "The lower bound for the probability of trading calculation, used to measure liquidity available on a market to determine if LPs are meeting their commitment. This is a network parameter.",
"The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.": "The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.",
"The maximum amount, as a fraction, that an LP's bond can be slashed by if they fail to reach the minimum SLA. This is a network parameter.": "The maximum amount, as a fraction, that an LP's bond can be slashed by if they fail to reach the minimum SLA. This is a network parameter.",
"The percentage of their bond an LP forfeits if they reduce their commitment while the market is below target stake. If 100%, an LP's entire bond is forfeited when they cancel their full commitment. This is a network parameter.": "The percentage of their bond an LP forfeits if they reduce their commitment while the market is below target stake. If 100%, an LP's entire bond is forfeited when they cancel their full commitment. This is a network parameter.",
"The scaling between the liquidity demand estimate, based on open interest and target stake.": "The scaling between the liquidity demand estimate, based on open interest and target stake.",
"The second currency in a pair for a currency-based derivatives market.": "The second currency in a pair for a currency-based derivatives market.",
"The smallest price increment on the book.": "The smallest price increment on the book.",
"The total number of contracts traded in the last 24 hours.": "The total number of contracts traded in the last 24 hours.",
"The trading mode the market is currently running.": "The trading mode the market is currently running.",
"The triggering ratio for entering liquidity auction.": "The triggering ratio for entering liquidity auction.",
"The underlying that is being priced by the market, described by the market's oracle.": "The underlying that is being priced by the market, described by the market's oracle.",
"The volume at which all trades would occur if the auction was uncrossed now (when in auction mode).": "The volume at which all trades would occur if the auction was uncrossed now (when in auction mode).",
"The volume of all open positions in a given market (the sum of the size of all positions greater than 0).": "The volume of all open positions in a given market (the sum of the size of all positions greater than 0).",
"There is 1 unit of the settlement asset ({{assetSymbol}}) to every 1 quote unit ({{quoteUnit}}).": "There is 1 unit of the settlement asset ({{assetSymbol}}) to every 1 quote unit ({{quoteUnit}}).",
"This market": "This market",
"This oracle has not proven ownership of any accounts.": "This oracle has not proven ownership of any accounts.",
"This public key has been observed acting in bad faith.": "This public key has been observed acting in bad faith.",
"This public key is no longer in the control of its original owners.": "This public key is no longer in the control of its original owners.",
"This public key is no longer in use.": "This public key is no longer in use.",
"This public key is suspected to be acting in bad faith, pending investigation.": "This public key is suspected to be acting in bad faith, pending investigation.",
"This public key's proofs have been verified.": "This public key's proofs have been verified.",
"This public key's proofs have not been verified yet, or no proofs have been provided yet.": "This public key's proofs have not been verified yet, or no proofs have been provided yet.",
"Time horizon of the price projection in seconds.": "Time horizon of the price projection in seconds.",
"Updated": "Updated",
"Used to calculate the penalty to liquidity providers when they cannot support their open position with the assets in their margin and general accounts. This is a network parameter.": "Used to calculate the penalty to liquidity providers when they cannot support their open position with the assets in their margin and general accounts. This is a network parameter.",
"Verified since {{lastVerified}}": "Verified since {{lastVerified}}",
"verifyProofs_one": "Verify {{count}} proof of ownership",
"verifyProofs_other": "Verify {{count}} proofs of ownership",
"View governance proposal": "View governance proposal",
"View liquidity provision table": "View liquidity provision table",
"View on Etherscan": "View on Etherscan",
"View settlement data specification": "View settlement data specification",
"View settlement schedule specification": "View settlement schedule specification",
"View termination specification": "View termination specification",
"Within {{horizonSecs}} seconds": "Within {{horizonSecs}} seconds"
}
+49
View File
@@ -0,0 +1,49 @@
{
"{{tifLabel}}. Post Only": "{{tifLabel}}. Post Only",
"{{tifLabel}}. Reduce only": "{{tifLabel}}. Reduce only",
"Cancel": "Cancel",
"Cancel all": "Cancel all",
"Cancel order": "Cancel order",
"Cancels": "Cancels",
"Copy": "Copy",
"Copy order ID": "Copy order ID",
"Created": "Created",
"Edit order": "Edit order",
"Expires": "Expires",
"Expires at": "Expires at",
"Filled": "Filled",
"Iceberg order": "Iceberg order",
"Liquidity provision": "Liquidity provision",
"Market": "Market",
"MAX": "MAX",
"Minimum size": "Minimum size",
"No orders": "No orders",
"No stop orders": "No stop orders",
"One Cancels the Other": "One Cancels the Other",
"Order details": "Order details",
"Order ID": "Order ID",
"Peak size": "Peak size",
"Pegged": "Pegged",
"Post only": "Post only",
"Price": "Price",
"Reduce only": "Reduce only",
"Remaining": "Remaining",
"Reserved remaining": "Reserved remaining",
"Side": "Side",
"Size": "Size",
"Something went wrong: {{errorMessage}}": "Something went wrong: {{errorMessage}}",
"Status": "Status",
"Submit": "Submit",
"The maximum volume that can be traded at once. Must be less than the total size of the order.": "The maximum volume that can be traded at once. Must be less than the total size of the order.",
"The price cannot be negative": "The price cannot be negative",
"The size cannot be negative": "The size cannot be negative",
"Trigger": "Trigger",
"Type": "Type",
"Update": "Update",
"Updated": "Updated",
"View order details": "View order details",
"When the order trades and its size falls below this threshold, it will be reset to the peak size and moved to the back of the priority order. Must be less than or equal to peak size, and greater than 0.": "When the order trades and its size falls below this threshold, it will be reset to the peak size and moved to the back of the priority order. Must be less than or equal to peak size, and greater than 0.",
"Yes": "Yes",
"You need to provide a price": "You need to provide a price",
"You need to provide a size": "You need to provide a size"
}
+30
View File
@@ -0,0 +1,30 @@
{
"Best case": "Best case",
"Close position": "Close position",
"Entry / Mark": "Entry / Mark",
"Lifetime loss socialisation deductions: {{losses}}": "Lifetime loss socialisation deductions: {{losses}}",
"Maintained by network": "Maintained by network",
"Margin / Leverage": "Margin / Leverage",
"Market": "Market",
"No positions": "No positions",
"Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.": "Profit or loss is realised whenever your position is reduced to zero and the margin is released back to your collateral balance. P&L excludes any fees paid.",
"Read more about loss socialisation": "Read more about loss socialisation",
"Read more about position resolution": "Read more about position resolution",
"Realised PNL": "Realised PNL",
"Realised PNL: {{value}}": "Realised PNL: {{value}}",
"Size / Notional": "Size / Notional",
"Status: {{status}}": "Status: {{status}}",
"The position was distressed, but could not be closed out - orders were removed from the book, and the open volume will be closed out once there is sufficient volume on the book.": "The position was distressed, but could not be closed out - orders were removed from the book, and the open volume will be closed out once there is sufficient volume on the book.",
"The position was distressed, but removing open orders from the book brought the margin level back to a point where the open position could be maintained.": "The position was distressed, but removing open orders from the book brought the margin level back to a point where the open position could be maintained.",
"Unrealised PNL": "Unrealised PNL",
"Unrealised profit is the current profit on your open position. Margin is still allocated to your position.": "Unrealised profit is the current profit on your open position. Margin is still allocated to your position.",
"Vega key": "Vega key",
"View settlement asset details": "View settlement asset details",
"Worst case": "Worst case",
"Worst case liquidation price": "Worst case liquidation price",
"You did not have enough {{assetSymbol}} collateral to meet the maintenance margin requirements for your position, so it was closed by the network.": "You did not have enough {{assetSymbol}} collateral to meet the maintenance margin requirements for your position, so it was closed by the network.",
"You received less {{assetSymbol}} in gains that you should have when the market moved in your favour. This occurred because one or more other trader(s) were closed out and did not have enough funds to cover their losses, and the market's insurance pool was empty.": "You received less {{assetSymbol}} in gains that you should have when the market moved in your favour. This occurred because one or more other trader(s) were closed out and did not have enough funds to cover their losses, and the market's insurance pool was empty.",
"Your open orders were cancelled.": "Your open orders were cancelled.",
"Your position is distressed.": "Your position is distressed.",
"Your position was closed.": "Your position was closed."
}
+46
View File
@@ -0,0 +1,46 @@
{
"[This is {{network}} transaction only]": "[This is {{network}} transaction only]",
"{{proposalChange}} proposal {{proposalState}}": "{{proposalChange}} proposal {{proposalState}}",
"<0>{{count}}</0> blocks": "<0>{{count}}</0> blocks",
"Awaiting network confirmation": "Awaiting network confirmation",
"blocks": "blocks",
"Changes have been proposed for this asset.": "Changes have been proposed for this asset.",
"Changes have been proposed for this market.": "Changes have been proposed for this market.",
"Closing date": "Closing date",
"Confirm transaction in wallet": "Confirm transaction in wallet",
"Enactment date: {{date}}": "Enactment date: {{date}}",
"Enactment date": "Enactment date",
"estimated time to protocol upgrade": "estimated time to protocol upgrade",
"estimating...": "estimating...",
"Market": "Market",
"Network upgrade in {{countdown}}": "Network upgrade in {{countdown}}",
"No proposed markets": "No proposed markets",
"Parent market": "Parent market",
"Please open your wallet application and confirm or reject the transaction": "Please open your wallet application and confirm or reject the transaction",
"Please wait for your transaction to be confirmed": "Please wait for your transaction to be confirmed",
"Proposal declined": "Proposal declined",
"Proposal enacted": "Proposal enacted",
"Proposal failed": "Proposal failed",
"Proposal passed": "Proposal passed",
"Proposal rejected": "Proposal rejected",
"Proposal submitted": "Proposal submitted",
"Proposal waiting for node vote": "Proposal waiting for node vote",
"Rejection reason: {{reason}}": "Rejection reason: {{reason}}",
"Settlement asset": "Settlement asset",
"State": "State",
"Submission failed": "Submission failed",
"The network is being upgraded to {{vegaReleaseTag}}": "The network is being upgraded to {{vegaReleaseTag}}",
"The network will upgrade to {{vegaReleaseTag}} in {{countdown}}": "The network will upgrade to {{vegaReleaseTag}} in {{countdown}}",
"Trading activity will be interrupted, manage your risk appropriately.": "Trading activity will be interrupted, manage your risk appropriately.",
"Trading and other network activity has stopped until the upgrade is complete.": "Trading and other network activity has stopped until the upgrade is complete.",
"Transaction complete": "Transaction complete",
"Transaction failed": "Transaction failed",
"Unknown proposal {{proposalState}}": "Unknown proposal {{proposalState}}",
"Update <0>{{key}}</0> to {{value}}": "Update <0>{{key}}</0> to {{value}}",
"View details": "View details",
"View in block explorer": "View in block explorer",
"View proposal details": "View proposal details",
"View proposal": "View proposal",
"Voting": "Voting",
"Your transaction has been confirmed": "Your transaction has been confirmed"
}
+6
View File
@@ -0,0 +1,6 @@
{
"Created at": "Created at",
"No trades": "No trades",
"Price": "Price",
"Size": "Size"
}
+22 -1
View File
@@ -2,6 +2,7 @@
"(Combined set volume {{runningVolume}} over last {{epochs}} epochs)": "(Combined set volume {{runningVolume}} over last {{epochs}} epochs)",
"(Created at: {{createdAt}})": "(Created at: {{createdAt}})",
"{{amount}} $VEGA staked": "{{amount}} $VEGA staked",
"{{assetSymbol}} Reward pot": "{{assetSymbol}} Reward pot",
"{{checkedAssets}} Assets": "{{checkedAssets}} Assets",
"{{distance}} ago": "{{distance}} ago",
"{{instrumentCode}} liquidity provision": "{{instrumentCode}} liquidity provision",
@@ -17,7 +18,9 @@
"Anyone with the referral link can apply it to their key(s) of choice via an on chain transaction": "Anyone with the referral link can apply it to their key(s) of choice via an on chain transaction",
"Asset (1)": "Asset (1)",
"Assets": "Assets",
"Available to withdraw this epoch": "Available to withdraw this epoch",
"Base commission rate": "Base commission rate",
"Base rate": "Base rate",
"Best bid": "Best bid",
"Best offer": "Best offer",
"Browse": "Browse",
@@ -71,6 +74,7 @@
"Discounts are applied automatically during trading based on the key(s) used": "Discounts are applied automatically during trading based on the key(s) used",
"Docs": "Docs",
"Earn commission & stake rewards": "Earn commission & stake rewards",
"Earned by me": "Earned by me",
"Enactment date reached and usual auction exit checks pass": "Enactment date reached and usual auction exit checks pass",
"Environment not configured": "Environment not configured",
"epochs in referral set": "epochs in referral set",
@@ -96,6 +100,7 @@
"Funding Rate": "Funding Rate",
"Funding rate": "Funding rate",
"Futures": "Futures",
"From epoch": "From epoch",
"Generate a referral code to share with your friends and start earning commission.": "Generate a referral code to share with your friends and start earning commission.",
"Generate code": "Generate code",
"Get started": "Get started",
@@ -109,6 +114,7 @@
"Help identify bugs and improve the service by sharing anonymous usage data.": "Help identify bugs and improve the service by sharing anonymous usage data.",
"Help us identify bugs and improve Vega Governance by sharing anonymous usage data.": "Help us identify bugs and improve Vega Governance by sharing anonymous usage data.",
"Hide closed markets": "Hide closed markets",
"Hoarder reward multiplier": "Hoarder reward multiplier",
"How it works": "How it works",
"I want a code": "I want a code",
"Improve vega console": "Improve vega console",
@@ -122,6 +128,7 @@
"Liquidity": "Liquidity",
"Liquidity fees": "Liquidity fees",
"Liquidity supplied": "Liquidity supplied",
"Locked {{assetSymbol}}": "Locked {{assetSymbol}}",
"Low fees and no cost to place orders": "Low fees and no cost to place orders",
"Mainnet status & incidents": "Mainnet status & incidents",
"Make withdrawal": "Make withdrawal",
@@ -157,6 +164,7 @@
"No perpetual markets.": "No perpetual markets.",
"No referral program active": "No referral program active",
"No rejected orders": "No rejected orders",
"No rewards": "No rewards",
"No thanks": "No thanks",
"No third party has access to your funds.": "No third party has access to your funds.",
"No volume discount program active": "No volume discount program active",
@@ -165,6 +173,7 @@
"Non-custodial and pseudonymous": "Non-custodial and pseudonymous",
"None": "None",
"Number of traders": "Number of traders",
"Not connected": "Not connected",
"Open": "Open",
"Open a position": "Open a position",
"Open markets": "Open markets",
@@ -176,7 +185,7 @@
"Parent of a market": "Parent of a market",
"Past {{count}} epochs": "Past {{count}} epochs",
"Perpetuals": "Perpetuals",
"Please choose another market from the <0>market list<0>": "Please choose another market from the <0>market list<0>",
"Please choose another market from the <0>market list</0>": "Please choose another market from the <0>market list</0>",
"Please connect Vega wallet": "Please connect Vega wallet",
"Portfolio": "Portfolio",
"Positions": "Positions",
@@ -193,6 +202,7 @@
"Read the terms": "Read the terms",
"Ready to trade": "Ready to trade",
"Ready to trade with real funds? <0>Switch to Mainnet</0>": "Ready to trade with real funds? <0>Switch to Mainnet</0>",
"Redeem rewards": "Redeem rewards",
"Referral benefits": "Referral benefits",
"Referral discount": "Referral discount",
"referral-statistics-commission": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
@@ -205,6 +215,9 @@
"Required epochs": "Required epochs",
"Required for next tier": "Required for next tier",
"Resources": "Resources",
"Rewards": "Rewards",
"Rewards history": "Rewards history",
"Rewards multipliers": "Rewards multipliers",
"SCCR": "SCCR",
"Search": "Search",
"See all markets": "See all markets",
@@ -229,10 +242,12 @@
"Status": "Status",
"Stop": "Stop",
"Stop orders": "Stop orders",
"Streak reward multiplier": "Streak reward multiplier",
"Successor of a market": "Successor of a market",
"Successors to this market have been proposed": "Successors to this market have been proposed",
"Supplied stake": "Supplied stake",
"Suspended due to price or liquidity monitoring trigger": "Suspended due to price or liquidity monitoring trigger",
"to": "to",
"Target stake": "Target stake",
"The amount of fees paid to liquidity providers across the whole market during the last epoch {{epoch}}.": "The amount of fees paid to liquidity providers across the whole market during the last epoch {{epoch}}.",
"The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee": "The commission is taken from the infrastructure fee, maker fee, and liquidity provider fee, not from the referee",
@@ -254,6 +269,7 @@
"Toast location": "Toast location",
"Total commission (last {{count}}} epochs)": "Total commission (last {{count}}} epochs)",
"Total discount": "Total discount",
"Total distributed": "Total distributed",
"Total fee after discount": "Total fee after discount",
"Total fee before discount": "Total fee before discount",
"Trader": "Trader",
@@ -267,6 +283,10 @@
"Transfer": "Transfer",
"Unknown": "Unknown",
"Unknown settlement date": "Unknown settlement date",
"Vega Reward pot": "Vega Reward pot",
"Vesting": "Vesting",
"Vesting {{assetSymbol}}": "Vesting {{assetSymbol}}",
"Vesting multiplier": "Vesting multiplier",
"View as party": "View as party",
"View liquidity provision table": "View liquidity provision table",
"View on Explorer": "View on Explorer",
@@ -284,6 +304,7 @@
"We're sorry but we don't have an active referral programme currently running. You can propose a new programme <0>here</0>.": "We're sorry but we don't have an active referral programme currently running. You can propose a new programme <0>here</0>.",
"Welcome to Vega trading!": "Welcome to Vega trading!",
"Withdraw": "Withdraw",
"You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs.": "You are joining the group shown, but will not have access to benefits until you have completed at least {{count}} epochs.",
"You can opt out any time via settings": "You can opt out any time via settings",
"You may encounter bugs, loss of functionality or loss of assets.": "You may encounter bugs, loss of functionality or loss of assets.",
"You must be connected to the Vega wallet.": "You must be connected to the Vega wallet.",
+21
View File
@@ -0,0 +1,21 @@
{
"{{fee}} Fee": "{{fee}} Fee",
"Auction Trigger stake {{trigger}}": "Auction Trigger stake {{trigger}}",
"Collapse": "Collapse",
"Copied": "Copied",
"Dark mode": "Dark mode",
"Dismiss all toasts": "Dismiss all toasts",
"Dismiss all": "Dismiss all",
"Exit view as": "Exit view as",
"Expand": "Expand",
"Light mode": "Light mode",
"Loading...": "Loading...",
"No data": "No data",
"Providers greater than 2x target stake not shown": "Providers greater than 2x target stake not shown",
"Show more": "Show more",
"Something went wrong: {{errorMessage}}": "Something went wrong: {{errorMessage}}",
"Target stake {{target}}": "Target stake {{target}}",
"This is an example of a toast notification": "This is an example of a toast notification",
"Try again": "Try again",
"Viewing as Vega user: {{pubKey}}": "Viewing as Vega user: {{pubKey}}"
}
+15
View File
@@ -0,0 +1,15 @@
{
"Expired on {{date}}": "Expired on {{date}}",
"Not time-based": "Not time-based",
"Expired": "Expired",
"Mark": "Mark",
"Required": "Required",
"Invalid Ethereum address": "Invalid Ethereum address",
"Invalid Vega key": "Invalid Vega key",
"Value is below minimum": "Value is below minimum",
"Value is above maximum": "Value is above maximum",
"Must be valid JSON": "Must be valid JSON",
"{{field}} must be a multiple of {{step}} for this market": "{{field}} must be a multiple of {{step}} for this market",
"{{field}} must be whole numbers for this market": "{{field}} must be whole numbers for this market",
"{{field}} accepts up to {{decimals}} decimal places": "{{field}} accepts up to {{decimals}} decimal places"
}
+63
View File
@@ -0,0 +1,63 @@
{
"About the Vega wallet": "About the Vega wallet",
"Supported browsers": "Supported browsers",
"Connect Vega wallet": "Connect Vega wallet",
"Get a Vega wallet": "Get a Vega wallet",
"Connect securely, deposit funds and approve or reject transactions with the Vega wallet": "Connect securely, deposit funds and approve or reject transactions with the Vega wallet",
"Connect": "Connect",
"Vega Wallet <0>full featured<0>": "Vega Wallet <0>full featured<0>",
"your browser": "your browser",
"Connect with Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.": "Connect with Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.",
"Install Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.": "Install Vega Wallet extension for {{browserName}} to access all features including key management and detailed transaction views from your browser.",
"Metamask Snap <0>quick start</0>": "Metamask Snap <0>quick start</0>",
"Connect directly via Metamask with the Vega Snap for single key support without advanced features.": "Connect directly via Metamask with the Vega Snap for single key support without advanced features.",
"Connect via Vega MetaMask Snap": "Connect via Vega MetaMask Snap",
"Install Metamask with the Vega Snap for single key support without advanced features.": "Install Metamask with the Vega Snap for single key support without advanced features.",
"Install Vega MetaMask Snap": "Install Vega MetaMask Snap",
"No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>": "No MetaMask version that supports snaps detected. Learn more about <0>MetaMask Snaps</0>",
"Advanced / Other options...": "Advanced / Other options...",
"View as party": "View as party",
"Get the Vega Wallet": "Get the Vega Wallet",
"Custom wallet location": "Custom wallet location",
"Go back": "Go back",
"Connect the App/CLI": "Connect the App/CLI",
"Use the Desktop App/CLI": "Use the Desktop App/CLI",
"Enter a custom wallet location": "Enter a custom wallet location",
"<0>No running Desktop App/CLI detected. Open your app now to connect or enter a</0> <1>custom wallet location</1>": "<0>No running Desktop App/CLI detected. Open your app now to connect or enter a</0> <1>custom wallet location</1>",
"Verifying chain": "Verifying chain",
"Successfully connected": "Successfully connected",
"Connecting...": "Connecting...",
"Approve the connection from your Vega wallet app. If you have multiple wallets you'll need to choose which to connect with.": "Approve the connection from your Vega wallet app. If you have multiple wallets you'll need to choose which to connect with.",
"Understand the risk": "Understand the risk",
"Cancel": "Cancel",
"I agree": "I agree",
"Something went wrong": "Something went wrong",
"An unknown error occurred": "An unknown error occurred",
"Try again": "Try again",
"User rejected": "User rejected",
"The user rejected the wallet connection": "The user rejected the wallet connection",
"Wrong network": "Wrong network",
"No wallet detected": "No wallet detected",
"Vega browser extension not installed": "Vega browser extension not installed",
"Snap failed": "Snap failed",
"Could not connect to Vega MetaMask Snap": "Could not connect to Vega MetaMask Snap",
"No wallet application running at {{connectorUrl}}": "No wallet application running at {{connectorUrl}}",
"No Vega Wallet application running": "No Vega Wallet application running",
"Read the docs to troubleshoot": "Read the docs to troubleshoot",
"Connection in progress": "Connection in progress",
"Approve the connection from your Vega wallet app.": "Approve the connection from your Vega wallet app.",
"To complete your wallet connection, set your wallet network in your app to \"{{appChainId}}\".": "To complete your wallet connection, set your wallet network in your app to \"{{appChainId}}\".",
"SELECT A VEGA KEY": "SELECT A VEGA KEY",
"Select": "Select",
"Copy": "Copy",
"Disconnect all keys": "Disconnect all keys",
"Pubkey must be 64 characters in length": "Pubkey must be 64 characters in length",
"Pubkey must be be valid hex": "Pubkey must be be valid hex",
"VIEW AS VEGA USER": "VIEW AS VEGA USER",
"Browse from the perspective of another Vega user in read-only mode.": "Browse from the perspective of another Vega user in read-only mode.",
"Required": "Required",
"Browse network": "Browse network",
"Checking wallet version": "Checking wallet version",
"Checking your wallet is compatible with this app": "Checking your wallet is compatible with this app",
"Wrong Network": "Wrong Network"
}
+110
View File
@@ -0,0 +1,110 @@
{
"{{title}} complete": "{{title}} complete",
"{{title}} failed": "{{title}} failed",
"{{title}} pending": "{{title}} pending",
"Action required": "Action required",
"Approved": "Approved",
"Await Ethereum transaction": "Await Ethereum transaction",
"Awaiting confirmation": "Awaiting confirmation",
"Awaiting confirmations {{confirmations}}/{[requiredConfirmations}}": "Awaiting confirmations {{confirmations}}/{[requiredConfirmations}}",
"Awaiting Ethereum transaction {{confirmations}}/{{requiredConfirmations}} confirmations...": "Awaiting Ethereum transaction {{confirmations}}/{{requiredConfirmations}} confirmations...",
"Batch market instruction": "Batch market instruction",
"Cancel all orders": "Cancel all orders",
"Cancel all orders for <strong>{{marketName}}</strong>": "Cancel all orders for <strong>{{marketName}}</strong>",
"Cancel all stop orders": "Cancel all stop orders",
"Cancel all stop orders for <strong>{{marketName}}</strong>": "Cancel all stop orders for <strong>{{marketName}}</strong>",
"Cancel order": "Cancel order",
"Cancel order - {{status}}": "Cancel order - {{status}}",
"Cancel stop order": "Cancel stop order",
"Cannot be completed until {{time}}": "Cannot be completed until {{time}}",
"Change network": "Change network",
"Close": "Close",
"Close position for <strong>{{marketName}}</strong>": "Close position for <strong>{{marketName}}</strong>",
"Coinbase": "Coinbase",
"Complete withdrawal": "Complete withdrawal",
"Confirm transaction": "Confirm transaction",
"Confirm transaction in wallet": "Confirm transaction in wallet",
"Confirmed": "Confirmed",
"Confirmed in wallet": "Confirmed in wallet",
"Connect to your Ethereum wallet": "Connect to your Ethereum wallet",
"Connect wallet": "Connect wallet",
"Connect wallet to withdraw": "Connect wallet to withdraw",
"Copy": "Copy",
"Delayed": "Delayed",
"Deposit": "Deposit",
"Edit order": "Edit order",
"Edit order - {{status}}": "Edit order - {{status}}",
"Error": "Error",
"Error occurred": "Error occurred",
"Error: {{errorMessage}}": "Error: {{errorMessage}}",
"Ethereum transaction complete": "Ethereum transaction complete",
"Filled": "Filled",
"Funds unlocked": "Funds unlocked",
"Go to your Ethereum wallet and connect to the network {{networkName}}": "Go to your Ethereum wallet and connect to the network {{networkName}}",
"If the network is reset or has an outage, records of your withdrawal may be lost. It is recommended that you save these details in a safe place so you can still complete your withdrawal.": "If the network is reset or has an outage, records of your withdrawal may be lost. It is recommended that you save these details in a safe place so you can still complete your withdrawal.",
"Invalid asset source: {{source}}": "Invalid asset source: {{source}}",
"Loading": "Loading",
"MetaMask": "MetaMask",
"MetaMask, Brave or other injected web wallet": "MetaMask, Brave or other injected web wallet",
"No data": "No data",
"Order cancelled'": "Order cancelled'",
"Order expired'": "Order expired'",
"Order filled": "Order filled",
"Order parked": "Order parked",
"Order partially filled": "Order partially filled",
"Order rejected": "Order rejected",
"Order stopped": "Order stopped",
"Order submitted": "Order submitted",
"Pending approval": "Pending approval",
"Please go to your Vega wallet application and approve or reject the transaction.": "Please go to your Vega wallet application and approve or reject the transaction.",
"Please go to your wallet application and approve or reject the transaction.": "Please go to your wallet application and approve or reject the transaction.",
"Please wait for your transaction to be confirmed": "Please wait for your transaction to be confirmed",
"Please wait for your transaction to be confirmed.": "Please wait for your transaction to be confirmed.",
"Processing": "Processing",
"Processing deposit": "Processing deposit",
"Return": "Return",
"Save withdrawal details": "Save withdrawal details",
"save your withdrawal details": "save your withdrawal details",
"Something went wrong": "Something went wrong",
"Submission failed": "Submission failed",
"Submit order": "Submit order",
"Submit order - {{status}}": "Submit order - {{status}}",
"Submit stop order": "Submit stop order",
"The amount you're withdrawing has triggered a time delay": "The amount you're withdrawing has triggered a time delay",
"The connection to your Vega Wallet has been lost.": "The connection to your Vega Wallet has been lost.",
"The withdrawal has been approved.": "The withdrawal has been approved.",
"To {{address}}": "To {{address}}",
"To complete this withdrawal, connect the Ethereum wallet {{receiverAddress}}": "To complete this withdrawal, connect the Ethereum wallet {{receiverAddress}}",
"Transaction confirmed": "Transaction confirmed",
"Transfer": "Transfer",
"Transfer complete": "Transfer complete",
"Unknown": "Unknown",
"Vega confirmation": "Vega confirmation",
"Vega is confirming your transaction...": "Vega is confirming your transaction...",
"Verifying withdrawal approval": "Verifying withdrawal approval",
"Verifying...": "Verifying...",
"View in block explorer": "View in block explorer",
"View on Etherscan": "View on Etherscan",
"View transaction on Etherscan": "View transaction on Etherscan",
"Waiting for deposit confirmation.": "Waiting for deposit confirmation.",
"Wallet disconnected": "Wallet disconnected",
"WalletConnect": "WalletConnect",
"WalletConnect Legacy": "WalletConnect Legacy",
"WalletConnect v1": "WalletConnect v1",
"WalletConnect v2": "WalletConnect v2",
"Withdraw": "Withdraw",
"Withdraw {{amount}} {{symbol}}": "Withdraw {{amount}} {{symbol}}",
"Withdraw dependencies not met.": "Withdraw dependencies not met.",
"Withdraw failure": "Withdraw failure",
"Your {{timeInForce}} order was not filled and it has been stopped": "Your {{timeInForce}} order was not filled and it has been stopped",
"Your Ethereum wallet is connected to the wrong network.": "Your Ethereum wallet is connected to the wrong network.",
"Your funds have been unlocked for withdrawal.": "Your funds have been unlocked for withdrawal.",
"Your order has been rejected": "Your order has been rejected",
"Your order has been rejected because: {{rejectionReason}}": "Your order has been rejected because: {{rejectionReason}}",
"Your order has been stopped": "Your order has been stopped",
"Your order has been stopped because: {{rejectionReason}}": "Your order has been stopped because: {{rejectionReason}}",
"Your order was rejected.": "Your order was rejected.",
"Your transaction has been completed.": "Your transaction has been completed.",
"Your transaction has been confirmed": "Your transaction has been confirmed",
"Your transaction has been confirmed.": "Your transaction has been confirmed."
}
+49
View File
@@ -0,0 +1,49 @@
{
"All {{symbol}} withdrawals are subject to a {{delay}} delay.": "All {{symbol}} withdrawals are subject to a {{delay}} delay.",
"Amount": "Amount",
"Asset": "Asset",
"Available to withdraw in {{availableTimestamp}}": "Available to withdraw in {{availableTimestamp}}",
"Balance available": "Balance available",
"Complete the withdrawal to release your funds": "Complete the withdrawal to release your funds",
"Complete these {{count}} withdrawals to release your funds": "Complete these {{count}} withdrawals to release your funds",
"Complete withdrawal": "Complete withdrawal",
"Completed": "Completed",
"Connect Ethereum wallet to complete": "Connect Ethereum wallet to complete",
"Connect": "Connect",
"Created": "Created",
"Delay time": "Delay time",
"Delayed (ready in {{readyIn}})": "Delayed (ready in {{readyIn}})",
"Delayed withdrawal threshold": "Delayed withdrawal threshold",
"Disconnect": "Disconnect",
"Failed": "Failed",
"Insufficient amount in account": "Insufficient amount in account",
"Invalid asset source: {{source}}": "Invalid asset source: {{source}}",
"No withdrawals": "No withdrawals",
"None": "None",
"Pending": "Pending",
"Please select an asset": "Please select an asset",
"Read more": "Read more",
"Ready to complete": "Ready to complete",
"Recipient": "Recipient",
"Rejected": "Rejected",
"Release funds": "Release funds",
"Status": "Status",
"Step 1 - Release funds from Vega": "Step 1 - Release funds from Vega",
"Step 2 - Transfer funds to your Ethereum wallet": "Step 2 - Transfer funds to your Ethereum wallet",
"There are two steps required to make a withdrawal": "There are two steps required to make a withdrawal",
"This app only works on {{chainName}}. Please change chain.": "This app only works on {{chainName}}. Please change chain.",
"To (Ethereum address)": "To (Ethereum address)",
"Transaction": "Transaction",
"Use maximum": "Use maximum",
"Verifying withdrawal approval": "Verifying withdrawal approval",
"View withdrawal details": "View withdrawal details",
"View withdrawals": "View withdrawals",
"Withdraw {{amount}} {{symbol}}": "Withdraw {{amount}} {{symbol}}",
"Withdraw funds": "Withdraw funds",
"Withdraw": "Withdraw",
"Withdrawal ready": "Withdrawal ready",
"Withdrawals of {{threshold}} {{symbol}} or more will be delayed for {{delay}}.": "Withdrawals of {{threshold}} {{symbol}} or more will be delayed for {{delay}}.",
"Withdrawals ready": "Withdrawals ready",
"You have no assets to withdraw": "You have no assets to withdraw",
"Your funds have been unlocked for withdrawal - <0>View in block explorer<0>": "Your funds have been unlocked for withdrawal - <0>View in block explorer<0>"
}
+14
View File
@@ -0,0 +1,14 @@
export const useTranslation = () => ({
t: (label: string, replacements?: Record<string, string>) => {
let translatedLabel = label;
if (typeof replacements === 'object' && replacements !== null) {
Object.keys(replacements).forEach((key) => {
translatedLabel = translatedLabel.replace(
`{{${key}}}`,
replacements[key]
);
});
}
return translatedLabel;
},
});
+66 -56
View File
@@ -3,8 +3,8 @@ import type { ReactNode } from 'react';
import { useCallback, useEffect } from 'react';
import type { Toast } from '@vegaprotocol/ui-toolkit';
import { useToasts, Intent } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { subscribeWithSelector } from 'zustand/middleware';
import { useT } from './use-t';
type DownloadSettings = {
title: string;
@@ -52,24 +52,31 @@ export const useLedgerDownloadFile = create<LedgerDownloadFileStore>()(
}))
);
const ErrorContent = ({ message }: { message?: string }) => (
<>
<h4 className="mb-1 text-sm">{t('Something went wrong')}</h4>
<p>{message || t('Try again later')}</p>
</>
);
const ErrorContent = ({ message }: { message?: string }) => {
const t = useT();
return (
<>
<h4 className="mb-1 text-sm">{t('Something went wrong')}</h4>
<p>{message || t('Try again later')}</p>
</>
);
};
const InfoContent = ({ progress = false }) => (
<>
<p>{t('Please note this can take several minutes.')}</p>
<p>{t('You will be notified here when your file is ready.')}</p>
<h4 className="my-2">
{progress ? t('Still in progress') : t('Download has been started')}
</h4>
</>
);
const InfoContent = ({ progress = false }) => {
const t = useT();
return (
<>
<p>{t('Please note this can take several minutes.')}</p>
<p>{t('You will be notified here when your file is ready.')}</p>
<h4 className="my-2">
{progress ? t('Still in progress') : t('Download has been started')}
</h4>
</>
);
};
export const useLedgerDownloadManager = () => {
const t = useT();
const queue = useLedgerDownloadFile((store) => store.queue);
const updateQueue = useLedgerDownloadFile((store) => store.updateQueue);
const removeItem = useLedgerDownloadFile((store) => store.removeItem);
@@ -88,48 +95,51 @@ export const useLedgerDownloadManager = () => {
[removeToast, removeItem]
);
const createToast = (item: DownloadSettings) => {
let content: ReactNode;
switch (true) {
case item.isError:
content = <ErrorContent message={item.errorMessage} />;
break;
case Boolean(item.blob):
content = (
const createToast = useCallback(
(item: DownloadSettings) => {
let content: ReactNode;
switch (true) {
case item.isError:
content = <ErrorContent message={item.errorMessage} />;
break;
case Boolean(item.blob):
content = (
<>
<h4 className="mb-1 text-sm">{t('Your file is ready')}</h4>
<a
onClick={() => onDownloadClose(item.link)}
href={URL.createObjectURL(item.blob as Blob)}
download={item.filename}
className="underline"
>
{t('Get file here')}
</a>
</>
);
break;
default:
content = <InfoContent progress={item.isDelayed} />;
}
const toast: Toast = {
id: item.link,
intent: item.intent || Intent.Primary,
content: (
<>
<h4 className="mb-1 text-sm">{t('Your file is ready')}</h4>
<a
onClick={() => onDownloadClose(item.link)}
href={URL.createObjectURL(item.blob as Blob)}
download={item.filename}
className="underline"
>
{t('Get file here')}
</a>
<h3 className="mb-1 text-md uppercase">{item.title}</h3>
{content}
</>
);
break;
default:
content = <InfoContent progress={item.isDelayed} />;
}
const toast: Toast = {
id: item.link,
intent: item.intent || Intent.Primary,
content: (
<>
<h3 className="mb-1 text-md uppercase">{item.title}</h3>
{content}
</>
),
onClose: () => onDownloadClose(item.link),
loader: !item.isDownloaded && !item.isError,
};
if (hasToast(toast.id)) {
updateToast(toast.id, toast);
} else {
setToast(toast);
}
};
),
onClose: () => onDownloadClose(item.link),
loader: !item.isDownloaded && !item.isError,
};
if (hasToast(toast.id)) {
updateToast(toast.id, toast);
} else {
setToast(toast);
}
},
[hasToast, setToast, onDownloadClose, updateToast, t]
);
useEffect(() => {
queue.forEach((item) => {
+12 -8
View File
@@ -14,9 +14,9 @@ import {
toNanoSeconds,
VEGA_ID_REGEX,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { localLoggerFactory } from '@vegaprotocol/logger';
import { useLedgerDownloadFile } from './ledger-download-store';
import { useT } from './use-t';
const DEFAULT_EXPORT_FILE_NAME = 'ledger_entries.csv';
@@ -70,6 +70,7 @@ interface Props {
}
export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => {
const t = useT();
const now = useRef(new Date());
const [dateFrom, setDateFrom] = useState(() => {
return formatForInput(subDays(now.current, 7));
@@ -116,11 +117,14 @@ export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => {
const startDownload = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const title = t('Downloading for %s from %s till %s', [
assets[assetId],
format(new Date(dateFrom), 'dd MMMM yyyy HH:mm'),
format(new Date(dateTo || Date.now()), 'dd MMMM yyyy HH:mm'),
]);
const title = t(
'Downloading for {{asset}} from {{startDate}} till {{endDate}}',
{
asset: assets[assetId],
startDate: format(new Date(dateFrom), 'dd MMMM yyyy HH:mm'),
endDate: format(new Date(dateTo || Date.now()), 'dd MMMM yyyy HH:mm'),
}
);
const downloadStoreItem = {
title,
@@ -225,8 +229,8 @@ export const LedgerExportForm = ({ partyId, vegaUrl, assets }: Props) => {
{offset && (
<p className="text-xs text-neutral-400 mt-1">
{t(
'The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC%s.',
[toHoursAndMinutes(offset)]
'The downloaded file uses the UTC time zone for all listed times. Your time zone is UTC{{offset}}.',
{ offset: toHoursAndMinutes(offset) }
)}
</p>
)}
+3
View File
@@ -0,0 +1,3 @@
import { useTranslation } from 'react-i18next';
export const useT = () => useTranslation('ledger').t;
+14
View File
@@ -0,0 +1,14 @@
export const useTranslation = () => ({
t: (label: string, replacements?: Record<string, string>) => {
let translatedLabel = label;
if (typeof replacements === 'object' && replacements !== null) {
Object.keys(replacements).forEach((key) => {
translatedLabel = translatedLabel.replace(
`{{${key}}}`,
replacements[key]
);
});
}
return translatedLabel;
},
});
@@ -1,24 +1,60 @@
import LiquidityTable from './liquidity-table';
import { act, render, screen } from '@testing-library/react';
import { act, render, screen, within } from '@testing-library/react';
import * as Schema from '@vegaprotocol/types';
import type { LiquidityProvisionData } from './liquidity-data-provider';
import userEvent from '@testing-library/user-event';
const singleRow = {
party: 'a3f762f0a6e998e1d0c6e73017a13ec8a22386c30f7f64a1bdca47330bc592dd',
const partyId1 = 'party1';
const partyId2 = 'party2';
const singleRow: LiquidityProvisionData = {
id: 'lp-single',
commitmentMinTimeFraction: '100',
performanceHysteresisEpochs: 4,
priceRange: '1',
slaCompetitionFactor: '1',
partyId: partyId1,
party: {
id: partyId1,
},
createdAt: '2022-08-19T17:18:36.257028Z',
updatedAt: '2022-08-19T17:18:36.257028Z',
commitmentAmount: '56298653179',
commitmentAmount: '100',
fee: '0.001',
status: Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
feeShare: {
equityLikeShare: '0.5',
averageEntryValuation: '0.5',
virtualStake: '0.5',
averageScore: '0.5',
},
supplied: '67895',
obligation: '56785',
} as unknown as LiquidityProvisionData;
};
const multiRow: LiquidityProvisionData = {
id: 'lp-multi',
commitmentMinTimeFraction: '100',
performanceHysteresisEpochs: 4,
priceRange: '1',
slaCompetitionFactor: '1',
partyId: partyId2,
party: {
id: partyId2,
},
createdAt: '2022-08-19T17:18:37.257028Z',
updatedAt: '2022-08-19T17:18:37.257028Z',
commitmentAmount: '200',
fee: '0.002',
status: Schema.LiquidityProvisionStatus.STATUS_ACTIVE,
feeShare: {
equityLikeShare: '0.5',
averageEntryValuation: '0.5',
virtualStake: '0.5',
averageScore: '0.5',
},
};
const singleRowData = [singleRow];
const multiRowData = [singleRow, multiRow];
describe('LiquidityTable', () => {
it('should render successfully', async () => {
@@ -26,6 +62,10 @@ describe('LiquidityTable', () => {
const { baseElement } = render(
<LiquidityTable rowData={[]} stakeToCcyVolume={'1'} />
);
// 5002-LIQP-002
// 5002-LIQP-004
// 5002-LIQP-005
// 5002-LIQP-011
expect(baseElement).toBeTruthy();
});
});
@@ -65,7 +105,30 @@ describe('LiquidityTable', () => {
'Created',
'Updated',
];
// 5002-LIQP-001
expect(headers).toHaveLength(expectedHeaders.length);
expect(headerTexts).toEqual(expectedHeaders);
});
it('should be able to sort', async () => {
await act(async () => {
render(
<LiquidityTable rowData={multiRowData} stakeToCcyVolume={'0.3'} />
);
});
const headers = await screen.findAllByRole('columnheader');
const commitmentHeader = headers.find(
(h) => h.getAttribute('col-id') === 'commitmentAmount'
);
if (!commitmentHeader) {
throw new Error('No commitment header found');
}
// 5002-LIQP-003
expect(commitmentHeader).toHaveAttribute('aria-sort', 'none');
await userEvent.click(within(commitmentHeader).getByText(/commitment/i));
expect(commitmentHeader).toHaveAttribute('aria-sort', 'ascending');
});
});
+14 -13
View File
@@ -4,7 +4,6 @@ import {
addDecimalsFormatNumberQuantum,
getDateTimeFormat,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import type {
TypedDataAgGrid,
VegaICellRendererParams,
@@ -27,6 +26,7 @@ import BigNumber from 'bignumber.js';
import { LiquidityProvisionStatus } from '@vegaprotocol/types';
import { LiquidityProvisionStatusMapping } from '@vegaprotocol/types';
import type { LiquidityProvisionData } from './liquidity-data-provider';
import { useT } from './use-t';
const formatNumberPercentage = (value: BigNumber, decimals?: number) => {
const decimalPlaces =
@@ -81,6 +81,7 @@ export const LiquidityTable = ({
quantum,
...props
}: LiquidityTableProps) => {
const t = useT();
const colDefs = useMemo(() => {
const assetDecimalsFormatter = ({ value }: ITooltipParams) => {
if (!value) return '-';
@@ -125,32 +126,32 @@ export const LiquidityTable = ({
}
if (lessThanMinimum) {
return t(
`This LP's time on the book in the current epoch (%s) is less than the minimum required (%s), so they could lose all fee revenue for this epoch.`,
[
formatNumberPercentage(
"This LP's time on the book in the current epoch ({{currentEpoch}}) is less than the minimum required ({{minimumRequired}}), so they could lose all fee revenue for this epoch.",
{
currentEpoch: formatNumberPercentage(
new BigNumber(data.sla.currentEpochFractionOfTimeOnBook).times(
100
),
4
),
formatNumberPercentage(
minimumRequired: formatNumberPercentage(
new BigNumber(data.commitmentMinTimeFraction).times(100),
4
),
]
}
);
}
if (lessThanFull) {
return t(
`This LP's time on the book in the current epoch (%s) is less than 100%, so they could lose some fees to a better performing LP.`,
[
formatNumberPercentage(
"This LP's time on the book in the current epoch ({{currentEpoch}}) is less than 100%, so they could lose some fees to a better performing LP.",
{
currentEpoch: formatNumberPercentage(
new BigNumber(data.sla.currentEpochFractionOfTimeOnBook).times(
100
),
4
),
]
}
);
}
return addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0);
@@ -219,7 +220,7 @@ export const LiquidityTable = ({
},
},
{
headerName: t(`Commitment (${symbol})`),
headerName: t(`Commitment ({{symbol}})`, { symbol }),
field: 'commitmentAmount',
type: 'rightAligned',
headerTooltip: t(
@@ -399,7 +400,7 @@ export const LiquidityTable = ({
headerTooltip: t(
`The liquidity fees accrued by each provider, which will be distributed at the end of the epoch after applying any penalties.`
),
valueFormatter: stakeToCcyVolumeQuantumFormatter,
valueFormatter: assetDecimalsQuantumFormatter,
tooltipValueGetter: feesAccruedTooltip,
cellClassRules: {
'text-warning': ({ data }: { data: LiquidityProvisionData }) => {
@@ -495,7 +496,7 @@ export const LiquidityTable = ({
},
];
return defs;
}, [assetDecimalPlaces, quantum, stakeToCcyVolume, symbol]);
}, [assetDecimalPlaces, quantum, stakeToCcyVolume, symbol, t]);
return (
<AgGrid
overlayNoRowsTemplate={t('No liquidity provisions')}
+3
View File
@@ -0,0 +1,3 @@
import { useTranslation } from 'react-i18next';
export const useT = () => useTranslation('liquidity').t;
@@ -0,0 +1,15 @@
export const useTranslation = () => ({
t: (label: string, replacements?: Record<string, string>) => {
const replace =
replacements?.replace && typeof replacements === 'object'
? replacements?.replace
: replacements;
let translatedLabel = replacements?.defaultValue || label;
if (typeof replace === 'object' && replace !== null) {
Object.keys(replace).forEach((key) => {
translatedLabel = translatedLabel.replace(`{{${key}}}`, replace[key]);
});
}
return translatedLabel;
},
});
+2 -1
View File
@@ -2,7 +2,6 @@ import { DepthChart } from 'pennant';
import throttle from 'lodash/throttle';
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
import { addDecimal, getNumberFormat } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { useDataProvider } from '@vegaprotocol/data-provider';
import { marketDepthProvider } from './market-depth-provider';
@@ -16,6 +15,7 @@ import {
} from './__generated__/MarketDepth';
import { type DepthChartProps } from 'pennant';
import { parseLevel, updateLevels } from './depth-chart-utils';
import { useT } from './use-t';
interface DepthChartManagerProps {
marketId: string;
@@ -39,6 +39,7 @@ const getMidPrice = (
type DepthData = Pick<DepthChartProps, 'data' | 'midPrice'>;
export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
const t = useT();
const { theme } = useThemeSwitcher();
const variables = useMemo(() => ({ marketId }), [marketId]);
const [depthData, setDepthData] = useState<DepthData | null>(null);
+3 -1
View File
@@ -1,7 +1,6 @@
import { useMemo, useRef, useState } from 'react';
import ReactVirtualizedAutoSizer from 'react-virtualized-auto-sizer';
import { addDecimalsFormatNumber } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { usePrevious } from '@vegaprotocol/react-helpers';
import { OrderbookRow } from './orderbook-row';
import type { OrderbookRowData } from './orderbook-data';
@@ -10,6 +9,7 @@ import { Splash, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import classNames from 'classnames';
import type { PriceLevelFieldsFragment } from './__generated__/MarketDepth';
import { OrderbookControls } from './orderbook-controls';
import { useT } from './use-t';
// Sets row height, will be used to calculate number of rows that can be
// displayed each side of the book without overflow
@@ -85,6 +85,7 @@ export const OrderbookMid = ({
bestAskPrice: string;
bestBidPrice: string;
}) => {
const t = useT();
const previousLastTradedPrice = usePrevious(lastTradedPrice);
const priceChangeRef = useRef<'up' | 'down' | 'none'>('none');
const spread = (BigInt(bestAskPrice) - BigInt(bestBidPrice)).toString();
@@ -153,6 +154,7 @@ export const Orderbook = ({
bids,
assetSymbol,
}: OrderbookProps) => {
const t = useT();
const [resolution, setResolution] = useState(1);
const groupedAsks = useMemo(() => {
+3
View File
@@ -0,0 +1,3 @@
import { useTranslation } from 'react-i18next';
export const useT = () => useTranslation('market-depth').t;
+3 -2
View File
@@ -3,12 +3,12 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type MarketsDataFieldsFragment = { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, market: { __typename?: 'Market', id: string } };
export type MarketsDataFieldsFragment = { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, openInterest: string, market: { __typename?: 'Market', id: string } };
export type MarketsDataQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type MarketsDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, market: { __typename?: 'Market', id: string } } | null } }> } | null };
export type MarketsDataQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', data?: { __typename?: 'MarketData', bestBidPrice: string, bestOfferPrice: string, markPrice: string, trigger: Types.AuctionTrigger, staticMidPrice: string, marketState: Types.MarketState, marketTradingMode: Types.MarketTradingMode, indicativeVolume: string, indicativePrice: string, bestStaticBidPrice: string, bestStaticOfferPrice: string, targetStake?: string | null, suppliedStake?: string | null, auctionStart?: string | null, auctionEnd?: string | null, openInterest: string, market: { __typename?: 'Market', id: string } } | null } }> } | null };
export const MarketsDataFieldsFragmentDoc = gql`
fragment MarketsDataFields on MarketData {
@@ -30,6 +30,7 @@ export const MarketsDataFieldsFragmentDoc = gql`
suppliedStake
auctionStart
auctionEnd
openInterest
}
`;
export const MarketsDataDocument = gql`
@@ -7,10 +7,10 @@ import {
} from '@vegaprotocol/utils';
import { PriceChangeCell, signedNumberCssClass } from '@vegaprotocol/datagrid';
import { Tooltip, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import { t } from '@vegaprotocol/i18n';
import { useCandles } from '../../hooks/use-candles';
import BigNumber from 'bignumber.js';
import classNames from 'classnames';
import { useT } from '../../use-t';
interface Props {
marketId?: string;
@@ -25,6 +25,7 @@ export const Last24hPriceChange = ({
decimalPlaces,
initialValue,
}: Props) => {
const t = useT();
const { oneDayCandles, error, fiveDaysCandles } = useCandles({
marketId,
});
@@ -1,8 +1,8 @@
import { calcCandleVolume } from '../../market-utils';
import { addDecimalsFormatNumber, isNumeric } from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import { Tooltip } from '@vegaprotocol/ui-toolkit';
import { useCandles } from '../../hooks';
import { useT } from '../../use-t';
interface Props {
marketId?: string;
@@ -17,6 +17,7 @@ export const Last24hVolume = ({
formatDecimals,
initialValue,
}: Props) => {
const t = useT();
const { oneDayCandles, fiveDaysCandles } = useCandles({
marketId,
});
@@ -41,8 +42,8 @@ export const Last24hVolume = ({
<div>
<span className="flex flex-col">
{t(
'24 hour change is unavailable at this time. The volume change in the last 120 hours is %s',
[candleVolumeValue]
'24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}}',
{ candleVolumeValue }
)}
</span>
</div>
@@ -2,7 +2,6 @@ import {
addDecimalsFormatNumber,
formatNumberPercentage,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
import {
Intent,
KeyValueTable,
@@ -13,9 +12,10 @@ import {
import BigNumber from 'bignumber.js';
import startCase from 'lodash/startCase';
import { tooltipMapping } from './tooltip-mapping';
import { useTooltipMapping } from './tooltip-mapping';
import type { ReactNode } from 'react';
import { useT } from '../../use-t';
interface RowProps {
field: string;
value: ReactNode;
@@ -39,6 +39,8 @@ export const Row = ({
parentValue,
hasParentData,
}: RowProps) => {
const t = useT();
const tooltipMapping = useTooltipMapping();
// Note: we need both 'parentValue' and 'hasParentData' to do a conditional
// check to differentiate between when parentData itself is missing and when
// a specific parentValue is missing. These values are only used when we

Some files were not shown because too many files have changed in this diff Show More