diff --git a/apps/token/src/hooks/use-network-param.tsx b/apps/token/src/hooks/use-network-param.tsx deleted file mode 100644 index 6e871ddcf..000000000 --- a/apps/token/src/hooks/use-network-param.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { useQuery } from '@apollo/client'; -import { gql } from '@apollo/client'; - -import type { NetworkParams } from './__generated__/NetworkParams'; - -export const NETWORK_PARAMS_QUERY = gql` - query NetworkParams { - networkParameters { - key - value - } - } -`; - -export function useNetworkParam(params: string[]) { - const { data, loading, error } = useQuery( - NETWORK_PARAMS_QUERY - ); - - const foundParams = data?.networkParameters - ?.filter((p) => params.includes(p.key)) - .sort((a, b) => params.indexOf(a.key) - params.indexOf(b.key)); - - return { - data: foundParams ? foundParams.map((f) => f.value) : null, - loading, - error, - }; -} - -export function useNetworkParamWithKeys(params: string[]) { - const { data, loading, error } = useQuery( - NETWORK_PARAMS_QUERY - ); - - const foundParams = - params.length === 0 - ? data?.networkParameters - : data?.networkParameters?.filter((p) => params.includes(p.key)); - - const sortedParams = - foundParams && foundParams.length > 0 - ? [...foundParams].sort((a, b) => { - if (a.key < b.key) { - return -1; - } - if (a.key > b.key) { - return 1; - } - return 0; - }) - : null; - - return { - data: sortedParams, - loading, - error, - }; -} diff --git a/apps/token/src/routes/governance/hooks/use-vote-information.ts b/apps/token/src/routes/governance/hooks/use-vote-information.ts index 2bfc74852..e028c14b0 100644 --- a/apps/token/src/routes/governance/hooks/use-vote-information.ts +++ b/apps/token/src/routes/governance/hooks/use-vote-information.ts @@ -1,7 +1,6 @@ -import { useNetworkParams } from '@vegaprotocol/react-helpers'; +import { useNetworkParams, NetworkParams } from '@vegaprotocol/react-helpers'; import React from 'react'; -import { NetworkParams } from '../../../config'; import { useAppState } from '../../../contexts/app-state/app-state-context'; import { BigNumber } from '../../../lib/bignumber'; import { addDecimal } from '../../../lib/decimals'; @@ -16,63 +15,63 @@ const useProposalNetworkParams = ({ }: { proposal: ProposalFields; }) => { - const { data, loading } = useNetworkParams([ - NetworkParams.GOV_UPDATE_MARKET_REQUIRED_MAJORITY, - NetworkParams.GOV_UPDATE_MARKET_REQUIRED_PARTICIPATION, - NetworkParams.GOV_NEW_MARKET_REQUIRED_MAJORITY, - NetworkParams.GOV_NEW_MARKET_REQUIRED_PARTICIPATION, - NetworkParams.GOV_ASSET_REQUIRED_MAJORITY, - NetworkParams.GOV_ASSET_REQUIRED_PARTICIPATION, - NetworkParams.GOV_UPDATE_NET_PARAM_REQUIRED_MAJORITY, - NetworkParams.GOV_UPDATE_NET_PARAM_REQUIRED_PARTICIPATION, - NetworkParams.GOV_FREEFORM_REQUIRED_MAJORITY, - NetworkParams.GOV_FREEFORM_REQUIRED_PARTICIPATION, + const { params } = useNetworkParams([ + NetworkParams.governance_proposal_updateMarket_requiredMajority, + NetworkParams.governance_proposal_updateMarket_requiredParticipation, + NetworkParams.governance_proposal_market_requiredMajority, + NetworkParams.governance_proposal_market_requiredParticipation, + NetworkParams.governance_proposal_asset_requiredMajority, + NetworkParams.governance_proposal_asset_requiredParticipation, + NetworkParams.governance_proposal_updateNetParam_requiredMajority, + NetworkParams.governance_proposal_updateNetParam_requiredParticipation, + NetworkParams.governance_proposal_freeform_requiredMajority, + NetworkParams.governance_proposal_freeform_requiredParticipation, ]); - if (loading || !data) { + + if (!params) { return { requiredMajority: new BigNumber(1), requiredParticipation: new BigNumber(1), }; } - const [ - updateMarketMajority, - updateMarketParticipation, - newMarketMajority, - newMarketParticipation, - assetMajority, - assetParticipation, - paramMajority, - paramParticipation, - freeformMajority, - freeformParticipation, - ] = data; - switch (proposal.terms.change.__typename) { case 'UpdateMarket': return { - requiredMajority: updateMarketMajority, - requiredParticipation: new BigNumber(updateMarketParticipation), + requiredMajority: + params.governance_proposal_updateMarket_requiredMajority, + requiredParticipation: new BigNumber( + params.governance_proposal_updateMarket_requiredParticipation + ), }; case 'UpdateNetworkParameter': return { - requiredMajority: paramMajority, - requiredParticipation: new BigNumber(paramParticipation), + requiredMajority: + params.governance_proposal_updateNetParam_requiredMajority, + requiredParticipation: new BigNumber( + params.governance_proposal_updateNetParam_requiredParticipation + ), }; case 'NewAsset': return { - requiredMajority: assetMajority, - requiredParticipation: new BigNumber(assetParticipation), + requiredMajority: params.governance_proposal_asset_requiredMajority, + requiredParticipation: new BigNumber( + params.governance_proposal_asset_requiredParticipation + ), }; case 'NewMarket': return { - requiredMajority: newMarketMajority, - requiredParticipation: new BigNumber(newMarketParticipation), + requiredMajority: params.governance_proposal_market_requiredMajority, + requiredParticipation: new BigNumber( + params.governance_proposal_market_requiredParticipation + ), }; case 'NewFreeform': return { - requiredMajority: freeformMajority, - requiredParticipation: freeformParticipation, + requiredMajority: params.governance_proposal_freeform_requiredMajority, + requiredParticipation: new BigNumber( + params.governance_proposal_freeform_requiredParticipation + ), }; default: throw new Error('Unknown proposal type'); diff --git a/apps/token/src/routes/governance/propose/freeform/propose-freeform.tsx b/apps/token/src/routes/governance/propose/freeform/propose-freeform.tsx index e030db571..40047c41c 100644 --- a/apps/token/src/routes/governance/propose/freeform/propose-freeform.tsx +++ b/apps/token/src/routes/governance/propose/freeform/propose-freeform.tsx @@ -1,4 +1,3 @@ -import { useMemo } from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { @@ -19,9 +18,8 @@ import { import { AsyncRenderer, Link } from '@vegaprotocol/ui-toolkit'; import { Heading } from '../../../../components/heading'; import { VegaWalletContainer } from '../../../../components/vega-wallet-container'; -import { useNetworkParamWithKeys } from '../../../../hooks/use-network-param'; -import { NetworkParams } from '../../../../config'; import type { ProposalFreeformTerms } from '@vegaprotocol/wallet'; +import { useNetworkParams, NetworkParams } from '@vegaprotocol/react-helpers'; export interface FreeformProposalFormFields { proposalVoteDeadline: string; @@ -32,40 +30,13 @@ export interface FreeformProposalFormFields { } export const ProposeFreeform = () => { - const { - data: networkParamsData, - loading: networkParamsLoading, - error: networkParamsError, - } = useNetworkParamWithKeys([ - NetworkParams.GOV_FREEFORM_MIN_CLOSE, - NetworkParams.GOV_FREEFORM_MAX_CLOSE, - NetworkParams.GOV_FREEFORM_MIN_PROPOSER_BALANCE, - NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS, + const { params, loading, error } = useNetworkParams([ + NetworkParams.governance_proposal_freeform_minClose, + NetworkParams.governance_proposal_freeform_maxClose, + NetworkParams.governance_proposal_freeform_minProposerBalance, + NetworkParams.spam_protection_proposal_min_tokens, ]); - const { - minVoteDeadline, - maxVoteDeadline, - minProposerBalance, - minSpamBalance, - } = useMemo( - () => ({ - minVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_FREEFORM_MIN_CLOSE - )?.value, - maxVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_FREEFORM_MAX_CLOSE - )?.value, - minProposerBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_FREEFORM_MIN_PROPOSER_BALANCE - )?.value, - minSpamBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS - )?.value, - }), - [networkParamsData] - ); - const { VEGA_DOCS_URL, VEGA_EXPLORER_URL } = useEnvironment(); const { t } = useTranslation(); const { @@ -89,18 +60,16 @@ export const ProposeFreeform = () => { }; return ( - + {() => ( <> {VEGA_DOCS_URL && ( @@ -145,8 +114,8 @@ export const ProposeFreeform = () => { required: t('Required'), })} voteErrorMessage={errors?.proposalVoteDeadline?.message} - voteMinClose={minVoteDeadline as string} - voteMaxClose={maxVoteDeadline as string} + voteMinClose={params.governance_proposal_freeform_minClose} + voteMaxClose={params.governance_proposal_freeform_maxClose} /> diff --git a/apps/token/src/routes/governance/propose/network-parameter/propose-network-parameter.tsx b/apps/token/src/routes/governance/propose/network-parameter/propose-network-parameter.tsx index f68fc2886..65767f723 100644 --- a/apps/token/src/routes/governance/propose/network-parameter/propose-network-parameter.tsx +++ b/apps/token/src/routes/governance/propose/network-parameter/propose-network-parameter.tsx @@ -1,7 +1,9 @@ -import { useState, useMemo } from 'react'; +import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useForm } from 'react-hook-form'; -import { isJsonObject } from '@vegaprotocol/react-helpers'; +import type { NetworkParamsKey } from '@vegaprotocol/react-helpers'; +import { NetworkParams } from '@vegaprotocol/react-helpers'; +import { isJsonObject, useNetworkParams } from '@vegaprotocol/react-helpers'; import { useProposalSubmit, getClosingTimestamp, @@ -30,9 +32,6 @@ import { } from '@vegaprotocol/ui-toolkit'; import { Heading } from '../../../../components/heading'; import { VegaWalletContainer } from '../../../../components/vega-wallet-container'; -import { useNetworkParamWithKeys } from '../../../../hooks/use-network-param'; -import { NetworkParams } from '../../../../config'; -import type { ProposalNetworkParameterTerms } from '@vegaprotocol/wallet'; interface SelectedNetworkParamCurrentValueProps { value: string; @@ -72,46 +71,21 @@ export interface NetworkParameterProposalFormFields { export const ProposeNetworkParameter = () => { const [selectedNetworkParam, setSelectedNetworkParam] = useState< - string | undefined + NetworkParamsKey | undefined >(undefined); const { - data: networkParamsData, + params, loading: networkParamsLoading, error: networkParamsError, - } = useNetworkParamWithKeys([]); - - const { - minVoteDeadline, - maxVoteDeadline, - minEnactmentDeadline, - maxEnactmentDeadline, - minProposerBalance, - minSpamBalance, - } = useMemo( - () => ({ - minVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_NET_PARAM_MIN_CLOSE - )?.value, - maxVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_NET_PARAM_MAX_CLOSE - )?.value, - minEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_NET_PARAM_MIN_ENACT - )?.value, - maxEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_NET_PARAM_MAX_ENACT - )?.value, - minProposerBalance: networkParamsData?.find( - ({ key }) => - key === NetworkParams.GOV_UPDATE_NET_PARAM_MIN_PROPOSER_BALANCE - )?.value, - minSpamBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS - )?.value, - }), - [networkParamsData] - ); + } = useNetworkParams([ + NetworkParams.governance_proposal_updateNetParam_maxClose, + NetworkParams.governance_proposal_updateNetParam_minClose, + NetworkParams.governance_proposal_updateNetParam_maxEnact, + NetworkParams.governance_proposal_updateNetParam_minEnact, + NetworkParams.governance_proposal_updateNetParam_minProposerBalance, + NetworkParams.spam_protection_proposal_min_tokens, + ]); const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment(); const { t } = useTranslation(); @@ -140,7 +114,7 @@ export const ProposeNetworkParameter = () => { fields.proposalVoteDeadline, fields.proposalEnactmentDeadline ), - } as ProposalNetworkParameterTerms, + }, }); }; @@ -148,15 +122,17 @@ export const ProposeNetworkParameter = () => { {() => ( <> {VEGA_DOCS_URL && ( @@ -213,11 +189,15 @@ export const ProposeNetworkParameter = () => { {...register('proposalNetworkParameterKey', { required: t('Required'), })} - onChange={(e) => setSelectedNetworkParam(e.target.value)} + onChange={(e) => + setSelectedNetworkParam( + e.target.value as NetworkParamsKey + ) + } value={selectedNetworkParam} > - {networkParamsData?.map(({ key }) => ( + {Object.keys(params).map((key) => ( @@ -233,11 +213,7 @@ export const ProposeNetworkParameter = () => { {selectedNetworkParam && (
key === selectedNetworkParam - )?.value || '' - } + value={params[selectedNetworkParam]} /> { required: t('Required'), })} voteErrorMessage={errors?.proposalVoteDeadline?.message} - voteMinClose={minVoteDeadline as string} - voteMaxClose={maxVoteDeadline as string} + voteMinClose={ + params.governance_proposal_updateNetParam_minClose + } + voteMaxClose={ + params.governance_proposal_updateNetParam_maxClose + } enactmentRegister={register('proposalEnactmentDeadline', { required: t('Required'), })} enactmentErrorMessage={ errors?.proposalEnactmentDeadline?.message } - enactmentMinClose={minEnactmentDeadline as string} - enactmentMaxClose={maxEnactmentDeadline as string} + enactmentMinClose={ + params.governance_proposal_updateNetParam_minEnact + } + enactmentMaxClose={ + params.governance_proposal_updateNetParam_maxEnact + } /> diff --git a/apps/token/src/routes/governance/propose/new-asset/propose-new-asset.tsx b/apps/token/src/routes/governance/propose/new-asset/propose-new-asset.tsx index a7d95f1f4..602e4e985 100644 --- a/apps/token/src/routes/governance/propose/new-asset/propose-new-asset.tsx +++ b/apps/token/src/routes/governance/propose/new-asset/propose-new-asset.tsx @@ -1,4 +1,3 @@ -import { useMemo } from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { @@ -22,9 +21,8 @@ import { import { AsyncRenderer, Link } from '@vegaprotocol/ui-toolkit'; import { Heading } from '../../../../components/heading'; import { VegaWalletContainer } from '../../../../components/vega-wallet-container'; -import { useNetworkParamWithKeys } from '../../../../hooks/use-network-param'; -import { NetworkParams } from '../../../../config'; import type { ProposalNewAssetTerms } from '@vegaprotocol/wallet'; +import { NetworkParams, useNetworkParams } from '@vegaprotocol/react-helpers'; export interface NewAssetProposalFormFields { proposalVoteDeadline: string; @@ -38,49 +36,18 @@ export interface NewAssetProposalFormFields { export const ProposeNewAsset = () => { const { - data: networkParamsData, + params, loading: networkParamsLoading, error: networkParamsError, - } = useNetworkParamWithKeys([ - NetworkParams.GOV_ASSET_MIN_CLOSE, - NetworkParams.GOV_ASSET_MAX_CLOSE, - NetworkParams.GOV_ASSET_MIN_ENACT, - NetworkParams.GOV_ASSET_MAX_ENACT, - NetworkParams.GOV_ASSET_MIN_PROPOSER_BALANCE, - NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS, + } = useNetworkParams([ + NetworkParams.governance_proposal_asset_minClose, + NetworkParams.governance_proposal_asset_maxClose, + NetworkParams.governance_proposal_asset_minEnact, + NetworkParams.governance_proposal_asset_maxEnact, + NetworkParams.governance_proposal_asset_minProposerBalance, + NetworkParams.spam_protection_proposal_min_tokens, ]); - const { - minVoteDeadline, - maxVoteDeadline, - minEnactmentDeadline, - maxEnactmentDeadline, - minProposerBalance, - minSpamBalance, - } = useMemo( - () => ({ - minVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_ASSET_MIN_CLOSE - )?.value, - maxVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_ASSET_MAX_CLOSE - )?.value, - minEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_ASSET_MIN_ENACT - )?.value, - maxEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_ASSET_MAX_ENACT - )?.value, - minProposerBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_ASSET_MIN_PROPOSER_BALANCE - )?.value, - minSpamBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS - )?.value, - }), - [networkParamsData] - ); - const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment(); const { t } = useTranslation(); const { @@ -116,15 +83,17 @@ export const ProposeNewAsset = () => { {() => ( <> {VEGA_DOCS_URL && ( @@ -190,16 +159,16 @@ export const ProposeNewAsset = () => { required: t('Required'), })} voteErrorMessage={errors?.proposalVoteDeadline?.message} - voteMinClose={minVoteDeadline as string} - voteMaxClose={maxVoteDeadline as string} + voteMinClose={params.governance_proposal_asset_minClose} + voteMaxClose={params.governance_proposal_asset_maxClose} enactmentRegister={register('proposalEnactmentDeadline', { required: t('Required'), })} enactmentErrorMessage={ errors?.proposalEnactmentDeadline?.message } - enactmentMinClose={minEnactmentDeadline as string} - enactmentMaxClose={maxEnactmentDeadline as string} + enactmentMinClose={params.governance_proposal_asset_minEnact} + enactmentMaxClose={params.governance_proposal_asset_maxEnact} validationRequired={true} validationRegister={register('proposalValidationDeadline', { required: t('Required'), diff --git a/apps/token/src/routes/governance/propose/new-market/propose-new-market.tsx b/apps/token/src/routes/governance/propose/new-market/propose-new-market.tsx index c2a17b4c4..ef8ebba09 100644 --- a/apps/token/src/routes/governance/propose/new-market/propose-new-market.tsx +++ b/apps/token/src/routes/governance/propose/new-market/propose-new-market.tsx @@ -1,4 +1,3 @@ -import { useMemo } from 'react'; import { useForm } from 'react-hook-form'; import { useTranslation } from 'react-i18next'; import { @@ -21,9 +20,8 @@ import { import { AsyncRenderer, Link } from '@vegaprotocol/ui-toolkit'; import { Heading } from '../../../../components/heading'; import { VegaWalletContainer } from '../../../../components/vega-wallet-container'; -import { useNetworkParamWithKeys } from '../../../../hooks/use-network-param'; -import { NetworkParams } from '../../../../config'; import type { ProposalNewMarketTerms } from '@vegaprotocol/wallet'; +import { NetworkParams, useNetworkParams } from '@vegaprotocol/react-helpers'; export interface NewMarketProposalFormFields { proposalVoteDeadline: string; @@ -36,49 +34,18 @@ export interface NewMarketProposalFormFields { export const ProposeNewMarket = () => { const { - data: networkParamsData, + params, loading: networkParamsLoading, error: networkParamsError, - } = useNetworkParamWithKeys([ - NetworkParams.GOV_NEW_MARKET_MIN_CLOSE, - NetworkParams.GOV_NEW_MARKET_MAX_CLOSE, - NetworkParams.GOV_NEW_MARKET_MIN_ENACT, - NetworkParams.GOV_NEW_MARKET_MAX_ENACT, - NetworkParams.GOV_NEW_MARKET_MIN_PROPOSER_BALANCE, - NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS, + } = useNetworkParams([ + NetworkParams.governance_proposal_market_maxClose, + NetworkParams.governance_proposal_market_minClose, + NetworkParams.governance_proposal_market_maxEnact, + NetworkParams.governance_proposal_market_minEnact, + NetworkParams.governance_proposal_market_minProposerBalance, + NetworkParams.spam_protection_proposal_min_tokens, ]); - const { - minVoteDeadline, - maxVoteDeadline, - minEnactmentDeadline, - maxEnactmentDeadline, - minProposerBalance, - minSpamBalance, - } = useMemo( - () => ({ - minVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_NEW_MARKET_MIN_CLOSE - )?.value, - maxVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_NEW_MARKET_MAX_CLOSE - )?.value, - minEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_NEW_MARKET_MIN_ENACT - )?.value, - maxEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_NEW_MARKET_MAX_ENACT - )?.value, - minProposerBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_NEW_MARKET_MIN_PROPOSER_BALANCE - )?.value, - minSpamBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS - )?.value, - }), - [networkParamsData] - ); - const { VEGA_EXPLORER_URL, VEGA_DOCS_URL } = useEnvironment(); const { t } = useTranslation(); const { @@ -111,15 +78,17 @@ export const ProposeNewMarket = () => { {() => ( <> {VEGA_DOCS_URL && ( @@ -186,16 +155,16 @@ export const ProposeNewMarket = () => { required: t('Required'), })} voteErrorMessage={errors?.proposalVoteDeadline?.message} - voteMinClose={minVoteDeadline as string} - voteMaxClose={maxVoteDeadline as string} + voteMinClose={params.governance_proposal_market_minClose} + voteMaxClose={params.governance_proposal_market_maxClose} enactmentRegister={register('proposalEnactmentDeadline', { required: t('Required'), })} enactmentErrorMessage={ errors?.proposalEnactmentDeadline?.message } - enactmentMinClose={minEnactmentDeadline as string} - enactmentMaxClose={maxEnactmentDeadline as string} + enactmentMinClose={params.governance_proposal_market_minEnact} + enactmentMaxClose={params.governance_proposal_market_maxEnact} /> diff --git a/apps/token/src/routes/governance/propose/update-market/propose-update-market.tsx b/apps/token/src/routes/governance/propose/update-market/propose-update-market.tsx index dece9a0df..00dcaa919 100644 --- a/apps/token/src/routes/governance/propose/update-market/propose-update-market.tsx +++ b/apps/token/src/routes/governance/propose/update-market/propose-update-market.tsx @@ -29,10 +29,9 @@ import { } from '@vegaprotocol/ui-toolkit'; import { Heading } from '../../../../components/heading'; import { VegaWalletContainer } from '../../../../components/vega-wallet-container'; -import { useNetworkParamWithKeys } from '../../../../hooks/use-network-param'; -import { NetworkParams } from '../../../../config'; import type { ProposalUpdateMarketTerms } from '@vegaprotocol/wallet'; import type { ProposalMarketsQuery } from './__generated__/ProposalMarketsQuery'; +import { NetworkParams, useNetworkParams } from '@vegaprotocol/react-helpers'; const MARKETS_QUERY = gql` query ProposalMarketsQuery { @@ -64,16 +63,16 @@ export interface UpdateMarketProposalFormFields { export const ProposeUpdateMarket = () => { const { - data: networkParamsData, + params, loading: networkParamsLoading, error: networkParamsError, - } = useNetworkParamWithKeys([ - NetworkParams.GOV_UPDATE_MARKET_MIN_CLOSE, - NetworkParams.GOV_UPDATE_MARKET_MAX_CLOSE, - NetworkParams.GOV_UPDATE_MARKET_MIN_ENACT, - NetworkParams.GOV_UPDATE_MARKET_MAX_ENACT, - NetworkParams.GOV_UPDATE_MARKET_MIN_PROPOSER_BALANCE, - NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS, + } = useNetworkParams([ + NetworkParams.governance_proposal_updateMarket_maxClose, + NetworkParams.governance_proposal_updateMarket_minClose, + NetworkParams.governance_proposal_updateMarket_maxEnact, + NetworkParams.governance_proposal_updateMarket_minEnact, + NetworkParams.governance_proposal_updateMarket_minProposerBalance, + NetworkParams.spam_protection_proposal_min_tokens, ]); const { @@ -103,38 +102,6 @@ export const ProposeUpdateMarket = () => { }); }, [marketsData]); - const { - minVoteDeadline, - maxVoteDeadline, - minEnactmentDeadline, - maxEnactmentDeadline, - minProposerBalance, - minSpamBalance, - } = useMemo( - () => ({ - minVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_MARKET_MIN_CLOSE - )?.value, - maxVoteDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_MARKET_MAX_CLOSE - )?.value, - minEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_MARKET_MIN_ENACT - )?.value, - maxEnactmentDeadline: networkParamsData?.find( - ({ key }) => key === NetworkParams.GOV_UPDATE_MARKET_MAX_ENACT - )?.value, - minProposerBalance: networkParamsData?.find( - ({ key }) => - key === NetworkParams.GOV_UPDATE_MARKET_MIN_PROPOSER_BALANCE - )?.value, - minSpamBalance: networkParamsData?.find( - ({ key }) => key === NetworkParams.SPAM_PROTECTION_PROPOSAL_MIN_TOKENS - )?.value, - }), - [networkParamsData] - ); - const [selectedMarket, setSelectedMarket] = useState( undefined ); @@ -174,15 +141,17 @@ export const ProposeUpdateMarket = () => { {() => ( <> {VEGA_EXPLORER_URL && ( @@ -296,16 +265,24 @@ export const ProposeUpdateMarket = () => { required: t('Required'), })} voteErrorMessage={errors?.proposalVoteDeadline?.message} - voteMinClose={minVoteDeadline as string} - voteMaxClose={maxVoteDeadline as string} + voteMinClose={ + params.governance_proposal_updateMarket_minClose + } + voteMaxClose={ + params.governance_proposal_updateMarket_maxClose + } enactmentRegister={register('proposalEnactmentDeadline', { required: t('Required'), })} enactmentErrorMessage={ errors?.proposalEnactmentDeadline?.message } - enactmentMinClose={minEnactmentDeadline as string} - enactmentMaxClose={maxEnactmentDeadline as string} + enactmentMinClose={ + params.governance_proposal_updateMarket_minEnact + } + enactmentMaxClose={ + params.governance_proposal_updateMarket_maxEnact + } /> diff --git a/apps/token/src/routes/rewards/home/index.tsx b/apps/token/src/routes/rewards/home/index.tsx index aa6beb2aa..86e093b59 100644 --- a/apps/token/src/routes/rewards/home/index.tsx +++ b/apps/token/src/routes/rewards/home/index.tsx @@ -10,7 +10,6 @@ import { useTranslation } from 'react-i18next'; import { EpochCountdown } from '../../../components/epoch-countdown'; import { Heading } from '../../../components/heading'; import { SplashLoader } from '../../../components/splash-loader'; -import { NetworkParams } from '../../../config'; import { AppStateActionType, useAppState, @@ -18,7 +17,7 @@ import { import type { Rewards } from './__generated__/Rewards'; import { RewardInfo } from './reward-info'; import { useVegaWallet } from '@vegaprotocol/wallet'; -import { useNetworkParams } from '@vegaprotocol/react-helpers'; +import { useNetworkParams, NetworkParams } from '@vegaprotocol/react-helpers'; export const REWARDS_QUERY = gql` query Rewards($partyId: ID!) { @@ -73,33 +72,30 @@ export const RewardsIndex = () => { variables: { partyId: keypair?.pub }, skip: !keypair?.pub, }); - const { - data: rewardAssetData, - loading: rewardAssetLoading, - error: rewardAssetError, - } = useNetworkParams([ - NetworkParams.REWARD_ASSET, - NetworkParams.REWARD_PAYOUT_DURATION, + const { params } = useNetworkParams([ + NetworkParams.reward_asset, + NetworkParams.reward_staking_delegation_payoutDelay, ]); const payoutDuration = React.useMemo(() => { - if (!rewardAssetData || !rewardAssetData[1]) { + if (!params) { return 0; } - return new Duration(rewardAssetData[1]).milliseconds(); - }, [rewardAssetData]); + return new Duration( + params.reward_staking_delegation_payoutDelay + ).milliseconds(); + }, [params]); - if (error || rewardAssetError) { + if (error) { return (

{t('Something went wrong')}

{error &&
{error.message}
} - {rewardAssetError &&
{rewardAssetError.message}
}
); } - if (loading || rewardAssetLoading || !rewardAssetData?.length) { + if (loading || !params) { return ( @@ -145,7 +141,7 @@ export const RewardsIndex = () => { ) : (
diff --git a/apps/token/src/routes/staking/staking-form.tsx b/apps/token/src/routes/staking/staking-form.tsx index 666639328..7ab1f5b16 100644 --- a/apps/token/src/routes/staking/staking-form.tsx +++ b/apps/token/src/routes/staking/staking-form.tsx @@ -5,7 +5,6 @@ import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import { TokenInput } from '../../components/token-input'; -import { NetworkParams } from '../../config'; import { useAppState } from '../../contexts/app-state/app-state-context'; import { useSearchParams } from '../../hooks/use-search-params'; import { BigNumber } from '../../lib/bignumber'; @@ -30,7 +29,7 @@ import type { UndelegateSubmissionBody, } from '@vegaprotocol/wallet'; import { useVegaWallet } from '@vegaprotocol/wallet'; -import { useNetworkParam } from '@vegaprotocol/react-helpers'; +import { useNetworkParam, NetworkParams } from '@vegaprotocol/react-helpers'; export const PARTY_DELEGATIONS_QUERY = gql` query PartyDelegations($partyId: ID!) { @@ -103,14 +102,14 @@ export const StakingForm = ({ setAmount(''); }, [action, setAmount]); - const { data } = useNetworkParam( - NetworkParams.VALIDATOR_DELEGATION_MIN_AMOUNT + const { param: minAmount } = useNetworkParam( + NetworkParams.validators_delegation_minAmount ); const minTokensWithDecimals = React.useMemo(() => { - const minTokens = new BigNumber(data && data.length === 1 ? data[0] : ''); + const minTokens = new BigNumber(minAmount !== null ? minAmount : ''); return addDecimal(minTokens, appState.decimals); - }, [appState.decimals, data]); + }, [appState.decimals, minAmount]); const maxDelegation = React.useMemo(() => { if (action === Actions.Add) { diff --git a/libs/liquidity/src/lib/liquidity-data-provider.ts b/libs/liquidity/src/lib/liquidity-data-provider.ts index 7e0821206..cba4b7d7a 100644 --- a/libs/liquidity/src/lib/liquidity-data-provider.ts +++ b/libs/liquidity/src/lib/liquidity-data-provider.ts @@ -1,15 +1,13 @@ import { gql, useQuery } from '@apollo/client'; import type { LiquidityProvisionStatus } from '@vegaprotocol/types'; import { AccountType } from '@vegaprotocol/types'; -import { useNetworkParam } from '@vegaprotocol/react-helpers'; +import { useNetworkParam, NetworkParams } from '@vegaprotocol/react-helpers'; import BigNumber from 'bignumber.js'; import type { MarketLiquidity, MarketLiquidity_market_data_liquidityProviderFeeShare, } from './__generated__'; -const SISKA_NETWORK_PARAMETER = 'market.liquidity.stakeToCcySiskas'; - const MARKET_LIQUIDITY_QUERY = gql` query MarketLiquidity($marketId: ID!, $partyId: String) { market(id: $marketId) { @@ -106,7 +104,9 @@ export const useLiquidityProvision = ({ partyId?: string; marketId?: string; }) => { - const { data: stakeToCcySiskas } = useNetworkParam(SISKA_NETWORK_PARAMETER); + const { param: stakeToCcySiskas } = useNetworkParam( + NetworkParams.market_liquidity_stakeToCcySiskas + ); const stakeToCcySiska = stakeToCcySiskas && stakeToCcySiskas[0]; const { data, loading, error } = useQuery( MARKET_LIQUIDITY_QUERY, diff --git a/libs/react-helpers/src/hooks/use-network-params.spec.tsx b/libs/react-helpers/src/hooks/use-network-params.spec.tsx new file mode 100644 index 000000000..bae1e2344 --- /dev/null +++ b/libs/react-helpers/src/hooks/use-network-params.spec.tsx @@ -0,0 +1,116 @@ +import { renderHook, waitFor } from '@testing-library/react'; +import type { MockedResponse } from '@apollo/client/testing'; +import { MockedProvider } from '@apollo/client/testing'; +import type { NetworkParamsKey } from './use-network-params'; +import { + NetworkParams, + NETWORK_PARAMETERS_QUERY, + NETWORK_PARAMETER_QUERY, + useNetworkParam, + useNetworkParams, +} from './use-network-params'; +import type { ReactNode } from 'react'; +import type { NetworkParams as NetworkParamsResponse } from './__generated__'; +import { act } from 'react-dom/test-utils'; + +describe('useNetworkParam', () => { + const setup = (arg: NetworkParamsKey) => { + const mock: MockedResponse = { + request: { + query: NETWORK_PARAMETER_QUERY, + variables: { + key: arg, + }, + }, + result: { + data: { + networkParameter: { + __typename: 'NetworkParameter', + key: 'reward.staking.delegation.payoutDelay', + value: '200', + }, + }, + }, + }; + const wrapper = ({ children }: { children: ReactNode }) => ( + {children} + ); + + return renderHook(() => useNetworkParam(arg), { wrapper }); + }; + + it('returns a single param value', async () => { + const { result } = setup( + NetworkParams.reward_staking_delegation_payoutDelay + ); + expect(result.current.param).toBe(null); + await waitFor(() => { + expect(result.current.param).toEqual('200'); + }); + }); +}); + +describe('useNetworkParams', () => { + const setup = (args?: NetworkParamsKey[]) => { + const mock: MockedResponse = { + request: { + query: NETWORK_PARAMETERS_QUERY, + }, + result: { + data: { + networkParameters: [ + { + __typename: 'NetworkParameter', + key: 'spam.protection.proposal.min.tokens', + value: '1', + }, + { + __typename: 'NetworkParameter', + key: 'governance.proposal.updateMarket.minProposerBalance', + value: '1', + }, + { + __typename: 'NetworkParameter', + key: 'reward.staking.delegation.payoutDelay', + value: '200', + }, + ], + }, + }, + }; + const wrapper = ({ children }: { children: ReactNode }) => ( + {children} + ); + + return renderHook(() => useNetworkParams(args), { wrapper }); + }; + it('returns an object with only desired params', async () => { + const { result } = setup([ + NetworkParams.spam_protection_proposal_min_tokens, + NetworkParams.governance_proposal_updateMarket_minProposerBalance, + ]); + + expect(result.current.params).toBe(null); + + await waitFor(() => { + expect(result.current.params).toEqual({ + spam_protection_proposal_min_tokens: '1', + governance_proposal_updateMarket_minProposerBalance: '1', + }); + }); + }); + + it('returns all params', async () => { + const { result } = setup(); + + expect(result.current.params).toBe(null); + + await waitFor(() => { + expect(result.current.params).toEqual({ + spam_protection_proposal_min_tokens: '1', + governance_proposal_updateMarket_minProposerBalance: '1', + reward_staking_delegation_payoutDelay: '200', + }); + }); + }); +}); diff --git a/libs/react-helpers/src/hooks/use-network-params.ts b/libs/react-helpers/src/hooks/use-network-params.ts index c8c16cb3d..e373c86fb 100644 --- a/libs/react-helpers/src/hooks/use-network-params.ts +++ b/libs/react-helpers/src/hooks/use-network-params.ts @@ -1,5 +1,6 @@ import { gql, useQuery } from '@apollo/client'; -import type { NetworkParams } from './__generated__/NetworkParams'; +import { useMemo } from 'react'; +import type { NetworkParams as NetworkParamsResponse } from './__generated__'; export const NETWORK_PARAMETERS_QUERY = gql` query NetworkParams { @@ -10,27 +11,127 @@ export const NETWORK_PARAMETERS_QUERY = gql` } `; -export const useNetworkParam = (param: string) => { - const { data, loading, error } = useQuery( +export const NETWORK_PARAMETER_QUERY = gql` + query NetworkParam($key: String!) { + networkParameter(key: $key) { + key + value + } + } +`; + +export const NetworkParams = { + blockchains_ethereumConfig: 'blockchains_ethereumConfig', + reward_asset: 'reward_asset', + reward_staking_delegation_payoutDelay: + 'reward_staking_delegation_payoutDelay', + governance_proposal_updateMarket_requiredMajority: + 'governance_proposal_updateMarket_requiredMajority', + governance_proposal_market_minClose: 'governance_proposal_market_minClose', + governance_proposal_market_maxClose: 'governance_proposal_market_maxClose', + governance_proposal_market_minEnact: 'governance_proposal_market_minEnact', + governance_proposal_market_maxEnact: 'governance_proposal_market_maxEnact', + governance_proposal_updateMarket_minClose: + 'governance_proposal_updateMarket_minClose', + governance_proposal_updateMarket_maxClose: + 'governance_proposal_updateMarket_maxClose', + governance_proposal_updateMarket_minEnact: + 'governance_proposal_updateMarket_minEnact', + governance_proposal_updateMarket_maxEnact: + 'governance_proposal_updateMarket_maxEnact', + governance_proposal_asset_minClose: 'governance_proposal_asset_minClose', + governance_proposal_asset_maxClose: 'governance_proposal_asset_maxClose', + governance_proposal_asset_minEnact: 'governance_proposal_asset_minEnact', + governance_proposal_asset_maxEnact: 'governance_proposal_asset_maxEnact', + governance_proposal_updateNetParam_minClose: + 'governance_proposal_updateNetParam_minClose', + governance_proposal_updateNetParam_maxClose: + 'governance_proposal_updateNetParam_maxClose', + governance_proposal_updateNetParam_minEnact: + 'governance_proposal_updateNetParam_minEnact', + governance_proposal_updateNetParam_maxEnact: + 'governance_proposal_updateNetParam_maxEnact', + governance_proposal_freeform_minClose: + 'governance_proposal_freeform_minClose', + governance_proposal_freeform_maxClose: + 'governance_proposal_freeform_maxClose', + governance_proposal_updateMarket_requiredParticipation: + 'governance_proposal_updateMarket_requiredParticipation', + governance_proposal_updateMarket_minProposerBalance: + 'governance_proposal_updateMarket_minProposerBalance', + governance_proposal_market_requiredMajority: + 'governance_proposal_market_requiredMajority', + governance_proposal_market_requiredParticipation: + 'governance_proposal_market_requiredParticipation', + governance_proposal_market_minProposerBalance: + 'governance_proposal_market_minProposerBalance', + governance_proposal_asset_requiredMajority: + 'governance_proposal_asset_requiredMajority', + governance_proposal_asset_requiredParticipation: + 'governance_proposal_asset_requiredParticipation', + governance_proposal_asset_minProposerBalance: + 'governance_proposal_asset_minProposerBalance', + governance_proposal_updateNetParam_requiredMajority: + 'governance_proposal_updateNetParam_requiredMajority', + governance_proposal_updateNetParam_requiredParticipation: + 'governance_proposal_updateNetParam_requiredParticipation', + governance_proposal_updateNetParam_minProposerBalance: + 'governance_proposal_updateNetParam_minProposerBalance', + governance_proposal_freeform_requiredParticipation: + 'governance_proposal_freeform_requiredParticipation', + governance_proposal_freeform_requiredMajority: + 'governance_proposal_freeform_requiredMajority', + governance_proposal_freeform_minProposerBalance: + 'governance_proposal_freeform_minProposerBalance', + validators_delegation_minAmount: 'validators_delegation_minAmount', + spam_protection_proposal_min_tokens: 'spam_protection_proposal_min_tokens', + market_liquidity_stakeToCcySiskas: 'market_liquidity_stakeToCcySiskas', +} as const; + +type Params = typeof NetworkParams; +export type NetworkParamsKey = Params[keyof Params]; +type Result = { + [key in keyof Params]: string; +}; + +export const useNetworkParams = (params?: T) => { + const { data, loading, error } = useQuery( NETWORK_PARAMETERS_QUERY ); - const foundParams = data?.networkParameters?.filter((p) => param === p.key); + + const paramsObj = useMemo(() => { + if (!data?.networkParameters) return null; + return data.networkParameters + .map((p) => ({ + ...p, + key: p.key.split('.').join('_'), + })) + .filter((p) => { + if (params === undefined || params.length === 0) return true; + if (params.includes(p.key as NetworkParamsKey)) return true; + return false; + }) + .reduce((obj, p) => { + obj[p.key] = p.value; + return obj; + }, {} as { [key: string]: string }); + }, [data, params]); + return { - data: foundParams ? foundParams.map((f) => f.value) : null, + params: paramsObj as Pick, loading, error, }; }; -export const useNetworkParams = (params: string[]) => { - const { data, loading, error } = useQuery( - NETWORK_PARAMETERS_QUERY - ); - const foundParams = data?.networkParameters - ?.filter((p) => params.includes(p.key)) - .sort((a, b) => params.indexOf(a.key) - params.indexOf(b.key)); +export const useNetworkParam = (param: NetworkParamsKey) => { + const { data, loading, error } = useQuery(NETWORK_PARAMETER_QUERY, { + variables: { + key: param, + }, + }); return { - data: foundParams ? foundParams.map((f) => f.value) : null, + param: data?.networkParameter ? data.networkParameter.value : null, loading, error, };