Build the list of validators and required signatures at the moment of the transaction (#367)
This commit is contained in:
parent
9e9e891db8
commit
0eb7c41278
@ -10,6 +10,7 @@ import { ValidatorsConfirmations } from './ValidatorsConfirmations'
|
|||||||
import { getConfirmationsStatusDescription } from '../utils/networks'
|
import { getConfirmationsStatusDescription } from '../utils/networks'
|
||||||
import { useStateProvider } from '../state/StateProvider'
|
import { useStateProvider } from '../state/StateProvider'
|
||||||
import { ExecutionConfirmation } from './ExecutionConfirmation'
|
import { ExecutionConfirmation } from './ExecutionConfirmation'
|
||||||
|
import { useValidatorContract } from '../hooks/useValidatorContract'
|
||||||
|
|
||||||
const StatusLabel = styled.label`
|
const StatusLabel = styled.label`
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -43,11 +44,14 @@ export const ConfirmationsContainer = ({ message, receipt, fromHome, timestamp }
|
|||||||
home: { name: homeName },
|
home: { name: homeName },
|
||||||
foreign: { name: foreignName }
|
foreign: { name: foreignName }
|
||||||
} = useStateProvider()
|
} = useStateProvider()
|
||||||
|
const { requiredSignatures, validatorList } = useValidatorContract({ fromHome, receipt })
|
||||||
const { confirmations, status, executionData, signatureCollected } = useMessageConfirmations({
|
const { confirmations, status, executionData, signatureCollected } = useMessageConfirmations({
|
||||||
message,
|
message,
|
||||||
receipt,
|
receipt,
|
||||||
fromHome,
|
fromHome,
|
||||||
timestamp
|
timestamp,
|
||||||
|
requiredSignatures,
|
||||||
|
validatorList
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -66,7 +70,11 @@ export const ConfirmationsContainer = ({ message, receipt, fromHome, timestamp }
|
|||||||
: ''}
|
: ''}
|
||||||
</p>
|
</p>
|
||||||
</StatusDescription>
|
</StatusDescription>
|
||||||
<ValidatorsConfirmations confirmations={confirmations} />
|
<ValidatorsConfirmations
|
||||||
|
confirmations={confirmations}
|
||||||
|
requiredSignatures={requiredSignatures}
|
||||||
|
validatorList={validatorList}
|
||||||
|
/>
|
||||||
{signatureCollected && <ExecutionConfirmation executionData={executionData} isHome={!fromHome} />}
|
{signatureCollected && <ExecutionConfirmation executionData={executionData} isHome={!fromHome} />}
|
||||||
</StyledConfirmationContainer>
|
</StyledConfirmationContainer>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { formatTxHashExtended } from '../utils/networks'
|
import { formatTxHashExtended } from '../utils/networks'
|
||||||
import { useStateProvider } from '../state/StateProvider'
|
|
||||||
import { useWindowWidth } from '@react-hook/window-size'
|
import { useWindowWidth } from '@react-hook/window-size'
|
||||||
import { VALIDATOR_CONFIRMATION_STATUS } from '../config/constants'
|
import { VALIDATOR_CONFIRMATION_STATUS } from '../config/constants'
|
||||||
import { SimpleLoading } from './commons/Loading'
|
import { SimpleLoading } from './commons/Loading'
|
||||||
@ -18,12 +17,15 @@ const RequiredConfirmations = styled.label`
|
|||||||
|
|
||||||
export interface ValidatorsConfirmationsParams {
|
export interface ValidatorsConfirmationsParams {
|
||||||
confirmations: Array<ConfirmationParam>
|
confirmations: Array<ConfirmationParam>
|
||||||
|
requiredSignatures: number
|
||||||
|
validatorList: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ValidatorsConfirmations = ({ confirmations }: ValidatorsConfirmationsParams) => {
|
export const ValidatorsConfirmations = ({
|
||||||
const {
|
confirmations,
|
||||||
home: { requiredSignatures, validatorList }
|
requiredSignatures,
|
||||||
} = useStateProvider()
|
validatorList
|
||||||
|
}: ValidatorsConfirmationsParams) => {
|
||||||
const windowWidth = useWindowWidth()
|
const windowWidth = useWindowWidth()
|
||||||
|
|
||||||
const getValidatorStatusElement = (validatorStatus = '') => {
|
const getValidatorStatusElement = (validatorStatus = '') => {
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { HOME_AMB_ABI, FOREIGN_AMB_ABI, BRIDGE_VALIDATORS_ABI } from '../../../commons'
|
import { HOME_AMB_ABI, FOREIGN_AMB_ABI } from '../../../commons'
|
||||||
import { FOREIGN_BRIDGE_ADDRESS, HOME_BRIDGE_ADDRESS } from '../config/constants'
|
import { FOREIGN_BRIDGE_ADDRESS, HOME_BRIDGE_ADDRESS } from '../config/constants'
|
||||||
import { Contract } from 'web3-eth-contract'
|
import { Contract } from 'web3-eth-contract'
|
||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
import {
|
import { getRequiredBlockConfirmations } from '../utils/contract'
|
||||||
getRequiredBlockConfirmations,
|
|
||||||
getRequiredSignatures,
|
|
||||||
getValidatorAddress,
|
|
||||||
getValidatorList
|
|
||||||
} from '../utils/contract'
|
|
||||||
|
|
||||||
export interface useBridgeContractsParams {
|
export interface useBridgeContractsParams {
|
||||||
homeWeb3: Web3
|
homeWeb3: Web3
|
||||||
@ -20,9 +15,6 @@ export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContracts
|
|||||||
const [foreignBridge, setForeignBridge] = useState<Maybe<Contract>>(null)
|
const [foreignBridge, setForeignBridge] = useState<Maybe<Contract>>(null)
|
||||||
const [homeBlockConfirmations, setHomeBlockConfirmations] = useState(0)
|
const [homeBlockConfirmations, setHomeBlockConfirmations] = useState(0)
|
||||||
const [foreignBlockConfirmations, setForeignBlockConfirmations] = useState(0)
|
const [foreignBlockConfirmations, setForeignBlockConfirmations] = useState(0)
|
||||||
const [homeValidatorContract, setHomeValidatorContract] = useState<Maybe<Contract>>(null)
|
|
||||||
const [homeRequiredSignatures, setHomeRequiredSignatures] = useState(0)
|
|
||||||
const [homeValidatorList, setHomeValidatorList] = useState([])
|
|
||||||
|
|
||||||
const callRequireBlockConfirmations = async (contract: Maybe<Contract>, setResult: Function) => {
|
const callRequireBlockConfirmations = async (contract: Maybe<Contract>, setResult: Function) => {
|
||||||
if (!contract) return
|
if (!contract) return
|
||||||
@ -30,31 +22,11 @@ export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContracts
|
|||||||
setResult(result)
|
setResult(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
const callValidatorContract = async (bridgeContract: Maybe<Contract>, web3: Web3, setValidatorContract: Function) => {
|
|
||||||
if (!web3 || !bridgeContract) return
|
|
||||||
const address = await getValidatorAddress(bridgeContract)
|
|
||||||
const contract = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, address)
|
|
||||||
setValidatorContract(contract)
|
|
||||||
}
|
|
||||||
|
|
||||||
const callRequiredSignatures = async (contract: Maybe<Contract>, setResult: Function) => {
|
|
||||||
if (!contract) return
|
|
||||||
const result = await getRequiredSignatures(contract)
|
|
||||||
setResult(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
const callValidatorList = async (contract: Maybe<Contract>, setResult: Function) => {
|
|
||||||
if (!contract) return
|
|
||||||
const result = await getValidatorList(contract)
|
|
||||||
setResult(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => {
|
() => {
|
||||||
if (!homeWeb3) return
|
if (!homeWeb3) return
|
||||||
const homeContract = new homeWeb3.eth.Contract(HOME_AMB_ABI, HOME_BRIDGE_ADDRESS)
|
const homeContract = new homeWeb3.eth.Contract(HOME_AMB_ABI, HOME_BRIDGE_ADDRESS)
|
||||||
callRequireBlockConfirmations(homeContract, setHomeBlockConfirmations)
|
callRequireBlockConfirmations(homeContract, setHomeBlockConfirmations)
|
||||||
callValidatorContract(homeContract, homeWeb3, setHomeValidatorContract)
|
|
||||||
setHomeBridge(homeContract)
|
setHomeBridge(homeContract)
|
||||||
},
|
},
|
||||||
[homeWeb3]
|
[homeWeb3]
|
||||||
@ -70,21 +42,10 @@ export const useBridgeContracts = ({ homeWeb3, foreignWeb3 }: useBridgeContracts
|
|||||||
[foreignWeb3]
|
[foreignWeb3]
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(
|
|
||||||
() => {
|
|
||||||
callRequiredSignatures(homeValidatorContract, setHomeRequiredSignatures)
|
|
||||||
callValidatorList(homeValidatorContract, setHomeValidatorList)
|
|
||||||
},
|
|
||||||
[homeValidatorContract]
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
homeBridge,
|
homeBridge,
|
||||||
foreignBridge,
|
foreignBridge,
|
||||||
homeBlockConfirmations,
|
homeBlockConfirmations,
|
||||||
foreignBlockConfirmations,
|
foreignBlockConfirmations
|
||||||
homeValidatorContract,
|
|
||||||
homeRequiredSignatures,
|
|
||||||
homeValidatorList
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,8 @@ export interface useMessageConfirmationsParams {
|
|||||||
receipt: Maybe<TransactionReceipt>
|
receipt: Maybe<TransactionReceipt>
|
||||||
fromHome: boolean
|
fromHome: boolean
|
||||||
timestamp: number
|
timestamp: number
|
||||||
|
requiredSignatures: number
|
||||||
|
validatorList: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfirmationParam {
|
export interface ConfirmationParam {
|
||||||
@ -44,7 +46,14 @@ export interface ExecutionData {
|
|||||||
executionResult: boolean
|
executionResult: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useMessageConfirmations = ({ message, receipt, fromHome, timestamp }: useMessageConfirmationsParams) => {
|
export const useMessageConfirmations = ({
|
||||||
|
message,
|
||||||
|
receipt,
|
||||||
|
fromHome,
|
||||||
|
timestamp,
|
||||||
|
requiredSignatures,
|
||||||
|
validatorList
|
||||||
|
}: useMessageConfirmationsParams) => {
|
||||||
const { home, foreign } = useStateProvider()
|
const { home, foreign } = useStateProvider()
|
||||||
const [confirmations, setConfirmations] = useState<Array<ConfirmationParam>>([])
|
const [confirmations, setConfirmations] = useState<Array<ConfirmationParam>>([])
|
||||||
const [status, setStatus] = useState(CONFIRMATIONS_STATUS.UNDEFINED)
|
const [status, setStatus] = useState(CONFIRMATIONS_STATUS.UNDEFINED)
|
||||||
@ -91,7 +100,7 @@ export const useMessageConfirmations = ({ message, receipt, fromHome, timestamp
|
|||||||
targetBlock,
|
targetBlock,
|
||||||
setWaitingBlocks,
|
setWaitingBlocks,
|
||||||
setWaitingBlocksResolved,
|
setWaitingBlocksResolved,
|
||||||
home.validatorList,
|
validatorList,
|
||||||
setConfirmations,
|
setConfirmations,
|
||||||
blockProvider,
|
blockProvider,
|
||||||
interval,
|
interval,
|
||||||
@ -103,15 +112,7 @@ export const useMessageConfirmations = ({ message, receipt, fromHome, timestamp
|
|||||||
blockProvider.stop()
|
blockProvider.stop()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[foreign.blockConfirmations, foreign.web3, fromHome, home.blockConfirmations, validatorList, home.web3, receipt]
|
||||||
foreign.blockConfirmations,
|
|
||||||
foreign.web3,
|
|
||||||
fromHome,
|
|
||||||
home.blockConfirmations,
|
|
||||||
home.validatorList,
|
|
||||||
home.web3,
|
|
||||||
receipt
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// The collected signature event is only fetched once the signatures are collected on tx from home to foreign, to calculate if
|
// The collected signature event is only fetched once the signatures are collected on tx from home to foreign, to calculate if
|
||||||
@ -208,11 +209,11 @@ export const useMessageConfirmations = ({ message, receipt, fromHome, timestamp
|
|||||||
getConfirmationsForTx(
|
getConfirmationsForTx(
|
||||||
message.data,
|
message.data,
|
||||||
home.web3,
|
home.web3,
|
||||||
home.validatorList,
|
validatorList,
|
||||||
home.bridgeContract,
|
home.bridgeContract,
|
||||||
confirmationContractMethod,
|
confirmationContractMethod,
|
||||||
setConfirmations,
|
setConfirmations,
|
||||||
home.requiredSignatures,
|
requiredSignatures,
|
||||||
setSignatureCollected,
|
setSignatureCollected,
|
||||||
waitingBlocksResolved,
|
waitingBlocksResolved,
|
||||||
subscriptions,
|
subscriptions,
|
||||||
@ -231,9 +232,9 @@ export const useMessageConfirmations = ({ message, receipt, fromHome, timestamp
|
|||||||
fromHome,
|
fromHome,
|
||||||
message.data,
|
message.data,
|
||||||
home.web3,
|
home.web3,
|
||||||
home.validatorList,
|
validatorList,
|
||||||
home.bridgeContract,
|
home.bridgeContract,
|
||||||
home.requiredSignatures,
|
requiredSignatures,
|
||||||
waitingBlocksResolved,
|
waitingBlocksResolved,
|
||||||
timestamp
|
timestamp
|
||||||
]
|
]
|
||||||
|
68
alm/src/hooks/useValidatorContract.ts
Normal file
68
alm/src/hooks/useValidatorContract.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { Contract } from 'web3-eth-contract'
|
||||||
|
import Web3 from 'web3'
|
||||||
|
import { getRequiredSignatures, getValidatorAddress, getValidatorList } from '../utils/contract'
|
||||||
|
import { BRIDGE_VALIDATORS_ABI } from '../../../commons'
|
||||||
|
import { useStateProvider } from '../state/StateProvider'
|
||||||
|
import { TransactionReceipt } from 'web3-eth'
|
||||||
|
|
||||||
|
export interface useValidatorContractParams {
|
||||||
|
fromHome: boolean
|
||||||
|
receipt: Maybe<TransactionReceipt>
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useValidatorContract = ({ receipt, fromHome }: useValidatorContractParams) => {
|
||||||
|
const [validatorContract, setValidatorContract] = useState<Maybe<Contract>>(null)
|
||||||
|
const [requiredSignatures, setRequiredSignatures] = useState(0)
|
||||||
|
const [validatorList, setValidatorList] = useState([])
|
||||||
|
|
||||||
|
const { home, foreign } = useStateProvider()
|
||||||
|
|
||||||
|
const callValidatorContract = async (bridgeContract: Maybe<Contract>, web3: Web3, setValidatorContract: Function) => {
|
||||||
|
if (!web3 || !bridgeContract) return
|
||||||
|
const address = await getValidatorAddress(bridgeContract)
|
||||||
|
const contract = new web3.eth.Contract(BRIDGE_VALIDATORS_ABI, address)
|
||||||
|
setValidatorContract(contract)
|
||||||
|
}
|
||||||
|
|
||||||
|
const callRequiredSignatures = async (
|
||||||
|
contract: Maybe<Contract>,
|
||||||
|
receipt: TransactionReceipt,
|
||||||
|
setResult: Function
|
||||||
|
) => {
|
||||||
|
if (!contract) return
|
||||||
|
const result = await getRequiredSignatures(contract, receipt.blockNumber)
|
||||||
|
setResult(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
const callValidatorList = async (contract: Maybe<Contract>, receipt: TransactionReceipt, setResult: Function) => {
|
||||||
|
if (!contract) return
|
||||||
|
const result = await getValidatorList(contract, receipt.blockNumber)
|
||||||
|
setResult(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
const web3 = fromHome ? home.web3 : foreign.web3
|
||||||
|
const bridgeContract = fromHome ? home.bridgeContract : foreign.bridgeContract
|
||||||
|
|
||||||
|
if (!web3 || !bridgeContract) return
|
||||||
|
callValidatorContract(bridgeContract, web3, setValidatorContract)
|
||||||
|
},
|
||||||
|
[home.web3, foreign.web3, home.bridgeContract, foreign.bridgeContract, fromHome]
|
||||||
|
)
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
if (!receipt) return
|
||||||
|
callRequiredSignatures(validatorContract, receipt, setRequiredSignatures)
|
||||||
|
callValidatorList(validatorContract, receipt, setValidatorList)
|
||||||
|
},
|
||||||
|
[validatorContract, receipt]
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
requiredSignatures,
|
||||||
|
validatorList
|
||||||
|
}
|
||||||
|
}
|
@ -21,14 +21,8 @@ export interface BaseNetworkParams {
|
|||||||
blockConfirmations: number
|
blockConfirmations: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HomeNetworkParams extends BaseNetworkParams {
|
|
||||||
validatorContract: Maybe<Contract>
|
|
||||||
requiredSignatures: number
|
|
||||||
validatorList: Array<string>
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StateContext {
|
export interface StateContext {
|
||||||
home: HomeNetworkParams
|
home: BaseNetworkParams
|
||||||
foreign: BaseNetworkParams
|
foreign: BaseNetworkParams
|
||||||
loading: boolean
|
loading: boolean
|
||||||
}
|
}
|
||||||
@ -40,10 +34,7 @@ const initialState = {
|
|||||||
web3: null,
|
web3: null,
|
||||||
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
bridgeAddress: HOME_BRIDGE_ADDRESS,
|
||||||
bridgeContract: null,
|
bridgeContract: null,
|
||||||
blockConfirmations: 0,
|
blockConfirmations: 0
|
||||||
validatorContract: null,
|
|
||||||
requiredSignatures: 0,
|
|
||||||
validatorList: []
|
|
||||||
},
|
},
|
||||||
foreign: {
|
foreign: {
|
||||||
chainId: 0,
|
chainId: 0,
|
||||||
@ -61,15 +52,7 @@ const StateContext = createContext<StateContext>(initialState)
|
|||||||
export const StateProvider = ({ children }: { children: ReactNode }) => {
|
export const StateProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const homeNetwork = useNetwork(HOME_RPC_URL)
|
const homeNetwork = useNetwork(HOME_RPC_URL)
|
||||||
const foreignNetwork = useNetwork(FOREIGN_RPC_URL)
|
const foreignNetwork = useNetwork(FOREIGN_RPC_URL)
|
||||||
const {
|
const { homeBridge, foreignBridge, homeBlockConfirmations, foreignBlockConfirmations } = useBridgeContracts({
|
||||||
homeBridge,
|
|
||||||
foreignBridge,
|
|
||||||
homeBlockConfirmations,
|
|
||||||
foreignBlockConfirmations,
|
|
||||||
homeValidatorContract,
|
|
||||||
homeRequiredSignatures,
|
|
||||||
homeValidatorList
|
|
||||||
} = useBridgeContracts({
|
|
||||||
homeWeb3: homeNetwork.web3,
|
homeWeb3: homeNetwork.web3,
|
||||||
foreignWeb3: foreignNetwork.web3
|
foreignWeb3: foreignNetwork.web3
|
||||||
})
|
})
|
||||||
@ -80,9 +63,6 @@ export const StateProvider = ({ children }: { children: ReactNode }) => {
|
|||||||
name: HOME_NETWORK_NAME,
|
name: HOME_NETWORK_NAME,
|
||||||
bridgeContract: homeBridge,
|
bridgeContract: homeBridge,
|
||||||
blockConfirmations: homeBlockConfirmations,
|
blockConfirmations: homeBlockConfirmations,
|
||||||
validatorContract: homeValidatorContract,
|
|
||||||
requiredSignatures: homeRequiredSignatures,
|
|
||||||
validatorList: homeValidatorList,
|
|
||||||
...homeNetwork
|
...homeNetwork
|
||||||
},
|
},
|
||||||
foreign: {
|
foreign: {
|
||||||
|
@ -7,12 +7,46 @@ export const getRequiredBlockConfirmations = async (contract: Contract) => {
|
|||||||
|
|
||||||
export const getValidatorAddress = (contract: Contract) => contract.methods.validatorContract().call()
|
export const getValidatorAddress = (contract: Contract) => contract.methods.validatorContract().call()
|
||||||
|
|
||||||
export const getRequiredSignatures = async (contract: Contract) => {
|
export const getRequiredSignatures = async (contract: Contract, blockNumber: number) => {
|
||||||
const requiredSignatures = await contract.methods.requiredSignatures().call()
|
const events = await contract.getPastEvents('RequiredSignaturesChanged', {
|
||||||
|
fromBlock: 0,
|
||||||
|
toBlock: blockNumber
|
||||||
|
})
|
||||||
|
|
||||||
|
// Use the value form last event before the transaction
|
||||||
|
const event = events[events.length - 1]
|
||||||
|
const { requiredSignatures } = event.returnValues
|
||||||
return parseInt(requiredSignatures)
|
return parseInt(requiredSignatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getValidatorList = (contract: Contract) => contract.methods.validatorList().call()
|
export const getValidatorList = async (contract: Contract, blockNumber: number) => {
|
||||||
|
let currentList: string[] = await contract.methods.validatorList().call()
|
||||||
|
const [added, removed] = await Promise.all([
|
||||||
|
contract.getPastEvents('ValidatorAdded', {
|
||||||
|
fromBlock: blockNumber
|
||||||
|
}),
|
||||||
|
contract.getPastEvents('ValidatorRemoved', {
|
||||||
|
fromBlock: blockNumber
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
|
// Ordered desc
|
||||||
|
const orderedEvents = [...added, ...removed].sort(({ blockNumber: prev }, { blockNumber: next }) => next - prev)
|
||||||
|
|
||||||
|
// Stored as a Set to avoid duplicates
|
||||||
|
const validatorList = new Set(currentList)
|
||||||
|
|
||||||
|
orderedEvents.forEach(e => {
|
||||||
|
const { validator } = e.returnValues
|
||||||
|
if (e.event === 'ValidatorRemoved') {
|
||||||
|
validatorList.add(validator)
|
||||||
|
} else if (e.event === 'ValidatorAdded') {
|
||||||
|
validatorList.delete(validator)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return Array.from(validatorList)
|
||||||
|
}
|
||||||
|
|
||||||
export const getMessagesSigned = (contract: Contract, hash: string) => contract.methods.messagesSigned(hash).call()
|
export const getMessagesSigned = (contract: Contract, hash: string) => contract.methods.messagesSigned(hash).call()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user