Summary
A user attempting to create a Linked Wearable collection using ApeChain encounters two bugs in CreateThirdPartyCollectionModal. The root cause is that several new ContractNetwork enum values (APE_MAINNET, APE_CALDERA, BASE_MAINNET, BASE_SEPOLIA, MONAD_MAINNET, MONAD_TESTNET) were added to @dcl/schemas but the Builder — and the upstream dependencies it relies on — were never updated to support them.
Status: ApeChain, Base, and Monad are not currently supported in the Builder. This issue is kept in the backlog until full upstream support is confirmed and ready.
Bugs
Bug 1 — Wrong label in the network dropdown
CreateThirdPartyCollectionModal.tsx:87 builds dropdown options from Object.values(ContractNetwork) and resolves labels via t('global.networks.${network}'). The global.networks section in en.json (lines 1012–1017) only has translations for mainnet, matic, sepolia, and amoy. The 6 new networks show raw enum keys (e.g. global.networks.ape_mainnet) instead of human-readable names.
Affected values: ape_mainnet, ape_caldera, base_mainnet, base_sepolia, monad_mainnet, monad_testnet
Bug 2 — Infinite loading spinner
In utils.ts:3-16, fromContractNetworkToChainId only handles Ethereum, Polygon, Amoy, and Sepolia — any other value throws Error: Invalid network synchronously.
In CreateThirdPartyCollectionModal.tsx:96-124, setIsCheckingContract(true) is called on line 96 and fromContractNetworkToChainId() is invoked around line 99, but the try block doesn't begin until line 108. When the function throws for an unsupported network, the error escapes the try/finally entirely — so the finally block that calls setIsCheckingContract(false) is never reached. The spinner hangs indefinitely with no error message shown to the user.
Bonus bug — isContractValid set incorrectly
validateContract (line 118) sets setIsContractValid(true) even when the contract fails the ERC-721/ERC-1155 interface check (only contractError is set in that case). This secondary logic bug may allow submission of an invalid contract depending on how the parent form consumes the state.
Root cause
ape_mainnet (and the other 5 new networks) were added to the ContractNetwork enum in @dcl/schemas without a corresponding ChainId entry, no RPC URL in decentraland-connect, and no i18n or Builder-side wiring.
Dependency gap:
@dcl/schemas ChainId enum has no entries for APE, Base, or Monad — the chain ID numbers exist only as inline comments in ContractNetwork source.
decentraland-connect's getRpcUrls covers only 9 chains and has no URLs for these networks.
- Even adding a
case APE_MAINNET in utils.ts would fail immediately — there is no valid ChainId to return and no RPC endpoint to use for contract validation.
- Downstream catalyst/lambdas-side validation for ApeChain mappings also needs verification.
Required implementation sequence (when ApeChain support is prioritized)
@dcl/schemas (upstream): Add ChainId.APE_MAINNET = 33139 (and Base/Monad if planned). Add a compile-time exhaustiveness guard — a contractNetworkToChainId: Record<ContractNetwork, ChainId> mapping — so TypeScript refuses to compile if any future ContractNetwork member lacks a matching ChainId entry. This prevents the gap from recurring silently.
decentraland-connect (upstream): Add RPC URLs for the new chains in getRpcUrls, keyed by the new ChainId values.
decentraland/builder:
- Bump
@dcl/schemas and decentraland-connect deps.
- Add cases to
fromContractNetworkToChainId() in utils.ts.
- Add
global.networks.* translation entries for all 6 new networks to en.json.
- Add
NetworkIcon / imgSrcByNetwork entries (icons to be provided by design).
- Move
setIsCheckingContract(true) and the provider construction inside the try block so unsupported/missing networks surface the existing contractError message instead of hanging (this defensive fix is independent and could be done sooner).
- Verify catalyst/lambdas-side support for ApeChain collection mappings.
Files involved (Builder)
| File |
Change needed |
src/components/Modals/CreateThirdPartyCollectionModal/CreateThirdPartyCollectionModal.tsx |
Move setIsCheckingContract(true) and provider construction inside try; fix setIsContractValid logic |
src/components/Modals/CreateThirdPartyCollectionModal/utils.ts |
Add cases to fromContractNetworkToChainId |
src/modules/translation/languages/en.json |
Add global.networks.* entries for new networks |
src/components/NetworkIcon/utils.ts |
Add icon entries for new networks |
Requested by Rocío Corral Mena via Slack
Summary
A user attempting to create a Linked Wearable collection using ApeChain encounters two bugs in
CreateThirdPartyCollectionModal. The root cause is that several newContractNetworkenum values (APE_MAINNET,APE_CALDERA,BASE_MAINNET,BASE_SEPOLIA,MONAD_MAINNET,MONAD_TESTNET) were added to@dcl/schemasbut the Builder — and the upstream dependencies it relies on — were never updated to support them.Bugs
Bug 1 — Wrong label in the network dropdown
CreateThirdPartyCollectionModal.tsx:87builds dropdown options fromObject.values(ContractNetwork)and resolves labels viat('global.networks.${network}'). Theglobal.networkssection inen.json(lines 1012–1017) only has translations formainnet,matic,sepolia, andamoy. The 6 new networks show raw enum keys (e.g.global.networks.ape_mainnet) instead of human-readable names.Affected values:
ape_mainnet,ape_caldera,base_mainnet,base_sepolia,monad_mainnet,monad_testnetBug 2 — Infinite loading spinner
In
utils.ts:3-16,fromContractNetworkToChainIdonly handles Ethereum, Polygon, Amoy, and Sepolia — any other value throwsError: Invalid networksynchronously.In
CreateThirdPartyCollectionModal.tsx:96-124,setIsCheckingContract(true)is called on line 96 andfromContractNetworkToChainId()is invoked around line 99, but thetryblock doesn't begin until line 108. When the function throws for an unsupported network, the error escapes thetry/finallyentirely — so thefinallyblock that callssetIsCheckingContract(false)is never reached. The spinner hangs indefinitely with no error message shown to the user.Bonus bug —
isContractValidset incorrectlyvalidateContract(line 118) setssetIsContractValid(true)even when the contract fails the ERC-721/ERC-1155 interface check (onlycontractErroris set in that case). This secondary logic bug may allow submission of an invalid contract depending on how the parent form consumes the state.Root cause
ape_mainnet(and the other 5 new networks) were added to theContractNetworkenum in@dcl/schemaswithout a correspondingChainIdentry, no RPC URL indecentraland-connect, and no i18n or Builder-side wiring.Dependency gap:
@dcl/schemasChainIdenum has no entries for APE, Base, or Monad — the chain ID numbers exist only as inline comments inContractNetworksource.decentraland-connect'sgetRpcUrlscovers only 9 chains and has no URLs for these networks.case APE_MAINNETinutils.tswould fail immediately — there is no validChainIdto return and no RPC endpoint to use for contract validation.Required implementation sequence (when ApeChain support is prioritized)
@dcl/schemas(upstream): AddChainId.APE_MAINNET = 33139(and Base/Monad if planned). Add a compile-time exhaustiveness guard — acontractNetworkToChainId: Record<ContractNetwork, ChainId>mapping — so TypeScript refuses to compile if any futureContractNetworkmember lacks a matchingChainIdentry. This prevents the gap from recurring silently.decentraland-connect(upstream): Add RPC URLs for the new chains ingetRpcUrls, keyed by the newChainIdvalues.decentraland/builder:@dcl/schemasanddecentraland-connectdeps.fromContractNetworkToChainId()inutils.ts.global.networks.*translation entries for all 6 new networks toen.json.NetworkIcon/imgSrcByNetworkentries (icons to be provided by design).setIsCheckingContract(true)and the provider construction inside thetryblock so unsupported/missing networks surface the existingcontractErrormessage instead of hanging (this defensive fix is independent and could be done sooner).Files involved (Builder)
src/components/Modals/CreateThirdPartyCollectionModal/CreateThirdPartyCollectionModal.tsxsetIsCheckingContract(true)and provider construction insidetry; fixsetIsContractValidlogicsrc/components/Modals/CreateThirdPartyCollectionModal/utils.tsfromContractNetworkToChainIdsrc/modules/translation/languages/en.jsonglobal.networks.*entries for new networkssrc/components/NetworkIcon/utils.tsRequested by Rocío Corral Mena via Slack