Skip to content
This repository has been archived by the owner on Aug 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #120 from oceanprotocol/feature/usecallback
Browse files Browse the repository at this point in the history
fix hooks dependencies
  • Loading branch information
mihaisc authored Sep 24, 2020
2 parents 22be66d + f5724c5 commit c937847
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 112 deletions.
15 changes: 10 additions & 5 deletions src/hooks/useCompute/useCompute.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useState } from 'react'
import { useOcean } from '../../providers'
import { ComputeValue } from './ComputeOptions'
import { feedback } from './../../utils'
import { DID, Logger } from '@oceanprotocol/lib'
import { Logger } from '@oceanprotocol/lib'
import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm'
import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob'
import { checkAndBuyDT } from '../../utils/dtUtils'
Expand All @@ -14,7 +13,7 @@ interface UseCompute {
dataTokenAddress: string,
algorithmRawCode: string,
computeContainer: ComputeValue
) => Promise<ComputeJob>
) => Promise<ComputeJob | void>
computeStep?: number
computeStepText?: string
computeError?: string
Expand Down Expand Up @@ -45,7 +44,13 @@ function useCompute(): UseCompute {
const [computeError, setComputeError] = useState<string | undefined>()
const [isLoading, setIsLoading] = useState(false)

function setStep(index: number) {
function setStep(index?: number) {
if (!index) {
setComputeStep(undefined)
setComputeStepText(undefined)
return
}

setComputeStep(index)
setComputeStepText(computeFeedback[index])
}
Expand All @@ -56,7 +61,7 @@ function useCompute(): UseCompute {
dataTokenAddress: string,
algorithmRawCode: string,
computeContainer: ComputeValue
): Promise<ComputeJob> {
): Promise<ComputeJob | void> {
if (!ocean || !account) return

setComputeError(undefined)
Expand Down
119 changes: 68 additions & 51 deletions src/hooks/useMetadata/useMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react'
import { useState, useEffect, useCallback } from 'react'
import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib'
import { useOcean } from '../../providers'
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus'
Expand All @@ -7,83 +7,100 @@ import { isDDO } from '../../utils'
import BestPrice from './BestPrice'

interface UseMetadata {
ddo: DDO
did: DID | string
metadata: Metadata
title: string
price: BestPrice
ddo: DDO | undefined
did: DID | string | undefined
metadata: Metadata | undefined
title: string | undefined
price: BestPrice | undefined
isLoaded: boolean
getPrice: (dataTokenAddress?: string) => Promise<BestPrice>
getPrice: (dataTokenAddress: string) => Promise<BestPrice | void>
}

function useMetadata(asset?: DID | string | DDO): UseMetadata {
const { ocean, status, accountId } = useOcean()
const [internalDdo, setDDO] = useState<DDO | undefined>()
const [internalDid, setDID] = useState<DID | string | undefined>()
const [metadata, setMetadata] = useState<Metadata | undefined>()
const [title, setTitle] = useState<string | undefined>()
const { ocean, status, accountId, chainId } = useOcean()
const [internalDdo, setDDO] = useState<DDO>()
const [internalDid, setDID] = useState<DID | string>()
const [metadata, setMetadata] = useState<Metadata>()
const [title, setTitle] = useState<string>()
const [isLoaded, setIsLoaded] = useState(false)
const [price, setPrice] = useState<BestPrice | undefined>()
const [price, setPrice] = useState<BestPrice>()

async function getDDO(did: DID | string): Promise<DDO | null> {
if (status !== ProviderStatus.CONNECTED) return null
const getDDO = useCallback(
async (did: DID | string): Promise<DDO> => {
const ddo = await ocean.metadatastore.retrieveDDO(did)
return ddo
},
[ocean?.metadatastore]
)

const ddo = await ocean.metadatastore.retrieveDDO(did)
return ddo
}

async function getPrice(dataTokenAddress?: string): Promise<BestPrice> {
if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken
return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId)
}
const getPrice = useCallback(
async (dataTokenAddress: string): Promise<BestPrice> => {
const price = await getBestDataTokenPrice(
ocean,
dataTokenAddress,
accountId
)
return price
},
[ocean, accountId]
)

async function getMetadata(): Promise<Metadata | null> {
if (!internalDdo) return null
const metadata = internalDdo.findServiceByType('metadata')
const getMetadata = useCallback(async (ddo: DDO): Promise<Metadata> => {
const metadata = ddo.findServiceByType('metadata')
return metadata.attributes
}
}, [])

//
// Get and set DDO based on passed DDO or DID
//
useEffect(() => {
if (!asset || !ocean || status !== ProviderStatus.CONNECTED) return

async function init(): Promise<void> {
if (ocean && status === ProviderStatus.CONNECTED) {
if (!asset) return
if (!asset) return

if (isDDO(asset)) {
setDDO(asset)
setDID(asset.id)
} else {
const ddo = await getDDO(asset)
Logger.debug('DDO', ddo)
setDDO(ddo)
setDID(asset)
}
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)
Logger.debug('DDO', ddo)
setDDO(ddo)
setDID(asset as DID)
}
}
init()
}, [ocean, status])
}, [ocean, status, asset, getDDO])

