import { useState, useEffect, useCallback } from 'react' import { DID, DDO, Metadata, Logger, BestPrice } from '@oceanprotocol/lib' import { useOcean } from 'providers' import { isDDO, getDataTokenPrice } from 'utils' import axios, { CancelToken } from 'axios' interface UseMetadata { ddo: DDO | undefined did: DID | string | undefined metadata: Metadata | undefined title: string | undefined owner: string | undefined price: BestPrice | undefined getLivePrice: () => Promise } function useMetadata(asset?: DID | string | DDO): UseMetadata { const { ocean, config, status, networkId } = useOcean() const [internalDdo, setDDO] = useState() const [internalDid, setDID] = useState() const [metadata, setMetadata] = useState() const [title, setTitle] = useState() const [price, setPrice] = useState() const [owner, setOwner] = useState() const getDDO = useCallback( async ( did: DID | string, cancelToken: CancelToken ): Promise => { if (!config.metadataCacheUri) return const request = await axios.get( `${config.metadataCacheUri}/api/v1/aquarius/assets/ddo/${did}`, { cancelToken } ) const ddo = request.data as DDO return ddo }, [config.metadataCacheUri] ) const getLivePrice = useCallback(async (): Promise => { if (!internalDdo) return { type: '', address: '', value: 0, ocean: 0, datatoken: 0 } as BestPrice const price = await getDataTokenPrice( ocean, internalDdo.dataToken, internalDdo?.price?.type, internalDdo.price.pools[0] ) return price }, [ocean, internalDdo]) const getMetadata = useCallback(async (ddo: DDO): Promise => { const metadata = ddo.findServiceByType('metadata') return metadata.attributes }, []) // // Get and set DDO based on passed DDO or DID // useEffect(() => { if (!asset) return const source = axios.CancelToken.source() let isMounted = true async function init(): Promise { if (isDDO(asset as string | DDO | DID)) { setDDO(asset as DDO) setDID((asset as DDO).id) } else { // asset is a DID const ddo = await getDDO(asset as DID, source.token) if (!isMounted) return Logger.debug('DDO', ddo) setDDO(ddo) setDID(asset as DID) } } init() return () => { isMounted = false source.cancel() } }, [asset, getDDO]) // // Get metadata & price for stored DDO // useEffect(() => { async function init(): Promise { if (!internalDdo) return // Set price from DDO first setPrice(internalDdo.price) const metadata = await getMetadata(internalDdo) setMetadata(metadata) setTitle(metadata.main.name) setOwner(internalDdo.publicKey[0].owner) } init() }, [status, networkId, config, internalDdo, getMetadata]) return { ddo: internalDdo, did: internalDid, metadata, title, owner, price, getLivePrice } } export { useMetadata, UseMetadata } export default useMetadata