Merge branch 'main' of github.com:vegaprotocol/frontend-monorepo into fix/remove-asset-in-settled-market-check

This commit is contained in:
Madalina Raicu 2024-02-02 13:48:51 +00:00
commit 70d054de81
No known key found for this signature in database
GPG Key ID: 688B7B31149C1DCD
284 changed files with 7713 additions and 3323 deletions

View File

@ -205,7 +205,7 @@ jobs:
# run tests # run tests
#---------------------------------------------- #----------------------------------------------
- name: Run tests - name: Run tests
run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v -s --numprocesses 1 --dist loadfile --durations=45 run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v --numprocesses 1 --dist loadfile --durations=45
working-directory: apps/trading/e2e working-directory: apps/trading/e2e
#---------------------------------------------- #----------------------------------------------
# upload traces # upload traces

View File

@ -1,5 +1,4 @@
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.rocks NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.rocks
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
NX_VEGA_ENV=STAGNET1 NX_VEGA_ENV=STAGNET1
@ -9,7 +8,6 @@ NX_VEGA_WALLET_URL=http://localhost:1789
NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks NX_TENDERMINT_URL=https://tm.n01.stagnet1.vega.rocks
NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://tm.n01.stagnet1.vega.xyz/websocket
NX_BLOCK_EXPLORER=https://be.stagnet1.vega.rocks/rest NX_BLOCK_EXPLORER=https://be.stagnet1.vega.rocks/rest
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json
NX_VEGA_GOVERNANCE_URL=https://governance.stagnet1.vega.rocks NX_VEGA_GOVERNANCE_URL=https://governance.stagnet1.vega.rocks
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json

View File

@ -1,6 +1,5 @@
# App configuration variables # App configuration variables
NX_VEGA_ENV=CUSTOM NX_VEGA_ENV=CUSTOM
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_VEGA_EXPLORER_URL=/ NX_VEGA_EXPLORER_URL=/
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json

View File

@ -2,7 +2,6 @@
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml
NX_VEGA_ENV=DEVNET NX_VEGA_ENV=DEVNET
NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest NX_BLOCK_EXPLORER=https://be.devnet1.vega.xyz/rest
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_GOVERNANCE_URL=https://dev.governance.vega.xyz NX_VEGA_GOVERNANCE_URL=https://dev.governance.vega.xyz
NX_VEGA_URL=https://api.devnet1.vega.xyz/graphql NX_VEGA_URL=https://api.devnet1.vega.xyz/graphql
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/devnet1/vegawallet-devnet1.toml

View File

@ -4,7 +4,6 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/maste
NX_VEGA_URL=https://api.vega.community/graphql NX_VEGA_URL=https://api.vega.community/graphql
NX_VEGA_ENV=MAINNET NX_VEGA_ENV=MAINNET
NX_BLOCK_EXPLORER=https://be.vega.community/rest NX_BLOCK_EXPLORER=https://be.vega.community/rest
NX_ETHERSCAN_URL=https://etherscan.io
NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz NX_VEGA_GOVERNANCE_URL=https://governance.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/ NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz/

View File

@ -4,7 +4,6 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-inter
NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql NX_VEGA_URL=https://api.mainnet-mirror.vega.rocks/graphql
NX_VEGA_ENV=MAINNET_MIRROR NX_VEGA_ENV=MAINNET_MIRROR
NX_BLOCK_EXPLORER=https://be.mainnet-mirror.vega.rocks/rest NX_BLOCK_EXPLORER=https://be.mainnet-mirror.vega.rocks/rest
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks NX_VEGA_GOVERNANCE_URL=https://governance.mainnet-mirror.vega.rocks
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks/ NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks/

View File

@ -4,7 +4,6 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-inter
NX_VEGA_ENV=TESTNET NX_VEGA_ENV=TESTNET
NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql NX_VEGA_URL=https://api.n07.testnet.vega.xyz/graphql
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf NX_VEGA_GOVERNANCE_URL=https://governance.fairground.wtf
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf

View File

@ -4,7 +4,6 @@ NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks/maste
NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql NX_VEGA_URL=https://api-validators-testnet.vega.rocks/graphql
NX_VEGA_REST=https://api-validators-testnet.vega.rocks/ NX_VEGA_REST=https://api-validators-testnet.vega.rocks/
NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8 NX_ETHEREUM_PROVIDER_URL=https://sepolia.infura.io/v3/4f846e79e13f44d1b51bbd7ed9edefb8
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest NX_BLOCK_EXPLORER=https://be.validators-testnet.vega.rocks/rest

View File

@ -3,7 +3,6 @@ NX_TENDERMINT_URL=http://localhost:26607/
NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26607/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://localhost:26607/websocket
NX_VEGA_ENV=CUSTOM NX_VEGA_ENV=CUSTOM
NX_BLOCK_EXPLORER= NX_BLOCK_EXPLORER=
NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/test/announcements.json
NX_VEGA_EXPLORER_URL=/ NX_VEGA_EXPLORER_URL=/
NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/main/__generated__/oracle-proofs.json

View File

@ -1,34 +0,0 @@
import React from 'react';
import { DATA_SOURCES } from '../../../config';
import Hash from '../hash';
export enum EthExplorerLinkTypes {
block = 'block',
address = 'address',
tx = 'tx',
}
export type EthExplorerLinkProps = Partial<typeof HTMLAnchorElement> & {
id: string;
type: EthExplorerLinkTypes;
};
export const EthExplorerLink = ({
id,
type,
...props
}: EthExplorerLinkProps) => {
const link = `${DATA_SOURCES.ethExplorerUrl}/${type}/${id}`;
return (
<a
className="underline external font-mono"
target="_blank"
rel="noopener noreferrer"
{...props}
href={link}
>
<Hash text={id} />
</a>
);
};

View File

@ -0,0 +1,34 @@
import type { ChainIdMapping } from './external-chain';
import { SUPPORTED_CHAIN_IDS, SUPPORTED_CHAIN_LABELS } from './external-chain';
export const SUPPORTED_CHAIN_ICON_URLS: ChainIdMapping = {
'1': '/assets/chain-eth-logo.svg',
'100': '/assets/chain-gno-logo.svg',
'42161': '/assets/chain-arb-logo.svg',
'11155111': '/assets/chain-eth-logo.svg',
};
export type ExternalChainIconProps = {
chainId?: string;
};
export const ExternalChainIcon = ({
// If chainID is not provided, default to a non-existent chain
chainId = '-1',
}: ExternalChainIconProps) => {
if (SUPPORTED_CHAIN_IDS.includes(chainId)) {
const url = SUPPORTED_CHAIN_ICON_URLS[chainId];
const alt = SUPPORTED_CHAIN_LABELS[chainId];
return (
<img
src={url}
className="inline-block w-4 h-4 mr-1 dark:invert"
alt={alt}
title={alt}
/>
);
} else {
return null;
}
};

View File

@ -0,0 +1,38 @@
export type ChainIdMapping = {
[K in typeof SUPPORTED_CHAIN_IDS[number]]: string;
};
export const SUPPORTED_CHAIN_IDS: string[] = ['1', '100', '42161', '11155111'];
export const SUPPORTED_CHAIN_LABELS: ChainIdMapping = {
'1': 'Ethereum',
'100': 'Gnosis',
'42161': 'Arbitrum',
'11155111': 'Sepolia',
};
export function getExternalExplorerLink(chainId: string, type: string) {
if (SUPPORTED_CHAIN_IDS.includes(chainId)) {
switch (chainId) {
case '1':
return 'https://etherscan.io';
case '100':
return 'https://gnosisscan.io';
case '42161':
return 'https://arbiscan.io';
case '11155111':
return 'https://sepolia.etherscan.io';
default:
return '#';
}
} else {
return '#';
}
}
export function getExternalChainLabel(chainId?: string) {
if (chainId && SUPPORTED_CHAIN_IDS.includes(chainId)) {
return SUPPORTED_CHAIN_LABELS[chainId];
} else {
return 'Custom Chain';
}
}

View File

@ -0,0 +1,41 @@
import Hash from '../hash';
import { getExternalExplorerLink } from './external-chain';
import { ExternalChainIcon } from './external-chain-icon';
export enum EthExplorerLinkTypes {
block = 'block',
address = 'address',
tx = 'tx',
}
export type ExternalExplorerLinkProps = Partial<typeof HTMLAnchorElement> & {
id: string;
type: EthExplorerLinkTypes;
// Defaults to Ethereum Mainnet, as chain support was added late
chain?: string;
code?: boolean;
};
export const ExternalExplorerLink = ({
id,
type,
chain = '1',
code = false,
...props
}: ExternalExplorerLinkProps) => {
const link = `${getExternalExplorerLink(chain, type)}/${type}/${id}${
code ? '#code' : ''
}`;
return (
<a
className="underline external font-mono"
target="_blank"
rel="noopener noreferrer"
{...props}
href={link}
>
<ExternalChainIcon chainId={chain} />
<Hash text={id} />
</a>
);
};

View File

@ -1,9 +1,11 @@
query ExplorerProposal($id: ID!) { query ExplorerProposal($id: ID!) {
proposal(id: $id) { proposal(id: $id) {
id ... on Proposal {
rationale { id
title rationale {
description title
description
}
} }
} }
} }

View File

@ -8,16 +8,18 @@ export type ExplorerProposalQueryVariables = Types.Exact<{
}>; }>;
export type ExplorerProposalQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null }; export type ExplorerProposalQuery = { __typename?: 'Query', proposal?: { __typename?: 'BatchProposal' } | { __typename?: 'Proposal', id?: string | null, rationale: { __typename?: 'ProposalRationale', title: string, description: string } } | null };
export const ExplorerProposalDocument = gql` export const ExplorerProposalDocument = gql`
query ExplorerProposal($id: ID!) { query ExplorerProposal($id: ID!) {
proposal(id: $id) { proposal(id: $id) {
id ... on Proposal {
rationale { id
title rationale {
description title
description
}
} }
} }
} }

View File

