Skip to content

Commit

Permalink
Merge pull request #233 from lidofinance/develop
Browse files Browse the repository at this point in the history
Merge from develop into main
  • Loading branch information
AnnaSila authored Jan 12, 2024
2 parents 14e244b + 70c61d1 commit bcc5023
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 98 deletions.
2 changes: 1 addition & 1 deletion modules/blockChain/contractAddresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const DAI: ChainAddressMap = {
export const Finance: ChainAddressMap = {
[CHAINS.Mainnet]: '0xB9E5CBB9CA5b0d659238807E84D0176930753d86',
[CHAINS.Goerli]: '0x75c7b1D23f1cad7Fb4D60281d7069E46440BC179',
[CHAINS.Holesky]: ' 0xf0F281E5d7FBc54EAFcE0dA225CDbde04173AB16',
[CHAINS.Holesky]: '0xf0F281E5d7FBc54EAFcE0dA225CDbde04173AB16',
}

export const AllowedRecipientRegistry: ChainAddressMap = {
Expand Down
196 changes: 103 additions & 93 deletions modules/motions/hooks/useAvailableMotions.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { useCallback, useEffect, useState, useMemo } from 'react'
import { useMemo } from 'react'
import { utils } from 'ethers'

import { useWeb3 } from 'modules/blockChain/hooks/useWeb3'
import {
EvmAddressesByType,
EvmTypesByAdress,
parseEvmSupportedChainId,
} from 'modules/motions/evmAddresses'

import { useNodeOperatorsList } from './useNodeOperatorsList'
import { EVM_CONTRACTS } from './useContractEvmScript'
import { MotionTypeForms } from 'modules/motions/types'
import { useSWR } from 'modules/network/hooks/useSwr'

const isHasTrustedCaller = (
contract: unknown,
Expand All @@ -22,113 +22,123 @@ const isHasTrustedCaller = (

type NodeOperatorsList = ReturnType<typeof useNodeOperatorsList>['data']

type AvailableMotions = Record<MotionTypeForms, boolean>

const getIsNodeOperatorConnected = (
walletAddress: string | null | undefined,
nodeOperatorsList: NodeOperatorsList,
) => {
if (!walletAddress || !nodeOperatorsList) return false
const isWalletInList = nodeOperatorsList.some(
return nodeOperatorsList.some(
o => utils.getAddress(o.rewardAddress) === utils.getAddress(walletAddress),
)

return isWalletInList
}

export const useAvailableMotions = () => {
const { chainId, walletAddress } = useWeb3()
const [availableMotions, setAvailableMotions] =
useState<Record<MotionTypeForms, boolean>>()

const nodeOperators = useNodeOperatorsList('curated')

const sandboxNodeOperators = useNodeOperatorsList('sandbox')

const nodeOperatorIncreaseLimitAddressMap =
EvmAddressesByType[MotionTypeForms.NodeOperatorIncreaseLimit]
const nodeOperatorIncreaseLimitAddress =
nodeOperatorIncreaseLimitAddressMap[parseEvmSupportedChainId(chainId)]
const sandboxNodeOperatorIncreaseLimitAddressMap =
EvmAddressesByType[MotionTypeForms.SandboxNodeOperatorIncreaseLimit]
const sandboxNodeOperatorIncreaseLimitAddress =
sandboxNodeOperatorIncreaseLimitAddressMap[
parseEvmSupportedChainId(chainId)
]

const contracts = useMemo(() => {
return Object.values(EVM_CONTRACTS).filter(
contract =>
contract.address[chainId] &&
contract.address[chainId] !== nodeOperatorIncreaseLimitAddress &&
contract.address[chainId] !== sandboxNodeOperatorIncreaseLimitAddress,
)
}, [
chainId,
nodeOperatorIncreaseLimitAddress,
sandboxNodeOperatorIncreaseLimitAddress,
])

const getTrustedConnectionInfo = useCallback(async () => {
const promiseResult = await Promise.allSettled(
contracts.map(contract => {
const connectedContract = contract.connectRpc({ chainId })

if (!isHasTrustedCaller(connectedContract)) return null

return connectedContract.trustedCaller()
}),
)

const isNodeOperatorConnected = getIsNodeOperatorConnected(
walletAddress,
nodeOperators.data,
)
const isSandboxNodeOperatorConnected = getIsNodeOperatorConnected(
walletAddress,
sandboxNodeOperators.data,
)

const trustedCallerConnectedMap = promiseResult.reduce(
(acc, cur, index) => {
if (cur.status !== 'fulfilled') return acc
const contractAddress = contracts[index].address[chainId]

if (!contractAddress) return acc
const contractType =
EvmTypesByAdress[parseEvmSupportedChainId(chainId)][contractAddress]

if (
!contractType ||
!Object.keys(MotionTypeForms).includes(contractType)
)
return acc

acc[contractType as MotionTypeForms] = cur.value === walletAddress

return acc
},
{
[MotionTypeForms.NodeOperatorIncreaseLimit]: isNodeOperatorConnected,
[MotionTypeForms.SandboxNodeOperatorIncreaseLimit]:
isSandboxNodeOperatorConnected,
} as Record<MotionTypeForms, boolean>,
)
setAvailableMotions(trustedCallerConnectedMap)
}, [
contracts,
walletAddress,
nodeOperators.data,
sandboxNodeOperators.data,
chainId,
])

useEffect(() => {
getTrustedConnectionInfo()
}, [getTrustedConnectionInfo])
const { data: nodeOperators, initialLoading: isNodeOperatorsDataLoading } =
useNodeOperatorsList('curated')

const {
data: sandboxNodeOperators,
initialLoading: isSandboxNodeOperatorsDataLoading,
} = useNodeOperatorsList('sandbox')

const {
data: availableMotions,
initialLoading: isAvailableMotionsDataLoading,
} = useSWR<AvailableMotions>(
walletAddress && nodeOperators && sandboxNodeOperators
? `available-motions-${chainId}-${walletAddress}`
: null,
async () => {
const parsedChainId = parseEvmSupportedChainId(chainId)
const nodeOperatorIncreaseLimitAddress =
EVM_CONTRACTS[MotionTypeForms.NodeOperatorIncreaseLimit].address[
parsedChainId
]
const sandboxNodeOperatorIncreaseLimitAddress =
EVM_CONTRACTS[MotionTypeForms.SandboxNodeOperatorIncreaseLimit].address[
parsedChainId
]

const promiseResult = await Promise.allSettled(
Object.values(EVM_CONTRACTS).map(async contract => {
const contractAddress = contract.address[chainId]

if (
!contractAddress ||
contractAddress === nodeOperatorIncreaseLimitAddress ||
contractAddress === sandboxNodeOperatorIncreaseLimitAddress
) {
return null
}

const connectedContract = contract.connectRpc({ chainId })

if (!isHasTrustedCaller(connectedContract)) {
return null
}

const trustedCaller = await connectedContract.trustedCaller()

return { contractAddress, trustedCaller }
}),
)

const isNodeOperatorConnected = getIsNodeOperatorConnected(
walletAddress,
nodeOperators,
)
const isSandboxNodeOperatorConnected = getIsNodeOperatorConnected(
walletAddress,
sandboxNodeOperators,
)

return promiseResult.reduce(
(acc, cur) => {
if (cur.status !== 'fulfilled' || !cur.value) {
return acc
}

const { contractAddress, trustedCaller } = cur.value

const contractType =
EvmTypesByAdress[parseEvmSupportedChainId(chainId)][contractAddress]

if (
!contractType ||
!Object.keys(MotionTypeForms).includes(contractType)
) {
return acc
}

acc[contractType as MotionTypeForms] = trustedCaller === walletAddress

return acc
},
{
[MotionTypeForms.NodeOperatorIncreaseLimit]: isNodeOperatorConnected,
[MotionTypeForms.SandboxNodeOperatorIncreaseLimit]:
isSandboxNodeOperatorConnected,
} as AvailableMotions,
)
},
{ revalidateOnReconnect: false, revalidateOnFocus: false },
)

const notHaveAvailableMotions = useMemo(() => {
if (!availableMotions) return true
return Object.values(availableMotions).every(value => !value)
}, [availableMotions])

return { availableMotions, notHaveAvailableMotions }
return {
availableMotions,
initialLoading:
isAvailableMotionsDataLoading ||
isNodeOperatorsDataLoading ||
isSandboxNodeOperatorsDataLoading,
notHaveAvailableMotions,
}
}
4 changes: 4 additions & 0 deletions modules/motions/hooks/useTransitionLimits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ export const useTransitionLimits = () => {

const limits: LimitsMap = {}

if (!params.length) {
return limits
}

for (const index of TOKEN_INDEXES) {
const rawAddress: string | undefined =
// literal definition because params[4][2].toHexString() === '0x00
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function DescNodeOperatorIncreaseLimit({
const nodeOperatorId = Number(callData._nodeOperatorId)
const registryType = getNodeOperatorRegistryType(motionType)
const { data: nodeOperators } = useNodeOperatorsList(registryType)
const nodeOperatorName = nodeOperators?.[nodeOperatorId].name ?? ''
const nodeOperatorName = nodeOperators?.[nodeOperatorId]?.name ?? ''

return (
<div>
Expand Down
7 changes: 4 additions & 3 deletions modules/motions/ui/MotionFormStartNew/MotionFormStartNew.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export function MotionFormStartNew({ onComplete }: Props) {
const [isSubmitting, setSubmitting] = useState(false)
const sendTransaction = useSendTransactionGnosisWorkaround()

const { availableMotions, notHaveAvailableMotions } = useAvailableMotions()
const { availableMotions, initialLoading, notHaveAvailableMotions } =
useAvailableMotions()

const formMethods = useForm<FormData>({
mode: 'onChange',
Expand Down Expand Up @@ -106,8 +107,8 @@ export function MotionFormStartNew({ onComplete }: Props) {
</>
)

if (!availableMotions) return <PageLoader />
if (notHaveAvailableMotions) {
if (initialLoading) return <PageLoader />
if (notHaveAvailableMotions || !availableMotions) {
return (
<MessageBox>
Only Trusted Callers & Node Operator have access to Easy Track motion
Expand Down

0 comments on commit bcc5023

Please sign in to comment.