Remove legacy

This commit is contained in:
Tommy Verrall
2025-04-07 15:27:54 +02:00
parent ca0449e03d
commit 7b75f22a8e
10 changed files with 0 additions and 1220 deletions
@@ -1,46 +0,0 @@
import React from 'react';
import { Box } from '@mui/material';
import { NodeTypeSelector } from 'src/components';
import { CurrencyDenom, TNodeType } from '@nymproject/types';
import { GatewayAmount, GatewayData } from 'src/pages/bonding/types';
import GatewayInitForm from './GatewayInitForm';
import GatewayAmountForm from './GatewayAmountForm';
export const BondGatewayForm = ({
step,
denom,
gatewayData,
amountData,
hasVestingTokens,
onSelectNodeType,
onValidateGatewayData,
onValidateAmountData,
}: {
step: 1 | 2 | 3 | 4;
gatewayData: GatewayData;
amountData: GatewayAmount;
denom: CurrencyDenom;
hasVestingTokens: boolean;
onSelectNodeType: (nodeType: TNodeType) => void;
onValidateGatewayData: (data: GatewayData) => void;
onValidateAmountData: (data: GatewayAmount) => Promise<void>;
}) => (
<>
{step === 1 && (
<>
<Box sx={{ mb: 2 }}>
<NodeTypeSelector disabled={false} setNodeType={onSelectNodeType} nodeType="gateway" />
</Box>
<GatewayInitForm onNext={onValidateGatewayData} gatewayData={gatewayData} />
</>
)}
{step === 2 && (
<GatewayAmountForm
denom={denom}
amountData={amountData}
hasVestingTokens={hasVestingTokens}
onNext={onValidateAmountData}
/>
)}
</>
);
@@ -1,84 +0,0 @@
import React, { useEffect } from 'react';
import { CurrencyDenom } from '@nymproject/types';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
import { Box, Stack } from '@mui/material';
import { amountSchema } from './gatewayValidationSchema';
import { checkHasEnoughFunds, checkHasEnoughLockedTokens } from '../../../../utils';
import { GatewayAmount } from '../../../../pages/bonding/types';
import { TokenPoolSelector } from '../../../TokenPoolSelector';
const GatewayAmountForm = ({
denom,
amountData,
hasVestingTokens,
onNext,
}: {
denom: CurrencyDenom;
amountData: GatewayAmount;
hasVestingTokens: boolean;
onNext: (data: any) => void;
}) => {
const {
formState: { errors },
handleSubmit,
setValue,
getValues,
setError,
} = useForm({ resolver: yupResolver(amountSchema), defaultValues: amountData });
const handleRequestValidation = async (event: { detail: { step: number } }) => {
let hasSufficientTokens = true;
const values = getValues();
if (values.tokenPool === 'balance') {
hasSufficientTokens = await checkHasEnoughFunds(values.amount.amount);
}
if (values.tokenPool === 'locked') {
hasSufficientTokens = await checkHasEnoughLockedTokens(values.amount.amount);
}
if (event.detail.step === 2 && hasSufficientTokens) {
handleSubmit(onNext)();
} else {
setError('amount.amount', { message: 'Not enough tokens' });
}
};
useEffect(() => {
window.addEventListener('validate_bond_gateway_step' as any, handleRequestValidation);
return () => window.removeEventListener('validate_bond_gateway_step' as any, handleRequestValidation);
}, []);
return (
<Stack gap={3}>
<Box display="flex" gap={3} justifyContent="center" sx={{ mt: 2 }}>
{hasVestingTokens && <TokenPoolSelector disabled={false} onSelect={(pool) => setValue('tokenPool', pool)} />}
<CurrencyFormField
required
fullWidth
label="Amount"
autoFocus
onChanged={(newValue) => setValue('amount', newValue, { shouldValidate: true })}
validationError={errors.amount?.amount?.message}
denom={denom}
initialValue={amountData.amount.amount}
/>
<CurrencyFormField
required
fullWidth
label="Operator Cost"
autoFocus
onChanged={(newValue) => setValue('operatorCost', newValue, { shouldValidate: true })}
validationError={errors.operatorCost?.amount?.message}
denom={denom}
initialValue={amountData.operatorCost.amount}
/>
</Box>
</Stack>
);
};
export default GatewayAmountForm;
@@ -1,124 +0,0 @@
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { clean } from 'semver';
import { Checkbox, FormControlLabel, Stack, TextField } from '@mui/material';
import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { GatewayData } from '../../../../pages/bonding/types';
import { gatewayValidationSchema } from './gatewayValidationSchema';
const GatewayInitForm = ({
gatewayData,
onNext,
}: {
gatewayData: GatewayData;
onNext: (data: GatewayData) => void;
}) => {
const [showAdvancedOptions, setShowAdvancedOptions] = useState(false);
const {
register,
formState: { errors },
handleSubmit,
setValue,
} = useForm({ resolver: yupResolver(gatewayValidationSchema), defaultValues: gatewayData });
const handleRequestValidation = (event: { detail: { step: number } }) => {
if (event.detail.step === 1) {
handleSubmit((data) => {
const validatedData = {
...data,
version: clean(data.version) as string,
};
onNext(validatedData);
})();
}
};
useEffect(() => {
window.addEventListener('validate_bond_gateway_step' as any, handleRequestValidation);
return () => window.removeEventListener('validate_bond_gateway_step' as any, handleRequestValidation);
}, []);
return (
<Stack gap={3}>
<IdentityKeyFormField
required
fullWidth
label="Identity Key"
initialValue={gatewayData?.identityKey}
errorText={errors.identityKey?.message}
onChanged={(value) => setValue('identityKey', value)}
showTickOnValid={false}
/>
<TextField
{...register('sphinxKey')}
name="sphinxKey"
label="Sphinx key"
error={Boolean(errors.sphinxKey)}
helperText={errors.sphinxKey?.message}
InputLabelProps={{ shrink: true }}
/>
<TextField
{...register('location')}
name="location"
label="Location"
error={Boolean(errors.location)}
helperText={errors.location?.message}
required
InputLabelProps={{ shrink: true }}
sx={{ flexBasis: '50%' }}
/>
<Stack direction="row" gap={3}>
<TextField
{...register('host')}
name="host"
label="Host"
error={Boolean(errors.host)}
helperText={errors.host?.message}
required
InputLabelProps={{ shrink: true }}
sx={{ flexBasis: '50%' }}
/>
<TextField
{...register('version')}
name="version"
label="Version"
error={Boolean(errors.version)}
helperText={errors.version?.message}
required
InputLabelProps={{ shrink: true }}
sx={{ flexBasis: '50%' }}
/>
</Stack>
<FormControlLabel
control={<Checkbox onChange={() => setShowAdvancedOptions((show) => !show)} checked={showAdvancedOptions} />}
label="Show advanced options"
/>
{showAdvancedOptions && (
<Stack direction="row" gap={3} sx={{ mb: 2 }}>
<TextField
{...register('mixPort')}
name="mixPort"
label="Mix port"
error={Boolean(errors.mixPort)}
helperText={errors.mixPort?.message}
fullWidth
InputLabelProps={{ shrink: true }}
/>
<TextField
{...register('clientsPort')}
name="clientsPort"
label="Client WS API port"
error={Boolean(errors.clientsPort)}
helperText={errors.clientsPort?.message}
fullWidth
InputLabelProps={{ shrink: true }}
/>
</Stack>
)}
</Stack>
);
};
export default GatewayInitForm;
@@ -1,125 +0,0 @@
import React, { useContext, useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { Box, FormHelperText, Stack, TextField, Typography } from '@mui/material';
import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField';
import { CurrencyDenom } from '@nymproject/types';
import { amountSchema } from './mixnodeValidationSchema';
import { MixnodeAmount } from '../../../../pages/bonding/types';
import { AppContext } from '../../../../context';
import { checkHasEnoughFunds, checkHasEnoughLockedTokens } from '../../../../utils';
import { TokenPoolSelector } from '../../../TokenPoolSelector';
import { ModalListItem } from '../../../Modals/ModalListItem';
const MixnodeAmountForm = ({
amountData,
hasVestingTokens,
denom,
onNext,
}: {
amountData: MixnodeAmount;
hasVestingTokens: boolean;
denom: CurrencyDenom;
onNext: (data: MixnodeAmount) => void;
}) => {
const { mixnetContractParams } = useContext(AppContext);
const {
register,
formState: { errors },
handleSubmit,
setValue,
getValues,
setError,
} = useForm({ resolver: yupResolver(amountSchema(mixnetContractParams)), defaultValues: amountData });
const { userBalance } = useContext(AppContext);
const handleRequestValidation = async (event: { detail: { step: number } }) => {
let hasSufficientTokens = true;
const values = getValues();
if (values.tokenPool === 'balance') {
hasSufficientTokens = await checkHasEnoughFunds(values.amount.amount);
}
if (values.tokenPool === 'locked') {
hasSufficientTokens = await checkHasEnoughLockedTokens(values.amount.amount);
}
if (event.detail.step === 2 && hasSufficientTokens) {
handleSubmit(onNext)();
} else {
setError('amount.amount', { message: 'Not enough tokens' });
}
};
useEffect(() => {
window.addEventListener('validate_bond_mixnode_step' as any, handleRequestValidation);
return () => window.removeEventListener('validate_bond_mixnode_step' as any, handleRequestValidation);
}, []);
return (
<Stack gap={3}>
<Box display="flex" gap={3} justifyContent="center">
{hasVestingTokens && <TokenPoolSelector disabled={false} onSelect={(pool) => setValue('tokenPool', pool)} />}
<CurrencyFormField
required
fullWidth
label="Amount"
autoFocus
onChanged={(newValue) => {
setValue('amount', newValue, { shouldValidate: true });
}}
validationError={errors.amount?.amount?.message}
denom={denom}
initialValue={amountData.amount.amount}
/>
</Box>
<Box>
<CurrencyFormField
required
fullWidth
label="Operating cost"
onChanged={(newValue) => {
setValue('operatorCost', newValue, { shouldValidate: true });
}}
validationError={errors.operatorCost?.amount?.message}
denom={denom}
initialValue={amountData.operatorCost.amount}
/>
<FormHelperText>
Monthly operational costs of running your node. If your node is in the active set the amount will be paid back
to you from the rewards.
</FormHelperText>
</Box>
<Box>
<TextField
{...register('profitMargin')}
name="profitMargin"
label="Profit margin"
error={Boolean(errors.profitMargin)}
helperText={errors.profitMargin?.message}
fullWidth
/>
<FormHelperText>
The percentage of node rewards that you as the node operator take before rewards are distributed to operator
and delegators.
</FormHelperText>
</Box>
<Box sx={{ mb: 1 }}>
{!hasVestingTokens && (
<ModalListItem
divider
label="Account balance"
value={userBalance.balance?.printable_balance.toUpperCase()}
fontWeight={600}
/>
)}
<Typography variant="body2">Est. fee for this transaction will be calculated in the next page</Typography>
</Box>
</Stack>
);
};
export default MixnodeAmountForm;
@@ -1,117 +0,0 @@
import React, { useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { clean } from 'semver';
import { Checkbox, FormControlLabel, Stack, TextField } from '@mui/material';
import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField';
import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { mixnodeValidationSchema } from './mixnodeValidationSchema';
import { MixnodeData } from '../../../../pages/bonding/types';
const MixnodeInitForm = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; onNext: (data: any) => void }) => {
const [showAdvancedOptions, setShowAdvancedOptions] = useState(false);
const {
register,
formState: { errors },
handleSubmit,
setValue,
} = useForm({ resolver: yupResolver(mixnodeValidationSchema), defaultValues: mixnodeData });
const handleRequestValidation = (event: { detail: { step: number } }) => {
if (event.detail.step === 1) {
handleSubmit((data) => {
const validatedData = {
...data,
version: clean(data.version),
};
onNext(validatedData);
})();
}
};
useEffect(() => {
window.addEventListener('validate_bond_mixnode_step' as any, handleRequestValidation);
return () => window.removeEventListener('validate_bond_mixnode_step' as any, handleRequestValidation);
}, []);
return (
<Stack gap={3}>
<IdentityKeyFormField
required
fullWidth
label="Identity Key"
initialValue={mixnodeData?.identityKey}
errorText={errors.identityKey?.message}
onChanged={(value) => setValue('identityKey', value)}
showTickOnValid={false}
/>
<TextField
{...register('sphinxKey')}
name="sphinxKey"
label="Sphinx key"
error={Boolean(errors.sphinxKey)}
helperText={errors.sphinxKey?.message}
InputLabelProps={{ shrink: true }}
/>
<Stack direction="row" gap={3}>
<TextField
{...register('host')}
name="host"
label="Host"
error={Boolean(errors.host)}
helperText={errors.host?.message}
required
InputLabelProps={{ shrink: true }}
sx={{ flexBasis: '50%' }}
/>
<TextField
{...register('version')}
name="version"
label="Version"
error={Boolean(errors.version)}
helperText={errors.version?.message}
required
InputLabelProps={{ shrink: true }}
sx={{ flexBasis: '50%' }}
/>
</Stack>
<FormControlLabel
control={<Checkbox onChange={() => setShowAdvancedOptions((show) => !show)} checked={showAdvancedOptions} />}
label="Show advanced options"
/>
{showAdvancedOptions && (
<Stack direction="row" gap={3} sx={{ mb: 2 }}>
<TextField
{...register('mixPort')}
name="mixPort"
label="Mix port"
error={Boolean(errors.mixPort)}
helperText={errors.mixPort?.message}
fullWidth
InputLabelProps={{ shrink: true }}
/>
<TextField
{...register('verlocPort')}
name="verlocPort"
label="Verloc port"
error={Boolean(errors.verlocPort)}
helperText={errors.verlocPort?.message}
fullWidth
InputLabelProps={{ shrink: true }}
/>
<TextField
{...register('httpApiPort')}
name="httpApiPort"
label="HTTP api port"
error={Boolean(errors.httpApiPort)}
helperText={errors.httpApiPort?.message}
fullWidth
InputLabelProps={{ shrink: true }}
/>
</Stack>
)}
</Stack>
);
};
export default MixnodeInitForm;
@@ -1,91 +0,0 @@
import * as Yup from 'yup';
import {
isLessThan,
isValidHostname,
validateAmount,
validateKey,
validateLocation,
validateRawPort,
validateVersion,
} from 'src/utils';
export const gatewayValidationSchema = Yup.object().shape({
identityKey: Yup.string()
.required('An identity key is required')
.test('valid-id-key', 'A valid identity key is required', (value) => validateKey(value || '', 32)),
sphinxKey: Yup.string()
.required('A sphinx key is required')
.test('valid-sphinx-key', 'A valid sphinx key is required', (value) => validateKey(value || '', 32)),
host: Yup.string()
.required('A host is required')
.test('no-whitespace', 'Host cannot contain whitespace', (value) => !/\s/.test(value || ''))
.test('valid-host', 'A valid host is required', (value) => (value ? isValidHostname(value) : false)),
version: Yup.string()
.required('A version is required')
.test('no-whitespace', 'A version cannot contain whitespace', (value) => !/\s/.test(value || ''))
.test('valid-version', 'A valid version is required', (value) => (value ? validateVersion(value) : false)),
location: Yup.string()
.required('A location is required')
.test('valid-location', 'A valid location is required', (locationValueTest) =>
locationValueTest ? validateLocation(locationValueTest) : false,
),
mixPort: Yup.number()
.required('A mixport is required')
.test('valid-mixport', 'A valid mixport is required', (value) => (value ? validateRawPort(value) : false)),
clientsPort: Yup.number()
.required('A clients port is required')
.test('valid-clients', 'A valid clients port is required', (value) => (value ? validateRawPort(value) : false)),
});
export const amountSchema = Yup.object().shape({
amount: Yup.object().shape({
amount: Yup.string()
.required('An amount is required')
.test('valid-amount', 'Pledge error', async function isValidAmount(this, value) {
const isValid = await validateAmount(value || '', '100');
if (!isValid) {
return this.createError({ message: 'A valid amount is required (min 100)' });
}
return true;
}),
}),
operatorCost: Yup.object().shape({
amount: Yup.string()
.required('An operating cost is required')
// eslint-disable-next-line
.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;
}),
}),
});
export const updateGatewayValidationSchema = Yup.object().shape({
host: Yup.string()
.required('A host is required')
.test('no-whitespace', 'Host cannot contain whitespace', (value) => !/\s/.test(value || ''))
.test('valid-host', 'A valid host is required', (value) => (value ? isValidHostname(value) : false)),
mixPort: Yup.number()
.required('A mixport is required')
.test('valid-mixport', 'A valid mixport is required', (value) => (value ? validateRawPort(value) : false)),
httpApiPort: Yup.number()
.required('A clients port is required')
.test('valid-clients', 'A valid clients port is required', (value) => (value ? validateRawPort(value) : false)),
location: Yup.string().test('valid-location', 'A valid location is required', (value) =>
value ? validateLocation(value) : false,
),
version: Yup.string()
.test('no-whitespace', 'A version cannot contain whitespace', (value) => !/\s/.test(value || ''))
.test('valid-version', 'A valid version is required', (value) => (value ? validateVersion(value) : false)),
});
@@ -1,130 +0,0 @@
import React, { useContext, useEffect, useState } from 'react';
import { Box } from '@mui/material';
import { CurrencyDenom, TNodeType } from '@nymproject/types';
import { ConfirmTx } from 'src/components/ConfirmTX';
import { ModalListItem } from 'src/components/Modals/ModalListItem';
import { SimpleModal } from 'src/components/Modals/SimpleModal';
import { useGetFee } from 'src/hooks/useGetFee';
import { GatewayAmount, GatewayData } from 'src/pages/bonding/types';
import { BalanceWarning } from 'src/components/FeeWarning';
import { AppContext } from 'src/context';
import { BondGatewayForm } from '../forms/legacyForms/BondGatewayForm';
const defaultGatewayValues: GatewayData = {
identityKey: '',
sphinxKey: '',
ownerSignature: '',
location: '',
host: '',
version: '',
mixPort: 1789,
clientsPort: 9000,
};
const defaultAmountValues = (denom: CurrencyDenom) => ({
amount: { amount: '100', denom },
operatorCost: { amount: '40', denom },
tokenPool: 'balance',
});
export const BondGatewayModal = ({
denom,
hasVestingTokens,
onSelectNodeType,
onClose,
onError,
}: {
denom: CurrencyDenom;
hasVestingTokens: boolean;
onSelectNodeType: (type: TNodeType) => void;
onClose: () => void;
onError: (e: string) => void;
}) => {
const [step, setStep] = useState<1 | 2 | 3>(1);
const [gatewayData, setGatewayData] = useState<GatewayData>(defaultGatewayValues);
const [amountData, setAmountData] = useState<GatewayAmount>(defaultAmountValues(denom));
const { fee, resetFeeState, feeError } = useGetFee();
const { userBalance } = useContext(AppContext);
useEffect(() => {
if (feeError) {
onError(feeError);
}
}, [feeError]);
const validateStep = async (s: number) => {
const event = new CustomEvent('validate_bond_gateway_step', { detail: { step: s } });
window.dispatchEvent(event);
};
const handleBack = () => {
if (step === 2) {
setStep(1);
} else if (step === 3) {
setStep(2);
}
};
const handleUpdateGatwayData = (data: GatewayData) => {
setGatewayData(data);
setStep(2);
};
const handleUpdateAmountData = async (data: GatewayAmount) => {
setAmountData(data);
setStep(3);
};
const handleConfirm = async () => {};
if (fee) {
return (
<ConfirmTx
open
header="Bond details"
fee={fee}
onClose={onClose}
onPrev={resetFeeState}
onConfirm={handleConfirm}
>
<ModalListItem label="Node identity key" value={gatewayData.identityKey} divider />
<ModalListItem
label="Amount"
value={`${amountData.amount.amount} ${amountData.amount.denom.toUpperCase()}`}
divider
/>
{fee.amount?.amount && userBalance.balance && (
<BalanceWarning fee={fee.amount?.amount} tx={amountData.amount.amount} />
)}
</ConfirmTx>
);
}
return (
<SimpleModal
open
onOk={async () => {
await validateStep(step);
}}
onBack={step === 2 ? handleBack : undefined}
onClose={onClose}
header="Bond gateway"
subHeader={`Step ${step}/3`}
okLabel="Next"
>
<Box sx={{ mb: 2 }}>
<BondGatewayForm
step={step}
denom={denom}
gatewayData={gatewayData}
amountData={amountData}
hasVestingTokens={hasVestingTokens}
onValidateGatewayData={handleUpdateGatwayData}
onValidateAmountData={handleUpdateAmountData}
onSelectNodeType={onSelectNodeType}
/>
</Box>
</SimpleModal>
);
};
@@ -1,254 +0,0 @@
import React, { useContext, useState } from 'react';
import { useForm } from 'react-hook-form';
import { clean } from 'semver';
import { yupResolver } from '@hookform/resolvers/yup';
import { Button, Divider, Typography, TextField, Grid, Box } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import {
simulateUpdateGatewayConfig,
simulateVestingUpdateGatewayConfig,
updateGatewayConfig,
vestingUpdateGatewayConfig,
} from 'src/requests';
import { useBondingContext } from 'src/context/bonding';
import { SimpleModal } from 'src/components/Modals/SimpleModal';
import { Console } from 'src/utils/console';
import { Alert } from 'src/components/Alert';
import { ConfirmTx } from 'src/components/ConfirmTX';
import { useGetFee } from 'src/hooks/useGetFee';
import { LoadingModal } from 'src/components/Modals/LoadingModal';
import { updateGatewayValidationSchema } from 'src/components/Bonding/forms/legacyForms/gatewayValidationSchema';
import { BalanceWarning } from 'src/components/FeeWarning';
import { AppContext } from 'src/context';
import { TBondedGateway } from 'src/requests/gatewayDetails';
export const GeneralGatewaySettings = ({ bondedNode }: { bondedNode: TBondedGateway }) => {
const [openConfirmationModal, setOpenConfirmationModal] = useState<boolean>(false);
const { getFee, fee, resetFeeState } = useGetFee();
const { refresh } = useBondingContext();
const { userBalance } = useContext(AppContext);
const theme = useTheme();
const {
register,
handleSubmit,
formState: { errors, isSubmitting, isDirty, isValid },
} = useForm({
resolver: yupResolver(updateGatewayValidationSchema),
mode: 'onChange',
defaultValues: {
host: bondedNode.host,
mixPort: bondedNode.mixPort,
httpApiPort: bondedNode.httpApiPort,
version: bondedNode.version,
location: bondedNode.location,
},
});
const onSubmit = async (data: any) => {
resetFeeState();
const { host, mixPort, httpApiPort, version, location } = data;
try {
const GatewayConfigParams = {
host,
mix_port: mixPort,
location,
version: clean(version) as string,
clients_port: httpApiPort,
};
if (bondedNode.proxy) {
await vestingUpdateGatewayConfig(GatewayConfigParams, fee?.fee);
} else {
await updateGatewayConfig(GatewayConfigParams, fee?.fee);
}
setOpenConfirmationModal(true);
} catch (error) {
Console.error(error);
}
};
return (
<Grid container xs item>
{fee && (
<ConfirmTx
open
header="Update node settings"
fee={fee}
onConfirm={handleSubmit((d) => onSubmit(d))}
onPrev={resetFeeState}
onClose={resetFeeState}
>
{fee.amount?.amount && userBalance?.balance?.amount.amount && (
<Box sx={{ mb: 2 }}>
<BalanceWarning fee={fee.amount.amount} />
</Box>
)}
</ConfirmTx>
)}
{isSubmitting && <LoadingModal />}
<Alert
title={
<Box sx={{ fontWeight: 600 }}>
Changing these values will ONLY change the data about your node on the blockchain. Remember to change your
nodes config file with the same values too
</Box>
}
dismissable
/>
<Grid container>
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Port
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('mixPort')}
name="mixPort"
label="Mix Port"
fullWidth
error={!!errors.mixPort}
helperText={errors.mixPort?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
<Grid item width={1}>
<TextField
{...register('httpApiPort')}
name="httpApiPort"
label="Client Port"
fullWidth
error={!!errors.httpApiPort}
helperText={errors.httpApiPort?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Host
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('host')}
name="host"
label="Host"
fullWidth
error={!!errors.host}
helperText={errors.host?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Version
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('version')}
name="version"
label="Version"
fullWidth
error={!!errors.version}
helperText={errors.version?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Location
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('location')}
name="location"
label="Location"
fullWidth
error={!!errors.location}
helperText={errors.location?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Divider flexItem />
<Grid container justifyContent="end">
<Button
size="large"
variant="contained"
disabled={isSubmitting || !isDirty || !isValid}
onClick={handleSubmit((data) =>
getFee(bondedNode.proxy ? simulateVestingUpdateGatewayConfig : simulateUpdateGatewayConfig, {
host: data.host,
mix_port: data.mixPort,
clients_port: data.httpApiPort,
location: bondedNode.location!,
version: data.version,
}),
)}
sx={{ m: 3 }}
>
Submit changes to the blockchain
</Button>
</Grid>
</Grid>
<SimpleModal
open={openConfirmationModal}
header="Your changes are submitted to the blockchain"
subHeader="Remember to change the values
on your gatewayss config file too."
okLabel="close"
hideCloseIcon
displayInfoIcon
onOk={async () => {
setOpenConfirmationModal(false);
await refresh();
}}
buttonFullWidth
sx={{
width: '450px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
headerStyles={{
width: '100%',
mb: 1,
textAlign: 'center',
color: theme.palette.nym.nymWallet.text.blue,
fontSize: 16,
}}
subHeaderStyles={{
width: '100%',
mb: 1,
textAlign: 'center',
color: 'main',
fontSize: 14,
}}
/>
</Grid>
);
};
@@ -1,245 +0,0 @@
import React, { useContext, useState } from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { clean } from 'semver';
import { Box, Button, Divider, Grid, Stack, TextField, Typography } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import { isMixnode } from 'src/types';
import { simulateUpdateMixnodeConfig, simulateVestingUpdateMixnodeConfig, updateMixnodeConfig } from 'src/requests';
import { SimpleModal } from 'src/components/Modals/SimpleModal';
import { bondedInfoParametersValidationSchema } from 'src/components/Bonding/forms/legacyForms/mixnodeValidationSchema';
import { Console } from 'src/utils/console';
import { Alert } from 'src/components/Alert';
import { vestingUpdateMixnodeConfig } from 'src/requests/vesting';
import { ConfirmTx } from 'src/components/ConfirmTX';
import { useGetFee } from 'src/hooks/useGetFee';
import { LoadingModal } from 'src/components/Modals/LoadingModal';
import { BalanceWarning } from 'src/components/FeeWarning';
import { AppContext } from 'src/context';
import { TBondedMixnode } from 'src/requests/mixnodeDetails';
export const GeneralMixnodeSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }) => {
const [openConfirmationModal, setOpenConfirmationModal] = useState<boolean>(false);
const { getFee, fee, resetFeeState } = useGetFee();
const { userBalance } = useContext(AppContext);
const theme = useTheme();
const {
register,
handleSubmit,
formState: { errors, isSubmitting, isDirty, isValid },
} = useForm({
resolver: yupResolver(bondedInfoParametersValidationSchema),
mode: 'onChange',
defaultValues: isMixnode(bondedNode) ? bondedNode : {},
});
const onSubmit = async (data: {
host?: string;
version?: string;
mixPort?: number;
verlocPort?: number;
httpApiPort?: number;
}) => {
resetFeeState();
const { host, version, mixPort, verlocPort, httpApiPort } = data;
if (host && version && mixPort && verlocPort && httpApiPort) {
const MixNodeConfigParams = {
host,
mix_port: mixPort,
verloc_port: verlocPort,
http_api_port: httpApiPort,
version: clean(version) as string,
};
try {
if (bondedNode.proxy) {
await vestingUpdateMixnodeConfig(MixNodeConfigParams);
} else {
await updateMixnodeConfig(MixNodeConfigParams);
}
setOpenConfirmationModal(true);
} catch (error) {
Console.error(error);
}
}
};
return (
<Grid container xs>
{fee && (
<ConfirmTx
open
header="Update node settings"
fee={fee}
onConfirm={handleSubmit((d) => onSubmit(d))}
onPrev={resetFeeState}
onClose={resetFeeState}
>
{fee.amount?.amount && userBalance?.balance?.amount.amount && (
<Box sx={{ mb: 2 }}>
<BalanceWarning fee={fee.amount.amount} />
</Box>
)}
</ConfirmTx>
)}
{isSubmitting && <LoadingModal />}
<Alert
title={
<Stack>
<Typography fontWeight={600}>
Changing these values will ONLY change the data about your node on the blockchain.
</Typography>
<Typography>Remember to change your nodes config file with the same values too.</Typography>
</Stack>
}
bgColor={`${theme.palette.nym.nymWallet.text.blue}0D !important`}
dismissable
/>
<Grid container mt={2}>
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Port
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('mixPort')}
name="mixPort"
label="Mix Port"
fullWidth
error={!!errors.mixPort}
helperText={errors.mixPort?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
<Grid item width={1}>
<TextField
{...register('verlocPort')}
name="verlocPort"
label="Verloc Port"
fullWidth
error={!!errors.verlocPort}
helperText={errors.verlocPort?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
<Grid item width={1}>
<TextField
{...register('httpApiPort')}
name="httpApiPort"
label="HTTP port"
fullWidth
error={!!errors.httpApiPort}
helperText={errors.httpApiPort?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Divider sx={{ width: '100%' }} />
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Host
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('host')}
name="host"
label="Host"
fullWidth
error={!!errors.host}
helperText={errors.host?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Divider sx={{ width: '100%' }} />
<Grid item container direction="row" alignItems="left" justifyContent="space-between" padding={3}>
<Grid item>
<Typography variant="body1" sx={{ fontWeight: 600, mb: 1 }}>
Version
</Typography>
</Grid>
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Grid item width={1}>
<TextField
{...register('version')}
name="version"
label="Version"
fullWidth
error={!!errors.version}
helperText={errors.version?.message}
InputLabelProps={{ shrink: true }}
/>
</Grid>
</Grid>
</Grid>
<Divider sx={{ width: '100%' }} />
<Grid item container direction="row" justifyContent="space-between" padding={3}>
<Grid item />
<Grid spacing={3} item container alignItems="center" xs={12} md={6}>
<Button
size="large"
variant="contained"
disabled={isSubmitting || !isDirty || !isValid}
onClick={handleSubmit((data) =>
getFee(bondedNode.proxy ? simulateVestingUpdateMixnodeConfig : simulateUpdateMixnodeConfig, {
host: data.host,
mix_port: data.mixPort,
verloc_port: data.verlocPort,
http_api_port: data.httpApiPort,
version: data.version,
}),
)}
sx={{ m: 3, mr: 0 }}
fullWidth
>
Submit changes to the blockchain
</Button>
</Grid>
</Grid>
</Grid>
<SimpleModal
open={openConfirmationModal}
header="Your changes are submitted to the blockchain"
subHeader="Remember to change the values
on your nodes config file too."
okLabel="close"
hideCloseIcon
displayInfoIcon
onOk={async () => {
await setOpenConfirmationModal(false);
}}
buttonFullWidth
sx={{
width: '450px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
headerStyles={{
width: '100%',
mb: 1,
textAlign: 'center',
color: theme.palette.nym.nymWallet.text.blue,
fontSize: 16,
}}
subHeaderStyles={{
width: '100%',
mb: 1,
textAlign: 'center',
color: 'main',
fontSize: 14,
}}
/>
</Grid>
);
};
@@ -2,9 +2,7 @@ import React, { useState } from 'react';
import { Box, Button, Divider, Grid } from '@mui/material';
import { isGateway, isMixnode, isNymNode } from 'src/types';
import { TBondedNode } from 'src/context/bonding';
import { GeneralMixnodeSettings } from './GeneralMixnodeSettings';
import { ParametersSettings } from './ParametersSettings';
import { GeneralGatewaySettings } from './GeneralGatewaySettings';
import { GeneralNymNodeSettings } from './GeneralNymNodeSettings';
const makeGeneralNav = (bondedNode: TBondedNode) => {
@@ -22,8 +20,6 @@ export const NodeGeneralSettings = ({ bondedNode }: { bondedNode: TBondedNode })
const getSettings = () => {
switch (navSelection) {
case 0: {
if (isMixnode(bondedNode)) return <GeneralMixnodeSettings bondedNode={bondedNode} />;
if (isGateway(bondedNode)) return <GeneralGatewaySettings bondedNode={bondedNode} />;
if (isNymNode(bondedNode)) return <GeneralNymNodeSettings bondedNode={bondedNode} />;
break;
}