market/src/@utils/subgraph.ts

224 lines
5.5 KiB
TypeScript
Raw Normal View History

import { gql, OperationResult, TypedDocumentNode, OperationContext } from 'urql'
2022-08-02 11:53:22 +02:00
import { LoggerInstance } from '@oceanprotocol/lib'
2021-10-13 18:48:59 +02:00
import { getUrqlClientInstance } from '@context/UrqlProvider'
import { getOceanConfig } from './ocean'
import { AssetPreviousOrder } from '../@types/subgraph/AssetPreviousOrder'
import { OrdersData_orders as OrdersData } from '../@types/subgraph/OrdersData'
import { OpcFeesQuery as OpcFeesData } from '../@types/subgraph/OpcFeesQuery'
2022-08-02 11:53:22 +02:00
import { getPublishedAssets, getTopPublishers } from '@utils/aquarius'
export interface UserLiquidity {
Account metadata header (#776) * get all neded data for the header from 3box, aqua and subgraph * fix tvl display error * WIP metadata header styling * added more styling for the header * make page title optional so we can remove it on account page * stroke change for svg images and default values * more styling added to the header * fixed linter * added ocean balance to tvl * update styling for statistcs * fixed eror for go to my account from another account page * updated styling for mobile use * wip show more on explorer links and description * properly display read more for explorer links and description * replaced show more with 3box redirect on description * change accounts default picture and check links length before display element * use optional on links * grid cleanup, new number unit, split up stats * rename all the things, more profile header styling * visual hierarchy, improve image loading experience * layout flow & visual tweaks * more description * replaced account route with profile when accesing a profile by the eth address * use account id from url if exists when fetching data * bump @oceanprotocol/art to v3.2.0 * styling, fallbacks, edge case fixes * clean up Publisher atom, link to profile page * fixed issue when switching to my profile from another profile * output accountId, make it copyable, remove stats icons * render tweaks, markup cleanup * add 3box reference * mobile tabs spacing tweaks * text flow and spacing tweaks Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2021-09-01 13:56:34 +02:00
price: string
oceanBalance: string
}
2021-04-09 11:55:18 +02:00
export interface PriceList {
[key: string]: string
}
const PreviousOrderQuery = gql`
query AssetPreviousOrder($id: String!, $account: String!) {
orders(
first: 1
2022-01-31 13:41:58 +01:00
where: { datatoken: $id, payer: $account }
orderBy: createdTimestamp
orderDirection: desc
) {
createdTimestamp
tx
}
}
`
const UserTokenOrders = gql`
query OrdersData($user: String!) {
orders(
orderBy: createdTimestamp
orderDirection: desc
where: { consumer: $user }
) {
consumer {
id
}
2022-01-31 13:41:58 +01:00
datatoken {
id
2022-01-31 13:41:58 +01:00
address
symbol
}
consumerMarketToken {
address
symbol
}
createdTimestamp
tx
}
}
`
const OpcFeesQuery = gql`
query OpcFeesQuery($id: ID!) {
opc(id: $id) {
swapOceanFee
swapNonOceanFee
orderFee
providerFee
}
}
`
export function getSubgraphUri(chainId: number): string {
const config = getOceanConfig(chainId)
return config.subgraphUri
}
2021-07-22 14:01:30 +02:00
export function getQueryContext(chainId: number): OperationContext {
try {
const queryContext: OperationContext = {
url: `${getSubgraphUri(
Number(chainId)
)}/subgraphs/name/oceanprotocol/ocean-subgraph`,
requestPolicy: 'network-only'
}
return queryContext
} catch (error) {
LoggerInstance.error('Get query context error: ', error.message)
2021-07-22 14:01:30 +02:00
}
}
export async function fetchData(
2021-06-22 07:52:49 +02:00
query: TypedDocumentNode,
variables: any,
context: OperationContext
): Promise<any> {
2021-04-09 11:55:18 +02:00
try {
2021-06-22 07:52:49 +02:00
const client = getUrqlClientInstance()
const response = await client.query(query, variables, context).toPromise()
2021-04-09 11:55:18 +02:00
return response
} catch (error) {
LoggerInstance.error('Error fetchData: ', error.message)
}
return null
}
export async function fetchDataForMultipleChains(
query: TypedDocumentNode,
variables: any,
chainIds: number[]
): Promise<any[]> {
let datas: any[] = []
try {
for (const chainId of chainIds) {
const context: OperationContext = getQueryContext(chainId)
const response = await fetchData(query, variables, context)
if (!response || response.error) continue
datas = datas.concat(response?.data)
}
return datas
} catch (error) {
LoggerInstance.error('Error fetchDataForMultipleChains: ', error.message)
}
}
export async function getOpcFees(chainId: number) {
let opcFees
const variables = {
id: 1
}
const context = getQueryContext(chainId)
try {
const response: OperationResult<OpcFeesData> = await fetchData(
OpcFeesQuery,
variables,
context
)
opcFees = response?.data?.opc
} catch (error) {
LoggerInstance.error('Error getOpcFees: ', error.message)
throw Error(error.message)
}
return opcFees
}
export async function getPreviousOrders(
id: string,
account: string,
assetTimeout: string
): Promise<string> {
const variables = { id, account }
2021-06-22 07:52:49 +02:00
const fetchedPreviousOrders: OperationResult<AssetPreviousOrder> =
await fetchData(PreviousOrderQuery, variables, null)
2022-01-13 22:41:19 +01:00
if (fetchedPreviousOrders.data?.orders?.length === 0) return null
if (assetTimeout === '0') {
2022-01-13 22:41:19 +01:00
return fetchedPreviousOrders?.data?.orders[0]?.tx
} else {
const expiry =
2022-01-13 22:41:19 +01:00
fetchedPreviousOrders?.data?.orders[0]?.createdTimestamp * 1000 +
Number(assetTimeout) * 1000
if (Date.now() <= expiry) {
2022-01-13 22:41:19 +01:00
return fetchedPreviousOrders?.data?.orders[0]?.tx
} else {
return null
}
2021-04-09 11:55:18 +02:00
}
}
export async function getUserTokenOrders(
accountId: string,
chainIds: number[]
): Promise<OrdersData[]> {
const data: OrdersData[] = []
const variables = { user: accountId?.toLowerCase() }
try {
const tokenOrders = await fetchDataForMultipleChains(
UserTokenOrders,
variables,
chainIds
)
for (let i = 0; i < tokenOrders?.length; i++) {
tokenOrders[i].orders.forEach((tokenOrder: OrdersData) => {
data.push(tokenOrder)
})
}
return data
} catch (error) {
LoggerInstance.error('Error getUserTokenOrders', error.message)
}
}
export async function getUserSales(
accountId: string,
chainIds: number[]
): Promise<number> {
try {
const result = await getPublishedAssets(accountId, chainIds, null)
const { totalOrders } = result.aggregations
return totalOrders.value
} catch (error) {
LoggerInstance.error('Error getUserSales', error.message)
}
}
export async function getTopAssetsPublishers(
chainIds: number[],
nrItems = 9
): Promise<AccountTeaserVM[]> {
const publishers: AccountTeaserVM[] = []
const result = await getTopPublishers(chainIds, null)
const { topPublishers } = result.aggregations
for (let i = 0; i < topPublishers.buckets.length; i++) {
publishers.push({
address: topPublishers.buckets[i].key,
nrSales: parseInt(topPublishers.buckets[i].totalSales.value)
})
}
publishers.sort((a, b) => b.nrSales - a.nrSales)
return publishers.slice(0, nrItems)
}