Skip to content

Commit 8d84b10

Browse files
authored
Migrate worlds API from broken entities/active to /about endpoint (#2)
The asset-bundle-registry /entities/active endpoint is no longer working. Use the worlds-content-server /about endpoint instead, which provides scene URNs to fetch entity data in a two-step flow.
1 parent 6a82e1b commit 8d84b10

1 file changed

Lines changed: 40 additions & 24 deletions

File tree

src/features/map/api/worldsApi.ts

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
const ASSET_BUNDLE_REGISTRY = 'https://asset-bundle-registry.decentraland.org'
21
const WORLDS_CONTENT_SERVER = 'https://worlds-content-server.decentraland.org'
32

43
export interface WorldInfo {
@@ -15,6 +14,12 @@ export interface WorldInfo {
1514
banSceneId: string | null // Scene ID at ban time (for detecting redeploys)
1615
}
1716

17+
interface WorldAboutResponse {
18+
configurations?: {
19+
scenesUrn?: string[]
20+
}
21+
}
22+
1823
interface WorldEntity {
1924
id: string
2025
type: string
@@ -36,49 +41,60 @@ interface WorldEntity {
3641
}
3742

3843
/**
39-
* Fetch world info from asset-bundle-registry
44+
* Fetch world info from worlds-content-server via /about endpoint
4045
*/
4146
export async function fetchWorldInfo(worldName: string): Promise<WorldInfo> {
4247
let normalizedName = worldName.trim().toLowerCase()
4348

44-
// Append .dcl.eth if not already present
4549
if (!normalizedName.endsWith('.dcl.eth') && !normalizedName.endsWith('.eth')) {
4650
normalizedName = `${normalizedName}.dcl.eth`
4751
}
4852

49-
const response = await fetch(`${ASSET_BUNDLE_REGISTRY}/entities/active`, {
50-
method: 'POST',
51-
headers: { 'Content-Type': 'application/json' },
52-
body: JSON.stringify({ pointers: [normalizedName] })
53-
})
53+
const aboutResponse = await fetch(
54+
`${WORLDS_CONTENT_SERVER}/world/${normalizedName}/about`
55+
)
5456

55-
if (!response.ok) {
56-
throw new Error(`Failed to fetch world info: ${response.status}`)
57+
if (!aboutResponse.ok) {
58+
throw new Error(`World "${normalizedName}" not found`)
5759
}
5860

59-
const entities: WorldEntity[] = await response.json()
60-
const entity = entities[0]
61+
const aboutData: WorldAboutResponse = await aboutResponse.json()
62+
const scenesUrn = aboutData.configurations?.scenesUrn
6163

62-
if (!entity) {
64+
if (!scenesUrn || scenesUrn.length === 0) {
6365
throw new Error(`World "${normalizedName}" not found`)
6466
}
6567

68+
const urn = scenesUrn[0]
69+
const hashMatch = urn.match(/urn:decentraland:entity:([^?]+)/)
70+
if (!hashMatch) {
71+
throw new Error(`Invalid scene URN format for "${normalizedName}"`)
72+
}
73+
const entityHash = hashMatch[1]
74+
75+
const entityResponse = await fetch(
76+
`${WORLDS_CONTENT_SERVER}/contents/${entityHash}`
77+
)
78+
79+
if (!entityResponse.ok) {
80+
throw new Error(`Failed to fetch entity for "${normalizedName}": ${entityResponse.status}`)
81+
}
82+
83+
const entity: WorldEntity = await entityResponse.json()
84+
6685
const metadata = entity.metadata
6786
const title = metadata?.display?.title || metadata?.worldConfiguration?.name || normalizedName
6887
const description = metadata?.display?.description || null
6988
const owner = metadata?.owner || null
7089
const tags = metadata?.tags || []
7190

72-
// Build thumbnail URL if available
73-
let thumbnail: string | null = null
74-
if (metadata?.display?.navmapThumbnail) {
75-
const thumbnailHash = entity.content?.find(
76-
c => c.file === metadata.display?.navmapThumbnail
77-
)?.hash
78-
if (thumbnailHash) {
79-
thumbnail = `${WORLDS_CONTENT_SERVER}/contents/${thumbnailHash}`
80-
}
81-
}
91+
const thumbnailFile = metadata?.display?.navmapThumbnail
92+
const thumbnailHash = thumbnailFile
93+
? entity.content?.find(c => c.file === thumbnailFile)?.hash
94+
: undefined
95+
const thumbnail = thumbnailHash
96+
? `${WORLDS_CONTENT_SERVER}/contents/${thumbnailHash}`
97+
: null
8298

8399
return {
84100
name: normalizedName,
@@ -87,7 +103,7 @@ export async function fetchWorldInfo(worldName: string): Promise<WorldInfo> {
87103
thumbnail,
88104
owner,
89105
tags,
90-
sceneId: entity.id,
106+
sceneId: entityHash,
91107
isBanned: false, // Will be updated by caller with local ban state
92108
banId: null,
93109
banReason: null,

0 commit comments

Comments
 (0)