remove OceanProvider (#988)

This commit is contained in:
Matthias Kretschmann 2022-01-13 13:15:15 +00:00 committed by GitHub
parent 329ac9bbc3
commit f6097bf158
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 108 additions and 242 deletions

View File

@ -7,7 +7,7 @@ import React, {
useCallback,
ReactNode
} from 'react'
import { Asset, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
import { Asset, Config, LoggerInstance, Purgatory } from '@oceanprotocol/lib'
import getAssetPurgatoryData from '@utils/purgatory'
import { CancelToken } from 'axios'
import { retrieveDDO } from '@utils/aquarius'
@ -15,6 +15,7 @@ import { getPrice } from '@utils/subgraph'
import { useWeb3 } from './Web3'
import { useSiteMetadata } from '@hooks/useSiteMetadata'
import { useCancelToken } from '@hooks/useCancelToken'
import { getOceanConfig, getDevelopmentConfig } from '@utils/ocean'
interface AssetProviderValue {
isInPurgatory: boolean
@ -26,6 +27,7 @@ interface AssetProviderValue {
error?: string
refreshInterval: number
isAssetNetwork: boolean
oceanConfig: Config
loading: boolean
refreshDdo: (token?: CancelToken) => Promise<void>
}
@ -35,10 +37,10 @@ const AssetContext = createContext({} as AssetProviderValue)
const refreshInterval = 10000 // 10 sec.
function AssetProvider({
asset,
did,
children
}: {
asset: string | Asset
did: string
children: ReactNode
}): ReactElement {
const { appConfig } = useSiteMetadata()
@ -47,24 +49,24 @@ function AssetProvider({
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<Purgatory>()
const [ddo, setDDO] = useState<Asset>()
const [did, setDID] = useState<string>()
const [title, setTitle] = useState<string>()
const [price, setPrice] = useState<BestPrice>()
const [owner, setOwner] = useState<string>()
const [error, setError] = useState<string>()
const [loading, setLoading] = useState(false)
const [isAssetNetwork, setIsAssetNetwork] = useState<boolean>()
const [oceanConfig, setOceanConfig] = useState<Config>()
const newCancelToken = useCancelToken()
const fetchDdo = async (token?: CancelToken) => {
LoggerInstance.log('[asset] Init asset, get DDO')
setLoading(true)
const ddo = await retrieveDDO(asset as string, token)
const ddo = await retrieveDDO(did, token)
if (!ddo) {
setError(
`[asset] The DDO for ${asset} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
`[asset] The DDO for ${did} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
)
} else {
setError(undefined)
@ -94,11 +96,11 @@ function AssetProvider({
}
}, [])
//
// Get and set DDO based on passed DDO or DID
//
// -----------------------------------
// Get and set DDO based on passed DID
// -----------------------------------
useEffect(() => {
if (!asset || !appConfig.metadataCacheUri) return
if (!did || !appConfig.metadataCacheUri) return
let isMounted = true
@ -107,7 +109,6 @@ function AssetProvider({
if (!isMounted || !ddo) return
LoggerInstance.debug('[asset] Got DDO', ddo)
setDDO(ddo)
setDID(asset as string)
setTitle(ddo.metadata.name)
setOwner(ddo.nft.owner)
setIsInPurgatory(ddo.purgatory.state === true)
@ -117,8 +118,11 @@ function AssetProvider({
return () => {
isMounted = false
}
}, [asset, appConfig.metadataCacheUri])
}, [did, appConfig.metadataCacheUri])
// -----------------------------------
// Attach price to asset
// -----------------------------------
const initPrice = useCallback(async (ddo: Asset): Promise<void> => {
if (!ddo) return
const returnedPrice = await getPrice(ddo)
@ -130,7 +134,9 @@ function AssetProvider({
initPrice(ddo)
}, [ddo, initPrice])
// -----------------------------------
// Check user network against asset network
// -----------------------------------
useEffect(() => {
if (!networkId || !ddo) return
@ -138,6 +144,23 @@ function AssetProvider({
setIsAssetNetwork(isAssetNetwork)
}, [networkId, ddo])
// -----------------------------------
// Load ocean config based on asset network
// -----------------------------------
useEffect(() => {
if (!ddo?.chainId) return
const oceanConfig = {
...getOceanConfig(ddo?.chainId),
// add local dev values
...(ddo?.chainId === 8996 && {
...getDevelopmentConfig()
})
}
setOceanConfig(oceanConfig)
}, [ddo])
return (
<AssetContext.Provider
value={
@ -153,7 +176,8 @@ function AssetProvider({
refreshInterval,
loading,
refreshDdo,
isAssetNetwork
isAssetNetwork,
oceanConfig
} as AssetProviderValue
}
>

View File

@ -1,107 +0,0 @@
import React, {
useContext,
useState,
createContext,
ReactElement,
useCallback,
ReactNode,
useEffect
} from 'react'
import { Config, LoggerInstance } from '@oceanprotocol/lib'
import { useWeb3 } from './Web3'
import { getDevelopmentConfig, getOceanConfig } from '@utils/ocean'
import { useAsset } from './Asset'
interface OceanProviderValue {
config: Config
}
const OceanContext = createContext({} as OceanProviderValue)
function OceanProvider({ children }: { children: ReactNode }): ReactElement {
const { web3, accountId } = useWeb3()
const { ddo } = useAsset()
const [config, setConfig] = useState<Config>()
// -----------------------------------
// Helper: Create Ocean instance
// -----------------------------------
const connect = useCallback(
async (config: Config) => {
if (!web3) return
const newConfig: Config = {
...config,
web3Provider: web3
}
try {
LoggerInstance.log(
'[ocean] Connecting Ocean... not anymore ',
newConfig
)
setConfig(newConfig)
} catch (error) {
LoggerInstance.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 ( !accountId || !web3) return
// async function getInfo() {
// const account = (await ocean.accounts.list())[0]
// LoggerInstance.log('[ocean] Account: ', account)
// setAccount(account)
// }
// getInfo()
// }, [ocean, accountId, web3])
return (
<OceanContext.Provider
value={
{
connect,
config
// refreshBalance
} as OceanProviderValue
}
>
{children}
</OceanContext.Provider>
)
}
// Helper hook to access the provider values
const useOcean = (): OceanProviderValue => useContext(OceanContext)
export { OceanProvider, useOcean, OceanContext }
export default OceanProvider

View File

@ -1,9 +1,9 @@
import { useState, useEffect } from 'react'
import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
import { Config, LoggerInstance } from '@oceanprotocol/lib'
import Web3 from 'web3'
import axios, { AxiosResponse } from 'axios'
import { getOceanConfig } from '@utils/ocean'
const blockDifferenceThreshold = 30
const ethGraphUrl = `https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks`
@ -52,33 +52,41 @@ async function getBlockSubgraph(subgraphUri: string) {
return blockNumberGraph
}
export function useGraphSyncStatus(): UseGraphSyncStatus {
const { config } = useOcean()
export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
const { block, web3Loading } = useWeb3()
const [blockGraph, setBlockGraph] = useState<number>()
const [blockHead, setBlockHead] = useState<number>()
const [isGraphSynced, setIsGraphSynced] = useState(true)
const [subgraphLoading, setSubgraphLoading] = useState(false)
const [oceanConfig, setOceanConfig] = useState<Config>()
// Grab ocean config based on passed networkId
useEffect(() => {
if (!networkId) return
const oceanConfig = getOceanConfig(networkId)
setOceanConfig(oceanConfig)
}, [networkId])
// Get and set head block
useEffect(() => {
if (!config?.nodeUri || web3Loading) return
if (!oceanConfig?.nodeUri || web3Loading) return
async function initBlockHead() {
const blockHead = block || (await getBlockHead(config))
const blockHead = block || (await getBlockHead(oceanConfig))
setBlockHead(blockHead)
LoggerInstance.log('[GraphStatus] Head block: ', blockHead)
}
initBlockHead()
}, [web3Loading, block, config])
}, [web3Loading, block, oceanConfig])
// Get and set subgraph block
useEffect(() => {
if (!config?.subgraphUri) return
if (!oceanConfig?.subgraphUri) return
async function initBlockSubgraph() {
setSubgraphLoading(true)
const blockGraph = await getBlockSubgraph(config.subgraphUri)
const blockGraph = await getBlockSubgraph(oceanConfig.subgraphUri)
setBlockGraph(blockGraph)
setSubgraphLoading(false)
LoggerInstance.log(
@ -87,7 +95,7 @@ export function useGraphSyncStatus(): UseGraphSyncStatus {
)
}
initBlockSubgraph()
}, [config])
}, [oceanConfig])
// Set sync status
useEffect(() => {

View File

@ -1,5 +1,5 @@
import { Asset, LoggerInstance } from '@oceanprotocol/lib'
import { useState } from 'react'
import { Asset, Config, LoggerInstance } from '@oceanprotocol/lib'
import { useEffect, useState } from 'react'
import { TransactionReceipt } from 'web3-core'
import { Decimal } from 'decimal.js'
import {
@ -10,8 +10,8 @@ import {
getDispenseFeedback
} from '@utils/feedback'
import { sleep } from '@utils/index'
import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
import { getOceanConfig } from '@utils/ocean'
interface UsePricing {
getDTSymbol: (ddo: Asset) => Promise<string>
@ -33,12 +33,20 @@ interface UsePricing {
}
function usePricing(): UsePricing {
const { accountId } = useWeb3()
const { config } = useOcean()
const { accountId, networkId } = useWeb3()
const [pricingIsLoading, setPricingIsLoading] = useState(false)
const [pricingStep, setPricingStep] = useState<number>()
const [pricingStepText, setPricingStepText] = useState<string>()
const [pricingError, setPricingError] = useState<string>()
const [oceanConfig, setOceanConfig] = useState<Config>()
// Grab ocen config based on passed networkId
useEffect(() => {
if (!networkId) return
const oceanConfig = getOceanConfig(networkId)
setOceanConfig(oceanConfig)
}, [networkId])
async function getDTSymbol(ddo: Asset): Promise<string> {
if (!accountId) return
@ -155,18 +163,20 @@ function usePricing(): UsePricing {
break
}
case 'fixed': {
if (!config.oceanTokenAddress) {
LoggerInstance.error(`'oceanTokenAddress' not set in config`)
if (!oceanConfig.oceanTokenAddress) {
LoggerInstance.error(`'oceanTokenAddress' not set in oceanConfig`)
return
}
if (!config.fixedRateExchangeAddress) {
LoggerInstance.error(`'fixedRateExchangeAddress' not set in config`)
if (!oceanConfig.fixedRateExchangeAddress) {
LoggerInstance.error(
`'fixedRateExchangeAddress' not set in oceanConfig`
)
return
}
LoggerInstance.log('Buying token from exchange', price, accountId)
// await ocean.datatokens.approve(
// config.oceanTokenAddress,
// config.fixedRateExchangeAddress,
// oceanConfig.oceanTokenAddress,
// oceanConfig.fixedRateExchangeAddress,
// `${price.value}`,
// accountId
// )
@ -232,8 +242,8 @@ function usePricing(): UsePricing {
let { amountDataToken } = priceOptions
const isPool = type === 'dynamic'
if (!isPool && !config.fixedRateExchangeAddress) {
LoggerInstance.error(`'fixedRateExchangeAddress' not set in config.`)
if (!isPool && !oceanConfig.fixedRateExchangeAddress) {
LoggerInstance.error(`'fixedRateExchangeAddress' not set in oceanConfig.`)
return
}

View File

@ -200,8 +200,6 @@ function getServiceEndpoints(data: TokenOrder[], assets: Asset[]): string[] {
// export async function getComputeJobs(
// chainIds: number[],
// config: Config,
// ocean: Ocean,
// account: Account,
// ddo?: Asset,
// token?: CancelToken

View File

@ -2,7 +2,6 @@ import React, { ReactElement, ReactNode, useEffect, useState } from 'react'
import External from '@images/external.svg'
import classNames from 'classnames/bind'
import { Config } from '@oceanprotocol/lib'
import { useOcean } from '@context/Ocean'
import styles from './index.module.css'
import { getOceanConfig } from '@utils/ocean'
@ -19,7 +18,6 @@ export default function ExplorerLink({
children: ReactNode
className?: string
}): ReactElement {
const { config } = useOcean()
const [url, setUrl] = useState<string>()
const [oceanConfig, setOceanConfig] = useState<Config>()
const styleClasses = cx({
@ -30,15 +28,10 @@ export default function ExplorerLink({
useEffect(() => {
if (!networkId) return
async function initOcean() {
const oceanInitialConfig = getOceanConfig(networkId)
setOceanConfig(oceanInitialConfig)
setUrl(oceanInitialConfig?.explorerUri)
}
if (oceanConfig === undefined) {
initOcean()
}
}, [config, oceanConfig, networkId])
const oceanConfig = getOceanConfig(networkId)
setOceanConfig(oceanConfig)
setUrl(oceanConfig?.explorerUri)
}, [networkId])
return (
<a

View File

@ -1,14 +0,0 @@
.sync {
display: inline-block;
font-size: var(--font-size-mini);
cursor: help;
}
.text {
margin-left: calc(var(--spacer) / 12);
}
.status {
transform: scale(0.7);
transform-origin: bottom;
}

View File

@ -1,23 +0,0 @@
import React, { ReactElement } from 'react'
import Tooltip from '@shared/atoms/Tooltip'
import Status from '@shared/atoms/Status'
import { useGraphSyncStatus } from '@hooks/useGraphSyncStatus'
import styles from './index.module.css'
export default function SyncStatus(): ReactElement {
const { isGraphSynced, blockGraph, blockHead } = useGraphSyncStatus()
return (
<div className={styles.sync}>
<Tooltip
content={`Synced to Ethereum block ${blockGraph} (out of ${blockHead})`}
>
<Status
className={styles.status}
state={isGraphSynced ? 'success' : 'error'}
/>
<span className={styles.text}>{blockGraph}</span>
</Tooltip>
</div>
)
}

View File

@ -12,12 +12,14 @@ export declare type Web3Error = {
}
export default function Web3Feedback({
networkId,
isAssetNetwork
}: {
networkId: number
isAssetNetwork?: boolean
}): ReactElement {
const { accountId } = useWeb3()
const { isGraphSynced, blockGraph, blockHead } = useGraphSyncStatus()
const { isGraphSynced, blockGraph, blockHead } = useGraphSyncStatus(networkId)
const [state, setState] = useState<string>()
const [title, setTitle] = useState<string>()
const [message, setMessage] = useState<string>()

View File

@ -7,7 +7,6 @@ import { compareAsBN } from '@utils/numbers'
import ButtonBuy from '@shared/ButtonBuy'
import PriceOutput from './PriceOutput'
import { useAsset } from '@context/Asset'
import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
import content from '../../../../../content/pages/startComputeDataset.json'
import { Asset } from '@oceanprotocol/lib'

View File

@ -18,7 +18,6 @@ import { getMaxPercentRemove } from './utils'
import debounce from 'lodash.debounce'
import UserLiquidity from '../UserLiquidity'
import InputElement from '@shared/FormInput/InputElement'
import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
import Decimal from 'decimal.js'
import { useAsset } from '@context/Asset'

View File

@ -8,7 +8,6 @@ import {
} from 'formik'
import Input from '@shared/FormInput'
import Button from '@shared/atoms/Button'
import { useOcean } from '@context/Ocean'
import { FormTradeData, TradeItem } from './_types'
import UserLiquidity from '../UserLiquidity'
import { useWeb3 } from '@context/Web3'

View File

@ -157,7 +157,7 @@ export default function AssetActions({
return (
<>
<Tabs items={tabs} className={styles.actions} />
<Web3Feedback isAssetNetwork={isAssetNetwork} />
<Web3Feedback networkId={ddo?.chainId} isAssetNetwork={isAssetNetwork} />
</>
)
}

View File

@ -111,7 +111,10 @@ export default function EditComputeDataset({
setShowEdit={setShowEdit}
/>
</article>
<Web3Feedback isAssetNetwork={isAssetNetwork} />
<Web3Feedback
networkId={ddo?.chainId}
isAssetNetwork={isAssetNetwork}
/>
{debug === true && (
<div className={styles.grid}>
{/* <DebugEditCompute values={values} ddo={ddo} /> */}

View File

@ -1,10 +1,10 @@
import React, { ChangeEvent, ReactElement } from 'react'
import { Field, Form, FormikContextType, useFormikContext } from 'formik'
import { useOcean } from '@context/Ocean'
import Input, { InputProps } from '@shared/FormInput'
import FormActions from './FormActions'
import styles from './FormEditMetadata.module.css'
import { FormPublishData } from '../../Publish/_types'
import { useAsset } from '@context/Asset'
// function handleTimeoutCustomOption(
// data: FormFieldContent[],
@ -54,7 +54,7 @@ export default function FormEditMetadata({
showPrice: boolean
isComputeDataset: boolean
}): ReactElement {
const { config } = useOcean()
const { oceanConfig } = useAsset()
const {
validateField,
setFieldValue
@ -99,7 +99,7 @@ export default function FormEditMetadata({
}
{...field}
component={Input}
prefix={field.name === 'price' && config.oceanTokenSymbol}
prefix={field.name === 'price' && oceanConfig.oceanTokenSymbol}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
handleFieldChange(e, field)
}

View File

@ -145,7 +145,7 @@ export default function Edit({
/> */}
<aside>
<Web3Feedback />
<Web3Feedback networkId={ddo?.chainId} />
</aside>
{/* {debug === true && <Debug values={values} ddo={ddo} />} */}

View File

@ -21,7 +21,6 @@ export default function Footer(): ReactElement {
return (
<footer className={styles.footer}>
<div className={styles.content}>
{/* <SyncStatus /> | */}
<BuildId />
<MarketStats />
<div className={styles.copyright}>

View File

@ -128,7 +128,7 @@ export default function Details(): ReactElement {
</p>
</li>
</ul>
<Web3Feedback />
<Web3Feedback networkId={networkId} />
</div>
)
}

View File

@ -5,12 +5,10 @@ import { LoggerInstance } from '@oceanprotocol/lib'
import Dotdotdot from 'react-dotdotdot'
import Table from '@shared/atoms/Table'
import Button from '@shared/atoms/Button'
import { useOcean } from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
import Details from './Details'
import Refresh from '@images/refresh.svg'
import { useUserPreferences } from '@context/UserPreferences'
import { getOceanConfig } from '@utils/ocean'
import NetworkName from '@shared/NetworkName'
// import { getComputeJobs } from '@utils/compute'
import styles from './index.module.css'
@ -75,26 +73,15 @@ export default function ComputeJobs({
}: {
minimal?: boolean
}): ReactElement {
const { config } = useOcean()
const { accountId, networkId } = useWeb3()
const { ddo } = useAsset()
const [isLoading, setIsLoading] = useState(false)
const { chainIds } = useUserPreferences()
const [isLoading, setIsLoading] = useState(false)
const [jobs, setJobs] = useState<ComputeJobMetaData[]>([])
const isMounted = useIsMounted()
const columnsMinimal = [columns[4], columns[5], columns[3]]
// useEffect(() => {
// async function initOcean() {
// const oceanInitialConfig = getOceanConfig(networkId)
// await connect(oceanInitialConfig)
// }
// if (ocean === undefined) {
// initOcean()
// }
// }, [networkId])
const fetchJobs = useCallback(async () => {
if (!chainIds || chainIds.length === 0 || !accountId) {
setJobs([])
@ -103,13 +90,13 @@ export default function ComputeJobs({
}
try {
setIsLoading(true)
// const jobs = await getComputeJobs(chainIds, config, ocean, account, ddo)
// const jobs = await getComputeJobs(chainIds, accountId, ddo)
// isMounted() && setJobs(jobs.computeJobs)
// setIsLoading(jobs.isLoaded)
} catch (error) {
LoggerInstance.error(error.message)
}
}, [chainIds, accountId, config, ddo, isMounted])
}, [chainIds, accountId, ddo, isMounted])
useEffect(() => {
fetchJobs()

View File

@ -6,7 +6,6 @@ import PublishedList from './PublishedList'
import Downloads from './Downloads'
import ComputeJobs from './ComputeJobs'
import styles from './index.module.css'
import OceanProvider from '@context/Ocean'
import { useWeb3 } from '@context/Web3'
interface HistoryTab {
@ -35,11 +34,7 @@ function getTabs(accountId: string, userAccountId: string): HistoryTab[] {
]
const computeTab: HistoryTab = {
title: 'Compute Jobs',
content: (
<OceanProvider>
<ComputeJobs />
</OceanProvider>
)
content: <ComputeJobs />
}
if (accountId === userAccountId) {
defaultTabs.push(computeTab)

View File

@ -2,17 +2,14 @@ import React, { ReactElement } from 'react'
import { useRouter } from 'next/router'
import PageTemplateAssetDetails from '../../components/Asset'
import AssetProvider from '@context/Asset'
import OceanProvider from '@context/Ocean'
export default function PageAssetDetails(): ReactElement {
const router = useRouter()
const { did } = router.query
return (
<AssetProvider asset={did as string}>
<OceanProvider>
<PageTemplateAssetDetails uri={router.pathname} />
</OceanProvider>
<AssetProvider did={did as string}>
<PageTemplateAssetDetails uri={router.pathname} />
</AssetProvider>
)
}

View File

@ -1,7 +1,6 @@
import React, { ReactElement } from 'react'
import Publish from '../components/Publish'
import Page from '@shared/Page'
import OceanProvider from '@context/Ocean'
import content from '../../content/publish/index.json'
import router from 'next/router'
@ -9,15 +8,13 @@ export default function PagePublish(): ReactElement {
const { title, description } = content
return (
<OceanProvider>
<Page
title={title}
description={description}
uri={router.route}
noPageHeader
>
<Publish content={content} />
</Page>
</OceanProvider>
<Page
title={title}
description={description}
uri={router.route}
noPageHeader
>
<Publish content={content} />
</Page>
)
}