mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
272 lines
6.8 KiB
TypeScript
272 lines
6.8 KiB
TypeScript
import React, { ReactElement, useCallback, useEffect, useState } from 'react'
|
|
import Time from '@shared/atoms/Time'
|
|
import Table from '@shared/atoms/Table'
|
|
import AssetTitle from '@shared/AssetList/AssetListTitle'
|
|
import { useUserPreferences } from '@context/UserPreferences'
|
|
import { gql } from 'urql'
|
|
import { TransactionHistory_poolTransactions as TransactionHistoryPoolTransactions } from '../../../@types/apollo/TransactionHistory'
|
|
import web3 from 'web3'
|
|
import { fetchDataForMultipleChains } from '@utils/subgraph'
|
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
|
import NetworkName from '@shared/NetworkName'
|
|
import { retrieveDDOListByDIDs } from '@utils/aquarius'
|
|
import { CancelToken } from 'axios'
|
|
import Title from './Title'
|
|
import styles from './index.module.css'
|
|
import { LoggerInstance } from '@oceanprotocol/lib'
|
|
import { useCancelToken } from '@hooks/useCancelToken'
|
|
|
|
const REFETCH_INTERVAL = 20000
|
|
|
|
const txHistoryQueryByPool = gql`
|
|
query TransactionHistoryByPool($user: String, $pool: String) {
|
|
poolTransactions(
|
|
orderBy: timestamp
|
|
orderDirection: desc
|
|
where: { userAddress: $user, poolAddress: $pool }
|
|
first: 1000
|
|
) {
|
|
tokens {
|
|
poolToken {
|
|
id
|
|
symbol
|
|
}
|
|
value
|
|
type
|
|
tokenAddress
|
|
}
|
|
tx
|
|
event
|
|
timestamp
|
|
poolAddress {
|
|
datatokenAddress
|
|
}
|
|
}
|
|
}
|
|
`
|
|
const txHistoryQuery = gql`
|
|
query TransactionHistory($user: String) {
|
|
poolTransactions(
|
|
orderBy: timestamp
|
|
orderDirection: desc
|
|
where: { userAddress: $user }
|
|
first: 1000
|
|
) {
|
|
tokens {
|
|
poolToken {
|
|
id
|
|
symbol
|
|
}
|
|
value
|
|
type
|
|
tokenAddress
|
|
}
|
|
tx
|
|
event
|
|
timestamp
|
|
poolAddress {
|
|
datatokenAddress
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
export interface Datatoken {
|
|
symbol: string
|
|
}
|
|
|
|
export interface PoolTransaction extends TransactionHistoryPoolTransactions {
|
|
networkId: number
|
|
ddo: Asset
|
|
}
|
|
|
|
const columns = [
|
|
{
|
|
name: 'Title',
|
|
selector: function getTitleRow(row: PoolTransaction) {
|
|
return <Title row={row} />
|
|
}
|
|
},
|
|
{
|
|
name: 'Data Set',
|
|
selector: function getAssetRow(row: PoolTransaction) {
|
|
return <AssetTitle ddo={row.ddo} />
|
|
}
|
|
},
|
|
{
|
|
name: 'Network',
|
|
selector: function getNetwork(row: PoolTransaction) {
|
|
return <NetworkName networkId={row.networkId} />
|
|
},
|
|
maxWidth: '12rem'
|
|
},
|
|
{
|
|
name: 'Time',
|
|
selector: function getTimeRow(row: PoolTransaction) {
|
|
return (
|
|
<Time
|
|
className={styles.time}
|
|
date={row.timestamp.toString()}
|
|
relative
|
|
isUnix
|
|
/>
|
|
)
|
|
},
|
|
maxWidth: '10rem'
|
|
}
|
|
]
|
|
|
|
// hack! if we use a function to omit one field this will display a strange refresh to the enduser for each row
|
|
const columnsMinimal = [columns[0], columns[3]]
|
|
|
|
export default function PoolTransactions({
|
|
poolAddress,
|
|
poolChainId,
|
|
minimal,
|
|
accountId
|
|
}: {
|
|
poolAddress?: string
|
|
poolChainId?: number[]
|
|
minimal?: boolean
|
|
accountId: string
|
|
}): ReactElement {
|
|
const [transactions, setTransactions] = useState<PoolTransaction[]>()
|
|
const [isLoading, setIsLoading] = useState<boolean>(false)
|
|
const { chainIds } = useUserPreferences()
|
|
const { appConfig } = useSiteMetadata()
|
|
const [dataFetchInterval, setDataFetchInterval] = useState<NodeJS.Timeout>()
|
|
const [data, setData] = useState<PoolTransaction[]>()
|
|
const cancelToken = useCancelToken()
|
|
|
|
const getPoolTransactionData = useCallback(async () => {
|
|
const variables = {
|
|
user: accountId?.toLowerCase(),
|
|
pool: poolAddress?.toLowerCase()
|
|
}
|
|
const transactions: PoolTransaction[] = []
|
|
const result = await fetchDataForMultipleChains(
|
|
poolAddress ? txHistoryQueryByPool : txHistoryQuery,
|
|
variables,
|
|
poolAddress ? poolChainId : chainIds
|
|
)
|
|
|
|
for (let i = 0; i < result.length; i++) {
|
|
result[i].poolTransactions.forEach((poolTransaction: PoolTransaction) => {
|
|
transactions.push(poolTransaction)
|
|
})
|
|
}
|
|
|
|
if (JSON.stringify(data) !== JSON.stringify(transactions)) {
|
|
setData(transactions)
|
|
}
|
|
}, [accountId, chainIds, data, poolAddress, poolChainId])
|
|
|
|
const getPoolTransactions = useCallback(
|
|
async (cancelToken: CancelToken) => {
|
|
if (!data) {
|
|
return
|
|
}
|
|
const poolTransactions: PoolTransaction[] = []
|
|
const didList: string[] = []
|
|
|
|
for (let i = 0; i < data.length; i++) {
|
|
const { datatokenAddress } = data[i].poolAddress
|
|
const did = web3.utils
|
|
.toChecksumAddress(datatokenAddress)
|
|
.replace('0x', 'did:op:')
|
|
didList.push(did)
|
|
}
|
|
if (didList.length === 0) {
|
|
setIsLoading(false)
|
|
return
|
|
}
|
|
const ddoList = await retrieveDDOListByDIDs(
|
|
didList,
|
|
chainIds,
|
|
cancelToken
|
|
)
|
|
for (let i = 0; i < data.length; i++) {
|
|
poolTransactions.push({
|
|
...data[i],
|
|
networkId: ddoList[i]?.chainId,
|
|
ddo: ddoList[i]
|
|
})
|
|
}
|
|
const sortedTransactions = poolTransactions.sort(
|
|
(a, b) => b.timestamp - a.timestamp
|
|
)
|
|
|
|
setTransactions(sortedTransactions)
|
|
setIsLoading(false)
|
|
},
|
|
[data, chainIds, setIsLoading]
|
|
)
|
|
|
|
//
|
|
// Get data, periodically
|
|
//
|
|
useEffect(() => {
|
|
if (!appConfig?.metadataCacheUri) return
|
|
|
|
async function getTransactions() {
|
|
try {
|
|
await getPoolTransactionData()
|
|
if (dataFetchInterval) return
|
|
const interval = setInterval(async () => {
|
|
await getPoolTransactionData()
|
|
}, REFETCH_INTERVAL)
|
|
setDataFetchInterval(interval)
|
|
} catch (error) {
|
|
LoggerInstance.error(
|
|
'Error fetching pool transactions: ',
|
|
error.message
|
|
)
|
|
}
|
|
}
|
|
getTransactions()
|
|
|
|
return () => {
|
|
clearInterval(dataFetchInterval)
|
|
}
|
|
}, [getPoolTransactionData, dataFetchInterval, appConfig.metadataCacheUri])
|
|
|
|
//
|
|
// Transform to final transactions
|
|
//
|
|
useEffect(() => {
|
|
if (!cancelToken()) return
|
|
async function transformData() {
|
|
try {
|
|
setIsLoading(true)
|
|
await getPoolTransactions(cancelToken())
|
|
} catch (error) {
|
|
LoggerInstance.error(
|
|
'Error fetching pool transactions: ',
|
|
error.message
|
|
)
|
|
}
|
|
}
|
|
transformData()
|
|
|
|
return () => {
|
|
cancelToken()
|
|
}
|
|
}, [cancelToken, getPoolTransactions])
|
|
|
|
return accountId ? (
|
|
<Table
|
|
columns={minimal ? columnsMinimal : columns}
|
|
data={transactions}
|
|
isLoading={isLoading}
|
|
noTableHead={minimal}
|
|
dense={minimal}
|
|
pagination={
|
|
minimal ? transactions?.length >= 4 : transactions?.length >= 9
|
|
}
|
|
paginationPerPage={minimal ? 5 : 10}
|
|
/>
|
|
) : (
|
|
<div>Please connect your Web3 wallet.</div>
|
|
)
|
|
}
|