From 7b653c46bacb1766d59dee523bd87e15a5e3687f Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 20 Apr 2021 09:44:18 +0300 Subject: [PATCH 1/6] fetch asset price withoud relying on ddo.price --- src/providers/Asset.tsx | 88 +++-------------------------------------- src/utils/subgraph.ts | 79 +++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 91 deletions(-) diff --git a/src/providers/Asset.tsx b/src/providers/Asset.tsx index 0f336cc6a..d6e947e57 100644 --- a/src/providers/Asset.tsx +++ b/src/providers/Asset.tsx @@ -12,11 +12,9 @@ import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Purga import getAssetPurgatoryData from '../utils/purgatory' import axios, { CancelToken } from 'axios' import { retrieveDDO } from '../utils/aquarius' +import { getPrice } from '../utils/subgraph' import { MetadataMarket } from '../@types/MetaData' import { useOcean } from './Ocean' -import { gql, useQuery } from '@apollo/client' -import { PoolPrice } from '../@types/apollo/PoolPrice' -import { FrePrice } from '../@types/apollo/FrePrice' interface AssetProviderValue { isInPurgatory: boolean @@ -33,25 +31,6 @@ interface AssetProviderValue { refreshDdo: (token?: CancelToken) => Promise } -const poolQuery = gql` - query PoolPrice($datatoken: String) { - pools(where: { datatokenAddress: $datatoken }) { - spotPrice - datatokenReserve - oceanReserve - } - } -` - -const freQuery = gql` - query FrePrice($datatoken: String) { - fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) { - rate - id - } - } -` - const AssetContext = createContext({} as AssetProviderValue) const refreshInterval = 10000 // 10 sec. @@ -74,64 +53,6 @@ function AssetProvider({ const [owner, setOwner] = useState() const [error, setError] = useState() const [type, setType] = useState() - const [variables, setVariables] = useState({}) - - /* eslint-disable @typescript-eslint/no-unused-vars */ - const { - refetch: refetchFre, - startPolling: startPollingFre, - data: frePrice - } = useQuery(freQuery, { - variables, - skip: false - }) - const { - refetch: refetchPool, - startPolling: startPollingPool, - data: poolPrice - } = useQuery(poolQuery, { - variables, - skip: false - }) - /* eslint-enable @typescript-eslint/no-unused-vars */ - - // 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]) - - useEffect(() => { - if ( - !frePrice || - frePrice.fixedRateExchanges.length === 0 || - price.type !== 'exchange' - ) - return - setPrice((prevState) => ({ - ...prevState, - value: frePrice.fixedRateExchanges[0].rate, - address: frePrice.fixedRateExchanges[0].id - })) - }, [frePrice]) - - useEffect(() => { - if (!poolPrice || poolPrice.pools.length === 0 || price.type !== 'pool') - return - setPrice((prevState) => ({ - ...prevState, - value: poolPrice.pools[0].spotPrice, - ocean: poolPrice.pools[0].oceanReserve, - datatoken: poolPrice.pools[0].datatokenReserve - })) - }, [poolPrice]) const fetchDdo = async (token?: CancelToken) => { Logger.log('[asset] Init asset, get DDO') @@ -198,8 +119,11 @@ function AssetProvider({ // Set price & metadata from DDO first // TODO Hacky hack, temporary™: set isConsumable to true by default since Aquarius can't be trusted. - setPrice({ ...ddo.price, isConsumable: 'true' }) - setVariables({ datatoken: ddo?.dataToken.toLowerCase() }) + // setPrice({ ...ddo.price, isConsumable: 'true' }) + + const returnedPrice = await getPrice(ddo) + console.log('returnedPrice', returnedPrice) + setPrice({ ...returnedPrice, isConsumable: 'true' }) // Get metadata from DDO const { attributes } = ddo.findServiceByType('metadata') diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 3ae3304cf..f07cfefb0 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -1,5 +1,5 @@ import { gql, DocumentNode, ApolloQueryResult } from '@apollo/client' -import { DDO } from '@oceanprotocol/lib' +import { DDO, BestPrice } from '@oceanprotocol/lib' import { getApolloClientInstance } from '../providers/ApolloClientProvider' import BigNumber from 'bignumber.js' @@ -7,8 +7,8 @@ export interface PriceList { [key: string]: string } -const freQuery = gql` - query AssetFrePrice($datatoken_in: [String!]) { +const FreQuery = gql` + query AssetsFrePrice($datatoken_in: [String!]) { fixedRateExchanges(orderBy: id, where: { datatoken_in: $datatoken_in }) { rate id @@ -20,8 +20,17 @@ const freQuery = gql` } ` -const poolQuery = gql` - query AssetPoolPrice($datatokenAddress_in: [String!]) { +const AssetFreQuery = gql` + query AssetFrePrice($datatoken: String) { + fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) { + rate + id + } + } +` + +const PoolQuery = gql` + query AssetsPoolPrice($datatokenAddress_in: [String!]) { pools(where: { datatokenAddress_in: $datatokenAddress_in }) { spotPrice id @@ -30,7 +39,19 @@ const poolQuery = gql` } ` -const previousOrderQuery = gql` +const AssetPoolPriceQuerry = gql` + query AssetPoolPrice($datatokenAddress: String) { + pools(where: { datatokenAddress: $datatokenAddress }) { + id + spotPrice + datatokenReserve + oceanReserve + datatokenAddress + } + } +` + +const PreviousOrderQuery = gql` query AssetPreviousOrder($id: String!, $account: String!) { tokenOrders( first: 1 @@ -70,7 +91,7 @@ export async function getPreviousOrders( account: account } const fetchedPreviousOrders: any = await fetchData( - previousOrderQuery, + PreviousOrderQuery, variables ) if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null @@ -104,13 +125,53 @@ export async function getAssetPrices(assets: DDO[]): Promise { const poolVariables = { datatokenAddress_in: dataTokenList } - const poolPriceResponse: any = await fetchData(poolQuery, poolVariables) + const poolPriceResponse: any = await fetchData(PoolQuery, poolVariables) for (const poolPrice of poolPriceResponse.data?.pools) { priceList[didDTMap[poolPrice.datatokenAddress]] = poolPrice.spotPrice } - const frePriceResponse: any = await fetchData(freQuery, freVariables) + const frePriceResponse: any = await fetchData(FreQuery, freVariables) for (const frePrice of frePriceResponse.data?.fixedRateExchanges) { priceList[didDTMap[frePrice.datatoken?.address]] = frePrice.rate } return priceList } + +export async function getPrice(asset: DDO): Promise { + const freVariables = { + datatoken: asset?.dataToken.toLowerCase() + } + + const poolVariables = { + datatokenAddress: asset?.dataToken.toLowerCase() + } + + const poolPriceResponse: any = await fetchData( + AssetPoolPriceQuerry, + poolVariables + ) + const frePriceResponse: any = await fetchData(AssetFreQuery, freVariables) + if (poolPriceResponse.data?.pools.length > 0) { + const price: BestPrice = { + type: 'pool', + address: poolPriceResponse.data?.pools[0]?.id, + value: poolPriceResponse.data?.pools[0]?.spotPrice, + ocean: poolPriceResponse.data?.pools[0]?.oceanReserve, + datatoken: poolPriceResponse.data?.pools[0]?.datatokenReserve, + pools: [poolPriceResponse.data?.pools[0]?.id] + } + return price + } else if (frePriceResponse.data?.fixedRateExchanges.length > 0) { + const price: BestPrice = { + type: 'exchange', + value: frePriceResponse.data?.fixedRateExchanges[0]?.rate, + address: frePriceResponse.data?.fixedRateExchanges[0]?.id, + exchange_id: frePriceResponse.data?.fixedRateExchanges[0]?.id, + ocean: 0, + datatoken: 0, + pools: [] + } + return price + } else { + return null + } +} From 4aae5fe6c184e484ba03d44d4163be6140a43fc2 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Wed, 21 Apr 2021 13:00:30 +0300 Subject: [PATCH 2/6] removed price querry from compute --- .../organisms/AssetActions/Compute/index.tsx | 73 +------------------ 1 file changed, 3 insertions(+), 70 deletions(-) diff --git a/src/components/organisms/AssetActions/Compute/index.tsx b/src/components/organisms/AssetActions/Compute/index.tsx index 3286acb75..c716ab58b 100644 --- a/src/components/organisms/AssetActions/Compute/index.tsx +++ b/src/components/organisms/AssetActions/Compute/index.tsx @@ -3,7 +3,6 @@ import { DDO, File as FileMetadata, Logger, - ServiceType, publisherTrustedAlgorithm, BestPrice } from '@oceanprotocol/lib' @@ -34,11 +33,8 @@ import FormStartComputeDataset from './FormComputeDataset' import styles from './index.module.css' import SuccessConfetti from '../../../atoms/SuccessConfetti' import Button from '../../../atoms/Button' -import { gql, useQuery } from '@apollo/client' -import { FrePrice } from '../../../../@types/apollo/FrePrice' -import { PoolPrice } from '../../../../@types/apollo/PoolPrice' import { secondsToString } from '../../../../utils/metadata' -import { getPreviousOrders } from '../../../../utils/subgraph' +import { getPreviousOrders, getPrice } from '../../../../utils/subgraph' const SuccessAction = () => ( ) -const freQuery = gql` - query AlgorithmFrePrice($datatoken: String) { - fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) { - rate - id - } - } -` -const poolQuery = gql` - query AlgorithmPoolPrice($datatoken: String) { - pools(where: { datatokenAddress: $datatoken }) { - spotPrice - } - } -` - export default function Compute({ isBalanceSufficient, dtBalance, @@ -91,7 +71,6 @@ export default function Compute({ ) const [algorithmDTBalance, setalgorithmDTBalance] = useState() const [algorithmPrice, setAlgorithmPrice] = useState() - const [variables, setVariables] = useState({}) const [ previousAlgorithmOrderId, setPreviousAlgorithmOrderId @@ -99,25 +78,6 @@ export default function Compute({ const [datasetTimeout, setDatasetTimeout] = useState() const [algorithmTimeout, setAlgorithmTimeout] = useState() - /* eslint-disable @typescript-eslint/no-unused-vars */ - const { - refetch: refetchFre, - startPolling: startPollingFre, - data: frePrice - } = useQuery(freQuery, { - variables, - skip: false - }) - const { - refetch: refetchPool, - startPolling: startPollingPool, - data: poolPrice - } = useQuery(poolQuery, { - variables, - skip: false - }) - /* eslint-enable @typescript-eslint/no-unused-vars */ - const isComputeButtonDisabled = isJobStarting === true || file === null || !ocean || !isBalanceSufficient const hasDatatoken = Number(dtBalance) >= 1 @@ -211,37 +171,10 @@ export default function Compute({ setDatasetTimeout(secondsToString(timeout)) }, [ddo]) - useEffect(() => { - if ( - !frePrice || - frePrice.fixedRateExchanges.length === 0 || - algorithmPrice.type !== 'exchange' - ) - return - setAlgorithmPrice((prevState) => ({ - ...prevState, - value: frePrice.fixedRateExchanges[0].rate, - address: frePrice.fixedRateExchanges[0].id - })) - }, [frePrice]) - - useEffect(() => { - if ( - !poolPrice || - poolPrice.pools.length === 0 || - algorithmPrice.type !== 'pool' - ) - return - setAlgorithmPrice((prevState) => ({ - ...prevState, - value: poolPrice.pools[0].spotPrice - })) - }, [poolPrice]) - const initMetadata = useCallback(async (ddo: DDO): Promise => { if (!ddo) return - setAlgorithmPrice(ddo.price) - setVariables({ datatoken: ddo?.dataToken.toLowerCase() }) + const price = await getPrice(ddo) + setAlgorithmPrice(price) }, []) useEffect(() => { From 0cef2cccd59c5ebe023a8fd301dc072fe24695b9 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Thu, 22 Apr 2021 14:03:58 +0300 Subject: [PATCH 3/6] update price value for pool assets using consumePrice and added isConsumable logic --- package-lock.json | 2 +- src/providers/Asset.tsx | 7 +------ src/utils/subgraph.ts | 27 +++++++++++++++++++++------ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 81941ee59..cc1026ce2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18101,7 +18101,7 @@ } }, "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1a27c59c15ab1e95ee8e5c4ed6ad814c49cc439e", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.11.8", diff --git a/src/providers/Asset.tsx b/src/providers/Asset.tsx index d6e947e57..548128f38 100644 --- a/src/providers/Asset.tsx +++ b/src/providers/Asset.tsx @@ -117,13 +117,8 @@ function AssetProvider({ const initMetadata = useCallback(async (ddo: DDO): Promise => { if (!ddo) return - // Set price & metadata from DDO first - // TODO Hacky hack, temporary™: set isConsumable to true by default since Aquarius can't be trusted. - // setPrice({ ...ddo.price, isConsumable: 'true' }) - const returnedPrice = await getPrice(ddo) - console.log('returnedPrice', returnedPrice) - setPrice({ ...returnedPrice, isConsumable: 'true' }) + setPrice({ ...returnedPrice }) // Get metadata from DDO const { attributes } = ddo.findServiceByType('metadata') diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index f07cfefb0..69c995eec 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -32,8 +32,9 @@ const AssetFreQuery = gql` const PoolQuery = gql` query AssetsPoolPrice($datatokenAddress_in: [String!]) { pools(where: { datatokenAddress_in: $datatokenAddress_in }) { - spotPrice id + spotPrice + consumePrice datatokenAddress } } @@ -44,9 +45,10 @@ const AssetPoolPriceQuerry = gql` pools(where: { datatokenAddress: $datatokenAddress }) { id spotPrice + consumePrice + datatokenAddress datatokenReserve oceanReserve - datatokenAddress } } ` @@ -127,7 +129,10 @@ export async function getAssetPrices(assets: DDO[]): Promise { } const poolPriceResponse: any = await fetchData(PoolQuery, poolVariables) for (const poolPrice of poolPriceResponse.data?.pools) { - priceList[didDTMap[poolPrice.datatokenAddress]] = poolPrice.spotPrice + priceList[didDTMap[poolPrice.datatokenAddress]] = + poolPrice.consumePrice === '-1' + ? poolPrice.spotPrice + : poolPrice.consumePrice } const frePriceResponse: any = await fetchData(FreQuery, freVariables) for (const frePrice of frePriceResponse.data?.fixedRateExchanges) { @@ -154,13 +159,22 @@ export async function getPrice(asset: DDO): Promise { const price: BestPrice = { type: 'pool', address: poolPriceResponse.data?.pools[0]?.id, - value: poolPriceResponse.data?.pools[0]?.spotPrice, + value: + poolPriceResponse.data?.pools[0]?.consumePrice === '-1' + ? poolPriceResponse.data?.pools[0]?.spotPrice + : poolPriceResponse.data?.pools[0]?.consumePrice, ocean: poolPriceResponse.data?.pools[0]?.oceanReserve, datatoken: poolPriceResponse.data?.pools[0]?.datatokenReserve, - pools: [poolPriceResponse.data?.pools[0]?.id] + pools: [poolPriceResponse.data?.pools[0]?.id], + isConsumable: + poolPriceResponse.data?.pools[0]?.consumePrice === '-1' + ? 'false' + : 'true' } return price } else if (frePriceResponse.data?.fixedRateExchanges.length > 0) { + // TODO Hacky hack, temporary™: set isConsumable to true for fre assets. + // isConsumable: 'true' const price: BestPrice = { type: 'exchange', value: frePriceResponse.data?.fixedRateExchanges[0]?.rate, @@ -168,7 +182,8 @@ export async function getPrice(asset: DDO): Promise { exchange_id: frePriceResponse.data?.fixedRateExchanges[0]?.id, ocean: 0, datatoken: 0, - pools: [] + pools: [], + isConsumable: 'true' } return price } else { From 1d02f53a06791b2d8442a9b277f3251d36e88715 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Fri, 23 Apr 2021 12:07:59 +0300 Subject: [PATCH 4/6] fixed no price set usecase --- src/utils/subgraph.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 69c995eec..2c8998930 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -187,6 +187,16 @@ export async function getPrice(asset: DDO): Promise { } return price } else { - return null + const price: BestPrice = { + type: '', + value: 0, + address: '', + exchange_id: '', + ocean: 0, + datatoken: 0, + pools: [], + isConsumable: 'false' + } + return price } } From 5adf03c5f16849f383436c37e6721f3093fd283e Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 11 May 2021 16:09:16 +0300 Subject: [PATCH 5/6] added fetchPolicy no-cache on graph requests from subgraph.ts util --- src/utils/subgraph.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 2c8998930..2cf0df0c2 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -75,7 +75,8 @@ async function fetchData( const client = getApolloClientInstance() const response = await client.query({ query: query, - variables: variables + variables: variables, + fetchPolicy: 'no-cache' }) return response } catch (error) { @@ -142,6 +143,7 @@ export async function getAssetPrices(assets: DDO[]): Promise { } export async function getPrice(asset: DDO): Promise { + console.log('get price', asset) const freVariables = { datatoken: asset?.dataToken.toLowerCase() } From 3dba118546643c9889f698946f7074026b3158f4 Mon Sep 17 00:00:00 2001 From: Bogdan Fazakas Date: Tue, 11 May 2021 16:15:35 +0300 Subject: [PATCH 6/6] remove unnecessary console log --- src/utils/subgraph.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/utils/subgraph.ts b/src/utils/subgraph.ts index 2cf0df0c2..9f5ede40c 100644 --- a/src/utils/subgraph.ts +++ b/src/utils/subgraph.ts @@ -143,7 +143,6 @@ export async function getAssetPrices(assets: DDO[]): Promise { } export async function getPrice(asset: DDO): Promise { - console.log('get price', asset) const freVariables = { datatoken: asset?.dataToken.toLowerCase() }