From 59d24a05d4033a3d2cdf8f34e2fca6a8a06e2c46 Mon Sep 17 00:00:00 2001 From: Juanma Hidalgo Date: Fri, 3 Jan 2025 14:51:00 +0100 Subject: [PATCH] feat: add logic to show the assets in the rental contract when asking nfts by owner --- src/metrics.ts | 5 +++-- src/ports/nfts/component.ts | 26 +++++++++++++++++++++++++- src/ports/nfts/landQueries.ts | 26 ++++++++++++++++++++------ src/ports/nfts/queries.ts | 2 +- 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/metrics.ts b/src/metrics.ts index 4cedd03..64fef58 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -1,10 +1,11 @@ import { IMetricsComponent } from '@well-known-components/interfaces' import { metricDeclarations as logsMetricsDeclarations } from '@well-known-components/logger' -import { getDefaultHttpMetrics, validateMetricsDeclaration } from '@well-known-components/metrics' +import { validateMetricsDeclaration } from '@well-known-components/metrics' +import { metricDeclarations as graphMetrics } from '@well-known-components/thegraph-component' export const metricDeclarations = { - ...getDefaultHttpMetrics(), ...logsMetricsDeclarations, + ...graphMetrics, test_ping_counter: { help: 'Count calls to ping', type: IMetricsComponent.CounterType, diff --git a/src/ports/nfts/component.ts b/src/ports/nfts/component.ts index 42daffd..7aaa40d 100644 --- a/src/ports/nfts/component.ts +++ b/src/ports/nfts/component.ts @@ -1,5 +1,7 @@ import { ListingStatus, NFTCategory, NFTFilters, RentalStatus } from '@dcl/schemas' import { fromNFTsAndOrdersToNFTsResult } from '../../adapters/nfts' +import { getEthereumChainId } from '../../logic/chainIds' +import { getMarketplaceContracts } from '../../logic/contracts' import { HttpError } from '../../logic/http/response' import { AppComponents } from '../../types' import { getOrdersQuery } from '../orders/queries' @@ -9,6 +11,8 @@ import { getNFTsQuery } from './queries' import { DBNFT, INFTsComponent } from './types' import { getNFTFilters } from './utils' +export const MAX_SUBGRAPH_QUERY_IN_ELEMENTS = 500 + export function createNFTsComponent(components: Pick): INFTsComponent { const { dappsDatabase: pg, config, rentals } = components @@ -31,7 +35,27 @@ export function createNFTsComponent(components: Pick contract.name === 'Estates') + const landContract = contracts.find(contract => contract.name === 'LAND') + const rentalAssets = await rentals.getRentalAssets({ + lessors: [filters.owner], + contractAddresses: [landContract?.address || '', estateContract?.address || ''], + isClaimed: false, + // In order to avoid pagination issues, we need to fetch all the assets for this owner in the rentals subgraph. + // The number is determined by the maximum recommended number of entries a filter_in query can have. + // It is improbable that any user will have more than MAX_SUBGRAPH_QUERY_IN_ELEMENTS Lands or Estates on rent. + // But in the case that they do, retrieved data might be incomplete 💀 + first: MAX_SUBGRAPH_QUERY_IN_ELEMENTS + }) + rentalAssetsIds = rentalAssets.map( + asset => `${asset.contractAddress === estateContract?.address ? 'estate' : 'parcel'}-${asset.contractAddress}-${asset.tokenId}` + ) + } + query = getNFTsQuery({ ...nftFilters, rentalAssetsIds }) const nfts = await client.query(query) const nftIds = nfts.rows.map(nft => nft.id) query = getOrdersQuery({ nftIds, status: ListingStatus.OPEN, owner }, 'combined_nft_orders') // Added a specific prefix to track this queries in the logs easily diff --git a/src/ports/nfts/landQueries.ts b/src/ports/nfts/landQueries.ts index 9ea5e1f..fafc55e 100644 --- a/src/ports/nfts/landQueries.ts +++ b/src/ports/nfts/landQueries.ts @@ -21,12 +21,26 @@ export function getNFTsSortBy(sortBy?: NFTSortBy) { } } -function getAllLANDWheres(filters: GetNFTsFilters) { - const { owner, minDistanceToPlaza, maxDistanceToPlaza, adjacentToRoad, minEstateSize, maxEstateSize, minPrice, maxPrice, ids, search } = - filters - const FILTER_BY_OWNER = owner - ? SQL` nft.owner_id IN (SELECT id FROM squid_marketplace.account WHERE address = ${owner.toLowerCase()}) ` - : null +function getAllLANDWheres(filters: GetNFTsFilters & { rentalAssetsIds?: string[] }) { + const { + owner, + minDistanceToPlaza, + maxDistanceToPlaza, + adjacentToRoad, + minEstateSize, + maxEstateSize, + minPrice, + maxPrice, + ids, + search, + rentalAssetsIds + } = filters + const FILTER_BY_OWNER = + owner && rentalAssetsIds?.length + ? SQL` (nft.owner_id IN (SELECT id FROM squid_marketplace.account WHERE address = ${owner.toLowerCase()}) OR nft.id = ANY(${rentalAssetsIds})) ` + : owner && !rentalAssetsIds?.length + ? SQL` nft.owner_id IN (SELECT id FROM squid_marketplace.account WHERE address = ${owner.toLowerCase()}) ` + : null const FILTER_BY_MIN_PRICE = minPrice ? SQL` (nft.search_order_price >= ${minPrice} OR (trades.assets -> 'received' ->> 'amount')::numeric(78) >= ${minPrice})` : null diff --git a/src/ports/nfts/queries.ts b/src/ports/nfts/queries.ts index 9cef7a5..af67421 100644 --- a/src/ports/nfts/queries.ts +++ b/src/ports/nfts/queries.ts @@ -315,7 +315,7 @@ export function getMainQuerySortByStatement(sortBy?: NFTSortBy) { } } -export function getNFTsQuery(nftFilters: GetNFTsFilters = {}, uncapped = false): SQLStatement { +export function getNFTsQuery(nftFilters: GetNFTsFilters & { rentalAssetsIds?: string[] } = {}, uncapped = false): SQLStatement { // The Recently Listed sort by is handled by a different CTE because it needs to join with the trades table if (nftFilters.isLand || nftFilters.category === NFTCategory.PARCEL || nftFilters.category === NFTCategory.ESTATE) { return nftFilters.isOnSale ? getLandsOnSaleQuery(nftFilters) : getAllLANDsQuery(nftFilters)