From 5f36742ce6104064a9ce5cfaa2b7f7a64cc3dc2d Mon Sep 17 00:00:00 2001 From: Fouad Date: Fri, 21 Oct 2022 09:51:19 +0100 Subject: [PATCH] fix up operating cost (#1698) --- .../src/components/Bonding/BondedMixnode.tsx | 4 +- .../Bonding/forms/mixnodeValidationSchema.ts | 18 ++++--- nym-wallet/src/context/bonding.tsx | 8 ++- nym-wallet/src/context/mocks/bonding.tsx | 2 +- .../general-settings/ParametersSettings.tsx | 52 +++++++++---------- .../settings-pages/general-settings/index.tsx | 3 +- 6 files changed, 44 insertions(+), 43 deletions(-) diff --git a/nym-wallet/src/components/Bonding/BondedMixnode.tsx b/nym-wallet/src/components/Bonding/BondedMixnode.tsx index 9cefa40331..a4df67a9d3 100644 --- a/nym-wallet/src/components/Bonding/BondedMixnode.tsx +++ b/nym-wallet/src/components/Bonding/BondedMixnode.tsx @@ -33,7 +33,7 @@ const headers: Header[] = [ 'The percentage of the node rewards that you as the node operator will take before the rest of the reward is shared between you and the delegators.', }, { - header: 'Operator cost', + header: 'Operating cost', id: 'operator-cost', // tooltipText: 'TODO', // TODO }, @@ -94,7 +94,7 @@ export const BondedMixnode = ({ id: 'pm-cell', }, { - cell: operatorCost ? `${operatorCost} NYM` : '-', + cell: operatorCost ? `${operatorCost.amount} ${operatorCost.denom}` : '-', id: 'operator-cost-cell', }, { diff --git a/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts b/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts index 3d6e407301..aa5752f4aa 100644 --- a/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts +++ b/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts @@ -37,15 +37,17 @@ export const mixnodeValidationSchema = Yup.object().shape({ const operatingCostAndPmValidation = { profitMargin: Yup.number().required('Profit Percentage is required').min(0).max(100), - operatorCost: Yup.string() - .required('An operating cost is required') - .test('valid-operating-cost', 'A valid amount is required (min 40)', async function isValidAmount(this, value) { - if (value && (!Number(value) || isLessThan(+value, 40))) { - return false; - } + operatorCost: Yup.object().shape({ + amount: Yup.string() + .required('An operating cost is required') + .test('valid-operating-cost', 'A valid amount is required (min 40)', async function isValidAmount(this, value) { + if (value && (!Number(value) || isLessThan(+value, 40))) { + return false; + } - return true; - }), + return true; + }), + }), }; export const amountSchema = Yup.object().shape({ diff --git a/nym-wallet/src/context/bonding.tsx b/nym-wallet/src/context/bonding.tsx index fcacae9f9b..6f87921db6 100644 --- a/nym-wallet/src/context/bonding.tsx +++ b/nym-wallet/src/context/bonding.tsx @@ -54,7 +54,7 @@ export type TBondedMixnode = { delegators: number; status: MixnodeStatus; proxy?: string; - operatorCost?: string; + operatorCost: DecCoin; host: string; estimatedRewards?: DecCoin; activeSetProbability?: SelectionChance; @@ -141,7 +141,6 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod const additionalDetails: { status: MixnodeStatus; stakeSaturation: string; - operatorCost?: string; estimatedRewards?: DecCoin; } = { status: 'not_found', @@ -163,7 +162,6 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod } try { const rewardEstimation = await getMixnodeRewardEstimation(mixId); - additionalDetails.operatorCost = unymToNym(rewardEstimation.estimation.operating_cost); const estimatedRewards = unymToNym(rewardEstimation.estimation.total_node_reward); if (estimatedRewards) { additionalDetails.estimatedRewards = { @@ -240,7 +238,7 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod bond_information: { mix_id }, } = data; - const { status, stakeSaturation, operatorCost, estimatedRewards } = await getAdditionalMixnodeDetails(mix_id); + const { status, stakeSaturation, estimatedRewards } = await getAdditionalMixnodeDetails(mix_id); const setProbabilities = await getSetProbabilities(mix_id); const nodeDescription = await getNodeDescription( bond_information.mix_node.host, @@ -261,7 +259,7 @@ export const BondingContextProvider = ({ children }: { children?: React.ReactNod operatorRewards, status, stakeSaturation, - operatorCost, + operatorCost: rewarding_details.cost_params.interval_operating_cost, host: bond_information.mix_node.host.replace(/\s/g, ''), routingScore, activeSetProbability: setProbabilities?.in_active, diff --git a/nym-wallet/src/context/mocks/bonding.tsx b/nym-wallet/src/context/mocks/bonding.tsx index 88f4df6530..6ab98ce490 100644 --- a/nym-wallet/src/context/mocks/bonding.tsx +++ b/nym-wallet/src/context/mocks/bonding.tsx @@ -16,7 +16,7 @@ const bondedMixnodeMock: TBondedMixnode = { operatorRewards: { denom: 'nym', amount: '1234' }, delegators: 5423, status: 'active', - operatorCost: '0.22', + operatorCost: { denom: 'nym', amount: '1234' }, host: '1.2.3.4', routingScore: 75, activeSetProbability: 'High', diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx index 0e30dc63a7..ce7a3d0250 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import { @@ -13,38 +13,42 @@ import { FormHelperText, } from '@mui/material'; import { useTheme } from '@mui/material/styles'; +import { CurrencyDenom, MixNodeCostParams } from '@nymproject/types'; +import { add, format, fromUnixTime } from 'date-fns'; import { isMixnode } from 'src/types'; import { getCurrentInterval, getPendingIntervalEvents, updateMixnodeCostParams } from 'src/requests'; import { TBondedMixnode, TBondedGateway } from 'src/context/bonding'; import { SimpleModal } from 'src/components/Modals/SimpleModal'; import { bondedNodeParametersValidationSchema } from 'src/components/Bonding/forms/mixnodeValidationSchema'; import { Console } from 'src/utils/console'; -import { add, format, fromUnixTime } from 'date-fns'; import { Alert } from 'src/components/Alert'; import { ChangeMixCostParams } from 'src/pages/bonding/types'; -import { MixNodeCostParams } from '@nymproject/types'; +import { AppContext } from 'src/context'; +import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; -export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode | TBondedGateway }): JSX.Element => { +export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): JSX.Element => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); const [intervalTime, setIntervalTime] = useState(); const [nextEpoch, setNextEpoch] = useState(); const [pendingUpdates, setPendingUpdates] = useState(); + const { clientDetails } = useContext(AppContext); const theme = useTheme(); + const defaultValues = { + operatorCost: bondedNode.operatorCost, + profitMargin: bondedNode.profitMargin, + }; + const { register, handleSubmit, reset, + setValue, formState: { errors, isSubmitting, isDirty, isValid }, } = useForm({ resolver: yupResolver(bondedNodeParametersValidationSchema), mode: 'onChange', - defaultValues: isMixnode(bondedNode) - ? { - operatorCost: bondedNode.operatorCost, - profitMargin: bondedNode.profitMargin, - } - : {}, + defaultValues, }); const getIntervalAsDate = async () => { @@ -91,13 +95,13 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode getPendingEvents(); }, []); - const onSubmit = async (data: { operatorCost?: string; profitMargin?: string }) => { + const onSubmit = async (data: { operatorCost: { amount: string; denom: CurrencyDenom }; profitMargin: string }) => { if (data.operatorCost && data.profitMargin) { const MixNodeCostParams = { profit_margin_percent: (+data.profitMargin / 100).toString(), interval_operating_cost: { - denom: bondedNode.bond.denom, - amount: data.operatorCost.toString(), + amount: data.operatorCost.amount, + denom: data.operatorCost.denom, }, }; try { @@ -188,20 +192,16 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode - - {bondedNode.bond.denom.toUpperCase()} - - ), + label="Operating cost" + onChanged={(newValue) => { + setValue('operatorCost', newValue, { shouldValidate: true, shouldDirty: true }); }} + validationError={errors.operatorCost?.amount?.message} + denom={clientDetails?.display_mix_denom || 'nym'} + initialValue={defaultValues.operatorCost.amount} /> {pendingUpdates && ( @@ -222,7 +222,7 @@ export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode size="large" variant="contained" disabled={isSubmitting || !isDirty || !isValid} - onClick={handleSubmit((d) => onSubmit(d))} + onClick={handleSubmit(onSubmit)} type="submit" sx={{ m: 3, width: '320px' }} endIcon={isSubmitting && } diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/index.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/index.tsx index 1e36b195f2..6597c096f7 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/index.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/index.tsx @@ -3,6 +3,7 @@ import { Box, Button, Divider, Grid } from '@mui/material'; import { TBondedMixnode, TBondedGateway } from '../../../../../context/bonding'; import { InfoSettings } from './InfoSettings'; import { ParametersSettings } from './ParametersSettings'; +import { isMixnode } from 'src/types'; const nodeGeneralNav = ['Info', 'Parameters']; @@ -34,7 +35,7 @@ export const NodeGeneralSettings = ({ bondedNode }: { bondedNode: TBondedMixnode {settingsCard === nodeGeneralNav[0] && } - {settingsCard === nodeGeneralNav[1] && } + {settingsCard === nodeGeneralNav[1] && isMixnode(bondedNode) && } );