2020-11-20 14:31:28 +01:00
|
|
|
import React, {
|
|
|
|
useContext,
|
|
|
|
useState,
|
|
|
|
useEffect,
|
|
|
|
createContext,
|
|
|
|
ReactElement,
|
|
|
|
useCallback,
|
|
|
|
ReactNode
|
|
|
|
} from 'react'
|
2021-02-25 19:15:42 +01:00
|
|
|
import { Logger, DDO, BestPrice, MetadataMain } from '@oceanprotocol/lib'
|
2020-11-20 14:31:28 +01:00
|
|
|
import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/PurgatoryData'
|
|
|
|
import getAssetPurgatoryData from '../utils/purgatory'
|
2020-12-10 14:30:40 +01:00
|
|
|
import axios, { CancelToken } from 'axios'
|
2020-11-23 15:46:49 +01:00
|
|
|
import { retrieveDDO } from '../utils/aquarius'
|
2020-12-10 14:30:40 +01:00
|
|
|
import { MetadataMarket } from '../@types/MetaData'
|
2021-03-17 11:44:26 +01:00
|
|
|
import { useOcean } from './Ocean'
|
|
|
|
import { gql, useQuery } from '@apollo/client'
|
|
|
|
import { PoolPrice } from '../@types/apollo/PoolPrice'
|
|
|
|
import { FrePrice } from '../@types/apollo/FrePrice'
|
2020-11-20 14:31:28 +01:00
|
|
|
|
|
|
|
interface AssetProviderValue {
|
|
|
|
isInPurgatory: boolean
|
|
|
|
purgatoryData: PurgatoryData
|
|
|
|
ddo: DDO | undefined
|
|
|
|
did: string | undefined
|
2020-12-10 14:30:40 +01:00
|
|
|
metadata: MetadataMarket | undefined
|
2020-11-20 14:31:28 +01:00
|
|
|
title: string | undefined
|
|
|
|
owner: string | undefined
|
|
|
|
price: BestPrice | undefined
|
2021-02-25 19:15:42 +01:00
|
|
|
type: MetadataMain['type'] | undefined
|
2020-11-20 14:31:28 +01:00
|
|
|
error?: string
|
|
|
|
refreshInterval: number
|
2020-12-10 14:30:40 +01:00
|
|
|
refreshDdo: (token?: CancelToken) => Promise<void>
|
2020-11-20 14:31:28 +01:00
|
|
|
}
|
|
|
|
|
2021-03-17 11:44:26 +01:00
|
|
|
const poolQuery = gql`
|
|
|
|
query PoolPrice($datatoken: String) {
|
|
|
|
pools(where: { datatokenAddress: $datatoken }) {
|
|
|
|
spotPrice
|
2021-04-12 17:50:26 +02:00
|
|
|
datatokenReserve
|
|
|
|
oceanReserve
|
2021-03-17 11:44:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
|
|
|
const freQuery = gql`
|
|
|
|
query FrePrice($datatoken: String) {
|
|
|
|
fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) {
|
|
|
|
rate
|
2021-03-26 09:48:27 +01:00
|
|
|
id
|
2021-03-17 11:44:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`
|
|
|
|
|
2020-11-20 14:31:28 +01:00
|
|
|
const AssetContext = createContext({} as AssetProviderValue)
|
|
|
|
|
|
|
|
const refreshInterval = 10000 // 10 sec.
|
|
|
|
|
|
|
|
function AssetProvider({
|
|
|
|
asset,
|
|
|
|
children
|
|
|
|
}: {
|
|
|
|
asset: string | DDO
|
|
|
|
children: ReactNode
|
|
|
|
}): ReactElement {
|
2021-03-17 11:44:26 +01:00
|
|
|
const { config } = useOcean()
|
2020-11-20 14:31:28 +01:00
|
|
|
const [isInPurgatory, setIsInPurgatory] = useState(false)
|
|
|
|
const [purgatoryData, setPurgatoryData] = useState<PurgatoryData>()
|
|
|
|
const [ddo, setDDO] = useState<DDO>()
|
|
|
|
const [did, setDID] = useState<string>()
|
2020-12-10 14:30:40 +01:00
|
|
|
const [metadata, setMetadata] = useState<MetadataMarket>()
|
2020-11-20 14:31:28 +01:00
|
|
|
const [title, setTitle] = useState<string>()
|
|
|
|
const [price, setPrice] = useState<BestPrice>()
|
|
|
|
const [owner, setOwner] = useState<string>()
|
|
|
|
const [error, setError] = useState<string>()
|
2021-02-25 19:15:42 +01:00
|
|
|
const [type, setType] = useState<MetadataMain['type']>()
|
2021-03-17 11:44:26 +01:00
|
|
|
const [variables, setVariables] = useState({})
|
|
|
|
|
Start compute job (#439)
* Wip start compute job
* Wip select algorithm design
* Asset selection form component, for start compute job (#442)
* prototype AssetSelection
* assetselection styling
* typing "fix"
* put back file info icon
* AssetSelection styling in context
* update start job method, fixed algo select, and fixed option typing
* compute logic update
* add has previous orders for algo asset
* fixed search algorithm assets in start compute form
* fixed lint errors
* updated previous order for algo logic and compute flow
* update use price hook and added buy DT for algo
* display only alg of type exchange and sort by value
* display only trusted algo for asset if field is set
* added logic for allow all published algorithms or no algorithms allowed
* asset selection style & spacing tweaks
* refactor get algorithms for compute and edit compute
* fixed form options and more refactoring
* new ButtonBuy component
* shared component between consume/compute
* dealing with various states: loading, previous orders, help text output
* effect dependencies
* move error output into toast
* formik data flow refactor
* ditch custom field change handler
* fix initialValues
* typed form data & validation
* fixes multiple form validation issues along the way
* isInitialValid → validateOnMount
* metadata display tweaks
* error feedback tweaks
* oler assets checks, confeti on succes job, market fee on order, removed algo compute logic
* more startJob logging
* feedback & messaging changes
* metadata display
* return all algos, fixed & dynamic priced ones
* fix DOM nesting
* messaging updates
* copy tweaks
* check algorithm previous history for both acces and compute sercive types
* handle start compute error
* extra checks on start compute response
* styling tweaks, fix toast UI errors
* AssetSelection: empty screen, tweak min/max height
* fix FRE issues on start compute
* check is ordarable before start compute job
* logging tweaks
* disable eslint no-unused-vars rule for some Apollo code blocks
* fix metadata editing for compute assets
* consider dataset timeout for compute too
Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2021-04-01 17:21:08 +02:00
|
|
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2021-03-17 11:44:26 +01:00
|
|
|
const {
|
|
|
|
refetch: refetchFre,
|
|
|
|
startPolling: startPollingFre,
|
|
|
|
data: frePrice
|
|
|
|
} = useQuery<FrePrice>(freQuery, {
|
|
|
|
variables,
|
2021-03-26 09:48:27 +01:00
|
|
|
skip: false
|
2021-03-17 11:44:26 +01:00
|
|
|
})
|
|
|
|
const {
|
|
|
|
refetch: refetchPool,
|
|
|
|
startPolling: startPollingPool,
|
|
|
|
data: poolPrice
|
|
|
|
} = useQuery<PoolPrice>(poolQuery, {
|
|
|
|
variables,
|
2021-03-26 09:48:27 +01:00
|
|
|
skip: false
|
2021-03-17 11:44:26 +01:00
|
|
|
})
|
Start compute job (#439)
* Wip start compute job
* Wip select algorithm design
* Asset selection form component, for start compute job (#442)
* prototype AssetSelection
* assetselection styling
* typing "fix"
* put back file info icon
* AssetSelection styling in context
* update start job method, fixed algo select, and fixed option typing
* compute logic update
* add has previous orders for algo asset
* fixed search algorithm assets in start compute form
* fixed lint errors
* updated previous order for algo logic and compute flow
* update use price hook and added buy DT for algo
* display only alg of type exchange and sort by value
* display only trusted algo for asset if field is set
* added logic for allow all published algorithms or no algorithms allowed
* asset selection style & spacing tweaks
* refactor get algorithms for compute and edit compute
* fixed form options and more refactoring
* new ButtonBuy component
* shared component between consume/compute
* dealing with various states: loading, previous orders, help text output
* effect dependencies
* move error output into toast
* formik data flow refactor
* ditch custom field change handler
* fix initialValues
* typed form data & validation
* fixes multiple form validation issues along the way
* isInitialValid → validateOnMount
* metadata display tweaks
* error feedback tweaks
* oler assets checks, confeti on succes job, market fee on order, removed algo compute logic
* more startJob logging
* feedback & messaging changes
* metadata display
* return all algos, fixed & dynamic priced ones
* fix DOM nesting
* messaging updates
* copy tweaks
* check algorithm previous history for both acces and compute sercive types
* handle start compute error
* extra checks on start compute response
* styling tweaks, fix toast UI errors
* AssetSelection: empty screen, tweak min/max height
* fix FRE issues on start compute
* check is ordarable before start compute job
* logging tweaks
* disable eslint no-unused-vars rule for some Apollo code blocks
* fix metadata editing for compute assets
* consider dataset timeout for compute too
Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2021-04-01 17:21:08 +02:00
|
|
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
2020-11-20 14:31:28 +01:00
|
|
|
|
2021-03-26 09:48:27 +01:00
|
|
|
// this is not working as expected, thus we need to fetch both pool and fre
|
|
|
|
// useEffect(() => {
|
|
|
|
// if (!ddo || !variables || variables === '') return
|
|
|
|
|
|
|
|
// if (ddo.price.type === 'exchange') {
|
|
|
|
// refetchFre(variables)
|
|
|
|
// startPollingFre(refreshInterval)
|
|
|
|
// } else {
|
|
|
|
// refetchPool(variables)
|
|
|
|
// startPollingPool(refreshInterval)
|
|
|
|
// }
|
|
|
|
// }, [ddo, variables])
|
2020-11-20 14:31:28 +01:00
|
|
|
|
2021-03-17 11:44:26 +01:00
|
|
|
useEffect(() => {
|
2021-03-26 09:48:27 +01:00
|
|
|
if (
|
|
|
|
!frePrice ||
|
|
|
|
frePrice.fixedRateExchanges.length === 0 ||
|
|
|
|
price.type !== 'exchange'
|
|
|
|
)
|
|
|
|
return
|
|
|
|
setPrice((prevState) => ({
|
|
|
|
...prevState,
|
|
|
|
value: frePrice.fixedRateExchanges[0].rate,
|
|
|
|
address: frePrice.fixedRateExchanges[0].id
|
|
|
|
}))
|
2021-03-17 11:44:26 +01:00
|
|
|
}, [frePrice])
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-03-26 09:48:27 +01:00
|
|
|
if (!poolPrice || poolPrice.pools.length === 0 || price.type !== 'pool')
|
|
|
|
return
|
|
|
|
setPrice((prevState) => ({
|
|
|
|
...prevState,
|
2021-04-12 17:50:26 +02:00
|
|
|
value: poolPrice.pools[0].spotPrice,
|
|
|
|
ocean: poolPrice.pools[0].oceanReserve,
|
|
|
|
datatoken: poolPrice.pools[0].datatokenReserve
|
2021-03-26 09:48:27 +01:00
|
|
|
}))
|
2021-03-17 11:44:26 +01:00
|
|
|
}, [poolPrice])
|
2020-11-20 14:31:28 +01:00
|
|
|
|
2020-12-10 14:30:40 +01:00
|
|
|
const fetchDdo = async (token?: CancelToken) => {
|
2021-03-17 11:44:26 +01:00
|
|
|
Logger.log('[asset] Init asset, get DDO')
|
2020-12-10 14:30:40 +01:00
|
|
|
const ddo = await retrieveDDO(
|
|
|
|
asset as string,
|
|
|
|
config.metadataCacheUri,
|
|
|
|
token
|
|
|
|
)
|
|
|
|
|
|
|
|
if (!ddo) {
|
|
|
|
setError(
|
2021-03-17 11:44:26 +01:00
|
|
|
`[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.`
|
2020-12-10 14:30:40 +01:00
|
|
|
)
|
|
|
|
} else {
|
|
|
|
setError(undefined)
|
|
|
|
}
|
|
|
|
return ddo
|
|
|
|
}
|
|
|
|
|
|
|
|
const refreshDdo = async (token?: CancelToken) => {
|
|
|
|
const ddo = await fetchDdo(token)
|
2021-03-17 11:44:26 +01:00
|
|
|
Logger.debug('[asset] Got DDO', ddo)
|
2020-12-10 14:30:40 +01:00
|
|
|
setDDO(ddo)
|
|
|
|
}
|
2021-03-17 11:44:26 +01:00
|
|
|
|
2020-11-20 14:31:28 +01:00
|
|
|
//
|
|
|
|
// Get and set DDO based on passed DDO or DID
|
|
|
|
//
|
|
|
|
useEffect(() => {
|
2020-11-23 15:46:49 +01:00
|
|
|
if (!asset || !config?.metadataCacheUri) return
|
2020-11-20 14:31:28 +01:00
|
|
|
|
|
|
|
const source = axios.CancelToken.source()
|
|
|
|
let isMounted = true
|
|
|
|
|
2020-12-10 14:30:40 +01:00
|
|
|
async function init() {
|
|
|
|
const ddo = await fetchDdo(source.token)
|
2020-11-20 14:31:28 +01:00
|
|
|
if (!isMounted) return
|
2021-03-17 11:44:26 +01:00
|
|
|
Logger.debug('[asset] Got DDO', ddo)
|
2020-11-20 14:31:28 +01:00
|
|
|
setDDO(ddo)
|
|
|
|
setDID(asset as string)
|
|
|
|
}
|
|
|
|
init()
|
|
|
|
return () => {
|
|
|
|
isMounted = false
|
|
|
|
source.cancel()
|
|
|
|
}
|
2020-11-23 15:46:49 +01:00
|
|
|
}, [asset, config?.metadataCacheUri])
|
2020-11-20 14:31:28 +01:00
|
|
|
|
|
|
|
const setPurgatory = useCallback(async (did: string): Promise<void> => {
|
|
|
|
if (!did) return
|
2021-03-17 11:44:26 +01:00
|
|
|
|
2020-11-20 14:31:28 +01:00
|
|
|
try {
|
|
|
|
const result = await getAssetPurgatoryData(did)
|
2021-03-17 11:44:26 +01:00
|
|
|
const isInPurgatory = result?.did !== undefined
|
|
|
|
setIsInPurgatory(isInPurgatory)
|
|
|
|
isInPurgatory && setPurgatoryData(result)
|
2020-11-20 14:31:28 +01:00
|
|
|
} catch (error) {
|
|
|
|
Logger.error(error)
|
|
|
|
}
|
|
|
|
}, [])
|
|
|
|
|
2021-03-17 11:44:26 +01:00
|
|
|
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
|
|
|
if (!ddo) return
|
|
|
|
|
|
|
|
// Set price & metadata from DDO first
|
2021-04-15 13:47:32 +02:00
|
|
|
// TODO Hacky hack, temporary™: set isConsumable to true by default since Aquarius can't be trusted.
|
|
|
|
setPrice({ ...ddo.price, isConsumable: 'true' })
|
2021-03-17 11:44:26 +01:00
|
|
|
setVariables({ datatoken: ddo?.dataToken.toLowerCase() })
|
|
|
|
|
|
|
|
// Get metadata from DDO
|
|
|
|
const { attributes } = ddo.findServiceByType('metadata')
|
|
|
|
setMetadata((attributes as unknown) as MetadataMarket)
|
|
|
|
setTitle(attributes?.main.name)
|
2021-03-17 12:54:47 +01:00
|
|
|
setType(attributes.main.type)
|
2021-03-17 11:44:26 +01:00
|
|
|
setOwner(ddo.publicKey[0].owner)
|
|
|
|
Logger.log('[asset] Got Metadata from DDO', attributes)
|
|
|
|
|
|
|
|
setIsInPurgatory(ddo.isInPurgatory === 'true')
|
|
|
|
await setPurgatory(ddo.id)
|
|
|
|
}, [])
|
2020-11-20 14:31:28 +01:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (!ddo) return
|
|
|
|
initMetadata(ddo)
|
|
|
|
}, [ddo, initMetadata])
|
|
|
|
|
|
|
|
return (
|
|
|
|
<AssetContext.Provider
|
|
|
|
value={
|
|
|
|
{
|
|
|
|
ddo,
|
|
|
|
did,
|
|
|
|
metadata,
|
|
|
|
title,
|
|
|
|
owner,
|
|
|
|
price,
|
2021-02-19 15:25:49 +01:00
|
|
|
type,
|
2020-11-20 14:31:28 +01:00
|
|
|
error,
|
|
|
|
isInPurgatory,
|
|
|
|
purgatoryData,
|
|
|
|
refreshInterval,
|
2021-03-17 11:44:26 +01:00
|
|
|
refreshDdo
|
2020-11-20 14:31:28 +01:00
|
|
|
} 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
|