Compare commits

...

2 Commits

Author SHA1 Message Date
Mark Sinclair d0462eb4ad Add URL to operator T&Cs to default memos used during bonding for wallet and CLI 2024-05-29 17:15:17 +01:00
Mark Sinclair fef2e1afd0 nym-wallet: add checkbox to accept T&Cs for operators 2024-05-29 17:14:49 +01:00
5 changed files with 70 additions and 6 deletions
@@ -324,10 +324,10 @@ impl ExecuteMsg {
ExecuteMsg::AdvanceCurrentEpoch { .. } => "advancing current epoch".into(),
ExecuteMsg::ReconcileEpochEvents { .. } => "reconciling epoch events".into(),
ExecuteMsg::BondMixnode { mix_node, .. } => {
format!("bonding mixnode {}", mix_node.identity_key)
format!("bonding mixnode {}, accepted https://nymtech.net/terms-and-conditions/operators/v1.0.0", mix_node.identity_key)
}
ExecuteMsg::BondMixnodeOnBehalf { mix_node, .. } => {
format!("bonding mixnode {} on behalf", mix_node.identity_key)
format!("bonding mixnode {} on behalf, accepted https://nymtech.net/terms-and-conditions/operators/v1.0.0", mix_node.identity_key)
}
ExecuteMsg::PledgeMore {} => "pledging additional tokens".into(),
ExecuteMsg::PledgeMoreOnBehalf { .. } => "pledging additional tokens on behalf".into(),
@@ -346,10 +346,10 @@ impl ExecuteMsg {
"updating mixnode configuration on behalf".into()
}
ExecuteMsg::BondGateway { gateway, .. } => {
format!("bonding gateway {}", gateway.identity_key)
format!("bonding gateway {}, accepted https://nymtech.net/terms-and-conditions/operators/v1.0.0", gateway.identity_key)
}
ExecuteMsg::BondGatewayOnBehalf { gateway, .. } => {
format!("bonding gateway {} on behalf", gateway.identity_key)
format!("bonding gateway {} on behalf, accepted https://nymtech.net/terms-and-conditions/operators/v1.0.0", gateway.identity_key)
}
ExecuteMsg::UnbondGateway { .. } => "unbonding gateway".into(),
ExecuteMsg::UnbondGatewayOnBehalf { .. } => "unbonding gateway on behalf".into(),
@@ -6,6 +6,7 @@ import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyForm
import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { GatewayData } from '../../../pages/bonding/types';
import { gatewayValidationSchema } from './gatewayValidationSchema';
import { TermsAndConditions, TermsAndConditionsHelp } from './TermsAndConditions';
const GatewayInitForm = ({
gatewayData,
@@ -21,6 +22,7 @@ const GatewayInitForm = ({
formState: { errors },
handleSubmit,
setValue,
setError,
} = useForm({ resolver: yupResolver(gatewayValidationSchema), defaultValues: gatewayData });
const handleRequestValidation = (event: { detail: { step: number } }) => {
@@ -30,7 +32,11 @@ const GatewayInitForm = ({
...data,
version: clean(data.version) as string,
};
onNext(validatedData);
if (!validatedData.acceptedTermsAndConditions) {
setError('acceptedTermsAndConditions', { message: 'You must accept the terms and conditions' });
} else {
onNext(validatedData);
}
})();
}
};
@@ -117,6 +123,17 @@ const GatewayInitForm = ({
/>
</Stack>
)}
<FormControlLabel
{...register('acceptedTermsAndConditions')}
name="acceptedTermsAndConditions"
required
control={<Checkbox />}
label={<TermsAndConditions error={Boolean(errors.acceptedTermsAndConditions)} />}
/>
<TermsAndConditionsHelp
error={Boolean(errors.acceptedTermsAndConditions)}
helperText={errors.acceptedTermsAndConditions?.message}
/>
</Stack>
);
};
@@ -6,6 +6,7 @@ import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyForm
import { yupResolver } from '@hookform/resolvers/yup/dist/yup';
import { mixnodeValidationSchema } from './mixnodeValidationSchema';
import { MixnodeData } from '../../../pages/bonding/types';
import { TermsAndConditions, TermsAndConditionsHelp } from './TermsAndConditions';
const MixnodeInitForm = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; onNext: (data: any) => void }) => {
const [showAdvancedOptions, setShowAdvancedOptions] = useState(false);
@@ -15,6 +16,7 @@ const MixnodeInitForm = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; on
formState: { errors },
handleSubmit,
setValue,
setError,
} = useForm({ resolver: yupResolver(mixnodeValidationSchema), defaultValues: mixnodeData });
const handleRequestValidation = (event: { detail: { step: number } }) => {
@@ -24,7 +26,11 @@ const MixnodeInitForm = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; on
...data,
version: clean(data.version),
};
onNext(validatedData);
if (!validatedData.acceptedTermsAndConditions) {
setError('acceptedTermsAndConditions', { message: 'You must accept the terms and conditions' });
} else {
onNext(validatedData);
}
})();
}
};
@@ -110,6 +116,17 @@ const MixnodeInitForm = ({ mixnodeData, onNext }: { mixnodeData: MixnodeData; on
/>
</Stack>
)}
<FormControlLabel
{...register('acceptedTermsAndConditions')}
name="acceptedTermsAndConditions"
required
control={<Checkbox />}
label={<TermsAndConditions error={Boolean(errors.acceptedTermsAndConditions)} />}
/>
<TermsAndConditionsHelp
error={Boolean(errors.acceptedTermsAndConditions)}
helperText={errors.acceptedTermsAndConditions?.message}
/>
</Stack>
);
};
@@ -0,0 +1,29 @@
import React from 'react';
import Typography from '@mui/material/Typography';
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
export const TermsAndConditions: React.FC<{
error?: boolean;
}> = ({ error }) => (
<Typography display="inline" color={(theme) => (error ? theme.palette.error.main : undefined)}>
I agree to the{' '}
<a href="https://nymtech.net/terms-and-conditions/operators/v1.0.0" target="_blank" rel="noreferrer">
operator terms and conditions
</a>
</Typography>
);
export const TermsAndConditionsHelp: React.FC<{
error?: boolean;
helperText?: string;
}> = ({ error, helperText }) => {
if (!error || !helperText) {
return null;
}
return (
<Typography color="error.main" display="flex" alignItems="center">
<WarningAmberIcon sx={{ mr: 1 }} />
{helperText}
</Typography>
);
};
+1
View File
@@ -11,6 +11,7 @@ export type NodeIdentity = {
host: string;
version: string;
mixPort: number;
acceptedTermsAndConditions?: boolean;
};
export type MixnodeData = NodeIdentity & {