mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Merge pull request #540 from oceanprotocol/issue497-fetch-price-subgraph
Fetch asset price without relying on ddo's price
This commit is contained in:
commit
48cb9b1840
2
package-lock.json
generated
2
package-lock.json
generated
@ -18101,7 +18101,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ethereumjs-abi": {
|
"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",
|
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bn.js": "^4.11.8",
|
"bn.js": "^4.11.8",
|
||||||
|
@ -3,7 +3,6 @@ import {
|
|||||||
DDO,
|
DDO,
|
||||||
File as FileMetadata,
|
File as FileMetadata,
|
||||||
Logger,
|
Logger,
|
||||||
ServiceType,
|
|
||||||
publisherTrustedAlgorithm,
|
publisherTrustedAlgorithm,
|
||||||
BestPrice
|
BestPrice
|
||||||
} from '@oceanprotocol/lib'
|
} from '@oceanprotocol/lib'
|
||||||
@ -37,11 +36,8 @@ import FormStartComputeDataset from './FormComputeDataset'
|
|||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import SuccessConfetti from '../../../atoms/SuccessConfetti'
|
import SuccessConfetti from '../../../atoms/SuccessConfetti'
|
||||||
import Button from '../../../atoms/Button'
|
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 { secondsToString } from '../../../../utils/metadata'
|
||||||
import { getPreviousOrders } from '../../../../utils/subgraph'
|
import { getPreviousOrders, getPrice } from '../../../../utils/subgraph'
|
||||||
|
|
||||||
const SuccessAction = () => (
|
const SuccessAction = () => (
|
||||||
<Button style="text" to="/history" size="small">
|
<Button style="text" to="/history" size="small">
|
||||||
@ -49,23 +45,6 @@ const SuccessAction = () => (
|
|||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
|
|
||||||
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
|
|
||||||
consumePrice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export default function Compute({
|
export default function Compute({
|
||||||
isBalanceSufficient,
|
isBalanceSufficient,
|
||||||
dtBalance,
|
dtBalance,
|
||||||
@ -95,7 +74,6 @@ export default function Compute({
|
|||||||
)
|
)
|
||||||
const [algorithmDTBalance, setalgorithmDTBalance] = useState<string>()
|
const [algorithmDTBalance, setalgorithmDTBalance] = useState<string>()
|
||||||
const [algorithmPrice, setAlgorithmPrice] = useState<BestPrice>()
|
const [algorithmPrice, setAlgorithmPrice] = useState<BestPrice>()
|
||||||
const [variables, setVariables] = useState({})
|
|
||||||
const [
|
const [
|
||||||
previousAlgorithmOrderId,
|
previousAlgorithmOrderId,
|
||||||
setPreviousAlgorithmOrderId
|
setPreviousAlgorithmOrderId
|
||||||
@ -103,25 +81,6 @@ export default function Compute({
|
|||||||
const [datasetTimeout, setDatasetTimeout] = useState<string>()
|
const [datasetTimeout, setDatasetTimeout] = useState<string>()
|
||||||
const [algorithmTimeout, setAlgorithmTimeout] = useState<string>()
|
const [algorithmTimeout, setAlgorithmTimeout] = useState<string>()
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
|
|
||||||
const isComputeButtonDisabled =
|
const isComputeButtonDisabled =
|
||||||
isJobStarting === true || file === null || !ocean || !isBalanceSufficient
|
isJobStarting === true || file === null || !ocean || !isBalanceSufficient
|
||||||
const hasDatatoken = Number(dtBalance) >= 1
|
const hasDatatoken = Number(dtBalance) >= 1
|
||||||
@ -215,40 +174,10 @@ export default function Compute({
|
|||||||
setDatasetTimeout(secondsToString(timeout))
|
setDatasetTimeout(secondsToString(timeout))
|
||||||
}, [ddo])
|
}, [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].consumePrice === '-1'
|
|
||||||
? poolPrice.pools[0].spotPrice
|
|
||||||
: poolPrice.pools[0].consumePrice
|
|
||||||
}))
|
|
||||||
}, [poolPrice])
|
|
||||||
|
|
||||||
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
||||||
if (!ddo) return
|
if (!ddo) return
|
||||||
setAlgorithmPrice(ddo.price)
|
const price = await getPrice(ddo)
|
||||||
setVariables({ datatoken: ddo?.dataToken.toLowerCase() })
|
setAlgorithmPrice(price)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -12,11 +12,9 @@ import { PurgatoryData } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Purga
|
|||||||
import getAssetPurgatoryData from '../utils/purgatory'
|
import getAssetPurgatoryData from '../utils/purgatory'
|
||||||
import axios, { CancelToken } from 'axios'
|
import axios, { CancelToken } from 'axios'
|
||||||
import { retrieveDDO } from '../utils/aquarius'
|
import { retrieveDDO } from '../utils/aquarius'
|
||||||
|
import { getPrice } from '../utils/subgraph'
|
||||||
import { MetadataMarket } from '../@types/MetaData'
|
import { MetadataMarket } from '../@types/MetaData'
|
||||||
import { useOcean } from './Ocean'
|
import { useOcean } from './Ocean'
|
||||||
import { gql, useQuery } from '@apollo/client'
|
|
||||||
import { PoolPrice } from '../@types/apollo/PoolPrice'
|
|
||||||
import { FrePrice } from '../@types/apollo/FrePrice'
|
|
||||||
|
|
||||||
interface AssetProviderValue {
|
interface AssetProviderValue {
|
||||||
isInPurgatory: boolean
|
isInPurgatory: boolean
|
||||||
@ -33,26 +31,6 @@ interface AssetProviderValue {
|
|||||||
refreshDdo: (token?: CancelToken) => Promise<void>
|
refreshDdo: (token?: CancelToken) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
const poolQuery = gql`
|
|
||||||
query PoolPrice($datatoken: String) {
|
|
||||||
pools(where: { datatokenAddress: $datatoken }) {
|
|
||||||
spotPrice
|
|
||||||
consumePrice
|
|
||||||
datatokenReserve
|
|
||||||
oceanReserve
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const freQuery = gql`
|
|
||||||
query FrePrice($datatoken: String) {
|
|
||||||
fixedRateExchanges(orderBy: id, where: { datatoken: $datatoken }) {
|
|
||||||
rate
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const AssetContext = createContext({} as AssetProviderValue)
|
const AssetContext = createContext({} as AssetProviderValue)
|
||||||
|
|
||||||
const refreshInterval = 10000 // 10 sec.
|
const refreshInterval = 10000 // 10 sec.
|
||||||
@ -75,68 +53,6 @@ function AssetProvider({
|
|||||||
const [owner, setOwner] = useState<string>()
|
const [owner, setOwner] = useState<string>()
|
||||||
const [error, setError] = useState<string>()
|
const [error, setError] = useState<string>()
|
||||||
const [type, setType] = useState<MetadataMain['type']>()
|
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].consumePrice === '-1'
|
|
||||||
? poolPrice.pools[0].spotPrice
|
|
||||||
: poolPrice.pools[0].consumePrice,
|
|
||||||
ocean: poolPrice.pools[0].oceanReserve,
|
|
||||||
datatoken: poolPrice.pools[0].datatokenReserve,
|
|
||||||
isConsumable: poolPrice.pools[0].consumePrice === '-1' ? 'false' : 'true'
|
|
||||||
}))
|
|
||||||
}, [poolPrice])
|
|
||||||
|
|
||||||
const fetchDdo = async (token?: CancelToken) => {
|
const fetchDdo = async (token?: CancelToken) => {
|
||||||
Logger.log('[asset] Init asset, get DDO')
|
Logger.log('[asset] Init asset, get DDO')
|
||||||
@ -201,10 +117,8 @@ function AssetProvider({
|
|||||||
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
const initMetadata = useCallback(async (ddo: DDO): Promise<void> => {
|
||||||
if (!ddo) return
|
if (!ddo) return
|
||||||
|
|
||||||
// Set price & metadata from DDO first
|
const returnedPrice = await getPrice(ddo)
|
||||||
// TODO Hacky hack, temporary™: set isConsumable to true by default since Aquarius can't be trusted.
|
setPrice({ ...returnedPrice })
|
||||||
setPrice({ ...ddo.price, isConsumable: 'true' })
|
|
||||||
setVariables({ datatoken: ddo?.dataToken.toLowerCase() })
|
|
||||||
|
|
||||||
// Get metadata from DDO
|
// Get metadata from DDO
|
||||||
const { attributes } = ddo.findServiceByType('metadata')
|
const { attributes } = ddo.findServiceByType('metadata')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { gql, DocumentNode, ApolloQueryResult } from '@apollo/client'
|
import { gql, DocumentNode, ApolloQueryResult } from '@apollo/client'
|
||||||
import { DDO } from '@oceanprotocol/lib'
|
import { DDO, BestPrice } from '@oceanprotocol/lib'
|
||||||
import { getApolloClientInstance } from '../providers/ApolloClientProvider'
|
import { getApolloClientInstance } from '../providers/ApolloClientProvider'
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
|
|
||||||
@ -7,8 +7,8 @@ export interface PriceList {
|
|||||||
[key: string]: string
|
[key: string]: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const freQuery = gql`
|
const FreQuery = gql`
|
||||||
query AssetFrePrice($datatoken_in: [String!]) {
|
query AssetsFrePrice($datatoken_in: [String!]) {
|
||||||
fixedRateExchanges(orderBy: id, where: { datatoken_in: $datatoken_in }) {
|
fixedRateExchanges(orderBy: id, where: { datatoken_in: $datatoken_in }) {
|
||||||
rate
|
rate
|
||||||
id
|
id
|
||||||
@ -20,18 +20,40 @@ const freQuery = gql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const poolQuery = gql`
|
const AssetFreQuery = gql`
|
||||||
query AssetPoolPrice($datatokenAddress_in: [String!]) {
|
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 }) {
|
pools(where: { datatokenAddress_in: $datatokenAddress_in }) {
|
||||||
|
id
|
||||||
spotPrice
|
spotPrice
|
||||||
consumePrice
|
consumePrice
|
||||||
id
|
|
||||||
datatokenAddress
|
datatokenAddress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const previousOrderQuery = gql`
|
const AssetPoolPriceQuerry = gql`
|
||||||
|
query AssetPoolPrice($datatokenAddress: String) {
|
||||||
|
pools(where: { datatokenAddress: $datatokenAddress }) {
|
||||||
|
id
|
||||||
|
spotPrice
|
||||||
|
consumePrice
|
||||||
|
datatokenAddress
|
||||||
|
datatokenReserve
|
||||||
|
oceanReserve
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const PreviousOrderQuery = gql`
|
||||||
query AssetPreviousOrder($id: String!, $account: String!) {
|
query AssetPreviousOrder($id: String!, $account: String!) {
|
||||||
tokenOrders(
|
tokenOrders(
|
||||||
first: 1
|
first: 1
|
||||||
@ -53,7 +75,8 @@ async function fetchData(
|
|||||||
const client = getApolloClientInstance()
|
const client = getApolloClientInstance()
|
||||||
const response = await client.query({
|
const response = await client.query({
|
||||||
query: query,
|
query: query,
|
||||||
variables: variables
|
variables: variables,
|
||||||
|
fetchPolicy: 'no-cache'
|
||||||
})
|
})
|
||||||
return response
|
return response
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -71,7 +94,7 @@ export async function getPreviousOrders(
|
|||||||
account: account
|
account: account
|
||||||
}
|
}
|
||||||
const fetchedPreviousOrders: any = await fetchData(
|
const fetchedPreviousOrders: any = await fetchData(
|
||||||
previousOrderQuery,
|
PreviousOrderQuery,
|
||||||
variables
|
variables
|
||||||
)
|
)
|
||||||
if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null
|
if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null
|
||||||
@ -105,16 +128,76 @@ export async function getAssetPrices(assets: DDO[]): Promise<PriceList> {
|
|||||||
const poolVariables = {
|
const poolVariables = {
|
||||||
datatokenAddress_in: dataTokenList
|
datatokenAddress_in: dataTokenList
|
||||||
}
|
}
|
||||||
const poolPriceResponse: any = await fetchData(poolQuery, poolVariables)
|
const poolPriceResponse: any = await fetchData(PoolQuery, poolVariables)
|
||||||
for (const poolPrice of poolPriceResponse.data?.pools) {
|
for (const poolPrice of poolPriceResponse.data?.pools) {
|
||||||
priceList[didDTMap[poolPrice.datatokenAddress]] =
|
priceList[didDTMap[poolPrice.datatokenAddress]] =
|
||||||
poolPrice.consumePrice === '-1'
|
poolPrice.consumePrice === '-1'
|
||||||
? poolPrice.spotPrice
|
? poolPrice.spotPrice
|
||||||
: poolPrice.consumePrice
|
: poolPrice.consumePrice
|
||||||
}
|
}
|
||||||
const frePriceResponse: any = await fetchData(freQuery, freVariables)
|
const frePriceResponse: any = await fetchData(FreQuery, freVariables)
|
||||||
for (const frePrice of frePriceResponse.data?.fixedRateExchanges) {
|
for (const frePrice of frePriceResponse.data?.fixedRateExchanges) {
|
||||||
priceList[didDTMap[frePrice.datatoken?.address]] = frePrice.rate
|
priceList[didDTMap[frePrice.datatoken?.address]] = frePrice.rate
|
||||||
}
|
}
|
||||||
return priceList
|
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]?.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],
|
||||||
|
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,
|
||||||
|
address: frePriceResponse.data?.fixedRateExchanges[0]?.id,
|
||||||
|
exchange_id: frePriceResponse.data?.fixedRateExchanges[0]?.id,
|
||||||
|
ocean: 0,
|
||||||
|
datatoken: 0,
|
||||||
|
pools: [],
|
||||||
|
isConsumable: 'true'
|
||||||
|
}
|
||||||
|
return price
|
||||||
|
} else {
|
||||||
|
const price: BestPrice = {
|
||||||
|
type: '',
|
||||||
|
value: 0,
|
||||||
|
address: '',
|
||||||
|
exchange_id: '',
|
||||||
|
ocean: 0,
|
||||||
|
datatoken: 0,
|
||||||
|
pools: [],
|
||||||
|
isConsumable: 'false'
|
||||||
|
}
|
||||||
|
return price
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user