Skip to content

Commit

Permalink
Merge pull request #202 from decentraland/fix/owner-queries
Browse files Browse the repository at this point in the history
feat: improve ownership queries
  • Loading branch information
juanmahidalgo authored Dec 10, 2024
2 parents 28db09b + d8adbe6 commit 39eb15b
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/ports/nfts/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function createNFTsComponent(components: Pick<AppComponents, 'dappsDataba
const nftsQuery = getNFTsQuery(nftFilters)
const nfts = await pg.query<DBNFT>(nftsQuery)
const nftIds = nfts.rows.map(nft => nft.id)
const query = getOrdersQuery({ nftIds, status: ListingStatus.OPEN })
const query = getOrdersQuery({ nftIds, status: ListingStatus.OPEN, owner })
const orders = await pg.query<DBOrder>(query)

const landNftIds = nfts.rows
Expand Down
33 changes: 22 additions & 11 deletions src/ports/nfts/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function getFilteredNFTCTE(nftFilters: GetNFTsFilters, uncapped = false): SQLSta
.append(SQL`)`)
}

function getFilteredEstateCTE(): SQLStatement {
function getFilteredEstateCTE(filters: GetNFTsFilters): SQLStatement {
return SQL`
, filtered_estate AS (
SELECT
Expand All @@ -137,13 +137,18 @@ function getFilteredEstateCTE(): SQLStatement {
FROM
squid_marketplace.estate est
LEFT JOIN squid_marketplace.parcel est_parcel ON est.id = est_parcel.estate_id
`.append(
filters.owner
? SQL` WHERE est.owner_id IN (SELECT id FROM squid_marketplace.account WHERE address = ${filters.owner.toLocaleLowerCase()}) `
: SQL``
).append(SQL`
GROUP BY
est.id, est.token_id, est.size, est.data_id
)
`
)
`)
}

function getParcelEstateDataCTE(): SQLStatement {
function getParcelEstateDataCTE(filters: GetNFTsFilters): SQLStatement {
return SQL`
, parcel_estate_data AS (
SELECT
Expand All @@ -154,11 +159,16 @@ function getParcelEstateDataCTE(): SQLStatement {
squid_marketplace.parcel par
LEFT JOIN squid_marketplace.estate par_est ON par.estate_id = par_est.id
LEFT JOIN squid_marketplace.data est_data ON par_est.data_id = est_data.id
`.append(
filters.owner
? SQL`WHERE par_est.owner_id IN (SELECT id FROM squid_marketplace.account WHERE address = ${filters.owner.toLocaleLowerCase()}) `
: SQL``
).append(SQL`
)
`
`)
}

function getTradesCTE(): SQLStatement {
function getTradesCTE(filters: GetNFTsFilters): SQLStatement {
return SQL`
, trades AS (
SELECT
Expand Down Expand Up @@ -227,10 +237,11 @@ function getTradesCTE(): SQLStatement {
LEFT JOIN squid_trades.trade as trade_status ON trade_status.signature = t.hashed_signature
LEFT JOIN squid_trades.signature_index as signer_signature_index ON LOWER(signer_signature_index.address) = LOWER(t.signer)
LEFT JOIN (select * from squid_trades.signature_index signature_index where LOWER(signature_index.address) IN ('0x2d6b3508f9aca32d2550f92b2addba932e73c1ff','0x540fb08edb56aae562864b390542c97f562825ba')) as contract_signature_index ON t.network = contract_signature_index.network
WHERE t.type = 'public_nft_order'
WHERE t.type = 'public_nft_order' `.append(filters.owner ? SQL` AND t.signer = ${filters.owner.toLocaleLowerCase()} ` : SQL``)
.append(SQL`
GROUP BY t.id, t.created_at, t.network, t.chain_id, t.signer, t.checks, contract_signature_index.index, signer_signature_index.index
)
`
`)
}

function getNFTLimitAndOffsetStatement(nftFilters?: GetNFTsFilters) {
Expand Down Expand Up @@ -275,9 +286,9 @@ export function getNFTsQuery(nftFilters: GetNFTsFilters = {}, uncapped = false):
}

return getFilteredNFTCTE(nftFilters, uncapped)
.append(getFilteredEstateCTE())
.append(getParcelEstateDataCTE())
.append(getTradesCTE())
.append(getFilteredEstateCTE(nftFilters))
.append(getParcelEstateDataCTE(nftFilters))
.append(getTradesCTE(nftFilters))
.append(
SQL`
SELECT
Expand Down
26 changes: 18 additions & 8 deletions src/ports/orders/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ContractName, getContract } from 'decentraland-transactions'
import { getEthereumChainId, getPolygonChainId } from '../../logic/chainIds'
import { getDBNetworks } from '../../utils'
import { MAX_ORDER_TIMESTAMP } from '../catalog/queries'
import { getTradesForTypeQuery } from '../trades/queries'
import { getTradesForTypeQueryWithFilters } from '../trades/queries'
import { getWhereStatementFromFilters } from '../utils'

function getOrdersSortByStatement(filters: OrderFilters): SQLStatement {
Expand Down Expand Up @@ -44,17 +44,23 @@ function getInnerOrdersLimitAndOffsetStatement(filters: OrderFilters) {
return SQL` LIMIT ${innerLimit}`
}

export function getTradesOrdersQuery(): string {
export function getTradesOrdersQuery(filters: OrderFilters): SQLStatement {
const marketplacePolygon = getContract(ContractName.OffChainMarketplace, getPolygonChainId())
const marketplaceEthereum = getContract(ContractName.OffChainMarketplace, getEthereumChainId())

return `
return SQL`
SELECT
id::text,
id::text as trade_id,
CASE
WHEN LOWER(network) = 'matic' then '${marketplacePolygon.address}'
ELSE '${marketplaceEthereum.address}'
WHEN LOWER(network) = 'matic' then '`
.append(marketplacePolygon.address)
.append(
SQL`'
ELSE '`
.append(marketplaceEthereum.address)
.append(
SQL`'
END AS marketplace_address,
assets -> 'sent' ->> 'category' as category,
assets -> 'sent' ->> 'contract_address' as nft_address,
Expand All @@ -73,7 +79,11 @@ export function getTradesOrdersQuery(): string {
EXTRACT(EPOCH FROM created_at) as updated_at,
EXTRACT(EPOCH FROM expires_at) as expires_at,
network
FROM (${getTradesForTypeQuery(TradeType.PUBLIC_NFT_ORDER)}) as trades`
FROM (`
.append(getTradesForTypeQueryWithFilters(TradeType.PUBLIC_NFT_ORDER, { owner: filters.owner }))
.append(SQL`) as trades`)
)
)
}

export function getLegacyOrdersQuery(): string {
Expand Down Expand Up @@ -153,7 +163,7 @@ export function getOrderAndTradeQueries(filters: OrderFilters & { nftIds?: strin

const orderTradesQuery = SQL`SELECT *, COUNT(*) OVER() as count `
.append(SQL`FROM (`)
.append(getTradesOrdersQuery())
.append(getTradesOrdersQuery(filters))
.append(SQL`) as order_trades`)
.append(getWhereStatementFromFilters(tradesFilters))
.append(commonQueryParts)
Expand Down Expand Up @@ -206,7 +216,7 @@ export function getOrdersCountQuery(filters: OrderFilters & { nftIds?: string[]
COUNT(*) OVER() AS trades_count
FROM (
`
.append(getTradesOrdersQuery())
.append(getTradesOrdersQuery(filters))
.append(
SQL`
) AS trades_filtered
Expand Down
1 change: 0 additions & 1 deletion src/ports/sales/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ function getLegacySalesQuery(filters: SaleFilters): SQLStatement {
}

const getNFTCTE = (filters: SaleFilters) => {
console.log('filters', filters)
const FILTER_BY_CONTRACT_ADDRESS = filters.contractAddress ? SQL` contract_address = ${filters.contractAddress.toLowerCase()} ` : null
const FILTER_BY_ITEM_ID = filters.itemId ? SQL` item_id = ${filters.itemId} ` : null
const FILTER_BY_TOKEN_ID = filters.tokenId ? SQL` token_id = ${filters.tokenId} ` : null
Expand Down
88 changes: 87 additions & 1 deletion src/ports/trades/queries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { keccak256 } from 'ethers'
import SQL, { SQLStatement } from 'sql-template-strings'
import { TradeAsset, ListingStatus, TradeAssetType, TradeAssetWithBeneficiary, TradeCreation, TradeType } from '@dcl/schemas'
import { TradeAsset, ListingStatus, TradeAssetType, TradeAssetWithBeneficiary, TradeCreation, TradeType, NFTFilters } from '@dcl/schemas'
import { ContractName, getContract } from 'decentraland-transactions'
import { getEthereumChainId, getPolygonChainId } from '../../logic/chainIds'

Expand Down Expand Up @@ -168,6 +168,92 @@ export function getTradesForTypeQuery(type: TradeType) {
`
}

export function getTradesForTypeQueryWithFilters(type: TradeType, filters: NFTFilters) {
const marketplacePolygon = getContract(ContractName.OffChainMarketplace, getPolygonChainId())
const marketplaceEthereum = getContract(ContractName.OffChainMarketplace, getEthereumChainId())
return SQL`
SELECT
t.id,
t.created_at,
t.signer,
t.expires_at,
t.checks,
t.network,
t.chain_id,
COUNT(*) OVER() as count,
json_object_agg(assets_with_values.direction, json_build_object(
'contract_address', assets_with_values.contract_address,
'direction', assets_with_values.direction,
'beneficiary', assets_with_values.beneficiary,
'extra', assets_with_values.extra,
'token_id', assets_with_values.token_id,
'item_id', assets_with_values.item_id,
'amount', assets_with_values.amount,
'creator', assets_with_values.creator,
'owner', assets_with_values.owner,
'category', assets_with_values.category,
'nft_id', assets_with_values.nft_id,
'issued_id', assets_with_values.issued_id,
'nft_name', assets_with_values.nft_name
)) as assets,
CASE
WHEN COUNT(CASE WHEN trade_status.action = 'cancelled' THEN 1 END) > 0 THEN 'cancelled'
WHEN (
(signer_signature_index.index IS NOT NULL AND signer_signature_index.index != (t.checks ->> 'signerSignatureIndex')::int)
OR (signer_signature_index.index IS NULL AND (t.checks ->> 'signerSignatureIndex')::int != 0)
) THEN 'cancelled'
WHEN (t.expires_at < now()::timestamptz(3)) THEN 'cancelled'
WHEN (
(contract_signature_index.index IS NOT NULL AND contract_signature_index.index != (t.checks ->> 'contractSignatureIndex')::int)
OR (contract_signature_index.index IS NULL AND (t.checks ->> 'contractSignatureIndex')::int != 0)
) THEN 'cancelled'
WHEN COUNT(CASE WHEN trade_status.action = 'executed' THEN 1 END) >= (t.checks ->> 'uses')::int then 'sold'
ELSE 'open'
END AS status
FROM marketplace.trades as t
JOIN (
SELECT
ta.trade_id,
ta.contract_address,
ta.direction,
ta.beneficiary,
ta.extra,
erc721_asset.token_id,
coalesce(item_asset.item_id, nft.item_blockchain_id::text) as item_id,
erc20_asset.amount,
item.creator,
account.address as owner,
nft.category,
nft.id as nft_id,
nft.issued_id as issued_id,
nft.name as nft_name
FROM marketplace.trade_assets as ta
LEFT JOIN marketplace.trade_assets_erc721 as erc721_asset ON ta.id = erc721_asset.asset_id
LEFT JOIN marketplace.trade_assets_erc20 as erc20_asset ON ta.id = erc20_asset.asset_id
LEFT JOIN marketplace.trade_assets_item as item_asset ON ta.id = item_asset.asset_id
LEFT JOIN squid_marketplace.item as item ON (ta.contract_address = item.collection_id AND item_asset.item_id = item.blockchain_id::text)
LEFT JOIN squid_marketplace.nft as nft ON (ta.contract_address = nft.contract_address AND erc721_asset.token_id = nft.token_id::text)
LEFT JOIN squid_marketplace.account as account ON (account.id = nft.owner_id)
) as assets_with_values ON t.id = assets_with_values.trade_id
LEFT JOIN squid_trades.trade as trade_status ON trade_status.signature = t.hashed_signature
LEFT JOIN squid_trades.signature_index as signer_signature_index ON LOWER(signer_signature_index.address) = LOWER(t.signer)
LEFT JOIN (select * from squid_trades.signature_index signature_index where LOWER(signature_index.address) IN ('`
.append(marketplaceEthereum.address.toLowerCase())
.append(SQL`'`)
.append(
SQL`,'`.append(marketplacePolygon.address.toLowerCase()).append(
SQL`')) as contract_signature_index ON t.network = contract_signature_index.network
WHERE t.type = '`
.append(type)
.append(
SQL`'`.append(filters.owner ? SQL` AND t.signer = ${filters.owner.toLowerCase()}` : SQL``).append(SQL`
GROUP BY t.id, t.created_at, t.network, t.chain_id, t.signer, t.checks, contract_signature_index.index, signer_signature_index.index
`)
)
)
)
}

export function getTradeAssetsWithValuesByHashedSignatureQuery(hashedSignature: string) {
return getTradeAssetsWithValuesQuery(SQL`t.hashed_signature = ${hashedSignature}`)
}

0 comments on commit 39eb15b

Please sign in to comment.