Skip to content

Commit

Permalink
Merge pull request #278 from threshold-network/simplify-mapped-operat…
Browse files Browse the repository at this point in the history
…or-data-check

Simplify mapped operators data check

The main goal is to reduce the repetition of the code for
`isOperatorMappedOnlyInRandomBeacon`, `isOperatorMappedOnlyInTbtc` etc. For
`useRegisterMultipleOperator` hook I've created the reducer that will get the
operator addresses from the state and returns all the needed data.
  • Loading branch information
r-czajkowski authored Oct 26, 2022
2 parents 9371160 + 0f73828 commit 06009f9
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { useModal } from "../../../hooks/useModal"
import StakeAddressInfo from "../../../pages/Staking/StakeCard/StakeAddressInfo"
import { mapOperatorToStakingProviderModalClosed } from "../../../store/modal"
import { BaseModalProps } from "../../../types"
import { isAddressZero } from "../../../web3/utils"
import InfoBox from "../../InfoBox"
import withBaseModal from "../withBaseModal"

Expand Down Expand Up @@ -54,28 +53,20 @@ const OperatorMappingConfirmation: FC<
const MapOperatorToStakingProviderConfirmationModal: FC<
BaseModalProps & {
operator: string
mappedOperatorTbtc: string
mappedOperatorRandomBeacon: string
isOperatorMappedOnlyInTbtc: boolean
isOperatorMappedOnlyInRandomBeacon: boolean
}
> = ({
operator,
mappedOperatorTbtc,
mappedOperatorRandomBeacon,
isOperatorMappedOnlyInTbtc,
isOperatorMappedOnlyInRandomBeacon,
closeModal,
}) => {
const { account } = useWeb3React()
const { registerMultipleOperators } =
useRegisterMultipleOperatorsTransaction()
const dispatch = useAppDispatch()

const isOperatorMappedOnlyInTbtc =
!isAddressZero(mappedOperatorTbtc) &&
isAddressZero(mappedOperatorRandomBeacon)

const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(mappedOperatorTbtc) &&
!isAddressZero(mappedOperatorRandomBeacon)

const { openModal } = useModal()
const onSuccess = useCallback(
(tx: ContractTransaction) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ const validateInputtedOperatorAddress = async (
checkIfOperatorIsMappedToAnotherStakingProvider: (
operator: string
) => Promise<boolean>,
mappedOperatorRandomBeacon: string,
mappedOperatorTbtc: string
mappedOperatorTbtc: string,
mappedOperatorRandomBeacon: string
): Promise<string | undefined> => {
let validationMsg: string | undefined = ""

const isOperatorMappedOnlyInTbtc =
!isAddressZero(mappedOperatorTbtc) &&
isAddressZero(mappedOperatorRandomBeacon)

const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(mappedOperatorTbtc) &&
!isAddressZero(mappedOperatorRandomBeacon)

try {
const isOperatorMappedToAnotherStakingProvider =
await checkIfOperatorIsMappedToAnotherStakingProvider(operator)
validationMsg = undefined
if (isOperatorMappedToAnotherStakingProvider) {
validationMsg = "Operator is already mapped to another staking provider."
}

const isOperatorMappedOnlyInTbtc =
!isAddressZero(mappedOperatorTbtc) &&
isAddressZero(mappedOperatorRandomBeacon)

const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(mappedOperatorTbtc) &&
!isAddressZero(mappedOperatorRandomBeacon)

if (
isOperatorMappedOnlyInRandomBeacon &&
!isSameETHAddress(operator, mappedOperatorRandomBeacon)
Expand Down Expand Up @@ -104,8 +105,8 @@ const MapOperatorToStakingProviderForm = withFormik<
errors.operator = await validateInputtedOperatorAddress(
values.operator,
checkIfOperatorIsMappedToAnotherStakingProvider,
mappedOperatorRandomBeacon,
mappedOperatorTbtc
mappedOperatorTbtc,
mappedOperatorRandomBeacon
)
}

Expand Down
21 changes: 11 additions & 10 deletions src/components/Modal/MapOperatorToStakingProviderModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import {
isSameETHAddress,
AddressZero,
} from "../../../web3/utils"
import { selectMappedOperators } from "../../../store/account/selectors"
import { useAppSelector } from "../../../hooks/store"

export interface MapOperatorToStakingProviderModalProps {
mappedOperatorTbtc: string
Expand All @@ -38,29 +40,28 @@ export interface MapOperatorToStakingProviderModalProps {

const MapOperatorToStakingProviderModal: FC<
BaseModalProps & MapOperatorToStakingProviderModalProps
> = ({ mappedOperatorTbtc, mappedOperatorRandomBeacon }) => {
> = () => {
const { account } = useWeb3React()
const formRef =
useRef<FormikProps<MapOperatorToStakingProviderFormValues>>(null)
const { closeModal, openModal } = useModal()
const threshold = useThreshold()

const isOperatorMappedOnlyInTbtc =
!isAddressZero(mappedOperatorTbtc) &&
isAddressZero(mappedOperatorRandomBeacon)

const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(mappedOperatorTbtc) &&
!isAddressZero(mappedOperatorRandomBeacon)
const {
mappedOperatorTbtc,
mappedOperatorRandomBeacon,
isOperatorMappedOnlyInRandomBeacon,
isOperatorMappedOnlyInTbtc,
} = useAppSelector(selectMappedOperators)

const onSubmit = async ({
operator,
}: MapOperatorToStakingProviderFormValues) => {
if (account) {
openModal(ModalType.MapOperatorToStakingProviderConfirmation, {
operator,
mappedOperatorTbtc,
mappedOperatorRandomBeacon,
isOperatorMappedOnlyInTbtc,
isOperatorMappedOnlyInRandomBeacon,
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ import { useWeb3React } from "@web3-react/core"
import { OperatorMappedSuccessTx } from "../../components/Modal/MapOperatorToStakingProviderSuccessModal"
import { mapOperatorToStakingProviderModalClosed } from "../../store/modal"
import { useAppDispatch, useAppSelector } from "../store"
import { selectMappedOperators } from "../../store/account"

export const useRegisterMultipleOperatorsTransaction = () => {
const mappedOperatorTbtc = useAppSelector(
(state) => state.account.operatorMapping.data.tbtc
)
const mappedOperatorRandomBeacon = useAppSelector(
(state) => state.account.operatorMapping.data.randomBeacon
)
const {
mappedOperatorTbtc,
mappedOperatorRandomBeacon,
isOperatorMappedInBothApps,
isOperatorMappedOnlyInRandomBeacon,
isOperatorMappedOnlyInTbtc,
} = useAppSelector((state) => selectMappedOperators(state))
const { account } = useWeb3React()
const { openModal, closeModal } = useModal()
const dispatch = useAppDispatch()
Expand All @@ -35,20 +37,9 @@ export const useRegisterMultipleOperatorsTransaction = () => {
throw new Error("Connect to the staking provider account first!")
}

if (
!isAddressZero(mappedOperatorRandomBeacon) &&
!isAddressZero(mappedOperatorTbtc)
)
if (isOperatorMappedInBothApps)
throw new Error("Both apps already have mapped operator!")

const isOperatorMappedOnlyInTbtc =
!isAddressZero(mappedOperatorTbtc) &&
isAddressZero(mappedOperatorRandomBeacon)

const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(mappedOperatorTbtc) &&
!isAddressZero(mappedOperatorRandomBeacon)

if (isOperatorMappedOnlyInRandomBeacon)
throw new Error("Random beacon app already has mapped operator!")

Expand Down
23 changes: 5 additions & 18 deletions src/pages/Staking/OperatorAddressMappingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,17 @@ import {
} from "@threshold-network/components"
import { FC } from "react"
import { ModalType } from "../../enums"
import { useAppSelector } from "../../hooks/store"
import { useModal } from "../../hooks/useModal"
import { isAddressZero } from "../../web3/utils"
import { selectMappedOperators } from "../../store/account/selectors"

const OperatorAddressMappingCard: FC<{
mappedOperatorTbtc: string
mappedOperatorRandomBeacon: string
}> = ({ mappedOperatorTbtc, mappedOperatorRandomBeacon }) => {
const OperatorAddressMappingCard: FC = () => {
const { openModal } = useModal()
const isOperatorMappedOnlyInTbtc =
!isAddressZero(mappedOperatorTbtc) &&
isAddressZero(mappedOperatorRandomBeacon)

const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(mappedOperatorTbtc) &&
!isAddressZero(mappedOperatorRandomBeacon)

const isOneOfTheAppsNotMapped =
isOperatorMappedOnlyInRandomBeacon || isOperatorMappedOnlyInTbtc
const { isOneOfTheAppsNotMapped } = useAppSelector(selectMappedOperators)

const onStartMappingClick = () => {
openModal(ModalType.MapOperatorToStakingProvider, {
mappedOperatorTbtc,
mappedOperatorRandomBeacon,
})
openModal(ModalType.MapOperatorToStakingProvider)
}

return (
Expand Down
5 changes: 1 addition & 4 deletions src/pages/Staking/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ const StakingPage: PageComponent = (props) => {
isOperatorMappingInitialFetchDone &&
(isAddressZero(mappedOperators.tbtc) ||
isAddressZero(mappedOperators.randomBeacon)) && (
<OperatorAddressMappingCard
mappedOperatorTbtc={mappedOperators.tbtc}
mappedOperatorRandomBeacon={mappedOperators.randomBeacon}
/>
<OperatorAddressMappingCard />
)}
{hasStakes ? (
stakes.map((stake) => (
Expand Down
1 change: 1 addition & 0 deletions src/store/account/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./slice"
export * from "./selectors"
28 changes: 28 additions & 0 deletions src/store/account/selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createSelector } from "@reduxjs/toolkit"
import { RootState } from ".."
import { isAddressZero } from "../../web3/utils"
import { AccountState } from "./slice"

export const selectAccountState = (state: RootState) => state.account

export const selectMappedOperators = createSelector(
[selectAccountState],
(accountState: AccountState) => {
const { randomBeacon, tbtc } = accountState.operatorMapping.data
const isOperatorMappedOnlyInTbtc =
!isAddressZero(tbtc) && isAddressZero(randomBeacon)
const isOperatorMappedOnlyInRandomBeacon =
isAddressZero(tbtc) && !isAddressZero(randomBeacon)

return {
mappedOperatorTbtc: tbtc,
mappedOperatorRandomBeacon: randomBeacon,
isOperatorMappedOnlyInTbtc,
isOperatorMappedOnlyInRandomBeacon,
isOneOfTheAppsNotMapped:
isOperatorMappedOnlyInRandomBeacon || isOperatorMappedOnlyInTbtc,
isOperatorMappedInBothApps:
!isAddressZero(randomBeacon) && !isAddressZero(tbtc),
}
}
)
2 changes: 1 addition & 1 deletion src/store/account/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { StakingAppName } from "../staking-applications"
import { getStakingProviderOperatorInfo } from "./effects"

interface AccountState {
export interface AccountState {
address: string
isStakingProvider: boolean
operatorMapping: FetchingState<Record<StakingAppName, string>>
Expand Down

0 comments on commit 06009f9

Please sign in to comment.