From 53d3d5ac1cb7e5a70693ac185f3fa02a8cd417de Mon Sep 17 00:00:00 2001 From: Edd Date: Thu, 5 Jan 2023 13:10:42 +0000 Subject: [PATCH] feat(explorer): improve empty states and loading indicators (#2496) * feat(explorer): initial empty list component on block txs list * feat(explorer): messages formatting * chore(explorer): update generated types * feat(explorer): empty state for markets and assets and governance and blocks and txs * feat(explorer): use loader rather than the word loading * feat(explorer): use loader rather than the word loading in more places * feat(explorer): empty state appears below headers in more pages * feat(explorer): txs per block update * feat(explorer): update tests to match new messages * test(explorer): add test for loading and empty states for assets * test(explorer): add test for loading and empty states for more routes * test(explorer): change loading detector --- .../explorer-e2e/src/integration/blocks.cy.js | 2 +- apps/explorer/project.json | 2 +- .../blocks/blocks-infinite-list.spec.tsx | 3 +- .../blocks/blocks-infinite-list.tsx | 15 ++- .../app/components/empty-list/empty-list.tsx | 34 +++++++ .../txs/details/tx-undelegation.tsx | 2 - .../components/txs/txs-infinite-list.spec.tsx | 5 +- .../app/components/txs/txs-infinite-list.tsx | 15 ++- .../src/app/components/txs/txs-per-block.tsx | 11 ++- .../src/app/routes/assets/index.spec.tsx | 44 +++++++++ apps/explorer/src/app/routes/assets/index.tsx | 23 +++-- .../src/app/routes/blocks/id/block.tsx | 8 +- .../explorer/src/app/routes/genesis/index.tsx | 11 ++- .../src/app/routes/governance/index.tsx | 22 ++++- .../src/app/routes/markets/index.spec.tsx | 48 +++++++++ .../explorer/src/app/routes/markets/index.tsx | 32 +++--- .../src/app/routes/validators/index.tsx | 11 ++- apps/explorer/src/types/explorer.d.ts | 99 ++++++++++++++----- 18 files changed, 318 insertions(+), 69 deletions(-) create mode 100644 apps/explorer/src/app/components/empty-list/empty-list.tsx create mode 100644 apps/explorer/src/app/routes/assets/index.spec.tsx create mode 100644 apps/explorer/src/app/routes/markets/index.spec.tsx diff --git a/apps/explorer-e2e/src/integration/blocks.cy.js b/apps/explorer-e2e/src/integration/blocks.cy.js index 9b3894752..aeb680b73 100644 --- a/apps/explorer-e2e/src/integration/blocks.cy.js +++ b/apps/explorer-e2e/src/integration/blocks.cy.js @@ -116,7 +116,7 @@ context('Blocks page', { tags: '@regression' }, function () { }); function waitForBlocksResponse() { - cy.contains('Loading...').should('not.exist', { timeout: 18000 }); + cy.get('[data-testid="loader"]').should('not.exist', { timeout: 18000 }); } function validateBlocksDisplayed() { diff --git a/apps/explorer/project.json b/apps/explorer/project.json index 26f15df38..9cfabdf0f 100644 --- a/apps/explorer/project.json +++ b/apps/explorer/project.json @@ -70,7 +70,7 @@ "executor": "@nrwl/workspace:run-commands", "options": { "commands": [ - "npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.62.1/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types" + "npx openapi-typescript https://raw.githubusercontent.com/vegaprotocol/documentation/main/specs/v0.65.1/blockexplorer.openapi.json --output apps/explorer/src/types/explorer.d.ts --immutable-types" ] } }, diff --git a/apps/explorer/src/app/components/blocks/blocks-infinite-list.spec.tsx b/apps/explorer/src/app/components/blocks/blocks-infinite-list.spec.tsx index 4a425dd8a..7bad45618 100644 --- a/apps/explorer/src/app/components/blocks/blocks-infinite-list.spec.tsx +++ b/apps/explorer/src/app/components/blocks/blocks-infinite-list.spec.tsx @@ -59,7 +59,8 @@ describe('Blocks infinite list', () => { error={undefined} /> ); - expect(screen.getByText('No items')).toBeInTheDocument(); + expect(screen.getByTestId('emptylist')).toBeInTheDocument(); + expect(screen.getByText('This chain has 0 blocks')).toBeInTheDocument(); }); it('error is displayed at item level', () => { diff --git a/apps/explorer/src/app/components/blocks/blocks-infinite-list.tsx b/apps/explorer/src/app/components/blocks/blocks-infinite-list.tsx index a06c60a27..f57765c14 100644 --- a/apps/explorer/src/app/components/blocks/blocks-infinite-list.tsx +++ b/apps/explorer/src/app/components/blocks/blocks-infinite-list.tsx @@ -4,6 +4,8 @@ import InfiniteLoader from 'react-window-infinite-loader'; import { t } from '@vegaprotocol/react-helpers'; import type { BlockMeta } from '../../routes/blocks/tendermint-blockchain-response'; import { BlockData } from './block-data'; +import EmptyList from '../empty-list/empty-list'; +import { Loader } from '@vegaprotocol/ui-toolkit'; interface BlocksInfiniteListProps { hasMoreBlocks: boolean; @@ -31,7 +33,16 @@ export const BlocksInfiniteList = ({ className, }: BlocksInfiniteListProps) => { if (!blocks) { - return
No items
; + if (!areBlocksLoading) { + return ( + + ); + } else { + return ; + } } // If there are more items to be loaded then add an extra row to hold a loading indicator. @@ -50,7 +61,7 @@ export const BlocksInfiniteList = ({ if (error) { content = t(`${error}`); } else if (!isItemLoaded(index)) { - content = t('Loading...'); + content = ; } else { content = ; } diff --git a/apps/explorer/src/app/components/empty-list/empty-list.tsx b/apps/explorer/src/app/components/empty-list/empty-list.tsx new file mode 100644 index 000000000..6fd2df7dd --- /dev/null +++ b/apps/explorer/src/app/components/empty-list/empty-list.tsx @@ -0,0 +1,34 @@ +export type EmptyListProps = { + heading?: string; + label?: string; +}; + +/** + * Renders the empty state from github ticket #1463 + */ +const EmptyList = ({ heading, label }: EmptyListProps) => { + return ( +
+
+
+
+
+ +
+ {heading ? ( +

+ {heading} +

+ ) : null} + {label ? ( +

{label}

+ ) : null} +
+
+ ); +}; + +export default EmptyList; diff --git a/apps/explorer/src/app/components/txs/details/tx-undelegation.tsx b/apps/explorer/src/app/components/txs/details/tx-undelegation.tsx index f24986f5d..85ad23544 100644 --- a/apps/explorer/src/app/components/txs/details/tx-undelegation.tsx +++ b/apps/explorer/src/app/components/txs/details/tx-undelegation.tsx @@ -14,8 +14,6 @@ export const methodText: Record< METHOD_NOW: 'Immediate', METHOD_UNSPECIFIED: 'Unspecified', METHOD_AT_END_OF_EPOCH: 'End of epoch', - // This will be removed in a future release - METHOD_IN_ANGER: 'Immediate', }; interface TxDetailsUndelegateProps { diff --git a/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx b/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx index f07b5b4eb..723ef5274 100644 --- a/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx +++ b/apps/explorer/src/app/components/txs/txs-infinite-list.spec.tsx @@ -46,7 +46,10 @@ describe('Txs infinite list', () => { error={undefined} /> ); - expect(screen.getByText('No items')).toBeInTheDocument(); + expect(screen.getByTestId('emptylist')).toBeInTheDocument(); + expect( + screen.getByText('This chain has 0 transactions') + ).toBeInTheDocument(); }); it('error is displayed at item level', () => { diff --git a/apps/explorer/src/app/components/txs/txs-infinite-list.tsx b/apps/explorer/src/app/components/txs/txs-infinite-list.tsx index 8baf7c856..7f448b65b 100644 --- a/apps/explorer/src/app/components/txs/txs-infinite-list.tsx +++ b/apps/explorer/src/app/components/txs/txs-infinite-list.tsx @@ -4,6 +4,8 @@ import InfiniteLoader from 'react-window-infinite-loader'; import { t, useScreenDimensions } from '@vegaprotocol/react-helpers'; import { TxsInfiniteListItem } from './txs-infinite-list-item'; import type { BlockExplorerTransactionResult } from '../../routes/types/block-explorer-response'; +import EmptyList from '../empty-list/empty-list'; +import { Loader } from '@vegaprotocol/ui-toolkit'; interface TxsInfiniteListProps { hasMoreTxs: boolean; @@ -29,7 +31,7 @@ const Item = ({ index, style, isLoading, error }: ItemProps) => { if (error) { content = t(`Cannot fetch transaction: ${error}`); } else if (isLoading) { - content = t('Loading...'); + content = ; } else { const { hash, @@ -68,7 +70,16 @@ export const TxsInfiniteList = ({ const isStacked = ['xs', 'sm', 'md', 'lg'].includes(screenSize); if (!txs) { - return
No items
; + if (!areTxsLoading) { + return ( + + ); + } else { + return ; + } } // If there are more items to be loaded then add an extra row to hold a loading indicator. diff --git a/apps/explorer/src/app/components/txs/txs-per-block.tsx b/apps/explorer/src/app/components/txs/txs-per-block.tsx index 2107f440e..afd1e0a19 100644 --- a/apps/explorer/src/app/components/txs/txs-per-block.tsx +++ b/apps/explorer/src/app/components/txs/txs-per-block.tsx @@ -8,6 +8,8 @@ import type { BlockExplorerTransactions } from '../../routes/types/block-explore import isNumber from 'lodash/isNumber'; import { ChainResponseCode } from './details/chain-response-code/chain-reponse.code'; import { getTxsDataUrl } from '../../hooks/use-txs-data'; +import { Loader } from '@vegaprotocol/ui-toolkit'; +import EmptyList from '../empty-list/empty-list'; interface TxsPerBlockProps { blockHeight: string; @@ -84,10 +86,13 @@ export const TxsPerBlock = ({ blockHeight, txCount }: TxsPerBlockProps) => { + ) : loading ? ( + ) : ( -
- {t(`No transactions in block ${blockHeight}`)} -
+ )} ); diff --git a/apps/explorer/src/app/routes/assets/index.spec.tsx b/apps/explorer/src/app/routes/assets/index.spec.tsx new file mode 100644 index 000000000..a7bbe8ca8 --- /dev/null +++ b/apps/explorer/src/app/routes/assets/index.spec.tsx @@ -0,0 +1,44 @@ +import { MockedProvider } from '@apollo/client/testing'; +import { render } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import Assets from './index'; +import type { MockedResponse } from '@apollo/client/testing'; +import { ExplorerAssetDocument } from '../../components/links/asset-link/__generated__/Asset'; + +function renderComponent(mock: MockedResponse[]) { + return ( + + + + + + ); +} + +describe('Assets index', () => { + it('Renders loader when loading', async () => { + const mock = { + request: { + query: ExplorerAssetDocument, + }, + result: { + data: {}, + }, + }; + const res = render(renderComponent([mock])); + expect(await res.findByTestId('loader')).toBeInTheDocument(); + }); + + it('Renders EmptyList when loading completes and there are no results', async () => { + const mock = { + request: { + query: ExplorerAssetDocument, + }, + result: { + data: {}, + }, + }; + const res = render(renderComponent([mock])); + expect(await res.findByTestId('emptylist')).toBeInTheDocument(); + }); +}); diff --git a/apps/explorer/src/app/routes/assets/index.tsx b/apps/explorer/src/app/routes/assets/index.tsx index 4d83d46cf..01bcfd8a9 100644 --- a/apps/explorer/src/app/routes/assets/index.tsx +++ b/apps/explorer/src/app/routes/assets/index.tsx @@ -2,14 +2,15 @@ import { getNodes, t } from '@vegaprotocol/react-helpers'; import React from 'react'; import { RouteTitle } from '../../components/route-title'; import { SubHeading } from '../../components/sub-heading'; -import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; +import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; import { useExplorerAssetsQuery } from './__generated__/Assets'; import type { AssetsFieldsFragment } from './__generated__/Assets'; import { useScrollToLocation } from '../../hooks/scroll-to-location'; import { useDocumentTitle } from '../../hooks/use-document-title'; +import EmptyList from '../../components/empty-list/empty-list'; const Assets = () => { - const { data } = useExplorerAssetsQuery(); + const { data, loading } = useExplorerAssetsQuery(); useDocumentTitle(['Assets']); useScrollToLocation(); @@ -17,17 +18,25 @@ const Assets = () => { const assets = getNodes(data?.assetsConnection); if (!assets || assets.length === 0) { - return
; + if (!loading) { + return ( +
+ {t('Assets')} + +
+ ); + } else { + return ; + } } return (
{t('Assets')} {assets.map((a) => { - if (!a) { - return null; - } - return ( diff --git a/apps/explorer/src/app/routes/blocks/id/block.tsx b/apps/explorer/src/app/routes/blocks/id/block.tsx index 940422e29..aa102a085 100644 --- a/apps/explorer/src/app/routes/blocks/id/block.tsx +++ b/apps/explorer/src/app/routes/blocks/id/block.tsx @@ -18,6 +18,7 @@ import { RenderFetched } from '../../../components/render-fetched'; import { t, useFetch } from '@vegaprotocol/react-helpers'; import { NodeLink } from '../../../components/links'; import { useDocumentTitle } from '../../../hooks/use-document-title'; +import EmptyList from '../../../components/empty-list/empty-list'; const Block = () => { const { block } = useParams<{ block: string }>(); @@ -112,7 +113,12 @@ const Block = () => { blockHeight={blockData.result.block.header.height} txCount={blockData.result.block.data.txs.length} /> - ) : null} + ) : ( + + )} )} diff --git a/apps/explorer/src/app/routes/genesis/index.tsx b/apps/explorer/src/app/routes/genesis/index.tsx index cfafa77a6..7c5126290 100644 --- a/apps/explorer/src/app/routes/genesis/index.tsx +++ b/apps/explorer/src/app/routes/genesis/index.tsx @@ -1,6 +1,6 @@ import { t, useFetch } from '@vegaprotocol/react-helpers'; import { RouteTitle } from '../../components/route-title'; -import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; +import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; import { DATA_SOURCES } from '../../config'; import type { TendermintGenesisResponse } from './tendermint-genesis-response'; import { useDocumentTitle } from '../../hooks/use-document-title'; @@ -9,11 +9,16 @@ const Genesis = () => { useDocumentTitle(['Genesis']); const { - state: { data: genesis }, + state: { data: genesis, loading }, } = useFetch( `${DATA_SOURCES.tendermintUrl}/genesis` ); - if (!genesis?.result.genesis) return null; + if (!genesis?.result.genesis) { + if (loading) { + return ; + } + return null; + } return (
{t('Genesis')} diff --git a/apps/explorer/src/app/routes/governance/index.tsx b/apps/explorer/src/app/routes/governance/index.tsx index 05c8e57b3..ddd7b0067 100644 --- a/apps/explorer/src/app/routes/governance/index.tsx +++ b/apps/explorer/src/app/routes/governance/index.tsx @@ -2,19 +2,35 @@ import { t } from '@vegaprotocol/react-helpers'; import React from 'react'; import { RouteTitle } from '../../components/route-title'; import { SubHeading } from '../../components/sub-heading'; -import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; +import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; import { useExplorerProposalsQuery } from './__generated__/Proposals'; import { useDocumentTitle } from '../../hooks/use-document-title'; +import EmptyList from '../../components/empty-list/empty-list'; const Governance = () => { - const { data } = useExplorerProposalsQuery({ + const { data, loading } = useExplorerProposalsQuery({ errorPolicy: 'ignore', }); useDocumentTitle(); if (!data || !data.proposalsConnection || !data.proposalsConnection.edges) { - return
; + if (!loading) { + return ( +
+ + {t('Governance Proposals')} + + + +
+ ); + } else { + return ; + } } const proposals = data?.proposalsConnection?.edges.map((e) => { diff --git a/apps/explorer/src/app/routes/markets/index.spec.tsx b/apps/explorer/src/app/routes/markets/index.spec.tsx new file mode 100644 index 000000000..7786261a6 --- /dev/null +++ b/apps/explorer/src/app/routes/markets/index.spec.tsx @@ -0,0 +1,48 @@ +import { MockedProvider } from '@apollo/client/testing'; +import { render } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import Markets from './index'; +import type { MockedResponse } from '@apollo/client/testing'; +import { ExplorerMarketsDocument } from './__generated__/Markets'; + +function renderComponent(mock: MockedResponse[]) { + return ( + + + + + + ); +} + +describe('Markets index', () => { + it('Renders loader when loading', async () => { + const mock = { + request: { + query: ExplorerMarketsDocument, + }, + result: { + data: { + marketsConnection: [], + }, + }, + }; + const res = render(renderComponent([mock])); + expect(await res.findByTestId('loader')).toBeInTheDocument(); + }); + + it('Renders EmptyList when loading completes and there are no results', async () => { + const mock = { + request: { + query: ExplorerMarketsDocument, + }, + result: { + data: { + marketsConnection: [], + }, + }, + }; + const res = render(renderComponent([mock])); + expect(await res.findByTestId('emptylist')).toBeInTheDocument(); + }); +}); diff --git a/apps/explorer/src/app/routes/markets/index.tsx b/apps/explorer/src/app/routes/markets/index.tsx index 22ad04915..3c87feb68 100644 --- a/apps/explorer/src/app/routes/markets/index.tsx +++ b/apps/explorer/src/app/routes/markets/index.tsx @@ -1,14 +1,15 @@ import React from 'react'; -import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; +import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; import { RouteTitle } from '../../components/route-title'; import { SubHeading } from '../../components/sub-heading'; import { t } from '@vegaprotocol/react-helpers'; import { useExplorerMarketsQuery } from './__generated__/Markets'; import { useScrollToLocation } from '../../hooks/scroll-to-location'; import { useDocumentTitle } from '../../hooks/use-document-title'; +import EmptyList from '../../components/empty-list/empty-list'; const Markets = () => { - const { data } = useExplorerMarketsQuery(); + const { data, loading } = useExplorerMarketsQuery(); useScrollToLocation(); useDocumentTitle(['Markets']); @@ -19,16 +20,23 @@ const Markets = () => {
{t('Markets')} - {m - ? m.map((e) => ( - - - {e.node.tradableInstrument.instrument.name} - - - - )) - : null} + {m ? ( + m.map((e) => ( + + + {e.node.tradableInstrument.instrument.name} + + + + )) + ) : loading ? ( + + ) : ( + + )}
); }; diff --git a/apps/explorer/src/app/routes/validators/index.tsx b/apps/explorer/src/app/routes/validators/index.tsx index fc121ffa2..84b8195eb 100644 --- a/apps/explorer/src/app/routes/validators/index.tsx +++ b/apps/explorer/src/app/routes/validators/index.tsx @@ -1,8 +1,7 @@ import { t } from '@vegaprotocol/react-helpers'; -import React from 'react'; import { RouteTitle } from '../../components/route-title'; import { SubHeading } from '../../components/sub-heading'; -import { SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; +import { Loader, SyntaxHighlighter } from '@vegaprotocol/ui-toolkit'; import { DATA_SOURCES } from '../../config'; import { useFetch } from '@vegaprotocol/react-helpers'; import type { TendermintValidatorsResponse } from './tendermint-validator-response'; @@ -28,7 +27,9 @@ const Validators = () => { {t('Vega data')} - ) : null} + ) : ( + + )} {validators ? ( <> @@ -36,7 +37,9 @@ const Validators = () => { - ) : null} + ) : ( + + )}
); }; diff --git a/apps/explorer/src/types/explorer.d.ts b/apps/explorer/src/types/explorer.d.ts index 324e152c7..5ef6211ad 100644 --- a/apps/explorer/src/types/explorer.d.ts +++ b/apps/explorer/src/types/explorer.d.ts @@ -14,9 +14,17 @@ type OneOf = T extends [infer Only] : T extends [infer A, infer B, ...infer Rest] ? OneOf<[XOR, ...Rest]> : never; -/* typescript-eslint:enable no-explicit-any */ +/* eslint-enable @typescript-eslint/no-explicit-any */ export interface paths { + '/info': { + /** + * Info + * @description Retrieves information about the block explorer. + * Response contains a semver formatted version of the data node and the commit hash, from which the block explorer was built, + */ + get: operations['BlockExplorer_Info']; + }; '/transactions': { /** * List transactions @@ -100,8 +108,7 @@ export interface components { readonly UndelegateSubmissionMethod: | 'METHOD_UNSPECIFIED' | 'METHOD_NOW' - | 'METHOD_AT_END_OF_EPOCH' - | 'METHOD_IN_ANGER'; + | 'METHOD_AT_END_OF_EPOCH'; readonly blockexplorerapiv1Transaction: { /** * The height of the block the transaction was found in @@ -117,6 +124,11 @@ export interface components { readonly command?: components['schemas']['v1InputData']; /** The cursor for this transaction (in the page, used for paginated results) */ readonly cursor?: string; + /** + * An optional error happening when processing / checking the transaction + * Should be set if error code is not 0 + */ + readonly error?: string; /** The hash of the transaction */ readonly hash?: string; /** @@ -124,6 +136,8 @@ export interface components { * Format: int64 */ readonly index?: number; + /** Submitter's signature of transaction */ + readonly signature?: components['schemas']['v1Signature']; /** The submitter of the transaction (Vega public key) */ readonly submitter?: string; /** The type of transaction */ @@ -159,7 +173,7 @@ export interface components { readonly '@type'?: string; [key: string]: unknown | undefined; }; - /** Used announce a node as a new potential validator */ + /** Used announce a node as a new pending validator */ readonly v1AnnounceNode: { /** AvatarURL of the validator */ readonly avatarUrl?: string; @@ -192,7 +206,7 @@ export interface components { * Format: int64 */ readonly vegaPubKeyIndex?: number; - /** Signature from the validator made using the vega wallet */ + /** Signature from the validator made using the Vega wallet */ readonly vegaSignature?: components['schemas']['v1Signature']; }; /** @@ -287,6 +301,12 @@ export interface components { /** The transaction corresponding to the hash */ readonly transaction?: components['schemas']['blockexplorerapiv1Transaction']; }; + readonly v1InfoResponse: { + /** The commit hash from which the data-node was built */ + readonly commitHash?: string; + /** A semver formatted version of the data node */ + readonly version?: string; + }; readonly v1InputData: { readonly announceNode?: components['schemas']['v1AnnounceNode']; readonly batchMarketInstructions?: components['schemas']['v1BatchMarketInstructions']; @@ -351,7 +371,7 @@ export interface components { /** The ID of the node that will be signed in or out of the smartcontract */ readonly validatorNodeId?: string; }; - /** A transaction to allow validator to rotate their vega keys */ + /** A transaction to allow validator to rotate their Vega keys */ readonly v1KeyRotateSubmission: { /** Hash of currently used public key */ readonly currentPubKeyHash?: string; @@ -414,7 +434,7 @@ export interface components { readonly sig?: string; }; /** - * The kind of the signature created by a node, for example, allow-listing a new asset, withdrawal etc + * The kind of signature created by a node, for example, allow-listing a new asset, withdrawal etc * @description - NODE_SIGNATURE_KIND_UNSPECIFIED: Represents an unspecified or missing value from the input * - NODE_SIGNATURE_KIND_ASSET_NEW: Represents a signature for a new asset allow-listing * - NODE_SIGNATURE_KIND_ASSET_WITHDRAWAL: Represents a signature for an asset withdrawal @@ -432,7 +452,7 @@ export interface components { | 'NODE_SIGNATURE_KIND_ERC20_MULTISIG_SIGNER_REMOVED' | 'NODE_SIGNATURE_KIND_ASSET_UPDATE'; /** - * Used when a node votes for validating a given resource exists or is valid, + * Used when a node votes for validating that a given resource exists or is valid, * for example, an ERC20 deposit is valid and exists on ethereum */ readonly v1NodeVote: { @@ -553,6 +573,12 @@ export interface components { readonly v1PropertyKey: { /** @description name is the name of the property. */ readonly name?: string; + /** + * An optional decimal place to be be applied on the provided value + * valid only for PropertyType of type DECIMAL and INTEGER + * Format: uint64 + */ + readonly numberDecimalPlaces?: string; /** @description type is the type of the property. */ readonly type?: components['schemas']['v1PropertyKeyType']; }; @@ -596,7 +622,7 @@ export interface components { * Format: uint64 */ readonly upgradeBlockHeight?: string; - /** the release tag for the vega binary */ + /** the release tag for the Vega binary */ readonly vegaReleaseTag?: string; }; /** @@ -659,8 +685,8 @@ export interface components { readonly nodeId?: string; }; /** - * A message from a validator signaling they are still online and validating blocks - * or ready to validate block when they are till a potential validator + * A message from a validator signalling they are still online and validating blocks + * or ready to validate blocks when they are still a pending validator */ readonly v1ValidatorHeartbeat: { /** Signature from the validator made using the ethereum wallet */ @@ -1061,11 +1087,6 @@ export interface components { readonly quoteName?: string; /** Asset ID for the product's settlement asset */ readonly settlementAsset?: string; - /** - * The number of decimal places implied by the settlement data (such as price) emitted by the settlement data source - * Format: int64 - */ - readonly settlementDataDecimals?: number; }; /** Instrument configuration */ readonly vegaInstrumentConfiguration: { @@ -1111,17 +1132,17 @@ export interface components { /** Risk model parameters for log normal */ readonly vegaLogNormalModelParams: { /** - * Mu param + * Mu parameter, annualised growth rate of the underlying asset * Format: double */ readonly mu?: number; /** - * R param + * R parameter, annualised growth rate of the risk-free asset, used for discounting of future cash flows, can be any real number * Format: double */ readonly r?: number; /** - * Sigma param + * Sigma parameter, annualised volatility of the underlying asset, must be a strictly non-negative real number * Format: double */ readonly sigma?: number; @@ -1136,7 +1157,7 @@ export interface components { */ readonly riskAversionParameter?: number; /** - * Tau + * Tau parameter of the risk model, projection horizon measured as a year fraction used in the expected shortfall calculation to obtain the maintenance margin, must be a strictly non-negative real number * Format: double */ readonly tau?: number; @@ -1180,6 +1201,11 @@ export interface components { readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters']; /** Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected */ readonly logNormal?: components['schemas']['vegaLogNormalRiskModel']; + /** + * Percentage move up and down from the mid price which specifies the range of + * price levels over which automated liquidity provision orders will be deployed + */ + readonly lpPriceRange?: string; /** Optional new market meta data, tags */ readonly metadata?: readonly string[]; /** @@ -1239,7 +1265,7 @@ export interface components { readonly vegaPriceMonitoringTrigger: { /** * Price monitoring auction extension duration in seconds should the price - * breach it's theoretical level over the specified horizon at the specified + * breach its theoretical level over the specified horizon at the specified * probability level * Format: int64 */ @@ -1436,11 +1462,6 @@ export interface components { readonly dataSourceSpecForTradingTermination?: components['schemas']['vegaDataSourceDefinition']; /** Human-readable name/abbreviation of the quote name */ readonly quoteName?: string; - /** - * The number of decimal places implied by the settlement data (such as price) emitted by the settlement external data source - * Format: int64 - */ - readonly settlementDataDecimals?: number; }; /** Instrument configuration */ readonly vegaUpdateInstrumentConfiguration: { @@ -1464,6 +1485,11 @@ export interface components { readonly liquidityMonitoringParameters?: components['schemas']['vegaLiquidityMonitoringParameters']; /** Log normal risk model parameters, valid only if MODEL_LOG_NORMAL is selected */ readonly logNormal?: components['schemas']['vegaLogNormalRiskModel']; + /** + * Percentage move up and down from the mid price which specifies the range of + * price levels over which automated liquidity provision orders will be deployed + */ + readonly lpPriceRange?: string; /** Optional market metadata, tags */ readonly metadata?: readonly string[]; /** Price monitoring parameters */ @@ -1504,6 +1530,27 @@ export interface components { export type external = Record; export interface operations { + BlockExplorer_Info: { + /** + * Info + * @description Retrieves information about the block explorer. + * Response contains a semver formatted version of the data node and the commit hash, from which the block explorer was built, + */ + responses: { + /** @description A successful response. */ + 200: { + content: { + readonly 'application/json': components['schemas']['v1InfoResponse']; + }; + }; + /** @description An unexpected error response. */ + default: { + content: { + readonly 'application/json': components['schemas']['googlerpcStatus']; + }; + }; + }; + }; BlockExplorer_ListTransactions: { /** * List transactions