diff --git a/example/src/AllDdos.tsx b/example/src/AllDdos.tsx index 08b6d4a..5040552 100644 --- a/example/src/AllDdos.tsx +++ b/example/src/AllDdos.tsx @@ -4,6 +4,7 @@ import { DDO } from '@oceanprotocol/lib' import { useState } from 'react' import { useEffect } from 'react' import shortid from 'shortid' +import { MetadataExample } from './MetadataExample' export function AllDdos() { const { accountId, chainId, account, ocean } = useOcean() @@ -32,7 +33,7 @@ export function AllDdos() { {ddos?.map((ddo) => { return (
- {ddo.id} +
) diff --git a/example/src/App.tsx b/example/src/App.tsx index 53390d7..d573c29 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -10,6 +10,7 @@ import { ConsumeDdo } from './ConsumeDdo' import WalletConnectProvider from '@walletconnect/web3-provider' import Torus from '@toruslabs/torus-embed' import { NetworkMonitor } from './NetworkMonitor' +import { MetadataExample } from './MetadataExample' // factory Address needs to be updated each time you deploy the contract on local network const config = { @@ -53,11 +54,7 @@ function App() { }, []) return ( - +
diff --git a/example/src/MetadataExample.tsx b/example/src/MetadataExample.tsx new file mode 100644 index 0000000..263e378 --- /dev/null +++ b/example/src/MetadataExample.tsx @@ -0,0 +1,25 @@ +import React, { useEffect, useState } from 'react' +import { useMetadata } from '@oceanprotocol/react' + +export function MetadataExample({ did }: { did: string }) { + const { title, getBestPrice } = useMetadata(did) + const [price, setPrice] = useState() + + useEffect(() => { + async function init(): Promise { + if (title) { + const price = await getBestPrice() + setPrice(price) + } + } + init() + }, [title]) + + return ( + <> +
+ {title} - {price} +
+ + ) +} diff --git a/src/hooks/useMetadata/useMetadata.ts b/src/hooks/useMetadata/useMetadata.ts index bdf5eac..d4093a1 100644 --- a/src/hooks/useMetadata/useMetadata.ts +++ b/src/hooks/useMetadata/useMetadata.ts @@ -1,81 +1,95 @@ import { useState, useEffect } from 'react' -import { DID, DDO, Metadata, MetadataStore, Logger } from '@oceanprotocol/lib' +import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib' import { useOcean } from '../../providers' import ProviderStatus from '../../providers/OceanProvider/ProviderStatus' import { getBestDataTokenPrice, getCheapestPool } from '../../utils/dtUtils' interface UseMetadata { ddo: DDO + did: DID | string metadata: Metadata title: string - getDDO: (did: DID | string) => Promise - getMetadata: (did: DID | string) => Promise - getTitle: (did: DID | string) => Promise - getBestPrice: (dataTokenAddress: string) => Promise + isLoaded: boolean + getBestPrice: (dataTokenAddress?: string) => Promise getBestPool: ( - dataTokenAddress: string + dataTokenAddress?: string ) => Promise<{ poolAddress: string; poolPrice: string }> } -function useMetadata(did?: DID | string): UseMetadata { +function useMetadata(did?: DID | string, ddo?: DDO): UseMetadata { const { ocean, status, config, accountId } = useOcean() - const [ddo, setDDO] = useState() + const [internalDdo, setDDO] = useState() + const [internalDid, setDID] = useState() const [metadata, setMetadata] = useState() const [title, setTitle] = useState() + const [isLoaded, setIsLoaded] = useState(false) async function getDDO(did: DID | string): Promise { if (status === ProviderStatus.CONNECTED) { const ddo = await ocean.metadatastore.retrieveDDO(did) return ddo } - - // fallback hitting MetadataStore directly - const metadataStore = new MetadataStore(config.metadataStoreUri, Logger) - const ddo = await metadataStore.retrieveDDO(did) - return ddo } - async function getBestPrice(dataTokenAddress: string): Promise { + async function getBestPrice(dataTokenAddress?: string): Promise { + if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken return await getBestDataTokenPrice(ocean, accountId, dataTokenAddress) } async function getBestPool( dataTokenAddress: string ): Promise<{ poolAddress: string; poolPrice: string }> { + if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken return await getCheapestPool(ocean, accountId, dataTokenAddress) } - async function getMetadata(did: DID | string): Promise { - const ddo = await getDDO(did) - if (!ddo) return - const metadata = ddo.findServiceByType('metadata') + async function getMetadata(): Promise { + if (!internalDdo) return + const metadata = internalDdo.findServiceByType('metadata') return metadata.attributes } - async function getTitle(did: DID | string): Promise { - const metadata = await getMetadata(did) + async function getTitle(): Promise { + const metadata = await getMetadata() return metadata.main.name } useEffect(() => { async function init(): Promise { - if (!did) return - const ddo = await getDDO(did) - setDDO(ddo) - - const metadata = await getMetadata(did) - setMetadata(metadata) - setTitle(metadata.main.name) + Logger.debug('meta init', status) + if (ocean && status === ProviderStatus.CONNECTED) { + if (ddo) { + setDDO(ddo) + setDID(ddo.id) + } + Logger.debug('meta init', did) + if (did && !ddo) { + const ddo = await getDDO(did) + Logger.debug('DDO', ddo) + setDDO(ddo) + setDID(did) + } + } } init() - }, [ocean]) + }, [ocean, status]) + useEffect(() => { + async function init(): Promise { + if (internalDdo) { + const metadata = await getMetadata() + setMetadata(metadata) + setTitle(metadata.main.name) + setIsLoaded(true) + } + } + init() + }, [internalDdo]) return { - ddo, + ddo: internalDdo, + did: internalDid, metadata, title, - getDDO, - getMetadata, - getTitle, + isLoaded, getBestPrice, getBestPool }