Refactor aquarius calls (#917)

* aquarius refactor

Signed-off-by: mihaisc <mihai.scarlat@smartcontrol.ro>

* fix highest liquidity

Signed-off-by: mihaisc <mihai@oceanprotocol.com>

* fix

* update search

Signed-off-by: mihaisc <mihai@oceanprotocol.com>

* remove test code

Signed-off-by: mihaisc <mihai@oceanprotocol.com>

* remove logs&unused dep

* remove old types

* fix bookmarks

* fix downloaded assets

* fix published list

* fix profile

* fix compute history

* fix compute

* fix edit compute

* remove old commented code
This commit is contained in:
mihaisc 2021-10-21 00:24:00 -07:00 committed by GitHub
parent fdcf72b067
commit cef0969065
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 645 additions and 526 deletions

View File

@ -235,7 +235,6 @@ Wenn du Fragen zu Purgatory hast oder wenn du kein GitHub-Konto besitzt und möc
Du hast das Recht, deine personenbezogenen Daten in einem strukturierten, gängigen und maschinenlesbaren Format zu erhalten. Zusätzlich hast du das Recht, diese Daten ungehindert an einen anderen Verantwortlichen zu übermitteln, sofern die in Art. 20 DSGVO definierten Voraussetzungen zutreffen.
Sie können von Ihrem Recht auf Datenübertragbarkeit Gebrauch machen, indem Sie sich mit uns in Verbindung setzen.
## 7.6 Widerspruchsrecht (Art. 21 GDPR)
Du hast das Recht, aus Gründen, die sich aus deiner besonderen Situation ergeben, gegen die Verarbeitung deiner personenbezogenen Daten Widerspruch einzulegen, wenn wir die Verarbeitung auf die Wahrung unseres berechtigten Interessens stützen (Art. 6(1)(f) GDPR). Wenn du Widerspruch einlegst, werden wir deine personenbezogenen Daten nicht mehr verarbeiten, es sei denn, wir können zwingende schutzwürdige Gründe für die Verarbeitung nachweisen, die deine Rechte, Freiheiten und Interessen überwiegen, oder wenn die Verarbeitung zur Begründung, Ausübung oder Verteidigung von Rechtsansprüchen erforderlich ist.

View File

@ -235,7 +235,6 @@ Si vous avez des questions sur Purgatory ou si vous n&#39;avez pas de compte Git
Vous avez le droit de recevoir vos données personnelles dans un format structuré, couramment utilisé et lisible par machine. En outre, vous avez le droit de transmettre ces données à un autre responsable du traitement sans entrave, lorsque les fondements juridiques définis à l&#39;article 20 du RGPD s&#39;appliquent.
Vous pouvez faire usage de votre droit à la portabilité des données en nous contactant.
## 7.6 Droit d&#39;opposition (art. 21 du RGPD)
Pour des motifs liés à votre situation particulière, vous avez le droit de vous opposer au traitement de vos données personnelles lorsque nous avons basé le traitement sur des intérêts légitimes (art. 6(1)(f) du RGPD). Si vous vous y opposez, Ocean ne traitera plus vos données personnelles à moins que nous puissions démontrer des motifs légitimes impérieux pour le traitement, outrepassant vos droits, libertés et intérêts, ou si le traitement est nécessaire pour établir, exercer ou défendre des réclamations légales.

View File

@ -1,5 +1,5 @@
import { useUserPreferences } from '../../providers/UserPreferences'
import React, { ReactElement, useEffect, useState } from 'react'
import React, { ReactElement, useCallback, useEffect, useState } from 'react'
import Table from '../atoms/Table'
import { Logger } from '@oceanprotocol/lib'
import Price from '../atoms/Price'
@ -7,22 +7,9 @@ import Tooltip from '../atoms/Tooltip'
import AssetTitle from './AssetListTitle'
import { retrieveDDOListByDIDs } from '../../utils/aquarius'
import { getAssetsBestPrices, AssetListPrices } from '../../utils/subgraph'
import axios, { CancelToken } from 'axios'
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
import { useCancelToken } from '../../hooks/useCancelToken'
async function getAssetsBookmarked(
bookmarks: string[],
chainIds: number[],
cancelToken: CancelToken
) {
try {
const result = await retrieveDDOListByDIDs(bookmarks, chainIds, cancelToken)
return result
} catch (error) {
Logger.error(error.message)
}
}
import { CancelToken } from 'axios'
const columns = [
{
@ -62,6 +49,27 @@ export default function Bookmarks(): ReactElement {
const [isLoading, setIsLoading] = useState<boolean>()
const { chainIds } = useUserPreferences()
const newCancelToken = useCancelToken()
const getAssetsBookmarked = useCallback(
async (
bookmarks: string[],
chainIds: number[],
cancelToken: CancelToken
) => {
try {
const result = await retrieveDDOListByDIDs(
bookmarks,
chainIds,
cancelToken
)
return result
} catch (error) {
Logger.error(error.message)
}
},
[]
)
useEffect(() => {
if (!appConfig?.metadataCacheUri || bookmarks === []) return
@ -90,7 +98,13 @@ export default function Bookmarks(): ReactElement {
setIsLoading(false)
}
init()
}, [appConfig?.metadataCacheUri, bookmarks, chainIds, newCancelToken])
}, [
appConfig?.metadataCacheUri,
bookmarks,
chainIds,
getAssetsBookmarked,
newCancelToken
])
return (
<Table

View File

@ -15,6 +15,8 @@ import { useWeb3 } from '../../../../providers/Web3'
import { usePricing } from '../../../../hooks/usePricing'
import { useAsset } from '../../../../providers/Asset'
import {
generateBaseQuery,
getFilterTerm,
queryMetadata,
transformDDOToAssetSelection
} from '../../../../utils/aquarius'
@ -27,7 +29,6 @@ import {
ComputeAlgorithm,
ComputeOutput
} from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
import { SearchQuery } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
import axios from 'axios'
import FormStartComputeDataset from './FormComputeDataset'
import styles from './index.module.css'
@ -42,6 +43,9 @@ import ComputeJobs from '../../../pages/Profile/History/ComputeJobs'
import { BestPrice } from '../../../../models/BestPrice'
import { useCancelToken } from '../../../../hooks/useCancelToken'
import { useIsMounted } from '../../../../hooks/useIsMounted'
import { BaseQueryParams } from '../../../../models/aquarius/BaseQueryParams'
import { SortTermOptions } from '../../../../models/SortAndFilters'
import { SearchQuery } from '../../../../models/aquarius/SearchQuery'
const SuccessAction = () => (
<Button style="text" to="/profile?defaultTab=ComputeJobs" size="small">
@ -133,23 +137,18 @@ export default function Compute({
trustedAlgorithmList: publisherTrustedAlgorithm[],
chainId?: number
): SearchQuery {
let algoQuerry = ''
trustedAlgorithmList.forEach((trusteAlgo) => {
algoQuerry += `id:"${trusteAlgo.did}" OR `
})
if (trustedAlgorithmList.length >= 1) {
algoQuerry = algoQuerry.substring(0, algoQuerry.length - 3)
}
const algorithmQuery =
trustedAlgorithmList.length > 0 ? `(${algoQuerry}) AND` : ``
const query = {
query: {
query_string: {
query: `${algorithmQuery} service.attributes.main.type:algorithm AND chainId:${chainId} -isInPurgatory:true`
}
},
sort: { created: 'desc' }
}
const algorithmDidList = trustedAlgorithmList.map((x) => x.did)
const baseParams = {
chainIds: [chainId],
sort: { sortBy: SortTermOptions.Created },
filters: [
getFilterTerm('service.attributes.main.type', 'algorithm'),
getFilterTerm('id', algorithmDidList)
]
} as BaseQueryParams
const query = generateBaseQuery(baseParams)
return query
}

View File

@ -6,16 +6,19 @@ import { AssetSelectionAsset } from '../../../molecules/FormFields/AssetSelectio
import stylesIndex from './index.module.css'
import styles from './FormEditMetadata.module.css'
import {
generateBaseQuery,
getFilterTerm,
queryMetadata,
transformDDOToAssetSelection
} from '../../../../utils/aquarius'
import { useAsset } from '../../../../providers/Asset'
import { ComputePrivacyForm } from '../../../../models/FormEditComputeDataset'
import { publisherTrustedAlgorithm as PublisherTrustedAlgorithm } from '@oceanprotocol/lib'
import axios from 'axios'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import FormActions from './FormActions'
import { useCancelToken } from '../../../../hooks/useCancelToken'
import { BaseQueryParams } from '../../../../models/aquarius/BaseQueryParams'
import { SortTermOptions } from '../../../../models/SortAndFilters'
export default function FormEditComputeDataset({
data,
@ -37,14 +40,13 @@ export default function FormEditComputeDataset({
async function getAlgorithmList(
publisherTrustedAlgorithms: PublisherTrustedAlgorithm[]
): Promise<AssetSelectionAsset[]> {
const query = {
query: {
query_string: {
query: `service.attributes.main.type:algorithm AND chainId:${ddo.chainId} -isInPurgatory:true`
}
},
sort: { created: 'desc' }
}
const baseParams = {
chainIds: [ddo.chainId],
sort: { sortBy: SortTermOptions.Created },
filters: [getFilterTerm('service.attributes.main.type', 'algorithm')]
} as BaseQueryParams
const query = generateBaseQuery(baseParams)
const querryResult = await queryMetadata(query, newCancelToken())
const datasetComputeService = ddo.findServiceByType('compute')
const algorithmSelectionList = await transformDDOToAssetSelection(

View File

@ -1,57 +1,47 @@
import React, { ReactElement, useEffect, useState } from 'react'
import AssetList from '../organisms/AssetList'
import { SearchQuery } from '@oceanprotocol/lib/dist/node/metadatacache/MetadataCache'
import Button from '../atoms/Button'
import Bookmarks from '../molecules/Bookmarks'
import {
queryMetadata,
transformChainIdsListToQuery
generateBaseQuery,
getFilterTerm,
queryMetadata
} from '../../utils/aquarius'
import Permission from '../organisms/Permission'
import { getHighestLiquidityDIDs } from '../../utils/subgraph'
import { getHighestLiquidityDatatokens } from '../../utils/subgraph'
import { DDO, Logger } from '@oceanprotocol/lib'
import { useSiteMetadata } from '../../hooks/useSiteMetadata'
import { useUserPreferences } from '../../providers/UserPreferences'
import styles from './Home.module.css'
import { useIsMounted } from '../../hooks/useIsMounted'
import { useCancelToken } from '../../hooks/useCancelToken'
import { SearchQuery } from '../../models/aquarius/SearchQuery'
import { SortTermOptions } from '../../models/SortAndFilters'
import { BaseQueryParams } from '../../models/aquarius/BaseQueryParams'
import { PagedAssets } from '../../models/PagedAssets'
async function getQueryHighest(
chainIds: number[]
): Promise<[SearchQuery, string]> {
const [dids, didsLength] = await getHighestLiquidityDIDs(chainIds)
const queryHighest = {
size: didsLength > 0 ? didsLength : 1,
query: {
query_string: {
query: `${dids && `(${dids}) AND`}(${transformChainIdsListToQuery(
chainIds
)}) AND -isInPurgatory:true `,
fields: ['dataToken']
}
}
}
return [queryHighest, dids]
}
function getQueryLatest(chainIds: number[]): any {
return {
size: 9,
query: {
query_string: {
query: `(${transformChainIdsListToQuery(
chainIds
)}) AND -isInPurgatory:true `
}
): Promise<[SearchQuery, string[]]> {
const dtList = await getHighestLiquidityDatatokens(chainIds)
const baseQueryParams = {
chainIds,
esPaginationOptions: {
size: dtList.length > 0 ? dtList.length : 1
},
sort: { created: 'desc' }
}
filters: [getFilterTerm('dataToken', dtList)]
} as BaseQueryParams
const queryHighest = generateBaseQuery(baseQueryParams)
return [queryHighest, dtList]
}
function sortElements(items: DDO[], sorted: string[]) {
items.sort(function (a, b) {
return sorted.indexOf(a.dataToken) - sorted.indexOf(b.dataToken)
return (
sorted.indexOf(a.dataToken.toLowerCase()) -
sorted.indexOf(b.dataToken.toLowerCase())
)
})
return items
}
@ -65,7 +55,7 @@ function SectionQueryResult({
title: ReactElement | string
query: SearchQuery
action?: ReactElement
queryData?: string
queryData?: string[]
}) {
const { chainIds } = useUserPreferences()
const [result, setResult] = useState<any>()
@ -75,7 +65,7 @@ function SectionQueryResult({
useEffect(() => {
async function init() {
if (chainIds.length === 0) {
const result: any = {
const result: PagedAssets = {
results: [],
page: 0,
totalPages: 0,
@ -89,8 +79,7 @@ function SectionQueryResult({
const result = await queryMetadata(query, newCancelToken())
if (!isMounted()) return
if (queryData && result?.totalResults > 0) {
const searchDIDs = queryData.split(' ')
const sortedAssets = sortElements(result.results, searchDIDs)
const sortedAssets = sortElements(result.results, queryData)
const overflow = sortedAssets.length - 9
sortedAssets.splice(sortedAssets.length - overflow, overflow)
result.results = sortedAssets
@ -103,7 +92,7 @@ function SectionQueryResult({
}
}
init()
}, [isMounted, newCancelToken, query])
}, [chainIds.length, isMounted, newCancelToken, query, queryData])
return (
<section className={styles.section}>
@ -119,13 +108,22 @@ function SectionQueryResult({
}
export default function HomePage(): ReactElement {
const [queryAndDids, setQueryAndDids] = useState<[SearchQuery, string]>()
const [queryAndDids, setQueryAndDids] = useState<[SearchQuery, string[]]>()
const [queryLatest, setQueryLatest] = useState<SearchQuery>()
const { chainIds } = useUserPreferences()
useEffect(() => {
getQueryHighest(chainIds).then((results) => {
setQueryAndDids(results)
})
const baseParams = {
chainIds: chainIds,
esPaginationOptions: { size: 9 },
sort: { sortBy: SortTermOptions.Created }
} as BaseQueryParams
setQueryLatest(generateBaseQuery(baseParams))
}, [chainIds])
return (
@ -144,15 +142,17 @@ export default function HomePage(): ReactElement {
/>
)}
<SectionQueryResult
title="Recently Published"
query={getQueryLatest(chainIds)}
action={
<Button style="text" to="/search?sort=created&sortOrder=desc">
All data sets and algorithms
</Button>
}
/>
{queryLatest && (
<SectionQueryResult
title="Recently Published"
query={queryLatest}
action={
<Button style="text" to="/search?sort=created&sortOrder=desc">
All data sets and algorithms
</Button>
}
/>
)}
</>
</Permission>
)

View File

@ -5,7 +5,6 @@ import { useUserPreferences } from '../../../../providers/UserPreferences'
import {
getAccountLiquidityInOwnAssets,
getAssetsBestPrices,
getUserSales,
UserLiquidity,
calculateUserLiquidity
} from '../../../../utils/subgraph'

View File

@ -4,8 +4,7 @@ import Time from '../../../atoms/Time'
import AssetTitle from '../../../molecules/AssetListTitle'
import NetworkName from '../../../atoms/NetworkName'
import { useProfile } from '../../../../providers/Profile'
import { DownloadedAsset } from '../../../../utils/aquarius'
import { DownloadedAsset } from '../../../../models/aquarius/DownloadedAsset'
const columns = [
{
name: 'Data Set',

View File

@ -64,9 +64,9 @@ function Liquidity({ row, type }: { row: Asset; type: string }) {
price =
isValidNumber(row.poolShare.poolId.oceanReserve) &&
isValidNumber(row.poolShare.poolId.datatokenReserve) &&
isValidNumber(row.poolShare.poolId.consumePrice)
isValidNumber(row.poolShare.poolId.spotPrice)
? new Decimal(row.poolShare.poolId.datatokenReserve)
.mul(new Decimal(row.poolShare.poolId.consumePrice))
.mul(new Decimal(row.poolShare.poolId.spotPrice))
.plus(row.poolShare.poolId.oceanReserve)
.toString()
: '0'
@ -148,6 +148,7 @@ async function getPoolSharesAssets(
didList.push(did)
}
const ddoList = await retrieveDDOListByDIDs(didList, chainIds, cancelToken)
for (let i = 0; i < data.length; i++) {
const userLiquidity = calculateUserLiquidity(data[i])
assetList.push({
@ -176,9 +177,11 @@ export default function PoolShares({
const isMounted = useIsMounted()
const fetchPoolSharesAssets = useCallback(
async (cancelToken: CancelToken) => {
if (!poolShares || isPoolSharesLoading || !isMounted()) return
async (
chainIds: number[],
poolShares: PoolShare[],
cancelToken: CancelToken
) => {
try {
const assets = await getPoolSharesAssets(
poolShares,
@ -192,18 +195,23 @@ export default function PoolShares({
setLoading(false)
}
},
[poolShares, isPoolSharesLoading, isMounted]
[]
)
// do not add chainIds,dataFetchInterval to effect dep
useEffect(() => {
const cancelToken = newCancelToken()
async function init() {
setLoading(true)
await fetchPoolSharesAssets(cancelToken)
if (!poolShares || isPoolSharesLoading || !chainIds || !isMounted())
return
await fetchPoolSharesAssets(chainIds, poolShares, cancelToken)
setLoading(false)
if (dataFetchInterval) return
const interval = setInterval(async () => {
await fetchPoolSharesAssets(cancelToken)
await fetchPoolSharesAssets(chainIds, poolShares, cancelToken)
}, REFETCH_INTERVAL)
setDataFetchInterval(interval)
}
@ -212,7 +220,13 @@ export default function PoolShares({
return () => {
clearInterval(dataFetchInterval)
}
}, [dataFetchInterval, fetchPoolSharesAssets, newCancelToken])
}, [
fetchPoolSharesAssets,
isPoolSharesLoading,
newCancelToken,
poolShares,
isMounted
])
return accountId ? (
<Table

View File

@ -1,5 +1,5 @@
import { Logger } from '@oceanprotocol/lib'
import React, { ReactElement, useEffect, useState } from 'react'
import React, { ReactElement, useCallback, useEffect, useState } from 'react'
import AssetList from '../../../organisms/AssetList'
import { getPublishedAssets } from '../../../../utils/aquarius'
import Filters from '../../../templates/Search/Filters'
@ -7,6 +7,7 @@ import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import { useUserPreferences } from '../../../../providers/UserPreferences'
import styles from './PublishedList.module.css'
import { useCancelToken } from '../../../../hooks/useCancelToken'
import { PagedAssets } from '../../../../models/PagedAssets'
export default function PublishedList({
accountId
@ -16,50 +17,53 @@ export default function PublishedList({
const { appConfig } = useSiteMetadata()
const { chainIds } = useUserPreferences()
const [queryResult, setQueryResult] = useState<any>()
const [queryResult, setQueryResult] = useState<PagedAssets>()
const [isLoading, setIsLoading] = useState(false)
const [page, setPage] = useState<number>(1)
const [service, setServiceType] = useState('dataset OR algorithm')
const [access, setAccsesType] = useState('access OR compute')
const [service, setServiceType] = useState()
const [access, setAccsesType] = useState()
const newCancelToken = useCancelToken()
async function getPublished() {
try {
setIsLoading(true)
const result = await getPublishedAssets(
accountId,
chainIds,
newCancelToken(),
page,
service,
access
)
setQueryResult(result)
} catch (error) {
Logger.error(error.message)
} finally {
setIsLoading(false)
}
}
const getPublished = useCallback(
async (accountId, chainIds, page, service, access, cancelToken) => {
try {
setIsLoading(true)
const result = await getPublishedAssets(
accountId.toLowerCase(),
chainIds,
cancelToken,
page,
service,
access
)
setQueryResult(result)
} catch (error) {
Logger.error(error.message)
} finally {
setIsLoading(false)
}
},
[]
)
useEffect(() => {
async function fetchPublishedAssets() {
await getPublished()
}
if (page !== 1) {
setPage(1)
} else {
fetchPublishedAssets()
}
}, [service, access])
if (queryResult && queryResult.totalPages < page) setPage(1)
}, [page, queryResult])
useEffect(() => {
if (!accountId) return
async function fetchPublishedAssets() {
await getPublished()
}
fetchPublishedAssets()
}, [accountId, page, appConfig.metadataCacheUri, chainIds, newCancelToken])
getPublished(accountId, chainIds, page, service, access, newCancelToken())
}, [
accountId,
page,
appConfig.metadataCacheUri,
chainIds,
newCancelToken,
getPublished,
service,
access
])
return accountId ? (
<>

View File

@ -1,13 +1,13 @@
import React, { ReactElement, useState } from 'react'
import { useNavigate } from '@reach/router'
import classNames from 'classnames/bind'
import {
addExistingParamsToUrl,
FilterByAccessOptions,
FilterByTypeOptions
} from './utils'
import { addExistingParamsToUrl } from './utils'
import Button from '../../atoms/Button'
import styles from './Filters.module.css'
import {
FilterByAccessOptions,
FilterByTypeOptions
} from '../../../models/SortAndFilters'
const cx = classNames.bind(styles)

View File

@ -1,4 +1,4 @@
import React, { ReactElement, useState, useEffect } from 'react'
import React, { ReactElement, useState, useEffect, useCallback } from 'react'
import Permission from '../../organisms/Permission'
import AssetList from '../../organisms/AssetList'
import queryString from 'query-string'
@ -10,6 +10,7 @@ import { updateQueryStringParameter } from '../../../utils'
import { useUserPreferences } from '../../../providers/UserPreferences'
import { useCancelToken } from '../../../hooks/useCancelToken'
import styles from './index.module.css'
import { PagedAssets } from '../../../models/PagedAssets'
export default function SearchPage({
location,
@ -20,54 +21,61 @@ export default function SearchPage({
setTotalResults: (totalResults: number) => void
setTotalPagesNumber: (totalPagesNumber: number) => void
}): ReactElement {
const parsed = queryString.parse(location.search)
const { text, owner, tags, page, sort, sortOrder, serviceType, accessType } =
parsed
const [parsed, setParsed] = useState<queryString.ParsedQuery<string>>()
const { chainIds } = useUserPreferences()
const [queryResult, setQueryResult] = useState<any>()
const [queryResult, setQueryResult] = useState<PagedAssets>()
const [loading, setLoading] = useState<boolean>()
const [service, setServiceType] = useState<string>(serviceType as string)
const [access, setAccessType] = useState<string>(accessType as string)
const [sortType, setSortType] = useState<string>(sort as string)
const [sortDirection, setSortDirection] = useState<string>(
sortOrder as string
)
const [serviceType, setServiceType] = useState<string>()
const [accessType, setAccessType] = useState<string>()
const [sortType, setSortType] = useState<string>()
const [sortDirection, setSortDirection] = useState<string>()
const newCancelToken = useCancelToken()
async function fetchAssets() {
setLoading(true)
setTotalResults(undefined)
const queryResult = await getResults(parsed, chainIds, newCancelToken())
useEffect(() => {
const parsed = queryString.parse(location.search)
const { sort, sortOrder, serviceType, accessType } = parsed
setParsed(parsed)
setServiceType(serviceType as string)
setAccessType(accessType as string)
setSortDirection(sortOrder as string)
setSortType(sort as string)
}, [location])
setQueryResult(queryResult)
setTotalResults(queryResult.totalResults)
setTotalPagesNumber(queryResult.totalPages)
setLoading(false)
}
const updatePage = useCallback(
(page: number) => {
const { pathname, search } = location
const newUrl = updateQueryStringParameter(
pathname + search,
'page',
`${page}`
)
return navigate(newUrl)
},
[location]
)
function setPage(page: number) {
const newUrl = updateQueryStringParameter(
location.pathname + location.search,
'page',
`${page}`
)
return navigate(newUrl)
}
const fetchAssets = useCallback(
async (parsed: queryString.ParsedQuery<string>, chainIds: number[]) => {
setLoading(true)
setTotalResults(undefined)
const queryResult = await getResults(parsed, chainIds, newCancelToken())
setQueryResult(queryResult)
setTotalResults(queryResult.totalResults)
setTotalPagesNumber(queryResult.totalPages)
setLoading(false)
},
[newCancelToken, setTotalPagesNumber, setTotalResults]
)
useEffect(() => {
if (!parsed || !queryResult) return
const { page } = parsed
if (queryResult.totalPages < Number(page)) updatePage(1)
}, [parsed, queryResult, updatePage])
useEffect(() => {
async function initSearch() {
await fetchAssets()
}
initSearch()
}, [text, owner, tags, sort, page, sortOrder, chainIds, newCancelToken])
useEffect(() => {
if (page !== '1') {
setPage(1)
} else {
fetchAssets()
}
}, [serviceType, accessType])
if (!parsed || !chainIds) return
fetchAssets(parsed, chainIds)
}, [parsed, chainIds, newCancelToken, fetchAssets])
return (
<Permission eventType="browse">
@ -75,8 +83,8 @@ export default function SearchPage({
<div className={styles.search}>
<div className={styles.row}>
<Filters
serviceType={service}
accessType={access}
serviceType={serviceType}
accessType={accessType}
setServiceType={setServiceType}
setAccessType={setAccessType}
addFiltersToUrl
@ -96,7 +104,7 @@ export default function SearchPage({
isLoading={loading}
page={queryResult?.page}
totalPages={queryResult?.totalPages}
onPageChange={setPage}
onPageChange={updatePage}
/>
</div>
</>

View File

@ -1,13 +1,13 @@
import React, { ReactElement } from 'react'
import { useNavigate } from '@reach/router'
import {
addExistingParamsToUrl,
SortTermOptions,
SortValueOptions
} from './utils'
import { addExistingParamsToUrl } from './utils'
import Button from '../../atoms/Button'
import styles from './sort.module.css'
import classNames from 'classnames/bind'
import {
SortDirectionOptions,
SortTermOptions
} from '../../../models/SortAndFilters'
const cx = classNames.bind(styles)
@ -29,7 +29,7 @@ export default function Sort({
}): ReactElement {
const navigate = useNavigate()
const directionArrow = String.fromCharCode(
sortDirection === SortValueOptions.Ascending ? 9650 : 9660
sortDirection === SortDirectionOptions.Ascending ? 9650 : 9660
)
async function sortResults(sortBy?: string, direction?: string) {
let urlLocation: string
@ -46,10 +46,10 @@ export default function Sort({
}
function handleSortButtonClick(value: string) {
if (value === sortType) {
if (sortDirection === SortValueOptions.Descending) {
sortResults(null, SortValueOptions.Ascending)
if (sortDirection === SortDirectionOptions.Descending) {
sortResults(null, SortDirectionOptions.Ascending)
} else {
sortResults(null, SortValueOptions.Descending)
sortResults(null, SortDirectionOptions.Descending)
}
} else {
sortResults(value, null)

View File

@ -1,51 +1,18 @@
import { Logger } from '@oceanprotocol/lib'
import {
queryMetadata,
transformChainIdsListToQuery
generateBaseQuery,
getFilterTerm,
queryMetadata
} from '../../../utils/aquarius'
import queryString from 'query-string'
import { CancelToken } from 'axios'
export const SortTermOptions = {
Created: 'created',
Relevance: '_score'
} as const
type SortTermOptions = typeof SortTermOptions[keyof typeof SortTermOptions]
export const SortElasticTerm = {
Liquidity: 'price.ocean',
Price: 'price.value',
Created: 'created'
} as const
type SortElasticTerm = typeof SortElasticTerm[keyof typeof SortElasticTerm]
export const SortValueOptions = {
Ascending: 'asc',
Descending: 'desc'
} as const
type SortValueOptions = typeof SortValueOptions[keyof typeof SortValueOptions]
export const FilterByTypeOptions = {
Data: 'dataset',
Algorithm: 'algorithm'
} as const
type FilterByTypeOptions =
typeof FilterByTypeOptions[keyof typeof FilterByTypeOptions]
export const FilterByAccessOptions = {
Download: 'access',
Compute: 'compute'
}
type FilterByAccessOptions =
typeof FilterByAccessOptions[keyof typeof FilterByAccessOptions]
function getSortType(sortParam: string): string {
const sortTerm =
sortParam === SortTermOptions.Created
? SortTermOptions.Created
: SortTermOptions.Relevance
return sortTerm
}
import { BaseQueryParams } from '../../../models/aquarius/BaseQueryParams'
import { SearchQuery } from '../../../models/aquarius/SearchQuery'
import { FilterTerm } from '../../../models/aquarius/FilterTerm'
import {
SortDirectionOptions,
SortTermOptions
} from '../../../models/SortAndFilters'
export function escapeESReservedChars(text: string): string {
return text?.replace(/([!*+\-=<>&|()\\[\]{}^~?:\\/"])/g, '\\$1')
@ -60,10 +27,10 @@ export function getSearchQuery(
page?: string,
offset?: string,
sort?: string,
sortOrder?: string,
sortDirection?: string,
serviceType?: string,
accessType?: string
): any {
): SearchQuery {
text = escapeESReservedChars(text)
const emptySearchTerm = text === undefined || text === ''
@ -98,81 +65,70 @@ export function getSearchQuery(
'service.attributes.additionalInformation.description',
'service.attributes.additionalInformation.tags'
]
return {
from: (Number(page) - 1 || 0) * (Number(offset) || 21),
size: Number(offset) || 21,
query: {
bool: {
must: [
{
bool: {
should: [
{
query_string: {
query: `${modifiedSearchTerm}`,
fields: searchFields,
minimum_should_match: '2<75%',
phrase_slop: 2,
boost: 5
}
},
{
query_string: {
query: `${noSpaceSearchTerm}*`,
fields: searchFields,
boost: 5,
lenient: true
}
},
{
match_phrase: {
content: {
query: `${searchTerm}`,
boost: 10
}
}
},
{
query_string: {
query: `${prefixedSearchTerm}`,
fields: searchFields,
default_operator: 'AND'
}
const nestedQuery = {
must: [
{
bool: {
should: [
{
query_string: {
query: `${modifiedSearchTerm}`,
fields: searchFields,
minimum_should_match: '2<75%',
phrase_slop: 2,
boost: 5
}
},
{
query_string: {
query: `${noSpaceSearchTerm}*`,
fields: searchFields,
boost: 5,
lenient: true
}
},
{
match_phrase: {
content: {
query: `${searchTerm}`,
boost: 10
}
]
}
},
{
query_string: {
query: `${prefixedSearchTerm}`,
fields: searchFields,
default_operator: 'AND'
}
}
},
{
match: {
'service.attributes.main.type':
serviceType === undefined
? 'dataset OR algorithm'
: `${serviceType}`
}
},
{
match: {
'service.type':
accessType === undefined ? 'access OR compute' : `${accessType}`
}
},
{
query_string: {
query: `${transformChainIdsListToQuery(chainIds)}`
}
},
{
term: {
isInPurgatory: false
}
}
]
]
}
}
},
sort: {
[sort]: sortOrder
}
]
}
const filters: FilterTerm[] = []
accessType !== undefined &&
filters.push(getFilterTerm('service.type', accessType))
serviceType !== undefined &&
filters.push(getFilterTerm('service.attributes.main.type', serviceType))
const baseQueryParams = {
chainIds,
nestedQuery,
esPaginationOptions: {
from: (Number(page) - 1 || 0) * (Number(offset) || 21),
size: Number(offset) || 21
},
sortOptions: { sortBy: sort, sortDirection: sortDirection },
filters
} as BaseQueryParams
const query = generateBaseQuery(baseQueryParams)
return query
}
export async function getResults(
@ -242,7 +198,7 @@ export async function addExistingParamsToUrl(
// sort should be relevance when fixed in aqua
urlLocation = `${urlLocation}sort=${encodeURIComponent(
SortTermOptions.Relevance
)}&sortOrder=${SortValueOptions.Descending}&`
)}&sortOrder=${SortDirectionOptions.Descending}&`
}
urlLocation = urlLocation.slice(0, -1)
return urlLocation

View File

@ -0,0 +1,8 @@
import { DDO } from '@oceanprotocol/lib'
export interface PagedAssets {
results: DDO[]
page: number
totalPages: number
totalResults: number
}

View File

@ -0,0 +1,26 @@
export enum SortDirectionOptions {
Ascending = 'asc',
Descending = 'desc'
}
export enum SortTermOptions {
Created = 'created',
Relevance = '_score'
}
export enum FilterByTypeOptions {
Data = 'dataset',
Algorithm = 'algorithm'
}
export enum FilterByAccessOptions {
Download = 'access',
Compute = 'compute'
}
export interface SortOptions {
sortBy: SortTermOptions
sortDirection?: SortDirectionOptions
}
export type Filters = FilterByTypeOptions | FilterByAccessOptions

View File

@ -0,0 +1,12 @@
import { SortOptions } from '../SortAndFilters'
import { EsPaginationOptions } from './EsPaginationOptions'
import { FilterTerm } from './FilterTerm'
export interface BaseQueryParams {
chainIds: number[]
nestedQuery?: any
esPaginationOptions?: EsPaginationOptions
sortOptions?: SortOptions
filters?: FilterTerm[]
ignorePurgatory?: boolean
}

View File

@ -0,0 +1,8 @@
import { DDO } from '@oceanprotocol/lib'
export interface DownloadedAsset {
dtSymbol: string
timestamp: number
networkId: number
ddo: DDO
}

View File

@ -0,0 +1,4 @@
export interface EsPaginationOptions {
from?: number
size?: number
}

View File

@ -0,0 +1,5 @@
export interface FilterTerm {
[property: string]: {
[property: string]: string | number | boolean | number[] | string[]
}
}

View File

@ -0,0 +1,8 @@
import { SortDirectionOptions } from '../SortAndFilters'
export interface SearchQuery {
from?: number
size?: number
// eslint-disable-next-line @typescript-eslint/no-explicit-any
query: any
sort?: { [jsonPath: string]: SortDirectionOptions }
}

View File

@ -0,0 +1,41 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable camelcase */
import { DDO } from '@oceanprotocol/lib'
export interface Explanation {
value: number
description: string
details: Explanation[]
}
export interface ShardsResponse {
total: number
successful: number
failed: number
skipped: number
}
export interface SearchResponse {
took: number
timed_out: boolean
_scroll_id?: string | undefined
_shards: ShardsResponse
hits: {
total: number
max_score: number
hits: Array<{
_index: string
_type: string
_id: string
_score: number
_source: DDO
_version?: number | undefined
_explanation?: Explanation | undefined
fields?: any
highlight?: any
inner_hits?: any
matched_queries?: string[] | undefined
sort?: string[] | undefined
}>
}
aggregations?: any
}

View File

@ -52,8 +52,8 @@ export default function PageGatsbySearch(props: PageProps): ReactElement {
>
<PageSearch
location={props.location}
setTotalResults={(totalResults) => setTotalResults(totalResults)}
setTotalPagesNumber={(totalPages) => setTotalPagesNumber(totalPages)}
setTotalResults={setTotalResults}
setTotalPagesNumber={setTotalPagesNumber}
/>
</Page>
)

View File

@ -15,11 +15,7 @@ import {
import { useUserPreferences } from './UserPreferences'
import { PoolShares_poolShares as PoolShare } from '../@types/apollo/PoolShares'
import { DDO, Logger } from '@oceanprotocol/lib'
import {
DownloadedAsset,
getDownloadAssets,
getPublishedAssets
} from '../utils/aquarius'
import { getDownloadAssets, getPublishedAssets } from '../utils/aquarius'
import { useSiteMetadata } from '../hooks/useSiteMetadata'
import { Profile } from '../models/Profile'
import { accountTruncate } from '../utils/web3'
@ -27,6 +23,7 @@ import axios, { CancelToken } from 'axios'
import ethereumAddress from 'ethereum-address'
import get3BoxProfile from '../utils/profile'
import web3 from 'web3'
import { DownloadedAsset } from '../models/aquarius/DownloadedAsset'
interface ProfileProviderValue {
profile: Profile
@ -134,31 +131,34 @@ function ProfileProvider({
const [isPoolSharesLoading, setIsPoolSharesLoading] = useState<boolean>(false)
const [poolSharesInterval, setPoolSharesInterval] = useState<NodeJS.Timeout>()
const fetchPoolShares = useCallback(async () => {
if (!accountId || !chainIds || !isEthAddress) return
const fetchPoolShares = useCallback(
async (accountId, chainIds, isEthAddress) => {
if (!accountId || !chainIds || !isEthAddress) return
try {
setIsPoolSharesLoading(true)
const poolShares = await getPoolSharesData(accountId, chainIds)
setPoolShares(poolShares)
Logger.log(
`[profile] Fetched ${poolShares.length} pool shares.`,
poolShares
)
} catch (error) {
Logger.error('Error fetching pool shares: ', error.message)
} finally {
setIsPoolSharesLoading(false)
}
}, [accountId, chainIds, isEthAddress])
try {
setIsPoolSharesLoading(true)
const poolShares = await getPoolSharesData(accountId, chainIds)
setPoolShares(poolShares)
Logger.log(
`[profile] Fetched ${poolShares.length} pool shares.`,
poolShares
)
} catch (error) {
Logger.error('Error fetching pool shares: ', error.message)
} finally {
setIsPoolSharesLoading(false)
}
},
[]
)
useEffect(() => {
async function init() {
await fetchPoolShares()
await fetchPoolShares(accountId, chainIds, isEthAddress)
if (poolSharesInterval) return
const interval = setInterval(async () => {
await fetchPoolShares()
await fetchPoolShares(accountId, chainIds, isEthAddress)
}, refreshInterval)
setPoolSharesInterval(interval)
}
@ -167,7 +167,7 @@ function ProfileProvider({
return () => {
clearInterval(poolSharesInterval)
}
}, [poolSharesInterval, fetchPoolShares])
}, [poolSharesInterval, fetchPoolShares, accountId, chainIds, isEthAddress])
//
// PUBLISHED ASSETS

View File

@ -10,49 +10,70 @@ import { PriceList, getAssetsPriceList } from './subgraph'
import axios, { CancelToken, AxiosResponse } from 'axios'
import { OrdersData_tokenOrders as OrdersData } from '../@types/apollo/OrdersData'
import { metadataCacheUri } from '../../app.config'
export interface DownloadedAsset {
dtSymbol: string
timestamp: number
networkId: number
ddo: DDO
}
import { DownloadedAsset } from '../models/aquarius/DownloadedAsset'
import { SearchQuery } from '../models/aquarius/SearchQuery'
import { SearchResponse } from '../models/aquarius/SearchResponse'
import { PagedAssets } from '../models/PagedAssets'
import { SortDirectionOptions, SortTermOptions } from '../models/SortAndFilters'
import { FilterTerm } from '../models/aquarius/FilterTerm'
import { BaseQueryParams } from '../models/aquarius/BaseQueryParams'
export const MAXIMUM_NUMBER_OF_PAGES_WITH_RESULTS = 476
function getQueryForAlgorithmDatasets(algorithmDid: string, chainId?: number) {
/**
* @param filterField the name of the actual field from the ddo schema e.g. 'id','service.attributes.main.type'
* @param value the value of the filter
* @returns json structure of the es filter
*/
export function getFilterTerm(
filterField: string,
value: string | number | boolean | number[] | string[]
): FilterTerm {
const isArray = Array.isArray(value)
return {
query: {
bool: {
must: [
{
match: {
'service.attributes.main.privacy.publisherTrustedAlgorithms.did':
algorithmDid
}
},
{
query_string: {
query: `chainId:${chainId}`
}
}
]
}
},
sort: { created: 'desc' }
[isArray ? 'terms' : 'term']: {
[filterField]: value
}
}
}
// TODO: import directly from ocean.js somehow.
// Transforming Aquarius' direct response is needed for getting actual DDOs
// and not just strings of DDOs. For now, taken from
// https://github.com/oceanprotocol/ocean.js/blob/main/src/metadatacache/MetadataCache.ts#L361-L375
export function generateBaseQuery(
baseQueryParams: BaseQueryParams
): SearchQuery {
const generatedQuery = {
from: baseQueryParams.esPaginationOptions?.from || 0,
size: baseQueryParams.esPaginationOptions?.size || 1000,
query: {
bool: {
...baseQueryParams.nestedQuery,
filter: [
...(baseQueryParams.filters || []),
getFilterTerm('chainId', baseQueryParams.chainIds),
getFilterTerm('_index', 'aquarius'),
...(baseQueryParams.ignorePurgatory
? []
: [getFilterTerm('isInPurgatory', 'false')])
]
}
}
} as SearchQuery
if (baseQueryParams.sortOptions !== undefined)
generatedQuery.sort = {
[baseQueryParams.sortOptions.sortBy]:
baseQueryParams.sortOptions.sortDirection ||
SortDirectionOptions.Descending
}
return generatedQuery
}
export function transformQueryResult(
queryResult: any,
queryResult: SearchResponse,
from = 0,
size = 21
): any {
const result: any = {
): PagedAssets {
const result: PagedAssets = {
results: [],
page: 0,
totalPages: 0,
@ -60,7 +81,7 @@ export function transformQueryResult(
}
result.results = (queryResult.hits.hits || []).map(
(hit: any) => new DDO(hit._source as DDO)
(hit) => new DDO(hit._source as DDO)
)
result.totalResults = queryResult.hits.total
result.totalPages =
@ -72,31 +93,12 @@ export function transformQueryResult(
return result
}
export function transformChainIdsListToQuery(chainIds: number[]): string {
let chainQuery = ''
chainIds.forEach((chainId) => {
chainQuery += `chainId:${chainId} OR `
})
chainQuery = chainQuery.slice(0, chainQuery.length - 4)
return chainQuery
}
export function transformDIDListToQuery(didList: string[] | DID[]): string {
let chainQuery = ''
const regex = new RegExp('(:)', 'g')
didList.forEach((did: any) => {
chainQuery += `id:${did.replace(regex, '\\:')} OR `
})
chainQuery = chainQuery.slice(0, chainQuery.length - 4)
return chainQuery
}
export async function queryMetadata(
query: any,
query: SearchQuery,
cancelToken: CancelToken
): Promise<any> {
): Promise<PagedAssets> {
try {
const response: AxiosResponse<any> = await axios.post(
const response: AxiosResponse<SearchResponse> = await axios.post(
`${metadataCacheUri}/api/v1/aquarius/assets/query`,
{ ...query },
{ cancelToken }
@ -155,6 +157,53 @@ export async function getAssetsNames(
}
}
export async function getAssetsFromDidList(
didList: string[],
chainIds: number[],
cancelToken: CancelToken
): Promise<any> {
try {
if (!(didList.length > 0)) return
const baseParams = {
chainIds: chainIds,
filters: [getFilterTerm('id', didList)],
ignorePurgatory: true
} as BaseQueryParams
const query = generateBaseQuery(baseParams)
const queryResult = await queryMetadata(query, cancelToken)
return queryResult
} catch (error) {
Logger.error(error.message)
}
}
export async function retrieveDDOListByDIDs(
didList: string[],
chainIds: number[],
cancelToken: CancelToken
): Promise<DDO[]> {
try {
if (didList?.length === 0 || chainIds?.length === 0) return []
const orderedDDOListByDIDList: DDO[] = []
const baseQueryparams = {
chainIds,
filters: [getFilterTerm('id', didList)],
ignorePurgatory: true
} as BaseQueryParams
const query = generateBaseQuery(baseQueryparams)
const result = await queryMetadata(query, cancelToken)
didList.forEach((did: string | DID) => {
const ddo: DDO = result.results.find((ddo: DDO) => ddo.id === did)
orderedDDOListByDIDList.push(ddo)
})
return orderedDDOListByDIDList
} catch (error) {
Logger.error(error.message)
}
}
export async function transformDDOToAssetSelection(
datasetProviderEndpoint: string,
ddoList: DDO[],
@ -212,60 +261,34 @@ export async function getAlgorithmDatasetsForCompute(
datasetChainId?: number,
cancelToken?: CancelToken
): Promise<AssetSelectionAsset[]> {
const computeDatasets = await queryMetadata(
getQueryForAlgorithmDatasets(algorithmId, datasetChainId),
cancelToken
)
const computeDatasetsForCurrentAlgorithm: DDO[] = []
computeDatasets.results.forEach((data: DDO) => {
const algorithm = data
.findServiceByType('compute')
.attributes.main.privacy.publisherTrustedAlgorithms.find(
(algo) => algo.did === algorithmId
const baseQueryParams = {
chainIds: [datasetChainId],
filters: [
getFilterTerm(
'service.attributes.main.privacy.publisherTrustedAlgorithms.did',
algorithmId
)
algorithm && computeDatasetsForCurrentAlgorithm.push(data)
})
if (computeDatasetsForCurrentAlgorithm.length === 0) {
return []
}
],
sortOptions: {
sortBy: SortTermOptions.Created,
sortDirection: SortDirectionOptions.Descending
}
} as BaseQueryParams
const query = generateBaseQuery(baseQueryParams)
const computeDatasets = await queryMetadata(query, cancelToken)
if (computeDatasets.totalResults === 0) return []
const datasets = await transformDDOToAssetSelection(
datasetProviderUri,
computeDatasetsForCurrentAlgorithm,
computeDatasets.results,
[],
cancelToken
)
return datasets
}
export async function retrieveDDOListByDIDs(
didList: string[] | DID[],
chainIds: number[],
cancelToken: CancelToken
): Promise<DDO[]> {
try {
if (didList?.length === 0 || chainIds?.length === 0) return []
const orderedDDOListByDIDList: DDO[] = []
const query = {
size: didList.length,
query: {
query_string: {
query: `(${transformDIDListToQuery(
didList
)}) AND (${transformChainIdsListToQuery(chainIds)})`
}
}
}
const result = await queryMetadata(query, cancelToken)
didList.forEach((did: string | DID) => {
const ddo: DDO = result.results.find((ddo: DDO) => ddo.id === did)
orderedDDOListByDIDList.push(ddo)
})
return orderedDDOListByDIDList
} catch (error) {
Logger.error(error.message)
}
}
export async function getPublishedAssets(
accountId: string,
chainIds: number[],
@ -273,26 +296,33 @@ export async function getPublishedAssets(
page?: number,
type?: string,
accesType?: string
): Promise<any> {
): Promise<PagedAssets> {
if (!accountId) return
type = type || 'dataset OR algorithm'
accesType = accesType || 'access OR compute'
const filters: FilterTerm[] = []
const queryPublishedAssets = {
from: (Number(page) - 1 || 0) * (Number(9) || 21),
size: Number(9) || 21,
query: {
query_string: {
query: `(publicKey.owner:${accountId}) AND (service.attributes.main.type:${type}) AND (service.type:${accesType}) AND (${transformChainIdsListToQuery(
chainIds
)})`
}
filters.push(getFilterTerm('publicKey.owner', accountId.toLowerCase()))
accesType !== undefined &&
filters.push(getFilterTerm('service.type', accesType))
type !== undefined &&
filters.push(getFilterTerm('service.attributes.main.type', type))
const baseQueryParams = {
chainIds,
filters,
sortOptions: {
sortBy: SortTermOptions.Created,
sortDirection: SortDirectionOptions.Descending
},
sort: { created: 'desc' }
}
esPaginationOptions: {
from: (Number(page) - 1 || 0) * 9,
size: 9
}
} as BaseQueryParams
const query = generateBaseQuery(baseQueryParams)
try {
const result = await queryMetadata(queryPublishedAssets, cancelToken)
const result = await queryMetadata(query, cancelToken)
return result
} catch (error) {
if (axios.isCancel(error)) {
@ -309,38 +339,34 @@ export async function getDownloadAssets(
chainIds: number[],
cancelToken: CancelToken
): Promise<DownloadedAsset[]> {
const downloadedAssets: DownloadedAsset[] = []
try {
const queryResult = await retrieveDDOListByDIDs(
didList,
const baseQueryparams = {
chainIds,
cancelToken
)
const ddoList = queryResult
filters: [
getFilterTerm('id', didList),
getFilterTerm('service.type', 'access')
]
} as BaseQueryParams
const query = generateBaseQuery(baseQueryparams)
const result = await queryMetadata(query, cancelToken)
for (let i = 0; i < tokenOrders?.length; i++) {
const ddo = ddoList.filter(
(ddo: { dataToken: string }) =>
tokenOrders[i].datatokenId.address.toLowerCase() ===
ddo.dataToken.toLowerCase()
)[0]
const downloadedAssets: DownloadedAsset[] = result.results
.map((ddo) => {
const order = tokenOrders.find(
({ datatokenId }) =>
datatokenId?.address.toLowerCase() === ddo.dataToken.toLowerCase()
)
// make sure we are only pushing download orders
if (ddo.service[1].type !== 'access') continue
downloadedAssets.push({
ddo,
networkId: ddo.chainId,
dtSymbol: tokenOrders[i].datatokenId.symbol,
timestamp: tokenOrders[i].timestamp
return {
ddo,
networkId: ddo.chainId,
dtSymbol: order?.datatokenId?.symbol,
timestamp: order?.timestamp
}
})
}
.sort((a, b) => b.timestamp - a.timestamp)
const sortedOrders = downloadedAssets.sort(
(a, b) => b.timestamp - a.timestamp
)
return sortedOrders
return downloadedAssets
} catch (error) {
Logger.error(error.message)
}

View File

@ -12,12 +12,13 @@ import {
import { ComputePrivacyForm } from '../models/FormEditComputeDataset'
import web3 from 'web3'
import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/Compute'
import axios, { CancelToken } from 'axios'
import { CancelToken } from 'axios'
import { gql } from 'urql'
import { ComputeJobMetaData } from '../@types/ComputeJobMetaData'
import { transformChainIdsListToQuery, queryMetadata } from './aquarius'
import { queryMetadata, getFilterTerm, generateBaseQuery } from './aquarius'
import { fetchDataForMultipleChains } from './subgraph'
import { OrdersData_tokenOrders_datatokenId as OrdersDatatoken } from '../@types/apollo/OrdersData'
import { BaseQueryParams } from '../models/aquarius/BaseQueryParams'
const getComputeOrders = gql`
query ComputeOrders($user: String!) {
@ -72,22 +73,22 @@ interface ComputeResults {
}
async function getAssetMetadata(
queryDtList: string,
queryDtList: string[],
cancelToken: CancelToken,
chainIds: number[]
): Promise<DDO[]> {
const queryDid = {
query: {
query_string: {
query: `(${queryDtList}) AND (${transformChainIdsListToQuery(
chainIds
)}) AND service.attributes.main.type:dataset AND service.type:compute`,
fields: ['dataToken']
}
}
}
const baseQueryparams = {
chainIds,
filters: [
getFilterTerm('dataToken', queryDtList),
getFilterTerm('service.type', 'compute'),
getFilterTerm('service.attributes.main.type', 'dataset')
],
ignorePurgatory: true
} as BaseQueryParams
const query = generateBaseQuery(baseQueryparams)
const result = await queryMetadata(query, cancelToken)
const result = await queryMetadata(queryDid, cancelToken)
return result.results
}
@ -206,18 +207,14 @@ async function getJobs(
return computeJobs
}
function getDtList(data: TokenOrder[]) {
function getDtList(data: TokenOrder[]): string[] {
const dtList = []
for (let i = 0; i < data.length; i++) {
dtList.push(data[i].datatokenId.address)
}
const queryDtList = JSON.stringify(dtList)
.replace(/,/g, ' ')
.replace(/"/g, '')
.replace(/(\[|\])/g, '')
return queryDtList
return dtList
}
export async function getComputeJobs(
@ -225,7 +222,8 @@ export async function getComputeJobs(
config: Config,
ocean: Ocean,
account: Account,
ddo?: DDO
ddo?: DDO,
token?: CancelToken
): Promise<ComputeResults> {
const assetDTAddress = ddo?.dataTokenInfo?.address
let computeResult: ComputeResults = {
@ -262,10 +260,9 @@ export async function getComputeJobs(
data = data.sort((a, b) => b.timestamp - a.timestamp)
const queryDtList = getDtList(data)
if (queryDtList === '') return
if (!queryDtList) return
const source = axios.CancelToken.source()
const assets = await getAssetMetadata(queryDtList, source.token, chainIds)
const assets = await getAssetMetadata(queryDtList, token, chainIds)
const serviceEndpoints = getServiceEndpoints(data, assets)
const providers: Provider[] = await getProviders(
serviceEndpoints,

View File

@ -590,10 +590,10 @@ export async function getAssetsBestPrices(
return assetsWithPrice
}
export async function getHighestLiquidityDIDs(
export async function getHighestLiquidityDatatokens(
chainIds: number[]
): Promise<[string, number]> {
const didList: string[] = []
): Promise<string[]> {
const dtList: string[] = []
let highestLiquidityAssets: HighestLiquidityAssetsPool[] = []
for (const chain of chainIds) {
const queryContext = getQueryContext(Number(chain))
@ -603,22 +603,12 @@ export async function getHighestLiquidityDIDs(
fetchedPools.data.pools
)
}
highestLiquidityAssets
.sort((a, b) => a.oceanReserve - b.oceanReserve)
.reverse()
highestLiquidityAssets.sort((a, b) => b.oceanReserve - a.oceanReserve)
for (let i = 0; i < highestLiquidityAssets.length; i++) {
if (!highestLiquidityAssets[i].datatokenAddress) continue
const did = web3.utils
.toChecksumAddress(highestLiquidityAssets[i].datatokenAddress)
.replace('0x', 'did:op:')
didList.push(did)
dtList.push(highestLiquidityAssets[i].datatokenAddress)
}
const searchDids = JSON.stringify(didList)
.replace(/,/g, ' ')
.replace(/"/g, '')
.replace(/(\[|\])/g, '')
.replace(/(did:op:)/g, '0x')
return [searchDids, didList.length]
return dtList
}
export function calculateUserLiquidity(poolShare: PoolShare): number {
@ -628,7 +618,7 @@ export function calculateUserLiquidity(poolShare: PoolShare): number {
const datatokens =
(poolShare.balance / poolShare.poolId.totalShares) *
poolShare.poolId.datatokenReserve
const totalLiquidity = ocean + datatokens * poolShare.poolId.consumePrice
const totalLiquidity = ocean + datatokens * poolShare.poolId.spotPrice
return totalLiquidity
}
@ -648,6 +638,7 @@ export async function getAccountLiquidityInOwnAssets(
)
let totalLiquidity = 0
let totalOceanLiquidity = 0
for (const result of results) {
for (const poolShare of result.poolShares) {
const userShare = poolShare.balance / poolShare.poolId.totalShares