Skip to content

Commit

Permalink
feat: Fetch and add the utility property (#375)
Browse files Browse the repository at this point in the history
* feat: Fetch and add the utility property

* fix: Remove double quotes
  • Loading branch information
LautaroPetaccio authored May 2, 2024
1 parent 764cc45 commit 2ae497e
Show file tree
Hide file tree
Showing 16 changed files with 513 additions and 25 deletions.
1 change: 1 addition & 0 deletions .env.defaults
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CORS_ORIGIN=^http:\/\/localhost:[0-9]{1,10}$
CORS_METHOD=*
BUILDER_SERVER_URL=https://builder-api.decentraland.org
MARKETPLACE_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/decentraland/marketplace
COLLECTIONS_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/decentraland/collections-matic-mainnet
RENTALS_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/decentraland/rentals-ethereum-mainnet
Expand Down
1 change: 1 addition & 0 deletions .env.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CORS_ORIGIN=*
CORS_METHOD=*
BUILDER_SERVER_URL=https://builder-api.decentraland.org
MARKETPLACE_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/decentraland/marketplace
COLLECTIONS_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/decentraland/collections-matic-mainnet
RENTALS_SUBGRAPH_URL=https://api.thegraph.com/subgraphs/name/decentraland/rentals-ethereum-mainnet
Expand Down
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"printWidth": 80
},
"dependencies": {
"@dcl/schemas": "^11.4.0",
"@dcl/schemas": "^11.7.0",
"@well-known-components/env-config-provider": "^1.2.0",
"@well-known-components/http-requests-logger-component": "^2.1.0",
"@well-known-components/http-server": "^1.1.6",
Expand Down
12 changes: 11 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ import { createOwnersComponent } from './ports/owner/component'
import { createFavoritesComponent } from './ports/favorites/components'
import { ItemOptions } from './ports/items/types'
import { createCatalogComponent } from './ports/catalog/component'
import { createBuilderComponent } from './ports/builder'

async function initComponents(): Promise<AppComponents> {
// Default config
Expand Down Expand Up @@ -231,6 +232,13 @@ async function initComponents(): Promise<AppComponents> {
const marketplaceChainId = getMarketplaceChainId()
const collectionsChainId = getCollectionsChainId()

// Builder component
const builder = createBuilderComponent({
url: await config.requireString('BUILDER_SERVER_URL'),
logs,
fetcher: fetch,
})

// subgraphs
const marketplaceSubgraph = await createSubgraphComponent(
{ logs, config, fetch, metrics },
Expand Down Expand Up @@ -375,6 +383,7 @@ async function initComponents(): Promise<AppComponents> {
})

const collectionsNFTs = createNFTComponent({
builder,
subgraph: collectionsSubgraph,
fragmentName: 'collectionsFragment',
getFragment: getCollectionsFragment,
Expand Down Expand Up @@ -446,7 +455,7 @@ async function initComponents(): Promise<AppComponents> {
)

// items
const collectionsItems = createItemsComponent([
const collectionsItems = createItemsComponent({ builder }, [
{
subgraph: collectionsSubgraph,
network: Network.MATIC,
Expand Down Expand Up @@ -732,6 +741,7 @@ async function initComponents(): Promise<AppComponents> {

return {
config,
builder,
logs,
server,
statusChecks,
Expand Down
42 changes: 42 additions & 0 deletions src/ports/builder/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { URL } from 'url'
import {
IFetchComponent,
ILoggerComponent,
} from '@well-known-components/interfaces'
import { IBuilderComponent } from './types'

export function createBuilderComponent(options: {
url: string
logs: ILoggerComponent
fetcher: IFetchComponent
}): IBuilderComponent {
const { fetcher, url, logs } = options
const logger = logs.getLogger('builder-component')

return {
async getItemUtility(
collectionAddress: string,
itemId: string
): Promise<string | undefined> {
try {
const baseUrl = new URL(url)
baseUrl.pathname = `/v1/published-collections/${collectionAddress}/items/${itemId}/utility`
const response = await fetcher.fetch(baseUrl.toString())
if (!response.ok) {
throw new Error(
`Failed to fetch utility for item: ${response.status}`
)
}
const utility = (await response.json()) as {
data: { utility: string | null }
}
return utility.data.utility ?? undefined
} catch (_e) {
logger.info(
`Failed looking for the utility of the item: ${collectionAddress} - ${itemId}.`
)
return undefined
}
},
}
}
2 changes: 2 additions & 0 deletions src/ports/builder/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './component'
export * from './types'
6 changes: 6 additions & 0 deletions src/ports/builder/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface IBuilderComponent {
getItemUtility(
collectionAddress: string,
itemId: string
): Promise<string | undefined>
}
18 changes: 16 additions & 2 deletions src/ports/items/component.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { ChainId, ItemFilters, Network } from '@dcl/schemas'
import { ISubgraphComponent } from '@well-known-components/thegraph-component'
import { AssetsNetworks } from '../../types'
import { AppComponents, AssetsNetworks } from '../../types'
import { IItemsComponent, ItemFragment } from './types'
import { fromItemFragment, getItemsQuery, getSubgraph } from './utils'

export function createItemsComponent(
components: Pick<AppComponents, 'builder'>,
options: {
subgraph: ISubgraphComponent
network: AssetsNetworks
chainId: ChainId
}[]
): IItemsComponent {
const { builder } = components

async function fetch(filters: ItemFilters) {
const option = getSubgraph(filters, options)
if (!option) return []

const { subgraph, network, chainId } = option

if (filters.network && filters.network !== network) {
Expand All @@ -25,13 +27,25 @@ export function createItemsComponent(
const { items: fragments } = await subgraph.query<{
items: ItemFragment[]
}>(query)

const isFetchingASingleItem =
filters.contractAddresses?.length === 1 && filters.itemId

const items = fragments.map((fragment) =>
fromItemFragment(
fragment,
network as Network.ETHEREUM | Network.MATIC,
chainId
)
)

if (items.length > 0 && isFetchingASingleItem) {
items[0].utility = await builder.getItemUtility(
items[0].contractAddress,
items[0].itemId
)
}

return items
}

Expand Down
2 changes: 2 additions & 0 deletions src/ports/items/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './component'
export * from './types'
22 changes: 16 additions & 6 deletions src/ports/nfts/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { PoolClient } from 'pg'
import { NFTCategory, NFTFilters, NFTSortBy } from '@dcl/schemas'
import { IPgComponent } from '@well-known-components/pg-component'
import { ISubgraphComponent } from '@well-known-components/thegraph-component'
import { getMarketplaceChainId } from '../../logic/chainIds'
import {
getLatestSubgraphSchema,
getMarketplaceSubgraphNameChain,
} from '../../subgraphUtils'
import { IBuilderComponent } from '../builder'
import { INFTsComponent, NFTResult } from './types'
import {
getByTokenIdQuery,
Expand All @@ -11,14 +17,10 @@ import {
getFuzzySearchQueryForENS,
getQueryVariables,
} from './utils'
import { getMarketplaceChainId } from '../../logic/chainIds'
import {
getLatestSubgraphSchema,
getMarketplaceSubgraphNameChain,
} from '../../subgraphUtils'

export function createNFTComponent<T extends { id: string }>(options: {
subgraph: ISubgraphComponent
builder?: IBuilderComponent
db?: IPgComponent
listsServer?: string
fragmentName: string
Expand All @@ -31,6 +33,7 @@ export function createNFTComponent<T extends { id: string }>(options: {
}): INFTsComponent {
const {
subgraph,
builder,
db,
fragmentName,
getFragment,
Expand Down Expand Up @@ -163,7 +166,14 @@ export function createNFTComponent<T extends { id: string }>(options: {
if (fragments.length === 0) {
return null
} else {
return fromFragment(fragments[0], caller)
const nftResult = fromFragment(fragments[0], caller)
if (builder && nftResult.nft.itemId) {
nftResult.nft.utility = await builder.getItemUtility(
contractAddress,
nftResult.nft.itemId
)
}
return nftResult
}
}

Expand Down
27 changes: 21 additions & 6 deletions src/tests/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ import {
import { createOwnersComponent } from '../ports/owner/component'
import { createFavoritesComponent } from '../ports/favorites/components'
import { createCatalogComponent } from '../ports/catalog/component'
import { createBuilderComponent } from '../ports/builder'

// start TCP port for listeners
let lastUsedPort = 19000 + parseInt(process.env.JEST_WORKER_ID || '1') * 1000
Expand Down Expand Up @@ -375,14 +376,27 @@ export async function initComponents(): Promise<AppComponents> {
MARKETPLACE_FAVORITES_SERVER_URL
)

// Builder component
const BUILDER_SERVER_URL = await config.requireString('BUILDER_SERVER_URL')
const builder = createBuilderComponent({
fetcher: fetchComponent,
logs,
url: BUILDER_SERVER_URL,
})

// items
const collectionsItems = createItemsComponent([
const collectionsItems = createItemsComponent(
{
subgraph: collectionsSubgraph,
network: Network.MATIC,
chainId: collectionsChainId,
builder,
},
])
[
{
subgraph: collectionsSubgraph,
network: Network.MATIC,
chainId: collectionsChainId,
},
]
)

const items = createMergerComponent<Item, ItemFilters, ItemSortBy>({
sources: [
Expand Down Expand Up @@ -579,7 +593,7 @@ export async function initComponents(): Promise<AppComponents> {
const marketplacePrices = createPricesComponent({
subgraph: marketplaceSubgraph,
queryGetter: getMarketplacePricesQuery,
customValidation: getMarketplacePriceFiltersValidation
customValidation: getMarketplacePriceFiltersValidation,
})

const collectionsPrices = createPricesComponent({
Expand Down Expand Up @@ -625,6 +639,7 @@ export async function initComponents(): Promise<AppComponents> {
return {
config,
logs,
builder,
tracer,
server,
statusChecks,
Expand Down
Loading

0 comments on commit 2ae497e

Please sign in to comment.