• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

decentraland / lamb2 / 18977134646

31 Oct 2025 03:23PM UTC coverage: 80.33% (-1.4%) from 81.718%
18977134646

push

github

web-flow
Merge branch 'main' into docs/api

537 of 755 branches covered (71.13%)

Branch coverage included in aggregate %.

542 of 675 new or added lines in 36 files covered. (80.3%)

1 existing line in 1 file now uncovered.

1603 of 1909 relevant lines covered (83.97%)

36.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.29
/src/components.ts
1
import { l1Contracts, L1Network, L2Network } from '@dcl/catalyst-contracts'
16✔
2
import { createDotEnvConfigComponent } from '@well-known-components/env-config-provider'
16✔
3
import {
16✔
4
  createServerComponent,
5
  createStatusCheckComponent,
6
  instrumentHttpServerWithPromClientRegistry
7
} from '@well-known-components/http-server'
8
import { createLogComponent } from '@well-known-components/logger'
16✔
9
import { createMetricsComponent } from '@well-known-components/metrics'
16✔
10
import { createContentClient } from 'dcl-catalyst-client'
16✔
11
import { HTTPProvider } from 'eth-connect'
16✔
12
import { createCatalystsFetcher } from './adapters/catalysts-fetcher'
16✔
13
import { createContentServerUrl } from './adapters/content-server-url'
16✔
14
import {
16✔
15
  createEmoteDefinitionsFetcherComponent,
16
  createWearableDefinitionsFetcherComponent
17
} from './adapters/definitions-fetcher'
18
import { createElementsFetcherComponent, createLegacyElementsFetcherComponent } from './adapters/elements-fetcher'
16✔
19
import { createEntitiesFetcherComponent } from './adapters/entities-fetcher'
16✔
20
import { createNameDenylistFetcher } from './adapters/name-denylist-fetcher'
16✔
21
import { createPOIsFetcher } from './adapters/pois-fetcher'
16✔
22
import { createResourcesStatusComponent } from './adapters/resource-status'
16✔
23
import { createStatusComponent } from './adapters/status'
16✔
24
import { fetchBaseWearables } from './logic/fetch-elements/fetch-base-items'
16✔
25
import { fetchEmotes, fetchWearables } from './logic/fetch-elements/fetch-items'
16✔
26
import { fetchLands } from './logic/fetch-elements/fetch-lands'
16✔
27
import { fetchNames } from './logic/fetch-elements/fetch-names'
16✔
28
import { fetchAllThirdPartyWearables } from './logic/fetch-elements/fetch-third-party-wearables'
16✔
29
import { metricDeclarations } from './metrics'
16✔
30
import { createFetchComponent } from './ports/fetch'
16✔
31
import { createOwnershipCachesComponent } from './ports/ownership-caches'
16✔
32
import { createTheGraphComponent, TheGraphComponent } from './ports/the-graph'
16✔
33
import { AppComponents, BaseWearable, GlobalContext } from './types'
34
import { createThirdPartyProvidersGraphFetcherComponent } from './adapters/third-party-providers-graph-fetcher'
16✔
35
import { createThirdPartyProvidersStorage } from './logic/third-party-providers-storage'
16✔
36
import { createProfilesComponent } from './adapters/profiles'
16✔
37
import { IFetchComponent } from '@well-known-components/interfaces'
38
import { createAlchemyNftFetcher } from './adapters/alchemy-nft-fetcher'
16✔
39
import { createMarketplaceApiFetcher } from './adapters/marketplace-api-fetcher'
16✔
40
import { createThirdPartyContractRegistry } from './ports/ownership-checker/third-party-contract-registry'
16✔
41
import { createThirdPartyItemChecker } from './ports/ownership-checker/third-party-item-checker'
16✔
42
import { createParcelRightsComponent } from './adapters/parcel-rights-fetcher'
16✔
43
import { fetchNameOwner } from './logic/fetch-elements/fetch-name-owner'
16✔
44
import { fetchAllPermissions } from './logic/fetch-elements/fetch-permissions'
16✔
45

