import React, { useContext, useState, createContext, ReactElement, useCallback, ReactNode, useEffect } from 'react' import { Ocean, Logger, Account, ConfigHelperConfig } from '@oceanprotocol/lib' import { useWeb3 } from './Web3' import { getDevelopmentConfig, getOceanConfig } from '@utils/ocean' import { useAsset } from './Asset' interface OceanProviderValue { ocean: Ocean account: Account config: ConfigHelperConfig connect: (config: ConfigHelperConfig) => Promise } const OceanContext = createContext({} as OceanProviderValue) function OceanProvider({ children }: { children: ReactNode }): ReactElement { const { web3, accountId } = useWeb3() const { ddo } = useAsset() const [ocean, setOcean] = useState() const [account, setAccount] = useState() const [config, setConfig] = useState() // ----------------------------------- // Helper: Create Ocean instance // ----------------------------------- const connect = useCallback( async (config: ConfigHelperConfig) => { if (!web3) return const newConfig: ConfigHelperConfig = { ...config, web3Provider: web3 } try { Logger.log('[ocean] Connecting Ocean...', newConfig) const newOcean = await Ocean.getInstance(newConfig) setOcean(newOcean) setConfig(newConfig) Logger.log('[ocean] Ocean instance created.', newOcean) } catch (error) { Logger.error('[ocean] Error: ', error.message) } }, [web3] ) // ----------------------------------- // Initial asset details connection // ----------------------------------- useEffect(() => { if (!ddo?.chainId) return const config = { ...getOceanConfig(ddo?.chainId), // add local dev values ...(ddo?.chainId === 8996 && { ...getDevelopmentConfig() }) } async function init() { await connect(config) } init() }, [connect, ddo]) // ----------------------------------- // Get user info, handle account change from web3 // ----------------------------------- useEffect(() => { if (!ocean || !accountId || !web3) return async function getInfo() { const account = (await ocean.accounts.list())[0] Logger.log('[ocean] Account: ', account) setAccount(account) } getInfo() }, [ocean, accountId, web3]) return ( {children} ) } // Helper hook to access the provider values const useOcean = (): OceanProviderValue => useContext(OceanContext) export { OceanProvider, useOcean, OceanContext } export default OceanProvider