diff --git a/apps/autonolas-registry/components/ListServices/ServiceState/2StepActiveRegistration/index.jsx b/apps/autonolas-registry/components/ListServices/ServiceState/2StepActiveRegistration/index.jsx index e88bbfb3..28b4f4d8 100644 --- a/apps/autonolas-registry/components/ListServices/ServiceState/2StepActiveRegistration/index.jsx +++ b/apps/autonolas-registry/components/ListServices/ServiceState/2StepActiveRegistration/index.jsx @@ -1,21 +1,18 @@ -import { useState, useEffect } from 'react'; -import PropTypes from 'prop-types'; -import { ethers } from 'ethers'; import { Divider, Typography } from 'antd'; -import { - convertToEth, - notifyError, - notifySuccess, -} from '@autonolas/frontend-library'; +import { ethers } from 'ethers'; import { isArray } from 'lodash'; +import PropTypes from 'prop-types'; +import { useEffect, useState } from 'react'; + +import { convertToEth, notifyError, notifySuccess } from '@autonolas/frontend-library'; -import { useHelpers } from '../../../../common-util/hooks'; import { SendTransactionButton } from '../../../../common-util/TransactionHelpers/SendTransactionButton'; -import { useSvmBonds } from '../../hooks/useSvmService'; -import { getBonds, getTokenBondRequest, checkAndApproveToken } from '../utils'; +import { useHelpers } from '../../../../common-util/hooks'; import { getNumberOfAgentAddress } from '../../helpers/functions'; -import { ActiveRegistrationTable } from './ActiveRegistrationTable'; +import { useSvmBonds } from '../../hooks/useSvmService'; import { useRegisterAgents } from '../useSvmServiceStateManagement'; +import { checkAndApproveToken, getBonds, getTokenBondRequest } from '../utils'; +import { ActiveRegistrationTable } from './ActiveRegistrationTable'; const { Text } = Typography; const STEP = 2; @@ -30,9 +27,7 @@ const getIdsAndAgentInstances = (dataSource) => { const ids = []; // filter out instances that are empty - const filteredDataSource = dataSource.filter( - ({ agentAddresses }) => !!agentAddresses, - ); + const filteredDataSource = dataSource.filter(({ agentAddresses }) => !!agentAddresses); const instances = filteredDataSource.map(({ agentAddresses, agentId }) => { /** @@ -68,8 +63,7 @@ export const ActiveRegistration = ({ isEthToken, updateDetails, }) => { - const { isSvm, account, chainId, doesNetworkHaveValidServiceManagerToken } = - useHelpers(); + const { isSvm, account, chainId, doesNetworkHaveValidServiceManagerToken } = useHelpers(); const { getSvmBonds } = useSvmBonds(); const [totalBonds, setTotalBond] = useState(null); @@ -101,12 +95,7 @@ export const ActiveRegistration = ({ } } - if ( - serviceId && - !isEthToken && - doesNetworkHaveValidServiceManagerToken && - !isSvm - ) { + if (serviceId && !isEthToken && doesNetworkHaveValidServiceManagerToken && !isSvm) { const response = await getTokenBondRequest(serviceId, dataSource); setEthTokenBonds(response); } @@ -169,16 +158,15 @@ export const ActiveRegistration = ({ }; const btnProps = getOtherBtnProps(STEP); - const totalBondEthToken = convertToEth((totalBonds || 0).toString()) || '--'; + const totalBondEthToken = totalBonds ? convertToEth(totalBonds.toString()) : '--'; let totalTokenBonds = 0; isArray(ethTokenBonds) && ethTokenBonds.forEach((bond, index) => { - const addressCount = getNumberOfAgentAddress( - dataSource[index].agentAddresses, - ); + const addressCount = getNumberOfAgentAddress(dataSource[index].agentAddresses); totalTokenBonds += addressCount * bond; }); + const totalTokenBondsEth = totalTokenBonds ? convertToEth(totalTokenBonds.toString()) : '--'; return (
@@ -194,11 +182,7 @@ export const ActiveRegistration = ({ {!isSvm && ( {`Adding instances will cause a bond of ${totalBondEthToken} ETH`} - {!isEthToken && ( - <> - {` and ${convertToEth((totalTokenBonds || 0).toString())} token`} - - )} + {!isEthToken && <>{` and ${totalTokenBondsEth} token`}} )} @@ -238,9 +222,8 @@ export const ActiveRegistration = ({ ActiveRegistration.propTypes = { serviceId: PropTypes.string, - dataSource: PropTypes.arrayOf( - PropTypes.oneOfType([PropTypes.array, PropTypes.object]), - ).isRequired, + dataSource: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.array, PropTypes.object])) + .isRequired, setDataSource: PropTypes.func.isRequired, getOtherBtnProps: PropTypes.func.isRequired, handleTerminate: PropTypes.func.isRequired, diff --git a/apps/autonolas-registry/components/ListServices/helpers/RegisterForm.jsx b/apps/autonolas-registry/components/ListServices/helpers/RegisterForm.jsx index 6c5941c3..bdffc5f7 100644 --- a/apps/autonolas-registry/components/ListServices/helpers/RegisterForm.jsx +++ b/apps/autonolas-registry/components/ListServices/helpers/RegisterForm.jsx @@ -1,4 +1,5 @@ import { Button, Form, Input } from 'antd'; +import { isEqual, sortBy } from 'lodash'; import { useRouter } from 'next/router'; import PropTypes from 'prop-types'; import { useEffect, useState } from 'react'; @@ -6,6 +7,8 @@ import useDeepCompareEffect from 'use-deep-compare-effect'; import { isValidAddress, notifyError } from '@autonolas/frontend-library'; +import { FORM_VALIDATION } from 'libs/util-functions/src'; + import { IpfsHashGenerationModal } from 'common-util/List/IpfsHashGenerationModal'; import { DependencyLabel, commaMessage } from 'common-util/List/ListCommon'; import { FormItemHash } from 'common-util/List/RegisterForm/helpers'; @@ -19,10 +22,8 @@ import { ThresholdInput } from './ThresholdInput'; export const FORM_NAME = 'serviceRegisterForm'; -const agentIdValidator = (form, value) => { - if (!/^\d+(\s*,\s*\d+?)*$/gm.test(value)) { - return Promise.reject(new Error('Please input a valid list')); - } +const agentIdValidator = async (form, value) => { + await FORM_VALIDATION.validateCommaSeparatedList.validator(form, value); const agentIdsStr = form.getFieldValue('agent_ids'); if (!agentIdsStr) { @@ -291,11 +292,20 @@ const RegisterForm = ({ message: 'Please input the agent Ids', }, () => ({ - validator(_, value) { - if (/^\d+(\s*,\s*\d+?)*$/gm.test(value)) { - return Promise.resolve(); + validator: async (_, value) => { + await FORM_VALIDATION.validateCommaSeparatedList.validator(form, value); + + // agentIds should be sorted before submitting the form + const agentIdsArray = value.split(',').map((val) => val.trim()); + if (!isEqual(agentIdsArray, sortBy(agentIdsArray))) { + return Promise.reject( + new Error( + 'Agent IDs should be sorted from low to high.', + ), + ); } - return Promise.reject(new Error('Please input a valid list')); + + return Promise.resolve(); }, }), ]}