Skip to content

Commit

Permalink
Merge pull request #1063 from multiversx/UpdateCollectionIndexing
Browse files Browse the repository at this point in the history
Fix collections retrieve
  • Loading branch information
danielailie authored Jan 18, 2024
2 parents 2421d26 + 27d6433 commit cdb73c4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 21 deletions.
21 changes: 21 additions & 0 deletions src/common/services/mx-communication/elastic-collection.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export interface CollectionElastic {
token: string;
name: string;
type: string;
ticker: string;
currentOwner: string;
timestamp: number;
properties: CollectionElasticProperties;
api_nftCount: number;
api_isVerified?: boolean;
}

export interface CollectionElasticProperties {
canTransferNFTCreateRole: boolean;
canPause: boolean;
canFreeze: boolean;
canWipe: boolean;
canMint: boolean;
canBurn: boolean;
canAddQuantity: boolean;
}
51 changes: 30 additions & 21 deletions src/modules/nftCollections/collections-getter.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Injectable } from '@nestjs/common';
import { orderBy } from 'lodash';
import { Address } from '@multiversx/sdk-core';
import { genericDescriptions } from 'src/config';
import { constants, genericDescriptions } from 'src/config';
import { Collection, CollectionAsset } from './models';
import { CollectionQuery } from './collection-query';
import { CollectionApi, MxApiService, MxIdentityService } from 'src/common';
import { MxApiService, MxElasticService, MxIdentityService } from 'src/common';
import { CacheInfo } from 'src/common/services/caching/entities/cache.info';
import { CollectionsNftsCountRedisHandler } from './collection-nfts-count.redis-handler';
import { CollectionsNftsRedisHandler } from './collection-nfts.redis-handler';
Expand All @@ -17,6 +17,10 @@ import { CollectionNftTrait } from '../nft-traits/models/collection-traits.model
import { DocumentDbService } from 'src/document-db/document-db.service';
import { BlacklistedCollectionsService } from '../blacklist/blacklisted-collections.service';
import { TrendingCollectionsService } from '../analytics/trending/trending-collections.service';
import { ELASTIC_TOKENS_INDEX } from 'src/utils/constants';
import { ElasticQuery, QueryType, ElasticSortOrder } from '@multiversx/sdk-nestjs-elastic';
import { NftTypeEnum } from '../assets/models';
import { CollectionElastic } from 'src/common/services/mx-communication/elastic-collection.model';

