1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-06-28 00:27:49 +02:00
market/src/providers/Asset.tsx

206 lines
5.2 KiB
TypeScript
Raw Normal View History

import React, {
useContext,
useState,
useEffect,
createContext,
ReactElement,
useCallback,
ReactNode
} from 'react'
import { Logger, DDO, BestPrice } from '@oceanprotocol/lib'
import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData'
import { getDataTokenPrice, useOcean } from '@oceanprotocol/react'
import getAssetPurgatoryData from '../utils/purgatory'
import { ConfigHelperConfig } from '@oceanprotocol/lib/dist/node/utils/ConfigHelper'
import axios, { CancelToken } from 'axios'
import { retrieveDDO } from '../utils/aquarius'
import { MetadataMarket } from '../@types/MetaData'
interface AssetProviderValue {
isInPurgatory: boolean
purgatoryData: PurgatoryData
ddo: DDO | undefined
did: string | undefined
metadata: MetadataMarket | undefined
title: string | undefined
owner: string | undefined
price: BestPrice | undefined
error?: string
refreshInterval: number
refreshDdo: (token?: CancelToken) => Promise<void>
refreshPrice: () => Promise<void>
}
const AssetContext = createContext({} as AssetProviderValue)
const refreshInterval = 10000 // 10 sec.
function AssetProvider({
asset,
children
}: {
asset: string | DDO
children: ReactNode
}): ReactElement {
const { ocean, status, config, networkId } = useOcean()
const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<PurgatoryData>()
const [ddo, setDDO] = useState<DDO>()
const [did, setDID] = useState<string>()
const [metadata, setMetadata] = useState<MetadataMarket>()
const [title, setTitle] = useState<string>()
const [price, setPrice] = useState<BestPrice>()
const [owner, setOwner] = useState<string>()
const [error, setError] = useState<string>()
const refreshPrice = useCallback(async () => {
if (
!ddo ||
status !== 1 ||
networkId !== (config as ConfigHelperConfig).networkId
)
return
const newPrice = await getDataTokenPrice(
ocean,
ddo.dataToken,
ddo?.price?.type,
ddo.price.address
)
setPrice(newPrice)
Pool tx history (#307) * graphql Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * ignore generated Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * delete generated Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix travis Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix travis Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix fetch Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix travis Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix fetch Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * update readme Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * pool creator liquidit& statistics Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * graph with the graph Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * cleanup Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix query Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * update poll interval Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * update graph url Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * ocean bump Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * run apollo codegen before starting gatsby * put back graph loading state * typing fix * graph tweak, add error state * readme update * remove unused functions, move graph provider Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix package-lock * fix graph when switching tabs * generate apollo files into one folder * fix loading Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * graph query Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * tx query Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix titles Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix text issues Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix query Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * local pagination Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * return refreshInterval to 10 sec Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * add Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> * fix data set column Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro> Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2021-01-22 18:05:02 +01:00
Logger.log(`Refreshed asset price: ${newPrice?.value}`, newPrice)
}, [ocean, config, ddo, networkId, status])
const fetchDdo = async (token?: CancelToken) => {
Logger.log('Init asset, get ddo')
const ddo = await retrieveDDO(
asset as string,
config.metadataCacheUri,
token
)
if (!ddo) {
setError(
`The DDO for ${asset} was not found in MetadataCache. If you just published a new data set, wait some seconds and refresh this page.`
)
} else {
setError(undefined)
}
return ddo
}
const refreshDdo = async (token?: CancelToken) => {
const ddo = await fetchDdo(token)
Logger.debug('DDO', ddo)
setDDO(ddo)
}
//
// Get and set DDO based on passed DDO or DID
//
useEffect(() => {
if (!asset || !config?.metadataCacheUri) return
const source = axios.CancelToken.source()
let isMounted = true
Logger.log('Init asset, get ddo')
async function init() {
const ddo = await fetchDdo(source.token)
if (!isMounted) return
Logger.debug('DDO', ddo)
setDDO(ddo)
setDID(asset as string)
}
init()
return () => {
isMounted = false
source.cancel()
}
}, [asset, config?.metadataCacheUri])
useEffect(() => {
// Re-fetch price periodically, triggering re-calculation of everything
let isMounted = true
const interval = setInterval(() => {
if (!isMounted) return
refreshPrice()
}, refreshInterval)
return () => {
clearInterval(interval)
isMounted = false
}
}, [ddo, networkId, refreshPrice])
const setPurgatory = useCallback(async (did: string): Promise<void> => {
if (!did) return
try {
const result = await getAssetPurgatoryData(did)
if (result?.did !== undefined) {
setIsInPurgatory(true)
setPurgatoryData(result)
return
}
setIsInPurgatory(false)
} catch (error) {
Logger.error(error)
}
}, [])
const initMetadata = useCallback(
async (ddo: DDO): Promise<void> => {
if (!ddo) return
Logger.log('Init metadata')
// Set price & metadata from DDO first
setPrice(ddo.price)
const { attributes } = ddo.findServiceByType('metadata')
setMetadata((attributes as unknown) as MetadataMarket)
setTitle(attributes?.main.name)
setOwner(ddo.publicKey[0].owner)
setIsInPurgatory(ddo.isInPurgatory === 'true')
await setPurgatory(ddo.id)
await refreshPrice()
},
[refreshPrice, setPurgatory]
)
useEffect(() => {
if (!ddo) return
initMetadata(ddo)
}, [ddo, initMetadata])
return (
<AssetContext.Provider
value={
{
ddo,
did,
metadata,
title,
owner,
price,
error,
isInPurgatory,
purgatoryData,
refreshInterval,
refreshDdo,
refreshPrice
} as AssetProviderValue
}
>
{children}
</AssetContext.Provider>
)
}
// Helper hook to access the provider values
const useAsset = (): AssetProviderValue => useContext(AssetContext)
export { AssetProvider, useAsset, AssetProviderValue, AssetContext }
export default AssetProvider