import { ethers } from 'ethers'; import { memoize, uniq } from 'lodash'; import config from '../config/config'; import { CollectionsRegistry } from '../contracts/CollectionsRegistry'; import { CollectionDefinition, DeployBlueprintName } from '../types'; import { getWalletConfigByChainId } from '../utils/chainUtils'; import { isZeroCollection } from '../utils/crypto'; const minuteResolver = (...args: unknown[]) => JSON.stringify(args + new Date().toISOString().slice(0, 16)); export const getCollectionIds = async (collectionsByChain: { [chainId: string]: Array; }) => { console.debug({ method: 'getCollectionIds', collectionsByChain }); const mappedCollections: Record> = {}; for (const collectionChainId of Object.keys(collectionsByChain)) { const chainConfig = getWalletConfigByChainId(collectionChainId); if (!chainConfig) { continue; } const collections = collectionsByChain[collectionChainId]; const collectionIds: Array = await CollectionsRegistry.getCollectionIds( chainConfig.chainId, collections ); mappedCollections[collectionChainId] = collections.reduce( (prev, curr, index) => { const collectionId = collectionIds[index]; if (isZeroCollection(collectionId)) { prev[curr] = null; } else { prev[curr] = collectionId; } return prev; }, {} as Record ); } return mappedCollections; }; export const getCollectionRecords = memoize( async ( ownerAddress: string, collectionIds: Array ): Promise<{ collections: CollectionDefinition[]; }> => { const collections = await Promise.allSettled( config.availableWallets.map(async ({ chainId }) => { const chainConfig = await getWalletConfigByChainId(chainId); if (!chainConfig) { return; } const ownedCollections = await CollectionsRegistry.listCollectionsPerOwner( chainId, ownerAddress ); const allCollectionIds = uniq([ ...collectionIds, ...ownedCollections.map((v) => v.id), ]); return Promise.all( allCollectionIds.map(async (collectionId) => { const record = await CollectionsRegistry.getRecord( chainConfig.chainId, collectionId ); if (record.addr === ethers.constants.AddressZero) { return null; } const collectionDefinition: CollectionDefinition = { collectionId, chainId, address: record.addr, name: record.userName, contractName: record.contractName as DeployBlueprintName, isNative: record.contractName === DeployBlueprintName.ERC721Native, availableChainIds: [], }; return collectionDefinition; }) ); }) ); const mappedCollections = collections .map((v) => v.status === 'fulfilled' ? v.value : (() => { console.warn({ method: 'getCollectionRecords', v, }); return false; })() ) .flat() .filter((v): v is CollectionDefinition => !!v); const chainIdPerCollectionId = mappedCollections.reduce( (prev, curr) => { if ( Array.isArray(prev[curr.collectionId]) && !prev[curr.collectionId].includes(curr.chainId) ) { prev[curr.collectionId].push(curr.chainId); } else { prev[curr.collectionId] = [curr.chainId]; } return prev; }, {} as Record> ); return { collections: mappedCollections.map((mappedCollection) => ({ ...mappedCollection, availableChainIds: chainIdPerCollectionId[mappedCollection.collectionId] || [], })), }; }, minuteResolver );