@Injectable()
export class CollectionsGetterService {
Expand All @@ -31,6 +35,7 @@ export class CollectionsGetterService {
private analyticsService: TrendingCollectionsService,
private documentDbService: DocumentDbService,
private blacklistedCollectionsService: BlacklistedCollectionsService,
private elasticService: MxElasticService,

Check warning on line 38 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L38

Added line #L38 was not covered by tests
) {}

async getCollections(
Expand Down Expand Up @@ -238,25 +243,19 @@ export class CollectionsGetterService {
}

public async getFullCollectionsRaw(): Promise<[Collection[], number]> {
const size = 25;
let from = 0;

const totalCount = await this.apiService.getCollectionsCount('?type=NonFungibleESDT,SemiFungibleESDT');
const query = this.getCollectionQuery();

Check warning on line 246 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L246

Added line #L246 was not covered by tests
let collectionsResponse: Collection[] = [];
do {
let mappedCollections = await this.getMappedCollections(from, size);
await this.elasticService.getScrollableList(ELASTIC_TOKENS_INDEX, 'token', query, async (items: CollectionElastic[]) => {
let mappedCollections = await this.getMappedCollections(items);

Check warning on line 249 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L248-L249

Added lines #L248 - L249 were not covered by tests

mappedCollections = await this.mapCollectionNftsCount(mappedCollections);

mappedCollections = await this.mapCollectionNfts(mappedCollections);

collectionsResponse.push(...mappedCollections);
});

from = from + size;
} while (from < totalCount && from <= 9975);
let uniqueCollections = [...new Map(collectionsResponse.map((item) => [item.collection, item])).values()];
uniqueCollections = orderBy(uniqueCollections, ['verified', 'creationDate'], ['desc', 'desc']);

return [uniqueCollections, uniqueCollections?.length];
}

Expand Down Expand Up @@ -309,21 +308,20 @@ export class CollectionsGetterService {
return [groupedCollections, groupedCollections.length];
}

private async getMappedCollections(page: number, size: number): Promise<Collection[]> {
const collections = await this.apiService.getCollections(new CollectionQuery().addPageSize(page, size).build());
const promisesCollections = collections?.map((collection): Promise<Collection> => this.mapCollection(collection));
private async getMappedCollections(items: CollectionElastic[]): Promise<Collection[]> {
const promisesCollections = items?.map((collection): Promise<Collection> => this.mapCollection(collection));
return await Promise.all(promisesCollections);
}

private async mapCollection(collection: CollectionApi): Promise<Collection> {
const ownerAddress = new Address(collection.owner);
private async mapCollection(collection: CollectionElastic): Promise<Collection> {
const ownerAddress = new Address(collection.currentOwner);

Check warning on line 317 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L317

Added line #L317 was not covered by tests
if (ownerAddress.isContractAddress()) {
const artist = await this.smartContractArtistService.getOrSetArtistForScAddress(collection.owner);
const artist = await this.smartContractArtistService.getOrSetArtistForScAddress(collection.currentOwner);

Check warning on line 319 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L319

Added line #L319 was not covered by tests
const followersCount = await this.idService.getFollowersCount(artist?.value?.owner);
return Collection.fromCollectionApi(collection, artist?.value?.owner, followersCount?.count);
return Collection.fromCollectionElastic(collection, artist?.value?.owner, followersCount?.count);
}
const followersCount = await this.idService.getFollowersCount(collection.owner);
return Collection.fromCollectionApi(collection, collection.owner, followersCount?.count);
const followersCount = await this.idService.getFollowersCount(collection.currentOwner);

Check warning on line 323 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L323

Added line #L323 was not covered by tests
return Collection.fromCollectionElastic(collection, collection.currentOwner, followersCount?.count);
}

private async mapCollectionNfts(localCollections: Collection[]) {
Expand Down Expand Up @@ -422,4 +420,15 @@ export class CollectionsGetterService {
}
return CollectionNftTrait.fromCollectionTraits(traitSummary.traitTypes);
}

private getCollectionQuery(): ElasticQuery {
return ElasticQuery.create()

Check warning on line 425 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L425

Added line #L425 was not covered by tests
.withMustNotExistCondition('identifier')
.withMustMultiShouldCondition([NftTypeEnum.NonFungibleESDT, NftTypeEnum.SemiFungibleESDT], (type) => QueryType.Match('type', type))

Check warning on line 427 in src/modules/nftCollections/collections-getter.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/collections-getter.service.ts#L427

Added line #L427 was not covered by tests
.withPagination({ from: 0, size: constants.getCollectionsFromElasticBatchSize })
.withSort([
{ name: 'api_isVerified', order: ElasticSortOrder.descending },
{ name: 'timestamp', order: ElasticSortOrder.descending },
]);
}
}
27 changes: 27 additions & 0 deletions src/modules/nftCollections/models/Collection.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CollectionNftTrait } from 'src/modules/nft-traits/models/collection-tra
import { CollectionAsset } from './CollectionAsset.dto';
import { CollectionSocial } from './CollectionSocial.dto';
import { CollectionVolumeLast24 } from 'src/modules/analytics/models/collection-volume';
import { CollectionElastic } from 'src/common/services/mx-communication/elastic-collection.model';

@ObjectType()
export class Collection {
Expand Down Expand Up @@ -121,6 +122,32 @@ export class Collection {
scamInfo: ScamInfo.fromScamInfoApi(collectionApi.scamInfo),
});
}

static fromCollectionElastic(collectionElastic: CollectionElastic, artistAddress?: string, followersCount?: number) {
if (!collectionElastic) {
return null;

Check warning on line 128 in src/modules/nftCollections/models/Collection.dto.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/models/Collection.dto.ts#L128

Added line #L128 was not covered by tests
}

return new Collection({

Check warning on line 131 in src/modules/nftCollections/models/Collection.dto.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/nftCollections/models/Collection.dto.ts#L131

Added line #L131 was not covered by tests
collection: collectionElastic.token,
artistAddress: artistAddress,
type: NftTypeEnum[collectionElastic.type],
ticker: collectionElastic.ticker,
ownerAddress: collectionElastic.currentOwner,
creationDate: collectionElastic.timestamp,
name: collectionElastic.name,
canTransferRole: collectionElastic.properties.canTransferNFTCreateRole,
canPause: collectionElastic.properties.canPause,
canBurn: collectionElastic.properties.canBurn,
canFreeze: collectionElastic.properties.canFreeze,
canWipe: collectionElastic.properties.canWipe,
canAddQuantity: collectionElastic.properties.canAddQuantity,
canCreate: collectionElastic.properties.canMint,
artistFollowersCount: followersCount,
nftsCount: collectionElastic.api_nftCount,
verified: collectionElastic.api_isVerified ?? false,
});
}
}

@ObjectType()
Expand Down

0 comments on commit cdb73c4

Please sign in to comment.