Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa2d1e3aa5 | ||
|
|
9ba55d95d8 | ||
|
|
2355099bce |
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Feature Epic
|
||||
about: A template to capture and scope user requirements, high level process, and basic mockups for an upcoming feature as part of the initial core spec review process.
|
||||
title: 'FEATURE EPIC: '
|
||||
title: 'Epic: '
|
||||
labels: feature-epic
|
||||
---
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ on:
|
||||
jobs:
|
||||
run-tests:
|
||||
name: run-tests
|
||||
runs-on: 8-cores
|
||||
timeout-minutes: 20
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
#----------------------------------------------
|
||||
# check-out frontend-monorepo
|
||||
@@ -125,7 +125,7 @@ jobs:
|
||||
#----------------------------------------------
|
||||
- name: Run tests
|
||||
working-directory: ./console-test
|
||||
run: poetry run pytest -s --numprocesses auto
|
||||
run: poetry run pytest --numprocesses auto
|
||||
- name: Check files
|
||||
run: |
|
||||
ls -al .
|
||||
|
||||
@@ -730,7 +730,6 @@ context(
|
||||
.getByTestId('key-value-table-row')
|
||||
.contains(heading)
|
||||
.parent()
|
||||
.parent()
|
||||
.siblings();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-83
@@ -45,10 +45,8 @@ export const useMarketDataDialogStore = create<MarketDataDialogState>(
|
||||
|
||||
export const ProposalMarketData = ({
|
||||
marketData,
|
||||
parentMarketData,
|
||||
}: {
|
||||
marketData: MarketInfoWithData;
|
||||
parentMarketData?: MarketInfoWithData;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
const { isOpen, open, close } = useMarketDataDialogStore();
|
||||
@@ -60,21 +58,8 @@ export const ProposalMarketData = ({
|
||||
|
||||
const settlementData = marketData.tradableInstrument.instrument.product
|
||||
.dataSourceSpecForSettlementData.data as DataSourceDefinition;
|
||||
const parentSettlementData =
|
||||
parentMarketData?.tradableInstrument.instrument?.product
|
||||
?.dataSourceSpecForSettlementData?.data;
|
||||
const terminationData = marketData.tradableInstrument.instrument.product
|
||||
.dataSourceSpecForTradingTermination.data as DataSourceDefinition;
|
||||
const parentTerminationData =
|
||||
parentMarketData?.tradableInstrument.instrument?.product
|
||||
?.dataSourceSpecForTradingTermination?.data;
|
||||
|
||||
const isParentSettlementDataEqual =
|
||||
parentSettlementData !== undefined &&
|
||||
isEqual(settlementData, parentSettlementData);
|
||||
const isParentTerminationDataEqual =
|
||||
parentTerminationData !== undefined &&
|
||||
isEqual(terminationData, parentTerminationData);
|
||||
|
||||
const getSigners = (data: DataSourceDefinition) => {
|
||||
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
||||
@@ -112,22 +97,12 @@ export const ProposalMarketData = ({
|
||||
<AccordionItem
|
||||
itemId="key-details"
|
||||
title={t('Key details')}
|
||||
content={
|
||||
<KeyDetailsInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<KeyDetailsInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="instrument"
|
||||
title={t('Instrument')}
|
||||
content={
|
||||
<InstrumentInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<InstrumentInfoPanel market={marketData} />}
|
||||
/>
|
||||
{isEqual(
|
||||
getSigners(settlementData),
|
||||
@@ -140,11 +115,6 @@ export const ProposalMarketData = ({
|
||||
<OracleInfoPanel
|
||||
market={marketData}
|
||||
type="settlementData"
|
||||
parentMarket={
|
||||
isParentSettlementDataEqual
|
||||
? undefined
|
||||
: parentMarketData
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -157,11 +127,6 @@ export const ProposalMarketData = ({
|
||||
<OracleInfoPanel
|
||||
market={marketData}
|
||||
type="settlementData"
|
||||
parentMarket={
|
||||
isParentSettlementDataEqual
|
||||
? undefined
|
||||
: parentMarketData
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -170,21 +135,11 @@ export const ProposalMarketData = ({
|
||||
itemId="termination-oracle"
|
||||
title={t('Termination Oracle')}
|
||||
content={
|
||||
<OracleInfoPanel
|
||||
market={marketData}
|
||||
type="termination"
|
||||
parentMarket={
|
||||
isParentTerminationDataEqual
|
||||
? undefined
|
||||
: parentMarketData
|
||||
}
|
||||
/>
|
||||
<OracleInfoPanel market={marketData} type="termination" />
|
||||
}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{/*Note: successor markets will not differ in their settlement*/}
|
||||
{/*assets, so no need to pass in parent market data for comparison.*/}
|
||||
<AccordionItem
|
||||
itemId="settlement-asset"
|
||||
title={t('Settlement asset')}
|
||||
@@ -193,42 +148,22 @@ export const ProposalMarketData = ({
|
||||
<AccordionItem
|
||||
itemId="metadata"
|
||||
title={t('Metadata')}
|
||||
content={
|
||||
<MetadataInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<MetadataInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="risk-model"
|
||||
title={t('Risk model')}
|
||||
content={
|
||||
<RiskModelInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<RiskModelInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="risk-parameters"
|
||||
title={t('Risk parameters')}
|
||||
content={
|
||||
<RiskParametersInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<RiskParametersInfoPanel market={marketData} />}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="risk-factors"
|
||||
title={t('Risk factors')}
|
||||
content={
|
||||
<RiskFactorsInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<RiskFactorsInfoPanel market={marketData} />}
|
||||
/>
|
||||
{(
|
||||
marketData.priceMonitoringSettings?.parameters?.triggers || []
|
||||
@@ -239,7 +174,6 @@ export const ProposalMarketData = ({
|
||||
content={
|
||||
<PriceMonitoringBoundsInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
triggerIndex={triggerIndex}
|
||||
/>
|
||||
}
|
||||
@@ -249,21 +183,13 @@ export const ProposalMarketData = ({
|
||||
itemId="liqudity-monitoring-parameters"
|
||||
title={t('Liquidity monitoring parameters')}
|
||||
content={
|
||||
<LiquidityMonitoringParametersInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
<LiquidityMonitoringParametersInfoPanel market={marketData} />
|
||||
}
|
||||
/>
|
||||
<AccordionItem
|
||||
itemId="liquidity-price-range"
|
||||
title={t('Liquidity price range')}
|
||||
content={
|
||||
<LiquidityPriceRangeInfoPanel
|
||||
market={marketData}
|
||||
parentMarket={parentMarketData}
|
||||
/>
|
||||
}
|
||||
content={<LiquidityPriceRangeInfoPanel market={marketData} />}
|
||||
/>
|
||||
</Accordion>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,6 @@ export interface ProposalProps {
|
||||
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
|
||||
networkParams: Partial<NetworkParamsResult>;
|
||||
newMarketData?: MarketInfoWithData | null;
|
||||
parentMarketData?: MarketInfoWithData | null;
|
||||
assetData?: AssetQuery | null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
restData: any;
|
||||
@@ -47,7 +46,6 @@ export const Proposal = ({
|
||||
networkParams,
|
||||
restData,
|
||||
newMarketData,
|
||||
parentMarketData,
|
||||
assetData,
|
||||
originalMarketProposalRestData,
|
||||
mostRecentlyEnactedAssociatedMarketProposal,
|
||||
@@ -159,10 +157,7 @@ export const Proposal = ({
|
||||
|
||||
{newMarketData && (
|
||||
<div className="mb-4">
|
||||
<ProposalMarketData
|
||||
marketData={newMarketData}
|
||||
parentMarketData={parentMarketData ? parentMarketData : undefined}
|
||||
/>
|
||||
<ProposalMarketData marketData={newMarketData} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -14,9 +14,6 @@ import {
|
||||
NetworkParams,
|
||||
useNetworkParams,
|
||||
} from '@vegaprotocol/network-parameters';
|
||||
import { useParentMarketIdQuery } from '@vegaprotocol/markets';
|
||||
import { FLAGS } from '@vegaprotocol/environment';
|
||||
import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
|
||||
|
||||
export const ProposalContainer = () => {
|
||||
const [
|
||||
@@ -57,10 +54,6 @@ export const ProposalContainer = () => {
|
||||
skip: !params.proposalId,
|
||||
});
|
||||
|
||||
const successor = useSuccessorMarketProposalDetails(params.proposalId);
|
||||
|
||||
const isSuccessor = !!successor?.parentMarketId || !!successor.code;
|
||||
|
||||
const {
|
||||
state: {
|
||||
data: originalMarketProposalRestData,
|
||||
@@ -103,36 +96,6 @@ export const ProposalContainer = () => {
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
data: parentMarketId,
|
||||
loading: parentMarketIdLoading,
|
||||
error: parentMarketIdError,
|
||||
} = useParentMarketIdQuery({
|
||||
variables: {
|
||||
marketId: newMarketData?.data?.market?.id || '',
|
||||
},
|
||||
skip:
|
||||
!FLAGS.SUCCESSOR_MARKETS ||
|
||||
!isSuccessor ||
|
||||
!newMarketData?.data?.market?.id,
|
||||
});
|
||||
|
||||
const {
|
||||
data: parentMarketData,
|
||||
loading: parentMarketLoading,
|
||||
error: parentMarketError,
|
||||
} = useDataProvider({
|
||||
dataProvider: marketInfoWithDataProvider,
|
||||
skipUpdates: true,
|
||||
variables: {
|
||||
marketId: parentMarketId?.market?.parentMarketID || '',
|
||||
skip:
|
||||
!FLAGS.SUCCESSOR_MARKETS ||
|
||||
!isSuccessor ||
|
||||
!parentMarketId?.market?.parentMarketID,
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
data: assetData,
|
||||
loading: assetLoading,
|
||||
@@ -197,8 +160,6 @@ export const ProposalContainer = () => {
|
||||
newMarketLoading ||
|
||||
assetLoading ||
|
||||
networkParamsLoading ||
|
||||
parentMarketIdLoading ||
|
||||
parentMarketLoading ||
|
||||
(restLoading ? (restLoading as boolean) : false) ||
|
||||
(originalMarketProposalRestLoading
|
||||
? (originalMarketProposalRestLoading as boolean)
|
||||
@@ -211,18 +172,15 @@ export const ProposalContainer = () => {
|
||||
error ||
|
||||
newMarketError ||
|
||||
assetError ||
|
||||
networkParamsError ||
|
||||
parentMarketIdError ||
|
||||
parentMarketError ||
|
||||
restError ||
|
||||
originalMarketProposalRestError ||
|
||||
previouslyEnactedMarketProposalsRestError
|
||||
previouslyEnactedMarketProposalsRestError ||
|
||||
networkParamsError
|
||||
}
|
||||
data={{
|
||||
...data,
|
||||
...networkParams,
|
||||
...(newMarketData ? { newMarketData } : {}),
|
||||
...(parentMarketData ? { parentMarketData } : {}),
|
||||
...(assetData ? { assetData } : {}),
|
||||
...(restData ? { restData } : {}),
|
||||
...(originalMarketProposalRestData
|
||||
@@ -239,7 +197,6 @@ export const ProposalContainer = () => {
|
||||
networkParams={networkParams}
|
||||
restData={restData}
|
||||
newMarketData={newMarketData}
|
||||
parentMarketData={parentMarketData}
|
||||
assetData={assetData}
|
||||
originalMarketProposalRestData={originalMarketProposalRestData}
|
||||
mostRecentlyEnactedAssociatedMarketProposal={
|
||||
|
||||
@@ -28,10 +28,10 @@ export const assetProvider = makeDataProvider<
|
||||
getData,
|
||||
});
|
||||
|
||||
export const useAssetDataProvider = (assetId: string, skip?: boolean) => {
|
||||
export const useAssetDataProvider = (assetId: string) => {
|
||||
return useDataProvider({
|
||||
dataProvider: assetProvider,
|
||||
variables: { assetId: assetId || '' },
|
||||
skip: !assetId || skip,
|
||||
skip: !assetId,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -4,10 +4,8 @@ import {
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import {
|
||||
Intent,
|
||||
KeyValueTable,
|
||||
KeyValueTableRow,
|
||||
Lozenge,
|
||||
Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import BigNumber from 'bignumber.js';
|
||||
@@ -24,11 +22,9 @@ interface RowProps {
|
||||
unformatted?: boolean;
|
||||
assetSymbol?: string;
|
||||
noBorder?: boolean;
|
||||
parentValue?: ReactNode;
|
||||
hasParentData?: boolean;
|
||||
}
|
||||
|
||||
export const Row = ({
|
||||
const Row = ({
|
||||
field,
|
||||
value,
|
||||
decimalPlaces,
|
||||
@@ -36,14 +32,7 @@ export const Row = ({
|
||||
unformatted,
|
||||
assetSymbol = '',
|
||||
noBorder = true,
|
||||
parentValue,
|
||||
hasParentData,
|
||||
}: RowProps) => {
|
||||
// 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
|
||||
// have successor market parent data.
|
||||
|
||||
const className = 'text-sm';
|
||||
|
||||
const getFormattedValue = (value: ReactNode) => {
|
||||
@@ -66,10 +55,6 @@ export const Row = ({
|
||||
const formattedValue = getFormattedValue(value);
|
||||
|
||||
if (!formattedValue) return null;
|
||||
|
||||
const newValueInSuccessorMarket = hasParentData && value && !parentValue;
|
||||
const valueDiffersFromParentMarket = parentValue && parentValue !== value;
|
||||
|
||||
return (
|
||||
<KeyValueTableRow
|
||||
key={field}
|
||||
@@ -78,35 +63,10 @@ export const Row = ({
|
||||
dtClassName={className}
|
||||
ddClassName={className}
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<Tooltip description={tooltipMapping[field]} align="start">
|
||||
<div tabIndex={-1}>{startCase(t(field))}</div>
|
||||
</Tooltip>
|
||||
|
||||
{valueDiffersFromParentMarket && (
|
||||
<Lozenge className="py-0" variant={Intent.Primary}>
|
||||
{t('Updated')}
|
||||
</Lozenge>
|
||||
)}
|
||||
|
||||
{newValueInSuccessorMarket && (
|
||||
<Lozenge className="py-0" variant={Intent.Primary}>
|
||||
{t('Added')}
|
||||
</Lozenge>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ wordBreak: 'break-word' }}>
|
||||
{valueDiffersFromParentMarket ? (
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="line-through">
|
||||
{getFormattedValue(parentValue)}
|
||||
</span>
|
||||
<span>{formattedValue}</span>
|
||||
</div>
|
||||
) : (
|
||||
formattedValue
|
||||
)}
|
||||
</div>
|
||||
<Tooltip description={tooltipMapping[field]} align="start">
|
||||
<div tabIndex={-1}>{startCase(t(field))}</div>
|
||||
</Tooltip>
|
||||
<span style={{ wordBreak: 'break-word' }}>{formattedValue}</span>
|
||||
</KeyValueTableRow>
|
||||
);
|
||||
};
|
||||
@@ -119,7 +79,6 @@ export interface MarketInfoTableProps {
|
||||
children?: ReactNode;
|
||||
assetSymbol?: string;
|
||||
noBorder?: boolean;
|
||||
parentData?: Record<string, ReactNode> | null | undefined;
|
||||
}
|
||||
|
||||
export const MarketInfoTable = ({
|
||||
@@ -130,33 +89,25 @@ export const MarketInfoTable = ({
|
||||
children,
|
||||
assetSymbol,
|
||||
noBorder,
|
||||
parentData,
|
||||
}: MarketInfoTableProps) => {
|
||||
if (!data || typeof data !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const hasParentData = parentData !== undefined;
|
||||
|
||||
return (
|
||||
<>
|
||||
<KeyValueTable>
|
||||
<>
|
||||
{Object.entries(data).map(([key, value]) => (
|
||||
<Row
|
||||
key={key}
|
||||
field={key}
|
||||
value={value}
|
||||
decimalPlaces={decimalPlaces}
|
||||
assetSymbol={assetSymbol}
|
||||
asPercentage={asPercentage}
|
||||
unformatted={unformatted}
|
||||
noBorder={noBorder}
|
||||
parentValue={parentData?.[key]}
|
||||
hasParentData={hasParentData}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
{Object.entries(data).map(([key, value]) => (
|
||||
<Row
|
||||
key={key}
|
||||
field={key}
|
||||
value={value}
|
||||
decimalPlaces={decimalPlaces}
|
||||
assetSymbol={assetSymbol}
|
||||
asPercentage={asPercentage}
|
||||
unformatted={unformatted}
|
||||
noBorder={noBorder}
|
||||
/>
|
||||
))}
|
||||
</KeyValueTable>
|
||||
<div className="flex flex-col gap-2">{children}</div>
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Fragment, useState } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
@@ -48,14 +47,11 @@ import {
|
||||
useSuccessorMarketQuery,
|
||||
} from '../../__generated__';
|
||||
import { useSuccessorMarketProposalDetailsQuery } from '@vegaprotocol/proposals';
|
||||
import type { MarketTradingMode } from '@vegaprotocol/types';
|
||||
import type { Signer } from '@vegaprotocol/types';
|
||||
import classNames from 'classnames';
|
||||
import compact from 'lodash/compact';
|
||||
|
||||
type MarketInfoProps = {
|
||||
market: MarketInfo;
|
||||
parentMarket?: MarketInfo;
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
@@ -160,43 +156,21 @@ export const InsurancePoolInfoPanel = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const KeyDetailsInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => {
|
||||
const { data: parentMarketIdData } = useParentMarketIdQuery({
|
||||
export const KeyDetailsInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
const { data: parentData } = useParentMarketIdQuery({
|
||||
variables: {
|
||||
marketId: market.id,
|
||||
},
|
||||
skip: !FLAGS.SUCCESSOR_MARKETS,
|
||||
});
|
||||
|
||||
const { data: successorProposalDetails } =
|
||||
useSuccessorMarketProposalDetailsQuery({
|
||||
variables: {
|
||||
proposalId: market.proposal?.id || '',
|
||||
},
|
||||
skip: !FLAGS.SUCCESSOR_MARKETS || !market.proposal?.id,
|
||||
});
|
||||
|
||||
// The following queries are needed as the parent market could also have been a successor market.
|
||||
// Note: the parent market is only passed to this component if the successor markets flag is enabled,
|
||||
// so that check is not needed in the skip.
|
||||
const { data: grandparentMarketIdData } = useParentMarketIdQuery({
|
||||
const { data: successor } = useSuccessorMarketProposalDetailsQuery({
|
||||
variables: {
|
||||
marketId: parentMarket?.id || '',
|
||||
proposalId: market.proposal?.id || '',
|
||||
},
|
||||
skip: !parentMarket?.id,
|
||||
skip: !FLAGS.SUCCESSOR_MARKETS || !market.proposal?.id,
|
||||
});
|
||||
|
||||
const { data: parentSuccessorProposalDetails } =
|
||||
useSuccessorMarketProposalDetailsQuery({
|
||||
variables: {
|
||||
proposalId: parentMarket?.proposal?.id || '',
|
||||
},
|
||||
skip: !parentMarket?.proposal?.id,
|
||||
});
|
||||
|
||||
const assetDecimals =
|
||||
market.tradableInstrument.instrument.product.settlementAsset.decimals;
|
||||
|
||||
@@ -207,12 +181,11 @@ export const KeyDetailsInfoPanel = ({
|
||||
? {
|
||||
name: market.tradableInstrument.instrument.name,
|
||||
marketID: market.id,
|
||||
parentMarketID: parentMarketIdData?.market?.parentMarketID || '-',
|
||||
parentMarketID: parentData?.market?.parentMarketID || '-',
|
||||
insurancePoolFraction:
|
||||
(successorProposalDetails?.proposal?.terms.change.__typename ===
|
||||
'NewMarket' &&
|
||||
successorProposalDetails.proposal.terms.change
|
||||
.successorConfiguration?.insurancePoolFraction) ||
|
||||
(successor?.proposal?.terms.change.__typename === 'NewMarket' &&
|
||||
successor.proposal.terms.change.successorConfiguration
|
||||
?.insurancePoolFraction) ||
|
||||
'-',
|
||||
tradingMode:
|
||||
market.tradingMode &&
|
||||
@@ -232,28 +205,6 @@ export const KeyDetailsInfoPanel = ({
|
||||
settlementAssetDecimalPlaces: assetDecimals,
|
||||
}
|
||||
}
|
||||
parentData={
|
||||
parentMarket && {
|
||||
name: parentMarket?.tradableInstrument?.instrument?.name,
|
||||
marketID: parentMarket?.id,
|
||||
parentMarketID: grandparentMarketIdData?.market?.parentMarketID,
|
||||
insurancePoolFraction:
|
||||
parentSuccessorProposalDetails?.proposal?.terms.change
|
||||
.__typename === 'NewMarket' &&
|
||||
parentSuccessorProposalDetails.proposal.terms.change
|
||||
.successorConfiguration?.insurancePoolFraction,
|
||||
tradingMode:
|
||||
parentMarket?.tradingMode &&
|
||||
MarketTradingModeMapping[
|
||||
parentMarket.tradingMode as MarketTradingMode
|
||||
],
|
||||
marketDecimalPlaces: parentMarket?.decimalPlaces,
|
||||
positionDecimalPlaces: parentMarket?.positionDecimalPlaces,
|
||||
settlementAssetDecimalPlaces:
|
||||
parentMarket?.tradableInstrument?.instrument?.product
|
||||
?.settlementAsset?.decimals,
|
||||
}
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -378,10 +329,7 @@ export const SuccessionLineInfoPanel = ({
|
||||
);
|
||||
};
|
||||
|
||||
export const InstrumentInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => (
|
||||
export const InstrumentInfoPanel = ({ market }: MarketInfoProps) => (
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
marketName: market.tradableInstrument.instrument.name,
|
||||
@@ -389,16 +337,6 @@ export const InstrumentInfoPanel = ({
|
||||
productType: market.tradableInstrument.instrument.product.__typename,
|
||||
quoteName: market.tradableInstrument.instrument.product.quoteName,
|
||||
}}
|
||||
parentData={
|
||||
parentMarket && {
|
||||
marketName: parentMarket?.tradableInstrument?.instrument?.name,
|
||||
code: parentMarket?.tradableInstrument?.instrument?.code,
|
||||
productType:
|
||||
parentMarket?.tradableInstrument?.instrument?.product?.__typename,
|
||||
quoteName:
|
||||
parentMarket?.tradableInstrument?.instrument?.product?.quoteName,
|
||||
}
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -411,7 +349,6 @@ export const SettlementAssetInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
() => market?.tradableInstrument.instrument.product?.settlementAsset.id,
|
||||
[market]
|
||||
);
|
||||
|
||||
const { data: asset } = useAssetDataProvider(assetId ?? '');
|
||||
return asset ? (
|
||||
<>
|
||||
@@ -434,148 +371,54 @@ export const SettlementAssetInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const getMarketMetadata = (market: MarketInfo) =>
|
||||
market.tradableInstrument.instrument.metadata.tags
|
||||
?.map((tag) => {
|
||||
const [key, value] = tag.split(':');
|
||||
return { [key]: value };
|
||||
})
|
||||
.reduce((acc, curr) => ({ ...acc, ...curr }), {});
|
||||
|
||||
export const MetadataInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => (
|
||||
export const MetadataInfoPanel = ({ market }: MarketInfoProps) => (
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
expiryDate: getMarketExpiryDateFormatted(
|
||||
market.tradableInstrument.instrument.metadata.tags
|
||||
),
|
||||
...(getMarketMetadata(market) || {}),
|
||||
...market.tradableInstrument.instrument.metadata.tags
|
||||
?.map((tag) => {
|
||||
const [key, value] = tag.split(':');
|
||||
return { [key]: value };
|
||||
})
|
||||
.reduce((acc, curr) => ({ ...acc, ...curr }), {}),
|
||||
}}
|
||||
parentData={
|
||||
parentMarket && {
|
||||
expiryDate: getMarketExpiryDateFormatted(
|
||||
parentMarket.tradableInstrument.instrument.metadata.tags
|
||||
),
|
||||
...(getMarketMetadata(parentMarket) || {}),
|
||||
}
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
export const RiskModelInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => {
|
||||
export const RiskModelInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
if (market.tradableInstrument.riskModel.__typename !== 'LogNormalRiskModel') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { tau, riskAversionParameter } = market.tradableInstrument.riskModel;
|
||||
|
||||
let parentData;
|
||||
|
||||
if (
|
||||
parentMarket?.tradableInstrument?.riskModel?.__typename ===
|
||||
'LogNormalRiskModel'
|
||||
) {
|
||||
const {
|
||||
tau: parentTau,
|
||||
riskAversionParameter: parentRiskAversionParameter,
|
||||
} = market.tradableInstrument.riskModel;
|
||||
|
||||
parentData = {
|
||||
tau: parentTau,
|
||||
riskAversionParameter: parentRiskAversionParameter,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<MarketInfoTable
|
||||
data={{ tau, riskAversionParameter }}
|
||||
parentData={parentData}
|
||||
unformatted
|
||||
/>
|
||||
);
|
||||
return <MarketInfoTable data={{ tau, riskAversionParameter }} unformatted />;
|
||||
};
|
||||
|
||||
export const RiskParametersInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => {
|
||||
const marketType = market.tradableInstrument.riskModel.__typename;
|
||||
|
||||
let data, parentData;
|
||||
|
||||
if (marketType === 'LogNormalRiskModel') {
|
||||
export const RiskParametersInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
if (market.tradableInstrument.riskModel.__typename === 'LogNormalRiskModel') {
|
||||
const { r, sigma, mu } = market.tradableInstrument.riskModel.params;
|
||||
data = { r, sigma, mu };
|
||||
|
||||
if (
|
||||
parentMarket?.tradableInstrument?.riskModel.__typename ===
|
||||
'LogNormalRiskModel'
|
||||
) {
|
||||
const parentParams = parentMarket.tradableInstrument.riskModel.params;
|
||||
parentData = {
|
||||
r: parentParams.r,
|
||||
sigma: parentParams.sigma,
|
||||
mu: parentParams.mu,
|
||||
};
|
||||
}
|
||||
} else if (marketType === 'SimpleRiskModel') {
|
||||
return <MarketInfoTable data={{ r, sigma, mu }} unformatted />;
|
||||
}
|
||||
if (market.tradableInstrument.riskModel.__typename === 'SimpleRiskModel') {
|
||||
const { factorLong, factorShort } =
|
||||
market.tradableInstrument.riskModel.params;
|
||||
data = { factorLong, factorShort };
|
||||
|
||||
if (
|
||||
parentMarket?.tradableInstrument?.riskModel.__typename ===
|
||||
'SimpleRiskModel'
|
||||
) {
|
||||
const parentParams = parentMarket.tradableInstrument.riskModel.params;
|
||||
parentData = {
|
||||
factorLong: parentParams.factorLong,
|
||||
factorShort: parentParams.factorShort,
|
||||
};
|
||||
}
|
||||
return <MarketInfoTable data={{ factorLong, factorShort }} unformatted />;
|
||||
}
|
||||
|
||||
if (!data) return null;
|
||||
|
||||
return <MarketInfoTable data={data} parentData={parentData} unformatted />;
|
||||
return null;
|
||||
};
|
||||
|
||||
export const RiskFactorsInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => {
|
||||
export const RiskFactorsInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
if (!market.riskFactors) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { short, long } = market.riskFactors;
|
||||
|
||||
let parentData;
|
||||
|
||||
if (parentMarket?.riskFactors) {
|
||||
const parentShort = parentMarket.riskFactors.short;
|
||||
const parentLong = parentMarket.riskFactors.long;
|
||||
parentData = { short: parentShort, long: parentLong };
|
||||
}
|
||||
|
||||
return (
|
||||
<MarketInfoTable
|
||||
data={{ short, long }}
|
||||
parentData={parentData}
|
||||
unformatted
|
||||
/>
|
||||
);
|
||||
return <MarketInfoTable data={{ short, long }} unformatted />;
|
||||
};
|
||||
|
||||
export const PriceMonitoringBoundsInfoPanel = ({
|
||||
market,
|
||||
triggerIndex,
|
||||
parentMarket,
|
||||
}: MarketInfoProps & {
|
||||
triggerIndex: number;
|
||||
}) => {
|
||||
@@ -583,35 +426,11 @@ export const PriceMonitoringBoundsInfoPanel = ({
|
||||
dataProvider: marketDataProvider,
|
||||
variables: { marketId: market.id },
|
||||
});
|
||||
|
||||
const { data: parentData } = useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
variables: { marketId: parentMarket?.id || '' },
|
||||
skip:
|
||||
!parentMarket ||
|
||||
!parentMarket?.priceMonitoringSettings?.parameters?.triggers?.[
|
||||
triggerIndex
|
||||
],
|
||||
});
|
||||
|
||||
const quoteUnit =
|
||||
market?.tradableInstrument.instrument.product?.quoteName || '';
|
||||
const parentQuoteUnit =
|
||||
parentMarket?.tradableInstrument.instrument.product?.quoteName || '';
|
||||
const isParentQuoteUnitEqual = quoteUnit === parentQuoteUnit;
|
||||
|
||||
const trigger =
|
||||
market.priceMonitoringSettings?.parameters?.triggers?.[triggerIndex];
|
||||
const parentTrigger =
|
||||
parentMarket?.priceMonitoringSettings?.parameters?.triggers?.[triggerIndex];
|
||||
const isParentTriggerEqual = isEqual(trigger, parentTrigger);
|
||||
|
||||
const bounds = data?.priceMonitoringBounds?.[triggerIndex];
|
||||
const parentBounds = parentData?.priceMonitoringBounds?.[triggerIndex];
|
||||
|
||||
const shouldShowParentData =
|
||||
isParentQuoteUnitEqual && isParentTriggerEqual && !!parentBounds;
|
||||
|
||||
if (!trigger) {
|
||||
console.error(
|
||||
`Could not find data for trigger ${triggerIndex} (market id: ${market.id})`
|
||||
@@ -638,14 +457,6 @@ export const PriceMonitoringBoundsInfoPanel = ({
|
||||
highestPrice: bounds.maxValidPrice,
|
||||
lowestPrice: bounds.minValidPrice,
|
||||
}}
|
||||
parentData={
|
||||
shouldShowParentData
|
||||
? {
|
||||
highestPrice: parentBounds.maxValidPrice,
|
||||
lowestPrice: parentBounds.minValidPrice,
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
decimalPlaces={market.decimalPlaces}
|
||||
assetSymbol={quoteUnit}
|
||||
/>
|
||||
@@ -661,31 +472,18 @@ export const PriceMonitoringBoundsInfoPanel = ({
|
||||
|
||||
export const LiquidityMonitoringParametersInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => {
|
||||
const marketData = {
|
||||
triggeringRatio: market.liquidityMonitoringParameters.triggeringRatio,
|
||||
timeWindow:
|
||||
market.liquidityMonitoringParameters.targetStakeParameters.timeWindow,
|
||||
scalingFactor:
|
||||
market.liquidityMonitoringParameters.targetStakeParameters.scalingFactor,
|
||||
};
|
||||
|
||||
const parentMarketData = parentMarket
|
||||
? {
|
||||
triggeringRatio:
|
||||
parentMarket.liquidityMonitoringParameters.triggeringRatio,
|
||||
timeWindow:
|
||||
parentMarket.liquidityMonitoringParameters.targetStakeParameters
|
||||
.timeWindow,
|
||||
scalingFactor:
|
||||
parentMarket.liquidityMonitoringParameters.targetStakeParameters
|
||||
.scalingFactor,
|
||||
}
|
||||
: {};
|
||||
|
||||
return <MarketInfoTable data={marketData} parentData={parentMarketData} />;
|
||||
};
|
||||
}: MarketInfoProps) => (
|
||||
<MarketInfoTable
|
||||
data={{
|
||||
triggeringRatio: market.liquidityMonitoringParameters.triggeringRatio,
|
||||
timeWindow:
|
||||
market.liquidityMonitoringParameters.targetStakeParameters.timeWindow,
|
||||
scalingFactor:
|
||||
market.liquidityMonitoringParameters.targetStakeParameters
|
||||
.scalingFactor,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const LiquidityInfoPanel = ({ market, children }: MarketInfoProps) => {
|
||||
const assetDecimals =
|
||||
@@ -712,61 +510,16 @@ export const LiquidityInfoPanel = ({ market, children }: MarketInfoProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const LiquidityPriceRangeInfoPanel = ({
|
||||
market,
|
||||
parentMarket,
|
||||
}: MarketInfoProps) => {
|
||||
export const LiquidityPriceRangeInfoPanel = ({ market }: MarketInfoProps) => {
|
||||
const quoteUnit =
|
||||
market?.tradableInstrument.instrument.product?.quoteName || '';
|
||||
const parentQuoteUnit =
|
||||
parentMarket?.tradableInstrument.instrument.product?.quoteName || '';
|
||||
|
||||
const liquidityPriceRange = formatNumberPercentage(
|
||||
new BigNumber(market.lpPriceRange).times(100)
|
||||
);
|
||||
const parentLiquidityPriceRange = parentMarket
|
||||
? formatNumberPercentage(
|
||||
new BigNumber(parentMarket.lpPriceRange).times(100)
|
||||
)
|
||||
: null;
|
||||
|
||||
const { data } = useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
variables: { marketId: market.id },
|
||||
});
|
||||
|
||||
const { data: parentMarketData } = useDataProvider({
|
||||
dataProvider: marketDataProvider,
|
||||
variables: { marketId: parentMarket?.id || '' },
|
||||
skip: !parentMarket,
|
||||
});
|
||||
|
||||
let parentData;
|
||||
|
||||
if (parentMarket && parentMarketData && quoteUnit === parentQuoteUnit) {
|
||||
parentData = {
|
||||
liquidityPriceRange: `${parentLiquidityPriceRange} of mid price`,
|
||||
lowestPrice:
|
||||
parentMarketData?.midPrice &&
|
||||
`${addDecimalsFormatNumber(
|
||||
new BigNumber(1)
|
||||
.minus(parentMarket.lpPriceRange)
|
||||
.times(parentMarketData.midPrice)
|
||||
.toString(),
|
||||
parentMarket.decimalPlaces
|
||||
)} ${quoteUnit}`,
|
||||
highestPrice:
|
||||
parentMarketData?.midPrice &&
|
||||
`${addDecimalsFormatNumber(
|
||||
new BigNumber(1)
|
||||
.plus(parentMarket.lpPriceRange)
|
||||
.times(parentMarketData.midPrice)
|
||||
.toString(),
|
||||
parentMarket.decimalPlaces
|
||||
)} ${quoteUnit}`,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="text-sm mb-2">
|
||||
@@ -799,7 +552,6 @@ export const LiquidityPriceRangeInfoPanel = ({
|
||||
market.decimalPlaces
|
||||
)} ${quoteUnit}`,
|
||||
}}
|
||||
parentData={parentData}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
@@ -808,12 +560,8 @@ export const LiquidityPriceRangeInfoPanel = ({
|
||||
export const OracleInfoPanel = ({
|
||||
market,
|
||||
type,
|
||||
parentMarket,
|
||||
}: MarketInfoProps & { type: 'settlementData' | 'termination' }) => {
|
||||
// If this is a successor market, this component will only receive parent market
|
||||
// data if the termination or settlement data is different from the parent.
|
||||
const product = market.tradableInstrument.instrument.product;
|
||||
const parentProduct = parentMarket?.tradableInstrument?.instrument?.product;
|
||||
const { VEGA_EXPLORER_URL, ORACLE_PROOFS_URL } = useEnvironment();
|
||||
const { data } = useOracleProofs(ORACLE_PROOFS_URL);
|
||||
|
||||
@@ -822,33 +570,12 @@ export const OracleInfoPanel = ({
|
||||
? product.dataSourceSpecForSettlementData.id
|
||||
: product.dataSourceSpecForTradingTermination.id;
|
||||
|
||||
const parentDataSourceSpecId =
|
||||
type === 'settlementData'
|
||||
? parentProduct?.dataSourceSpecForSettlementData?.id
|
||||
: parentProduct?.dataSourceSpecForTradingTermination?.id;
|
||||
|
||||
const dataSourceSpec = (
|
||||
type === 'settlementData'
|
||||
? product.dataSourceSpecForSettlementData.data
|
||||
: product.dataSourceSpecForTradingTermination.data
|
||||
) as DataSourceDefinition;
|
||||
|
||||
const parentDataSourceSpec =
|
||||
type === 'settlementData'
|
||||
? parentProduct?.dataSourceSpecForSettlementData?.data
|
||||
: (parentProduct?.dataSourceSpecForTradingTermination
|
||||
?.data as DataSourceDefinition);
|
||||
|
||||
const isParentDataSourceSpecEqual =
|
||||
parentDataSourceSpec !== undefined &&
|
||||
dataSourceSpec === parentDataSourceSpec;
|
||||
const isParentDataSourceSpecIdEqual =
|
||||
parentDataSourceSpecId !== undefined &&
|
||||
dataSourceSpecId === parentDataSourceSpecId;
|
||||
|
||||
// We'll only provide successor parent data (if it differs) to the
|
||||
// DataSourceProof component. Having an old external link struck through
|
||||
// is unlikely to be useful.
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<DataSourceProof
|
||||
@@ -857,14 +584,7 @@ export const OracleInfoPanel = ({
|
||||
providers={data}
|
||||
type={type}
|
||||
dataSourceSpecId={dataSourceSpecId}
|
||||
parentData={
|
||||
isParentDataSourceSpecEqual ? undefined : parentDataSourceSpec
|
||||
}
|
||||
parentDataSourceSpecId={
|
||||
isParentDataSourceSpecIdEqual ? undefined : parentDataSourceSpecId
|
||||
}
|
||||
/>
|
||||
|
||||
<ExternalLink
|
||||
data-testid="oracle-spec-links"
|
||||
href={`${VEGA_EXPLORER_URL}/oracles/${
|
||||
@@ -886,28 +606,14 @@ export const DataSourceProof = ({
|
||||
providers,
|
||||
type,
|
||||
dataSourceSpecId,
|
||||
parentData,
|
||||
parentDataSourceSpecId,
|
||||
}: {
|
||||
data: DataSourceDefinition;
|
||||
providers: Provider[] | undefined;
|
||||
type: 'settlementData' | 'termination';
|
||||
dataSourceSpecId: string;
|
||||
parentData?: DataSourceDefinition;
|
||||
parentDataSourceSpecId?: string;
|
||||
}) => {
|
||||
// If this is a successor market, we'll only pass parent data to child
|
||||
// components for comparison if the data differs from the parent market.
|
||||
if (data.sourceType.__typename === 'DataSourceDefinitionExternal') {
|
||||
const signers = data.sourceType.sourceType.signers || [];
|
||||
let parentSigners: Signer[];
|
||||
|
||||
if (
|
||||
parentData &&
|
||||
parentData.sourceType.__typename === 'DataSourceDefinitionExternal'
|
||||
) {
|
||||
parentSigners = parentData.sourceType.sourceType?.signers || [];
|
||||
}
|
||||
|
||||
if (!providers?.length) {
|
||||
return <NoOracleProof type={type} />;
|
||||
@@ -916,14 +622,7 @@ export const DataSourceProof = ({
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
{signers.map(({ signer }, i) => {
|
||||
const parentSigner = parentSigners?.find(
|
||||
({ signer: ParentSigner }) =>
|
||||
ParentSigner.__typename === signer.__typename
|
||||
)?.signer;
|
||||
|
||||
const isParentSignerEqual = isEqual(signer, parentSigner);
|
||||
|
||||
return isParentSignerEqual ? (
|
||||
return (
|
||||
<OracleLink
|
||||
key={i}
|
||||
providers={providers}
|
||||
@@ -931,16 +630,6 @@ export const DataSourceProof = ({
|
||||
type={type}
|
||||
dataSourceSpecId={dataSourceSpecId}
|
||||
/>
|
||||
) : (
|
||||
<OracleLink
|
||||
key={i}
|
||||
providers={providers}
|
||||
signer={signer}
|
||||
type={type}
|
||||
dataSourceSpecId={dataSourceSpecId}
|
||||
parentSigner={parentSigner}
|
||||
parentDataSourceSpecId={parentDataSourceSpecId}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
@@ -974,8 +663,18 @@ export const DataSourceProof = ({
|
||||
return <div>{t('Invalid data source')}</div>;
|
||||
};
|
||||
|
||||
const getSignerProviders = (signer: SignerKind, providers: Provider[]) =>
|
||||
providers.filter((p) => {
|
||||
const OracleLink = ({
|
||||
providers,
|
||||
signer,
|
||||
type,
|
||||
dataSourceSpecId,
|
||||
}: {
|
||||
providers: Provider[];
|
||||
signer: SignerKind;
|
||||
type: 'settlementData' | 'termination';
|
||||
dataSourceSpecId: string;
|
||||
}) => {
|
||||
const signerProviders = providers.filter((p) => {
|
||||
if (signer.__typename === 'PubKey') {
|
||||
if (
|
||||
p.oracle.type === 'public_key' &&
|
||||
@@ -997,62 +696,19 @@ const getSignerProviders = (signer: SignerKind, providers: Provider[]) =>
|
||||
return false;
|
||||
});
|
||||
|
||||
const OracleLink = ({
|
||||
providers,
|
||||
signer,
|
||||
type,
|
||||
dataSourceSpecId,
|
||||
parentSigner,
|
||||
parentDataSourceSpecId,
|
||||
}: {
|
||||
providers: Provider[];
|
||||
signer: SignerKind;
|
||||
type: 'settlementData' | 'termination';
|
||||
dataSourceSpecId: string;
|
||||
parentSigner?: SignerKind;
|
||||
parentDataSourceSpecId?: string;
|
||||
}) => {
|
||||
// If this is a successor market, the parent market data will only have been passed
|
||||
// in if it differs from the current data.
|
||||
const signerProviders = getSignerProviders(signer, providers);
|
||||
const parentSignerProviders = parentSigner
|
||||
? getSignerProviders(parentSigner, providers)
|
||||
: [];
|
||||
|
||||
if (!signerProviders.length) {
|
||||
return <NoOracleProof type={type} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mt-2">
|
||||
{signerProviders.map((provider) => {
|
||||
// Making the assumption here that if the provider name is the same,
|
||||
// that it is the same provider that the parent market used.
|
||||
const parentProvider = parentSignerProviders.find(
|
||||
(p) => p.name === provider.name
|
||||
);
|
||||
|
||||
const isParentProviderEqual =
|
||||
parentProvider !== undefined && isEqual(provider, parentProvider);
|
||||
|
||||
// We only want to pass the parent data to the child component if the
|
||||
// data differs from the parent market.
|
||||
return isParentProviderEqual ? (
|
||||
<OracleProfile
|
||||
key={dataSourceSpecId}
|
||||
provider={provider}
|
||||
dataSourceSpecId={dataSourceSpecId}
|
||||
/>
|
||||
) : (
|
||||
<OracleProfile
|
||||
key={dataSourceSpecId}
|
||||
provider={provider}
|
||||
dataSourceSpecId={dataSourceSpecId}
|
||||
parentProvider={parentProvider}
|
||||
parentDataSourceSpecId={parentDataSourceSpecId}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{signerProviders.map((provider) => (
|
||||
<OracleProfile
|
||||
key={dataSourceSpecId}
|
||||
provider={provider}
|
||||
dataSourceSpecId={dataSourceSpecId}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1075,18 +731,13 @@ const NoOracleProof = ({
|
||||
const OracleProfile = (props: {
|
||||
provider: Provider;
|
||||
dataSourceSpecId: string;
|
||||
parentProvider?: Provider;
|
||||
parentDataSourceSpecId?: string;
|
||||
}) => {
|
||||
// If this is a successor market, the parent market data will only have been passed
|
||||
// in if it differs from the current data.
|
||||
const [open, onChange] = useState(false);
|
||||
return (
|
||||
<div key={props.provider.name}>
|
||||
<OracleBasicProfile
|
||||
provider={props.provider}
|
||||
onClick={() => onChange(!open)}
|
||||
parentProvider={props.parentProvider}
|
||||
/>
|
||||
<OracleDialog {...props} open={open} onChange={onChange} />
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
ExternalLink,
|
||||
Icon,
|
||||
Intent,
|
||||
Lozenge,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
@@ -60,12 +59,10 @@ export const OracleBasicProfile = ({
|
||||
provider,
|
||||
onClick,
|
||||
markets: oracleMarkets,
|
||||
parentProvider,
|
||||
}: {
|
||||
provider: Provider;
|
||||
markets?: OracleMarketSpecFieldsFragment[] | undefined;
|
||||
onClick?: (value?: boolean) => void;
|
||||
parentProvider?: Provider;
|
||||
}) => {
|
||||
const { icon, message, intent } = getVerifiedStatusIcon(provider);
|
||||
|
||||
@@ -81,14 +78,8 @@ export const OracleBasicProfile = ({
|
||||
icon: getLinkIcon(proof.type),
|
||||
}));
|
||||
|
||||
// If this is a successor market and there's a different parent provider,
|
||||
// we'll just show that there's been a change, rather than add old data
|
||||
// in alongside the new provider.
|
||||
return (
|
||||
<>
|
||||
{parentProvider && (
|
||||
<Lozenge variant={Intent.Primary}>{t('Updated')}</Lozenge>
|
||||
)}
|
||||
<span className="flex gap-1">
|
||||
{provider.url && (
|
||||
<span className="flex align-items-bottom text-md gap-1">
|
||||
|
||||
@@ -11,27 +11,16 @@ export const OracleDialog = ({
|
||||
dataSourceSpecId,
|
||||
open,
|
||||
onChange,
|
||||
parentProvider,
|
||||
}: {
|
||||
dataSourceSpecId: string;
|
||||
provider: Provider;
|
||||
open: boolean;
|
||||
onChange?: (isOpen: boolean) => void;
|
||||
parentProvider?: Provider;
|
||||
}) => {
|
||||
// If this is a successor market, the parent market data will only have been passed
|
||||
// in if it differs from the current data. We'll pass this on to the title component
|
||||
// to show a change, but the full profile showing changes is unwieldy - it's enough
|
||||
// to know from the title that the oracle has changed.
|
||||
const oracleMarkets = useOracleMarkets(provider);
|
||||
return (
|
||||
<Dialog
|
||||
title={
|
||||
<OracleProfileTitle
|
||||
provider={provider}
|
||||
parentProvider={parentProvider}
|
||||
/>
|
||||
}
|
||||
title={<OracleProfileTitle provider={provider} />}
|
||||
aria-labelledby="oracle-proof-dialog"
|
||||
open={open}
|
||||
onChange={onChange}
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
ExternalLink,
|
||||
Icon,
|
||||
Intent,
|
||||
Lozenge,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
@@ -19,30 +18,15 @@ import type { OracleMarketSpecFieldsFragment } from '../../__generated__/OracleM
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { useState } from 'react';
|
||||
|
||||
export const OracleProfileTitle = ({
|
||||
provider,
|
||||
parentProvider,
|
||||
}: {
|
||||
provider: Provider;
|
||||
parentProvider?: Provider;
|
||||
}) => {
|
||||
// If this is a successor market, the parent provider will only have been passed
|
||||
// in if it differs from the current provider. If it is different, we'll just
|
||||
// show the change in name, not icons and proofs.
|
||||
export const OracleProfileTitle = ({ provider }: { provider: Provider }) => {
|
||||
const { icon, intent } = getVerifiedStatusIcon(provider);
|
||||
const verifiedProofs = provider.proofs.filter(
|
||||
(proof) => proof.available === true
|
||||
);
|
||||
return (
|
||||
<span className="flex gap-1">
|
||||
{parentProvider && (
|
||||
<Lozenge variant={Intent.Primary}>{t('Updated')}</Lozenge>
|
||||
)}
|
||||
{provider.url && (
|
||||
<span>
|
||||
{parentProvider && parentProvider.name && (
|
||||
<span className="line-through">{parentProvider.name}</span>
|
||||
)}
|
||||
<span className="pr-1">{provider.name}</span>
|
||||
<span className="dark:text-vega-light-300 text-vega-dark-300">
|
||||
({verifiedProofs.length})
|
||||
|
||||
@@ -150,9 +150,3 @@ query StopOrders($partyId: ID!) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query StopOrderById($stopOrderId: ID!) {
|
||||
stopOrder(id: $stopOrderId) {
|
||||
...StopOrderFields
|
||||
}
|
||||
}
|
||||
|
||||
+2
-44
@@ -32,7 +32,7 @@ export type OrdersUpdateSubscriptionVariables = Types.Exact<{
|
||||
|
||||
export type OrdersUpdateSubscription = { __typename?: 'Subscription', orders?: Array<{ __typename?: 'OrderUpdate', id: string, marketId: string, type?: Types.OrderType | null, side: Types.Side, size: string, status: Types.OrderStatus, rejectionReason?: Types.OrderRejectionReason | null, price: string, timeInForce: Types.OrderTimeInForce, remaining: string, expiresAt?: any | null, createdAt: any, updatedAt?: any | null, liquidityProvisionId?: string | null, peggedOrder?: { __typename: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null, icebergOrder?: { __typename: 'IcebergOrder', peakSize: string, minimumVisibleSize: string, reservedRemaining: string } | null }> | null };
|
||||
|
||||
export type OrderSubmissionFieldsFragment = { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null };
|
||||
export type OrderSubmissionFieldsFragment = { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null};
|
||||
|
||||
export type StopOrderFieldsFragment = { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger?: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string } | null, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } };
|
||||
|
||||
@@ -43,13 +43,6 @@ export type StopOrdersQueryVariables = Types.Exact<{
|
||||
|
||||
export type StopOrdersQuery = { __typename?: 'Query', stopOrders?: { __typename?: 'StopOrderConnection', edges?: Array<{ __typename?: 'StopOrderEdge', node?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger?: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string } | null, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null }> | null } | null };
|
||||
|
||||
export type StopOrderByIdQueryVariables = Types.Exact<{
|
||||
stopOrderId: Types.Scalars['ID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type StopOrderByIdQuery = { __typename?: 'Query', stopOrder?: { __typename?: 'StopOrder', id: string, ocoLinkId?: string | null, expiresAt?: any | null, expiryStrategy?: Types.StopOrderExpiryStrategy | null, triggerDirection: Types.StopOrderTriggerDirection, status: Types.StopOrderStatus, createdAt: any, updatedAt?: any | null, partyId: string, marketId: string, trigger?: { __typename?: 'StopOrderPrice', price: string } | { __typename?: 'StopOrderTrailingPercentOffset', trailingPercentOffset: string } | null, submission: { __typename?: 'OrderSubmission', marketId: string, price: string, size: string, side: Types.Side, timeInForce: Types.OrderTimeInForce, expiresAt: any, type: Types.OrderType, reference?: string | null, postOnly?: boolean | null, reduceOnly?: boolean | null, peggedOrder?: { __typename?: 'PeggedOrder', reference: Types.PeggedReference, offset: string } | null } } | null };
|
||||
|
||||
export const OrderFieldsFragmentDoc = gql`
|
||||
fragment OrderFields on Order {
|
||||
id
|
||||
@@ -316,39 +309,4 @@ export function useStopOrdersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions
|
||||
}
|
||||
export type StopOrdersQueryHookResult = ReturnType<typeof useStopOrdersQuery>;
|
||||
export type StopOrdersLazyQueryHookResult = ReturnType<typeof useStopOrdersLazyQuery>;
|
||||
export type StopOrdersQueryResult = Apollo.QueryResult<StopOrdersQuery, StopOrdersQueryVariables>;
|
||||
export const StopOrderByIdDocument = gql`
|
||||
query StopOrderById($stopOrderId: ID!) {
|
||||
stopOrder(id: $stopOrderId) {
|
||||
...StopOrderFields
|
||||
}
|
||||
}
|
||||
${StopOrderFieldsFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useStopOrderByIdQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useStopOrderByIdQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useStopOrderByIdQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useStopOrderByIdQuery({
|
||||
* variables: {
|
||||
* stopOrderId: // value for 'stopOrderId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useStopOrderByIdQuery(baseOptions: Apollo.QueryHookOptions<StopOrderByIdQuery, StopOrderByIdQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<StopOrderByIdQuery, StopOrderByIdQueryVariables>(StopOrderByIdDocument, options);
|
||||
}
|
||||
export function useStopOrderByIdLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<StopOrderByIdQuery, StopOrderByIdQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<StopOrderByIdQuery, StopOrderByIdQueryVariables>(StopOrderByIdDocument, options);
|
||||
}
|
||||
export type StopOrderByIdQueryHookResult = ReturnType<typeof useStopOrderByIdQuery>;
|
||||
export type StopOrderByIdLazyQueryHookResult = ReturnType<typeof useStopOrderByIdLazyQuery>;
|
||||
export type StopOrderByIdQueryResult = Apollo.QueryResult<StopOrderByIdQuery, StopOrderByIdQueryVariables>;
|
||||
export type StopOrdersQueryResult = Apollo.QueryResult<StopOrdersQuery, StopOrdersQueryVariables>;
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
getDateTimeFormat,
|
||||
isNumeric,
|
||||
toBigNum,
|
||||
formatTrigger,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
@@ -56,8 +55,29 @@ export const StopOrdersTable = memo<
|
||||
sortable: false,
|
||||
valueFormatter: ({
|
||||
data,
|
||||
}: VegaValueFormatterParams<StopOrder, 'trigger'>): string =>
|
||||
data ? formatTrigger(data, data.market.decimalPlaces) : '',
|
||||
value,
|
||||
}: VegaValueFormatterParams<StopOrder, 'trigger'>): string => {
|
||||
if (data && value?.__typename === 'StopOrderPrice') {
|
||||
return `${t('Mark')} ${
|
||||
data?.triggerDirection ===
|
||||
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||
? '<'
|
||||
: '>'
|
||||
} ${addDecimalsFormatNumber(
|
||||
value.price,
|
||||
data.market.decimalPlaces
|
||||
)}`;
|
||||
}
|
||||
if (data && value?.__typename === 'StopOrderTrailingPercentOffset') {
|
||||
return `${t('Mark')} ${
|
||||
data?.triggerDirection ===
|
||||
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||
? '+'
|
||||
: '-'
|
||||
}${(Number(value.trailingPercentOffset) * 100).toFixed(1)}%`;
|
||||
}
|
||||
return '-';
|
||||
},
|
||||
minWidth: 100,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ export const getIntentBackground = (intent?: Intent) => {
|
||||
return {
|
||||
'bg-neutral-200 dark:bg-neutral-800': intent === undefined,
|
||||
'bg-black dark:bg-white': intent === Intent.None,
|
||||
'bg-vega-blue-300 dark:bg-vega-blue-650': intent === Intent.Primary,
|
||||
'bg-vega-blue-300 dark:bg-vega-blue-700': intent === Intent.Primary,
|
||||
'bg-danger': intent === Intent.Danger,
|
||||
'bg-warning': intent === Intent.Warning,
|
||||
// contrast issues with light mode
|
||||
|
||||
@@ -3,4 +3,3 @@ export * from './number';
|
||||
export * from './range';
|
||||
export * from './size';
|
||||
export * from './strings';
|
||||
export * from './trigger';
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import * as Schema from '@vegaprotocol/types';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { addDecimalsFormatNumber } from './number';
|
||||
|
||||
export const formatTrigger = (
|
||||
data: Pick<Schema.StopOrder, 'trigger' | 'triggerDirection'> | undefined,
|
||||
marketDecimalPlaces: number,
|
||||
defaultValue = '-'
|
||||
) => {
|
||||
if (data && data?.trigger?.__typename === 'StopOrderPrice') {
|
||||
return `${t('Mark')} ${
|
||||
data?.triggerDirection ===
|
||||
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||
? '<'
|
||||
: '>'
|
||||
} ${addDecimalsFormatNumber(data.trigger.price, marketDecimalPlaces)}`;
|
||||
}
|
||||
if (data && data?.trigger?.__typename === 'StopOrderTrailingPercentOffset') {
|
||||
return `${t('Mark')} ${
|
||||
data?.triggerDirection ===
|
||||
Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW
|
||||
? '+'
|
||||
: '-'
|
||||
}${(Number(data?.trigger.trailingPercentOffset) * 100).toFixed(1)}%`;
|
||||
}
|
||||
return defaultValue;
|
||||
};
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
getVegaTransactionContentIntent,
|
||||
} from './use-vega-transaction-toasts';
|
||||
import { Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import type { OrderByIdQuery, StopOrderByIdQuery } from '@vegaprotocol/orders';
|
||||
|
||||
jest.mock('@vegaprotocol/assets', () => {
|
||||
const A1 = {
|
||||
@@ -24,7 +23,7 @@ jest.mock('@vegaprotocol/assets', () => {
|
||||
};
|
||||
return {
|
||||
...jest.requireActual('@vegaprotocol/assets'),
|
||||
useAssetsMapProvider: jest.fn(() => ({ data: { [A1.id]: A1 } })),
|
||||
useAssetsDataProvider: jest.fn(() => ({ data: [A1] })),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -51,7 +50,7 @@ jest.mock('@vegaprotocol/markets', () => {
|
||||
};
|
||||
return {
|
||||
...jest.requireActual('@vegaprotocol/markets'),
|
||||
useMarketsMapProvider: jest.fn(() => ({ data: { [M1.id]: M1 } })),
|
||||
useMarketList: jest.fn(() => ({ data: [M1] })),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -60,64 +59,20 @@ jest.mock('@vegaprotocol/orders', () => {
|
||||
...jest.requireActual('@vegaprotocol/orders'),
|
||||
useOrderByIdQuery: jest.fn(({ variables: { orderId } }) => {
|
||||
if (orderId === '0') {
|
||||
const data: OrderByIdQuery = {
|
||||
orderByID: {
|
||||
id: '0',
|
||||
side: 'SIDE_BUY',
|
||||
size: '10',
|
||||
remaining: '10',
|
||||
timeInForce: 'TIME_IN_FORCE_FOK',
|
||||
type: 'TYPE_MARKET',
|
||||
price: '1234',
|
||||
createdAt: new Date(),
|
||||
status: 'STATUS_ACTIVE',
|
||||
market: { id: 'market-1' },
|
||||
},
|
||||
} as OrderByIdQuery;
|
||||
return {
|
||||
data,
|
||||
};
|
||||
} else {
|
||||
return { data: undefined };
|
||||
}
|
||||
}),
|
||||
useStopOrderByIdQuery: jest.fn(({ variables: { stopOrderId } }) => {
|
||||
if (stopOrderId === '0') {
|
||||
const data: StopOrderByIdQuery = {
|
||||
stopOrder: {
|
||||
id: '0',
|
||||
ocoLinkId: null,
|
||||
expiresAt: null,
|
||||
expiryStrategy: null,
|
||||
triggerDirection: 'TRIGGER_DIRECTION_RISES_ABOVE',
|
||||
status: 'STATUS_CANCELLED',
|
||||
createdAt: '2023-08-03T07:12:36.325927Z',
|
||||
updatedAt: null,
|
||||
partyId: 'party-id',
|
||||
marketId: 'market-1',
|
||||
trigger: {
|
||||
price: '1234',
|
||||
__typename: 'StopOrderPrice',
|
||||
},
|
||||
submission: {
|
||||
marketId: 'market-1',
|
||||
price: '1234',
|
||||
data: {
|
||||
orderByID: {
|
||||
id: '0',
|
||||
side: 'SIDE_BUY',
|
||||
size: '10',
|
||||
side: 'SIDE_SELL',
|
||||
timeInForce: 'TIME_IN_FORCE_FOK',
|
||||
expiresAt: null,
|
||||
type: 'TYPE_MARKET',
|
||||
reference: '',
|
||||
peggedOrder: null,
|
||||
postOnly: false,
|
||||
reduceOnly: true,
|
||||
__typename: 'OrderSubmission',
|
||||
price: '1234',
|
||||
createdAt: new Date(),
|
||||
status: 'STATUS_ACTIVE',
|
||||
market: { id: 'market-1' },
|
||||
},
|
||||
__typename: 'StopOrder',
|
||||
},
|
||||
} as StopOrderByIdQuery;
|
||||
return {
|
||||
data,
|
||||
};
|
||||
} else {
|
||||
return { data: undefined };
|
||||
@@ -188,31 +143,6 @@ const submitOrder: VegaStoredTxState = {
|
||||
},
|
||||
};
|
||||
|
||||
const submitStopOrder: VegaStoredTxState = {
|
||||
id: 0,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
body: {
|
||||
stopOrdersSubmission: {
|
||||
risesAbove: {
|
||||
price: '1234',
|
||||
orderSubmission: {
|
||||
marketId: 'market-1',
|
||||
side: Side.SIDE_BUY,
|
||||
size: '10',
|
||||
timeInForce: OrderTimeInForce.TIME_IN_FORCE_FOK,
|
||||
type: OrderType.TYPE_MARKET,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
status: VegaTxStatus.Default,
|
||||
error: null,
|
||||
txHash: null,
|
||||
signature: null,
|
||||
dialogOpen: false,
|
||||
};
|
||||
|
||||
const editOrder: VegaStoredTxState = {
|
||||
id: 0,
|
||||
createdAt: new Date(),
|
||||
@@ -278,23 +208,6 @@ const cancelAll: VegaStoredTxState = {
|
||||
dialogOpen: false,
|
||||
};
|
||||
|
||||
const cancelStopOrder: VegaStoredTxState = {
|
||||
id: 0,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
body: {
|
||||
stopOrdersCancellation: {
|
||||
marketId: 'market-1',
|
||||
stopOrderId: '0',
|
||||
},
|
||||
},
|
||||
status: VegaTxStatus.Default,
|
||||
error: null,
|
||||
txHash: null,
|
||||
signature: null,
|
||||
dialogOpen: false,
|
||||
};
|
||||
|
||||
const closePosition: VegaStoredTxState = {
|
||||
id: 0,
|
||||
createdAt: new Date(),
|
||||
@@ -356,20 +269,12 @@ describe('VegaTransactionDetails', () => {
|
||||
it.each([
|
||||
{ tx: withdraw, details: 'Withdraw 12.34 $A' },
|
||||
{ tx: submitOrder, details: 'Submit order - activeM1+0.10 @ 12.34 $A' },
|
||||
{
|
||||
tx: submitStopOrder,
|
||||
details: 'Submit stop orderM1+0.10 @ ~ $AMark > 12.34',
|
||||
},
|
||||
{
|
||||
tx: editOrder,
|
||||
details: 'Edit order - activeM1+0.10 @ 12.34 $A+0.11 @ 10.00 $A',
|
||||
},
|
||||
{ tx: cancelOrder, details: 'Cancel orderM1+0.10 @ 12.34 $A' },
|
||||
{ tx: cancelAll, details: 'Cancel all orders' },
|
||||
{
|
||||
tx: cancelStopOrder,
|
||||
details: 'Cancel stop orderM1-0.10 @ 12.34 $AMark > 12.34',
|
||||
},
|
||||
{ tx: closePosition, details: 'Close position for M1' },
|
||||
{ tx: batch, details: 'Batch market instruction' },
|
||||
])('display details for transaction', ({ tx, details }) => {
|
||||
@@ -386,18 +291,12 @@ describe('getVegaTransactionContentIntent', () => {
|
||||
expect(getVegaTransactionContentIntent(submitOrder).intent).toBe(
|
||||
Intent.Success
|
||||
);
|
||||
expect(getVegaTransactionContentIntent(submitStopOrder).intent).toBe(
|
||||
Intent.Primary
|
||||
);
|
||||
expect(getVegaTransactionContentIntent(editOrder).intent).toBe(
|
||||
Intent.Primary
|
||||
);
|
||||
expect(getVegaTransactionContentIntent(cancelOrder).intent).toBe(
|
||||
Intent.Primary
|
||||
);
|
||||
expect(getVegaTransactionContentIntent(cancelStopOrder).intent).toBe(
|
||||
Intent.Primary
|
||||
);
|
||||
expect(getVegaTransactionContentIntent(cancelAll).intent).toBe(
|
||||
Intent.Primary
|
||||
);
|
||||
|
||||
@@ -5,10 +5,10 @@ import type {
|
||||
BatchMarketInstructionSubmissionBody,
|
||||
OrderAmendment,
|
||||
OrderTxUpdateFieldsFragment,
|
||||
OrderCancellationBody,
|
||||
OrderSubmission,
|
||||
VegaStoredTxState,
|
||||
WithdrawalBusEventFieldsFragment,
|
||||
StopOrdersSubmission,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import {
|
||||
isTransferTransaction,
|
||||
@@ -36,10 +36,9 @@ import {
|
||||
formatNumber,
|
||||
toBigNum,
|
||||
truncateByChars,
|
||||
formatTrigger,
|
||||
} from '@vegaprotocol/utils';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
import { useAssetsMapProvider } from '@vegaprotocol/assets';
|
||||
import { useAssetsDataProvider } from '@vegaprotocol/assets';
|
||||
import { useEthWithdrawApprovalsStore } from './use-ethereum-withdraw-approvals-store';
|
||||
import { DApp, EXPLORER_TX, useLinks } from '@vegaprotocol/environment';
|
||||
import {
|
||||
@@ -47,9 +46,8 @@ import {
|
||||
getOrderToastTitle,
|
||||
getRejectionReason,
|
||||
useOrderByIdQuery,
|
||||
useStopOrderByIdQuery,
|
||||
} from '@vegaprotocol/orders';
|
||||
import { useMarketsMapProvider } from '@vegaprotocol/markets';
|
||||
import { useMarketList } from '@vegaprotocol/markets';
|
||||
import type { Side } from '@vegaprotocol/types';
|
||||
import { OrderStatusMapping } from '@vegaprotocol/types';
|
||||
import { Size } from '@vegaprotocol/datagrid';
|
||||
@@ -138,8 +136,8 @@ const SubmitOrderDetails = ({
|
||||
data: OrderSubmission;
|
||||
order?: OrderTxUpdateFieldsFragment;
|
||||
}) => {
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
const market = markets?.[order?.marketId || ''];
|
||||
const { data: markets } = useMarketList();
|
||||
const market = markets?.find((m) => m.id === order?.marketId);
|
||||
if (!market) return null;
|
||||
|
||||
const price = order ? order.price : data.price;
|
||||
@@ -174,58 +172,6 @@ const SubmitOrderDetails = ({
|
||||
);
|
||||
};
|
||||
|
||||
const SubmitStopOrderDetails = ({ data }: { data: StopOrdersSubmission }) => {
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
const stopOrderSetup = data.risesAbove || data.fallsBelow;
|
||||
if (!stopOrderSetup) return null;
|
||||
const market = markets?.[stopOrderSetup?.orderSubmission.marketId];
|
||||
if (!market || !stopOrderSetup) return null;
|
||||
|
||||
const { price, size, side } = stopOrderSetup.orderSubmission;
|
||||
let trigger: Schema.StopOrderTrigger | null = null;
|
||||
if (stopOrderSetup.price) {
|
||||
trigger = { price: stopOrderSetup.price, __typename: 'StopOrderPrice' };
|
||||
} else if (stopOrderSetup.trailingPercentOffset) {
|
||||
trigger = {
|
||||
trailingPercentOffset: stopOrderSetup.trailingPercentOffset,
|
||||
__typename: 'StopOrderTrailingPercentOffset',
|
||||
};
|
||||
}
|
||||
const triggerDirection = data.risesAbove
|
||||
? Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_RISES_ABOVE
|
||||
: Schema.StopOrderTriggerDirection.TRIGGER_DIRECTION_FALLS_BELOW;
|
||||
return (
|
||||
<Panel>
|
||||
<h4>{t('Submit stop order')}</h4>
|
||||
<p>{market?.tradableInstrument.instrument.code}</p>
|
||||
<p>
|
||||
<SizeAtPrice
|
||||
meta={{
|
||||
positionDecimalPlaces: market.positionDecimalPlaces,
|
||||
decimalPlaces: market.decimalPlaces,
|
||||
asset:
|
||||
market.tradableInstrument.instrument.product.settlementAsset
|
||||
.symbol,
|
||||
}}
|
||||
side={side}
|
||||
size={size}
|
||||
price={price}
|
||||
/>
|
||||
<br />
|
||||
{trigger &&
|
||||
formatTrigger(
|
||||
{
|
||||
triggerDirection,
|
||||
trigger,
|
||||
},
|
||||
market.decimalPlaces,
|
||||
''
|
||||
)}
|
||||
</p>
|
||||
</Panel>
|
||||
);
|
||||
};
|
||||
|
||||
const EditOrderDetails = ({
|
||||
data,
|
||||
order,
|
||||
@@ -237,12 +183,13 @@ const EditOrderDetails = ({
|
||||
variables: { orderId: data.orderId },
|
||||
fetchPolicy: 'no-cache',
|
||||
});
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
const { data: markets } = useMarketList();
|
||||
|
||||
const originalOrder = order || orderById?.orderByID;
|
||||
const marketId = order?.marketId || orderById?.orderByID.market.id;
|
||||
const market = markets?.[marketId || ''];
|
||||
if (!originalOrder || !market) return null;
|
||||
if (!originalOrder) return null;
|
||||
const market = markets?.find((m) => m.id === marketId);
|
||||
if (!market) return null;
|
||||
|
||||
const original = (
|
||||
<SizeAtPrice
|
||||
@@ -298,11 +245,11 @@ const CancelOrderDetails = ({
|
||||
const { data: orderById } = useOrderByIdQuery({
|
||||
variables: { orderId },
|
||||
});
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
const { data: markets } = useMarketList();
|
||||
|
||||
const originalOrder = orderById?.orderByID;
|
||||
if (!originalOrder) return null;
|
||||
const market = markets?.[originalOrder.market.id];
|
||||
const market = markets?.find((m) => m.id === originalOrder.market.id);
|
||||
if (!market) return null;
|
||||
|
||||
const original = (
|
||||
@@ -335,52 +282,15 @@ const CancelOrderDetails = ({
|
||||
);
|
||||
};
|
||||
|
||||
const CancelStopOrderDetails = ({ stopOrderId }: { stopOrderId: string }) => {
|
||||
const { data: orderById } = useStopOrderByIdQuery({
|
||||
variables: { stopOrderId },
|
||||
});
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
|
||||
const originalOrder = orderById?.stopOrder;
|
||||
if (!originalOrder) return null;
|
||||
const market = markets?.[originalOrder.marketId];
|
||||
if (!market) return null;
|
||||
|
||||
const original = (
|
||||
<>
|
||||
<SizeAtPrice
|
||||
side={originalOrder.submission.side}
|
||||
size={originalOrder.submission.size}
|
||||
price={originalOrder.submission.price}
|
||||
meta={{
|
||||
positionDecimalPlaces: market.positionDecimalPlaces,
|
||||
decimalPlaces: market.decimalPlaces,
|
||||
asset:
|
||||
market.tradableInstrument.instrument.product.settlementAsset.symbol,
|
||||
}}
|
||||
/>
|
||||
<br />
|
||||
{formatTrigger(originalOrder, market.decimalPlaces, '')}
|
||||
</>
|
||||
);
|
||||
return (
|
||||
<Panel title={stopOrderId}>
|
||||
<h4>{t('Cancel stop order')}</h4>
|
||||
<p>{market?.tradableInstrument.instrument.code}</p>
|
||||
<p>
|
||||
<s>{original}</s>
|
||||
</p>
|
||||
</Panel>
|
||||
);
|
||||
};
|
||||
|
||||
export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
||||
const { data: assets } = useAssetsMapProvider();
|
||||
const { data: markets } = useMarketsMapProvider();
|
||||
const { data: assets } = useAssetsDataProvider();
|
||||
const { data: markets } = useMarketList();
|
||||
|
||||
if (isWithdrawTransaction(tx.body)) {
|
||||
const transactionDetails = tx.body;
|
||||
const asset = assets?.[transactionDetails.withdrawSubmission.asset];
|
||||
const asset = assets?.find(
|
||||
(a) => a.id === transactionDetails.withdrawSubmission.asset
|
||||
);
|
||||
if (asset) {
|
||||
const num = formatNumber(
|
||||
toBigNum(transactionDetails.withdrawSubmission.amount, asset.decimals),
|
||||
@@ -402,11 +312,15 @@ export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isStopOrdersSubmissionTransaction(tx.body)) {
|
||||
return <SubmitStopOrderDetails data={tx.body.stopOrdersSubmission} />;
|
||||
}
|
||||
|
||||
if (isOrderCancellationTransaction(tx.body)) {
|
||||
// CANCEL ALL (from Portfolio)
|
||||
if (
|
||||
tx.body.orderCancellation.marketId === undefined &&
|
||||
tx.body.orderCancellation.orderId === undefined
|
||||
) {
|
||||
return <Panel>{t('Cancel all orders')}</Panel>;
|
||||
}
|
||||
|
||||
// CANCEL
|
||||
if (
|
||||
tx.body.orderCancellation.orderId &&
|
||||
@@ -422,50 +336,22 @@ export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
||||
|
||||
// CANCEL ALL (from Trading)
|
||||
if (tx.body.orderCancellation.marketId) {
|
||||
const marketName =
|
||||
markets?.[tx.body.orderCancellation.marketId]?.tradableInstrument
|
||||
.instrument.code;
|
||||
if (marketName) {
|
||||
return (
|
||||
<Panel>
|
||||
{t('Cancel all orders for')} <strong>{marketName}</strong>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
}
|
||||
// CANCEL ALL (from Portfolio)
|
||||
return <Panel>{t('Cancel all orders')}</Panel>;
|
||||
}
|
||||
|
||||
if (isStopOrdersCancellationTransaction(tx.body)) {
|
||||
// CANCEL
|
||||
if (
|
||||
tx.body.stopOrdersCancellation.stopOrderId &&
|
||||
tx.body.stopOrdersCancellation.marketId
|
||||
) {
|
||||
const marketName = markets?.find(
|
||||
(m) =>
|
||||
m.id === (tx.body as OrderCancellationBody).orderCancellation.marketId
|
||||
)?.tradableInstrument.instrument.code;
|
||||
return (
|
||||
<CancelStopOrderDetails
|
||||
stopOrderId={String(tx.body.stopOrdersCancellation.stopOrderId)}
|
||||
/>
|
||||
<Panel>
|
||||
{marketName ? (
|
||||
<>
|
||||
{t('Cancel all orders for')} <strong>{marketName}</strong>
|
||||
</>
|
||||
) : (
|
||||
t('Cancel all orders')
|
||||
)}
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
|
||||
// CANCEL ALL for market
|
||||
if (tx.body.stopOrdersCancellation.marketId) {
|
||||
const marketName =
|
||||
markets?.[tx.body.stopOrdersCancellation.marketId]?.tradableInstrument
|
||||
.instrument.code;
|
||||
if (marketName) {
|
||||
return (
|
||||
<Panel>
|
||||
{t('Cancel all stop orders for')} <strong>{marketName}</strong>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// CANCEL ALL
|
||||
return <Panel>{t('Cancel all stop orders')}</Panel>;
|
||||
}
|
||||
|
||||
if (isOrderAmendmentTransaction(tx.body)) {
|
||||
@@ -482,7 +368,7 @@ export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
||||
const marketId = first(
|
||||
transaction.batchMarketInstructions.cancellations
|
||||
)?.marketId;
|
||||
const market = markets?.[marketId || ''];
|
||||
const market = marketId && markets?.find((m) => m.id === marketId);
|
||||
if (market) {
|
||||
return (
|
||||
<Panel>
|
||||
@@ -499,7 +385,7 @@ export const VegaTransactionDetails = ({ tx }: { tx: VegaStoredTxState }) => {
|
||||
|
||||
if (isTransferTransaction(tx.body)) {
|
||||
const { amount, to, asset } = tx.body.transfer;
|
||||
const transferAsset = assets?.[asset];
|
||||
const transferAsset = assets?.find((a) => a.id === asset);
|
||||
// only render if we have an asset to avoid unformatted amounts showing
|
||||
if (transferAsset) {
|
||||
const value = addDecimalsFormatNumber(amount, transferAsset.decimals);
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# First use & get started steps
|
||||
|
||||
## When first enter the app
|
||||
|
||||
- **Must** When I open Console for the first time I can see what it is i.e. a short description and key features in auto opened dialog window (first use popup) (<a name="0007-FUGS-001" href="#0007-FUGS-001">0007-FUGS-001</a>)
|
||||
- **Must** If my wallet is already connected I don't see the first use popup (<a name="0007-FUGS-002" href="#0007-FUGS-002">0007-FUGS-002</a>)
|
||||
- - **Must** If window.vega is detected (browser wallet is installed), don't open first use popup (<a name="0007-FUGS-003" href="#0007-FUGS-003">0007-FUGS-003</a>)
|
||||
- - **Must** If we detect previous connection using localStorage for desktop/cli wallet, don't open first use popup (<a name="0007-FUGS-004" href="#0007-FUGS-004">0007-FUGS-004</a>)
|
||||
- **Must** There is a call to action to browse markets, linking to the market view market/all (<a name="0007-FUGS-005" href="#0007-FUGS-005">0007-FUGS-005</a>)
|
||||
- **Must** I can see the steps I need to take to get started trading (<a name="0007-FUGS-007" href="#0007-FUGS-006">0007-FUGS-006</a>)
|
||||
- **Must** There is a call to action to get started, triggering the connect modal (<a name="0007-FUGS-007" href="#0007-FUGS-007">0007-FUGS-007</a>)
|
||||
- **Must** There is a link to try out trading on Fairground when I'm on Mainnet (<a name="0007-FUGS-008" href="#0007-FUGS-008">0007-FUGS-008</a>)
|
||||
- **Must** There is a link to trade with real funds on Mainnet when I am on Fairground (<a name="0007-FUGS-010" href="#0007-FUGS-010">0007-FUGS-010</a>)
|
||||
- **Must** When I am on the Fairground version, I can see a warning / call out that this is Fairground meaning I can try out with virtual assets at no risk (<a name="0007-FUGS-011" href="#0007-FUGS-011">0007-FUGS-011</a>)
|
||||
- If I dismiss the popup, I land on the default market (<a name="0007-FUGS-012" href="#0007-FUGS-012">0007-FUGS-012</a>)
|
||||
|
||||
## When first use popup has been seen, but no browser wallet is installed
|
||||
|
||||
- **Must** I can see the steps to get started with a visible call to action to "get started" in the context of the deal ticket, deposit, withdraw, transfer components in the sidebar (<a name="0007-FUGS-013" href="#0007-FUGS-013">0007-FUGS-013</a>)
|
||||
- **Must** Remove buttons from pane containers that prompt to connect wallet (<a name="0007-FUGS-014" href="#0007-FUGS-014">0007-FUGS-014</a>)
|
||||
- **Must** We've replaced "connect wallet" in the top right with "get started" (<a name="0007-FUGS-015" href="#0007-FUGS-015">0007-FUGS-015</a>)
|
||||
- **Must** When I press the get started CTA, I see the wallet connect popup (<a name="0007-FUGS-016" href="#0007-FUGS-016">0007-FUGS-016</a>)
|
||||
- **Must** If I have a wallet installed already I don't see this quick start onboarding, and instead call(s) to action in Console revert to connect wallet, not "get started" (button in nav header) (<a name="0007-FUGS-017" href="#0007-FUGS-017">0007-FUGS-017</a>)
|
||||
@@ -14,13 +14,8 @@ domain = 'vega.rocks'
|
||||
bucket_name = ''
|
||||
|
||||
if 'release/' in args.github_ref:
|
||||
if 'mainnet-mirror' in args.github_ref:
|
||||
env_name = 'mainnet-mirror'
|
||||
if 'validators-testnet' in args.github_ref:
|
||||
env_name = 'validators-testnet'
|
||||
else:
|
||||
# remove prefixing release/ and take the first string limited by - which is supposed to be name of the environment for releasing (format: release/testnet-trading)
|
||||
env_name = args.github_ref.replace('refs/heads/release/', '').split('-')[0]
|
||||
# remove prefixing release/ and take the first string limited by - which is supposed to be name of the environment for releasing (format: release/testnet-trading)
|
||||
env_name = args.github_ref.replace('refs/heads/release/', '').split('-')[0]
|
||||
elif 'develop' in args.github_ref:
|
||||
env_name = 'stagnet1'
|
||||
apps_deployed_from_develop_to_mainnet = {
|
||||
|
||||
Reference in New Issue
Block a user