Compare commits

..
Author SHA1 Message Date
Matthew Russell b363e9561f fix: assertion when testing proposed markets list 2024-03-11 12:18:45 +00:00
Matthew Russell de42caa2a3 fix: proposals list spec 2024-03-09 17:20:47 +00:00
Matthew Russell 42079206b4 chore: adding missing timestamp fields to tests 2024-03-09 16:58:29 +00:00
Matthew Russell 4f5ad8b087 fix: ts errors 2024-03-09 16:33:53 +00:00
Matthew Russell d41b1769d9 fix: mocks and translations 2024-03-09 16:18:25 +00:00
Matthew Russell 3ed6522bf4 fix: circ dep by moving proposed markets to app 2024-03-09 15:58:22 +00:00
Matthew Russell d67c7efb4f fix: circ dep by moving proposed markets to app 2024-03-09 15:55:00 +00:00
Matthew Russell 05b39e2c08 fix(trading): usdt approvals (#5939) 2024-03-07 14:21:31 +00:00
Matthew Russell 654dd1e7b0 fix(trading): stored state causing wrong chart data (#5928) 2024-03-05 18:17:18 +00:00
Matthew Russellandbwallacee 7ea7362a7d fix(trading): market into tab 24hr vol and price fix (#5910)
Co-authored-by: bwallacee <ben@vega.xyz>
2024-03-04 19:08:42 +00:00
Art bbfe42ddb1 fix(governance): rewards moved to console notification (#5904) 2024-03-04 18:09:52 +00:00
Matthew Russell b163af3e8a fix(trading): 24hr price and volume in header (#5908) 2024-03-04 18:00:54 +00:00
Matthew Russell 82df401611 fix(governance): incorrect penalty information in validators table and page (#5896) 2024-03-01 22:22:17 +00:00
Matthew Russell 4733bc169c fix(governance): rewards pagination and columns (#5879) 2024-02-29 14:57:07 +00:00
m.ray 2b91aebc2a fix(trading): fees by market fix order (#5877) 2024-02-29 10:25:56 +00:00
m.rayandbwallacee 375f4da541 fix(trading): fix reward card asssets (#5888)
Co-authored-by: bwallacee <ben@vega.xyz>
2024-02-29 09:21:35 +00:00
Matthew Russell bc413ed314 chore(trading): revert reuse vega work (#5883) 2024-02-28 16:57:42 +00:00
BenandMatthew Russell 2fab3daebd chore(trading): update vega binaries (#5873)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2024-02-27 23:24:28 +00:00
Art 2e07ada966 fix(governance): network paramater change in batch proposals (#5869) 2024-02-27 11:47:10 +01:00
ArtandDariusz Majcherczyk b81c4bc948 fix(governance): add multisig score to the validator page (#5845)
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2024-02-27 11:46:48 +01:00
4f8d6bd876 fix(trading): banner for resume trading (#5849)
Co-authored-by: Art <artur@vegaprotocol.io>
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2024-02-26 16:17:08 +00:00
Ben 52e5a37da3 chore(trading): fix skipped tests (#5868) 2024-02-26 15:52:22 +00:00
Ben 22599673ec chore(trading): remove fixture usage (#5865) 2024-02-26 14:24:56 +00:00
Ben 3c6a806ad3 chore(trading): reuse vega (#5850) 2024-02-26 12:57:16 +00:00
Dexter Edwards 7101d49d1d chore(governance, trading): update links for new beta extension (#5858) 2024-02-26 12:57:09 +00:00
111 changed files with 1127 additions and 1430 deletions
+2 -2
View File
@@ -25,7 +25,7 @@ jobs:
- name: Install dependencies
run: |
rm package.json
npm install --no-save @commitlint/cli @commitlint/config-conventional @commitlint/config-nx-scopes nx
npm install --no-save @commitlint/cli@16.3.0 @commitlint/config-conventional@18.6.1 @commitlint/config-nx-scopes@18.6.1 nx@17.1.2
- name: Check PR title
run: echo "${{ github.event.pull_request.title }}" | npx commitlint --config ./commitlint.config-ci.js
run: echo "${{ github.event.pull_request.title }}" | npx @commitlint/cli@16.3.0 --config ./commitlint.config-ci.js
-1
View File
@@ -14,7 +14,6 @@ NX_ORACLE_PROOFS_URL=https://raw.githubusercontent.com/vegaprotocol/well-known/m
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/main/announcements.json
NX_WALLETCONNECT_PROJECT_ID=fe8091dc35738863e509fc4947525c72
-1
View File
@@ -15,7 +15,6 @@ NX_ETH_WALLET_MNEMONIC=ozone access unlock valid olympic save include omit suppl
NX_LOCAL_PROVIDER_URL=http://localhost:8545/
NX_VEGA_WALLET_URL=http://localhost:1789
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
NX_VEGA_REST_URL=http://localhost:3008/api/v2/
-1
View File
@@ -8,7 +8,6 @@ NX_ETHERSCAN_URL=https://sepolia.etherscan.io
NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_EXPLORER_URL=#
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-devnet1-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_REST_URL=https://api.n00.devnet1.vega.xyz/api/v2/
-1
View File
@@ -10,7 +10,6 @@ NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/
NX_VEGA_EXPLORER_URL=https://explorer.vega.xyz
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40:87edc2605e544f888305d7fc4a9141bd@o286262.ingest.sentry.io/5882996
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_REST_URL=https://api.vega.community/api/v2/
-1
View File
@@ -9,7 +9,6 @@ NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_SENTRY_DSN=https://4b8c8a8ba07742648aa4dfe1b8d17e40@o286262.ingest.sentry.io/5882996
NX_VEGA_EXPLORER_URL=https://explorer.mainnet-mirror.vega.rocks
NX_VEGA_DOCS_URL=https://docs.vega.xyz/mainnet
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-mainnet-mirror-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/mainnet/announcements.json
NX_VEGA_REST_URL=https://api.mainnet-mirror.vega.rocks/api/v2/
-1
View File
@@ -5,7 +5,6 @@ NX_VEGA_NETWORKS='{"DEVNET":"https://dev.governance.vega.xyz","STAGNET1":"https:
NX_VEGA_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/networks-internal/main/stagnet1/vegawallet-stagnet1.toml
NX_VEGA_EXPLORER_URL=https://explorer.stagnet1.vega.rocks
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-stagnet1-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_REST_URL=https://api.n00.stagnet1.vega.xyz/api/v2/
-1
View File
@@ -9,7 +9,6 @@ NX_GITHUB_FEEDBACK_URL=https://github.com/vegaprotocol/feedback/discussions
NX_VEGA_EXPLORER_URL=https://explorer.fairground.wtf
NX_VEGA_DOCS_URL=https://docs.vega.xyz/testnet
NX_HOSTED_WALLET_URL=https://wallet.testnet.vega.xyz
NX_DELEGATIONS_PAGINATION=50
NX_TRANCHES_SERVICE_URL=https://tranches-testnet-k8s.ops.vega.xyz
NX_ANNOUNCEMENTS_CONFIG_URL=https://raw.githubusercontent.com/vegaprotocol/announcements/fairground/announcements.json
NX_VEGA_REST_URL=https://api.n07.testnet.vega.xyz/api/v2/
@@ -15,19 +15,16 @@ export const CollapsibleToggle = ({
dataTestId,
children,
}: CollapsibleToggleProps) => {
const classes = classnames(
'mb-4 transition-transform ease-in-out duration-300',
{
'rotate-180': toggleState,
}
);
const classes = classnames('transition-transform ease-in-out duration-300', {
'rotate-180': toggleState,
});
return (
<button
onClick={() => setToggleState(!toggleState)}
data-testid={dataTestId}
>
<div className="flex items-center gap-3">
<div className="flex items-baseline gap-3">
{children}
<div className={classes} data-testid="toggle-icon-wrapper">
<VegaIcon name={VegaIconNames.CHEVRON_DOWN} size={20} />
@@ -0,0 +1,44 @@
import {
useLinks,
DApp,
CONSOLE_REWARDS_PAGE,
} from '@vegaprotocol/environment';
import {
ExternalLink,
Intent,
NotificationBanner,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { Trans } from 'react-i18next';
import { useMatch } from 'react-router-dom';
import Routes from '../../routes/routes';
import { type ReactNode } from 'react';
const ConsoleRewardsLink = ({ children }: { children: ReactNode }) => {
const consoleLink = useLinks(DApp.Console);
return (
<ExternalLink
href={consoleLink(CONSOLE_REWARDS_PAGE)}
className="underline inline-flex gap-1 items-center"
title="Rewards in Console"
>
<span>{children}</span>
<VegaIcon size={12} name={VegaIconNames.OPEN_EXTERNAL} />
</ExternalLink>
);
};
export const RewardsMovedNotification = () => {
const onRewardsPage = useMatch(Routes.REWARDS);
if (!onRewardsPage) return null;
return (
<NotificationBanner intent={Intent.Warning}>
<Trans
i18nKey="rewardsMovedNotification"
components={[<ConsoleRewardsLink>Console</ConsoleRewardsLink>]}
/>
</NotificationBanner>
);
};
@@ -10,6 +10,7 @@ import {
ProtocolUpgradeProposalNotification,
} from '@vegaprotocol/proposals';
import { ViewingAsBanner } from '@vegaprotocol/ui-toolkit';
import { RewardsMovedNotification } from '../notifications/rewards-moved-notification';
interface AppLayoutProps {
children: ReactNode;
@@ -45,8 +46,10 @@ export const AppLayout = ({ children }: AppLayoutProps) => {
const NotificationsContainer = () => {
const { isReadOnly, pubKey, disconnect } = useVegaWallet();
return (
<div data-testid="banners">
<RewardsMovedNotification />
<ProtocolUpgradeProposalNotification
mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING}
/>
@@ -4,7 +4,6 @@ import keyBy from 'lodash/keyBy';
import uniq from 'lodash/uniq';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ENV } from '../../config';
import noIcon from '../../images/token-no-icon.png';
import vegaBlack from '../../images/vega_black.png';
@@ -37,7 +36,6 @@ export const usePollForDelegations = () => {
const { t } = useTranslation();
const { pubKey } = useVegaWallet();
const client = useApolloClient();
const { delegationsPagination } = ENV;
const [delegations, setDelegations] = React.useState<
WalletDelegationFieldsFragment[]
>([]);
@@ -68,11 +66,9 @@ export const usePollForDelegations = () => {
query: DelegationsDocument,
variables: {
partyId: pubKey,
delegationsPagination: delegationsPagination
? {
first: Number(delegationsPagination),
}
: undefined,
delegationsPagination: {
first: 50,
},
},
fetchPolicy: 'network-only',
})
@@ -236,14 +232,14 @@ export const usePollForDelegations = () => {
// will just continue to fail
clearInterval(interval);
});
}, 1000);
}, 20000);
}
return () => {
clearInterval(interval);
mounted = false;
};
}, [delegationsPagination, client, decimals, pubKey, t, vegaToken.address]);
}, [client, decimals, pubKey, t, vegaToken.address]);
return { delegations, currentStakeAvailable, delegatedNodes, accounts };
};
-1
View File
@@ -65,7 +65,6 @@ export const ENV = {
docsUrl: windowOrDefault('NX_VEGA_DOCS_URL'),
ethWalletMnemonic: windowOrDefault('NX_ETH_WALLET_MNEMONIC'),
localProviderUrl: windowOrDefault('NX_LOCAL_PROVIDER_URL'),
delegationsPagination: windowOrDefault('NX_DELEGATIONS_PAGINATION'),
rest: windowOrDefault('NX_VEGA_REST_URL'),
addresses:
ContractAddresses[(envName === 'local' ? 'CUSTOM' : envName) as Networks],
@@ -20,6 +20,7 @@ describe('getMultisigStatus', () => {
expect(result).toEqual({
multisigStatus: MultisigStatus.noNodes,
showMultisigStatusError: true,
zeroScoreNodes: [],
});
});
@@ -35,6 +36,7 @@ describe('getMultisigStatus', () => {
expect(result).toEqual({
multisigStatus: MultisigStatus.correct,
showMultisigStatusError: false,
zeroScoreNodes: [],
});
});
@@ -50,6 +52,22 @@ describe('getMultisigStatus', () => {
expect(result).toEqual({
multisigStatus: MultisigStatus.nodeNeedsRemoving,
showMultisigStatusError: true,
zeroScoreNodes: [
{
id: '1',
rewardScore: {
multisigScore: '0',
},
stakedTotal: '1000',
},
{
id: '2',
rewardScore: {
multisigScore: '0',
},
stakedTotal: '1000',
},
],
});
});
@@ -65,6 +83,15 @@ describe('getMultisigStatus', () => {
expect(result).toEqual({
multisigStatus: MultisigStatus.nodeNeedsAdding,
showMultisigStatusError: true,
zeroScoreNodes: [
{
id: '1',
rewardScore: {
multisigScore: '0',
},
stakedTotal: '1000',
},
],
});
});
});
@@ -1,5 +1,8 @@
import { removePaginationWrapper } from '@vegaprotocol/utils';
import type { PreviousEpochQuery } from '../routes/staking/__generated__/PreviousEpoch';
import type {
PreviousEpochQuery,
ValidatorNodeFragment,
} from '../routes/staking/__generated__/PreviousEpoch';
export enum MultisigStatus {
'correct' = 'correct',
@@ -17,12 +20,15 @@ export const getMultisigStatusInfo = (
previousEpochData?.epoch.validatorsConnection?.edges
);
const hasZero = allNodesInPreviousEpoch.some(
(node) => Number(node?.rewardScore?.multisigScore) === 0
);
const hasOne = allNodesInPreviousEpoch.some(
(node) => Number(node?.rewardScore?.multisigScore) === 1
);
const zeroScore = (node: ValidatorNodeFragment) =>
Number(node.rewardScore?.multisigScore) === 0;
const oneScore = (node: ValidatorNodeFragment) =>
Number(node.rewardScore?.multisigScore) === 1;
const hasZero = allNodesInPreviousEpoch.some(zeroScore);
const hasOne = allNodesInPreviousEpoch.some(oneScore);
const zeroScoreNodes = allNodesInPreviousEpoch.filter(zeroScore);
if (hasZero && hasOne) {
// If any individual node has 0 it means that node is missing from the multisig and needs to be added
@@ -38,5 +44,6 @@ export const getMultisigStatusInfo = (
return {
showMultisigStatusError: status !== MultisigStatus.correct,
multisigStatus: status,
zeroScoreNodes,
};
};
@@ -36,8 +36,8 @@ import { type Proposal, type BatchProposal } from '../../types';
import { type ProposalTermsFieldsFragment } from '../../__generated__/Proposals';
import { differenceInHours, format, formatDistanceToNowStrict } from 'date-fns';
import { DATE_FORMAT_DETAILED } from '../../../../lib/date-formats';
import { getIndicatorStyle } from '../proposal/colours';
import { MarketName } from '../proposal/market-name';
import { Indicator } from '../proposal/indicator';
const ProposalTypeTags = ({
proposal,
@@ -250,7 +250,7 @@ const ProposalDetails = ({
}}
components={{
// @ts-ignore children passed by i18next
lozenge: <Lozenge />,
lozenge: <Lozenge className="text-xs" />,
}}
/>
);
@@ -312,8 +312,11 @@ const ProposalDetails = ({
{proposal.subProposals.map((p, i) => {
if (!p?.terms) return null;
return (
<li key={i} className="flex gap-3 items-center">
<span className={getIndicatorStyle(i + 1)}>{i + 1}</span>
<li
key={i}
className="grid grid-cols-[40px_minmax(0,1fr)] grid-rows-1 gap-3 items-center"
>
<Indicator indicator={i + 1} />
<span>
<div>{renderDetails(p.terms)}</div>
<SubProposalStateText
@@ -18,7 +18,7 @@ export const ProposalJson = ({ proposal }: { proposal?: unknown }) => {
<SubHeading title={t('proposalJson')} />
</CollapsibleToggle>
{showDetails && <SyntaxHighlighter data={proposal} />}
{showDetails && <SyntaxHighlighter size="smaller" data={proposal} />}
</section>
);
};
@@ -143,14 +143,14 @@ export const ProposalMarketChanges = ({
<SubHeading
title={
<>
{t('UpdateToMarket')}: <MarketName marketId={marketId} />
{t('UpdateToMarket')}: <MarketName marketId={marketId} truncate />
</>
}
/>
</CollapsibleToggle>
{showChanges && (
<div className="mb-6">
<div className="mb-6 bg-vega-cdark-900 p-2 rounded-lg">
<JsonDiff left={left as JsonValue} right={right as JsonValue} />
</div>
)}
@@ -16,21 +16,21 @@ const getColour = (indicator: number, max = COLOURS.length) => {
export const getStyle = (indicator: number, max = COLOURS.length) =>
classNames({
'bg-vega-yellow-400 after:bg-vega-yellow-400':
'bg-vega-yellow-400 before:bg-vega-yellow-400':
'yellow' === getColour(indicator, max),
'bg-vega-green-400 after:bg-vega-green-400':
'bg-vega-green-400 before:bg-vega-green-400':
'green' === getColour(indicator, max),
'bg-vega-blue-400 after:bg-vega-blue-400':
'bg-vega-blue-400 before:bg-vega-blue-400':
'blue' === getColour(indicator, max),
'bg-vega-purple-400 after:bg-vega-purple-400':
'bg-vega-purple-400 before:bg-vega-purple-400':
'purple' === getColour(indicator, max),
'bg-vega-pink-400 after:bg-vega-pink-400':
'bg-vega-pink-400 before:bg-vega-pink-400':
'pink' === getColour(indicator, max),
'bg-vega-orange-400 after:bg-vega-orange-400':
'bg-vega-orange-400 before:bg-vega-orange-400':
'orange' === getColour(indicator, max),
'bg-vega-red-400 after:bg-vega-red-400':
'bg-vega-red-400 before:bg-vega-red-400':
'red' === getColour(indicator, max),
'bg-vega-clight-600 after:bg-vega-clight-600':
'bg-vega-clight-600 before:bg-vega-clight-600':
'none' === getColour(indicator, max),
});
@@ -40,7 +40,7 @@ export const getIndicatorStyle = (indicator: number) =>
'text-border-1',
getStyle(indicator),
// Comment below if you want to remove the "chevron"
'relative mr-[11px]',
'after:absolute after:z-[-1] after:top-1 after:right-[-11px] after:rounded-sm',
"after:w-[22.62px] after:h-[22.62px] after:rotate-45 after:content-['']"
'relative mr-[11px] z-1',
'before:absolute before:z-0 before:top-1 before:right-[-11px] before:rounded-sm',
"before:w-[22.62px] before:h-[22.62px] before:rotate-45 before:content-['']"
);
@@ -0,0 +1,9 @@
import { getIndicatorStyle } from './colours';
export const Indicator = ({ indicator }: { indicator: number }) => (
<div className={getIndicatorStyle(indicator)}>
<span className="absolute top-0 left-0 p-1 w-full text-center z-1">
{indicator}
</span>
</div>
);
@@ -1,6 +1,13 @@
import { useMarketInfoQuery } from '@vegaprotocol/markets';
import { truncateMiddle } from '@vegaprotocol/ui-toolkit';
export const MarketName = ({ marketId }: { marketId?: string }) => {
export const MarketName = ({
marketId,
truncate,
}: {
marketId?: string;
truncate?: boolean;
}) => {
const { data } = useMarketInfoQuery({
variables: {
marketId: marketId || '',
@@ -8,7 +15,7 @@ export const MarketName = ({ marketId }: { marketId?: string }) => {
skip: !marketId,
});
return (
<span>{data?.market?.tradableInstrument.instrument.code || marketId}</span>
);
const id = truncate ? truncateMiddle(marketId || '') : marketId;
return <span>{data?.market?.tradableInstrument.instrument.code || id}</span>;
};
@@ -1,3 +1,4 @@
import { Trans, useTranslation } from 'react-i18next';
import { type ProposalTermsFieldsFragment } from '../../__generated__/Proposals';
import { type Proposal, type BatchProposal } from '../../types';
import { ListAsset } from '../list-asset';
@@ -12,8 +13,10 @@ import {
import { ProposalUpdateBenefitTiers } from '../proposal-update-benefit-tiers';
import { ProposalUpdateMarketState } from '../proposal-update-market-state';
import { ProposalVolumeDiscountProgramDetails } from '../proposal-volume-discount-program-details';
import { getIndicatorStyle } from './colours';
import { type ProposalNode } from './proposal-utils';
import { Lozenge } from '@vegaprotocol/ui-toolkit';
import { Indicator } from './indicator';
import { SubHeading } from '../../../../components/heading';
export const ProposalChangeDetails = ({
proposal,
@@ -26,6 +29,7 @@ export const ProposalChangeDetails = ({
restData: ProposalNode | null;
indicator?: number;
}) => {
const { t } = useTranslation();
let details = null;
switch (terms.change.__typename) {
@@ -108,6 +112,25 @@ export const ProposalChangeDetails = ({
'rewards.activityStreak.benefitTiers'
) {
details = <ProposalUpdateBenefitTiers change={terms.change} />;
} else {
details = (
<div className="mb-4">
<SubHeading title={t(terms.change.__typename as string)} />
<span>
<Trans
i18nKey="Change <lozenge>{{key}}</lozenge> to <lozenge>{{value}}</lozenge>"
values={{
key: terms.change.networkParameter.key,
value: terms.change.networkParameter.value,
}}
components={{
// @ts-ignore children passed by i18next
lozenge: <Lozenge />,
}}
/>
</span>
</div>
);
}
break;
@@ -120,10 +143,12 @@ export const ProposalChangeDetails = ({
}
}
if (indicator != null) {
if (indicator != null && details != null) {
details = (
<div className="flex gap-3 mb-3">
<div className={getIndicatorStyle(indicator)}>{indicator}</div>
<div className="grid grid-cols-[40px_minmax(0,1fr)] grid-rows-1 gap-3 mb-3">
<div className="w-10">
<Indicator indicator={indicator} />
</div>
<div>{details}</div>
</div>
);
@@ -60,7 +60,7 @@ export const Proposal = ({ proposal, restData }: ProposalProps) => {
<ProposalDescription description={proposal.rationale.description} />
</div>
<div className="mb-4">
<div className="mb-4 flex flex-col gap-0">
{proposal.__typename === 'Proposal' ? (
<ProposalChangeDetails
proposal={proposal}
@@ -206,7 +206,7 @@ export const ProposalsList = ({
/>
)}
<section className="-mx-4 p-4 mb-8 bg-vega-dark-100">
<section className="-mx-4 p-4 mb-8 bg-vega-cdark-900 rounded-l-sm">
<SubHeading title={t('openProposals')} />
{sortedProposals.open.length > 0 ||
@@ -15,8 +15,8 @@ import {
type VoteFieldsFragment,
} from '../../__generated__/Proposals';
import { useBatchVoteInformation } from '../../hooks/use-vote-information';
import { getIndicatorStyle } from '../proposal/colours';
import { MarketName } from '../proposal/market-name';
import { Indicator } from '../proposal/indicator';
export const CompactVotes = ({ number }: { number: BigNumber }) => (
<CompactNumber
@@ -300,13 +300,11 @@ const VoteBreakdownBatchSubProposal = ({
</>
) : null;
const indicatorElement = indicator && (
<span className={getIndicatorStyle(indicator)}>{indicator}</span>
);
const indicatorElement = indicator && <Indicator indicator={indicator} />;
return (
<div className="mb-6">
<div className="flex items-baseline gap-3 mb-3">
<div className="flex items-center gap-3 mb-3">
{indicatorElement}
<h4>
{t(terms.change.__typename)} {marketName}
@@ -1,10 +1,9 @@
import { useMemo, useEffect, useState, useCallback, useRef } from 'react';
import { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { AsyncRenderer, Pagination } from '@vegaprotocol/ui-toolkit';
import { removePaginationWrapper } from '@vegaprotocol/utils';
import type { EpochFieldsFragment } from '../home/__generated__/Rewards';
import { useRewardsQuery } from '../home/__generated__/Rewards';
import { ENV } from '../../../config';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { EpochIndividualRewardsTable } from './epoch-individual-rewards-table';
import { generateEpochIndividualRewardsList } from './generate-epoch-individual-rewards-list';
@@ -27,22 +26,16 @@ export const EpochIndividualRewards = ({
const [page, setPage] = useState(1);
const { t } = useTranslation();
const { pubKey } = useVegaWallet();
const { delegationsPagination } = ENV;
const { param: marketCreationQuantumMultiple } = useNetworkParam(
'rewards_marketCreationQuantumMultiple'
);
const { data, loading, error, refetch } = useRewardsQuery({
const { data, loading, error } = useRewardsQuery({
notifyOnNetworkStatusChange: true,
variables: {
partyId: pubKey || '',
fromEpoch: epochId - EPOCHS_PAGE_SIZE,
toEpoch: epochId,
delegationsPagination: delegationsPagination
? {
first: Number(delegationsPagination),
}
: undefined,
...calculateEpochOffset({ epochId, page, size: EPOCHS_PAGE_SIZE }),
delegationsPagination: { first: 50 },
},
skip: !pubKey,
});
@@ -70,36 +63,6 @@ export const EpochIndividualRewards = ({
});
}, [data?.party, epochId, epochRewardSummaries, page, rewards]);
const refetchData = useCallback(
async (toPage?: number) => {
const targetPage = toPage ?? page;
await refetch({
partyId: pubKey || '',
...calculateEpochOffset({ epochId, page, size: EPOCHS_PAGE_SIZE }),
delegationsPagination: delegationsPagination
? {
first: Number(delegationsPagination),
}
: undefined,
});
setPage(targetPage);
},
[epochId, page, refetch, delegationsPagination, pubKey]
);
const prevEpochIdRef = useRef<number | null>(null);
useEffect(() => {
if (prevEpochIdRef.current === null) {
prevEpochIdRef.current = epochId;
} else if (epochId !== prevEpochIdRef.current) {
// When the epoch changes, we want to refetch the data to update the current page
refetchData();
}
prevEpochIdRef.current = epochId;
}, [epochId, refetchData]);
// Workarounds for the error handling of AsyncRenderer
const filteredErrors = filterAcceptableGraphqlErrors(error);
const filteredData = data || [];
@@ -131,10 +94,10 @@ export const EpochIndividualRewards = ({
isLoading={loading}
hasPrevPage={page > 1}
hasNextPage={page < totalPages}
onBack={() => refetchData(page - 1)}
onNext={() => refetchData(page + 1)}
onFirst={() => refetchData(1)}
onLast={() => refetchData(totalPages)}
onBack={() => setPage((x) => x - 1)}
onNext={() => setPage((x) => x + 1)}
onFirst={() => setPage(1)}
onLast={() => setPage(totalPages)}
>
{t('Page')} {page}
</Pagination>
@@ -23,36 +23,6 @@ describe('generateEpochIndividualRewardsList', () => {
epoch: { id: '2' },
};
const reward3: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '200',
percentageOfTotal: '0.2',
receivedAt: new Date(),
asset: { id: 'gbp', symbol: 'GBP', name: 'GBP', decimals: 7 },
party: { id: 'blah' },
epoch: { id: '2' },
};
const reward4: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '100',
percentageOfTotal: '0.1',
receivedAt: new Date(),
asset: { id: 'usd', symbol: 'USD', name: 'USD', decimals: 6 },
party: { id: 'blah' },
epoch: { id: '1' },
};
const reward5: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '150',
percentageOfTotal: '0.15',
receivedAt: new Date(),
asset: { id: 'usd', symbol: 'USD', name: 'USD', decimals: 6 },
party: { id: 'blah' },
epoch: { id: '3' },
};
const rewardWrongType: RewardFieldsFragment = {
rewardType: AccountType.ACCOUNT_TYPE_INSURANCE,
amount: '50',
@@ -120,26 +90,10 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '100',
percentageOfTotal: '0.1',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
],
@@ -147,7 +101,7 @@ describe('generateEpochIndividualRewardsList', () => {
});
it('should return an array sorted by epoch descending', () => {
const rewards = [reward1, reward2, reward3, reward4];
const rewards = [reward1, reward2];
const result1 = generateEpochIndividualRewardsList({
rewards,
epochId: 2,
@@ -157,7 +111,7 @@ describe('generateEpochIndividualRewardsList', () => {
expect(result1[0].epoch).toEqual(2);
expect(result1[1].epoch).toEqual(1);
const reorderedRewards = [reward4, reward3, reward2, reward1];
const reorderedRewards = [reward2, reward1];
const result2 = generateEpochIndividualRewardsList({
rewards: reorderedRewards,
epochId: 2,
@@ -170,7 +124,7 @@ describe('generateEpochIndividualRewardsList', () => {
it('returns data in the expected shape', () => {
// Just sanity checking the whole structure here
const rewards = [reward1, reward2, reward3, reward4];
const rewards = [reward1, reward2];
const result = generateEpochIndividualRewardsList({
rewards,
epochId: 2,
@@ -181,37 +135,6 @@ describe('generateEpochIndividualRewardsList', () => {
{
epoch: 2,
rewards: [
{
asset: 'GBP',
totalAmount: '200',
decimals: 7,
rewardTypes: {
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '200',
percentageOfTotal: '0.2',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
{
asset: 'EUR',
totalAmount: '50',
@@ -221,26 +144,10 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '50',
percentageOfTotal: '0.05',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
],
@@ -250,33 +157,17 @@ describe('generateEpochIndividualRewardsList', () => {
rewards: [
{
asset: 'USD',
totalAmount: '200',
totalAmount: '100',
decimals: 6,
rewardTypes: {
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '100',
percentageOfTotal: '0.1',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '100',
percentageOfTotal: '0.1',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
],
@@ -285,7 +176,7 @@ describe('generateEpochIndividualRewardsList', () => {
});
it('returns data correctly for the requested epoch range', () => {
const rewards = [reward1, reward2, reward3, reward4, reward5];
const rewards = [reward1, reward2];
const resultPageOne = generateEpochIndividualRewardsList({
rewards,
epochId: 3,
@@ -297,74 +188,11 @@ describe('generateEpochIndividualRewardsList', () => {
expect(resultPageOne).toEqual([
{
epoch: 3,
rewards: [
{
asset: 'USD',
decimals: 6,
totalAmount: '150',
rewardTypes: {
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '150',
percentageOfTotal: '0.15',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
],
rewards: [],
},
{
epoch: 2,
rewards: [
{
asset: 'GBP',
totalAmount: '200',
decimals: 7,
rewardTypes: {
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '200',
percentageOfTotal: '0.2',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
{
asset: 'EUR',
totalAmount: '50',
@@ -374,26 +202,10 @@ describe('generateEpochIndividualRewardsList', () => {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '50',
percentageOfTotal: '0.05',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
],
@@ -414,33 +226,17 @@ describe('generateEpochIndividualRewardsList', () => {
rewards: [
{
asset: 'USD',
totalAmount: '200',
totalAmount: '100',
decimals: 6,
rewardTypes: {
[AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
amount: '100',
percentageOfTotal: '0.1',
},
[AccountType.ACCOUNT_TYPE_GLOBAL_REWARD]: {
amount: '100',
percentageOfTotal: '0.1',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
amount: '0',
percentageOfTotal: '0',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
amount: '0',
percentageOfTotal: '0',
},
},
},
],
@@ -1,4 +1,4 @@
import { useState, useCallback, useEffect } from 'react';
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { AsyncRenderer, Pagination } from '@vegaprotocol/ui-toolkit';
import type { EpochFieldsFragment } from '../home/__generated__/Rewards';
@@ -23,37 +23,17 @@ export const EpochTotalRewards = ({ currentEpoch }: EpochTotalRewardsProps) => {
'rewards_marketCreationQuantumMultiple'
);
const [page, setPage] = useState(1);
const { data, loading, error, refetch } = useEpochAssetsRewardsQuery({
const { data, loading, error } = useEpochAssetsRewardsQuery({
notifyOnNetworkStatusChange: true,
variables: {
epochRewardSummariesFilter: {
fromEpoch: epochId - EPOCHS_PAGE_SIZE,
},
epochRewardSummariesFilter: calculateEpochOffset({
epochId,
page: page,
size: EPOCHS_PAGE_SIZE,
}),
},
});
const refetchData = useCallback(
async (toPage?: number) => {
const targetPage = toPage ?? page;
await refetch({
epochRewardSummariesFilter: calculateEpochOffset({
epochId,
page: targetPage,
size: EPOCHS_PAGE_SIZE,
}),
});
setPage(targetPage);
},
[epochId, page, refetch]
);
useEffect(() => {
// when the epoch changes, we want to refetch the data to update the current page
if (data) {
refetchData();
}
}, [epochId, data, refetchData]);
const epochTotalRewardSummaries =
generateEpochTotalRewardsList({
data,
@@ -85,10 +65,10 @@ export const EpochTotalRewards = ({ currentEpoch }: EpochTotalRewardsProps) => {
isLoading={loading}
hasPrevPage={page > 1}
hasNextPage={page < totalPages}
onBack={() => refetchData(page - 1)}
onNext={() => refetchData(page + 1)}
onFirst={() => refetchData(1)}
onLast={() => refetchData(totalPages)}
onBack={() => setPage((x) => x - 1)}
onNext={() => setPage((x) => x + 1)}
onFirst={() => setPage(1)}
onLast={() => setPage(totalPages)}
>
{t('Page')} {page}
</Pagination>
@@ -149,38 +149,6 @@ describe('generateEpochAssetRewardsList', () => {
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
amount: '0',
},
],
]),
totalAmount: '123',
},
@@ -291,40 +259,8 @@ describe('generateEpochAssetRewardsList', () => {
amount: '100',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
amount: '123',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
amount: '0',
},
],
]),
totalAmount: '223',
totalAmount: '100',
},
],
]),
@@ -334,66 +270,7 @@ describe('generateEpochAssetRewardsList', () => {
'2',
{
epoch: 2,
assetRewards: new Map([
[
'1',
{
assetId: '1',
decimals: 18,
name: 'Asset 1',
rewards: new Map([
[
AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
{
rewardType: AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
{
rewardType:
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '5',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
amount: '0',
},
],
]),
totalAmount: '5',
},
],
]),
assetRewards: new Map(),
},
],
])
@@ -489,66 +366,7 @@ describe('generateEpochAssetRewardsList', () => {
'2',
{
epoch: 2,
assetRewards: new Map([
[
'1',
{
assetId: '1',
name: 'Asset 1',
decimals: 18,
rewards: new Map([
[
AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
{
rewardType: AccountType.ACCOUNT_TYPE_GLOBAL_REWARD,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
{
rewardType:
AccountType.ACCOUNT_TYPE_FEES_INFRASTRUCTURE,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '33',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
amount: '0',
},
],
]),
totalAmount: '33',
},
],
]),
assetRewards: new Map(),
},
],
[
@@ -578,38 +396,6 @@ describe('generateEpochAssetRewardsList', () => {
amount: '15',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
amount: '0',
},
],
]),
totalAmount: '15',
},
@@ -656,40 +442,8 @@ describe('generateEpochAssetRewardsList', () => {
amount: '100',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
amount: '123',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES,
amount: '0',
},
],
[
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
{
rewardType:
AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS,
amount: '0',
},
],
]),
totalAmount: '223',
totalAmount: '100',
},
],
]),
@@ -18,22 +18,6 @@ export const RowAccountTypes = {
columnTitle: 'rewardsColInfraHeader',
description: 'rewardsColInfraTooltip',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES]: {
columnTitle: 'rewardsColPriceTakingHeader',
description: 'rewardsColPriceTakingTooltip',
},
[AccountType.ACCOUNT_TYPE_REWARD_MAKER_RECEIVED_FEES]: {
columnTitle: 'rewardsColPriceMakingHeader',
description: 'rewardsColPriceMakingTooltip',
},
[AccountType.ACCOUNT_TYPE_REWARD_LP_RECEIVED_FEES]: {
columnTitle: 'rewardsColLiquidityProvisionHeader',
description: 'rewardsColLiquidityProvisionTooltip',
},
[AccountType.ACCOUNT_TYPE_REWARD_MARKET_PROPOSERS]: {
columnTitle: 'rewardsColMarketCreationHeader',
description: 'rewardsColMarketCreationTooltip',
},
};
interface ColumnHeaderProps {
@@ -55,7 +39,7 @@ export const rowGridItemStyles = (last = false) =>
});
const gridStyles = classNames(
'grid grid-cols-[repeat(8,minmax(100px,auto))] max-w-full overflow-auto',
'grid grid-cols-[repeat(4,minmax(100px,auto))] max-w-full overflow-auto',
`border-t border-vega-dark-200`,
'text-sm'
);
@@ -1,27 +1,31 @@
fragment ValidatorNode on Node {
id
stakedTotal
rewardScore {
rawValidatorScore
performanceScore
multisigScore
validatorScore
normalisedScore
validatorStatus
}
rankingScore {
status
previousStatus
rankingScore
stakeScore
performanceScore
votingPower
}
}
query PreviousEpoch($epochId: ID) {
epoch(id: $epochId) {
id
validatorsConnection {
edges {
node {
id
stakedTotal
rewardScore {
rawValidatorScore
performanceScore
multisigScore
validatorScore
normalisedScore
validatorStatus
}
rankingScore {
status
previousStatus
rankingScore
stakeScore
performanceScore
votingPower
}
...ValidatorNode
}
}
}
@@ -3,6 +3,8 @@ import * as Types from '@vegaprotocol/types';
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
const defaultOptions = {} as const;
export type ValidatorNodeFragment = { __typename?: 'Node', id: string, stakedTotal: string, rewardScore?: { __typename?: 'RewardScore', rawValidatorScore: string, performanceScore: string, multisigScore: string, validatorScore: string, normalisedScore: string, validatorStatus: Types.ValidatorStatus } | null, rankingScore: { __typename?: 'RankingScore', status: Types.ValidatorStatus, previousStatus: Types.ValidatorStatus, rankingScore: string, stakeScore: string, performanceScore: string, votingPower: string } };
export type PreviousEpochQueryVariables = Types.Exact<{
epochId?: Types.InputMaybe<Types.Scalars['ID']>;
}>;
@@ -10,7 +12,28 @@ export type PreviousEpochQueryVariables = Types.Exact<{
export type PreviousEpochQuery = { __typename?: 'Query', epoch: { __typename?: 'Epoch', id: string, validatorsConnection?: { __typename?: 'NodesConnection', edges?: Array<{ __typename?: 'NodeEdge', node: { __typename?: 'Node', id: string, stakedTotal: string, rewardScore?: { __typename?: 'RewardScore', rawValidatorScore: string, performanceScore: string, multisigScore: string, validatorScore: string, normalisedScore: string, validatorStatus: Types.ValidatorStatus } | null, rankingScore: { __typename?: 'RankingScore', status: Types.ValidatorStatus, previousStatus: Types.ValidatorStatus, rankingScore: string, stakeScore: string, performanceScore: string, votingPower: string } } } | null> | null } | null } };
export const ValidatorNodeFragmentDoc = gql`
fragment ValidatorNode on Node {
id
stakedTotal
rewardScore {
rawValidatorScore
performanceScore
multisigScore
validatorScore
normalisedScore
validatorStatus
}
rankingScore {
status
previousStatus
rankingScore
stakeScore
performanceScore
votingPower
}
}
`;
export const PreviousEpochDocument = gql`
query PreviousEpoch($epochId: ID) {
epoch(id: $epochId) {
@@ -18,30 +41,13 @@ export const PreviousEpochDocument = gql`
validatorsConnection {
edges {
node {
id
stakedTotal
rewardScore {
rawValidatorScore
performanceScore
multisigScore
validatorScore
normalisedScore
validatorStatus
}
rankingScore {
status
previousStatus
rankingScore
stakeScore
performanceScore
votingPower
}
...ValidatorNode
}
}
}
}
}
`;
${ValidatorNodeFragmentDoc}`;
/**
* __usePreviousEpochQuery__
@@ -6,7 +6,6 @@ import { usePreviousEpochQuery } from '../__generated__/PreviousEpoch';
import { ValidatorTables } from './validator-tables';
import { useRefreshAfterEpoch } from '../../../hooks/use-refresh-after-epoch';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { ENV } from '../../../config';
import { getMultisigStatusInfo } from '../../../lib/get-multisig-status-info';
import { MultisigIncorrectNotice } from '../../../components/multisig-incorrect-notice';
@@ -20,7 +19,6 @@ export const EpochData = () => {
refetch: nodesRefetch,
} = useNodesQuery();
const { delegationsPagination } = ENV;
const {
data: userStakingData,
error: userStakingError,
@@ -29,11 +27,9 @@ export const EpochData = () => {
} = useStakingQuery({
variables: {
partyId: pubKey || '',
delegationsPagination: delegationsPagination
? {
first: Number(delegationsPagination),
}
: undefined,
delegationsPagination: {
first: 50,
},
},
});
const { data: previousEpochData } = usePreviousEpochQuery({
@@ -288,7 +288,7 @@ describe('Consensus validators table', () => {
expect(
grid.querySelector('[role="gridcell"][col-id="totalPenalties"]')
).toHaveTextContent('13.16%');
).toHaveTextContent('10.07%');
expect(
grid.querySelector('[role="gridcell"][col-id="normalisedVotingPower"]')
@@ -185,15 +185,19 @@ export const ConsensusValidatorsTable = ({
const { rawValidatorScore: previousEpochValidatorScore } =
getLastEpochScoreAndPerformance(previousEpochData, id);
const overstakingPenalty = calculateOverallPenalty(
const overstakingPenalty = calculateOverstakedPenalty(
id,
allNodesInPreviousEpoch
);
const totalPenalty = calculateOverstakedPenalty(
const totalPenalty = calculateOverallPenalty(
id,
allNodesInPreviousEpoch
);
const lastEpochDataForNode = allNodesInPreviousEpoch.find(
(node) => node.id === id
);
return {
id,
[ValidatorFields.RANKING_INDEX]: stakedTotalRanking,
@@ -239,6 +243,12 @@ export const ConsensusValidatorsTable = ({
: undefined,
[ValidatorFields.MULTISIG_ERROR]:
multisigStatus?.showMultisigStatusError,
[ValidatorFields.MULTISIG_PENALTY]: formatNumberPercentage(
new BigNumber(1)
.minus(lastEpochDataForNode?.rewardScore?.multisigScore ?? 1)
.times(100),
2
),
};
}
);
@@ -378,7 +388,6 @@ export const ConsensusValidatorsTable = ({
headerTooltip: t('StakeDescription').toString(),
cellRenderer: TotalStakeRenderer,
width: 120,
sort: 'desc',
},
{
field: ValidatorFields.PENDING_STAKE,
@@ -400,6 +409,7 @@ export const ConsensusValidatorsTable = ({
headerTooltip: t('NormalisedVotingPowerDescription').toString(),
cellRenderer: VotingPowerRenderer,
width: 120,
sort: 'desc',
},
{
field: ValidatorFields.TOTAL_PENALTIES,
@@ -40,6 +40,7 @@ export enum ValidatorFields {
PENDING_USER_STAKE = 'pendingUserStake',
USER_STAKE_SHARE = 'userStakeShare',
MULTISIG_ERROR = 'multisigError',
MULTISIG_PENALTY = 'multisigPenalty',
}
export const addUserDataToValidator = (
@@ -327,7 +328,7 @@ interface TotalPenaltiesRendererProps {
overstakedAmount: string;
overstakingPenalty: string;
totalPenalties: string;
multisigError?: boolean;
multisigPenalty: string;
};
}
@@ -346,11 +347,9 @@ export const TotalPenaltiesRenderer = ({
<div data-testid="overstaked-penalty-tooltip">
{t('overstakedPenalty')}: {data.overstakingPenalty}
</div>
{data.multisigError && (
<div data-testid="multisig-error-tooltip">
{t('multisigPenalty')}: 100%
</div>
)}
<div data-testid="multisig-error-tooltip">
{t('multisigPenalty')}: {data.multisigPenalty}
</div>
</>
}
>
@@ -1,4 +1,3 @@
import { ENV } from '../../../config';
import { Callout, Intent, Splash } from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import { useTranslation } from 'react-i18next';
@@ -28,16 +27,13 @@ export const NodeContainer = ({
}) => {
const { t } = useTranslation();
const { pubKey } = useVegaWallet();
const { delegationsPagination } = ENV;
const { data, loading, error, refetch } = useStakingQuery({
variables: {
partyId: pubKey || '',
delegationsPagination: delegationsPagination
? {
first: Number(delegationsPagination),
}
: undefined,
delegationsPagination: {
first: 50,
},
},
errorPolicy: 'all',
});
@@ -3,7 +3,6 @@ import * as Sentry from '@sentry/react';
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useNavigate } from 'react-router-dom';
import { ENV } from '../../../config';
import { usePartyDelegationsLazyQuery } from './__generated__/PartyDelegations';
import { TokenInput } from '../../../components/token-input';
import { useAppState } from '../../../contexts/app-state/app-state-context';
@@ -79,7 +78,6 @@ export const StakingForm = ({
const [error, setError] = useState<Error | null>(null);
const [isDialogVisible, setIsDialogVisible] = useState(false);
const { t } = useTranslation();
const { delegationsPagination } = ENV;
const [action, setAction] = React.useState<StakeAction>(
params.action as StakeAction
);
@@ -154,11 +152,9 @@ export const StakingForm = ({
const [delegationSearch, { data }] = usePartyDelegationsLazyQuery({
variables: {
partyId: pubKey,
delegationsPagination: delegationsPagination
? {
first: Number(delegationsPagination),
}
: undefined,
delegationsPagination: {
first: 50,
},
},
fetchPolicy: 'network-only',
});
@@ -104,6 +104,11 @@ export const ValidatorTable = ({
};
}, [node, previousEpochData?.epoch.validatorsConnection?.edges]);
const previousNodeData =
previousEpochData?.epoch.validatorsConnection?.edges?.find(
(e) => e?.node.id === node.id
);
return (
<>
<p className="mb-12">
@@ -281,6 +286,28 @@ export const ValidatorTable = ({
</span>
</Tooltip>
</KeyValueTableRow>
<KeyValueTableRow>
<span className="uppercase">{t('multisigPenalty')}</span>
<span
data-testid="multisig-penalty"
className="flex gap-2 items-baseline"
>
<Tooltip description={t('multisigPenaltyDescription')}>
<span>
{formatNumberPercentage(
new BigNumber(1)
.minus(
previousNodeData?.node.rewardScore?.multisigScore ??
1
)
.times(100),
2
)}
</span>
</Tooltip>
</span>
</KeyValueTableRow>
<KeyValueTableRow noBorder={true}>
<span>
<strong>{t('TOTAL PENALTIES')}</strong>
@@ -0,0 +1 @@
export { ProposalsList } from './proposals-list';
@@ -6,7 +6,7 @@ import {
ActionsDropdown,
} from '@vegaprotocol/ui-toolkit';
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
import { useT } from '../use-t';
import { useT } from '../../../lib/use-t';
export const ProposalActionsDropdown = ({ id }: { id: string }) => {
const t = useT();
@@ -18,6 +18,7 @@ export const ProposalActionsDropdown = ({ id }: { id: string }) => {
<Link
href={linkCreator(TOKEN_PROPOSAL.replace(':id', id))}
target="_blank"
className="flex items-center gap-2"
>
<VegaIcon name={VegaIconNames.OPEN_EXTERNAL} size={16} />
{t('View proposal')}
@@ -1,75 +1,42 @@
import { render, screen, waitFor, within } from '@testing-library/react';
import merge from 'lodash/merge';
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { ProposalsList } from './proposals-list';
import * as Types from '@vegaprotocol/types';
import { createProposalListFieldsFragment } from '../../lib/proposals-data-provider/proposals.mock';
import type { ProposalsListQuery } from '../../lib';
import { ProposalsListDocument } from '../../lib';
import type { PartialDeep } from 'type-fest';
import { MarketState } from '@vegaprotocol/types';
import { createMarketFragment } from '@vegaprotocol/mock';
import {
type MarketsQuery,
MarketsDocument,
type MarketsQueryVariables,
} from '@vegaprotocol/markets';
const parentMarketName = 'Parent Market Name';
const ParentMarketCell = () => <span>{parentMarketName}</span>;
describe('ProposalsList', () => {
const rowContainerSelector = '.ag-center-cols-container';
const createProposalsMock = (override?: PartialDeep<ProposalsListQuery>) => {
const defaultProposalEdges = [
{
__typename: 'ProposalEdge' as const,
node: createProposalListFieldsFragment({
id: 'id-1',
state: Types.ProposalState.STATE_OPEN,
}),
},
{
__typename: 'ProposalEdge' as const,
node: createProposalListFieldsFragment({
id: 'id-2',
state: Types.ProposalState.STATE_PASSED,
}),
},
{
__typename: 'ProposalEdge' as const,
node: createProposalListFieldsFragment({
id: 'id-3',
state: Types.ProposalState.STATE_WAITING_FOR_NODE_VOTE,
}),
},
];
const data = merge(
{
proposalsConnection: {
__typename: 'ProposalsConnection' as const,
edges: defaultProposalEdges,
},
},
override
);
const mock: MockedResponse<ProposalsListQuery> = {
request: {
query: ProposalsListDocument,
variables: {
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
},
},
result: {
data,
},
};
return mock;
};
beforeEach(() => {
jest.clearAllMocks();
const market = createMarketFragment({
state: MarketState.STATE_PROPOSED,
});
it('should be properly rendered', async () => {
const mock = createProposalsMock();
const mock: MockedResponse<MarketsQuery, MarketsQueryVariables> = {
request: {
query: MarketsDocument,
},
result: {
data: {
marketsConnection: {
edges: [
{
node: market,
},
],
},
},
},
};
render(
<MockedProvider mocks={[mock]}>
<ProposalsList cellRenderers={{ ParentMarketCell }} />
@@ -102,30 +69,25 @@ describe('ProposalsList', () => {
expect(await container.findAllByRole('row')).toHaveLength(
// @ts-ignore data is mocked
mock?.result?.data.proposalsConnection.edges.length
mock?.result?.data.marketsConnection.edges.length
);
expect(
container.getAllByRole('gridcell', {
name: (_, element) =>
element.getAttribute('col-id') ===
'terms.change.successorConfiguration.parentMarketId',
element.getAttribute('col-id') === 'parentMarketID',
})[0]
).toHaveTextContent(parentMarketName);
});
it('empty response should causes no data message display', async () => {
const mock: MockedResponse<ProposalsListQuery> = {
const mock: MockedResponse<MarketsQuery, MarketsQueryVariables> = {
request: {
query: ProposalsListDocument,
variables: {
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
},
query: MarketsDocument,
},
result: {
data: {
proposalsConnection: {
__typename: 'ProposalsConnection',
marketsConnection: {
edges: [],
},
},
@@ -0,0 +1,37 @@
import type { FC } from 'react';
import { AgGrid } from '@vegaprotocol/datagrid';
import { useProposedMarketsList } from '@vegaprotocol/markets';
import { type ProposalListFieldsFragment } from '@vegaprotocol/proposals';
import { useColumnDefs } from './use-column-defs';
import { useT } from '../../../lib/use-t';
const defaultColDef = {
sortable: true,
filter: true,
resizable: true,
filterParams: { buttons: ['reset'] },
};
interface ProposalListProps {
cellRenderers: {
[name: string]: FC<{ value: string; data: ProposalListFieldsFragment }>;
};
}
export const ProposalsList = ({ cellRenderers }: ProposalListProps) => {
const t = useT();
const { data } = useProposedMarketsList();
const columnDefs = useColumnDefs();
return (
<AgGrid
columnDefs={columnDefs}
rowData={data}
defaultColDef={defaultColDef}
getRowId={({ data }) => data.id}
overlayNoRowsTemplate={t('No proposed markets')}
components={cellRenderers}
rowHeight={45}
/>
);
};
@@ -13,12 +13,16 @@ import type {
VegaValueFormatterParams,
} from '@vegaprotocol/datagrid';
import {
ProposalProductTypeShortName,
ProposalStateMapping,
MarketStateMapping,
ProductTypeMapping,
ProductTypeShortName,
} from '@vegaprotocol/types';
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
import { ProposalActionsDropdown } from '../proposal-actions-dropdown';
import { useT } from '../../use-t';
import { ProposalActionsDropdown } from './proposal-actions-dropdown';
import {
type MarketFieldsFragment,
getProductType,
} from '@vegaprotocol/markets';
import { useT } from '../../../lib/use-t';
export const useColumnDefs = () => {
const t = useT();
@@ -28,7 +32,7 @@ export const useColumnDefs = () => {
{
colId: 'market',
headerName: t('Market'),
field: 'terms.change.instrument.code',
field: 'tradableInstrument.instrument.code',
pinned: true,
cellStyle: { lineHeight: '14px' },
cellRenderer: ({
@@ -36,20 +40,10 @@ export const useColumnDefs = () => {
data,
}: {
value: string;
data: ProposalListFieldsFragment;
data: MarketFieldsFragment;
}) => {
if (!value || !data) return '-';
const getProductType = (data: ProposalListFieldsFragment) => {
if (
data.terms.__typename === 'ProposalTerms' &&
data.terms.change.__typename === 'NewMarket'
) {
return data.terms.change.instrument.product?.__typename;
}
return undefined;
};
const productType = getProductType(data);
return (
productType && (
@@ -57,10 +51,10 @@ export const useColumnDefs = () => {
primary={value}
secondary={
<span
title={ProposalProductTypeShortName[productType]}
title={ProductTypeMapping[productType]}
className="uppercase"
>
{ProposalProductTypeShortName[productType]}
{ProductTypeShortName[productType]}
</span>
}
/>
@@ -71,7 +65,7 @@ export const useColumnDefs = () => {
{
colId: 'asset',
headerName: t('Settlement asset'),
field: 'terms.change.instrument.product.settlementAsset.symbol',
field: 'tradableInstrument.instrument.product.settlementAsset.symbol',
},
{
colId: 'state',
@@ -79,39 +73,42 @@ export const useColumnDefs = () => {
field: 'state',
valueFormatter: ({
value,
}: VegaValueFormatterParams<ProposalListFieldsFragment, 'state'>) =>
value ? ProposalStateMapping[value] : '-',
}: VegaValueFormatterParams<MarketFieldsFragment, 'state'>) => {
return value ? MarketStateMapping[value] : '-';
},
filter: SetFilter,
filterParams: {
set: ProposalStateMapping,
set: MarketStateMapping,
},
},
{
headerName: t('Parent market'),
field: 'terms.change.successorConfiguration.parentMarketId',
field: 'parentMarketID',
cellRenderer: 'ParentMarketCell',
},
{
colId: 'closing-date',
headerName: t('Closing date'),
field: 'terms.closingDatetime',
field: 'marketTimestamps.pending',
valueFormatter: ({
value,
}: VegaValueFormatterParams<
ProposalListFieldsFragment,
'terms.closingDatetime'
>) => (value ? getDateTimeFormat().format(new Date(value)) : '-'),
MarketFieldsFragment,
'marketTimestamps.pending'
>) => {
return value ? getDateTimeFormat().format(new Date(value)) : '-';
},
filter: DateRangeFilter,
},
{
colId: 'enactment-date',
headerName: t('Enactment date'),
field: 'terms.enactmentDatetime',
field: 'marketTimestamps.open',
valueFormatter: ({
value,
}: VegaValueFormatterParams<
ProposalListFieldsFragment,
'terms.enactmentDatetime'
MarketFieldsFragment,
'marketTimestamps.open'
>) => (value ? getDateTimeFormat().format(new Date(value)) : '-'),
filter: DateRangeFilter,
},
@@ -120,10 +117,10 @@ export const useColumnDefs = () => {
...COL_DEFS.actions,
cellRenderer: ({
data,
}: VegaICellRendererParams<ProposalListFieldsFragment>) => {
if (!data?.id) return null;
}: VegaICellRendererParams<MarketFieldsFragment>) => {
if (!data?.marketProposal?.id) return null;
return <ProposalActionsDropdown id={data.id} />;
return <ProposalActionsDropdown id={data.marketProposal.id} />;
},
},
]);
@@ -1,4 +1,4 @@
import { ProposalsList } from '@vegaprotocol/proposals';
import { ProposalsList } from './proposals-list';
import { ParentMarketCell } from './parent-market-cell';
const cellRenderers = {
@@ -30,8 +30,6 @@ export const ChartContainer = ({ marketId }: { marketId: string }) => {
setStudies,
setStudySizes,
setOverlays,
state,
setState,
} = useChartSettings();
const pennantChart = (
@@ -68,10 +66,6 @@ export const ChartContainer = ({ marketId }: { marketId: string }) => {
onIntervalChange={(newInterval) => {
setInterval(fromTradingViewResolution(newInterval));
}}
onAutoSaveNeeded={(data) => {
setState(data);
}}
state={state}
/>
);
}
@@ -9,7 +9,6 @@ type StudySizes = { [S in Study]?: number };
export type Chartlib = 'pennant' | 'tradingview';
interface StoredSettings {
state: object | undefined; // Don't see a better type provided from TradingView type definitions
chartlib: Chartlib;
// For interval we use the enum from @vegaprotocol/types, this is to make mapping between different
// chart types easier and more consistent
@@ -30,7 +29,6 @@ const STUDY_ORDER: Study[] = [
];
export const DEFAULT_CHART_SETTINGS = {
state: undefined,
chartlib: 'pennant' as const,
interval: Interval.INTERVAL_I15M,
type: ChartType.CANDLE,
@@ -47,7 +45,6 @@ export const useChartSettingsStore = create<
setStudies: (studies?: Study[]) => void;
setStudySizes: (sizes: number[]) => void;
setChartlib: (lib: Chartlib) => void;
setState: (state: object) => void;
}
>()(
persist(
@@ -95,9 +92,6 @@ export const useChartSettingsStore = create<
state.chartlib = lib;
});
},
setState: (state) => {
set({ state });
},
})),
{
name: 'vega_candles_chart_store',
@@ -151,7 +145,5 @@ export const useChartSettings = () => {
setOverlays: settings.setOverlays,
setStudySizes: settings.setStudySizes,
setChartlib: settings.setChartlib,
state: settings.state,
setState: settings.setState,
};
};
@@ -21,18 +21,13 @@ const useFeesTableColumnDefs = (): ColDef[] => {
pinned: 'left',
width: 150,
},
{
field: 'liquidityFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'feeAfterDiscount',
headerName: t('Total fee after discount'),
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'totalFee',
headerName: t('Total fee before discount'),
field: 'liquidityFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
@@ -43,6 +38,11 @@ const useFeesTableColumnDefs = (): ColDef[] => {
field: 'makerFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'totalFee',
headerName: t('Total fee before discount'),
valueFormatter: ({ value }: { value: number }) => value + '%',
},
] as ColDef[],
[t]
);
@@ -7,7 +7,7 @@ import {
useMaliciousOracle,
} from '@vegaprotocol/markets';
import { useState } from 'react';
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
import { type ProposalFragment } from '@vegaprotocol/proposals';
import { MarketSuspendedBanner } from './market-suspended-banner';
import { MarketUpdateBanner } from './market-update-banner';
import { MarketUpdateStateBanner } from './market-update-state-banner';
@@ -22,17 +22,17 @@ import {
type UpdateMarketBanner = {
kind: 'UpdateMarket';
proposals: MarketViewProposalFieldsFragment[];
proposals: ProposalFragment[];
};
type UpdateMarketStateBanner = {
kind: 'UpdateMarketState';
proposals: MarketViewProposalFieldsFragment[];
proposals: ProposalFragment[];
};
type NewMarketBanner = {
kind: 'NewMarket'; // aka a proposal of NewMarket which succeeds the current market
proposals: MarketViewProposalFieldsFragment[];
proposals: ProposalFragment[];
};
type SettledBanner = {
@@ -1,5 +1,5 @@
import { Fragment } from 'react';
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
import { type ProposalFragment } from '@vegaprotocol/proposals';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { DApp, TOKEN_PROPOSAL, useLinks } from '@vegaprotocol/environment';
import { useT } from '../../lib/use-t';
@@ -7,7 +7,7 @@ import { useT } from '../../lib/use-t';
export const MarketSuccessorProposalBanner = ({
proposals,
}: {
proposals: MarketViewProposalFieldsFragment[];
proposals: ProposalFragment[];
}) => {
const t = useT();
const tokenLink = useLinks(DApp.Governance);
@@ -28,7 +28,7 @@ export const MarketSuccessorProposalBanner = ({
}
)}{' '}
{proposals.map((item, i) => {
if (item.terms.change.__typename !== 'NewMarket') {
if (item.terms?.change.__typename !== 'NewMarket') {
return null;
}
@@ -1,7 +1,7 @@
import { render, screen } from '@testing-library/react';
import { ProposalState } from '@vegaprotocol/types';
import { MarketUpdateBanner } from './market-update-banner';
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
import { type ProposalFragment } from '@vegaprotocol/proposals';
describe('MarketUpdateBanner', () => {
const change = {
@@ -34,9 +34,7 @@ describe('MarketUpdateBanner', () => {
it('renders content for a single open proposal', () => {
render(
<MarketUpdateBanner
proposals={[openProposal as MarketViewProposalFieldsFragment]}
/>
<MarketUpdateBanner proposals={[openProposal as ProposalFragment]} />
);
expect(
@@ -50,9 +48,7 @@ describe('MarketUpdateBanner', () => {
it('renders content for a single passed proposal', () => {
render(
<MarketUpdateBanner
proposals={[passedProposal as MarketViewProposalFieldsFragment]}
/>
<MarketUpdateBanner proposals={[passedProposal as ProposalFragment]} />
);
expect(
@@ -65,10 +61,7 @@ describe('MarketUpdateBanner', () => {
});
it('renders content for multiple passed proposals', () => {
const proposals = [
openProposal,
openProposal,
] as MarketViewProposalFieldsFragment[];
const proposals = [openProposal, openProposal] as ProposalFragment[];
render(<MarketUpdateBanner proposals={proposals} />);
@@ -6,7 +6,7 @@ import {
TOKEN_PROPOSALS,
useLinks,
} from '@vegaprotocol/environment';
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
import { type ProposalFragment } from '@vegaprotocol/proposals';
import { ExternalLink } from '@vegaprotocol/ui-toolkit';
import { ProposalState } from '@vegaprotocol/types';
import { useT } from '../../lib/use-t';
@@ -14,17 +14,17 @@ import { useT } from '../../lib/use-t';
export const MarketUpdateBanner = ({
proposals,
}: {
proposals: MarketViewProposalFieldsFragment[];
proposals: ProposalFragment[];
}) => {
const governanceLink = useLinks(DApp.Governance);
const t = useT();
const openProposals = sortBy(
proposals.filter((p) => p.state === ProposalState.STATE_OPEN),
(p) => p.terms.enactmentDatetime
(p) => p.terms?.enactmentDatetime
);
const passedProposals = sortBy(
proposals.filter((p) => p.state === ProposalState.STATE_PASSED),
(p) => p.terms.enactmentDatetime
(p) => p.terms?.enactmentDatetime
);
let content = null;
@@ -49,7 +49,7 @@ export const MarketUpdateBanner = ({
content = (
<p>
{t('Proposal set to change market on {{date}}.', {
date: format(new Date(proposal.terms.enactmentDatetime), 'dd MMMM'),
date: format(new Date(proposal.terms?.enactmentDatetime), 'dd MMMM'),
})}
<ExternalLink href={proposalLink}>{t('View proposal')}</ExternalLink>,
</p>
@@ -1,8 +1,8 @@
import { type ReactNode } from 'react';
import sortBy from 'lodash/sortBy';
import { format, formatDuration, intervalToDuration } from 'date-fns';
import { type MarketViewProposalFieldsFragment } from '@vegaprotocol/proposals';
import { ProposalState } from '@vegaprotocol/types';
import { type ProposalFragment } from '@vegaprotocol/proposals';
import { MarketUpdateType, ProposalState } from '@vegaprotocol/types';
import {
DApp,
TOKEN_PROPOSAL,
@@ -19,18 +19,29 @@ export const MarketUpdateStateBanner = ({
proposals,
}: {
market: Market;
proposals: MarketViewProposalFieldsFragment[];
proposals: ProposalFragment[];
}) => {
const t = useT();
const governanceLink = useLinks(DApp.Governance);
const openTradingProposals = sortBy(
proposals.filter(
(p) =>
p.terms &&
p.terms.change.__typename === 'UpdateMarketState' &&
p.terms.change.updateType ===
MarketUpdateType.MARKET_STATE_UPDATE_TYPE_RESUME
),
(p) => p.terms?.enactmentDatetime
);
const openProposals = sortBy(
proposals.filter((p) => p.state === ProposalState.STATE_OPEN),
(p) => p.terms.enactmentDatetime
(p) => p.terms?.enactmentDatetime
);
const passedProposals = sortBy(
proposals.filter((p) => p.state === ProposalState.STATE_PASSED),
(p) => p.terms.enactmentDatetime
(p) => p.terms?.enactmentDatetime
);
if (!passedProposals.length && !openProposals.length) {
@@ -45,12 +56,41 @@ export const MarketUpdateStateBanner = ({
? governanceLink(TOKEN_PROPOSAL.replace(':id', openProposals[0]?.id))
: undefined;
const openTradingProposalsLink =
openTradingProposals[0]?.__typename === 'Proposal' &&
openTradingProposals[0]?.id
? governanceLink(
TOKEN_PROPOSAL.replace(':id', openTradingProposals[0].id)
)
: openTradingProposals[0]?.__typename === 'ProposalDetail' &&
openTradingProposals[0]?.batchId
? governanceLink(
TOKEN_PROPOSAL.replace(':id', openTradingProposals[0].batchId)
)
: undefined;
const proposalsLink =
openProposals.length > 1 ? governanceLink(TOKEN_PROPOSALS) : undefined;
let content: ReactNode;
if (passedProposals.length) {
if (openTradingProposals.length >= 1) {
content = (
<>
<p className="mb-1">
{t(
'Trading on market {{name}} was suspended by governance. There are open proposals to resume trading on this market.',
{ name }
)}
</p>
<p>
<ExternalLink href={openTradingProposalsLink}>
{t('View proposals')}
</ExternalLink>
</p>
</>
);
} else if (passedProposals.length) {
const { date, duration, price } = getMessageVariables(passedProposals[0]);
content = (
<>
@@ -116,20 +156,23 @@ export const MarketUpdateStateBanner = ({
return <div data-testid={`update-state-banner-${market.id}`}>{content}</div>;
};
const getMessageVariables = (proposal: MarketViewProposalFieldsFragment) => {
const enactmentDatetime = new Date(proposal.terms.enactmentDatetime);
const date = format(enactmentDatetime, 'dd MMMM');
const duration = formatDuration(
intervalToDuration({
start: new Date(),
end: enactmentDatetime,
}),
{
format: ['days', 'hours'],
}
);
const getMessageVariables = (proposal: ProposalFragment) => {
const enactmentDatetime =
proposal.terms && new Date(proposal.terms.enactmentDatetime);
const date = enactmentDatetime && format(enactmentDatetime, 'dd MMMM');
const duration =
enactmentDatetime &&
formatDuration(
intervalToDuration({
start: new Date(),
end: enactmentDatetime,
}),
{
format: ['days', 'hours'],
}
);
const price =
proposal.terms.change.__typename === 'UpdateMarketState'
proposal.terms?.change.__typename === 'UpdateMarketState'
? proposal.terms.change.price
: '';
return {
@@ -1,10 +1,10 @@
import {
useMarketProposals,
type MarketViewProposalFieldsFragment,
type ProposalFragment,
} from '@vegaprotocol/proposals';
import { ProposalState, ProposalType } from '@vegaprotocol/types';
const isPending = (p: MarketViewProposalFieldsFragment) => {
const isPending = (p: ProposalFragment) => {
return [ProposalState.STATE_OPEN, ProposalState.STATE_PASSED].includes(
p.state
);
@@ -21,9 +21,10 @@ export const useUpdateMarketStateProposals = (
const proposals = data
? data.filter(isPending).filter((p) => {
const change = p.terms.change;
const change = p.terms?.change;
if (
change &&
change.__typename === 'UpdateMarketState' &&
change.market.id === marketId
) {
@@ -48,8 +49,9 @@ export const useUpdateMarketProposals = (
const proposals = data
? data.filter(isPending).filter((p) => {
const change = p.terms.change;
const change = p.terms?.change;
if (
change &&
change.__typename === 'UpdateMarket' &&
change.marketId === marketId
) {
@@ -73,8 +75,9 @@ export const useSuccessorMarketProposals = (
const proposals = data
? data.filter(isPending).filter((p) => {
const change = p.terms.change;
const change = p.terms?.change;
if (
change &&
change.__typename === 'NewMarket' &&
change.successorConfiguration?.parentMarketId === marketId
) {
@@ -12,6 +12,7 @@ import { useT } from '../../lib/use-t';
import classNames from 'classnames';
import { MarketHeaderStats } from '../../client-pages/market/market-header-stats';
import { MarketMarkPrice } from '../market-mark-price';
import { MarketBanner } from '../market-banner';
/**
* This is only rendered for the mobile navigation
*/
@@ -108,8 +109,11 @@ export const MobileMarketHeader = () => {
}
>
{data && (
<div className="px-3 py-6 text-sm grid grid-cols-2 items-center gap-x-4 gap-y-6">
<MarketHeaderStats market={data} />
<div>
<MarketBanner market={data} />
<div className="px-3 py-6 text-sm grid grid-cols-2 items-center gap-x-4 gap-y-6">
<MarketHeaderStats market={data} />
</div>
</div>
)}
</FullScreenPopover>
@@ -24,6 +24,7 @@ import {
type DispatchStrategy,
IndividualScopeMapping,
IndividualScopeDescriptionMapping,
type Asset,
} from '@vegaprotocol/types';
import { Card } from '../card/card';
import { type ReactNode, useState } from 'react';
@@ -200,7 +201,8 @@ export const ActiveRewardCard = ({
transferNode.transfer.asset?.decimals || 0,
6
)}
rewardAsset={transferNode.asset}
rewardAsset={transferNode.dispatchAsset}
transferAsset={transferNode.transfer.asset || undefined}
endsIn={
transferNode.transfer.kind.endEpoch != null
? transferNode.transfer.kind.endEpoch - currentEpoch
@@ -216,6 +218,8 @@ const RewardCard = ({
colour,
rewardAmount,
rewardAsset,
transferAsset,
vegaAsset,
dispatchStrategy,
endsIn,
dispatchMetricInfo,
@@ -224,12 +228,14 @@ const RewardCard = ({
rewardAmount: string;
/** The asset linked to the dispatch strategy via `dispatchMetricAssetId` property. */
rewardAsset?: BasicAssetDetails;
/** The VEGA asset details, required to format the min staking amount. */
transferAsset?: Asset | undefined;
/** The VEGA asset details, required to format the min staking amount. */
vegaAsset?: BasicAssetDetails;
/** The transfer's dispatch strategy. */
dispatchStrategy: DispatchStrategy;
/** The number of epochs until the transfer stops. */
endsIn?: number;
/** The VEGA asset details, required to format the min staking amount. */
vegaAsset?: BasicAssetDetails;
dispatchMetricInfo?: ReactNode;
}) => {
const t = useT();
@@ -269,7 +275,9 @@ const RewardCard = ({
{rewardAmount}
</span>
<span className="font-alpha">{rewardAsset?.symbol || ''}</span>
<span className="font-alpha" data-testid="reward-asset">
{transferAsset?.symbol || ''}
</span>
</h3>
{/** DISTRIBUTION STRATEGY */}
@@ -357,6 +365,7 @@ const RewardCard = ({
<RewardRequirements
dispatchStrategy={dispatchStrategy}
rewardAsset={rewardAsset}
vegaAsset={vegaAsset}
/>
)}
</div>
@@ -379,8 +388,8 @@ export const DispatchMetricInfo = ({
let additionalDispatchMetricInfo = null;
// if asset found then display asset symbol
if (reward.asset) {
additionalDispatchMetricInfo = <span>{reward.asset.symbol}</span>;
if (reward.dispatchAsset) {
additionalDispatchMetricInfo = <span>{reward.dispatchAsset.symbol}</span>;
}
// but if scoped to only one market then display market name
if (marketNames.length === 1) {
+1 -1
View File
@@ -1,3 +1,3 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
VEGA_VERSION=v0.74.3
VEGA_VERSION=v0.74.6
LOCAL_SERVER=false
+1 -1
View File
@@ -1,3 +1,3 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:develop
VEGA_VERSION=v0.74.3
VEGA_VERSION=v0.74.6
LOCAL_SERVER=false
+155 -154
View File
@@ -341,135 +341,135 @@ test = ["objgraph", "psutil"]
[[package]]
name = "grpcio"
version = "1.60.1"
version = "1.62.0"
description = "HTTP/2-based RPC framework"
optional = false
python-versions = ">=3.7"
files = [
{file = "grpcio-1.60.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:14e8f2c84c0832773fb3958240c69def72357bc11392571f87b2d7b91e0bb092"},
{file = "grpcio-1.60.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:33aed0a431f5befeffd9d346b0fa44b2c01aa4aeae5ea5b2c03d3e25e0071216"},
{file = "grpcio-1.60.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:fead980fbc68512dfd4e0c7b1f5754c2a8e5015a04dea454b9cada54a8423525"},
{file = "grpcio-1.60.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:082081e6a36b6eb5cf0fd9a897fe777dbb3802176ffd08e3ec6567edd85bc104"},
{file = "grpcio-1.60.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55ccb7db5a665079d68b5c7c86359ebd5ebf31a19bc1a91c982fd622f1e31ff2"},
{file = "grpcio-1.60.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9b54577032d4f235452f77a83169b6527bf4b77d73aeada97d45b2aaf1bf5ce0"},
{file = "grpcio-1.60.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7d142bcd604166417929b071cd396aa13c565749a4c840d6c702727a59d835eb"},
{file = "grpcio-1.60.1-cp310-cp310-win32.whl", hash = "sha256:2a6087f234cb570008a6041c8ffd1b7d657b397fdd6d26e83d72283dae3527b1"},
{file = "grpcio-1.60.1-cp310-cp310-win_amd64.whl", hash = "sha256:f2212796593ad1d0235068c79836861f2201fc7137a99aa2fea7beeb3b101177"},
{file = "grpcio-1.60.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:79ae0dc785504cb1e1788758c588c711f4e4a0195d70dff53db203c95a0bd303"},
{file = "grpcio-1.60.1-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:4eec8b8c1c2c9b7125508ff7c89d5701bf933c99d3910e446ed531cd16ad5d87"},
{file = "grpcio-1.60.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:8c9554ca8e26241dabe7951aa1fa03a1ba0856688ecd7e7bdbdd286ebc272e4c"},
{file = "grpcio-1.60.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91422ba785a8e7a18725b1dc40fbd88f08a5bb4c7f1b3e8739cab24b04fa8a03"},
{file = "grpcio-1.60.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cba6209c96828711cb7c8fcb45ecef8c8859238baf15119daa1bef0f6c84bfe7"},
{file = "grpcio-1.60.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c71be3f86d67d8d1311c6076a4ba3b75ba5703c0b856b4e691c9097f9b1e8bd2"},
{file = "grpcio-1.60.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af5ef6cfaf0d023c00002ba25d0751e5995fa0e4c9eec6cd263c30352662cbce"},
{file = "grpcio-1.60.1-cp311-cp311-win32.whl", hash = "sha256:a09506eb48fa5493c58f946c46754ef22f3ec0df64f2b5149373ff31fb67f3dd"},
{file = "grpcio-1.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:49c9b6a510e3ed8df5f6f4f3c34d7fbf2d2cae048ee90a45cd7415abab72912c"},
{file = "grpcio-1.60.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:b58b855d0071575ea9c7bc0d84a06d2edfbfccec52e9657864386381a7ce1ae9"},
{file = "grpcio-1.60.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:a731ac5cffc34dac62053e0da90f0c0b8560396a19f69d9703e88240c8f05858"},
{file = "grpcio-1.60.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:cf77f8cf2a651fbd869fbdcb4a1931464189cd210abc4cfad357f1cacc8642a6"},
{file = "grpcio-1.60.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c557e94e91a983e5b1e9c60076a8fd79fea1e7e06848eb2e48d0ccfb30f6e073"},
{file = "grpcio-1.60.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:069fe2aeee02dfd2135d562d0663fe70fbb69d5eed6eb3389042a7e963b54de8"},
{file = "grpcio-1.60.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb0af13433dbbd1c806e671d81ec75bd324af6ef75171fd7815ca3074fe32bfe"},
{file = "grpcio-1.60.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2f44c32aef186bbba254129cea1df08a20be414144ac3bdf0e84b24e3f3b2e05"},
{file = "grpcio-1.60.1-cp312-cp312-win32.whl", hash = "sha256:a212e5dea1a4182e40cd3e4067ee46be9d10418092ce3627475e995cca95de21"},
{file = "grpcio-1.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:6e490fa5f7f5326222cb9f0b78f207a2b218a14edf39602e083d5f617354306f"},
{file = "grpcio-1.60.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:4216e67ad9a4769117433814956031cb300f85edc855252a645a9a724b3b6594"},
{file = "grpcio-1.60.1-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:73e14acd3d4247169955fae8fb103a2b900cfad21d0c35f0dcd0fdd54cd60367"},
{file = "grpcio-1.60.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:6ecf21d20d02d1733e9c820fb5c114c749d888704a7ec824b545c12e78734d1c"},
{file = "grpcio-1.60.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33bdea30dcfd4f87b045d404388469eb48a48c33a6195a043d116ed1b9a0196c"},
{file = "grpcio-1.60.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53b69e79d00f78c81eecfb38f4516080dc7f36a198b6b37b928f1c13b3c063e9"},
{file = "grpcio-1.60.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:39aa848794b887120b1d35b1b994e445cc028ff602ef267f87c38122c1add50d"},
{file = "grpcio-1.60.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:72153a0d2e425f45b884540a61c6639436ddafa1829a42056aa5764b84108b8e"},
{file = "grpcio-1.60.1-cp37-cp37m-win_amd64.whl", hash = "sha256:50d56280b482875d1f9128ce596e59031a226a8b84bec88cb2bf76c289f5d0de"},
{file = "grpcio-1.60.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:6d140bdeb26cad8b93c1455fa00573c05592793c32053d6e0016ce05ba267549"},
{file = "grpcio-1.60.1-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:bc808924470643b82b14fe121923c30ec211d8c693e747eba8a7414bc4351a23"},
{file = "grpcio-1.60.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:70c83bb530572917be20c21f3b6be92cd86b9aecb44b0c18b1d3b2cc3ae47df0"},
{file = "grpcio-1.60.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b106bc52e7f28170e624ba61cc7dc6829566e535a6ec68528f8e1afbed1c41f"},
{file = "grpcio-1.60.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30e980cd6db1088c144b92fe376747328d5554bc7960ce583ec7b7d81cd47287"},
{file = "grpcio-1.60.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0c5807e9152eff15f1d48f6b9ad3749196f79a4a050469d99eecb679be592acc"},
{file = "grpcio-1.60.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f1c3dc536b3ee124e8b24feb7533e5c70b9f2ef833e3b2e5513b2897fd46763a"},
{file = "grpcio-1.60.1-cp38-cp38-win32.whl", hash = "sha256:d7404cebcdb11bb5bd40bf94131faf7e9a7c10a6c60358580fe83913f360f929"},
{file = "grpcio-1.60.1-cp38-cp38-win_amd64.whl", hash = "sha256:c8754c75f55781515a3005063d9a05878b2cfb3cb7e41d5401ad0cf19de14872"},
{file = "grpcio-1.60.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:0250a7a70b14000fa311de04b169cc7480be6c1a769b190769d347939d3232a8"},
{file = "grpcio-1.60.1-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:660fc6b9c2a9ea3bb2a7e64ba878c98339abaf1811edca904ac85e9e662f1d73"},
{file = "grpcio-1.60.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:76eaaba891083fcbe167aa0f03363311a9f12da975b025d30e94b93ac7a765fc"},
{file = "grpcio-1.60.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d97c65ea7e097056f3d1ead77040ebc236feaf7f71489383d20f3b4c28412a"},
{file = "grpcio-1.60.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb2a2911b028f01c8c64d126f6b632fcd8a9ac975aa1b3855766c94e4107180"},
{file = "grpcio-1.60.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:5a1ebbae7e2214f51b1f23b57bf98eeed2cf1ba84e4d523c48c36d5b2f8829ff"},
{file = "grpcio-1.60.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a66f4d2a005bc78e61d805ed95dedfcb35efa84b7bba0403c6d60d13a3de2d6"},
{file = "grpcio-1.60.1-cp39-cp39-win32.whl", hash = "sha256:8d488fbdbf04283f0d20742b64968d44825617aa6717b07c006168ed16488804"},
{file = "grpcio-1.60.1-cp39-cp39-win_amd64.whl", hash = "sha256:61b7199cd2a55e62e45bfb629a35b71fc2c0cb88f686a047f25b1112d3810904"},
{file = "grpcio-1.60.1.tar.gz", hash = "sha256:dd1d3a8d1d2e50ad9b59e10aa7f07c7d1be2b367f3f2d33c5fade96ed5460962"},
{file = "grpcio-1.62.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:136ffd79791b1eddda8d827b607a6285474ff8a1a5735c4947b58c481e5e4271"},
{file = "grpcio-1.62.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:d6a56ba703be6b6267bf19423d888600c3f574ac7c2cc5e6220af90662a4d6b0"},
{file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:4cd356211579043fce9f52acc861e519316fff93980a212c8109cca8f47366b6"},
{file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e803e9b58d8f9b4ff0ea991611a8d51b31c68d2e24572cd1fe85e99e8cc1b4f8"},
{file = "grpcio-1.62.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4c04fe33039b35b97c02d2901a164bbbb2f21fb9c4e2a45a959f0b044c3512c"},
{file = "grpcio-1.62.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:95370c71b8c9062f9ea033a0867c4c73d6f0ff35113ebd2618171ec1f1e903e0"},
{file = "grpcio-1.62.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c912688acc05e4ff012c8891803659d6a8a8b5106f0f66e0aed3fb7e77898fa6"},
{file = "grpcio-1.62.0-cp310-cp310-win32.whl", hash = "sha256:821a44bd63d0f04e33cf4ddf33c14cae176346486b0df08b41a6132b976de5fc"},
{file = "grpcio-1.62.0-cp310-cp310-win_amd64.whl", hash = "sha256:81531632f93fece32b2762247c4c169021177e58e725494f9a746ca62c83acaa"},
{file = "grpcio-1.62.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:3fa15850a6aba230eed06b236287c50d65a98f05054a0f01ccedf8e1cc89d57f"},
{file = "grpcio-1.62.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:36df33080cd7897623feff57831eb83c98b84640b016ce443305977fac7566fb"},
{file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:7a195531828b46ea9c4623c47e1dc45650fc7206f8a71825898dd4c9004b0928"},
{file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab140a3542bbcea37162bdfc12ce0d47a3cda3f2d91b752a124cc9fe6776a9e2"},
{file = "grpcio-1.62.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f9d6c3223914abb51ac564dc9c3782d23ca445d2864321b9059d62d47144021"},
{file = "grpcio-1.62.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fbe0c20ce9a1cff75cfb828b21f08d0a1ca527b67f2443174af6626798a754a4"},
{file = "grpcio-1.62.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38f69de9c28c1e7a8fd24e4af4264726637b72f27c2099eaea6e513e7142b47e"},
{file = "grpcio-1.62.0-cp311-cp311-win32.whl", hash = "sha256:ce1aafdf8d3f58cb67664f42a617af0e34555fe955450d42c19e4a6ad41c84bd"},
{file = "grpcio-1.62.0-cp311-cp311-win_amd64.whl", hash = "sha256:eef1d16ac26c5325e7d39f5452ea98d6988c700c427c52cbc7ce3201e6d93334"},
{file = "grpcio-1.62.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:8aab8f90b2a41208c0a071ec39a6e5dbba16fd827455aaa070fec241624ccef8"},
{file = "grpcio-1.62.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:62aa1659d8b6aad7329ede5d5b077e3d71bf488d85795db517118c390358d5f6"},
{file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:0d7ae7fc7dbbf2d78d6323641ded767d9ec6d121aaf931ec4a5c50797b886532"},
{file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f359d635ee9428f0294bea062bb60c478a8ddc44b0b6f8e1f42997e5dc12e2ee"},
{file = "grpcio-1.62.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d48e5b1f8f4204889f1acf30bb57c30378e17c8d20df5acbe8029e985f735c"},
{file = "grpcio-1.62.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:662d3df5314ecde3184cf87ddd2c3a66095b3acbb2d57a8cada571747af03873"},
{file = "grpcio-1.62.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92cdb616be44c8ac23a57cce0243af0137a10aa82234f23cd46e69e115071388"},
{file = "grpcio-1.62.0-cp312-cp312-win32.whl", hash = "sha256:0b9179478b09ee22f4a36b40ca87ad43376acdccc816ce7c2193a9061bf35701"},
{file = "grpcio-1.62.0-cp312-cp312-win_amd64.whl", hash = "sha256:614c3ed234208e76991992342bab725f379cc81c7dd5035ee1de2f7e3f7a9842"},
{file = "grpcio-1.62.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:7e1f51e2a460b7394670fdb615e26d31d3260015154ea4f1501a45047abe06c9"},
{file = "grpcio-1.62.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:bcff647e7fe25495e7719f779cc219bbb90b9e79fbd1ce5bda6aae2567f469f2"},
{file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:56ca7ba0b51ed0de1646f1735154143dcbdf9ec2dbe8cc6645def299bb527ca1"},
{file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e84bfb2a734e4a234b116be208d6f0214e68dcf7804306f97962f93c22a1839"},
{file = "grpcio-1.62.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c1488b31a521fbba50ae86423f5306668d6f3a46d124f7819c603979fc538c4"},
{file = "grpcio-1.62.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:98d8f4eb91f1ce0735bf0b67c3b2a4fea68b52b2fd13dc4318583181f9219b4b"},
{file = "grpcio-1.62.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b3d3d755cfa331d6090e13aac276d4a3fb828bf935449dc16c3d554bf366136b"},
{file = "grpcio-1.62.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a33f2bfd8a58a02aab93f94f6c61279be0f48f99fcca20ebaee67576cd57307b"},
{file = "grpcio-1.62.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:5e709f7c8028ce0443bddc290fb9c967c1e0e9159ef7a030e8c21cac1feabd35"},
{file = "grpcio-1.62.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:2f3d9a4d0abb57e5f49ed5039d3ed375826c2635751ab89dcc25932ff683bbb6"},
{file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:62ccb92f594d3d9fcd00064b149a0187c246b11e46ff1b7935191f169227f04c"},
{file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:921148f57c2e4b076af59a815467d399b7447f6e0ee10ef6d2601eb1e9c7f402"},
{file = "grpcio-1.62.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f897b16190b46bc4d4aaf0a32a4b819d559a37a756d7c6b571e9562c360eed72"},
{file = "grpcio-1.62.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1bc8449084fe395575ed24809752e1dc4592bb70900a03ca42bf236ed5bf008f"},
{file = "grpcio-1.62.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81d444e5e182be4c7856cd33a610154fe9ea1726bd071d07e7ba13fafd202e38"},
{file = "grpcio-1.62.0-cp38-cp38-win32.whl", hash = "sha256:88f41f33da3840b4a9bbec68079096d4caf629e2c6ed3a72112159d570d98ebe"},
{file = "grpcio-1.62.0-cp38-cp38-win_amd64.whl", hash = "sha256:fc2836cb829895ee190813446dce63df67e6ed7b9bf76060262c55fcd097d270"},
{file = "grpcio-1.62.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:fcc98cff4084467839d0a20d16abc2a76005f3d1b38062464d088c07f500d170"},
{file = "grpcio-1.62.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:0d3dee701e48ee76b7d6fbbba18ba8bc142e5b231ef7d3d97065204702224e0e"},
{file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:b7a6be562dd18e5d5bec146ae9537f20ae1253beb971c0164f1e8a2f5a27e829"},
{file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29cb592c4ce64a023712875368bcae13938c7f03e99f080407e20ffe0a9aa33b"},
{file = "grpcio-1.62.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eda79574aec8ec4d00768dcb07daba60ed08ef32583b62b90bbf274b3c279f7"},
{file = "grpcio-1.62.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7eea57444a354ee217fda23f4b479a4cdfea35fb918ca0d8a0e73c271e52c09c"},
{file = "grpcio-1.62.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0e97f37a3b7c89f9125b92d22e9c8323f4e76e7993ba7049b9f4ccbe8bae958a"},
{file = "grpcio-1.62.0-cp39-cp39-win32.whl", hash = "sha256:39cd45bd82a2e510e591ca2ddbe22352e8413378852ae814549c162cf3992a93"},
{file = "grpcio-1.62.0-cp39-cp39-win_amd64.whl", hash = "sha256:b71c65427bf0ec6a8b48c68c17356cb9fbfc96b1130d20a07cb462f4e4dcdcd5"},
{file = "grpcio-1.62.0.tar.gz", hash = "sha256:748496af9238ac78dcd98cce65421f1adce28c3979393e3609683fcd7f3880d7"},
]
[package.extras]
protobuf = ["grpcio-tools (>=1.60.1)"]
protobuf = ["grpcio-tools (>=1.62.0)"]
[[package]]
name = "grpcio-tools"
version = "1.60.1"
version = "1.62.0"
description = "Protobuf code generator for gRPC"
optional = false
python-versions = ">=3.7"
files = [
{file = "grpcio-tools-1.60.1.tar.gz", hash = "sha256:da08224ab8675c6d464b988bd8ca02cccd2bf0275bceefe8f6219bfd4a4f5e85"},
{file = "grpcio_tools-1.60.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:184b27333b627a7cc0972fb70d21a8bb7c02ac4a6febc16768d78ea8ff883ddd"},
{file = "grpcio_tools-1.60.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:18d7737f29ef5bbe3352547d0eccd080807834f00df223867dfc860bf81e9180"},
{file = "grpcio_tools-1.60.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:cc8ba358d2c658c6ecbc58e779bf0fc5a673fecac015a70db27fc5b4d37b76b6"},
{file = "grpcio_tools-1.60.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2973f75e8ba5c551033a1d59cc97654f6f386deaf2559082011d245d7ed87bba"},
{file = "grpcio_tools-1.60.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28ae665113affebdd109247386786e5ab4dccfcfad1b5f68e9cce2e326b57ee6"},
{file = "grpcio_tools-1.60.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5c7ed086fef5ff59f46d53a052b1934b73e0f7d12365d656d6af3a88057d5a3e"},
{file = "grpcio_tools-1.60.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8540f6480428a52614db71dd6394f52cbc0d2565b5ea1136a982f26390a42c7a"},
{file = "grpcio_tools-1.60.1-cp310-cp310-win32.whl", hash = "sha256:5b4a939097005531edec331f22d0b82bff26e71ede009354d2f375b5d41e74f0"},
{file = "grpcio_tools-1.60.1-cp310-cp310-win_amd64.whl", hash = "sha256:075bb67895970f96aabc1761ca674bf4db193f8fcad387f08e50402023b5f953"},
{file = "grpcio_tools-1.60.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:284749d20fb22418f17d3d351b9eb838caf4a0393a9cb02c36e5c32fa4bbe9db"},
{file = "grpcio_tools-1.60.1-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:b1041377cf32ee2338284ee26e6b9c10f9ea7728092376b19803dcb9b91d510d"},
{file = "grpcio_tools-1.60.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:e529cd3d4109a6f4a3f7bdaca68946eb33734e2d7ffe861785a0586abe99ee67"},
{file = "grpcio_tools-1.60.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31294b534f25f02ead204e58dcbe0e5437a95a1a6f276bb9378905595b02ff6d"},
{file = "grpcio_tools-1.60.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fb6f4d2df0388c35c2804ba170f511238a681b679ead013bfe5e39d0ea9cf48"},
{file = "grpcio_tools-1.60.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:40cd8268a675269ce59c4fa50877597ec638bb1099c52237bb726c8ac9791868"},
{file = "grpcio_tools-1.60.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:985ac476da365267a2367ab20060f9096fbfc2e190fb02dd394f9ec05edf03ca"},
{file = "grpcio_tools-1.60.1-cp311-cp311-win32.whl", hash = "sha256:bd85f6c368b93ae45edf8568473053cb1cc075ef3489efb18f9832d4ecce062f"},
{file = "grpcio_tools-1.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:c20e752ff5057758845f4e5c7a298739bfba291f373ed18ea9c7c7acbe69e8ab"},
{file = "grpcio_tools-1.60.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:aafc94616c5f89c891d859057b194a153c451f9921053454e9d7d4cbf79047eb"},
{file = "grpcio_tools-1.60.1-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:9bba347000f57dae8aea79c0d76ef7d72895597524d30d0170c7d1974a3a03f3"},
{file = "grpcio_tools-1.60.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:1e96a532d38411f0543fe1903ff522f7142a9901afb0ed94de58d79caf1905be"},
{file = "grpcio_tools-1.60.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ea6e397d87f458bb2c387a4a6e1b65df74ce5b5194a1f16850c38309012e981"},
{file = "grpcio_tools-1.60.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aeecd5b8faa2aab67e6c8b8a57e888c00ce70d39f331ede0a21312e92def1a6"},
{file = "grpcio_tools-1.60.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d2c26ce5f774c98bd2d3d8d1703048394018b55d297ebdb41ed2ba35b9a34f68"},
{file = "grpcio_tools-1.60.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:214281cdafb7acfdcde848eca2de7c888a6e2b5cd25ab579712b965ea09a9cd4"},
{file = "grpcio_tools-1.60.1-cp312-cp312-win32.whl", hash = "sha256:8c4b917aa4fcdc77990773063f0f14540aab8d4a8bf6c862b964a45d891a31d2"},
{file = "grpcio_tools-1.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:0aa34c7c21cff2177a4096b2b0d51dfbc9f8a41f929847a434e89b352c5a215d"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-linux_armv7l.whl", hash = "sha256:acdba77584981fe799104aa545d9d97910bcf88c69b668b768c1f3e7d7e5afac"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:2a7fa55bc62d4b8ebe6fb26f8cf89df3cf3b504eb6c5f3a2f0174689d35fddb0"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:dffa326cf901fe08a0e218d9fdf593f12276088a8caa07fcbec7d051149cf9ef"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf945bd22f396c0d0c691e0990db2bfc4e77816b1edc2aea8a69c35ae721aac9"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6801cfc5a85f0fb6fd12cade45942aaa1c814422328d594d12d364815fe34123"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f95bdc6c7c50b7fc442e53537bc5b4eb8cab2a671c1da80d40b5a4ab1fd5d416"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:402efeec36d8b12b792bae8a900085416fc2f57a34b599445ace2e847b6b0d75"},
{file = "grpcio_tools-1.60.1-cp37-cp37m-win_amd64.whl", hash = "sha256:af88a2062b9c35034a80b25f289034b9c3c00c42bb88efaa465503a06fbd6a87"},
{file = "grpcio_tools-1.60.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:46b495bae31c5d3f6ac0240eb848f0642b5410f80dff2aacdea20cdea3938c1d"},
{file = "grpcio_tools-1.60.1-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:b5ae375207af9aa82f516dcd513d2e0c83690b7788d45844daad846ed87550f8"},
{file = "grpcio_tools-1.60.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:15f13e8f3d77b96adcb1e3615acec5b100bd836c6010c58a51465bcb9c06d128"},
{file = "grpcio_tools-1.60.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c354505e6a3d170da374f20404ea6a78135502df4f5534e5c532bdf24c4cc2a5"},
{file = "grpcio_tools-1.60.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8cfab27ba2bd36a3e3b522aed686133531e8b919703d0247a0885dae8815317"},
{file = "grpcio_tools-1.60.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b6ef213cb0aecb2832ee82a2eac32f29f31f50b17ce020604d82205096a6bd0c"},
{file = "grpcio_tools-1.60.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0b62cb2d43a7f0eacc6a6962dfff7c2564874012e1a72ae4167e762f449e2912"},
{file = "grpcio_tools-1.60.1-cp38-cp38-win32.whl", hash = "sha256:3fcabf484720a9fa1690e2825fc940027a05a0c79a1075a730008ef634bd8ad2"},
{file = "grpcio_tools-1.60.1-cp38-cp38-win_amd64.whl", hash = "sha256:22ce3e3d861321d208d8bfd6161ab976623520b179712c90b2c175151463a6b1"},
{file = "grpcio_tools-1.60.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:4e66fe204da15e08e599adb3060109a42927c0868fe8933e2d341ea649eceb03"},
{file = "grpcio_tools-1.60.1-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:c1047bd831de5d9da761e9dc246988d5f07d722186938dfd5f34807398101010"},
{file = "grpcio_tools-1.60.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:eba5fafd70585fbd4cb6ae45e3c5e11d8598e2426c9f289b78f682c0606e81cb"},
{file = "grpcio_tools-1.60.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bba7230c60238c7a4ffa29f1aff6d78edb41f2c79cbe4443406472b1c80ccb5d"},
{file = "grpcio_tools-1.60.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2bb8efc2cd64bd8f2779b426dd7e94e60924078ba5150cbbb60a846e62d1ed2"},
{file = "grpcio_tools-1.60.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:26f91161a91f1601777751230eaaafdf416fed08a15c3ba2ae391088e4a906c6"},
{file = "grpcio_tools-1.60.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2c19be2bba5583e30f88bb5d71b430176c396f0d6d0db3785e5845bfa3d28cd2"},
{file = "grpcio_tools-1.60.1-cp39-cp39-win32.whl", hash = "sha256:9aadc9c00baa2064baa4414cff7c269455449f14805a355226674d89c507342c"},
{file = "grpcio_tools-1.60.1-cp39-cp39-win_amd64.whl", hash = "sha256:652b08c9fef39186ce4f97f05f5440c0ed41f117db0f7d6cb0e0d75dbc6afd3f"},
{file = "grpcio-tools-1.62.0.tar.gz", hash = "sha256:7fca6ecfbbf0549058bb29dcc6e435d885b878d07701e77ac58e1e1f591736dc"},
{file = "grpcio_tools-1.62.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:465c51ebaa184ee3bb619cd5bfaf562bbdde166f2822a6935461e6a741f5ac19"},
{file = "grpcio_tools-1.62.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:0d9c9a4832f52c4597d6dc12d9ab3109c3bd0ee1686b8bf6d64f9eab4145e3cb"},
{file = "grpcio_tools-1.62.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:5a482d9625209023481e631c29a6df1392bfc49f9accfa880dabbacff642559a"},
{file = "grpcio_tools-1.62.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74196beed18383d53ff3e2412a6c1eefa3ff109e987be240368496bc3dcabc8b"},
{file = "grpcio_tools-1.62.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75aca28cbeb605c59b5689a7e000fbc2bd659d2f322c58461f3912f00069f6da"},
{file = "grpcio_tools-1.62.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:523adf731fa4c5af0bf7ee2edb65e8c7ef4d9df9951461d6a18fe096688efd2d"},
{file = "grpcio_tools-1.62.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:791aa220f8f1936e65bc079e9eb954fa0202a1f16e28b83956e59d17dface127"},
{file = "grpcio_tools-1.62.0-cp310-cp310-win32.whl", hash = "sha256:5dacc691b18d2c294ea971720ff980a1e2d68a3f7ddcd2f0670b3204e81c4b18"},
{file = "grpcio_tools-1.62.0-cp310-cp310-win_amd64.whl", hash = "sha256:6999a4e705b03aacad46e625feb7610e47ec88dbd51220c2282b6334f90721fc"},
{file = "grpcio_tools-1.62.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:19b74e141937c885c9e56b6a7dfa190ca7d583bd48bce9171dd65bbf108b9271"},
{file = "grpcio_tools-1.62.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:17c16e9a89c0b9f4ff2b143f232c5256383453ce7b55fe981598f9517adc8252"},
{file = "grpcio_tools-1.62.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:3730b1cd998a0cffc817602cc55e51f268fa97b3e38fa4bee578e3741474547a"},
{file = "grpcio_tools-1.62.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14201950513636f515dd455a06890e3a21d115b943cf6a8f5af67ad1413cfa1f"},
{file = "grpcio_tools-1.62.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74e0053360e0eadd75193c0c379b6d7f51d074ebbff856bd41780e1a028b38d"},
{file = "grpcio_tools-1.62.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d5959e3df126931d28cd94dd5f0a708b7dd96019de80ab715fb922fd0c8a838d"},
{file = "grpcio_tools-1.62.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1927934dfba4658a97c2dab267e53ed239264d40fdd5b295fc317693543db85b"},
{file = "grpcio_tools-1.62.0-cp311-cp311-win32.whl", hash = "sha256:2f5bd22203e64e1732e149bfdd3083716d038abca294e4e2852159b3d893f9ec"},
{file = "grpcio_tools-1.62.0-cp311-cp311-win_amd64.whl", hash = "sha256:cd1f4caeca614b04db803566473f7db0971e7a88268f95e4a529b0ace699b949"},
{file = "grpcio_tools-1.62.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f0884eaf6a2bbd7b03fea456e808909ee48dd4f7f455519d67defda791116368"},
{file = "grpcio_tools-1.62.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:6b900ae319b6f9ac1be0ca572dfb41c23a7ff6fcbf36e3be6d3054e1e4c60de6"},
{file = "grpcio_tools-1.62.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:3bbe79b134dfb7c98cf60e4962e31039bef824834cc7034bdf1886a2ed1097f9"},
{file = "grpcio_tools-1.62.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77196c7ac8741d4a2aebb023bcc2964ac65ca44180fd791640889ab2afed3e47"},
{file = "grpcio_tools-1.62.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b65288ebe12e38dd3650fea65d82fcce0d35df1ae4a770b525c10119ee71962f"},
{file = "grpcio_tools-1.62.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52b216c458458f6c292e12428916e80974c5113abc505a61e7b0b9f8932a785d"},
{file = "grpcio_tools-1.62.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:88aa62303278aec45bbb26bf679269c7890346c37140ae30e39da1070c341e11"},
{file = "grpcio_tools-1.62.0-cp312-cp312-win32.whl", hash = "sha256:bb6802d63e42734d2baf02e1343377fe18590ed6a1f5ffbdebbbe0f8331f176b"},
{file = "grpcio_tools-1.62.0-cp312-cp312-win_amd64.whl", hash = "sha256:d5652d3a52a2e8e1d9bdf28fbd15e21b166e31b968cd7c8c604bf31611c0bb5b"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:84e27206bd884be83a7fdcef8be3c90eb1591341c0ba9b0d25ec9db1043ba2f2"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:5eb63d9207b02a0fa30216907e1e7705cc2670f933e77236c6e0eb966ad3b4bf"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:95e49839d49e79187c43cd63af5c206dc5743a01d7d3d2f039772fa743cbb30c"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ae5cd2f89e33a529790bf8aa59a459484edb05e4f58d4cf78836b9dfa1fab43"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e1fd7301d762bf5984b7e7fb62fce82cff864d75f0a57e15cfd07ae1bd79133"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e38d5800151e6804d500e329f7ddfb615c50eee0c1607593e3147a4b21037e40"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:563a75924109e75809b2919e68d7e6ae7872e63d20258aae7899b14f6ff9e18b"},
{file = "grpcio_tools-1.62.0-cp37-cp37m-win_amd64.whl", hash = "sha256:5f8934715577c9cc0c792b8a77f7d0dd2bb60e951161b10c5f46b60856673240"},
{file = "grpcio_tools-1.62.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:ed6cf7ff4a10c46f85340f9c68982f9efb29f51ee4b66828310fcdf3c2d7ffd1"},
{file = "grpcio_tools-1.62.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:1faa5006fe9e7b9e65c47bc23f7cd333fdcdd4ba35d44080303848266db5ab05"},
{file = "grpcio_tools-1.62.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:3b526dc5566161a3a17599753838b9cfbdd4cb15b6ad419aae8a5d12053fa8ae"},
{file = "grpcio_tools-1.62.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09db3688efd3499ce3c0b02c0bac0656abdab4cb99716f81ad879c08b92c56e"},
{file = "grpcio_tools-1.62.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:006ea0cc16e8bf8f307326e0556e1384f24abb402cc4e6a720aa1dfe8f268647"},
{file = "grpcio_tools-1.62.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b46ba0b6552b4375ede65e0c89491af532635347f78d52a72f8a027529e713ed"},
{file = "grpcio_tools-1.62.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ec6f561c86fe13cff3be16f297cc05e1aa1274294524743a4cf91d971866fbb0"},
{file = "grpcio_tools-1.62.0-cp38-cp38-win32.whl", hash = "sha256:c85391e06620d6e16a56341caae5007d0c6219beba065e1e288f2523fba6a335"},
{file = "grpcio_tools-1.62.0-cp38-cp38-win_amd64.whl", hash = "sha256:679cf2507090e010da73e5001665c76de2a5927b2e2110e459222b1c81cb10c2"},
{file = "grpcio_tools-1.62.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:0e87f105f1d152934759f8975ed002d5ce057b3cdf1cc6cb63fe6008671a27b9"},
{file = "grpcio_tools-1.62.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:bf9f281f528e0220558d57e09b4518dec148dcb250d78bd9cbb27e09edabb3f9"},
{file = "grpcio_tools-1.62.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:711314cb4c6c8b3d51bafaee380ffa5012bd0567ed68f1b0b1fc07492b27acab"},
{file = "grpcio_tools-1.62.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54bb570bd963905de3bda596b35e06026552705edebbb2cb737b57aa5252b9e5"},
{file = "grpcio_tools-1.62.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dce5f04676cf94e6e2d13d7f91ac2de79097d86675bc4d404a3c24dcc0332c88"},
{file = "grpcio_tools-1.62.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:98ddf871c614cc0ed331c7159ebbbf5040be562279677d3bb97c2e6083539f72"},
{file = "grpcio_tools-1.62.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f3aaf3b20c0f7063856b2432335af8f76cf580f898e04085548cde28332d6833"},
{file = "grpcio_tools-1.62.0-cp39-cp39-win32.whl", hash = "sha256:3dee3be61d9032f777a9b4e2696ea3d0748a582cb99c672b5d41ca66821e8c87"},
{file = "grpcio_tools-1.62.0-cp39-cp39-win_amd64.whl", hash = "sha256:f54b5181784464bd3573ae7dbcf053da18a4b7a75fe19960791f383be3d035ca"},
]
[package.dependencies]
grpcio = ">=1.60.1"
grpcio = ">=1.62.0"
protobuf = ">=4.21.6,<5.0dev"
setuptools = "*"
@@ -564,40 +564,40 @@ files = [
[[package]]
name = "pandas"
version = "2.2.0"
version = "2.2.1"
description = "Powerful data structures for data analysis, time series, and statistics"
optional = false
python-versions = ">=3.9"
files = [
{file = "pandas-2.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8108ee1712bb4fa2c16981fba7e68b3f6ea330277f5ca34fa8d557e986a11670"},
{file = "pandas-2.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:736da9ad4033aeab51d067fc3bd69a0ba36f5a60f66a527b3d72e2030e63280a"},
{file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38e0b4fc3ddceb56ec8a287313bc22abe17ab0eb184069f08fc6a9352a769b18"},
{file = "pandas-2.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20404d2adefe92aed3b38da41d0847a143a09be982a31b85bc7dd565bdba0f4e"},
{file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7ea3ee3f125032bfcade3a4cf85131ed064b4f8dd23e5ce6fa16473e48ebcaf5"},
{file = "pandas-2.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9670b3ac00a387620489dfc1bca66db47a787f4e55911f1293063a78b108df1"},
{file = "pandas-2.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:5a946f210383c7e6d16312d30b238fd508d80d927014f3b33fb5b15c2f895430"},
{file = "pandas-2.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a1b438fa26b208005c997e78672f1aa8138f67002e833312e6230f3e57fa87d5"},
{file = "pandas-2.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8ce2fbc8d9bf303ce54a476116165220a1fedf15985b09656b4b4275300e920b"},
{file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2707514a7bec41a4ab81f2ccce8b382961a29fbe9492eab1305bb075b2b1ff4f"},
{file = "pandas-2.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85793cbdc2d5bc32620dc8ffa715423f0c680dacacf55056ba13454a5be5de88"},
{file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cfd6c2491dc821b10c716ad6776e7ab311f7df5d16038d0b7458bc0b67dc10f3"},
{file = "pandas-2.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a146b9dcacc3123aa2b399df1a284de5f46287a4ab4fbfc237eac98a92ebcb71"},
{file = "pandas-2.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbc1b53c0e1fdf16388c33c3cca160f798d38aea2978004dd3f4d3dec56454c9"},
{file = "pandas-2.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a41d06f308a024981dcaa6c41f2f2be46a6b186b902c94c2674e8cb5c42985bc"},
{file = "pandas-2.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:159205c99d7a5ce89ecfc37cb08ed179de7783737cea403b295b5eda8e9c56d1"},
{file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1e1f3861ea9132b32f2133788f3b14911b68102d562715d71bd0013bc45440"},
{file = "pandas-2.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:761cb99b42a69005dec2b08854fb1d4888fdf7b05db23a8c5a099e4b886a2106"},
{file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a20628faaf444da122b2a64b1e5360cde100ee6283ae8effa0d8745153809a2e"},
{file = "pandas-2.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f5be5d03ea2073627e7111f61b9f1f0d9625dc3c4d8dda72cc827b0c58a1d042"},
{file = "pandas-2.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:a626795722d893ed6aacb64d2401d017ddc8a2341b49e0384ab9bf7112bdec30"},
{file = "pandas-2.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9f66419d4a41132eb7e9a73dcec9486cf5019f52d90dd35547af11bc58f8637d"},
{file = "pandas-2.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:57abcaeda83fb80d447f28ab0cc7b32b13978f6f733875ebd1ed14f8fbc0f4ab"},
{file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e60f1f7dba3c2d5ca159e18c46a34e7ca7247a73b5dd1a22b6d59707ed6b899a"},
{file = "pandas-2.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb61dc8567b798b969bcc1fc964788f5a68214d333cade8319c7ab33e2b5d88a"},
{file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:52826b5f4ed658fa2b729264d63f6732b8b29949c7fd234510d57c61dbeadfcd"},
{file = "pandas-2.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bde2bc699dbd80d7bc7f9cab1e23a95c4375de615860ca089f34e7c64f4a8de7"},
{file = "pandas-2.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:3de918a754bbf2da2381e8a3dcc45eede8cd7775b047b923f9006d5f876802ae"},
{file = "pandas-2.2.0.tar.gz", hash = "sha256:30b83f7c3eb217fb4d1b494a57a2fda5444f17834f5df2de6b2ffff68dc3c8e2"},
{file = "pandas-2.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8df8612be9cd1c7797c93e1c5df861b2ddda0b48b08f2c3eaa0702cf88fb5f88"},
{file = "pandas-2.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0f573ab277252ed9aaf38240f3b54cfc90fff8e5cab70411ee1d03f5d51f3944"},
{file = "pandas-2.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f02a3a6c83df4026e55b63c1f06476c9aa3ed6af3d89b4f04ea656ccdaaaa359"},
{file = "pandas-2.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c38ce92cb22a4bea4e3929429aa1067a454dcc9c335799af93ba9be21b6beb51"},
{file = "pandas-2.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c2ce852e1cf2509a69e98358e8458775f89599566ac3775e70419b98615f4b06"},
{file = "pandas-2.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:53680dc9b2519cbf609c62db3ed7c0b499077c7fefda564e330286e619ff0dd9"},
{file = "pandas-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:94e714a1cca63e4f5939cdce5f29ba8d415d85166be3441165edd427dc9f6bc0"},
{file = "pandas-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f821213d48f4ab353d20ebc24e4faf94ba40d76680642fb7ce2ea31a3ad94f9b"},
{file = "pandas-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70e00c2d894cb230e5c15e4b1e1e6b2b478e09cf27cc593a11ef955b9ecc81a"},
{file = "pandas-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e97fbb5387c69209f134893abc788a6486dbf2f9e511070ca05eed4b930b1b02"},
{file = "pandas-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101d0eb9c5361aa0146f500773395a03839a5e6ecde4d4b6ced88b7e5a1a6403"},
{file = "pandas-2.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7d2ed41c319c9fb4fd454fe25372028dfa417aacb9790f68171b2e3f06eae8cd"},
{file = "pandas-2.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af5d3c00557d657c8773ef9ee702c61dd13b9d7426794c9dfeb1dc4a0bf0ebc7"},
{file = "pandas-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:06cf591dbaefb6da9de8472535b185cba556d0ce2e6ed28e21d919704fef1a9e"},
{file = "pandas-2.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:88ecb5c01bb9ca927ebc4098136038519aa5d66b44671861ffab754cae75102c"},
{file = "pandas-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:04f6ec3baec203c13e3f8b139fb0f9f86cd8c0b94603ae3ae8ce9a422e9f5bee"},
{file = "pandas-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a935a90a76c44fe170d01e90a3594beef9e9a6220021acfb26053d01426f7dc2"},
{file = "pandas-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c391f594aae2fd9f679d419e9a4d5ba4bce5bb13f6a989195656e7dc4b95c8f0"},
{file = "pandas-2.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9d1265545f579edf3f8f0cb6f89f234f5e44ba725a34d86535b1a1d38decbccc"},
{file = "pandas-2.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:11940e9e3056576ac3244baef2fedade891977bcc1cb7e5cc8f8cc7d603edc89"},
{file = "pandas-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:4acf681325ee1c7f950d058b05a820441075b0dd9a2adf5c4835b9bc056bf4fb"},
{file = "pandas-2.2.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9bd8a40f47080825af4317d0340c656744f2bfdb6819f818e6ba3cd24c0e1397"},
{file = "pandas-2.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df0c37ebd19e11d089ceba66eba59a168242fc6b7155cba4ffffa6eccdfb8f16"},
{file = "pandas-2.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:739cc70eaf17d57608639e74d63387b0d8594ce02f69e7a0b046f117974b3019"},
{file = "pandas-2.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9d3558d263073ed95e46f4650becff0c5e1ffe0fc3a015de3c79283dfbdb3df"},
{file = "pandas-2.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4aa1d8707812a658debf03824016bf5ea0d516afdea29b7dc14cf687bc4d4ec6"},
{file = "pandas-2.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:76f27a809cda87e07f192f001d11adc2b930e93a2b0c4a236fde5429527423be"},
{file = "pandas-2.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:1ba21b1d5c0e43416218db63037dbe1a01fc101dc6e6024bcad08123e48004ab"},
{file = "pandas-2.2.1.tar.gz", hash = "sha256:0ab90f87093c13f3e8fa45b48ba9f39181046e8f3317d3aadb2fffbb1b978572"},
]
[package.dependencies]
@@ -625,6 +625,7 @@ parquet = ["pyarrow (>=10.0.1)"]
performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"]
plot = ["matplotlib (>=3.6.3)"]
postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"]
pyarrow = ["pyarrow (>=10.0.1)"]
spss = ["pyreadstat (>=1.2.0)"]
sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"]
test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
@@ -799,13 +800,13 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"]
[[package]]
name = "pytest"
version = "8.0.1"
version = "8.0.2"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"},
{file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"},
{file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"},
{file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"},
]
[package.dependencies]
@@ -1018,19 +1019,19 @@ test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov",
[[package]]
name = "setuptools"
version = "69.1.0"
version = "69.1.1"
description = "Easily download, build, install, upgrade, and uninstall Python packages"
optional = false
python-versions = ">=3.8"
files = [
{file = "setuptools-69.1.0-py3-none-any.whl", hash = "sha256:c054629b81b946d63a9c6e732bc8b2513a7c3ea645f11d0139a2191d735c60c6"},
{file = "setuptools-69.1.0.tar.gz", hash = "sha256:850894c4195f09c4ed30dba56213bf7c3f21d86ed6bdaafb5df5972593bfc401"},
{file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"},
{file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"},
]
[package.extras]
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
[[package]]
name = "six"
@@ -1092,13 +1093,13 @@ files = [
[[package]]
name = "typing-extensions"
version = "4.9.0"
version = "4.10.0"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
{file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
{file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
{file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
{file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
]
[[package]]
@@ -1165,7 +1166,7 @@ profile = ["pytest-profiling", "snakeviz"]
type = "git"
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
reference = "HEAD"
resolved_reference = "3d85aa62ea794f7214fc3674bf328d28b91cda6d"
resolved_reference = "33fec45ce8044ef7f53b625584ce590d174f9057"
[[package]]
name = "websocket-client"
@@ -235,7 +235,7 @@ def test_submit_stop_oco_market_order_pending(
"PendingOCO"
)
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_submit_stop_oco_limit_order_pending(
continuous_market, vega: VegaServiceNull, page: Page
):
@@ -15,8 +15,7 @@ deal_ticket_deposit_dialog_button = "deal-ticket-deposit-dialog-button"
@pytest.fixture(scope="module")
def vega(request):
with init_vega(request) as vega_instance:
request.addfinalizer(lambda: cleanup_container(
vega_instance)) # Register the cleanup function
request.addfinalizer(lambda: cleanup_container(vega_instance))
yield vega_instance
@@ -25,7 +24,6 @@ def continuous_market(vega):
return setup_continuous_market(vega)
@pytest.mark.skip("tbd - issue only on the sim, should work in vega 0.74.0")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_should_display_info_and_button_for_deposit(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
@@ -33,17 +31,20 @@ def test_should_display_info_and_button_for_deposit(continuous_market, page: Pag
page.get_by_test_id(order_price).fill("20")
# 7002-SORD-060
expect(page.get_by_test_id(deal_ticket_warning_margin)).to_have_text(
"You may not have enough margin available to open this position.")
"You may not have enough margin available to open this position."
)
page.get_by_test_id(deal_ticket_warning_margin).hover()
expect(page.get_by_test_id("tooltip-content").nth(0)).to_have_text(
"1,661,888.12901 tDAI is currently required.You have only 999,991.49731.Deposit tDAI")
"1,661,888.12901 tDAI is currently required.You have only 999,991.49731.Deposit tDAI"
)
page.get_by_test_id(deal_ticket_deposit_dialog_button).nth(0).click()
expect(page.get_by_test_id("sidebar-content")
).to_contain_text("DepositFrom")
expect(page.get_by_test_id("sidebar-content")).to_contain_text("DepositFrom")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaServiceNull, page: Page):
def test_should_show_an_error_if_your_balance_is_zero(
continuous_market, vega: VegaServiceNull, page: Page
):
page.goto(f"/#/markets/{continuous_market}")
vega.create_key("key_empty")
change_keys(page, vega, "key_empty")
@@ -52,6 +53,7 @@ def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: V
# 7002-SORD-060
expect(page.get_by_test_id(place_order)).to_be_enabled()
# 7002-SORD-003
expect(page.get_by_test_id("deal-ticket-error-message-zero-balance")
).to_have_text("You need tDAI in your wallet to trade in this market.Make a deposit")
expect(page.get_by_test_id("deal-ticket-error-message-zero-balance")).to_have_text(
"You need tDAI in your wallet to trade in this market.Make a deposit"
)
expect(page.get_by_test_id(deal_ticket_deposit_dialog_button)).to_be_visible()
@@ -77,7 +77,7 @@ def test_market_info_market_volume(page: Page):
page.get_by_test_id(market_title_test_id).get_by_text(
"Market volume").click()
fields = [
["24 Hour Volume", "-"],
["24 Hour Volume", "0 (0 )"],
["Open Interest", "1"],
["Best Bid Volume", "99"],
["Best Offer Volume", "99"],
@@ -107,7 +107,6 @@ def test_market_info_liquidation(page: Page):
validate_info_section(page, fields)
@pytest.mark.skip("core issue #5681")
def test_market_info_key_details(page: Page, vega: VegaServiceNull):
# 6002-MDET-201
page.get_by_test_id(market_title_test_id).get_by_text(
@@ -117,8 +116,6 @@ def test_market_info_key_details(page: Page, vega: VegaServiceNull):
fields = [
["Market ID", short_market_id],
["Name", "BTC:DAI_2023"],
["Parent Market ID", "-"],
["Insurance Pool Fraction", "-"],
["Status", "Active"],
["Trading Mode", "Continuous"],
["Market Decimal Places", "5"],
@@ -63,9 +63,9 @@ def test_renders_markets_correctly(proposed_market, page: Page):
# 6001-MARK-052
# 6001-MARK-053
expect(row.locator('[col-id="state"]')).to_have_text("Open")
expect(row.locator('[col-id="state"]')).to_have_text("Proposed")
expect(
row.locator('[col-id="terms.change.successorConfiguration.parentMarketId"]')
row.locator('[col-id="parentMarketID"]')
).to_have_text("-")
# 6001-MARK-056
@@ -9,6 +9,7 @@ from actions.utils import next_epoch
from wallet_config import MM_WALLET, MM_WALLET2, GOVERNANCE_WALLET
from vega_sim.api import governance
@pytest.mark.usefixtures("risk_accepted")
def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
# 7002-SORD-001
@@ -16,15 +17,18 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
trading_mode = page.get_by_test_id("market-trading-mode").get_by_test_id(
"item-value"
)
market_state = page.get_by_test_id("market-state").get_by_test_id("item-value")
market_state = page.get_by_test_id(
"market-state").get_by_test_id("item-value")
# setup market in proposed step, without liquidity provided
market_id = proposed_market
page.goto(f"/#/markets/{market_id}")
# 6002-MDET-001
expect(page.get_by_test_id("header-title")).to_have_text("BTC:DAI_2023Futr")
expect(page.get_by_test_id("header-title")
).to_have_text("BTC:DAI_2023Futr")
# 6002-MDET-002
expect(page.get_by_test_id("market-expiry")).to_have_text("ExpiryNot time-based")
expect(page.get_by_test_id("market-expiry")
).to_have_text("ExpiryNot time-based")
page.get_by_test_id("market-expiry").hover()
expect(page.get_by_test_id("expiry-tooltip").first).to_have_text(
"This market expires when triggered by its oracle, not on a set date.View oracle specification"
@@ -123,16 +127,16 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
expect(market_state).to_have_text("Active")
vega.update_market_state(
market_id = market_id,
proposal_key = MM_WALLET.name,
market_state = MarketStateUpdateType.Suspend,
forward_time_to_enactment = False
market_id=market_id,
proposal_key=MM_WALLET.name,
market_state=MarketStateUpdateType.Suspend,
forward_time_to_enactment=False
)
expect(
page
.get_by_test_id("market-banner")
.get_by_test_id(f"update-state-banner-{market_id}")
.get_by_test_id("market-banner")
.get_by_test_id(f"update-state-banner-{market_id}")
).to_be_visible()
next_epoch(vega=vega)
@@ -143,12 +147,14 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
# banner should not show after resume
vega.update_market_state(
market_id = market_id,
proposal_key = MM_WALLET.name,
market_state = MarketStateUpdateType.Resume,
forward_time_to_enactment = False
market_id=market_id,
proposal_key=MM_WALLET.name,
market_state=MarketStateUpdateType.Resume,
forward_time_to_enactment=False
)
expect(page.get_by_test_id("market-banner")
).to_have_text(" Trading on market BTC:DAI_2023 was suspended by governance. There are open proposals to resume trading on this market.View proposals1/2")
next_epoch(vega=vega)
expect(page.get_by_test_id("market-banner")).not_to_be_visible()
@@ -1,10 +1,12 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from typing import List
from actions.vega import submit_order, submit_liquidity, submit_multiple_orders
from conftest import init_vega, cleanup_container
from fixtures.market import setup_simple_market
from wallet_config import MM_WALLET, MM_WALLET2
from actions.utils import next_epoch
@pytest.fixture(scope="module")
@@ -15,7 +17,7 @@ def vega(request):
@pytest.fixture(scope="module")
def setup_market(vega):
def setup_market(vega: VegaServiceNull):
market_id = setup_simple_market(vega)
submit_liquidity(vega, MM_WALLET.name, market_id)
submit_multiple_orders(
@@ -33,10 +35,9 @@ def setup_market(vega):
[[10, 69.995], [5, 70], [5, 85], [3, 90], [3, 95]],
)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
return [
vega,
market_id,
@@ -46,19 +47,19 @@ def setup_market(vega):
# these values don't align with the multiple orders above as
# creating a trade triggers the liquidity provision
orderbook_content = [
[130.00500, 10, 94],
[130.00000, 3, 84],
[120.00000, 7, 81],
[110.00000, 5, 74],
[105.00000, 2, 69],
[101.00000, 67, 67],
[130.00500, 10, 126],
[130.00000, 3, 116],
[120.00000, 7, 113],
[110.00000, 5, 106],
[105.00000, 2, 101],
[101.00000, 99, 99],
# mid
[99.00000, 102, 102],
[95.00000, 3, 105],
[90.00000, 3, 108],
[85.00000, 5, 113],
[70.00000, 5, 118],
[69.99500, 10, 128],
[99.00000, 99, 99],
[95.00000, 3, 102],
[90.00000, 3, 105],
[85.00000, 5, 110],
[70.00000, 5, 115],
[69.99500, 10, 125],
]
@@ -81,7 +82,6 @@ def verify_prices_descending(page: Page):
assert prices == sorted(prices, reverse=True)
@pytest.mark.skip("tbd")
@pytest.mark.usefixtures("risk_accepted")
def test_orderbook_grid_content(setup_market, page: Page):
vega = setup_market[0]
@@ -109,6 +109,7 @@ def test_orderbook_grid_content(setup_market, page: Page):
vega.wait_fn(1)
vega.wait_for_total_catchup()
next_epoch(vega)
# 6003-ORDB-001
# 6003-ORDB-002
@@ -120,7 +121,6 @@ def test_orderbook_grid_content(setup_market, page: Page):
page.goto(f"/#/markets/{market_id}")
page.locator("[data-testid=Orderbook]").click()
# 6003-ORDB-013
assert (
float(page.locator("[data-testid*=last-traded]").text_content())
@@ -144,50 +144,46 @@ def test_orderbook_grid_content(setup_market, page: Page):
def test_orderbook_resolution_change(setup_market, page: Page):
market_id = setup_market[1]
# 6003-ORDB-008
orderbook_content_0_00 = [
[130.01, 10, 94],
[130.00, 3, 84],
[120.00, 7, 81],
[110.00, 5, 74],
[105.00, 2, 69],
[101.00, 67, 67],
orderbook_content_0_01 = [
[130.01, 10, 126],
[130.00, 3, 116],
[120.00, 7, 113],
[110.00, 5, 106],
[105.00, 2, 101],
[101.00, 99, 99],
# mid
[99.00, 102, 102],
[95.00, 3, 105],
[90.00, 3, 108],
[85.00, 5, 113],
[70.00, 15, 128],
[99.00, 99, 99],
[95.00, 3, 102],
[90.00, 3, 105],
[85.00, 5, 110],
[70.00, 15, 125],
]
orderbook_content_10 = [
[130, 13, 94],
[120, 7, 81],
[110, 7, 74],
[100, 67, 67],
orderbook_content_1 = [
[130, 13, 126],
[120, 7, 113],
[110, 5, 106],
[105, 2, 101],
[101, 99, 99],
# mid
[100, 105, 105],
[90, 8, 113],
[70, 15, 128],
[99, 99, 99],
[95, 3, 102],
[90, 3, 105],
[85, 5, 110],
[70, 15, 125],
]
orderbook_content_100 = [
[100, 94, 94],
# mid
[100, 128, 128],
]
resolutions = [
["0.00", orderbook_content_0_00],
["10", orderbook_content_10],
["100", orderbook_content_100],
["0.01", orderbook_content_0_01],
["1", orderbook_content_1],
]
page.goto(f"/#/markets/{market_id}")
# temporary skip
# for resolution in resolutions:
# page.get_by_test_id("resolution").click()
# page.get_by_role("menu").get_by_text(resolution[0], exact=True).click()
# verify_orderbook_grid(page, resolution[1])
for resolution in resolutions:
page.get_by_test_id("resolution").click()
page.get_by_role("menuitem").get_by_text(resolution[0], exact=True).click()
verify_orderbook_grid(page, resolution[1])
@pytest.mark.usefixtures("risk_accepted")
@@ -209,7 +205,6 @@ def test_orderbook_price_size_copy(setup_market, page: Page):
expect(page.get_by_test_id("order-size")).to_have_value(volume.text_content())
@pytest.mark.skip("tbd")
@pytest.mark.usefixtures("risk_accepted")
def test_orderbook_price_movement(setup_market, page: Page):
vega = setup_market[0]
@@ -119,7 +119,7 @@ def setup_market_and_referral_scheme(vega: VegaServiceNull, continuous_market: s
forward_time(vega)
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaServiceNull, page: Page):
setup_market_and_referral_scheme(vega, continuous_market, page)
change_keys(page, vega, PARTY_B.name)
@@ -163,7 +163,7 @@ def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaSer
"1%", "1", "1%", "0", "1", "1"))
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_does_not_move_up_tiers_when_not_enough_epochs(continuous_market, vega: VegaServiceNull, page: Page):
setup_market_and_referral_scheme(vega, continuous_market, page)
change_keys(page, vega, PARTY_B.name)
+20 -2
View File
@@ -52,8 +52,25 @@ def setup_teams_and_games(vega: VegaServiceNull):
vega.update_network_parameter(
MM_WALLET.name, parameter="reward.asset", new_value=tDAI_asset_id
)
next_epoch(vega=vega)
vega.create_asset(
MM_WALLET.name,
name="VEGA",
symbol="VEGA",
decimals=5,
max_faucet_amount=1e10,
quantum=100000,
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
VEGA_asset_id = vega.find_asset_id(symbol="VEGA")
vega.mint(PARTY_A.name, VEGA_asset_id, 1e5)
vega.mint(PARTY_B.name, VEGA_asset_id, 1e5)
vega.wait_fn(1)
vega.wait_for_total_catchup()
team_name = create_team(vega)
next_epoch(vega)
@@ -101,7 +118,7 @@ def setup_teams_and_games(vega: VegaServiceNull):
from_key_name=PARTY_A.name,
from_account_type=vega_protos.vega.ACCOUNT_TYPE_GENERAL,
to_account_type=vega_protos.vega.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
asset=tDAI_asset_id,
asset=VEGA_asset_id,
reference="reward",
asset_for_metric=tDAI_asset_id,
metric=vega_protos.vega.DISPATCH_METRIC_MAKER_FEES_PAID,
@@ -119,7 +136,7 @@ def setup_teams_and_games(vega: VegaServiceNull):
from_key_name=PARTY_B.name,
from_account_type=vega_protos.vega.ACCOUNT_TYPE_GENERAL,
to_account_type=vega_protos.vega.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES,
asset=tDAI_asset_id,
asset=VEGA_asset_id,
reference="reward",
asset_for_metric=tDAI_asset_id,
metric=vega_protos.vega.DISPATCH_METRIC_MAKER_FEES_PAID,
@@ -288,6 +305,7 @@ def test_game_card(competitions_page: Page):
expect(game_1.get_by_test_id("entity-scope")).to_have_text("Individual")
expect(game_1.get_by_test_id("locked-for")).to_have_text("1 epoch")
expect(game_1.get_by_test_id("reward-value")).to_have_text("100.00")
expect(game_1.get_by_test_id("reward-asset")).to_have_text("VEGA")
expect(game_1.get_by_test_id("distribution-strategy")).to_have_text("Pro rata")
expect(game_1.get_by_test_id("dispatch-metric-info")).to_have_text(
"Price maker fees paid • tDAI"
+6 -5
View File
@@ -31,7 +31,7 @@ export type RewardTransfer = TransferNode & {
export type EnrichedRewardTransfer = RewardTransfer & {
/** Dispatch metric asset (reward asset) */
asset?: AssetFieldsFragment;
dispatchAsset?: AssetFieldsFragment;
/** A flag determining whether a reward asset is being traded on any of the active markets */
isAssetTraded?: boolean;
/** A list of markets in scope */
@@ -142,9 +142,10 @@ export const useRewards = ({
.filter((node) => (scopeToTeams ? isScopedToTeams(node) : true))
// enrich with dispatch asset and markets in scope details
.map((node) => {
const asset =
assets &&
assets[node.transfer.kind.dispatchStrategy.dispatchMetricAssetId];
const dispatchAsset =
(assets &&
assets[node.transfer.kind.dispatchStrategy.dispatchMetricAssetId]) ||
undefined;
const marketsInScope = compact(
node.transfer.kind.dispatchStrategy.marketIdsInScope?.map(
(id) => markets && markets[id]
@@ -167,7 +168,7 @@ export const useRewards = ({
});
return {
...node,
asset: asset ? asset : undefined,
dispatchAsset,
isAssetTraded: isAssetTraded != null ? isAssetTraded : undefined,
markets: marketsInScope.length > 0 ? marketsInScope : undefined,
};
+7
View File
@@ -62,3 +62,10 @@ export const DENY_LIST: Record<string, string[]> = {
'fdf0ec118d98393a7702cf72e46fc87ad680b152f64b2aac59e093ac2d688fbb',
],
};
// We need a record of USDT on mainnet as it needs special handling for
// deposits and approvals due to the contract not conforming exactly
// to ERC20
export const USDT_ID = {
MAINNET: 'bf1e88d19db4b3ca0d1d5bdb73718a01686b18cf731ca26adedf3c8b83802bba',
} as const;
+2
View File
@@ -13,6 +13,8 @@ export function generateMarket(override?: PartialDeep<Market>): Market {
state: Schema.MarketState.STATE_ACTIVE,
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2024-01-02',
pending: '2024-01-01',
close: '',
open: '',
},
+37 -15
View File
@@ -1,5 +1,9 @@
import type { Asset } from '@vegaprotocol/assets';
import { EtherscanLink } from '@vegaprotocol/environment';
import { USDT_ID, type Asset } from '@vegaprotocol/assets';
import {
EtherscanLink,
Networks,
useEnvironment,
} from '@vegaprotocol/environment';
import { Intent, Notification } from '@vegaprotocol/ui-toolkit';
import {
formatNumber,
@@ -15,7 +19,7 @@ import { useT } from './use-t';
interface ApproveNotificationProps {
isActive: boolean;
selectedAsset?: Asset;
onApprove: () => void;
onApprove: (amount?: string) => void;
approved: boolean;
balances: DepositBalances | null;
amount: string;
@@ -33,6 +37,7 @@ export const ApproveNotification = ({
approveTxId,
intent = Intent.Warning,
}: ApproveNotificationProps) => {
const { VEGA_ENV } = useEnvironment();
const t = useT();
const tx = useEthTransactionStore((state) => {
return state.transactions.find((t) => t?.id === approveTxId);
@@ -64,28 +69,45 @@ export const ApproveNotification = ({
text: t('Approve {{assetSymbol}}', {
assetSymbol: selectedAsset?.symbol,
}),
action: onApprove,
action: () => onApprove(),
dataTestId: 'approve-submit',
}}
/>
</div>
);
let message = t('Approve again to deposit more than {{allowance}}', {
allowance: formatNumber(balances.allowance.toString()),
});
const buttonProps = {
size: 'small' as const,
text: t('Approve {{assetSymbol}}', {
assetSymbol: selectedAsset?.symbol,
}),
action: () => onApprove(),
dataTestId: 'reapprove-submit',
};
if (VEGA_ENV === Networks.MAINNET && selectedAsset.id === USDT_ID[VEGA_ENV]) {
message = t(
'USDT approved amount cannot be changed, only revoked. Revoke and reapprove to deposit more than {{allowance}}.',
{
allowance: formatNumber(balances.allowance.toString()),
}
);
buttonProps.text = t('Revoke {{assetSymbol}} approval', {
assetSymbol: selectedAsset?.symbol,
});
buttonProps.action = () => onApprove('0');
}
const reApprovePrompt = (
<div className="mb-4">
<Notification
intent={intent}
testId="reapprove-default"
message={t('Approve again to deposit more than {{allowance}}', {
allowance: formatNumber(balances.allowance.toString()),
})}
buttonProps={{
size: 'small',
text: t('Approve {{assetSymbol}}', {
assetSymbol: selectedAsset?.symbol,
}),
action: onApprove,
dataTestId: 'reapprove-submit',
}}
message={message}
buttonProps={buttonProps}
/>
</div>
);
+3 -3
View File
@@ -58,7 +58,7 @@ export interface DepositFormProps {
onSelectAsset: (assetId: string) => void;
handleAmountChange: (amount: string) => void;
onDisconnect: () => void;
submitApprove: () => void;
submitApprove: (amount?: string) => void;
approveTxId: number | null;
submitFaucet: () => void;
faucetTxId: number | null;
@@ -423,8 +423,8 @@ export const DepositForm = ({
isActive={isActive}
approveTxId={approveTxId}
selectedAsset={selectedAsset}
onApprove={() => {
submitApprove();
onApprove={(amount) => {
submitApprove(amount);
setApproveNotificationIntent(Intent.Warning);
}}
balances={balances}
+2 -2
View File
@@ -35,11 +35,11 @@ export const useSubmitApproval = (
reset: () => {
setId(null);
},
perform: () => {
perform: (amount?: string) => {
if (!asset || !config) return;
const id = createEthTransaction(contract, 'approve', [
config?.collateral_bridge_contract.address,
MaxUint256.toString(),
amount ? amount : MaxUint256.toString(),
]);
setId(id);
},
+1
View File
@@ -134,6 +134,7 @@ export const CONSOLE_TRANSFER = '#/portfolio/assets/transfer';
export const CONSOLE_TRANSFER_ASSET =
'#/portfolio/assets/transfer?assetId=:assetId';
export const CONSOLE_MARKET_PAGE = '#/markets/:marketId';
export const CONSOLE_REWARDS_PAGE = '#/rewards';
// Governance pages
export const TOKEN_NEW_MARKET_PROPOSAL = '/proposals/propose/new-market';
+2
View File
@@ -65,6 +65,8 @@ export const generateFill = (override?: PartialDeep<Trade>) => {
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2005-03-31T19:37:00.000Z',
pending: '2005-04-01T19:37:00.000Z',
open: '2005-04-02T19:37:00.000Z',
close: '2005-04-02T19:37:00.000Z',
},
@@ -34,6 +34,8 @@ export const generateFundingPayment = (
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2005-03-31T19:37:00.000Z',
pending: '2005-04-01T19:37:00.000Z',
open: '2005-04-02T19:37:00.000Z',
close: '2005-04-02T19:37:00.000Z',
},
+2
View File
@@ -4,6 +4,7 @@
"Approval failed": "Approval failed",
"Approve {{assetSymbol}}": "Approve {{assetSymbol}}",
"Approve again to deposit more than {{allowance}}": "Approve again to deposit more than {{allowance}}",
"USDT approved amount cannot be changed, only revoked. Revoke and reapprove to deposit more than {{allowance}}.": "USDT approved amount cannot be changed, only revoked. Revoke and reapprove to deposit more than {{allowance}}.",
"Asset": "Asset",
"Balance available": "Balance available",
"Before you can make a deposit of your chosen asset, {{assetSymbol}}, you need to approve its use in your Ethereum wallet": "Before you can make a deposit of your chosen asset, {{assetSymbol}}, you need to approve its use in your Ethereum wallet",
@@ -23,6 +24,7 @@
"Please select": "Please select",
"Please select an asset": "Please select an asset",
"Remaining deposit allowance": "Remaining deposit allowance",
"Revoke {{assetSymbol}} approval": "Revoke {{assetSymbol}} approval",
"Select from wallet": "Select from wallet",
"The {{symbol}} faucet is not available at this time": "The {{symbol}} faucet is not available at this time",
"The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.": "The deposit cap is set when you approve an asset for use with this app. To increase this cap, approve {{assetSymbol}} again and choose a higher cap. Check the documentation for your Ethereum wallet app for details.",
+4 -1
View File
@@ -391,6 +391,8 @@
"multisigContractIncorrect": "was incorrectly configured as at the end of the last epoch so rewards were penalised. Validator and delegator rewards will continue to be penalised until this is resolved.",
"multisigContractLink": "Ethereum Multisig Contract",
"multisigPenalty": "Multisig penalty",
"multisigPenaltyThisNodeIndicator": "The multisig score for this node is equal to zero.",
"multisigPenaltyDescription": "The multisig score is used in the calculation of rewards. For each validator that gets a multisig score of zero, no staking rewards are paid to that consensus validators and their nominators until the epoch following the one in which the configuration issue is resolved.",
"myPendingStake": "My pending stake",
"myStake": "My stake",
"n/a": "N/A",
@@ -967,5 +969,6 @@
"YourIdentityAnonymous": "Your identity is always anonymous on Vega",
"yourStake": "Your stake",
"yourVote": "Your vote",
"youVoted": "You voted"
"youVoted": "You voted",
"rewardsMovedNotification": "Trading and liquidity rewards have moved. Visit <0>Console</0> to view your rewards."
}
-5
View File
@@ -1,8 +1,6 @@
{
"{{liquidityPriceRange}} of mid price": "{{liquidityPriceRange}} of mid price",
"{{probability}} probability price bounds": "{{probability}} probability price bounds",
"24 hour change is unavailable at this time. The price change in the last 120 hours is:": "24 hour change is unavailable at this time. The price change in the last 120 hours is:",
"24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}} for a total of {{candleVolumePrice}} {{quoteUnit}}": "24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}} for a total of {{candleVolumePrice}} {{quoteUnit}}",
"A concept derived from traditional markets. It is a calculated value for the current market price on a market.": "A concept derived from traditional markets. It is a calculated value for the current market price on a market.",
"A number that will be calculated by an appropriate stochastic risk model, dependent on the type of risk model used and its parameters.": "A number that will be calculated by an appropriate stochastic risk model, dependent on the type of risk model used and its parameters.",
"A sliding penalty for how much an LP bond is slashed if an LP fails to reach the minimum SLA. This is a network parameter.": "A sliding penalty for how much an LP bond is slashed if an LP fails to reach the minimum SLA. This is a network parameter.",
@@ -51,9 +49,6 @@
"Market": "Market",
"Market data": "Market data",
"Market governance": "Market governance",
"Market has not been active for 24 hours. The price change between {{start}} and {{end}} is:": "Market has not been active for 24 hours. The price change between {{start}} and {{end}} is:",
"Market has not been active for 24 hours. The volume traded between {{start}} and {{end}} is:": "Market has not been active for 24 hours. The volume traded between {{start}} and {{end}} is:",
"Market has not been active for 24 hours. The volume traded between {{start}} and {{end}} is {{candleVolumeValue}} for a total of {{candleVolumePrice}} {{quoteUnit}}": "Market has not been active for 24 hours. The volume traded between {{start}} and {{end}} is {{candleVolumeValue}} for a total of {{candleVolumePrice}} {{quoteUnit}}",
"Market ID": "Market ID",
"Market price": "Market price",
"Market specification": "Market specification",
-8
View File
@@ -5,19 +5,14 @@
"blocks": "blocks",
"Changes have been proposed for this asset.": "Changes have been proposed for this asset.",
"Changes have been proposed for this market.": "Changes have been proposed for this market.",
"Closing date": "Closing date",
"Confirm transaction in wallet": "Confirm transaction in wallet",
"Enactment date": "Enactment date",
"Enactment date: {{date}}": "Enactment date: {{date}}",
"estimated time to protocol upgrade": "estimated time to protocol upgrade",
"estimating...": "estimating...",
"Market": "Market",
"Network upgrade in {{countdown}}": "Network upgrade in {{countdown}}",
"No proposed markets": "No proposed markets",
"numberOfBlocks": "<0>{{count}}</0> blocks",
"numberOfBlocks_one": "<0>{{count}}</0> block",
"numberOfBlocks_other": "<0>{{count}}</0> blocks",
"Parent market": "Parent market",
"Please open your wallet application and confirm or reject the transaction": "Please open your wallet application and confirm or reject the transaction",
"Please wait for your transaction to be confirmed": "Please wait for your transaction to be confirmed",
"Proposal declined": "Proposal declined",
@@ -28,8 +23,6 @@
"Proposal submitted": "Proposal submitted",
"Proposal waiting for node vote": "Proposal waiting for node vote",
"Rejection reason: {{reason}}": "Rejection reason: {{reason}}",
"Settlement asset": "Settlement asset",
"State": "State",
"Submission failed": "Submission failed",
"The network is being upgraded to {{vegaReleaseTag}}": "The network is being upgraded to {{vegaReleaseTag}}",
"The network will upgrade to {{vegaReleaseTag}} in {{countdown}}": "The network will upgrade to {{vegaReleaseTag}} in {{countdown}}",
@@ -41,7 +34,6 @@
"Update <0>{{key}}</0> to {{value}}": "Update <0>{{key}}</0> to {{value}}",
"View details": "View details",
"View in block explorer": "View in block explorer",
"View proposal": "View proposal",
"View proposal details": "View proposal details",
"Voting": "Voting",
"Your transaction has been confirmed": "Your transaction has been confirmed"
+6
View File
@@ -40,6 +40,7 @@
"Close menu": "Close menu",
"Closed": "Closed",
"Closed markets": "Closed markets",
"Closing date": "Closing date",
"Code must be 64 characters in length": "Code must be 64 characters in length",
"Code must be be valid hex": "Code must be be valid hex",
"Collateral": "Collateral",
@@ -90,6 +91,7 @@
"Earned by me": "Earned by me",
"Eligible teams": "Eligible teams",
"Enactment date reached and usual auction exit checks pass": "Enactment date reached and usual auction exit checks pass",
"Enactment date": "Enactment date",
"[empty]": "[empty]",
"Ends in": "Ends in",
"Entity scope": "Entity scope",
@@ -211,6 +213,7 @@
"No orders": "No orders",
"No party accepts any liability for any losses whatsoever.": "No party accepts any liability for any losses whatsoever.",
"No perpetual markets.": "No perpetual markets.",
"No proposed markets": "No proposed markets",
"No referral program active": "No referral program active",
"No rejected orders": "No rejected orders",
"No rewards": "No rewards",
@@ -238,6 +241,7 @@
"PRNT": "PRNT",
"Page not found": "Page not found",
"Parent of a market": "Parent of a market",
"Parent market": "Parent market",
"Pennant": "Pennant",
"Perpetuals": "Perpetuals",
"place_ordinal_one": "{{count}}st",
@@ -307,6 +311,7 @@
"Staking multiplier": "Staking multiplier",
"Start trading": "Start trading",
"Start trading on the worlds most advanced decentralised exchange.": "Start trading on the worlds most advanced decentralised exchange.",
"State": "State",
"Status": "Status",
"Stop": "Stop",
"Stop orders": "Stop orders",
@@ -387,6 +392,7 @@
"View oracle specification": "View oracle specification",
"View parent market": "View parent market",
"View proposals": "View proposals",
"View proposal": "View proposal",
"View settlement asset details": "View settlement asset details",
"View successor market": "View successor market",
"View team": "View team",
File diff suppressed because one or more lines are too long
@@ -2,16 +2,14 @@ import { type ReactNode } from 'react';
import {
addDecimalsFormatNumber,
formatNumberPercentage,
getDateTimeFormat,
priceChange,
priceChangePercentage,
} from '@vegaprotocol/utils';
import { PriceChangeCell, signedNumberCssClass } from '@vegaprotocol/datagrid';
import { Tooltip, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import { signedNumberCssClass } from '@vegaprotocol/datagrid';
import { VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import { useCandles } from '../../hooks/use-candles';
import BigNumber from 'bignumber.js';
import classNames from 'classnames';
import { useT } from '../../use-t';
interface Props {
marketId?: string;
@@ -24,7 +22,6 @@ export const Last24hPriceChange = ({
decimalPlaces,
fallback,
}: Props) => {
const t = useT();
const { oneDayCandles, fiveDaysCandles, error } = useCandles({
marketId,
});
@@ -35,56 +32,6 @@ export const Last24hPriceChange = ({
return nonIdeal;
}
if (fiveDaysCandles.length < 24) {
return (
<Tooltip
description={
<span className="justify-start">
{t(
'Market has not been active for 24 hours. The price change between {{start}} and {{end}} is:',
{
start: getDateTimeFormat().format(
new Date(fiveDaysCandles[0].periodStart)
),
end: getDateTimeFormat().format(
new Date(
fiveDaysCandles[fiveDaysCandles.length - 1].periodStart
)
),
}
)}
<PriceChangeCell
candles={fiveDaysCandles.map((c) => c.close) || []}
decimalPlaces={decimalPlaces}
/>
</span>
}
>
<span>{nonIdeal}</span>
</Tooltip>
);
}
if (oneDayCandles.length < 24) {
return (
<Tooltip
description={
<span className="justify-start">
{t(
'24 hour change is unavailable at this time. The price change in the last 120 hours is:'
)}{' '}
<PriceChangeCell
candles={fiveDaysCandles.map((c) => c.close) || []}
decimalPlaces={decimalPlaces}
/>
</span>
}
>
<span>{nonIdeal}</span>
</Tooltip>
);
}
const candles = oneDayCandles?.map((c) => c.close) || [];
const change = priceChange(candles);
const changePercentage = priceChangePercentage(candles);
@@ -2,7 +2,6 @@ import { calcCandleVolume, calcCandleVolumePrice } from '../../market-utils';
import {
addDecimalsFormatNumber,
formatNumber,
getDateTimeFormat,
isNumeric,
} from '@vegaprotocol/utils';
import { Tooltip } from '@vegaprotocol/ui-toolkit';
@@ -37,83 +36,6 @@ export const Last24hVolume = ({
return nonIdeal;
}
if (fiveDaysCandles.length < 24) {
const candleVolume = calcCandleVolume(fiveDaysCandles);
const candleVolumePrice = calcCandleVolumePrice(
fiveDaysCandles,
marketDecimals,
positionDecimalPlaces
);
const candleVolumeValue =
candleVolume && isNumeric(positionDecimalPlaces)
? addDecimalsFormatNumber(
candleVolume,
positionDecimalPlaces,
formatDecimals
)
: '-';
return (
<Tooltip
description={
<div>
<span className="flex flex-col">
{t(
'Market has not been active for 24 hours. The volume traded between {{start}} and {{end}} is {{candleVolumeValue}} for a total of {{candleVolumePrice}} {{quoteUnit}}',
{
start: getDateTimeFormat().format(
new Date(fiveDaysCandles[0].periodStart)
),
end: getDateTimeFormat().format(
new Date(
fiveDaysCandles[fiveDaysCandles.length - 1].periodStart
)
),
candleVolumeValue,
candleVolumePrice,
quoteUnit,
}
)}
</span>
</div>
}
>
<span>{nonIdeal}</span>
</Tooltip>
);
}
if (oneDayCandles.length < 24) {
const candleVolume = calcCandleVolume(fiveDaysCandles);
const candleVolumePrice = calcCandleVolumePrice(
fiveDaysCandles,
marketDecimals,
positionDecimalPlaces
);
const candleVolumeValue =
candleVolume && isNumeric(positionDecimalPlaces)
? addDecimalsFormatNumber(
candleVolume,
positionDecimalPlaces,
formatDecimals
)
: '-';
return (
<Tooltip
description={
<div>
<span className="flex flex-col">
{t(
'24 hour change is unavailable at this time. The volume change in the last 120 hours is {{candleVolumeValue}} for a total of ({{candleVolumePrice}} {{quoteUnit}})',
{ candleVolumeValue, candleVolumePrice, quoteUnit }
)}
</span>
</div>
}
>
<span>{nonIdeal}</span>
</Tooltip>
);
}
const candleVolume = oneDayCandles
? calcCandleVolume(oneDayCandles)
: initialValue;
@@ -152,6 +152,8 @@ query MarketInfo($marketId: ID!) {
}
}
marketTimestamps {
proposed
pending
open
close
}
File diff suppressed because one or more lines are too long
@@ -26,6 +26,8 @@ export const marketInfoQuery = (
linearSlippageFactor: '0.01',
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2022-11-13T02:15:24.543614154Z',
pending: '2022-11-14T02:15:24.543614154Z',
open: '2022-11-15T02:15:24.543614154Z',
close: null,
},
+1 -8
View File
@@ -8,7 +8,7 @@ export const useCandles = ({ marketId }: { marketId?: string }) => {
const fiveDaysAgo = useFiveDaysAgo();
const yesterday = useYesterday();
const since = new Date(fiveDaysAgo).toISOString();
const { data, error } = useThrottledDataProvider({
const { data: fiveDaysCandles, error } = useThrottledDataProvider({
dataProvider: marketCandlesProvider,
variables: {
marketId: marketId || '',
@@ -18,13 +18,6 @@ export const useCandles = ({ marketId }: { marketId?: string }) => {
skip: !marketId,
});
const fiveDaysCandles = data?.filter((c) => {
if (c.open === '' || c.close === '' || c.high === '' || c.close === '') {
return false;
}
return true;
});
const oneDayCandles = fiveDaysCandles?.filter((candle) =>
isCandleLessThan24hOld(candle, yesterday)
);
@@ -13,6 +13,8 @@ const MARKET_A: Partial<Market> = {
id: '1',
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2022-05-11T13:08:27.693537312Z',
pending: '2022-05-12T13:08:27.693537312Z',
open: '2022-05-18T13:08:27.693537312Z',
close: null,
},
@@ -24,6 +26,8 @@ const MARKET_B: Partial<Market> = {
id: '2',
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2022-05-11T13:08:27.693537312Z',
pending: '2022-05-12T13:08:27.693537312Z',
open: '2022-05-18T13:00:39.328347732Z',
close: null,
},
@@ -35,6 +39,8 @@ const MARKET_C: Partial<Market> = {
id: '3',
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2022-05-11T13:08:27.693537312Z',
pending: '2022-05-12T13:08:27.693537312Z',
open: '2022-05-17T13:00:39.328347732Z',
close: null,
},
@@ -46,6 +52,8 @@ const MARKET_D: Partial<Market> = {
id: '4',
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2022-05-11T13:08:27.693537312Z',
pending: '2022-05-12T13:08:27.693537312Z',
open: '2022-05-16T13:00:39.328347732Z',
close: null,
},
+10
View File
@@ -123,6 +123,16 @@ export const filterAndSortClosedMarkets = (markets: MarketMaybeWithData[]) => {
});
};
export const filterAndSortProposedMarkets = (
markets: MarketMaybeWithData[]
) => {
return markets.filter((m) => {
return [MarketState.STATE_PROPOSED].includes(
m.data?.marketState || m.state
);
});
};
export const calcCandleLow = (candles: Candle[]): string | undefined => {
return candles
?.reduce((acc: BigNumber, c) => {
+13
View File
@@ -27,6 +27,7 @@ import * as Schema from '@vegaprotocol/types';
import {
filterAndSortClosedMarkets,
filterAndSortMarkets,
filterAndSortProposedMarkets,
} from './market-utils';
import type { Candle } from './market-candles-provider';
@@ -114,6 +115,11 @@ export const closedMarketsProvider = makeDerivedDataProvider<Market[], never>(
([markets]) => filterAndSortClosedMarkets(markets)
);
export const proposedMarketsProvider = makeDerivedDataProvider<Market[], never>(
[marketsProvider],
([markets]) => filterAndSortProposedMarkets(markets)
);
export type MarketMaybeWithCandles = Market & { candles?: Candle[] };
const addCandles = <T extends Market>(
@@ -241,3 +247,10 @@ export const useMarketList = () => {
reload,
};
};
export const useProposedMarketsList = () => {
return useDataProvider({
dataProvider: proposedMarketsProvider,
variables: undefined,
});
};
+10
View File
@@ -36,9 +36,19 @@ fragment MarketFields on Market {
}
}
marketTimestamps {
proposed
pending
open
close
}
marketProposal {
... on Proposal {
id
}
... on BatchProposal {
id
}
}
}
query Markets {
+9 -1
View File
@@ -39,8 +39,10 @@ export const createMarketFragment = (
state: Schema.MarketState.STATE_ACTIVE,
marketTimestamps: {
__typename: 'MarketTimestamps',
close: null,
proposed: '2022-08-23T11:36:32.252490405Z',
pending: '2022-08-24T11:36:32.252490405Z',
open: null,
close: null,
},
successorMarketID: null,
parentMarketID: null,
@@ -189,6 +191,9 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
tradingMode: Schema.MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
state: Schema.MarketState.STATE_SUSPENDED,
marketTimestamps: {
proposed: '2022-08-23T11:36:32.252490405Z',
pending: '2022-08-24T11:36:32.252490405Z',
open: '2022-08-25T11:36:32.252490405Z',
close: '2022-08-26T11:36:32.252490405Z',
},
fees: {
@@ -219,6 +224,9 @@ const marketFieldsFragments: MarketFieldsFragment[] = [
createMarketFragment({
id: 'market-3',
marketTimestamps: {
proposed: '2022-08-23T11:36:32.252490405Z',
pending: '2022-08-24T11:36:32.252490405Z',
open: '2022-08-25T11:36:32.252490405Z',
close: '2022-08-26T11:36:32.252490405Z',
},
fees: {
@@ -22,8 +22,10 @@ export const generateOrder = (partialOrder?: PartialDeep<Order>) => {
},
marketTimestamps: {
__typename: 'MarketTimestamps',
close: '',
open: '',
proposed: '2022-08-23T11:36:32.252490405Z',
pending: '2022-08-24T11:36:32.252490405Z',
open: null,
close: null,
},
positionDecimalPlaces: 2,
state: Schema.MarketState.STATE_ACTIVE,
@@ -32,6 +32,8 @@ export const generateStopOrder = (
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2005-04-02T19:37:00.000Z',
pending: '2005-04-03T19:37:00.000Z',
close: '',
open: '',
},
@@ -116,6 +116,8 @@ describe('OrderViewDialog', () => {
},
marketTimestamps: {
__typename: 'MarketTimestamps',
proposed: '2023-07-17T12:05:25.822854221Z',
pending: '2023-07-18T12:05:25.822854221Z',
open: '2023-07-19T12:05:25.822854221Z',
close: null,
},
-1
View File
@@ -1,6 +1,5 @@
export * from './asset-proposal-notification';
export * from './market-proposal-notification';
export * from './proposals-list';
export * from './protocol-upgrade-countdown';
export * from './protocol-upgrade-in-progress-notification';
export * from './protocol-upgrade-proposal-notification';
@@ -1 +0,0 @@
export * from './proposals-list';
@@ -1,56 +0,0 @@
import type { FC } from 'react';
import { AgGrid } from '@vegaprotocol/datagrid';
import * as Types from '@vegaprotocol/types';
import { removePaginationWrapper } from '@vegaprotocol/utils';
import type { ProposalListFieldsFragment } from '../../lib/proposals-data-provider/__generated__/Proposals';
import { useProposalsListQuery } from '../../lib/proposals-data-provider/__generated__/Proposals';
import { useColumnDefs } from './use-column-defs';
import { useT } from '../../use-t';
export const getNewMarketProposals = (data: ProposalListFieldsFragment[]) =>
data.filter((proposal) =>
[
Types.ProposalState.STATE_OPEN,
Types.ProposalState.STATE_PASSED,
Types.ProposalState.STATE_WAITING_FOR_NODE_VOTE,
].includes(proposal.state)
);
const defaultColDef = {
sortable: true,
filter: true,
resizable: true,
filterParams: { buttons: ['reset'] },
};
interface ProposalListProps {
cellRenderers: {
[name: string]: FC<{ value: string; data: ProposalListFieldsFragment }>;
};
}
export const ProposalsList = ({ cellRenderers }: ProposalListProps) => {
const t = useT();
const { data } = useProposalsListQuery({
variables: {
proposalType: Types.ProposalType.TYPE_NEW_MARKET,
},
errorPolicy: 'all', // currently there are some proposals failing due to proposals existing without settlement asset ids
});
const filteredData = getNewMarketProposals(
removePaginationWrapper(data?.proposalsConnection?.edges)
);
const columnDefs = useColumnDefs();
return (
<AgGrid
columnDefs={columnDefs}
rowData={filteredData}
defaultColDef={defaultColDef}
getRowId={({ data }) => data.id}
overlayNoRowsTemplate={t('No proposed markets')}
components={cellRenderers}
rowHeight={45}
/>
);
};
@@ -485,14 +485,45 @@ fragment MarketViewProposalFields on Proposal {
}
}
fragment SubProposal on ProposalDetail {
id
batchId
reference
state
terms {
closingDatetime
enactmentDatetime
change {
__typename
... on UpdateMarketState {
...UpdateMarketStateFields
}
... on NewMarket {
...NewMarketSuccessorFields
}
... on UpdateMarket {
...UpdateMarketFields
}
}
}
}
query MarketViewProposals(
$proposalType: ProposalType
$inState: ProposalState
) {
proposalsConnection(proposalType: $proposalType, inState: $inState) {
edges {
node {
...MarketViewProposalFields
proposalNode {
... on BatchProposal {
id
subProposals {
...SubProposal
}
}
... on Proposal {
...MarketViewProposalFields
}
}
}
}
@@ -500,6 +531,8 @@ query MarketViewProposals(
subscription MarketViewLiveProposals {
proposals {
...MarketViewProposalFields
... on Proposal {
...MarketViewProposalFields
}
}
}

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