Skip to content

Commit

Permalink
Merge pull request #238 from decentraland/feat/add-rented-assets
Browse files Browse the repository at this point in the history
feat: add logic to show the assets in the rental contract when asking nfts by owner
  • Loading branch information
juanmahidalgo authored Jan 3, 2025
2 parents 3cbff9d + 59d24a0 commit 31224ee
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 10 deletions.
5 changes: 3 additions & 2 deletions src/metrics.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
26 changes: 25 additions & 1 deletion src/ports/nfts/component.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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<AppComponents, 'dappsDatabase' | 'config' | 'rentals'>): INFTsComponent {
const { dappsDatabase: pg, config, rentals } = components

Expand All @@ -31,7 +35,27 @@ export function createNFTsComponent(components: Pick<AppComponents, 'dappsDataba
const client = await pg.getPool().connect()
let query
try {
query = getNFTsQuery(nftFilters)
let rentalAssetsIds: string[] = []
// When having the owner filter, we need to look for the rental assets with that lessor
if (filters.owner) {
const contracts = getMarketplaceContracts(getEthereumChainId())
const estateContract = contracts.find(contract => 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<DBNFT>(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
Expand Down
26 changes: 20 additions & 6 deletions src/ports/nfts/landQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ports/nfts/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 31224ee

Please sign in to comment.