1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

Merge pull request #488 from oceanprotocol/feature/sugraph-util-methods

Subgraph helpers for assetSelection list and previous orders
This commit is contained in:
Bogdan Fazakas 2021-04-14 16:06:25 +03:00 committed by GitHub
commit f531fea4b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 165 additions and 35 deletions

2
package-lock.json generated
View File

@ -16704,7 +16704,7 @@
}
},
"ethereumjs-abi": {
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f",
"version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1a27c59c15ab1e95ee8e5c4ed6ad814c49cc439e",
"from": "git+https://github.com/ethereumjs/ethereumjs-abi.git",
"requires": {
"bn.js": "^4.11.8",

View File

@ -13,7 +13,6 @@ import File from '../../../atoms/File'
import Alert from '../../../atoms/Alert'
import Web3Feedback from '../../../molecules/Wallet/Feedback'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import checkPreviousOrder from '../../../../utils/checkPreviousOrder'
import { useOcean } from '../../../../providers/Ocean'
import { useWeb3 } from '../../../../providers/Web3'
import { usePricing } from '../../../../hooks/usePricing'
@ -27,6 +26,7 @@ import {
getInitialValues,
validationSchema
} from '../../../../models/FormStartComputeDataset'
import { ComputeAlgorithm } from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
import { AssetSelectionAsset } from '../../../molecules/FormFields/AssetSelection'
import { SearchQuery } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
import axios from 'axios'
@ -38,7 +38,7 @@ import { gql, useQuery } from '@apollo/client'
import { FrePrice } from '../../../../@types/apollo/FrePrice'
import { PoolPrice } from '../../../../@types/apollo/PoolPrice'
import { secondsToString } from '../../../../utils/metadata'
import { ComputeAlgorithm } from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
import { getPreviousOrders } from '../../../../utils/subgraph'
const SuccessAction = () => (
<Button style="text" to="/history" size="small">
@ -122,8 +122,15 @@ export default function Compute({
isJobStarting === true || file === null || !ocean || !isBalanceSufficient
const hasDatatoken = Number(dtBalance) >= 1
async function checkPreviousOrders(ddo: DDO, serviceType: ServiceType) {
const orderId = await checkPreviousOrder(ocean, accountId, ddo, serviceType)
async function checkPreviousOrders(ddo: DDO) {
const { timeout } = (
ddo.findServiceByType('access') || ddo.findServiceByType('compute')
).attributes.main
const orderId = await getPreviousOrders(
ddo.dataToken?.toLowerCase(),
accountId?.toLowerCase(),
timeout.toString()
)
const assetType = ddo.findServiceByType('metadata').attributes.main.type
if (assetType === 'algorithm') {
setPreviousAlgorithmOrderId(orderId)
@ -246,23 +253,23 @@ export default function Compute({
useEffect(() => {
if (!ocean || !accountId) return
checkPreviousOrders(ddo, 'compute')
checkPreviousOrders(ddo)
}, [ocean, ddo, accountId])
useEffect(() => {
if (!ocean || !accountId || !selectedAlgorithmAsset) return
if (selectedAlgorithmAsset.findServiceByType('access')) {
checkPreviousOrders(selectedAlgorithmAsset, 'access').then(() => {
checkPreviousOrders(selectedAlgorithmAsset).then(() => {
if (
!hasPreviousAlgorithmOrder &&
selectedAlgorithmAsset.findServiceByType('compute')
) {
checkPreviousOrders(selectedAlgorithmAsset, 'compute')
checkPreviousOrders(selectedAlgorithmAsset)
}
})
} else if (selectedAlgorithmAsset.findServiceByType('compute')) {
checkPreviousOrders(selectedAlgorithmAsset, 'compute')
checkPreviousOrders(selectedAlgorithmAsset)
}
checkAssetDTBalance(selectedAlgorithmAsset)
initMetadata(selectedAlgorithmAsset)

View File

@ -9,6 +9,7 @@ import { Logger, ConfigHelperConfig } from '@oceanprotocol/lib'
import { useOcean } from './Ocean'
import fetch from 'cross-fetch'
import React, { useState, useEffect, ReactNode, ReactElement } from 'react'
let apolloClient: ApolloClient<NormalizedCacheObject>
function createClient(subgraphUri: string) {
const client = new ApolloClient({
@ -22,6 +23,10 @@ function createClient(subgraphUri: string) {
return client
}
export function getApolloClientInstance(): ApolloClient<NormalizedCacheObject> {
return apolloClient
}
export default function ApolloClientProvider({
children
}: {
@ -39,6 +44,7 @@ export default function ApolloClientProvider({
}
const newClient = createClient((config as ConfigHelperConfig).subgraphUri)
apolloClient = newClient
setClient(newClient)
}, [config])

View File

@ -10,8 +10,8 @@ import {
SearchQuery
} from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
import { AssetSelectionAsset } from '../components/molecules/FormFields/AssetSelection'
import { PriceList, getAssetPrices } from './subgraph'
import axios, { CancelToken, AxiosResponse } from 'axios'
import web3 from 'web3'
// TODO: import directly from ocean.js somehow.
// Transforming Aquarius' direct response is needed for getting actual DDOs
@ -113,37 +113,38 @@ export async function transformDDOToAssetSelection(
): Promise<AssetSelectionAsset[]> {
const source = axios.CancelToken.source()
const didList: string[] = []
const priceList: any = {}
const priceList: PriceList = await getAssetPrices(ddoList)
const symbolList: any = {}
ddoList.forEach((ddo: DDO) => {
for (const ddo of ddoList) {
didList.push(ddo.id)
priceList[ddo.id] = ddo.price.value
symbolList[ddo.id] = ddo.dataTokenInfo.symbol
})
}
const ddoNames = await getAssetsNames(didList, metadataCacheUri, source.token)
const algorithmList: AssetSelectionAsset[] = []
didList?.forEach((did: string) => {
let selected = false
selectedAlgorithms?.forEach((algorithm: PublisherTrustedAlgorithm) => {
if (algorithm.did === did) {
selected = true
}
})
selected
? algorithmList.unshift({
did: did,
name: ddoNames[did],
price: priceList[did],
checked: selected,
symbol: symbolList[did]
})
: algorithmList.push({
did: did,
name: ddoNames[did],
price: priceList[did],
checked: selected,
symbol: symbolList[did]
})
if (priceList[did]) {
let selected = false
selectedAlgorithms?.forEach((algorithm: PublisherTrustedAlgorithm) => {
if (algorithm.did === did) {
selected = true
}
})
selected
? algorithmList.unshift({
did: did,
name: ddoNames[did],
price: priceList[did],
checked: selected,
symbol: symbolList[did]
})
: algorithmList.push({
did: did,
name: ddoNames[did],
price: priceList[did],
checked: selected,
symbol: symbolList[did]
})
}
})
return algorithmList
}

116
src/utils/subgraph.ts Normal file
View File

@ -0,0 +1,116 @@
import { gql, DocumentNode, ApolloQueryResult } from '@apollo/client'
import { DDO } from '@oceanprotocol/lib'
import { getApolloClientInstance } from '../providers/ApolloClientProvider'
import BigNumber from 'bignumber.js'
export interface PriceList {
[key: string]: string
}
const freQuery = gql`
query AssetFrePrice($datatoken_in: [String!]) {
fixedRateExchanges(orderBy: id, where: { datatoken_in: $datatoken_in }) {
rate
id
datatoken {
id
address
}
}
}
`
const poolQuery = gql`
query AssetPoolPrice($datatokenAddress_in: [String!]) {
pools(where: { datatokenAddress_in: $datatokenAddress_in }) {
spotPrice
id
datatokenAddress
}
}
`
const previousOrderQuery = gql`
query AssetPreviousOrder($id: String!, $account: String!) {
tokenOrders(
first: 1
where: { datatokenId: $id, payer: $account }
orderBy: timestamp
orderDirection: desc
) {
timestamp
tx
}
}
`
async function fetchData(
query: DocumentNode,
variables: any
): Promise<ApolloQueryResult<any>> {
try {
const client = getApolloClientInstance()
const response = await client.query({
query: query,
variables: variables
})
return response
} catch (error) {
console.error('Error fetchData: ', error.message)
}
}
export async function getPreviousOrders(
id: string,
account: string,
assetTimeout: string
): Promise<string> {
const variables = {
id: id,
account: account
}
const fetchedPreviousOrders: any = await fetchData(
previousOrderQuery,
variables
)
if (fetchedPreviousOrders.data?.tokenOrders?.length === 0) return null
if (assetTimeout === '0') {
return fetchedPreviousOrders?.data?.tokenOrders[0]?.tx
} else {
const expiry = new BigNumber(
fetchedPreviousOrders?.data?.tokenOrders[0]?.timestamp
).plus(assetTimeout)
const unixTime = new BigNumber(Math.floor(Date.now() / 1000))
if (unixTime.isLessThan(expiry)) {
return fetchedPreviousOrders?.data?.tokenOrders[0]?.tx
} else {
return null
}
}
}
export async function getAssetPrices(assets: DDO[]): Promise<PriceList> {
const priceList: PriceList = {}
const didDTMap: any = {}
const dataTokenList: string[] = []
for (const ddo of assets) {
didDTMap[ddo?.dataToken.toLowerCase()] = ddo.id
dataTokenList.push(ddo?.dataToken.toLowerCase())
}
const freVariables = {
datatoken_in: dataTokenList
}
const poolVariables = {
datatokenAddress_in: dataTokenList
}
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)
for (const frePrice of frePriceResponse.data?.fixedRateExchanges) {
priceList[didDTMap[frePrice.datatoken?.address]] = frePrice.rate
}
return priceList
}