//
// Get metadata for stored DDO
//
useEffect(() => {
if (!accountId) return

async function init(): Promise<void> {
if (internalDdo) {
const metadata = await getMetadata()
setMetadata(metadata)
setTitle(metadata.main.name)
const price = await getPrice()
if (!internalDdo) return

setPrice(price)
setIsLoaded(true)
}
const metadata = await getMetadata(internalDdo)
setMetadata(metadata)
setTitle(metadata.main.name)
const price = await getPrice(internalDdo.dataToken)
price && setPrice(price)
setIsLoaded(true)
}
init()

const interval = setInterval(async () => {
const price = await getPrice()
setPrice(price)
if (!internalDdo) return
const price = await getPrice(internalDdo.dataToken)
price && setPrice(price)
}, 10000)
return () => clearInterval(interval)
}, [accountId, internalDdo])

return () => {
clearInterval(interval)
}
}, [accountId, chainId, internalDdo, getMetadata, getPrice])

return {
ddo: internalDdo,
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/usePublish/usePublish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function usePublish(): UsePublish {
): Promise<void | null> {
switch (priceOptions.type) {
case 'dynamic': {
const pool = await ocean.pool.createDTPool(
await ocean.pool.createDTPool(
accountId,
dataTokenAddress,
priceOptions.tokensToMint.toString(),
Expand All @@ -64,7 +64,7 @@ function usePublish(): UsePublish {
return null
}

const fixedPriceExchange = await ocean.fixedRateExchange.create(
await ocean.fixedRateExchange.create(
dataTokenAddress,
priceOptions.price.toString(),
accountId
Expand Down
96 changes: 50 additions & 46 deletions src/providers/OceanProvider/OceanProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import React, {
useState,
useEffect,
createContext,
ReactElement
ReactElement,
useCallback,
ReactNode
} from 'react'
import Web3 from 'web3'
import ProviderStatus from './ProviderStatus'
Expand Down Expand Up @@ -42,7 +44,7 @@ function OceanProvider({
}: {
initialConfig: Config
web3ModalOpts?: Partial<ICoreOptions>
children: any
children: ReactNode
}): ReactElement {
const [web3, setWeb3] = useState<Web3 | undefined>()
const [web3Provider, setWeb3Provider] = useState<any | undefined>()
Expand All @@ -60,71 +62,74 @@ function OceanProvider({
ProviderStatus.NOT_AVAILABLE
)

async function init() {
const init = useCallback(async () => {
Logger.log('Ocean Provider init')
window &&
window.ethereum &&
(window.ethereum.autoRefreshOnNetworkChange = false)

Logger.log('Web3Modal init.')
if (web3ModalOpts === undefined) {
web3ModalOpts = await getDefaultProviders()
}
const web3ModalInstance = new Web3Modal(web3ModalOpts)

const web3ModalInstance = new Web3Modal(
web3ModalOpts || (await getDefaultProviders())
)
setWeb3Modal(web3ModalInstance)
Logger.log('Web3Modal instance created.', web3ModalInstance)
}
}, [web3ModalOpts])

async function connect(newConfig?: Config) {
try {
Logger.log('Connecting ...', newConfig)
const connect = useCallback(
async (newConfig?: Config) => {
try {
Logger.log('Connecting ...', newConfig)

newConfig && setConfig(newConfig)
newConfig && setConfig(newConfig)

const provider = await web3Modal?.connect()
setWeb3Provider(provider)
const provider = await web3Modal?.connect()
setWeb3Provider(provider)

const web3 = new Web3(provider)
setWeb3(web3)
Logger.log('Web3 created.', web3)
const web3 = new Web3(provider)
setWeb3(web3)
Logger.log('Web3 created.', web3)

const chainId = web3 && (await web3.eth.getChainId())
setChainId(chainId)
Logger.log('chain id ', chainId)
const chainId = web3 && (await web3.eth.getChainId())
setChainId(chainId)
Logger.log('chain id ', chainId)

config.web3Provider = web3
const ocean = await Ocean.getInstance(config)
setOcean(ocean)
Logger.log('Ocean instance created.', ocean)
config.web3Provider = web3
const ocean = await Ocean.getInstance(config)
setOcean(ocean)
Logger.log('Ocean instance created.', ocean)

setStatus(ProviderStatus.CONNECTED)
setStatus(ProviderStatus.CONNECTED)

const account = (await ocean.accounts.list())[0]
setAccount(account)
Logger.log('Account ', account)
const account = (await ocean.accounts.list())[0]
setAccount(account)
Logger.log('Account ', account)

const accountId = await getAccountId(web3)
setAccountId(accountId)
Logger.log('account id', accountId)
const accountId = await getAccountId(web3)
setAccountId(accountId)
Logger.log('account id', accountId)

const balance = await getBalance(account)
setBalance(balance)
Logger.log('balance', JSON.stringify(balance))
} catch (error) {
Logger.error(error)
}
}
const balance = await getBalance(account)
setBalance(balance)
Logger.log('balance', JSON.stringify(balance))
} catch (error) {
Logger.error(error)
}
},
[config, web3Modal]
)

// On mount setup Web3Modal instance
useEffect(() => {
init()
}, [])
}, [init])

// Connect automatically to cached provider if present
useEffect(() => {
if (!web3Modal) return
web3Modal.cachedProvider && connect()
}, [web3Modal])
}, [web3Modal, connect])

async function refreshBalance() {
const balance = account && (await getBalance(account))
Expand All @@ -135,14 +140,13 @@ function OceanProvider({
web3Modal?.clearCachedProvider()
}

const handleAccountsChanged = async (accounts: string[]) => {
Logger.debug("Handling 'accountsChanged' event with payload", accounts)
connect()
}

// TODO: #68 Refetch balance periodically, or figure out some event to subscribe to

useEffect(() => {
const handleAccountsChanged = async (accounts: string[]) => {
Logger.debug("Handling 'accountsChanged' event with payload", accounts)
connect()
}
// web3Modal && web3Modal.on('connect', handleConnect)

if (web3Provider !== undefined && web3Provider !== null) {
Expand All @@ -154,7 +158,7 @@ function OceanProvider({
// web3Provider.removeListener('chainChanged', handleNetworkChanged)
}
}
}, [web3Modal, web3Provider])
}, [web3Modal, web3Provider, connect])

return (
<OceanContext.Provider
Expand Down
5 changes: 2 additions & 3 deletions src/utils/dtUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ export async function getCheapestPool(
export async function getCheapestExchange(
ocean: Ocean,
dataTokenAddress: string
): Promise<{ address?: string; price: string } | null> {
if (!ocean || !dataTokenAddress) return
): Promise<{ address?: string; price: string }> {
try {
const tokenExchanges = await ocean.fixedRateExchange.searchforDT(
dataTokenAddress,
Expand Down Expand Up @@ -94,7 +93,7 @@ export async function getBestDataTokenPrice(
ocean: Ocean,
dataTokenAddress: string,
accountId: string
): Promise<BestPrice | undefined> {
): Promise<BestPrice> {
const cheapestPool = await getCheapestPool(ocean, accountId, dataTokenAddress)
const cheapestExchange = await getCheapestExchange(ocean, dataTokenAddress)
Decimal.set({ precision: 5 })
Expand Down
Loading

0 comments on commit c937847

Please sign in to comment.