@ -3,7 +3,11 @@ import { MockedProvider } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing'; import type { MockedResponse } from '@apollo/client/testing';
import { render } from '@testing-library/react'; import { render } from '@testing-library/react';
import ProposalLink from './proposal-link'; import ProposalLink from './proposal-link';
import { ExplorerProposalDocument } from './__generated__/Proposal'; import {
ExplorerProposalDocument,
type ExplorerProposalQuery,
type ExplorerProposalQueryVariables,
} from './__generated__/Proposal';
import { GraphQLError } from 'graphql'; import { GraphQLError } from 'graphql';
function renderComponent(id: string, mocks: MockedResponse[]) { function renderComponent(id: string, mocks: MockedResponse[]) {
@ -23,7 +27,10 @@ describe('Proposal link component', () => {
}); });
it('Renders the ID on error', async () => { it('Renders the ID on error', async () => {
const mock = { const mock: MockedResponse<
ExplorerProposalQuery,
ExplorerProposalQueryVariables
> = {
request: { request: {
query: ExplorerProposalDocument, query: ExplorerProposalDocument,
variables: { variables: {
@ -40,17 +47,22 @@ describe('Proposal link component', () => {
}); });
it('Renders the proposal title when the query returns a result', async () => { it('Renders the proposal title when the query returns a result', async () => {
const mock = { const proposalId = '123';
const mock: MockedResponse<
ExplorerProposalQuery,
ExplorerProposalQueryVariables
> = {
request: { request: {
query: ExplorerProposalDocument, query: ExplorerProposalDocument,
variables: { variables: {
id: '123', id: proposalId,
}, },
}, },
result: { result: {
data: { data: {
proposal: { proposal: {
id: '123', __typename: 'Proposal',
id: proposalId,
rationale: { rationale: {
title: 'test-title', title: 'test-title',
description: 'test description', description: 'test description',
@ -60,13 +72,16 @@ describe('Proposal link component', () => {
}, },
}; };
const res = render(renderComponent('123', [mock])); const res = render(renderComponent(proposalId, [mock]));
expect(res.getByText('123')).toBeInTheDocument(); expect(res.getByText(proposalId)).toBeInTheDocument();
expect(await res.findByText('test-title')).toBeInTheDocument(); expect(await res.findByText('test-title')).toBeInTheDocument();
}); });
it('Leaves the proposal id when the market is not found', async () => { it('Leaves the proposal id when the market is not found', async () => {
const mock = { const mock: MockedResponse<
ExplorerProposalQuery,
ExplorerProposalQueryVariables
> = {
request: { request: {
query: ExplorerProposalDocument, query: ExplorerProposalDocument,
variables: { variables: {

View File

@ -1,7 +1,11 @@
import { useExplorerProposalQuery } from './__generated__/Proposal'; import {
useExplorerProposalQuery,
type ExplorerProposalQuery,
} from './__generated__/Proposal';
import { ExternalLink } from '@vegaprotocol/ui-toolkit'; import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { ENV } from '../../../config/env'; import { ENV } from '../../../config/env';
import Hash from '../hash'; import Hash from '../hash';
export type ProposalLinkProps = { export type ProposalLinkProps = {
id: string; id: string;
text?: string; text?: string;
@ -16,8 +20,13 @@ const ProposalLink = ({ id, text }: ProposalLinkProps) => {
variables: { id }, variables: { id },
}); });
const proposal = data?.proposal as Extract<
ExplorerProposalQuery['proposal'],
{ __typename?: 'Proposal' }
>;
const base = ENV.dataSources.governanceUrl; const base = ENV.dataSources.governanceUrl;
const label = data?.proposal?.rationale.title || id; const label = proposal?.rationale.title || id;
return ( return (
<ExternalLink href={`${base}/proposals/${id}`}> <ExternalLink href={`${base}/proposals/${id}`}>

View File

@ -1,6 +1,7 @@
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import type { MarketInfoWithData } from '@vegaprotocol/markets'; import type { MarketInfoWithData } from '@vegaprotocol/markets';
import { import {
LiquidationStrategyInfoPanel,
LiquidityPriceRangeInfoPanel, LiquidityPriceRangeInfoPanel,
LiquiditySLAParametersInfoPanel, LiquiditySLAParametersInfoPanel,
MarginScalingFactorsPanel, MarginScalingFactorsPanel,
@ -94,6 +95,8 @@ export const MarketDetails = ({ market }: { market: MarketInfoWithData }) => {
</> </>
) )
)} )}
<h2 className={headerClassName}>{t('Liquidation strategy')}</h2>
<LiquidationStrategyInfoPanel market={market} />
<h2 className={headerClassName}>{t('Liquidity monitoring')}</h2> <h2 className={headerClassName}>{t('Liquidity monitoring')}</h2>
<LiquidityMonitoringParametersInfoPanel market={market} /> <LiquidityMonitoringParametersInfoPanel market={market} />
<h2 className={headerClassName}>{t('Liquidity price range')}</h2> <h2 className={headerClassName}>{t('Liquidity price range')}</h2>

View File

@ -1,9 +1,10 @@
import { TableCell, TableRow } from '../../../table'; import { TableCell, TableRow } from '../../../table';
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
import { getExternalChainLabel } from '../../../links/external-explorer-link/external-chain';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { defaultAbiCoder, base64 } from 'ethers/lib/utils'; import { defaultAbiCoder, base64 } from 'ethers/lib/utils';
import { BigNumber } from 'ethers'; import { BigNumber } from 'ethers';
@ -44,10 +45,10 @@ export const TxDetailsContractCall = ({
}, },
}); });
if (!contractCall || !contractCall.result) { if (!contractCall) {
return null; return null;
} }
const chainLabel = getExternalChainLabel(contractCall.sourceChainId);
return ( return (
<> <>
{contractCall.specId && ( {contractCall.specId && (
@ -64,9 +65,12 @@ export const TxDetailsContractCall = ({
)} )}
{contractCall.blockHeight && ( {contractCall.blockHeight && (
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('ETH block')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink {chainLabel} {t('block')}
</TableCell>
<TableCell>
<ExternalExplorerLink
chain={contractCall.sourceChainId}
id={contractCall.blockHeight} id={contractCall.blockHeight}
type={EthExplorerLinkTypes.block} type={EthExplorerLinkTypes.block}
/> />
@ -75,14 +79,24 @@ export const TxDetailsContractCall = ({
)} )}
{data?.oracleSpec?.dataSourceSpec && ( {data?.oracleSpec?.dataSourceSpec && (
<OracleEthSource <OracleEthSource
chain={contractCall.sourceChainId}
sourceType={data.oracleSpec.dataSourceSpec.spec.data.sourceType} sourceType={data.oracleSpec.dataSourceSpec.spec.data.sourceType}
/> />
)} )}
<TableRow modifier="bordered"> {contractCall.error && (
<TableCell>{t('Result')}</TableCell> <TableRow modifier="bordered">
<TableCell>{decodeEthCallResult(contractCall.result)}</TableCell> <TableCell>{t('Call error')}</TableCell>
</TableRow> <TableCell>{contractCall.error}</TableCell>
</TableRow>
)}
{contractCall.result && (
<TableRow modifier="bordered">
<TableCell>{t('Result')}</TableCell>
<TableCell>{decodeEthCallResult(contractCall.result)}</TableCell>
</TableRow>
)}
</> </>
); );
}; };

View File

@ -3,9 +3,9 @@ import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { AssetLink } from '../../../links'; import { AssetLink } from '../../../links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventErc20AssetLimitsUpdatedProps { interface TxDetailsChainEventErc20AssetLimitsUpdatedProps {
assetLimitsUpdated: components['schemas']['vegaERC20AssetLimitsUpdated']; assetLimitsUpdated: components['schemas']['vegaERC20AssetLimitsUpdated'];
@ -42,7 +42,7 @@ export const TxDetailsChainEventErc20AssetLimitsUpdated = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('ERC20 asset')}</TableCell> <TableCell>{t('ERC20 asset')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={assetLimitsUpdated.sourceEthereumAddress} id={assetLimitsUpdated.sourceEthereumAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -3,9 +3,9 @@ import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { AssetLink } from '../../../links'; import { AssetLink } from '../../../links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventErc20AssetListProps { interface TxDetailsChainEventErc20AssetListProps {
assetList: components['schemas']['vegaERC20AssetList']; assetList: components['schemas']['vegaERC20AssetList'];
@ -32,7 +32,7 @@ export const TxDetailsChainEventErc20AssetList = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell> <TableCell>{t('Source')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={assetList.assetSource} id={assetList.assetSource}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -3,9 +3,9 @@ import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { AssetLink, PartyLink } from '../../../links'; import { AssetLink, PartyLink } from '../../../links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventProps { interface TxDetailsChainEventProps {
deposit: components['schemas']['vegaERC20Deposit']; deposit: components['schemas']['vegaERC20Deposit'];
@ -36,7 +36,7 @@ export const TxDetailsChainEventDeposit = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell> <TableCell>{t('Source')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={deposit.sourceEthereumAddress} id={deposit.sourceEthereumAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -3,9 +3,9 @@ import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { AssetLink } from '../../../links'; import { AssetLink } from '../../../links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventWithdrawalProps { interface TxDetailsChainEventWithdrawalProps {
withdrawal: components['schemas']['vegaERC20Withdrawal']; withdrawal: components['schemas']['vegaERC20Withdrawal'];
@ -35,7 +35,7 @@ export const TxDetailsChainEventWithdrawal = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Recipient')}</TableCell> <TableCell>{t('Recipient')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={withdrawal.targetEthereumAddress} id={withdrawal.targetEthereumAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -3,9 +3,9 @@ import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { PartyLink } from '../../../links'; import { PartyLink } from '../../../links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventStakeDepositProps { interface TxDetailsChainEventStakeDepositProps {
deposit: components['schemas']['vegaStakeDeposited']; deposit: components['schemas']['vegaStakeDeposited'];
@ -39,7 +39,7 @@ export const TxDetailsChainEventStakeDeposit = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell> <TableCell>{t('Source')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={deposit.ethereumAddress} id={deposit.ethereumAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -3,9 +3,9 @@ import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { PartyLink } from '../../../links'; import { PartyLink } from '../../../links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventStakeRemoveProps { interface TxDetailsChainEventStakeRemoveProps {
remove: components['schemas']['vegaStakeRemoved']; remove: components['schemas']['vegaStakeRemoved'];
@ -39,7 +39,7 @@ export const TxDetailsChainEventStakeRemove = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell> <TableCell>{t('Source')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={remove.ethereumAddress} id={remove.ethereumAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -3,9 +3,9 @@ import { t } from '@vegaprotocol/i18n';
import { TableRow, TableCell } from '../../../table'; import { TableRow, TableCell } from '../../../table';
import type { components } from '../../../../../types/explorer'; import type { components } from '../../../../../types/explorer';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../links/eth-explorer-link/eth-explorer-link'; } from '../../../links/external-explorer-link/external-explorer-link';
interface TxDetailsChainEventStakeTotalSupplyProps { interface TxDetailsChainEventStakeTotalSupplyProps {
update: components['schemas']['vegaStakeTotalSupply']; update: components['schemas']['vegaStakeTotalSupply'];
@ -38,7 +38,7 @@ export const TxDetailsChainEventStakeTotalSupply = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Source')}</TableCell> <TableCell>{t('Source')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={update.tokenAddress} id={update.tokenAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -1,7 +1,9 @@
query ExplorerProposalStatus($id: ID!) { query ExplorerProposalStatus($id: ID!) {
proposal(id: $id) { proposal(id: $id) {
id ... on Proposal {
state id
rejectionReason state
rejectionReason
}
} }
} }

View File

@ -8,15 +8,17 @@ export type ExplorerProposalStatusQueryVariables = Types.Exact<{
}>; }>;
export type ExplorerProposalStatusQuery = { __typename?: 'Query', proposal?: { __typename?: 'Proposal', id?: string | null, state: Types.ProposalState, rejectionReason?: Types.ProposalRejectionReason | null } | null }; export type ExplorerProposalStatusQuery = { __typename?: 'Query', proposal?: { __typename?: 'BatchProposal' } | { __typename?: 'Proposal', id?: string | null, state: Types.ProposalState, rejectionReason?: Types.ProposalRejectionReason | null } | null };
export const ExplorerProposalStatusDocument = gql` export const ExplorerProposalStatusDocument = gql`
query ExplorerProposalStatus($id: ID!) { query ExplorerProposalStatus($id: ID!) {
proposal(id: $id) { proposal(id: $id) {
id ... on Proposal {
state id
rejectionReason state
rejectionReason
}
} }
} }
`; `;

View File

@ -14,16 +14,18 @@ export function format(date: string | undefined, def: string) {
return new Date().toLocaleDateString() || def; return new Date().toLocaleDateString() || def;
} }
export function getDate( type Proposal = Extract<
data: ExplorerProposalStatusQuery | undefined, ExplorerProposalStatusQuery['proposal'],
terms: Terms { __typename?: 'Proposal' }
): string { >;
export function getDate(proposal: Proposal | undefined, terms: Terms): string {
const DEFAULT = t('Unknown'); const DEFAULT = t('Unknown');
if (!data?.proposal?.state) { if (!proposal?.state) {
return DEFAULT; return DEFAULT;
} }
switch (data.proposal.state) { switch (proposal.state) {
case 'STATE_DECLINED': case 'STATE_DECLINED':
return `${t('Rejected on')}: ${format(terms.closingTimestamp, DEFAULT)}`; return `${t('Rejected on')}: ${format(terms.closingTimestamp, DEFAULT)}`;
case 'STATE_ENACTED': case 'STATE_ENACTED':
@ -62,9 +64,11 @@ export const ProposalDate = ({ terms, id }: ProposalDateProps) => {
}, },
}); });
const proposal = data?.proposal as Proposal;
return ( return (
<Lozenge className="font-sans text-xs float-right"> <Lozenge className="font-sans text-xs float-right">
{getDate(data, terms)} {getDate(proposal, terms)}
</Lozenge> </Lozenge>
); );
}; };

View File

@ -2,17 +2,8 @@ import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit';
import type { IconProps } from '@vegaprotocol/ui-toolkit'; import type { IconProps } from '@vegaprotocol/ui-toolkit';
import { useExplorerProposalStatusQuery } from './__generated__/Proposal'; import { useExplorerProposalStatusQuery } from './__generated__/Proposal';
import type { ExplorerProposalStatusQuery } from './__generated__/Proposal'; import type { ExplorerProposalStatusQuery } from './__generated__/Proposal';
import type * as Apollo from '@apollo/client';
import type * as Types from '@vegaprotocol/types';
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
type ProposalQueryResult = Apollo.QueryResult<
ExplorerProposalStatusQuery,
Types.Exact<{
id: string;
}>
>;
interface ProposalStatusIconProps { interface ProposalStatusIconProps {
id: string; id: string;
} }
@ -29,29 +20,38 @@ type IconAndLabel = {
* @param data a data result from useExplorerProposalStatusQuery * @param data a data result from useExplorerProposalStatusQuery
* @returns Icon name * @returns Icon name
*/ */
export function getIconAndLabelForStatus( export function useIconAndLabelForStatus(id: string): IconAndLabel {
res: ProposalQueryResult const { data, loading, error } = useExplorerProposalStatusQuery({
): IconAndLabel { variables: {
id,
},
});
const proposal = data?.proposal as Extract<
ExplorerProposalStatusQuery['proposal'],
{ __typename?: 'Proposal' }
>;
const DEFAULT: IconAndLabel = { const DEFAULT: IconAndLabel = {
icon: 'error', icon: 'error',
label: t('Proposal state unknown'), label: t('Proposal state unknown'),
}; };
if (res.loading) { if (loading) {
return { return {
icon: 'more', icon: 'more',
label: t('Loading data'), label: t('Loading data'),
}; };
} }
if (!res?.data?.proposal || res.error) { if (!data?.proposal || error) {
return { return {
icon: 'error', icon: 'error',
label: res.error?.message || DEFAULT.label, label: error?.message || DEFAULT.label,
}; };
} }
switch (res.data.proposal.state) { switch (proposal.state) {
case 'STATE_DECLINED': case 'STATE_DECLINED':
return { return {
icon: 'stop', icon: 'stop',
@ -99,13 +99,7 @@ export function getIconAndLabelForStatus(
/** /**
*/ */
export const ProposalStatusIcon = ({ id }: ProposalStatusIconProps) => { export const ProposalStatusIcon = ({ id }: ProposalStatusIconProps) => {
const { icon, label } = getIconAndLabelForStatus( const { icon, label } = useIconAndLabelForStatus(id);
useExplorerProposalStatusQuery({
variables: {
id,
},
})
);
return ( return (
<div className="float-left mr-3"> <div className="float-left mr-3">

View File

@ -41,6 +41,7 @@ const AccountType: Record<AccountTypes, string> = {
ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY: 'Reward Return Volatility', ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY: 'Reward Return Volatility',
ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING: 'Reward Validator Ranking', ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING: 'Reward Validator Ranking',
ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD: 'Pending Fee Referral Reward', ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD: 'Pending Fee Referral Reward',
ACCOUNT_TYPE_ORDER_MARGIN: 'Order Margin',
}; };
interface TransferParticipantsProps { interface TransferParticipantsProps {

View File

@ -32,6 +32,7 @@ import { TxDetailsCreateReferralSet } from './tx-create-referral-set';
import { TxDetailsApplyReferralCode } from './tx-apply-referral-code'; import { TxDetailsApplyReferralCode } from './tx-apply-referral-code';
import { TxDetailsUpdateReferralSet } from './tx-update-referral-set'; import { TxDetailsUpdateReferralSet } from './tx-update-referral-set';
import { TxDetailsJoinTeam } from './tx-join-team'; import { TxDetailsJoinTeam } from './tx-join-team';
import { TxDetailsUpdateMarginMode } from './tx-update-margin-mode';
interface TxDetailsWrapperProps { interface TxDetailsWrapperProps {
txData: BlockExplorerTransactionResult | undefined; txData: BlockExplorerTransactionResult | undefined;
@ -133,6 +134,8 @@ function getTransactionComponent(txData?: BlockExplorerTransactionResult) {
return TxDetailsApplyReferralCode; return TxDetailsApplyReferralCode;
case 'Join Team': case 'Join Team':
return TxDetailsJoinTeam; return TxDetailsJoinTeam;
case 'Update Margin Mode':
return TxDetailsUpdateMarginMode;
default: default:
return TxDetailsGeneric; return TxDetailsGeneric;
} }

View File

@ -5,9 +5,9 @@ import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table'; import { TableCell, TableRow, TableWithTbody } from '../../table';
import type { components } from '../../../../types/explorer'; import type { components } from '../../../../types/explorer';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link'; } from '../../links/external-explorer-link/external-explorer-link';
import { BlockLink } from '../../links'; import { BlockLink } from '../../links';
type EthKeyRotate = components['schemas']['v1EthereumKeyRotateSubmission']; type EthKeyRotate = components['schemas']['v1EthereumKeyRotateSubmission'];
@ -46,7 +46,7 @@ export const TxDetailsEthKeyRotate = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Old Address')}</TableCell> <TableCell>{t('Old Address')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
id={k.currentAddress} id={k.currentAddress}
/> />
@ -57,7 +57,7 @@ export const TxDetailsEthKeyRotate = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('New Address')}</TableCell> <TableCell>{t('New Address')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
id={k.newAddress} id={k.newAddress}
/> />
@ -68,7 +68,7 @@ export const TxDetailsEthKeyRotate = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Submitter address')}</TableCell> <TableCell>{t('Submitter address')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
id={k.submitterAddress} id={k.submitterAddress}
/> />

View File

@ -6,9 +6,9 @@ import { TableRow, TableCell, TableWithTbody } from '../../table';
import type { components } from '../../../../types/explorer'; import type { components } from '../../../../types/explorer';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link'; } from '../../links/external-explorer-link/external-explorer-link';
import { NodeLink } from '../../links'; import { NodeLink } from '../../links';
type Command = components['schemas']['v1IssueSignatures']; type Command = components['schemas']['v1IssueSignatures'];
@ -57,7 +57,7 @@ export const TxDetailsIssueSignatures = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('ETH key')}</TableCell> <TableCell>{t('ETH key')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={cmd.submitter} id={cmd.submitter}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -6,9 +6,9 @@ import { TableRow, TableCell, TableWithTbody } from '../../table';
import type { components } from '../../../../types/explorer'; import type { components } from '../../../../types/explorer';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link'; } from '../../links/external-explorer-link/external-explorer-link';
import { PartyLink } from '../../links'; import { PartyLink } from '../../links';
import Hash from '../../links/hash'; import Hash from '../../links/hash';
import { ExternalLink } from '@vegaprotocol/ui-toolkit'; import { ExternalLink } from '@vegaprotocol/ui-toolkit';
@ -72,7 +72,7 @@ export const TxDetailsNodeAnnounce = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Ethereum Address')}</TableCell> <TableCell>{t('Ethereum Address')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
id={cmd.ethereumAddress} id={cmd.ethereumAddress}
/> />

View File

@ -8,9 +8,9 @@ import { useExplorerNodeVoteQuery } from './__generated__/Node-vote';
import { PartyLink } from '../../links'; import { PartyLink } from '../../links';
import { Time } from '../../time'; import { Time } from '../../time';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link'; } from '../../links/external-explorer-link/external-explorer-link';
interface TxDetailsNodeVoteProps { interface TxDetailsNodeVoteProps {
txData: BlockExplorerTransactionResult | undefined; txData: BlockExplorerTransactionResult | undefined;
@ -143,7 +143,7 @@ export function TxHash({ hash }: TxDetailsEthTxHashProps) {
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>Ethereum TX:</TableCell> <TableCell>Ethereum TX:</TableCell>
<TableCell> <TableCell>
<EthExplorerLink id={hash} type={EthExplorerLinkTypes.tx} /> <ExternalExplorerLink id={hash} type={EthExplorerLinkTypes.tx} />
</TableCell> </TableCell>
</TableRow> </TableRow>
); );

View File

@ -8,7 +8,7 @@ import GovernanceAssetBalance from '../../asset-balance/governance-asset-balance
import type { components } from '../../../../types/explorer'; import type { components } from '../../../../types/explorer';
export const methodText: Record< export const methodText: Record<
components['schemas']['UndelegateSubmissionMethod'], components['schemas']['v1UndelegateSubmissionMethod'],
string string
> = { > = {
METHOD_NOW: 'Immediate', METHOD_NOW: 'Immediate',

View File

@ -0,0 +1,60 @@
import { t } from '@vegaprotocol/i18n';
import type { BlockExplorerTransactionResult } from '../../../routes/types/block-explorer-response';
import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint-blocks-response';
import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table';
import type { components } from '../../../../types/explorer';
import { MarketLink } from '../../links';
interface TxDetailsUpdateMarginModeProps {
txData: BlockExplorerTransactionResult | undefined;
pubKey: string | undefined;
blockData: TendermintBlocksResponse | undefined;
}
type Mode = components['schemas']['UpdateMarginModeMode'];
const MarginModeLabels: Record<Mode, string> = {
MODE_CROSS_MARGIN: t('Cross margin'),
MODE_ISOLATED_MARGIN: t('Isolated margin'),
MODE_UNSPECIFIED: t('Unspecified'),
};
export const TxDetailsUpdateMarginMode = ({
txData,
pubKey,
blockData,
}: TxDetailsUpdateMarginModeProps) => {
if (!txData || !txData.command.updateMarginMode) {
return <>{t('Awaiting Block Explorer transaction details')}</>;
}
const u: components['schemas']['v1UpdateMarginMode'] =
txData.command.updateMarginMode;
return (
<TableWithTbody className="mb-8" allowWrap={true}>
<TxDetailsShared txData={txData} pubKey={pubKey} blockData={blockData} />
{u.marketId && (
<TableRow modifier="bordered">
<TableCell>{t('Market ID')}</TableCell>
<TableCell>
<MarketLink id={u.marketId} />
</TableCell>
</TableRow>
)}
{u.mode && (
<TableRow modifier="bordered">
<TableCell>{t('New margin mode')}</TableCell>
<TableCell>{MarginModeLabels[u.mode]}</TableCell>
</TableRow>
)}
{u.marginFactor && (
<TableRow modifier="bordered">
<TableCell>{t('Margin factor')}</TableCell>
<TableCell>{u.marginFactor}</TableCell>
</TableRow>
)}
</TableWithTbody>
);
};

View File

@ -4,9 +4,9 @@ import type { TendermintBlocksResponse } from '../../../routes/blocks/tendermint
import { TxDetailsShared } from './shared/tx-details-shared'; import { TxDetailsShared } from './shared/tx-details-shared';
import { TableCell, TableRow, TableWithTbody } from '../../table'; import { TableCell, TableRow, TableWithTbody } from '../../table';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../links/eth-explorer-link/eth-explorer-link'; } from '../../links/external-explorer-link/external-explorer-link';
import { txSignatureToDeterministicId } from '../lib/deterministic-ids'; import { txSignatureToDeterministicId } from '../lib/deterministic-ids';
import AssetBalance from '../../asset-balance/asset-balance'; import AssetBalance from '../../asset-balance/asset-balance';
import { useScrollToLocation } from '../../../hooks/scroll-to-location'; import { useScrollToLocation } from '../../../hooks/scroll-to-location';
@ -57,7 +57,7 @@ export const TxDetailsWithdrawSubmission = ({
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableCell>{t('Recipient')}</TableCell> <TableCell>{t('Recipient')}</TableCell>
<TableCell> <TableCell>
<EthExplorerLink <ExternalExplorerLink
id={w.ext.erc20.receiverAddress} id={w.ext.erc20.receiverAddress}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />

View File

@ -44,6 +44,7 @@ export type FilterOption =
| 'Transfer Funds' | 'Transfer Funds'
| 'Undelegate' | 'Undelegate'
| 'Update Referral Set' | 'Update Referral Set'
| 'Update Margin Mode'
| 'Validator Heartbeat' | 'Validator Heartbeat'
| 'Vote on Proposal' | 'Vote on Proposal'
| 'Withdraw'; | 'Withdraw';
@ -59,6 +60,7 @@ export const filterOptions: Record<string, FilterOption[]> = {
'Stop Orders Submission', 'Stop Orders Submission',
'Stop Orders Cancellation', 'Stop Orders Cancellation',
'Submit Order', 'Submit Order',
'Update Margin Mode',
], ],
'Transfers and Withdrawals': [ 'Transfers and Withdrawals': [
'Transfer Funds', 'Transfer Funds',

View File

@ -61,53 +61,4 @@ describe('TxsListNavigation', () => {
expect(nextPageMock).toHaveBeenCalledTimes(1); expect(nextPageMock).toHaveBeenCalledTimes(1);
}); });
it('disables "Older" button if hasMoreTxs is false', () => {
render(
<TxsListNavigation
refreshTxs={NOOP}
nextPage={NOOP}
previousPage={NOOP}
hasMoreTxs={false}
hasPreviousPage={false}
>
<span></span>
</TxsListNavigation>
);
expect(screen.getByText('Older')).toBeDisabled();
});
it('disables "Newer" button if hasPreviousPage is false', () => {
render(
<TxsListNavigation
refreshTxs={NOOP}
nextPage={NOOP}
previousPage={NOOP}
hasMoreTxs={true}
hasPreviousPage={false}
>
<span></span>
</TxsListNavigation>
);
expect(screen.getByText('Newer')).toBeDisabled();
});
it('disables both buttons when more and previous are false', () => {
render(
<TxsListNavigation
refreshTxs={NOOP}
nextPage={NOOP}
previousPage={NOOP}
hasMoreTxs={false}
hasPreviousPage={false}
>
<span></span>
</TxsListNavigation>
);
expect(screen.getByText('Newer')).toBeDisabled();
expect(screen.getByText('Older')).toBeDisabled();
});
}); });

View File

@ -10,7 +10,8 @@ export interface TxListNavigationProps {
loading?: boolean; loading?: boolean;
hasPreviousPage: boolean; hasPreviousPage: boolean;
hasMoreTxs: boolean; hasMoreTxs: boolean;
children: React.ReactNode; children?: React.ReactNode;
isEmpty?: boolean;
} }
/** /**
* Displays a list of transactions with filters and controls to navigate through the list. * Displays a list of transactions with filters and controls to navigate through the list.
@ -21,9 +22,8 @@ export const TxsListNavigation = ({
refreshTxs, refreshTxs,
nextPage, nextPage,
previousPage, previousPage,
hasMoreTxs,
hasPreviousPage,
children, children,
isEmpty,
loading = false, loading = false,
}: TxListNavigationProps) => { }: TxListNavigationProps) => {
return ( return (
@ -35,7 +35,6 @@ export const TxsListNavigation = ({
<Button <Button
className="mr-2" className="mr-2"
size="xs" size="xs"
disabled={!hasPreviousPage || loading}
onClick={() => { onClick={() => {
previousPage(); previousPage();
}} }}
@ -44,7 +43,7 @@ export const TxsListNavigation = ({
</Button> </Button>
<Button <Button
size="xs" size="xs"
disabled={!hasMoreTxs} disabled={isEmpty}
onClick={() => { onClick={() => {
nextPage(); nextPage();
}} }}

View File

@ -1,6 +1,7 @@
import { t } from '@vegaprotocol/i18n'; import { t } from '@vegaprotocol/i18n';
import type { components } from '../../../types/explorer'; import type { components } from '../../../types/explorer';
import { VoteIcon } from '../vote-icon/vote-icon'; import { VoteIcon } from '../vote-icon/vote-icon';
import { ExternalChainIcon } from '../links/external-explorer-link/external-chain-icon';
interface TxOrderTypeProps { interface TxOrderTypeProps {
orderType: string; orderType: string;
@ -188,6 +189,9 @@ export function getLabelForChainEvent(
} }
return t('Multisig update'); return t('Multisig update');
} else if (chainEvent.contractCall) { } else if (chainEvent.contractCall) {
if (chainEvent.contractCall.error) {
return t('Call error');
}
return t('Contract call'); return t('Contract call');
} }
return t('Chain Event'); return t('Chain Event');
@ -257,6 +261,11 @@ export const TxOrderType = ({ orderType, command }: TxOrderTypeProps) => {
data-testid="tx-type" data-testid="tx-type"
className={`text-sm rounded-md leading-tight px-2 inline-block whitespace-nowrap ${colours}`} className={`text-sm rounded-md leading-tight px-2 inline-block whitespace-nowrap ${colours}`}
> >
{command?.chainEvent && (
<ExternalChainIcon
chainId={command?.chainEvent?.contractCall?.sourceChainId}
/>
)}
{type} {type}
</div> </div>
); );

View File

@ -14,7 +14,6 @@ export const ENV = {
blockExplorerUrl: windowOrDefault('NX_BLOCK_EXPLORER'), blockExplorerUrl: windowOrDefault('NX_BLOCK_EXPLORER'),
tendermintUrl: windowOrDefault('NX_TENDERMINT_URL'), tendermintUrl: windowOrDefault('NX_TENDERMINT_URL'),
tendermintWebsocketUrl: windowOrDefault('NX_TENDERMINT_WEBSOCKET_URL'), tendermintWebsocketUrl: windowOrDefault('NX_TENDERMINT_WEBSOCKET_URL'),
ethExplorerUrl: windowOrDefault('NX_ETHERSCAN_URL'),
governanceUrl: windowOrDefault('NX_VEGA_GOVERNANCE_URL'), governanceUrl: windowOrDefault('NX_VEGA_GOVERNANCE_URL'),
vegaRepoUrl: windowOrDefault('NX_VEGA_REPO_URL'), vegaRepoUrl: windowOrDefault('NX_VEGA_REPO_URL'),
}, },

View File

@ -43,7 +43,7 @@ export const getTxsDataUrl = (params: IGetTxsDataUrl) => {
url.searchParams.append('first', count); url.searchParams.append('first', count);
url.searchParams.append('after', params.after); url.searchParams.append('after', params.after);
} else { } else {
url.searchParams.append('last', count); url.searchParams.append('first', count);
} }
// Hacky fix for param as array // Hacky fix for param as array

View File

@ -6,7 +6,7 @@ describe('getTxsDataUrl', () => {
count: 10, count: 10,
baseUrl: 'https://example.com/transactions', baseUrl: 'https://example.com/transactions',
}; };
const expectedUrl = 'https://example.com/transactions?last=10'; const expectedUrl = 'https://example.com/transactions?first=10';
expect(getTxsDataUrl(params)).toEqual(expectedUrl); expect(getTxsDataUrl(params)).toEqual(expectedUrl);
}); });
@ -41,7 +41,7 @@ describe('getTxsDataUrl', () => {
baseUrl: 'https://example.com/transactions', baseUrl: 'https://example.com/transactions',
}; };
const expectedUrl = const expectedUrl =
'https://example.com/transactions?last=10&filters[cmd.type]=Made%20Up%20Transaction&filters[tx.submitter]=1234'; 'https://example.com/transactions?first=10&filters[cmd.type]=Made%20Up%20Transaction&filters[tx.submitter]=1234';
expect(getTxsDataUrl(params)).toEqual(expectedUrl); expect(getTxsDataUrl(params)).toEqual(expectedUrl);
}); });

View File

@ -31,14 +31,14 @@ export interface IUseTxsData {
} }
export const useTxsData = ({ export const useTxsData = ({
count = 25, count = 50,
before, before,
after, after,
filters, filters,
party, party,
}: IUseTxsData) => { }: IUseTxsData) => {
const [, setSearchParams] = useSearchParams(); const [, setSearchParams] = useSearchParams();
let hasMoreTxs = true; let hasMoreTxs = false;
let txsData: BlockExplorerTransactionResult[] = []; let txsData: BlockExplorerTransactionResult[] = [];
const url = getTxsDataUrl({ const url = getTxsDataUrl({
@ -60,8 +60,8 @@ export const useTxsData = ({
} }
const nextPage = useCallback(() => { const nextPage = useCallback(() => {
const after = data?.transactions.at(-1)?.cursor || ''; const before = data?.transactions.at(-1)?.cursor || '';
const params: URLSearchParamsInit = { after }; const params: URLSearchParamsInit = { before };
if (filters) { if (filters) {
params.filters = Array.from(filters).join(','); params.filters = Array.from(filters).join(',');
} }
@ -69,8 +69,8 @@ export const useTxsData = ({
}, [filters, data, setSearchParams]); }, [filters, data, setSearchParams]);
const previousPage = useCallback(() => { const previousPage = useCallback(() => {
const before = data?.transactions[0]?.cursor || ''; const after = data?.transactions[0]?.cursor || '';
const params: URLSearchParamsInit = { before }; const params: URLSearchParamsInit = { after };
if (filters && filters.size > 0 && filters.size === 1) { if (filters && filters.size > 0 && filters.size === 1) {
params.filters = Array.from(filters)[0]; params.filters = Array.from(filters)[0];
} }

View File

@ -78,6 +78,7 @@ fragment ExplorerOracleDataSource on OracleSpec {
} }
} }
} }
sourceChainId
filters { filters {
key { key {
name name
@ -118,6 +119,7 @@ fragment ExplorerOracleDataSource on OracleSpec {
address address
requiredConfirmations requiredConfirmations
method method
sourceChainId
filters { filters {
key { key {
type type

View File

@ -67,6 +67,7 @@ fragment ExplorerOracleDataSourceSpec on ExternalDataSourceSpec {
sourceType { sourceType {
... on EthCallSpec { ... on EthCallSpec {
address address
sourceChainId
} }
... on DataSourceSpecConfiguration { ... on DataSourceSpecConfiguration {
signers { signers {

View File

@ -5,19 +5,19 @@ import * as Apollo from '@apollo/client';
const defaultOptions = {} as const; const defaultOptions = {} as const;
export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec', dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } }; export type ExplorerOracleDataConnectionFragment = { __typename?: 'OracleSpec', dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } };
export type ExplorerOracleDataSourceFragment = { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } }; export type ExplorerOracleDataSourceFragment = { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, sourceChainId: number, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } };
export type ExplorerOracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>; export type ExplorerOracleSpecsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } } | null> | null } | null }; export type ExplorerOracleSpecsQuery = { __typename?: 'Query', oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean }, edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, sourceChainId: number, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } } | null> | null } | null };
export type ExplorerOracleSpecByIdQueryVariables = Types.Exact<{ export type ExplorerOracleSpecByIdQueryVariables = Types.Exact<{
id: Types.Scalars['ID']; id: Types.Scalars['ID'];
}>; }>;
export type ExplorerOracleSpecByIdQuery = { __typename?: 'Query', oracleSpec?: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } | null }; export type ExplorerOracleSpecByIdQuery = { __typename?: 'Query', oracleSpec?: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, createdAt: any, updatedAt?: any | null, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } | { __typename?: 'EthCallSpec', abi?: Array<string> | null, args?: Array<string> | null, method: string, requiredConfirmations: number, address: string, sourceChainId: number, normalisers?: Array<{ __typename?: 'Normaliser', name: string, expression: string }> | null, trigger: { __typename?: 'EthCallTrigger', trigger: { __typename?: 'EthTimeTrigger', initial?: any | null, every?: number | null, until?: any | null } }, filters?: Array<{ __typename?: 'Filter', key: { __typename?: 'PropertyKey', name?: string | null, type: Types.PropertyKeyType, numberDecimalPlaces?: number | null }, conditions?: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator }> | null }> | null } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', matchedSpecIds?: Array<string> | null, broadcastAt: any, signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null, data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } | null };
export const ExplorerOracleDataConnectionFragmentDoc = gql` export const ExplorerOracleDataConnectionFragmentDoc = gql`
fragment ExplorerOracleDataConnection on OracleSpec { fragment ExplorerOracleDataConnection on OracleSpec {
@ -101,6 +101,7 @@ export const ExplorerOracleDataSourceFragmentDoc = gql`
} }
} }
} }
sourceChainId
filters { filters {
key { key {
name name
@ -141,6 +142,7 @@ export const ExplorerOracleDataSourceFragmentDoc = gql`
address address
requiredConfirmations requiredConfirmations
method method
sourceChainId
filters { filters {
key { key {
type type

View File

@ -9,12 +9,12 @@ export type ExplorerOracleFutureFragment = { __typename?: 'Future', dataSourceSp
export type ExplorerOracleForMarketsMarketFragment = { __typename?: 'Market', id: string, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Perpetual', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForSettlementSchedule: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Spot' } } } }; export type ExplorerOracleForMarketsMarketFragment = { __typename?: 'Market', id: string, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Perpetual', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForSettlementSchedule: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Spot' } } } };
export type ExplorerOracleDataSourceSpecFragment = { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } | { __typename?: 'EthCallSpec', address: string } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }; export type ExplorerOracleDataSourceSpecFragment = { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } | { __typename?: 'EthCallSpec', address: string, sourceChainId: number } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } };
export type ExplorerOracleFormMarketsQueryVariables = Types.Exact<{ [key: string]: never; }>; export type ExplorerOracleFormMarketsQueryVariables = Types.Exact<{ [key: string]: never; }>;
export type ExplorerOracleFormMarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Perpetual', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForSettlementSchedule: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Spot' } } } } }> } | null, oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } | { __typename?: 'EthCallSpec', address: string } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } } | null> | null } | null }; export type ExplorerOracleFormMarketsQuery = { __typename?: 'Query', marketsConnection?: { __typename?: 'MarketConnection', edges: Array<{ __typename?: 'MarketEdge', node: { __typename?: 'Market', id: string, state: Types.MarketState, tradableInstrument: { __typename?: 'TradableInstrument', instrument: { __typename?: 'Instrument', product: { __typename?: 'Future', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForTradingTermination: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Perpetual', dataSourceSpecForSettlementData: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus }, dataSourceSpecForSettlementSchedule: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus } } | { __typename?: 'Spot' } } } } }> } | null, oracleSpecsConnection?: { __typename?: 'OracleSpecsConnection', edges?: Array<{ __typename?: 'OracleSpecEdge', node: { __typename?: 'OracleSpec', dataSourceSpec: { __typename?: 'ExternalDataSourceSpec', spec: { __typename?: 'DataSourceSpec', id: string, status: Types.DataSourceSpecStatus, data: { __typename?: 'DataSourceDefinition', sourceType: { __typename?: 'DataSourceDefinitionExternal', sourceType: { __typename?: 'DataSourceSpecConfiguration', signers?: Array<{ __typename?: 'Signer', signer: { __typename?: 'ETHAddress', address?: string | null } | { __typename?: 'PubKey', key?: string | null } }> | null } | { __typename?: 'EthCallSpec', address: string, sourceChainId: number } } | { __typename?: 'DataSourceDefinitionInternal', sourceType: { __typename?: 'DataSourceSpecConfigurationTime', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null> } | { __typename?: 'DataSourceSpecConfigurationTimeTrigger', conditions: Array<{ __typename?: 'Condition', value?: string | null, operator: Types.ConditionOperator } | null>, triggers: Array<{ __typename?: 'InternalTimeTrigger', initial?: number | null, every?: number | null } | null> } } } } }, dataConnection: { __typename?: 'OracleDataConnection', edges?: Array<{ __typename?: 'OracleDataEdge', node: { __typename?: 'OracleData', externalData: { __typename?: 'ExternalData', data: { __typename?: 'Data', data?: Array<{ __typename?: 'Property', name: string, value: string }> | null } } } } | null> | null } } } | null> | null } | null };
export const ExplorerOracleFutureFragmentDoc = gql` export const ExplorerOracleFutureFragmentDoc = gql`
fragment ExplorerOracleFuture on Future { fragment ExplorerOracleFuture on Future {
@ -90,6 +90,7 @@ export const ExplorerOracleDataSourceSpecFragmentDoc = gql`
sourceType { sourceType {
... on EthCallSpec { ... on EthCallSpec {
address address
sourceChainId
} }
... on DataSourceSpecConfiguration { ... on DataSourceSpecConfiguration {
signers { signers {

View File

@ -28,7 +28,7 @@ export function isInternalSourceType(s: SourceType) {
export function getExternalType(s: SourceType) { export function getExternalType(s: SourceType) {
if (s.sourceType.__typename === 'EthCallSpec') { if (s.sourceType.__typename === 'EthCallSpec') {
return 'Ethereum Contract Call'; return 'Contract Call';
} else { } else {
return 'External Data'; return 'External Data';
} }

View File

@ -1,18 +1,24 @@
import { TableRow, TableCell, TableHeader } from '../../../components/table'; import { TableRow, TableCell, TableHeader } from '../../../components/table';
import type { SourceType } from './oracle'; import type { SourceType } from './oracle';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../components/links/eth-explorer-link/eth-explorer-link'; } from '../../../components/links/external-explorer-link/external-explorer-link';
import { getExternalChainLabel } from '../../../components/links/external-explorer-link/external-chain';
import { t } from 'i18next';
interface OracleDetailsEthSourceProps { interface OracleDetailsEthSourceProps {
sourceType: SourceType; sourceType: SourceType;
chain?: string;
} }
/** /**
* Given an Oracle that sources data from Ethereum, this component will render * Given an Oracle that sources data from Ethereum, this component will render
* a link to the smart contract and some basic details * a link to the smart contract and some basic details
*/ */
export function OracleEthSource({ sourceType }: OracleDetailsEthSourceProps) { export function OracleEthSource({
sourceType,
chain = '1',
}: OracleDetailsEthSourceProps) {
if ( if (
sourceType.__typename !== 'DataSourceDefinitionExternal' || sourceType.__typename !== 'DataSourceDefinitionExternal' ||
sourceType.sourceType.__typename !== 'EthCallSpec' sourceType.sourceType.__typename !== 'EthCallSpec'
@ -26,11 +32,20 @@ export function OracleEthSource({ sourceType }: OracleDetailsEthSourceProps) {
return null; return null;
} }
const chainLabel = getExternalChainLabel(chain);
return ( return (
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableHeader scope="row">Ethereum Contract</TableHeader> <TableHeader scope="row">
{chainLabel} {t('Contract')}
</TableHeader>
<TableCell modifier="bordered"> <TableCell modifier="bordered">
<EthExplorerLink id={address} type={EthExplorerLinkTypes.address} /> <ExternalExplorerLink
chain={chain}
id={address}
type={EthExplorerLinkTypes.address}
code={true}
/>
<span className="mx-3">&rArr;</span> <span className="mx-3">&rArr;</span>
<code>{sourceType.sourceType.method}</code> <code>{sourceType.sourceType.method}</code>
</TableCell> </TableCell>

View File

@ -1,8 +1,8 @@
import { PartyLink } from '../../../components/links'; import { PartyLink } from '../../../components/links';
import { import {
EthExplorerLink, ExternalExplorerLink,
EthExplorerLinkTypes, EthExplorerLinkTypes,
} from '../../../components/links/eth-explorer-link/eth-explorer-link'; } from '../../../components/links/external-explorer-link/external-explorer-link';
import { TableRow, TableCell, TableHeader } from '../../../components/table'; import { TableRow, TableCell, TableHeader } from '../../../components/table';
import { remove0x } from '@vegaprotocol/utils'; import { remove0x } from '@vegaprotocol/utils';
@ -37,13 +37,15 @@ export function getAddressLink(signer: Signer) {
} }
if (signer.__typename === 'ETHAddress') { if (signer.__typename === 'ETHAddress') {
return <EthExplorerLink id={address} type={EthExplorerLinkTypes.address} />; return (
<ExternalExplorerLink id={address} type={EthExplorerLinkTypes.address} />
);
} else if (signer.__typename === 'PubKey' && address.length !== 64) { } else if (signer.__typename === 'PubKey' && address.length !== 64) {
// This is a hack: some older oracles were submitted before proper checks stopped // This is a hack: some older oracles were submitted before proper checks stopped
// ETH addresses being returned as Vega addresses // ETH addresses being returned as Vega addresses
// Hacky 0x prefixing as a bonus // Hacky 0x prefixing as a bonus
return ( return (
<EthExplorerLink <ExternalExplorerLink
id={`0x${remove0x(address)}`} id={`0x${remove0x(address)}`}
type={EthExplorerLinkTypes.address} type={EthExplorerLinkTypes.address}
/> />
@ -61,7 +63,10 @@ interface OracleDetailsSignersProps {
/** /**
* Given an Oracle, this component will render either a link to Ethereum * Given an Oracle, this component will render either a link to Ethereum
* or the Vega party depending on which type is specified * or the Vega party depending on which type is specified.
*
* Note that this won't be shown for external contract calls as they do not
* have a signer in the same way.
*/ */
export function OracleSigners({ sourceType }: OracleDetailsSignersProps) { export function OracleSigners({ sourceType }: OracleDetailsSignersProps) {
if (sourceType.__typename !== 'DataSourceDefinitionExternal') { if (sourceType.__typename !== 'DataSourceDefinitionExternal') {

View File

@ -42,6 +42,11 @@ export const OracleDetails = ({
dataConnection, dataConnection,
}: OracleDetailsProps) => { }: OracleDetailsProps) => {
const sourceType = dataSource.dataSourceSpec.spec.data.sourceType; const sourceType = dataSource.dataSourceSpec.spec.data.sourceType;
const chain =
dataSource.dataSourceSpec.spec.data.sourceType.sourceType.__typename ===
'EthCallSpec'
? dataSource.dataSourceSpec.spec.data.sourceType.sourceType.sourceChainId.toString()
: undefined;
return ( return (
<div> <div>
@ -60,7 +65,7 @@ export const OracleDetails = ({
</TableCell> </TableCell>
</TableRow> </TableRow>
<OracleSigners sourceType={sourceType} /> <OracleSigners sourceType={sourceType} />
<OracleEthSource sourceType={sourceType} /> <OracleEthSource sourceType={sourceType} chain={chain} />
<OracleMarkets id={id} /> <OracleMarkets id={id} />
<TableRow modifier="bordered"> <TableRow modifier="bordered">
<TableHeader scope="row">{t('Filter')}</TableHeader> <TableHeader scope="row">{t('Filter')}</TableHeader>

View File

@ -51,9 +51,10 @@ export const TxsListFiltered = () => {
refreshTxs={refreshTxs} refreshTxs={refreshTxs}
nextPage={nextPage} nextPage={nextPage}
previousPage={previousPage} previousPage={previousPage}
hasPreviousPage={true} hasPreviousPage={hasMoreTxs}
loading={loading} loading={loading}
hasMoreTxs={hasMoreTxs} hasMoreTxs={hasMoreTxs}
isEmpty={txsData.length === 0}
> >
<TxsFilter <TxsFilter
filters={filters} filters={filters}
@ -70,7 +71,16 @@ export const TxsListFiltered = () => {
txs={txsData} txs={txsData}
loadMoreTxs={nextPage} loadMoreTxs={nextPage}
error={error} error={error}
className="mb-28 w-full min-w-[400px]" className="mb-4 w-full min-w-[400px]"
/>
<TxsListNavigation
refreshTxs={refreshTxs}
nextPage={nextPage}
previousPage={previousPage}
hasPreviousPage={hasMoreTxs}
loading={loading}
hasMoreTxs={hasMoreTxs}
isEmpty={txsData.length === 0}
/> />
</> </>
); );

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns:xodm="http://www.corel.com/coreldraw/odm/2003" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 2500 2500" style="enable-background:new 0 0 2500 2500;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
.st1{fill:#213147;}
.st2{fill:#12AAFF;}
.st3{fill:#9DCCED;}
.st4{fill:#FFFFFF;}
</style>
<g id="Layer_x0020_1">
<g id="_2405588477232">
<rect class="st0" width="2500" height="2500"></rect>
<g>
<g>
<path class="st1" d="M226,760v980c0,63,33,120,88,152l849,490c54,31,121,31,175,0l849-490c54-31,88-89,88-152V760 c0-63-33-120-88-152l-849-490c-54-31-121-31-175,0L314,608c-54,31-87,89-87,152H226z"></path>
<g>
<g>
<g>
<path class="st2" d="M1435,1440l-121,332c-3,9-3,19,0,29l208,571l241-139l-289-793C1467,1422,1442,1422,1435,1440z"></path>
</g>
<g>
<path class="st2" d="M1678,882c-7-18-32-18-39,0l-121,332c-3,9-3,19,0,29l341,935l241-139L1678,883V882z"></path>
</g>
</g>
</g>
<g>
<path class="st3" d="M1250,155c6,0,12,2,17,5l918,530c11,6,17,18,17,30v1060c0,12-7,24-17,30l-918,530c-5,3-11,5-17,5 s-12-2-17-5l-918-530c-11-6-17-18-17-30V719c0-12,7-24,17-30l918-530c5-3,11-5,17-5l0,0V155z M1250,0c-33,0-65,8-95,25L237,555 c-59,34-95,96-95,164v1060c0,68,36,130,95,164l918,530c29,17,62,25,95,25s65-8,95-25l918-530c59-34,95-96,95-164V719 c0-68-36-130-95-164L1344,25c-29-17-62-25-95-25l0,0H1250z"></path>
</g>
<polygon class="st1" points="642,2179 727,1947 897,2088 738,2234 "></polygon>
<g>
<path class="st4" d="M1172,644H939c-17,0-33,11-39,27L401,2039l241,139l550-1507c5-14-5-28-19-28L1172,644z"></path>
<path class="st4" d="M1580,644h-233c-17,0-33,11-39,27L738,2233l241,139l620-1701c5-14-5-28-19-28V644z"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none" fill-rule="evenodd"><circle cx="16" cy="16" r="16" fill="#136485"/><path fill="#FFF" d="M10.436 31.006a16.008 16.008 0 0 1-5.604-3.548l.147-.257c2.388-3.773 4.533-7.678 6.148-11.85 1.713-4.425 3.084-8.967 4.39-13.527.117-.407.256-.807.384-1.21.138.158.188.305.23.454.82 2.926 1.613 5.86 2.464 8.776 1.55 5.313 3.73 10.353 6.617 15.077.337.55.91 1.472 1.72 2.762a15.988 15.988 0 0 1-6.035 3.554 4320.193 4320.193 0 0 0-5.002-15.17l-.154-.002c-1.166 3.277-2.934 8.257-5.305 14.941zM16.075.049h-.124L16 0l.075.049z"/></g></svg>

After

Width:  |  Height:  |  Size: 622 B

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Creator: CorelDRAW 2019 (64-Bit) -->
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="100%" height="100%" version="1.1" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd"
viewBox="0 0 784.37 1277.39"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
<g id="Layer_x0020_1">
<metadata id="CorelCorpID_0Corel-Layer"/>
<g id="_1421394342400">
<g>
<polygon fill="#343434" fill-rule="nonzero" points="392.07,0 383.5,29.11 383.5,873.74 392.07,882.29 784.13,650.54 "/>
<polygon fill="#8C8C8C" fill-rule="nonzero" points="392.07,0 -0,650.54 392.07,882.29 392.07,472.33 "/>
<polygon fill="#3C3C3B" fill-rule="nonzero" points="392.07,956.52 387.24,962.41 387.24,1263.28 392.07,1277.38 784.37,724.89 "/>
<polygon fill="#8C8C8C" fill-rule="nonzero" points="392.07,1277.38 392.07,956.52 -0,724.89 "/>
<polygon fill="#141414" fill-rule="nonzero" points="392.07,882.29 784.13,650.54 392.07,472.33 "/>
<polygon fill="#393939" fill-rule="nonzero" points="0,650.54 392.07,882.29 392.07,472.33 "/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 428 428" style="enable-background:new 0 0 428 428;" xml:space="preserve">
<path style="fill:#00193C;" d="M125.8,243.7c12.3,0,24.3-4.1,34-11.6l-78-78c-18.8,24.3-14.3,59.3,10,78.1
C101.6,239.6,113.5,243.7,125.8,243.7L125.8,243.7z"/>
<path style="fill:#00193C;" d="M357.8,188c0-12.3-4.1-24.3-11.6-34l-78,78c24.3,18.8,59.2,14.3,78-10
C353.7,212.3,357.8,200.3,357.8,188z"/>
<path style="fill:#00193C;" d="M397.1,103.1l-34.5,34.5c27.8,33.3,23.4,82.9-9.9,110.7c-29.2,24.4-71.6,24.4-100.8,0L214,286.2
l-37.8-37.8c-33.3,27.8-82.9,23.4-110.7-9.9c-24.4-29.2-24.4-71.6,0-100.8L47.8,120L31,103.1C10.7,136.5,0,174.9,0,214
c0,118.2,95.8,214,214,214s214-95.8,214-214C428.1,174.9,417.3,136.5,397.1,103.1z"/>
<path style="fill:#00193C;" d="M368.8,66.3c-81.5-85.5-216.9-88.7-302.4-7.2c-2.5,2.4-4.9,4.8-7.2,7.2c-5.3,5.6-10.3,11.4-15,17.5
L214,253.7L383.8,83.8C379.2,77.7,374.1,71.9,368.8,66.3z M214,28c50,0,96.6,19.3,131.6,54.5L214,214.1L82.4,82.5
C117.4,47.3,164,28,214,28z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -28,7 +28,7 @@ export interface paths {
'/transactions': { '/transactions': {
/** /**
* List transactions * List transactions
* @description List transactions from the Vega blockchain * @description List transactions from the Vega blockchain from the newest to the oldest transactions.
*/ */
get: operations['BlockExplorer_ListTransactions']; get: operations['BlockExplorer_ListTransactions'];
}; };
@ -117,15 +117,31 @@ export interface components {
| 'EXPIRY_STRATEGY_CANCELS' | 'EXPIRY_STRATEGY_CANCELS'
| 'EXPIRY_STRATEGY_SUBMIT'; | 'EXPIRY_STRATEGY_SUBMIT';
/** /**
* @description - METHOD_NOW: Undelegate straight away, losing all rewards for the current epoch. * - SIZE_OVERRIDE_SETTING_UNSPECIFIED: Never valid
* - METHOD_AT_END_OF_EPOCH: Undelegate at the end of an epoch, retaining all rewards for the current epoch. * - SIZE_OVERRIDE_SETTING_NONE: No override, the size within the contained normal order submission will be used
* @default METHOD_UNSPECIFIED * - SIZE_OVERRIDE_SETTING_POSITION: Use the total position of the trader
* @default SIZE_OVERRIDE_SETTING_UNSPECIFIED
* @enum {string} * @enum {string}
*/ */
readonly UndelegateSubmissionMethod: readonly StopOrderSizeOverrideSetting:
| 'METHOD_UNSPECIFIED' | 'SIZE_OVERRIDE_SETTING_UNSPECIFIED'
| 'METHOD_NOW' | 'SIZE_OVERRIDE_SETTING_NONE'
| 'METHOD_AT_END_OF_EPOCH'; | 'SIZE_OVERRIDE_SETTING_POSITION';
readonly StopOrderSizeOverrideValue: {
/** Scaling percentage of the current positions size */
readonly percentage?: string;
};
/**
* - MODE_UNSPECIFIED: Never valid.
* - MODE_CROSS_MARGIN: Cross margin mode - margin is dynamically acquired and released as a position is marked to market
* - MODE_ISOLATED_MARGIN: Isolated margin mode - margin for any newly opened position volume is transferred to the margin account when the trade is executed
* @default MODE_UNSPECIFIED
* @enum {string}
*/
readonly UpdateMarginModeMode:
| 'MODE_UNSPECIFIED'
| 'MODE_CROSS_MARGIN'
| 'MODE_ISOLATED_MARGIN';
readonly blockexplorerapiv1Transaction: { readonly blockexplorerapiv1Transaction: {
/** /**
* Height of the block the transaction was found in * Height of the block the transaction was found in
@ -307,6 +323,30 @@ export interface components {
readonly stopOrdersSubmission?: readonly components['schemas']['v1StopOrdersSubmission'][]; readonly stopOrdersSubmission?: readonly components['schemas']['v1StopOrdersSubmission'][];
/** @description List of order submissions to be processed sequentially. */ /** @description List of order submissions to be processed sequentially. */
readonly submissions?: readonly components['schemas']['v1OrderSubmission'][]; readonly submissions?: readonly components['schemas']['v1OrderSubmission'][];
/** Update margin mode instruction */
readonly updateMarginMode?: readonly components['schemas']['v1UpdateMarginMode'][];
};
/**
* @description Command that allows a token holder to submit a batch governance proposal that can be voted on by any other token holders, and eventually enacted on the Vega network.
* For example this command can be used to propose a new market and a network parameter change with it.
*/
readonly v1BatchProposalSubmission: {
/** @description Rationale behind a proposal. */
readonly rationale?: components['schemas']['vegaProposalRationale'];
/** @description Arbitrary human-readable reference identifying the proposal. */
readonly reference?: string;
/** @description Proposal terms containing the type and details of the proposal, as well as time spans for voting and enactment. */
readonly terms?: components['schemas']['v1BatchProposalSubmissionTerms'];
};
/** Terms for a batch governance proposal submission */
readonly v1BatchProposalSubmissionTerms: {
/** @description List of individual changes included in the batch proposal. */
readonly changes?: readonly components['schemas']['vegaBatchProposalTermsChange'][];
/**
* Format: int64
* @description Closing timestamp in Unix time; adheres to `minClose` and `maxClose` limits.
*/
readonly closingTimestamp?: string;
}; };
/** @description A validator command sent automatically that provides information of events that have happened on foreign chains. */ /** @description A validator command sent automatically that provides information of events that have happened on foreign chains. */
readonly v1ChainEvent: { readonly v1ChainEvent: {
@ -347,6 +387,12 @@ export interface components {
readonly team?: components['schemas']['v1CreateReferralSetTeam']; readonly team?: components['schemas']['v1CreateReferralSetTeam'];
}; };
readonly v1CreateReferralSetTeam: { readonly v1CreateReferralSetTeam: {
/**
* @description List of public keys that are allowed to join the team.
* Only applicable to closed teams. Removing a party from the allow list does not remove
* the party from the team.
*/
readonly allowList?: readonly string[];
/** @description External link to an avatar for the team. */ /** @description External link to an avatar for the team. */
readonly avatarUrl?: string; readonly avatarUrl?: string;
/** @description Whether or not the team is closed to new party members. */ /** @description Whether or not the team is closed to new party members. */
@ -432,6 +478,8 @@ export interface components {
readonly applyReferralCode?: components['schemas']['v1ApplyReferralCode']; readonly applyReferralCode?: components['schemas']['v1ApplyReferralCode'];
/** @description Command to submit a batch of order instructions. */ /** @description Command to submit a batch of order instructions. */
readonly batchMarketInstructions?: components['schemas']['v1BatchMarketInstructions']; readonly batchMarketInstructions?: components['schemas']['v1BatchMarketInstructions'];
/** @description Command to submit a batch governance proposal. */
readonly batchProposalSubmission?: components['schemas']['v1BatchProposalSubmission'];
/** /**
* Format: uint64 * Format: uint64
* @description Block height which has been used to calculate the transaction proof-of-work. * @description Block height which has been used to calculate the transaction proof-of-work.
@ -449,6 +497,8 @@ export interface components {
readonly ethereumKeyRotateSubmission?: components['schemas']['v1EthereumKeyRotateSubmission']; readonly ethereumKeyRotateSubmission?: components['schemas']['v1EthereumKeyRotateSubmission'];
/** @description Command to request signatures to amend the multisig-control contract. */ /** @description Command to request signatures to amend the multisig-control contract. */
readonly issueSignatures?: components['schemas']['v1IssueSignatures']; readonly issueSignatures?: components['schemas']['v1IssueSignatures'];
/** @description Command to join a team. */
readonly joinTeam?: components['schemas']['v1JoinTeam'];
/** @description Validator command sent manually by a node operator to rotate their node's Vega keys. */ /** @description Validator command sent manually by a node operator to rotate their node's Vega keys. */
readonly keyRotateSubmission?: components['schemas']['v1KeyRotateSubmission']; readonly keyRotateSubmission?: components['schemas']['v1KeyRotateSubmission'];
/** @description Command to amend a liquidity commitment. */ /** @description Command to amend a liquidity commitment. */
@ -489,6 +539,10 @@ export interface components {
readonly transfer?: components['schemas']['commandsv1Transfer']; readonly transfer?: components['schemas']['commandsv1Transfer'];
/** @description Command to remove tokens delegated to a validator. */ /** @description Command to remove tokens delegated to a validator. */
readonly undelegateSubmission?: components['schemas']['v1UndelegateSubmission']; readonly undelegateSubmission?: components['schemas']['v1UndelegateSubmission'];
/** @description Command to update the margin mode of a party in a market. */
readonly updateMarginMode?: components['schemas']['v1UpdateMarginMode'];
/** @description Command to update a party's profile. */
readonly updatePartyProfile?: components['schemas']['v1UpdatePartyProfile'];
/** @description Command to update a referral set. */ /** @description Command to update a referral set. */
readonly updateReferralSet?: components['schemas']['v1UpdateReferralSet']; readonly updateReferralSet?: components['schemas']['v1UpdateReferralSet'];
/** @description Validator command sent automatically to signal regular participation in the network. */ /** @description Validator command sent automatically to signal regular participation in the network. */
@ -525,6 +579,11 @@ export interface components {
/** @description Node ID of the validator node that will be signed in or out of the smart contract. */ /** @description Node ID of the validator node that will be signed in or out of the smart contract. */
readonly validatorNodeId?: string; readonly validatorNodeId?: string;
}; };
/** @description Command that allows the submitter to join a team or change teams if they are already a member of a team. */
readonly v1JoinTeam: {
/** @description ID of the team to join, this is the same as the referral code used to generate the team. */
readonly id?: string;
};
/** @description A validator command sent manually that allows a node operator to indicate to the network that their node's Vega key will be rotated. */ /** @description A validator command sent manually that allows a node operator to indicate to the network that their node's Vega key will be rotated. */
readonly v1KeyRotateSubmission: { readonly v1KeyRotateSubmission: {
/** @description Hash of the node's current Vega public key. */ /** @description Hash of the node's current Vega public key. */
@ -686,6 +745,17 @@ export interface components {
readonly peggedReference?: components['schemas']['vegaPeggedReference']; readonly peggedReference?: components['schemas']['vegaPeggedReference'];
/** @description New price for the order. This field is an unsigned integer scaled to the market's decimal places. */ /** @description New price for the order. This field is an unsigned integer scaled to the market's decimal places. */
readonly price?: string; readonly price?: string;
/**
* Format: uint64
* @description New size for the order.
* Amending the size causes the size and remaining part of the order to be changed by the difference between the original and amended size.
* - Specifying a size smaller than the current size leaves the order at its current order book position.
* - Specifying a size larger than the current size removes and reinserts the order at the back of the price level.
* - Specifying a size that results in the remaining part of the order being reduced to zero cancels the order.
* This field is an unsigned integer scaled to the market's decimal places.
* If specified, size_delta must be set to 0.
*/
readonly size?: string;
/** /**
* Format: int64 * Format: int64
* @description Amend the size for the order by the delta specified: * @description Amend the size for the order by the delta specified:
@ -693,6 +763,7 @@ export interface components {
* - To increase the size from the current value, set a positive integer value * - To increase the size from the current value, set a positive integer value
* - To leave the size unchanged set a value of zero * - To leave the size unchanged set a value of zero
* This field needs to be scaled using the market's position decimal places. * This field needs to be scaled using the market's position decimal places.
* If specified, size must not be set.
*/ */
readonly sizeDelta?: string; readonly sizeDelta?: string;
/** @description New time in force for the order. */ /** @description New time in force for the order. */
@ -863,6 +934,10 @@ export interface components {
readonly orderSubmission?: components['schemas']['v1OrderSubmission']; readonly orderSubmission?: components['schemas']['v1OrderSubmission'];
/** @description Order will be submitted if the last traded price on the market breaches the given price. */ /** @description Order will be submitted if the last traded price on the market breaches the given price. */
readonly price?: string; readonly price?: string;
/** Indicates if this order is linked to an order or position to derive the order size */
readonly sizeOverrideSetting?: components['schemas']['StopOrderSizeOverrideSetting'];
/** If this order is linked to a position, provide an optional scaling factor */
readonly sizeOverrideValue?: components['schemas']['StopOrderSizeOverrideValue'];
/** @description Order will be submitted if the last traded price has moved the given percent from the highest/lowest mark price since the stop order was submitted. */ /** @description Order will be submitted if the last traded price has moved the given percent from the highest/lowest mark price since the stop order was submitted. */
readonly trailingPercentOffset?: string; readonly trailingPercentOffset?: string;
}; };
@ -909,10 +984,42 @@ export interface components {
*/ */
readonly amount?: string; readonly amount?: string;
/** @description Method of delegation. */ /** @description Method of delegation. */
readonly method?: components['schemas']['UndelegateSubmissionMethod']; readonly method?: components['schemas']['v1UndelegateSubmissionMethod'];
/** @description Node ID to undelegate stake from. */ /** @description Node ID to undelegate stake from. */
readonly nodeId?: string; readonly nodeId?: string;
}; };
/**
* @description - METHOD_NOW: Undelegate straight away, losing all rewards for the current epoch.
* - METHOD_AT_END_OF_EPOCH: Undelegate at the end of an epoch, retaining all rewards for the current epoch.
* @default METHOD_UNSPECIFIED
* @enum {string}
*/
readonly v1UndelegateSubmissionMethod:
| 'METHOD_UNSPECIFIED'
| 'METHOD_NOW'
| 'METHOD_AT_END_OF_EPOCH';
readonly v1UpdateMarginMode: {
/** Margin factor to use for margin in isolated mode. It is a multiplier that defines how much margin needs to be set aside */
readonly marginFactor?: string;
/** @description Market to change margin mode for. */
readonly marketId?: string;
/** @description Margin mode to use. */
readonly mode?: components['schemas']['UpdateMarginModeMode'];
};
/**
* @description Command to associate metadata to a public key, known as a party ID.
* Partial update is not supported, meaning previous values must be included in
* the update, otherwise they are removed.
*/
readonly v1UpdatePartyProfile: {
/** @description Alias given to the party. It must be unique network-wide. */
readonly alias?: string;
/**
* @description Freeform data to associate to the party.
* Support a maximum of 10 entries.
*/
readonly metadata?: readonly components['schemas']['vegaMetadata'][];
};
/** /**
* @description A command that allows the referrer of a referral set to update team details for a referral set. * @description A command that allows the referrer of a referral set to update team details for a referral set.
* Any field that is left unset or has a default value indicates that this field on the original referral set will be left unchanged. * Any field that is left unset or has a default value indicates that this field on the original referral set will be left unchanged.
@ -926,9 +1033,18 @@ export interface components {
readonly team?: components['schemas']['v1UpdateReferralSetTeam']; readonly team?: components['schemas']['v1UpdateReferralSetTeam'];
}; };
readonly v1UpdateReferralSetTeam: { readonly v1UpdateReferralSetTeam: {
/**
* @description List of public keys that are allowed to join the team.
* Only applicable to closed teams. Removing a party from the allow list does not remove
* the party from the team.
*/
readonly allowList?: readonly string[];
/** @description New link to an avatar for the team. */ /** @description New link to an avatar for the team. */
readonly avatarUrl?: string; readonly avatarUrl?: string;
/** @description Whether or not the team is closed to new party members. */ /**
* @description Whether or not the team is closed to new party members. When closed, only parties specified in the allow list can
* join the team.
*/
readonly closed?: boolean; readonly closed?: boolean;
/** @description New name of the team. */ /** @description New name of the team. */
readonly name?: string; readonly name?: string;
@ -1014,6 +1130,7 @@ export interface components {
* - ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY: Per asset market reward account given for return volatility * - ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY: Per asset market reward account given for return volatility
* - ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING: Per asset market reward account given to validators by their ranking * - ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING: Per asset market reward account given to validators by their ranking
* - ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD: Per asset account for pending fee referral reward payouts * - ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD: Per asset account for pending fee referral reward payouts
* - ACCOUNT_TYPE_ORDER_MARGIN: Per asset market account for party in isolated margin mode
* @default ACCOUNT_TYPE_UNSPECIFIED * @default ACCOUNT_TYPE_UNSPECIFIED
* @enum {string} * @enum {string}
*/ */
@ -1045,7 +1162,8 @@ export interface components {
| 'ACCOUNT_TYPE_REWARD_RELATIVE_RETURN' | 'ACCOUNT_TYPE_REWARD_RELATIVE_RETURN'
| 'ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY' | 'ACCOUNT_TYPE_REWARD_RETURN_VOLATILITY'
| 'ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING' | 'ACCOUNT_TYPE_REWARD_VALIDATOR_RANKING'
| 'ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD'; | 'ACCOUNT_TYPE_PENDING_FEE_REFERRAL_REWARD'
| 'ACCOUNT_TYPE_ORDER_MARGIN';
/** Vega representation of an external asset */ /** Vega representation of an external asset */
readonly vegaAssetDetails: { readonly vegaAssetDetails: {
/** @description Vega built-in asset. */ /** @description Vega built-in asset. */
@ -1071,6 +1189,42 @@ export interface components {
/** @description Minimum economically meaningful amount in the asset. */ /** @description Minimum economically meaningful amount in the asset. */
readonly quantum?: string; readonly quantum?: string;
}; };
/** Terms change for a batch governance proposal */
readonly vegaBatchProposalTermsChange: {
/** @description Proposal change to cancel a governance initiated transfe. */
readonly cancelTransfer?: components['schemas']['vegaCancelTransfer'];
/**
* Format: int64
* @description Timestamp as Unix time in seconds when proposal terms gets enacted if proposal passed the vote,
* constrained by `minEnact` and `maxEnact` network parameters.
*/
readonly enactmentTimestamp?: string;
/**
* @description Proposal change for a freeform request, which can be voted on but does not change the behaviour of the system,
* and can be used to gauge community sentiment.
*/
readonly newFreeform?: components['schemas']['vegaNewFreeform'];
/** @description Proposal change for creating new futures market. */
readonly newMarket?: components['schemas']['vegaNewMarket'];
/** @description Proposal change for creating new spot market. */
readonly newSpotMarket?: components['schemas']['vegaNewSpotMarket'];
/** @description Proposal change for a governance initiated transfer. */
readonly newTransfer?: components['schemas']['vegaNewTransfer'];
/** @description Proposal change for updating an asset. */
readonly updateAsset?: components['schemas']['vegaUpdateAsset'];
/** @description Proposal change for modifying an existing futures market. */
readonly updateMarket?: components['schemas']['vegaUpdateMarket'];
/** @description Proposal change for updating the state of a market. */
readonly updateMarketState?: components['schemas']['vegaUpdateMarketState'];
/** @description Proposal change for updating Vega network parameters. */
readonly updateNetworkParameter?: components['schemas']['vegaUpdateNetworkParameter'];
/** @description Proposal change for updating the referral program. */
readonly updateReferralProgram?: components['schemas']['vegaUpdateReferralProgram'];
/** @description Proposal change for modifying an existing spot market. */
readonly updateSpotMarket?: components['schemas']['vegaUpdateSpotMarket'];
/** @description Proposal change for updating the volume discount program. */
readonly updateVolumeDiscountProgram?: components['schemas']['vegaUpdateVolumeDiscountProgram'];
};
readonly vegaBenefitTier: { readonly vegaBenefitTier: {
/** /**
* @description Required number of epochs a party must have been in a referral set to * @description Required number of epochs a party must have been in a referral set to
@ -1125,6 +1279,44 @@ export interface components {
/** @description ID of the governance transfer proposal. */ /** @description ID of the governance transfer proposal. */
readonly transferId?: string; readonly transferId?: string;
}; };
/** @description Mark price configuration parameters. */
readonly vegaCompositePriceConfiguration: {
/** @description Cash amount, in asset decimals, used for the calculation of the mark price from the order book. */
readonly cashAmount?: string;
/** @description Which method is used for the calculation of the composite price for the market. */
readonly compositePriceType?: components['schemas']['vegaCompositePriceType'];
/** @description Additional price sources to be used for index price calculation. */
readonly dataSourcesSpec?: readonly components['schemas']['vegaDataSourceDefinition'][];
/** List of each price source and its corresponding binding */
readonly dataSourcesSpecBinding?: readonly components['schemas']['vegaSpecBindingForCompositePrice'][];
/**
* Format: uint64
* @description Decay power used for the calculation of mark price.
*/
readonly decayPower?: string;
/** @description Decay weight used for calculation of mark price. */
readonly decayWeight?: string;
/**
* @description For how long a price source is considered valid. One entry for each data source
* such that the first is for the trade based mark price, the second is for the book based price
* the third is for the first oracle, followed by more oracle data source staleness tolerance.
*/
readonly sourceStalenessTolerance?: readonly string[];
/** @description Weights for each composite price data source. */
readonly sourceWeights?: readonly string[];
};
/**
* @description - COMPOSITE_PRICE_TYPE_WEIGHTED: Composite price is calculated as a weighted average of the underlying mark prices.
* - COMPOSITE_PRICE_TYPE_MEDIAN: Composite price is calculated as a median of the underlying mark prices.
* - COMPOSITE_PRICE_TYPE_LAST_TRADE: Composite price is calculated as the last trade price.
* @default COMPOSITE_PRICE_TYPE_UNSPECIFIED
* @enum {string}
*/
readonly vegaCompositePriceType:
| 'COMPOSITE_PRICE_TYPE_UNSPECIFIED'
| 'COMPOSITE_PRICE_TYPE_WEIGHTED'
| 'COMPOSITE_PRICE_TYPE_MEDIAN'
| 'COMPOSITE_PRICE_TYPE_LAST_TRADE';
/** /**
* @description Represents the top level object that handles data sources. * @description Represents the top level object that handles data sources.
* Data source definition can be external or internal, with whatever * Data source definition can be external or internal, with whatever
@ -1197,21 +1389,17 @@ export interface components {
readonly tradingTerminationProperty?: string; readonly tradingTerminationProperty?: string;
}; };
/** /**
* Describes which property of the data source data is to be * @description Describes which properties of the data source data is to be
* used as settlement data and which to use as the trading terminated trigger * used for settlement.
*/ */
readonly vegaDataSourceSpecToPerpetualBinding: { readonly vegaDataSourceSpecToPerpetualBinding: {
/** /**
* @description Name of the property in the source data that should be used as settlement data. * @description Name of the property in the source data that should be used for settlement data.
* If it is set to "prices.BTC.value", then the perpetual market will use the value of * If it is set to "prices.BTC.value" for example, then the perpetual market will use the value of
* this property as settlement data. * this property to get settlement data.
*/ */
readonly settlementDataProperty?: string; readonly settlementDataProperty?: string;
/** /** @description Name of the property in the source data that should be used to determine the perpetual's settlement schedule. */
* @description Name of the property in the source data that should be used as settlement data.
* If it is set to "prices.BTC.value", then the perpetual market will use the value of
* this property as settlement data.
*/
readonly settlementScheduleProperty?: string; readonly settlementScheduleProperty?: string;
}; };
/** /**
@ -1493,6 +1681,11 @@ export interface components {
* Format: uint64 * Format: uint64
*/ */
readonly requiredConfirmations?: string; readonly requiredConfirmations?: string;
/**
* Format: uint64
* @description The ID of the EVM based chain which is to be used to source the oracle data.
*/
readonly sourceChainId?: string;
/** @description Conditions for determining when to call the contract method. */ /** @description Conditions for determining when to call the contract method. */
readonly trigger?: components['schemas']['vegaEthCallTrigger']; readonly trigger?: components['schemas']['vegaEthCallTrigger'];
}; };
@ -1519,6 +1712,11 @@ export interface components {
* @description Result of contract call, packed according to the ABI stored in the associated data source spec. * @description Result of contract call, packed according to the ABI stored in the associated data source spec.
*/ */
readonly result?: string; readonly result?: string;
/**
* Format: uint64
* @description Source chain for this chain event.
*/
readonly sourceChainId?: string;
/** @description ID of the data source spec that triggered this contract call. */ /** @description ID of the data source spec that triggered this contract call. */
readonly specId?: string; readonly specId?: string;
}; };
@ -1597,6 +1795,42 @@ export interface components {
readonly tolerance?: string; readonly tolerance?: string;
readonly value?: components['schemas']['vegaStateVarValue']; readonly value?: components['schemas']['vegaStateVarValue'];
}; };
/** @description Liquidation strategy used when the network holds a position resulting from position resolution. */
readonly vegaLiquidationStrategy: {
/** @description Fraction of the open position the market will try to close in a single attempt; range 0 through 1. */
readonly disposalFraction?: string;
/**
* Format: int64
* @description Interval, in seconds, at which the network will attempt to close its position.
*/
readonly disposalTimeStep?: string;
/**
* Format: uint64
* @description Size of the position that the network will try to close in a single attempt.
*/
readonly fullDisposalSize?: string;
/** @description Max fraction of the total volume of the orderbook, within liquidity bounds, that the network can use to close its position; range 0 through 1. */
readonly maxFractionConsumed?: string;
};
/** @description Market settings that describe how the liquidity fee is calculated. */
readonly vegaLiquidityFeeSettings: {
/** @description Constant liquidity fee used when using the constant fee method. */
readonly feeConstant?: string;
/** @description Method used to calculate the market's liquidity fee. */
readonly method?: components['schemas']['vegaLiquidityFeeSettingsMethod'];
};
/**
* @description - METHOD_MARGINAL_COST: Fee is the smallest value of all bids, such that liquidity providers with nominated fees less than or equal to this value still have sufficient commitment to fulfil the market's target stake.
* - METHOD_WEIGHTED_AVERAGE: Fee is the weighted average of all liquidity providers' nominated fees, weighted by their committment.
* - METHOD_CONSTANT: Fee is set by the market to a constant value irrespective of any liquidity provider's nominated fee.
* @default METHOD_UNSPECIFIED
* @enum {string}
*/
readonly vegaLiquidityFeeSettingsMethod:
| 'METHOD_UNSPECIFIED'
| 'METHOD_MARGINAL_COST'
| 'METHOD_WEIGHTED_AVERAGE'
| 'METHOD_CONSTANT';
/** LiquidityMonitoringParameters contains settings used for liquidity monitoring */ /** LiquidityMonitoringParameters contains settings used for liquidity monitoring */
readonly vegaLiquidityMonitoringParameters: { readonly vegaLiquidityMonitoringParameters: {
/** /**
@ -1674,6 +1908,13 @@ export interface components {
readonly vegaMatrixValue: { readonly vegaMatrixValue: {
readonly value?: readonly components['schemas']['vegaVectorValue'][]; readonly value?: readonly components['schemas']['vegaVectorValue'][];
}; };
/** @description Generic structure holding a key/value pair. */
readonly vegaMetadata: {
/** @description Key of the metadata. */
readonly key?: string;
/** @description Value of the metadata. */
readonly value?: string;
};
/** Represents a network parameter on Vega */ /** Represents a network parameter on Vega */
readonly vegaNetworkParameter: { readonly vegaNetworkParameter: {
/** @description Unique key of the network parameter. */ /** @description Unique key of the network parameter. */
@ -1708,6 +1949,10 @@ export interface components {
readonly instrument?: components['schemas']['vegaInstrumentConfiguration']; readonly instrument?: components['schemas']['vegaInstrumentConfiguration'];
/** @description Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume. */ /** @description Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume. */
readonly linearSlippageFactor?: string; readonly linearSlippageFactor?: string;
/** @description Liquidation strategy for this market. */
readonly liquidationStrategy?: components['schemas']['vegaLiquidationStrategy'];
/** @description Specifies how the liquidity fee for the market will be calculated. */
readonly liquidityFeeSettings?: components['schemas']['vegaLiquidityFeeSettings'];
/** @description Liquidity monitoring parameters. */ /** @description Liquidity monitoring parameters. */
readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters']; readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters'];
/** Liquidity SLA parameters */ /** Liquidity SLA parameters */
@ -1720,6 +1965,8 @@ export interface components {
* price levels over which automated liquidity provisions will be deployed. * price levels over which automated liquidity provisions will be deployed.
*/ */
readonly lpPriceRange?: string; readonly lpPriceRange?: string;
/** @description Mark price configuration. */
readonly markPriceConfiguration?: components['schemas']['vegaCompositePriceConfiguration'];
/** @description Optional new futures market metadata, tags. */ /** @description Optional new futures market metadata, tags. */
readonly metadata?: readonly string[]; readonly metadata?: readonly string[];
/** /**
@ -1750,6 +1997,8 @@ export interface components {
readonly decimalPlaces?: string; readonly decimalPlaces?: string;
/** @description New spot market instrument configuration. */ /** @description New spot market instrument configuration. */
readonly instrument?: components['schemas']['vegaInstrumentConfiguration']; readonly instrument?: components['schemas']['vegaInstrumentConfiguration'];
/** @description Specifies how the liquidity fee for the market will be calculated. */
readonly liquidityFeeSettings?: components['schemas']['vegaLiquidityFeeSettings'];
/** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */ /** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */
readonly logNormal?: components['schemas']['vegaLogNormalRiskModel']; readonly logNormal?: components['schemas']['vegaLogNormalRiskModel'];
/** @description Optional new spot market metadata, tags. */ /** @description Optional new spot market metadata, tags. */
@ -1865,6 +2114,14 @@ export interface components {
readonly dataSourceSpecForSettlementData?: components['schemas']['vegaDataSourceDefinition']; readonly dataSourceSpecForSettlementData?: components['schemas']['vegaDataSourceDefinition'];
/** @description Data source spec describing the data source for settlement schedule. */ /** @description Data source spec describing the data source for settlement schedule. */
readonly dataSourceSpecForSettlementSchedule?: components['schemas']['vegaDataSourceDefinition']; readonly dataSourceSpecForSettlementSchedule?: components['schemas']['vegaDataSourceDefinition'];
/** @description Lower bound for the funding-rate such that the funding-rate will never be lower than this value. */
readonly fundingRateLowerBound?: string;
/** @description Factor applied to funding-rates. This scales the impact that spot price deviations have on funding payments. */
readonly fundingRateScalingFactor?: string;
/** @description Upper bound for the funding-rate such that the funding-rate will never be higher than this value. */
readonly fundingRateUpperBound?: string;
/** @description Composite price configuration to drive the calculation of the index price used for funding payments. If undefined the default mark price of the market is used. */
readonly indexPriceConfiguration?: components['schemas']['vegaCompositePriceConfiguration'];
/** @description Continuously compounded interest rate used in funding rate calculation, in the range [-1, 1]. */ /** @description Continuously compounded interest rate used in funding rate calculation, in the range [-1, 1]. */
readonly interestRate?: string; readonly interestRate?: string;
/** @description Controls how much the upcoming funding payment liability contributes to party's margin, in the range [0, 1]. */ /** @description Controls how much the upcoming funding payment liability contributes to party's margin, in the range [0, 1]. */
@ -2042,6 +2299,14 @@ export interface components {
*/ */
readonly probabilityOfTrading?: number; readonly probabilityOfTrading?: number;
}; };
/**
* @description Describes which property of the data source data is to be
* used for price source.
*/
readonly vegaSpecBindingForCompositePrice: {
/** @description The property name of price. */
readonly priceSourceProperty?: string;
};
/** Spot product configuration */ /** Spot product configuration */
readonly vegaSpotProduct: { readonly vegaSpotProduct: {
/** @description Base asset ID. */ /** @description Base asset ID. */
@ -2172,6 +2437,8 @@ export interface components {
readonly code?: string; readonly code?: string;
/** @description Future. */ /** @description Future. */
readonly future?: components['schemas']['vegaUpdateFutureProduct']; readonly future?: components['schemas']['vegaUpdateFutureProduct'];
/** Instrument name */
readonly name?: string;
/** @description Perpetual. */ /** @description Perpetual. */
readonly perpetual?: components['schemas']['vegaUpdatePerpetualProduct']; readonly perpetual?: components['schemas']['vegaUpdatePerpetualProduct'];
}; };
@ -2188,6 +2455,10 @@ export interface components {
readonly instrument?: components['schemas']['vegaUpdateInstrumentConfiguration']; readonly instrument?: components['schemas']['vegaUpdateInstrumentConfiguration'];
/** @description Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume. */ /** @description Linear slippage factor is used to cap the slippage component of maintenance margin - it is applied to the slippage volume. */
readonly linearSlippageFactor?: string; readonly linearSlippageFactor?: string;
/** Liquidation strategy parameters */
readonly liquidationStrategy?: components['schemas']['vegaLiquidationStrategy'];
/** @description Specifies how the liquidity fee for the market will be calculated. */
readonly liquidityFeeSettings?: components['schemas']['vegaLiquidityFeeSettings'];
/** @description Liquidity monitoring parameters. */ /** @description Liquidity monitoring parameters. */
readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters']; readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters'];
/** Liquidity SLA parameters */ /** Liquidity SLA parameters */
@ -2200,6 +2471,8 @@ export interface components {
* price levels over which automated liquidity provisions will be deployed. * price levels over which automated liquidity provisions will be deployed.
*/ */
readonly lpPriceRange?: string; readonly lpPriceRange?: string;
/** @description Mark price configuration. */
readonly markPriceConfiguration?: components['schemas']['vegaCompositePriceConfiguration'];
/** @description Optional futures market metadata, tags. */ /** @description Optional futures market metadata, tags. */
readonly metadata?: readonly string[]; readonly metadata?: readonly string[];
/** @description Price monitoring parameters. */ /** @description Price monitoring parameters. */
@ -2238,6 +2511,14 @@ export interface components {
readonly dataSourceSpecForSettlementData?: components['schemas']['vegaDataSourceDefinition']; readonly dataSourceSpecForSettlementData?: components['schemas']['vegaDataSourceDefinition'];
/** @description Data source spec describing the data source for settlement schedule. */ /** @description Data source spec describing the data source for settlement schedule. */
readonly dataSourceSpecForSettlementSchedule?: components['schemas']['vegaDataSourceDefinition']; readonly dataSourceSpecForSettlementSchedule?: components['schemas']['vegaDataSourceDefinition'];
/** @description Lower bound for the funding-rate such that the funding-rate will never be lower than this value. */
readonly fundingRateLowerBound?: string;
/** @description Factor applied to funding-rates. This scales the impact that spot price deviations have on funding payments. */
readonly fundingRateScalingFactor?: string;
/** @description Upper bound for the funding-rate such that the funding-rate will never be higher than this value. */
readonly fundingRateUpperBound?: string;
/** @description Configuration for the index price used in funding payment calculation. */
readonly indexPriceConfiguration?: components['schemas']['vegaCompositePriceConfiguration'];
/** @description Continuously compounded interest rate used in funding rate calculation, in the range [-1, 1]. */ /** @description Continuously compounded interest rate used in funding rate calculation, in the range [-1, 1]. */
readonly interestRate?: string; readonly interestRate?: string;
/** @description Controls how much the upcoming funding payment liability contributes to party's margin, in the range [0, 1]. */ /** @description Controls how much the upcoming funding payment liability contributes to party's margin, in the range [0, 1]. */
@ -2258,6 +2539,8 @@ export interface components {
}; };
/** Configuration to update a spot market on Vega */ /** Configuration to update a spot market on Vega */
readonly vegaUpdateSpotMarketConfiguration: { readonly vegaUpdateSpotMarketConfiguration: {
/** @description Specifies how the liquidity fee for the market will be calculated. */
readonly liquidityFeeSettings?: components['schemas']['vegaLiquidityFeeSettings'];
/** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */ /** @description Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected. */
readonly logNormal?: components['schemas']['vegaLogNormalRiskModel']; readonly logNormal?: components['schemas']['vegaLogNormalRiskModel'];
/** @description Optional spot market metadata, tags. */ /** @description Optional spot market metadata, tags. */
@ -2356,19 +2639,14 @@ export interface operations {
}; };
/** /**
* List transactions * List transactions
* @description List transactions from the Vega blockchain * @description List transactions from the Vega blockchain from the newest to the oldest transactions.
*/ */
BlockExplorer_ListTransactions: { BlockExplorer_ListTransactions: {
parameters: { parameters: {
query?: { query?: {
/** /** @description Cursor to paginate the request. It can be used in conjunction with the `after` cursor. */
* @description Number of transactions to be returned from the blockchain.
* This is deprecated, use first and last instead.
*/
limit?: number;
/** @description Optional cursor to paginate the request. */
before?: string; before?: string;
/** @description Optional cursor to paginate the request. */ /** @description Cursor to paginate the request. It can be used in conjunction with the `before` cursor. */
after?: string; after?: string;
/** @description Transaction command types filter, for listing transactions with specified command types. */ /** @description Transaction command types filter, for listing transactions with specified command types. */
cmdTypes?: readonly string[]; cmdTypes?: readonly string[];
@ -2377,13 +2655,19 @@ export interface operations {
/** @description Party IDs filter, can be sender or receiver. */ /** @description Party IDs filter, can be sender or receiver. */
parties?: readonly string[]; parties?: readonly string[];
/** /**
* @description Number of transactions to be returned from the blockchain. Use in conjunction with the `after` cursor to paginate forwards. * @description Number of transactions to be returned from the blockchain.
* On its own, this will return the first `first` transactions. * Use in conjunction with the `after` cursor to paginate forwards. Paginating forwards means toward the most recent
* transactions.
* It cannot be used in conjunction with the `before` cursor.
* On its own, this will return the `first` most recent transactions.
*/ */
first?: number; first?: number;
/** /**
* @description Number of transactions to be returned from the blockchain. Use in conjunction with the `before` cursor to paginate backwards. * @description Number of transactions to be returned from the blockchain.
* On its own, this will return the last `last` transactions. * Use in conjunction with the `before` cursor to paginate backwards. Paginating forwards means toward the least recent
* transactions.
* It cannot be used in conjunction with the `after` cursor.
* On its own, this will return the `last` oldest transactions.
*/ */
last?: number; last?: number;
}; };

View File

@ -215,7 +215,7 @@ context(
}); });
// 3003-PMAN-001 // 3003-PMAN-001
it( it.skip(
'Able to submit valid new market proposal', 'Able to submit valid new market proposal',
// @ts-ignore clash between jest and cypress // @ts-ignore clash between jest and cypress
{ tags: '@smoke' }, { tags: '@smoke' },

View File

@ -31,7 +31,7 @@ import {
orderByUpgradeBlockHeight, orderByUpgradeBlockHeight,
} from '../proposals/components/proposals-list/proposals-list'; } from '../proposals/components/proposals-list/proposals-list';
import { BigNumber } from '../../lib/bignumber'; import { BigNumber } from '../../lib/bignumber';
import type { ProposalQuery } from '../proposals/proposal/__generated__/Proposal'; import { type Proposal } from '../proposals/types';
const nodesToShow = 6; const nodesToShow = 6;
@ -39,7 +39,7 @@ const HomeProposals = ({
proposals, proposals,
protocolUpgradeProposals, protocolUpgradeProposals,
}: { }: {
proposals: ProposalQuery['proposal'][]; proposals: Proposal[];
protocolUpgradeProposals: ProtocolUpgradeProposalFieldsFragment[]; protocolUpgradeProposals: ProtocolUpgradeProposalFieldsFragment[];
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();

View File

@ -1,16 +1,11 @@
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { ProposalState } from '@vegaprotocol/types'; import { ProposalState } from '@vegaprotocol/types';
import { ProposalInfoLabel } from '../proposal-info-label'; import { ProposalInfoLabel } from '../proposal-info-label';
import type { ReactNode } from 'react'; import { type ReactNode } from 'react';
import type { ProposalInfoLabelVariant } from '../proposal-info-label'; import { type ProposalInfoLabelVariant } from '../proposal-info-label';
import { type Proposal } from '../../types';
export const CurrentProposalState = ({ export const CurrentProposalState = ({ proposal }: { proposal: Proposal }) => {
proposal,
}: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
}) => {
const { t } = useTranslation(); const { t } = useTranslation();
let proposalStatus: ReactNode; let proposalStatus: ReactNode;
let variant = 'tertiary' as ProposalInfoLabelVariant; let variant = 'tertiary' as ProposalInfoLabelVariant;

View File

@ -1,272 +0,0 @@
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { render, screen } from '@testing-library/react';
import { ProposalRejectionReason, ProposalState } from '@vegaprotocol/types';
import type { NetworkParamsQuery } from '@vegaprotocol/network-parameters';
import { NetworkParamsDocument } from '@vegaprotocol/network-parameters';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { generateProposal } from '../../test-helpers/generate-proposals';
import { CurrentProposalStatus } from './current-proposal-status';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
const networkParamsQueryMock: MockedResponse<NetworkParamsQuery> = {
request: {
query: NetworkParamsDocument,
},
result: {
data: {
networkParametersConnection: {
edges: [
{
node: {
__typename: 'NetworkParameter',
key: 'governance.proposal.updateNetParam.requiredMajority',
value: '0.00000001',
},
},
{
node: {
__typename: 'NetworkParameter',
key: 'governance.proposal.updateNetParam.requiredParticipation',
value: '0.000000001',
},
},
],
},
},
},
};
const renderComponent = ({
proposal,
}: {
proposal: ProposalQuery['proposal'];
}) => {
render(
<AppStateProvider>
<MockedProvider mocks={[networkParamsQueryMock]}>
<CurrentProposalStatus proposal={proposal} />
</MockedProvider>
</AppStateProvider>
);
};
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(60 * 60 * 1000);
});
afterEach(() => {
jest.useRealTimers();
});
it('Proposal open - renders will fail state if the proposal will fail', async () => {
const failedProposal = generateProposal({
votes: {
__typename: 'ProposalVotes',
yes: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
no: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
},
});
renderComponent({ proposal: failedProposal });
expect(await screen.findByText('Currently expected to')).toBeInTheDocument();
expect(await screen.findByText('fail.')).toBeInTheDocument();
});
it('Proposal open - renders will pass state if the proposal will pass', async () => {
const proposal = generateProposal();
renderComponent({ proposal });
expect(await screen.findByText('Currently expected to')).toBeInTheDocument();
expect(await screen.findByText('pass.')).toBeInTheDocument();
});
it('Proposal enacted - renders vote passed and time since enactment', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_ENACTED,
terms: {
enactmentDatetime: new Date(0).toISOString(),
},
});
renderComponent({ proposal });
expect(await screen.findByText('Vote passed.')).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});
it('Proposal passed - renders vote passed and time since vote closed', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_PASSED,
terms: {
closingDatetime: new Date(0).toISOString(),
},
});
renderComponent({ proposal });
expect(await screen.findByText('Vote passed.')).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});
it('Proposal waiting for node vote - will pass - renders if the vote will pass and status', async () => {
const failedProposal = generateProposal({
state: ProposalState.STATE_WAITING_FOR_NODE_VOTE,
votes: {
__typename: 'ProposalVotes',
yes: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
no: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
},
});
renderComponent({ proposal: failedProposal });
expect(
await screen.findByText('Waiting for nodes to validate asset.')
).toBeInTheDocument();
expect(await screen.findByText('Currently expected to')).toBeInTheDocument();
expect(await screen.findByText('fail.')).toBeInTheDocument();
});
it('Proposal waiting for node vote - will fail - renders if the vote will pass and status', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_WAITING_FOR_NODE_VOTE,
});
renderComponent({ proposal });
expect(
await screen.findByText('Waiting for nodes to validate asset.')
).toBeInTheDocument();
expect(await screen.findByText('Currently expected to')).toBeInTheDocument();
expect(await screen.findByText('pass.')).toBeInTheDocument();
});
it('Proposal failed - renders vote failed reason and vote closed ago', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_FAILED,
errorDetails: 'foo',
terms: {
closingDatetime: new Date(0).toISOString(),
},
});
renderComponent({ proposal });
expect(
await screen.findByText('Vote closed. Failed due to:')
).toBeInTheDocument();
expect(await screen.findByText('foo')).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});
it('Proposal failed - renders rejection reason there are no error details', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_FAILED,
rejectionReason: ProposalRejectionReason.PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE,
terms: {
closingDatetime: new Date(0).toISOString(),
},
});
renderComponent({ proposal });
expect(
await screen.findByText('Vote closed. Failed due to:')
).toBeInTheDocument();
expect(
await screen.findByText('PROPOSAL_ERROR_CLOSE_TIME_TOO_LATE')
).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});
it('Proposal failed - renders unknown reason if there are no error details or rejection reason', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_FAILED,
terms: {
closingDatetime: new Date(0).toISOString(),
},
});
renderComponent({ proposal });
expect(
await screen.findByText('Vote closed. Failed due to:')
).toBeInTheDocument();
expect(await screen.findByText('unknown reason')).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});
it('Proposal failed - renders participation not met if participation is not met', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_FAILED,
terms: {
closingDatetime: new Date(0).toISOString(),
},
votes: {
__typename: 'ProposalVotes',
yes: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
no: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
},
});
renderComponent({ proposal });
expect(
await screen.findByText('Vote closed. Failed due to:')
).toBeInTheDocument();
expect(await screen.findByText('Participation not met')).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});
it('Proposal failed - renders majority not met if majority is not met', async () => {
const proposal = generateProposal({
state: ProposalState.STATE_FAILED,
terms: {
closingDatetime: new Date(0).toISOString(),
},
votes: {
__typename: 'ProposalVotes',
yes: {
__typename: 'ProposalVoteSide',
totalNumber: '0',
totalTokens: '0',
totalEquityLikeShareWeight: '0',
},
no: {
__typename: 'ProposalVoteSide',
totalNumber: '1',
totalTokens: '25242474195500835440000',
totalEquityLikeShareWeight: '0',
},
},
});
renderComponent({ proposal });
expect(
await screen.findByText('Vote closed. Failed due to:')
).toBeInTheDocument();
expect(await screen.findByText('Majority not met')).toBeInTheDocument();
expect(await screen.findByText('about 1 hour ago')).toBeInTheDocument();
});

View File

@ -1,143 +0,0 @@
import type { ReactNode } from 'react';
import { formatDistanceToNow } from 'date-fns';
import { useTranslation } from 'react-i18next';
import { ProposalState } from '@vegaprotocol/types';
import { useVoteInformation } from '../../hooks';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
export const StatusPass = ({ children }: { children: ReactNode }) => (
<span className="text-vega-green">{children}</span>
);
export const StatusFail = ({ children }: { children: ReactNode }) => (
<span className="text-danger">{children}</span>
);
const WillPass = ({
willPass,
children,
}: {
willPass: boolean;
children?: ReactNode;
}) => {
const { t } = useTranslation();
if (willPass) {
return (
<>
{children}
<StatusPass>{t('pass')}.</StatusPass>
<span className="ml-2">{t('finalOutcomeMayDiffer')}</span>
</>
);
} else {
return (
<>
{children}
<StatusFail>{t('fail')}.</StatusFail>
<span className="ml-2">{t('finalOutcomeMayDiffer')}</span>
</>
);
}
};
export const CurrentProposalStatus = ({
proposal,
}: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
}) => {
const { willPassByTokenVote, majorityMet, participationMet } =
useVoteInformation({
proposal,
});
const { t } = useTranslation();
const daysClosedAgo = formatDistanceToNow(
new Date(proposal?.terms.closingDatetime),
{ addSuffix: true }
);
const daysEnactedAgo =
proposal?.terms.enactmentDatetime &&
formatDistanceToNow(new Date(proposal.terms.enactmentDatetime), {
addSuffix: true,
});
if (proposal?.state === ProposalState.STATE_OPEN) {
return (
<WillPass willPass={willPassByTokenVote}>{t('currentlySetTo')}</WillPass>
);
}
if (
proposal?.state === ProposalState.STATE_FAILED ||
proposal?.state === ProposalState.STATE_DECLINED ||
proposal?.state === ProposalState.STATE_REJECTED
) {
if (!participationMet) {
return (
<>
<span>{t('voteFailedReason')}</span>
<StatusFail>{t('participationNotMet')}</StatusFail>
<span>&nbsp;{daysClosedAgo}</span>
</>
);
}
if (!majorityMet) {
return (
<>
<span>{t('voteFailedReason')}</span>
<StatusFail>{t('majorityNotMet')}</StatusFail>
<span>&nbsp;{daysClosedAgo}</span>
</>
);
}
return (
<>
<span>{t('voteFailedReason')}</span>
<StatusFail>
{proposal?.errorDetails ||
proposal?.rejectionReason ||
t('unknownReason')}
</StatusFail>
<span>&nbsp;{daysClosedAgo}</span>
</>
);
}
if (
proposal?.state === ProposalState.STATE_ENACTED ||
proposal?.state === ProposalState.STATE_PASSED
) {
return (
<>
<span>{t('votePassed')}</span>
<StatusPass>
&nbsp;
{proposal?.state === ProposalState.STATE_ENACTED
? t('Enacted')
: t('Passed')}
</StatusPass>
<span>
&nbsp;
{proposal?.state === ProposalState.STATE_ENACTED
? daysEnactedAgo
: daysClosedAgo}
</span>
</>
);
}
if (proposal?.state === ProposalState.STATE_WAITING_FOR_NODE_VOTE) {
return (
<WillPass willPass={willPassByTokenVote}>
<span>{t('WaitingForNodeVote')}</span>{' '}
<span>{t('currentlySetTo')}</span>
</WillPass>
);
}
return null;
};

View File

@ -1 +0,0 @@
export { CurrentProposalStatus } from './current-proposal-status';

View File

@ -6,11 +6,10 @@ import {
KeyValueTableRow, KeyValueTableRow,
RoundedWrapper, RoundedWrapper,
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals'; import { type Proposal } from '../../types';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
interface ProposalChangeTableProps { interface ProposalChangeTableProps {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
} }
export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => { export const ProposalChangeTable = ({ proposal }: ProposalChangeTableProps) => {

View File

@ -23,8 +23,8 @@ import { useFeatureFlags } from '@vegaprotocol/environment';
import { BrowserRouter } from 'react-router-dom'; import { BrowserRouter } from 'react-router-dom';
import { VoteState } from '../vote-details/use-user-vote'; import { VoteState } from '../vote-details/use-user-vote';
import { useNewTransferProposalDetails } from '@vegaprotocol/proposals'; import { useNewTransferProposalDetails } from '@vegaprotocol/proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type MockedResponse } from '@apollo/client/testing';
import type { MockedResponse } from '@apollo/client/testing'; import { type Proposal } from '../../types';
jest.mock('@vegaprotocol/proposals', () => ({ jest.mock('@vegaprotocol/proposals', () => ({
...jest.requireActual('@vegaprotocol/proposals'), ...jest.requireActual('@vegaprotocol/proposals'),
@ -36,7 +36,7 @@ jest.mock('@vegaprotocol/proposals', () => ({
})); }));
const renderComponent = ( const renderComponent = (
proposal: ProposalQuery['proposal'], proposal: Proposal,
isListItem = true, isListItem = true,
mocks: MockedResponse[] = [], mocks: MockedResponse[] = [],
voteState?: VoteState voteState?: VoteState
@ -64,6 +64,7 @@ describe('Proposal header', () => {
it('Renders New market proposal', () => { it('Renders New market proposal', () => {
useFeatureFlags.setState({ flags: { SUCCESSOR_MARKETS: true } }); useFeatureFlags.setState({ flags: { SUCCESSOR_MARKETS: true } });
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
rationale: { rationale: {
title: 'New some market', title: 'New some market',
@ -102,6 +103,7 @@ describe('Proposal header', () => {
it('Renders Update market proposal', () => { it('Renders Update market proposal', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
rationale: { rationale: {
title: 'New market id', title: 'New market id',
@ -130,6 +132,7 @@ describe('Proposal header', () => {
it('Renders New asset proposal - ERC20', () => { it('Renders New asset proposal - ERC20', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
rationale: { rationale: {
title: 'New asset: Fake currency', title: 'New asset: Fake currency',
@ -159,6 +162,7 @@ describe('Proposal header', () => {
it('Renders New asset proposal - BuiltInAsset', () => { it('Renders New asset proposal - BuiltInAsset', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
terms: { terms: {
change: { change: {
@ -184,6 +188,7 @@ describe('Proposal header', () => {
it('Renders Update network', () => { it('Renders Update network', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
rationale: { rationale: {
title: 'Network parameter', title: 'Network parameter',
@ -213,6 +218,7 @@ describe('Proposal header', () => {
it('Renders Freeform proposal - short rationale', () => { it('Renders Freeform proposal - short rationale', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
id: 'short', id: 'short',
rationale: { rationale: {
@ -234,6 +240,7 @@ describe('Proposal header', () => {
it('Renders Freeform proposal - long rationale (105 chars) - listing', () => { it('Renders Freeform proposal - long rationale (105 chars) - listing', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
id: 'long', id: 'long',
rationale: { rationale: {
@ -259,6 +266,7 @@ describe('Proposal header', () => {
// Remove once proposals have rationale and re-enable above tests // Remove once proposals have rationale and re-enable above tests
it('Renders Freeform proposal - id for title', () => { it('Renders Freeform proposal - id for title', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
id: 'freeform id', id: 'freeform id',
rationale: { rationale: {
@ -280,6 +288,7 @@ describe('Proposal header', () => {
it('Renders asset change proposal header', () => { it('Renders asset change proposal header', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
terms: { terms: {
change: { change: {
@ -297,6 +306,7 @@ describe('Proposal header', () => {
it("Renders unknown proposal if it's a different proposal type", () => { it("Renders unknown proposal if it's a different proposal type", () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
terms: { terms: {
change: { change: {
@ -313,6 +323,7 @@ describe('Proposal header', () => {
it('Renders proposal state: Enacted', () => { it('Renders proposal state: Enacted', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
state: ProposalState.STATE_ENACTED, state: ProposalState.STATE_ENACTED,
terms: { terms: {
@ -325,6 +336,7 @@ describe('Proposal header', () => {
it('Renders proposal state: Passed', () => { it('Renders proposal state: Passed', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
state: ProposalState.STATE_PASSED, state: ProposalState.STATE_PASSED,
terms: { terms: {
@ -338,6 +350,7 @@ describe('Proposal header', () => {
it('Renders proposal state: Waiting for node vote', () => { it('Renders proposal state: Waiting for node vote', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
state: ProposalState.STATE_WAITING_FOR_NODE_VOTE, state: ProposalState.STATE_WAITING_FOR_NODE_VOTE,
terms: { terms: {
@ -352,6 +365,7 @@ describe('Proposal header', () => {
it('Renders proposal state: Open', () => { it('Renders proposal state: Open', () => {
renderComponent( renderComponent(
// @ts-ignore we aren't using batch yet
generateProposal({ generateProposal({
state: ProposalState.STATE_OPEN, state: ProposalState.STATE_OPEN,
votes: { votes: {

View File

@ -8,8 +8,7 @@ import {
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
import { shorten } from '@vegaprotocol/utils'; import { shorten } from '@vegaprotocol/utils';
import { Heading, SubHeading } from '../../../../components/heading'; import { Heading, SubHeading } from '../../../../components/heading';
import type { ReactNode } from 'react'; import { type ReactNode } from 'react';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { truncateMiddle } from '../../../../lib/truncate-middle'; import { truncateMiddle } from '../../../../lib/truncate-middle';
import { CurrentProposalState } from '../current-proposal-state'; import { CurrentProposalState } from '../current-proposal-state';
import { ProposalInfoLabel } from '../proposal-info-label'; import { ProposalInfoLabel } from '../proposal-info-label';
@ -26,16 +25,17 @@ import {
} from '@vegaprotocol/environment'; } from '@vegaprotocol/environment';
import Routes from '../../../routes'; import Routes from '../../../routes';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import type { VoteState } from '../vote-details/use-user-vote'; import { type VoteState } from '../vote-details/use-user-vote';
import { VoteBreakdown } from '../vote-breakdown'; import { VoteBreakdown } from '../vote-breakdown';
import { GovernanceTransferKindMapping } from '@vegaprotocol/types'; import { GovernanceTransferKindMapping } from '@vegaprotocol/types';
import { type Proposal } from '../../types';
export const ProposalHeader = ({ export const ProposalHeader = ({
proposal, proposal,
isListItem = true, isListItem = true,
voteState, voteState,
}: { }: {
proposal: ProposalQuery['proposal']; proposal: Proposal;
isListItem?: boolean; isListItem?: boolean;
voteState?: VoteState | null; voteState?: VoteState | null;
}) => { }) => {
@ -53,7 +53,7 @@ export const ProposalHeader = ({
const titleContent = shorten(title ?? '', 100); const titleContent = shorten(title ?? '', 100);
const getAsset = (proposal: ProposalQuery['proposal']) => { const getAsset = (proposal: Proposal) => {
const terms = proposal?.terms; const terms = proposal?.terms;
if ( if (
terms?.change.__typename === 'NewMarket' && terms?.change.__typename === 'NewMarket' &&

View File

@ -266,7 +266,6 @@ export const ProposalMarketData = ({
/> />
</> </>
))} ))}
<h2 className={marketDataHeaderStyles}> <h2 className={marketDataHeaderStyles}>
{t('Liquidity monitoring parameters')} {t('Liquidity monitoring parameters')}
</h2> </h2>

View File

@ -1,5 +1,4 @@
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { import {
KeyValueTable, KeyValueTable,
KeyValueTableRow, KeyValueTableRow,
@ -14,9 +13,10 @@ import {
} from '@vegaprotocol/utils'; } from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { useAppState } from '../../../../contexts/app-state/app-state-context'; import { useAppState } from '../../../../contexts/app-state/app-state-context';
import { type Proposal } from '../../types';
interface ProposalReferralProgramDetailsProps { interface ProposalReferralProgramDetailsProps {
proposal: ProposalQuery['proposal']; proposal: Proposal | null;
} }
export const formatEndOfProgramTimestamp = (value: string) => { export const formatEndOfProgramTimestamp = (value: string) => {

View File

@ -1,6 +1,4 @@
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import { useCancelTransferProposalDetails } from '@vegaprotocol/proposals'; import { useCancelTransferProposalDetails } from '@vegaprotocol/proposals';
import { import {
KeyValueTable, KeyValueTable,
@ -8,11 +6,12 @@ import {
RoundedWrapper, RoundedWrapper,
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
import { SubHeading } from '../../../../components/heading'; import { SubHeading } from '../../../../components/heading';
import { type Proposal } from '../../types';
export const ProposalCancelTransferDetails = ({ export const ProposalCancelTransferDetails = ({
proposal, proposal,
}: { }: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const details = useCancelTransferProposalDetails(proposal?.id); const details = useCancelTransferProposalDetails(proposal?.id);

View File

@ -1,6 +1,4 @@
import { useState } from 'react'; import { useState } from 'react';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { CollapsibleToggle } from '../../../../components/collapsible-toggle'; import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
import { SubHeading } from '../../../../components/heading'; import { SubHeading } from '../../../../components/heading';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -21,11 +19,12 @@ import {
addDecimalsFormatNumberQuantum, addDecimalsFormatNumberQuantum,
formatDateWithLocalTimezone, formatDateWithLocalTimezone,
} from '@vegaprotocol/utils'; } from '@vegaprotocol/utils';
import { type Proposal } from '../../types';
export const ProposalTransferDetails = ({ export const ProposalTransferDetails = ({
proposal, proposal,
}: { }: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [show, setShow] = useState(false); const [show, setShow] = useState(false);

View File

@ -1,5 +1,4 @@
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { import {
KeyValueTable, KeyValueTable,
KeyValueTableRow, KeyValueTableRow,
@ -12,6 +11,7 @@ import {
} from '../proposal-referral-program-details'; } from '../proposal-referral-program-details';
import { formatNumberPercentage } from '@vegaprotocol/utils'; import { formatNumberPercentage } from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { type Proposal } from '../../types';
// These types are not generated as it's not known how dynamic these are // These types are not generated as it's not known how dynamic these are
type VestingBenefitTier = { type VestingBenefitTier = {
@ -43,7 +43,7 @@ export const formatVolumeDiscountFactor = (value: string) => {
}; };
interface ProposalReferralProgramDetailsProps { interface ProposalReferralProgramDetailsProps {
proposal: ProposalQuery['proposal']; proposal: Proposal | null;
} }
/** /**

View File

@ -5,13 +5,13 @@ import {
RoundedWrapper, RoundedWrapper,
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
import { Row } from '@vegaprotocol/markets'; import { Row } from '@vegaprotocol/markets';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { useState } from 'react'; import { useState } from 'react';
import { CollapsibleToggle } from '../../../../components/collapsible-toggle'; import { CollapsibleToggle } from '../../../../components/collapsible-toggle';
import { SubHeading } from '../../../../components/heading'; import { SubHeading } from '../../../../components/heading';
import { type Proposal } from '../../types';
interface ProposalUpdateMarketStateProps { interface ProposalUpdateMarketStateProps {
proposal: ProposalQuery['proposal']; proposal: Proposal | null;
} }
export const ProposalUpdateMarketState = ({ export const ProposalUpdateMarketState = ({

View File

@ -1,5 +1,4 @@
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { import {
KeyValueTable, KeyValueTable,
KeyValueTableRow, KeyValueTableRow,
@ -12,9 +11,10 @@ import {
} from '../proposal-referral-program-details'; } from '../proposal-referral-program-details';
import { formatNumberPercentage } from '@vegaprotocol/utils'; import { formatNumberPercentage } from '@vegaprotocol/utils';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { type Proposal } from '../../types';
interface ProposalReferralProgramDetailsProps { interface ProposalReferralProgramDetailsProps {
proposal: ProposalQuery['proposal']; proposal: Proposal | null;
} }
export const formatVolumeDiscountFactor = (value: string) => { export const formatVolumeDiscountFactor = (value: string) => {

View File

@ -1,13 +1,13 @@
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import { MockedProvider } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing';
import { VegaWalletProvider } from '@vegaprotocol/wallet'; import { VegaWalletProvider } from '@vegaprotocol/wallet';
import type { VegaWalletConfig } from '@vegaprotocol/wallet'; import { type VegaWalletConfig } from '@vegaprotocol/wallet';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import { generateProposal } from '../../test-helpers/generate-proposals'; import { generateProposal } from '../../test-helpers/generate-proposals';
import { Proposal } from './proposal'; import { Proposal } from './proposal';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import { ProposalState } from '@vegaprotocol/types'; import { ProposalState } from '@vegaprotocol/types';
import { mockNetworkParams } from '../../test-helpers/mocks'; import { mockNetworkParams } from '../../test-helpers/mocks';
import { type Proposal as IProposal } from '../../types';
jest.mock('@vegaprotocol/network-parameters', () => ({ jest.mock('@vegaprotocol/network-parameters', () => ({
...jest.requireActual('@vegaprotocol/network-parameters'), ...jest.requireActual('@vegaprotocol/network-parameters'),
@ -51,14 +51,14 @@ const vegaWalletConfig: VegaWalletConfig = {
chainId: 'VEGA_CHAIN_ID', chainId: 'VEGA_CHAIN_ID',
}; };
const renderComponent = (proposal: ProposalQuery['proposal']) => { const renderComponent = (proposal: IProposal) => {
render( render(
<MemoryRouter> <MemoryRouter>
<MockedProvider> <MockedProvider>
<VegaWalletProvider config={vegaWalletConfig}> <VegaWalletProvider config={vegaWalletConfig}>
<Proposal <Proposal
restData={{}} restData={{}}
proposal={proposal as ProposalQuery['proposal']} proposal={proposal}
networkParams={mockNetworkParams} networkParams={mockNetworkParams}
/> />
</VegaWalletProvider> </VegaWalletProvider>

View File

@ -12,14 +12,13 @@ import { UserVote } from '../vote-details';
import { ListAsset } from '../list-asset'; import { ListAsset } from '../list-asset';
import Routes from '../../../routes'; import Routes from '../../../routes';
import { ProposalMarketData } from '../proposal-market-data'; import { ProposalMarketData } from '../proposal-market-data';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type MarketInfo } from '@vegaprotocol/markets';
import type { MarketInfo } from '@vegaprotocol/markets'; import { type AssetQuery } from '@vegaprotocol/assets';
import type { AssetQuery } from '@vegaprotocol/assets';
import { removePaginationWrapper } from '@vegaprotocol/utils'; import { removePaginationWrapper } from '@vegaprotocol/utils';
import { ProposalState } from '@vegaprotocol/types'; import { ProposalState } from '@vegaprotocol/types';
import { ProposalMarketChanges } from '../proposal-market-changes'; import { ProposalMarketChanges } from '../proposal-market-changes';
import { ProposalUpdateMarketState } from '../proposal-update-market-state'; import { ProposalUpdateMarketState } from '../proposal-update-market-state';
import type { NetworkParamsResult } from '@vegaprotocol/network-parameters'; import { type NetworkParamsResult } from '@vegaprotocol/network-parameters';
import { useVoteSubmit } from '@vegaprotocol/proposals'; import { useVoteSubmit } from '@vegaprotocol/proposals';
import { useUserVote } from '../vote-details/use-user-vote'; import { useUserVote } from '../vote-details/use-user-vote';
import { import {
@ -28,9 +27,10 @@ import {
} from '../proposal-transfer'; } from '../proposal-transfer';
import { useFeatureFlags } from '@vegaprotocol/environment'; import { useFeatureFlags } from '@vegaprotocol/environment';
import { ProposalUpdateBenefitTiers } from '../proposal-update-benefit-tiers'; import { ProposalUpdateBenefitTiers } from '../proposal-update-benefit-tiers';
import { type Proposal as IProposal } from '../../types';
export interface ProposalProps { export interface ProposalProps {
proposal: ProposalQuery['proposal']; proposal: IProposal;
networkParams: Partial<NetworkParamsResult>; networkParams: Partial<NetworkParamsResult>;
marketData?: MarketInfo | null; marketData?: MarketInfo | null;
parentMarketData?: MarketInfo | null; parentMarketData?: MarketInfo | null;

View File

@ -1,7 +1,7 @@
import { BrowserRouter as Router } from 'react-router-dom'; import { BrowserRouter as Router } from 'react-router-dom';
import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider'; import { AppStateProvider } from '../../../../contexts/app-state/app-state-provider';
import { VegaWalletContext } from '@vegaprotocol/wallet'; import { VegaWalletContext } from '@vegaprotocol/wallet';
import type { MockedResponse } from '@apollo/client/testing'; import { type MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing'; import { MockedProvider } from '@apollo/client/testing';
import { render, screen } from '@testing-library/react'; import { render, screen } from '@testing-library/react';
import { format } from 'date-fns'; import { format } from 'date-fns';
@ -18,10 +18,10 @@ import {
lastWeek, lastWeek,
nextWeek, nextWeek,
} from '../../test-helpers/mocks'; } from '../../test-helpers/mocks';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type Proposal } from '../../types';
const renderComponent = ( const renderComponent = (
proposal: ProposalQuery['proposal'], proposal: Proposal,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
mocks: MockedResponse<any>[] = [networkParamsQueryMock] mocks: MockedResponse<any>[] = [networkParamsQueryMock]
) => ) =>

View File

@ -1,21 +1,20 @@
import { type ReactNode } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Button } from '@vegaprotocol/ui-toolkit'; import { Button } from '@vegaprotocol/ui-toolkit';
import { differenceInHours, format, formatDistanceToNowStrict } from 'date-fns'; import { differenceInHours, format, formatDistanceToNowStrict } from 'date-fns';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats'; import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
import type { ReactNode } from 'react';
import { import {
ProposalRejectionReasonMapping, ProposalRejectionReasonMapping,
ProposalState, ProposalState,
} from '@vegaprotocol/types'; } from '@vegaprotocol/types';
import Routes from '../../../routes'; import Routes from '../../../routes';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals'; import { type Proposal } from '../../types';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
export const ProposalsListItemDetails = ({ export const ProposalsListItemDetails = ({
proposal, proposal,
}: { }: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
const state = proposal?.state; const state = proposal?.state;

View File

@ -2,10 +2,10 @@ import { RoundedWrapper } from '@vegaprotocol/ui-toolkit';
import { ProposalHeader } from '../proposal-detail-header/proposal-header'; import { ProposalHeader } from '../proposal-detail-header/proposal-header';
import { ProposalsListItemDetails } from './proposals-list-item-details'; import { ProposalsListItemDetails } from './proposals-list-item-details';
import { useUserVote } from '../vote-details/use-user-vote'; import { useUserVote } from '../vote-details/use-user-vote';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type Proposal } from '../../types';
interface ProposalsListItemProps { interface ProposalsListItemProps {
proposal?: ProposalQuery['proposal'] | null; proposal?: Proposal | null;
} }
export const ProposalsListItem = ({ proposal }: ProposalsListItemProps) => { export const ProposalsListItem = ({ proposal }: ProposalsListItemProps) => {

View File

@ -17,8 +17,8 @@ import {
lastMonth, lastMonth,
nextMonth, nextMonth,
} from '../../test-helpers/mocks'; } from '../../test-helpers/mocks';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals'; import { type Proposal } from '../../types';
const openProposalClosesNextMonth = generateProposal({ const openProposalClosesNextMonth = generateProposal({
id: 'proposal1', id: 'proposal1',
@ -63,7 +63,7 @@ const closedProtocolUpgradeProposal = generateProtocolUpgradeProposal({
}); });
const renderComponent = ( const renderComponent = (
proposals: ProposalQuery['proposal'][], proposals: Proposal[],
protocolUpgradeProposals?: ProtocolUpgradeProposalFieldsFragment[] protocolUpgradeProposals?: ProtocolUpgradeProposalFieldsFragment[]
) => ( ) => (
<Router> <Router>

View File

@ -10,20 +10,20 @@ import Routes from '../../../routes';
import { Button, Toggle } from '@vegaprotocol/ui-toolkit'; import { Button, Toggle } from '@vegaprotocol/ui-toolkit';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { ExternalLink } from '@vegaprotocol/ui-toolkit'; import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import type { ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { ExternalLinks } from '@vegaprotocol/environment'; import { ExternalLinks } from '@vegaprotocol/environment';
import { type ProposalFieldsFragment } from '../../proposals/__generated__/Proposals';
import { type ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { type Proposal } from '../../types';
interface ProposalsListProps { interface ProposalsListProps {
proposals: Array<ProposalQuery['proposal']>; proposals: Proposal[];
protocolUpgradeProposals: ProtocolUpgradeProposalFieldsFragment[]; protocolUpgradeProposals: ProtocolUpgradeProposalFieldsFragment[];
lastBlockHeight?: string; lastBlockHeight?: string;
} }
interface SortedProposalsProps { interface SortedProposalsProps {
open: ProposalQuery['proposal'][]; open: Proposal[];
closed: ProposalQuery['proposal'][]; closed: Proposal[];
} }
interface SortedProtocolUpgradeProposalsProps { interface SortedProtocolUpgradeProposalsProps {
@ -31,7 +31,7 @@ interface SortedProtocolUpgradeProposalsProps {
closed: ProtocolUpgradeProposalFieldsFragment[]; closed: ProtocolUpgradeProposalFieldsFragment[];
} }
export const orderByDate = (arr: ProposalQuery['proposal'][]) => export const orderByDate = (arr: Proposal[]) =>
orderBy( orderBy(
arr, arr,
[ [
@ -91,14 +91,10 @@ export const ProposalsList = ({
); );
return { return {
open: open:
initialSorting.open.length > 0 initialSorting.open.length > 0 ? orderByDate(initialSorting.open) : [],
? orderByDate(initialSorting.open as ProposalQuery['proposal'][])
: [],
closed: closed:
initialSorting.closed.length > 0 initialSorting.closed.length > 0
? orderByDate( ? orderByDate(initialSorting.closed).reverse()
initialSorting.closed as ProposalQuery['proposal'][]
).reverse()
: [], : [],
}; };
}, [proposals]); }, [proposals]);
@ -125,9 +121,7 @@ export const ProposalsList = ({
}; };
}, [protocolUpgradeProposals, lastBlockHeight]); }, [protocolUpgradeProposals, lastBlockHeight]);
const filterPredicate = ( const filterPredicate = (p: ProposalFieldsFragment | Proposal) =>
p: ProposalFieldsFragment | ProposalQuery['proposal']
) =>
p?.id?.includes(filterString) || p?.id?.includes(filterString) ||
p?.party?.id?.toString().includes(filterString); p?.party?.id?.toString().includes(filterString);

View File

@ -12,7 +12,7 @@ import {
nextWeek, nextWeek,
lastMonth, lastMonth,
} from '../../test-helpers/mocks'; } from '../../test-helpers/mocks';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type Proposal } from '../../types';
const rejectedProposalClosesNextWeek = generateProposal({ const rejectedProposalClosesNextWeek = generateProposal({
id: 'rejected1', id: 'rejected1',
@ -35,7 +35,7 @@ const rejectedProposalClosedLastMonth = generateProposal({
}, },
}); });
const renderComponent = (proposals: ProposalQuery['proposal'][]) => ( const renderComponent = (proposals: Proposal[]) => (
<Router> <Router>
<MockedProvider mocks={[networkParamsQueryMock]}> <MockedProvider mocks={[networkParamsQueryMock]}>
<AppStateProvider> <AppStateProvider>

View File

@ -3,17 +3,17 @@ import { useTranslation } from 'react-i18next';
import { Heading } from '../../../../components/heading'; import { Heading } from '../../../../components/heading';
import { ProposalsListItem } from '../proposals-list-item'; import { ProposalsListItem } from '../proposals-list-item';
import { ProposalsListFilter } from '../proposals-list-filter'; import { ProposalsListFilter } from '../proposals-list-filter';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type Proposal } from '../../types';
interface ProposalsListProps { interface ProposalsListProps {
proposals: ProposalQuery['proposal'][]; proposals: Proposal[];
} }
export const RejectedProposalsList = ({ proposals }: ProposalsListProps) => { export const RejectedProposalsList = ({ proposals }: ProposalsListProps) => {
const { t } = useTranslation(); const { t } = useTranslation();
const [filterString, setFilterString] = useState(''); const [filterString, setFilterString] = useState('');
const filterPredicate = (p: ProposalQuery['proposal']) => const filterPredicate = (p: Proposal) =>
p?.id?.includes(filterString) || p?.id?.includes(filterString) ||
p?.party?.id?.toString().includes(filterString); p?.party?.id?.toString().includes(filterString);

View File

@ -9,8 +9,7 @@ import {
nextWeek, nextWeek,
} from '../../test-helpers/mocks'; } from '../../test-helpers/mocks';
import { CompactVotes, 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 type { MockedResponse } from '@apollo/client/testing';
import { import {
generateNoVotes, generateNoVotes,
generateProposal, generateProposal,
@ -18,7 +17,8 @@ import {
} from '../../test-helpers/generate-proposals'; } from '../../test-helpers/generate-proposals';
import { ProposalState } from '@vegaprotocol/types'; import { ProposalState } from '@vegaprotocol/types';
import { BigNumber } from '../../../../lib/bignumber'; import { BigNumber } from '../../../../lib/bignumber';
import type { AppState } from '../../../../contexts/app-state/app-state-context'; import { type AppState } from '../../../../contexts/app-state/app-state-context';
import { type Proposal } from '../../types';
const mockTotalSupply = new BigNumber(100); const mockTotalSupply = new BigNumber(100);
// Note - giving a fixedTokenValue of 1 means a ratio of 1:1 votes to tokens, making sums easier :) // Note - giving a fixedTokenValue of 1 means a ratio of 1:1 votes to tokens, making sums easier :)
@ -41,7 +41,7 @@ jest.mock('../../../../contexts/app-state/app-state-context', () => ({
})); }));
const renderComponent = ( const renderComponent = (
proposal: ProposalQuery['proposal'], proposal: Proposal,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
mocks: MockedResponse<any>[] = [networkParamsQueryMock] mocks: MockedResponse<any>[] = [networkParamsQueryMock]
) => ) =>

View File

@ -1,3 +1,4 @@
import { type ReactNode } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
@ -5,10 +6,8 @@ import { useVoteInformation } from '../../hooks';
import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit'; import { Icon, Tooltip } from '@vegaprotocol/ui-toolkit';
import { formatNumber } from '@vegaprotocol/utils'; import { formatNumber } from '@vegaprotocol/utils';
import { ProposalState } from '@vegaprotocol/types'; 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'; import { CompactNumber } from '@vegaprotocol/react-helpers';
import { type Proposal } from '../../types';
export const CompactVotes = ({ number }: { number: BigNumber }) => ( export const CompactVotes = ({ number }: { number: BigNumber }) => (
<CompactNumber <CompactNumber
@ -20,7 +19,7 @@ export const CompactVotes = ({ number }: { number: BigNumber }) => (
); );
interface VoteBreakdownProps { interface VoteBreakdownProps {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
} }
interface VoteProgressProps { interface VoteProgressProps {

View File

@ -5,14 +5,13 @@ import { ProposalState } from '@vegaprotocol/types';
import { ConnectToVega } from '../../../../components/connect-to-vega'; import { ConnectToVega } from '../../../../components/connect-to-vega';
import { VoteButtonsContainer } from './vote-buttons'; import { VoteButtonsContainer } from './vote-buttons';
import { SubHeading } from '../../../../components/heading'; import { SubHeading } from '../../../../components/heading';
import type { VoteValue } from '@vegaprotocol/types'; import { type VoteValue } from '@vegaprotocol/types';
import type { DialogProps, VegaTxState } from '@vegaprotocol/proposals'; import { type DialogProps, type VegaTxState } from '@vegaprotocol/proposals';
import type { ProposalFieldsFragment } from '../../proposals/__generated__/Proposals'; import { type VoteState } from './use-user-vote';
import type { ProposalQuery } from '../../proposal/__generated__/Proposal'; import { type Proposal } from '../../types';
import type { VoteState } from './use-user-vote';
interface UserVoteProps { interface UserVoteProps {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
minVoterBalance: string | null | undefined; minVoterBalance: string | null | undefined;
spamProtectionMinTokens: string | null | undefined; spamProtectionMinTokens: string | null | undefined;
transaction: VegaTxState | null; transaction: VegaTxState | null;

View File

@ -3,13 +3,12 @@ import {
useNetworkParams, useNetworkParams,
} from '@vegaprotocol/network-parameters'; } from '@vegaprotocol/network-parameters';
import { BigNumber } from '../../../lib/bignumber'; import { BigNumber } from '../../../lib/bignumber';
import type { ProposalFieldsFragment } from '../proposals/__generated__/Proposals'; import { type Proposal } from '../types';
import type { ProposalQuery } from '../proposal/__generated__/Proposal';
export const useProposalNetworkParams = ({ export const useProposalNetworkParams = ({
proposal, proposal,
}: { }: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal']; proposal: Proposal;
}) => { }) => {
const { params } = useNetworkParams([ const { params } = useNetworkParams([
NetworkParams.governance_proposal_updateMarket_requiredMajority, NetworkParams.governance_proposal_updateMarket_requiredMajority,

View File

@ -2,15 +2,10 @@ import { useMemo } from 'react';
import { useAppState } from '../../../contexts/app-state/app-state-context'; import { useAppState } from '../../../contexts/app-state/app-state-context';
import { BigNumber } from '../../../lib/bignumber'; import { BigNumber } from '../../../lib/bignumber';
import { useProposalNetworkParams } from './use-proposal-network-params'; import { useProposalNetworkParams } from './use-proposal-network-params';
import type { ProposalFieldsFragment } from '../proposals/__generated__/Proposals';
import type { ProposalQuery } from '../proposal/__generated__/Proposal';
import { addDecimal } from '@vegaprotocol/utils'; import { addDecimal } from '@vegaprotocol/utils';
import { type Proposal } from '../types';
export const useVoteInformation = ({ export const useVoteInformation = ({ proposal }: { proposal: Proposal }) => {
proposal,
}: {
proposal: ProposalFieldsFragment | ProposalQuery['proposal'];
}) => {
const { const {
appState: { totalSupply, decimals }, appState: { totalSupply, decimals },
} = useAppState(); } = useAppState();

View File

@ -86,228 +86,65 @@ query Proposal(
$includeUpdateReferralProgram: Boolean! $includeUpdateReferralProgram: Boolean!
) { ) {
proposal(id: $proposalId) { proposal(id: $proposalId) {
id ... on Proposal {
rationale {
title
description
}
reference
state
datetime
rejectionReason
party {
id id
} rationale {
errorDetails title
...NewMarketProductField @include(if: $includeNewMarketProductField) description
...UpdateMarketState @include(if: $includeUpdateMarketState) }
...UpdateReferralProgram @include(if: $includeUpdateReferralProgram) reference
...UpdateVolumeDiscountProgram state
terms { datetime
closingDatetime rejectionReason
enactmentDatetime party {
change { id
... on NewMarket { }
decimalPlaces errorDetails
metadata ...NewMarketProductField @include(if: $includeNewMarketProductField)
riskParameters { ...UpdateMarketState @include(if: $includeUpdateMarketState)
... on LogNormalRiskModel { ...UpdateReferralProgram @include(if: $includeUpdateReferralProgram)
riskAversionParameter ...UpdateVolumeDiscountProgram
tau terms {
params { closingDatetime
mu enactmentDatetime
r change {
sigma ... on NewMarket {
} decimalPlaces
} metadata
... on SimpleRiskModel { riskParameters {
params { ... on LogNormalRiskModel {
factorLong riskAversionParameter
factorShort tau
} params {
} mu
} r
instrument { sigma
name
code
product {
... on FutureProduct {
settlementAsset {
id
name
symbol
decimals
quantum
}
quoteName
dataSourceSpecBinding {
settlementDataProperty
tradingTerminationProperty
}
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
}
conditions {
operator
value
}
}
}
}
}
}
} }
} }
... on PerpetualProduct { ... on SimpleRiskModel {
settlementAsset { params {
id factorLong
name factorShort
symbol
decimals
quantum
} }
quoteName
} }
} }
}
priceMonitoringParameters {
triggers {
horizonSecs
probability
auctionExtensionSecs
}
}
liquidityMonitoringParameters {
targetStakeParameters {
timeWindow
scalingFactor
}
}
positionDecimalPlaces
linearSlippageFactor
}
... on UpdateMarket {
marketId
updateMarketConfiguration {
instrument { instrument {
name
code code
product { product {
... on UpdateFutureProduct { ... on FutureProduct {
quoteName settlementAsset {
dataSourceSpecForSettlementData { id
sourceType { name
... on DataSourceDefinitionInternal { symbol
sourceType { decimals
... on DataSourceSpecConfigurationTime { quantum
conditions {
operator
value
}
}
}
}
... on DataSourceDefinitionExternal {
sourceType {
... on DataSourceSpecConfiguration {
signers {
signer {
... on PubKey {
key
}
... on ETHAddress {
address
}
}
}
filters {
key {
name
type
}
conditions {
operator
value
}
}
}
}
}
}
} }
# dataSourceSpecForTradingTermination { quoteName
# 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 { dataSourceSpecBinding {
settlementDataProperty settlementDataProperty
tradingTerminationProperty tradingTerminationProperty
} }
}
... on UpdatePerpetualProduct {
quoteName
dataSourceSpecForSettlementData { dataSourceSpecForSettlementData {
sourceType { sourceType {
... on DataSourceDefinitionInternal { ... on DataSourceDefinitionInternal {
@ -348,14 +185,19 @@ query Proposal(
} }
} }
} }
dataSourceSpecBinding { }
settlementDataProperty ... on PerpetualProduct {
settlementScheduleProperty settlementAsset {
id
name
symbol
decimals
quantum
} }
quoteName
} }
} }
} }
metadata
priceMonitoringParameters { priceMonitoringParameters {
triggers { triggers {
horizonSecs horizonSecs
@ -369,71 +211,231 @@ query Proposal(
scalingFactor scalingFactor
} }
} }
riskParameters { positionDecimalPlaces
... on UpdateMarketSimpleRiskModel { linearSlippageFactor
simple { }
factorLong ... on UpdateMarket {
factorShort marketId
updateMarketConfiguration {
instrument {
code
product {
... on UpdateFutureProduct {
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
}
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 UpdatePerpetualProduct {
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
}
conditions {
operator
value
}
}
}
}
}
}
}
dataSourceSpecBinding {
settlementDataProperty
settlementScheduleProperty
}
}
} }
} }
... on UpdateMarketLogNormalRiskModel { metadata
logNormal { priceMonitoringParameters {
riskAversionParameter triggers {
tau horizonSecs
params { probability
r auctionExtensionSecs
sigma }
mu }
liquidityMonitoringParameters {
targetStakeParameters {
timeWindow
scalingFactor
}
}
riskParameters {
... on UpdateMarketSimpleRiskModel {
simple {
factorLong
factorShort
}
}
... on UpdateMarketLogNormalRiskModel {
logNormal {
riskAversionParameter
tau
params {
r
sigma
mu
}
} }
} }
} }
} }
} }
} ... on NewAsset {
... on NewAsset { name
name symbol
symbol decimals
decimals quantum
quantum source {
source { ... on BuiltinAsset {
... on BuiltinAsset { maxFaucetAmountMint
maxFaucetAmountMint }
} ... on ERC20 {
... on ERC20 { contractAddress
contractAddress lifetimeLimit
lifetimeLimit withdrawThreshold
withdrawThreshold }
} }
} }
} ... on UpdateNetworkParameter {
... on UpdateNetworkParameter { networkParameter {
networkParameter { key
key value
value }
} }
} ... on UpdateAsset {
... on UpdateAsset { quantum
quantum assetId
assetId source {
source { ... on UpdateERC20 {
... on UpdateERC20 { lifetimeLimit
lifetimeLimit withdrawThreshold
withdrawThreshold }
} }
} }
} }
} }
} votes {
votes { yes {
yes { totalTokens
totalTokens totalNumber
totalNumber totalEquityLikeShareWeight
totalEquityLikeShareWeight }
} no {
no { totalTokens
totalTokens totalNumber
totalNumber totalEquityLikeShareWeight
totalEquityLikeShareWeight }
} }
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -17,6 +17,7 @@ import {
import { useParentMarketIdQuery } from '@vegaprotocol/markets'; import { useParentMarketIdQuery } from '@vegaprotocol/markets';
import { useFeatureFlags } from '@vegaprotocol/environment'; import { useFeatureFlags } from '@vegaprotocol/environment';
import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals'; import { useSuccessorMarketProposalDetails } from '@vegaprotocol/proposals';
import { type Proposal as IProposal } from '../types';
export const ProposalContainer = () => { export const ProposalContainer = () => {
const featureFlags = useFeatureFlags((state) => state.flags); const featureFlags = useFeatureFlags((state) => state.flags);
@ -67,6 +68,8 @@ export const ProposalContainer = () => {
skip: !params.proposalId, skip: !params.proposalId,
}); });
const proposal = data?.proposal as IProposal;
const successor = useSuccessorMarketProposalDetails(params.proposalId); const successor = useSuccessorMarketProposalDetails(params.proposalId);
const isSuccessor = !!successor?.parentMarketId || !!successor.code; const isSuccessor = !!successor?.parentMarketId || !!successor.code;
@ -79,12 +82,12 @@ export const ProposalContainer = () => {
}, },
} = useFetch( } = useFetch(
`${ENV.rest}governance?proposalId=${ `${ENV.rest}governance?proposalId=${
data?.proposal?.terms.change.__typename === 'UpdateMarket' && proposal?.terms.change.__typename === 'UpdateMarket' &&
data?.proposal.terms.change.marketId proposal.terms.change.marketId
}`, }`,
undefined, undefined,
true, true,
data?.proposal?.terms.change.__typename !== 'UpdateMarket' proposal?.terms.change.__typename !== 'UpdateMarket'
); );
const { const {
@ -97,7 +100,7 @@ export const ProposalContainer = () => {
`${ENV.rest}governances?proposalState=STATE_ENACTED&proposalType=TYPE_UPDATE_MARKET`, `${ENV.rest}governances?proposalState=STATE_ENACTED&proposalType=TYPE_UPDATE_MARKET`,
undefined, undefined,
true, true,
data?.proposal?.terms.change.__typename !== 'UpdateMarket' proposal?.terms.change.__typename !== 'UpdateMarket'
); );
const { const {
@ -108,8 +111,8 @@ export const ProposalContainer = () => {
dataProvider: marketInfoProvider, dataProvider: marketInfoProvider,
skipUpdates: true, skipUpdates: true,
variables: { variables: {
marketId: data?.proposal?.id || '', marketId: proposal?.id || '',
skip: !data?.proposal?.id, skip: !proposal?.id,
}, },
}); });
@ -148,23 +151,22 @@ export const ProposalContainer = () => {
fetchPolicy: 'network-only', fetchPolicy: 'network-only',
variables: { variables: {
assetId: assetId:
(data?.proposal?.terms.change.__typename === 'NewAsset' && (proposal?.terms.change.__typename === 'NewAsset' && proposal?.id) ||
data?.proposal?.id) || (proposal?.terms.change.__typename === 'UpdateAsset' &&
(data?.proposal?.terms.change.__typename === 'UpdateAsset' && proposal.terms.change.assetId) ||
data.proposal.terms.change.assetId) ||
'', '',
}, },
skip: !['NewAsset', 'UpdateAsset'].includes( skip: !['NewAsset', 'UpdateAsset'].includes(
data?.proposal?.terms?.change?.__typename || '' proposal?.terms?.change?.__typename || ''
), ),
}); });
useEffect(() => { useEffect(() => {
if ( if (
previouslyEnactedMarketProposalsRestData && previouslyEnactedMarketProposalsRestData &&
data?.proposal?.terms.change.__typename === 'UpdateMarket' proposal?.terms.change.__typename === 'UpdateMarket'
) { ) {
const change = data?.proposal?.terms?.change as { marketId: string }; const change = proposal?.terms?.change as { marketId: string };
const filteredProposals = const filteredProposals =
// @ts-ignore rest data is not typed // @ts-ignore rest data is not typed
@ -188,8 +190,8 @@ export const ProposalContainer = () => {
}, [ }, [
previouslyEnactedMarketProposalsRestData, previouslyEnactedMarketProposalsRestData,
params.proposalId, params.proposalId,
data?.proposal?.terms.change.__typename, proposal?.terms.change.__typename,
data?.proposal?.terms.change, proposal?.terms.change,
]); ]);
useEffect(() => { useEffect(() => {
@ -242,7 +244,7 @@ export const ProposalContainer = () => {
> >
{data?.proposal ? ( {data?.proposal ? (
<Proposal <Proposal
proposal={data.proposal} proposal={proposal}
networkParams={networkParams} networkParams={networkParams}
restData={restData} restData={restData}
marketData={marketData} marketData={marketData}

View File

@ -8,6 +8,7 @@ import mergeWith from 'lodash/mergeWith';
import { type PartialDeep } from 'type-fest'; import { type PartialDeep } from 'type-fest';
import { type ProposalQuery } from '../proposal/__generated__/Proposal'; import { type ProposalQuery } from '../proposal/__generated__/Proposal';
import { type ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals'; import { type ProtocolUpgradeProposalFieldsFragment } from '@vegaprotocol/proposals';
import { type Proposal } from '../types';
export function generateProtocolUpgradeProposal( export function generateProtocolUpgradeProposal(
override: PartialDeep<ProtocolUpgradeProposalFieldsFragment> = {} override: PartialDeep<ProtocolUpgradeProposalFieldsFragment> = {}
@ -43,8 +44,8 @@ export function generateProtocolUpgradeProposal(
} }
export function generateProposal( export function generateProposal(
override: PartialDeep<ProposalQuery['proposal']> = {} override: PartialDeep<Proposal> = {}
): ProposalQuery['proposal'] { ): Proposal {
const defaultProposal: ProposalQuery['proposal'] = { const defaultProposal: ProposalQuery['proposal'] = {
__typename: 'Proposal', __typename: 'Proposal',
id: faker.datatype.uuid(), id: faker.datatype.uuid(),
@ -92,15 +93,16 @@ export function generateProposal(
}, },
}; };
return mergeWith< return mergeWith<Proposal, PartialDeep<Proposal>>(
ProposalQuery['proposal'], defaultProposal,
PartialDeep<ProposalQuery['proposal']> override,
>(defaultProposal, override, (objValue, srcValue) => { (objValue, srcValue) => {
if (!isArray(objValue)) { if (!isArray(objValue)) {
return; return;
}
return srcValue;
} }
return srcValue; );
});
} }
type Vote = Pick<Schema.Vote, '__typename' | 'value' | 'party' | 'datetime'>; type Vote = Pick<Schema.Vote, '__typename' | 'value' | 'party' | 'datetime'>;

View File

@ -0,0 +1,11 @@
import type { ProposalQuery } from './proposal/__generated__/Proposal';
/**
* The default Proposal type needs extracting from the ProposalNode union type
* as lots of fields on the original type don't exist on BatchProposal. Eventually
* we will support BatchProposal but for now we don't
*/
export type Proposal = Extract<
ProposalQuery['proposal'],
{ __typename?: 'Proposal' }
>;

View File

@ -21,10 +21,12 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags # Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
NX_ICEBERG_ORDERS=true NX_ICEBERG_ORDERS=true
NX_METAMASK_SNAPS=true NX_METAMASK_SNAPS=true
NX_REFERRALS=true NX_REFERRALS=true
# NX_DISABLE_CLOSE_POSITION=false # NX_DISABLE_CLOSE_POSITION=false
NX_TEAM_COMPETITION=true
NX_TENDERMINT_URL=https://be.vega.community NX_TENDERMINT_URL=https://be.vega.community
NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket

View File

@ -21,6 +21,7 @@ NX_ETH_WALLET_MNEMONIC="ozone access unlock valid olympic save include omit supp
# Cosmic elevator flags # Cosmic elevator flags
NX_SUCCESSOR_MARKETS=false NX_SUCCESSOR_MARKETS=false
NX_STOP_ORDERS=false NX_STOP_ORDERS=false
NX_ISOLATED_MARGIN=true
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=false NX_METAMASK_SNAPS=false

View File

@ -20,6 +20,7 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
# Cosmic elevator flags # Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=true
# NX_ICEBERG_ORDERS # NX_ICEBERG_ORDERS
# NX_PRODUCT_PERPETUALS # NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=true NX_METAMASK_SNAPS=true
@ -27,3 +28,8 @@ NX_REFERRALS=true
NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/ NX_TENDERMINT_URL=https://tm.be.devnet1.vega.xyz/
NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket NX_TENDERMINT_WEBSOCKET_URL=wss://be.devnet1.vega.xyz/websocket
NX_TEAM_COMPETITION=true
NX_CHARTING_LIBRARY_PATH=https://assets.vega.community/trading-view-bundle/v0.0.1/
NX_CHARTING_LIBRARY_HASH=PDjWaqPFndDp+LCvqbKvntWriaqNzNpZ5i9R/BULzCg=

View File

@ -21,6 +21,7 @@ NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
# Cosmic elevator flags # Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true NX_SUCCESSOR_MARKETS=true
NX_STOP_ORDERS=true NX_STOP_ORDERS=true
NX_ISOLATED_MARGIN=false
NX_ICEBERG_ORDERS=true NX_ICEBERG_ORDERS=true
NX_METAMASK_SNAPS=true NX_METAMASK_SNAPS=true
NX_REFERRALS=true NX_REFERRALS=true

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