1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00
market/src/@hooks/useGraphSyncStatus.ts
mihaisc 57be62a6b1
Refactor pricing and various components that are involved (#1046)
* update

* merge pr #1012

* fix header

* fix

* abort controller

* up next.8

* build fix

* update lock

* fix

* another fix

* ssh fix

* another ssh fix

* remove optional

* order mock

* small cleanup

* fix package

* price updates

* finish getPrice

* fix consume

* fix consume

* getConsumeDetails  comments

* restore functionality after consumeDetails

* fix some compute typings

* more price fetching updates

* 'minor' refactors and fixed build

* package-lock fix

* minor comments

* minor naming changes

* fix

* fix pool badge

* remove console.log
2022-02-03 03:29:39 -08:00

117 lines
3.8 KiB
TypeScript

import { useState, useEffect } from 'react'
import { useWeb3 } from '@context/Web3'
import { Config, LoggerInstance } from '@oceanprotocol/lib'
import Web3 from 'web3'
import axios, { AxiosResponse } from 'axios'
import { getOceanConfig } from '@utils/ocean'
const blockDifferenceThreshold = 30
const ethGraphUrl = `https://api.thegraph.com/subgraphs/name/blocklytics/ethereum-blocks`
const ethGraphQueryBody =
'{"query":" query Blocks{ blocks(first: 1, skip: 0, orderBy: number, orderDirection: desc, where: {number_gt: 9300000}) { id number timestamp author difficulty gasUsed gasLimit } }","variables":{},"operationName":"Blocks"}'
const graphQueryBody =
'{"query": "query Meta { _meta { block { hash number } deployment hasIndexingErrors } }", "variables": {},"operationName":"Meta"}'
export interface UseGraphSyncStatus {
isGraphSynced: boolean
blockHead: number
blockGraph: number
}
async function fetchGraph(
url: string,
queryBody: string
): Promise<AxiosResponse> {
try {
const response = await axios.post(url, { ...JSON.parse(queryBody) })
return response
} catch (error) {
LoggerInstance.error('Error parsing json: ' + error.message)
}
}
async function getBlockHead(config: Config) {
if (!config) return
// for ETH main, get block from graph fetch
if (config.network === 'mainnet') {
const response: any = await fetchGraph(ethGraphUrl, ethGraphQueryBody)
return Number(response?.data?.blocks[0]?.number)
}
// for everything else, create new web3 instance with infura
// TODO: this fails randomly , WHY!?!?!?!?!
const web3Instance = new Web3(config.nodeUri)
const blockHead = await web3Instance.eth.getBlockNumber()
return blockHead
}
async function getBlockSubgraph(subgraphUri: string) {
const response: any = await fetchGraph(
`${subgraphUri}/subgraphs/name/oceanprotocol/ocean-subgraph`,
graphQueryBody
)
const blockNumberGraph = Number(response?.data?.data?._meta?.block?.number)
return blockNumberGraph
}
export function useGraphSyncStatus(networkId: number): UseGraphSyncStatus {
const { block, web3Loading } = useWeb3()
const [blockGraph, setBlockGraph] = useState<number>()
const [blockHead, setBlockHead] = useState<number>()
const [isGraphSynced, setIsGraphSynced] = useState(true)
const [subgraphLoading, setSubgraphLoading] = useState(false)
const [oceanConfig, setOceanConfig] = useState<Config>()
// Grab ocean config based on passed networkId
useEffect(() => {
if (!networkId) return
const oceanConfig = getOceanConfig(networkId)
setOceanConfig(oceanConfig)
}, [networkId])
// Get and set head block
useEffect(() => {
if (!oceanConfig?.nodeUri || web3Loading) return
async function initBlockHead() {
const blockHead = block || (await getBlockHead(oceanConfig))
setBlockHead(blockHead)
LoggerInstance.log('[GraphStatus] Head block: ', blockHead)
}
initBlockHead()
}, [web3Loading, block, oceanConfig])
// Get and set subgraph block
useEffect(() => {
if (!oceanConfig?.subgraphUri) return
async function initBlockSubgraph() {
setSubgraphLoading(true)
const blockGraph = await getBlockSubgraph(oceanConfig.subgraphUri)
setBlockGraph(blockGraph)
setSubgraphLoading(false)
LoggerInstance.log(
'[GraphStatus] Latest block from subgraph: ',
blockGraph
)
}
initBlockSubgraph()
}, [oceanConfig])
// Set sync status
useEffect(() => {
if ((!blockGraph && !blockHead) || web3Loading || subgraphLoading) return
const difference = blockHead - blockGraph
if (difference > blockDifferenceThreshold) {
setIsGraphSynced(false)
return
}
setIsGraphSynced(true)
}, [blockGraph, blockHead, web3Loading, subgraphLoading])
return { blockHead, blockGraph, isGraphSynced }
}