1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-11-15 01:34:57 +01:00

fetch asset price withoud relying on ddo.price

This commit is contained in:
Bogdan Fazakas 2021-04-20 09:44:18 +03:00
parent 1639a3e6ce
commit 7b653c46ba
2 changed files with 76 additions and 91 deletions

View File

@ -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<void>
}
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<string>()
const [error, setError] = useState<string>()
const [type, setType] = useState<MetadataMain['type']>()
const [variables, setVariables] = useState({})
/* eslint-disable @typescript-eslint/no-unused-vars */
const {
refetch: refetchFre,
startPolling: startPollingFre,
data: frePrice
} = useQuery<FrePrice>(freQuery, {
variables,
skip: false
})
const {
refetch: refetchPool,
startPolling: startPollingPool,
data: poolPrice
} = useQuery<PoolPrice>(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')

View File

@ -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<PriceList> {
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<BestPrice> {
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
}
}