import React , { createContext , useContext , useMemo , useState , useEffect } from 'react' ; import { Admin } from '../chain/@types/Admin' ; import { adminFactory } from '../chain/contracts/Admin' ; import { useNetwork } from './network' ; import { listenForAccountChange } from '../chain/provider' ; type ContextType = { admins ? : string [ ] ; setAdmins : ( admins : string [ ] | undefined ) => void ; adminContract ? : Admin ; setAdminContract : React . Dispatch < React . SetStateAction < Admin | undefined > > ; userAddress ? : string ; setUserAddress : React . Dispatch < React . SetStateAction < string | undefined > > ; } | undefined ; const AdminDataContext = createContext < ContextType > ( undefined ) ; const loadAdminData = ( adminContract , setAdmins ) => { if ( adminContract === undefined ) { setAdmins ( undefined ) ; } else { adminContract . functions . getAdmins ( ) . then ( admins => { setAdmins ( admins ) ; } ) ; } } ; param { Object } props return export const AdminDataProvider = ( props ) => { const [ admins , setAdmins ] = useState < string [ ] | undefined > ( undefined ) ; const [ adminContract , setAdminContract ] = useState < Admin | undefined > ( undefined ) ; const [ userAddress , setUserAddress ] = useState < string | undefined > ( undefined ) ; const value = useMemo ( ( ) => ( { admins , setAdmins , adminContract , setAdminContract , userAddress , setUserAddress } ) , [ admins , setAdmins , adminContract , setAdminContract , userAddress , setUserAddress ] ) ; const { accountIngressContract , nodeIngressContract } = useNetwork ( ) ; useEffect ( ( ) => { const ingressContract = accountIngressContract || nodeIngressContract ; if ( ingressContract === undefined ) { setAdminContract ( undefined ) ; setUserAddress ( undefined ) ; } else { adminFactory ( ingressContract ) . then ( contract => { setAdminContract ( contract ) ; contract . removeAllListeners ( 'AdminAdded' ) ; contract . removeAllListeners ( 'AdminRemoved' ) ; contract . on ( 'AdminAdded' , ( success , account , message , event ) => { if ( success ) loadAdminData ( contract , setAdmins ) ; } ) ; contract . on ( 'AdminRemoved' , ( success , account , event ) => { if ( success ) loadAdminData ( contract , setAdmins ) ; } ) ; } ) ; ingressContract . signer . getAddress ( ) . then ( setUserAddress ) ; } } , [ accountIngressContract , nodeIngressContract , setAdmins , setUserAddress ] ) ; useEffect ( ( ) => { listenForAccountChange ( setUserAddress ) ; } , [ setUserAddress ] ) ; return < AdminDataContext . Provider value = { value } { ... props } />; } ; return { Object } export const useAdminData = ( ) => { const context = useContext ( AdminDataContext ) ; if ( ! context ) { throw new Error ( 'useAdminData must be used within an AdminDataProvider.' ) ; } const { admins , setAdmins , adminContract , userAddress } = context ; useEffect ( ( ) => { loadAdminData ( adminContract , setAdmins ) ; } , [ adminContract , setAdmins ] ) ; const formattedAdmins = useMemo ( ( ) => { return admins ? admins . map ( address => ( { address , identifier : address . toLowerCase ( ) , status : 'active' } ) ) . reverse ( ) : undefined ; } , [ admins ] ) ; const dataReady = useMemo ( ( ) => adminContract !== undefined && admins !== undefined && userAddress !== undefined , [ adminContract , admins , userAddress ] ) ; const isAdmin = useMemo ( ( ) => ( dataReady && admins ? admins . includes ( userAddress ! ) : false ) , [ dataReady , admins , userAddress ] ) ; return { dataReady , userAddress , isAdmin , admins : formattedAdmins , adminContract } ; } ;