46
// Initialize all the components of the app
47
export async function initComponents(
16✔
48
  fetchComponent?: IFetchComponent,
49
  theGraphComponent?: TheGraphComponent
50
): Promise<AppComponents> {
51
  const config = await createDotEnvConfigComponent({ path: ['.env.default', '.env'] })
35✔
52
  const logs = await createLogComponent({})
35✔
53
  const server = await createServerComponent<GlobalContext>(
35✔
54
    { config, logs },
55
    {
56
      cors: {
57
        maxAge: 36000
58
      }
59
    }
60
  )
61
  const statusChecks = await createStatusCheckComponent({ server, config })
35✔
62
  const fetch = fetchComponent ? fetchComponent : await createFetchComponent()
35!
63
  const metrics = await createMetricsComponent(metricDeclarations, { config })
35✔
64
  await instrumentHttpServerWithPromClientRegistry({ server, metrics, config, registry: metrics.registry! })
35✔
65

66
  const contentServerUrl = await createContentServerUrl({ config })
35✔
67
  const content = createContentClient({ url: contentServerUrl, fetcher: fetch })
35✔
68

69
  const theGraph = theGraphComponent
35!
70
    ? theGraphComponent
71
    : await createTheGraphComponent({ config, logs, fetch, metrics })
72

73
  const ownershipCaches = await createOwnershipCachesComponent({ config })
35✔
74

75
  const wearableDefinitionsFetcher = await createWearableDefinitionsFetcherComponent({
35✔
76
    config,
77
    logs,
78
    content,
79
    contentServerUrl
80
  })
81

82
  // TODO: use content client for collection items fetching. prevent injecting contentServerUrl and fetch components.
83
  const entitiesFetcher = await createEntitiesFetcherComponent({ config, logs, content, contentServerUrl, fetch })
35✔
84

85
  // Create marketplace API fetcher for primary data source
86
  const marketplaceApiFetcher = await createMarketplaceApiFetcher({ config, fetch, logs })
35✔
87

88
  const emoteDefinitionsFetcher = await createEmoteDefinitionsFetcherComponent({
35✔
89
    config,
90
    logs,
91
    content,
92
    contentServerUrl
93
  })
94
  const baseWearablesFetcher = createElementsFetcherComponent<BaseWearable>(
35✔
95
    { logs, theGraph, marketplaceApiFetcher },
96
    async (_deps, _address) => {
NEW
97
      const elements = await fetchBaseWearables({ entitiesFetcher })
×
NEW
98
      return { elements, totalAmount: elements.length }
×
99
    }
100
  )
101

102
  const wearablesFetcher = createElementsFetcherComponent({ logs, theGraph, marketplaceApiFetcher }, fetchWearables)
35✔
103

104
  const emotesFetcher = createElementsFetcherComponent({ logs, theGraph, marketplaceApiFetcher }, fetchEmotes)
35✔
105

106
  const namesFetcher = createElementsFetcherComponent({ logs, theGraph, marketplaceApiFetcher }, fetchNames)
35✔
107

108
  const landsFetcher = createLegacyElementsFetcherComponent({ logs }, async (address) => fetchLands(theGraph, address))
35✔
109

110
  const landsPermissionsFetcher = createElementsFetcherComponent({ logs, theGraph }, async (_deps, address) => {
35✔
111
    const elements = await fetchAllPermissions({ theGraph }, address)
7✔
112
    return { elements, totalAmount: elements.length }
6✔
113
  })
114

115
  const resourcesStatusCheck = createResourcesStatusComponent({ logs })
35✔
116
  const status = await createStatusComponent({ logs, fetch })
35✔
117

118
  const l1Network: L1Network = ((await config.getString('ETH_NETWORK')) ?? 'mainnet') as L1Network
35✔
119
  const contracts = l1Contracts[l1Network]
35✔
120
  if (!contracts) {
35!
121
    throw new Error(`Invalid ETH_NETWORK ${l1Network}`)
×
122
  }
123
  const l2Network: L2Network = l1Network === 'mainnet' ? 'polygon' : 'amoy'
35!
124
  const l1Provider = new HTTPProvider(`https://rpc.decentraland.org/${encodeURIComponent(l1Network)}?project=lamb2`, {
35✔
125
    fetch: fetch.fetch
126
  })
127
  const l2Provider = new HTTPProvider(`https://rpc.decentraland.org/${encodeURIComponent(l2Network)}?project=lamb2`, {
35✔
128
    fetch: fetch.fetch
129
  })
130
  const catalystsFetcher = await createCatalystsFetcher({ l1Provider }, l1Network)
35✔
131
  const poisFetcher = await createPOIsFetcher({ l2Provider }, l2Network)
35✔
132
  const nameDenylistFetcher = await createNameDenylistFetcher({ l1Provider }, l1Network)
35✔
133
  const parcelRightsFetcher = await createParcelRightsComponent(
35✔
134
    {
135
      logs,
136
      theGraph
137
    },
138
    l1Network
139
  )
140

141
  const l1ThirdPartyContractRegistry = await createThirdPartyContractRegistry(logs, l1Provider, l1Network as any, '.')
35✔
142
  const l2ThirdPartyContractRegistry = await createThirdPartyContractRegistry(logs, l2Provider, l2Network as any, '.')
35✔
143
  const l1ThirdPartyItemChecker = await createThirdPartyItemChecker(
35✔
144
    { entitiesFetcher, logs },
145
    l1Provider,
146
    l1ThirdPartyContractRegistry
147
  )
148
  const l2ThirdPartyItemChecker = await createThirdPartyItemChecker(
35✔
149
    { entitiesFetcher, logs },
150
    l2Provider,
151
    l2ThirdPartyContractRegistry
152
  )
153

154
  const thirdPartyProvidersGraphFetcher = createThirdPartyProvidersGraphFetcherComponent({ theGraph })
35✔
155
  const thirdPartyProvidersStorage = await createThirdPartyProvidersStorage({
35✔
156
    logs,
157
    thirdPartyProvidersGraphFetcher
158
  })
159

160
  const thirdPartyWearablesFetcher = createElementsFetcherComponent(
35✔
161
    { logs, theGraph, marketplaceApiFetcher },
162
    async (_deps, address) => {
NEW
163
      const elements = await fetchAllThirdPartyWearables(
×
164
        { alchemyNftFetcher, contentServerUrl, thirdPartyProvidersStorage, fetch, entitiesFetcher, metrics },
165
        address
166
      )
NEW
167
      return { elements, totalAmount: elements.length }
×
168
    }
169
  )
170

171
  const alchemyNftFetcher = await createAlchemyNftFetcher({ config, logs, fetch })
35✔
172

173
  const nameOwnerFetcher = createElementsFetcherComponent({ logs, theGraph }, async (_deps, name) => {
35✔
NEW
174
    const { owner } = await fetchNameOwner({ theGraph }, name)
×
NEW
175
    return { elements: owner ? [{ owner }] : [], totalAmount: owner ? 1 : 0 }
×
176
  })
177

178
  const profiles = await createProfilesComponent({
35✔
179
    alchemyNftFetcher,
180
    metrics,
181
    content,
182
    contentServerUrl,
183
    entitiesFetcher,
184
    theGraph,
185
    config,
186
    fetch,
187
    ownershipCaches,
188
    thirdPartyProvidersStorage,
189
    logs,
190
    wearablesFetcher,
191
    emotesFetcher,
192
    namesFetcher,
193
    l1ThirdPartyItemChecker,
194
    l2ThirdPartyItemChecker
195
  })
196

197
  return {
35✔
198
    config,
199
    logs,
200
    server,
201
    statusChecks,
202
    fetch,
203
    metrics,
204
    content,
205
    theGraph,
206
    ownershipCaches,
207
    baseWearablesFetcher,
208
    wearablesFetcher,
209
    wearableDefinitionsFetcher,
210
    emoteDefinitionsFetcher,
211
    entitiesFetcher,
212
    thirdPartyWearablesFetcher,
213
    emotesFetcher,
214
    namesFetcher,
215
    landsFetcher,
216
    landsPermissionsFetcher,
217
    parcelRightsFetcher,
218
    thirdPartyProvidersGraphFetcher,
219
    thirdPartyProvidersStorage,
220
    contentServerUrl,
221
    resourcesStatusCheck,
222
    status,
223
    l1Provider,
224
    l2Provider,
225
    catalystsFetcher,
226
    poisFetcher,
227
    nameDenylistFetcher,
228
    profiles,
229
    alchemyNftFetcher,
230
    l1ThirdPartyItemChecker,
231
    l2ThirdPartyItemChecker,
232
    marketplaceApiFetcher,
233
    nameOwnerFetcher
234
  }
235
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc