diff --git a/config/config.devnet-old.yaml b/config/config.devnet-old.yaml index 566c8e4ad..0acda1a78 100644 --- a/config/config.devnet-old.yaml +++ b/config/config.devnet-old.yaml @@ -22,7 +22,6 @@ flags: useRequestLogging: false useVmQueryTracing: false processNfts: true - indexer-v3: true collectionPropertiesFromGateway: false features: eventsNotifier: diff --git a/config/config.devnet.yaml b/config/config.devnet.yaml index 9b6ef1e53..66df9bc22 100644 --- a/config/config.devnet.yaml +++ b/config/config.devnet.yaml @@ -18,7 +18,6 @@ flags: useRequestLogging: false useVmQueryTracing: false processNfts: true - indexer-v3: true collectionPropertiesFromGateway: false features: eventsNotifier: @@ -165,4 +164,4 @@ inflation: - 719203 nftProcess: parallelism: 1 - maxRetries: 3 \ No newline at end of file + maxRetries: 3 diff --git a/config/config.e2e-mocked.mainnet.yaml b/config/config.e2e-mocked.mainnet.yaml index 9fccc3334..f2ffbd055 100644 --- a/config/config.e2e-mocked.mainnet.yaml +++ b/config/config.e2e-mocked.mainnet.yaml @@ -21,7 +21,6 @@ flags: useRequestCaching: true useKeepAliveAgent: true useTracing: false - indexer-v3: true collectionPropertiesFromGateway: false urls: self: 'https://api.multiversx.com' diff --git a/config/config.e2e.mainnet.yaml b/config/config.e2e.mainnet.yaml index 95b43449a..558ff31af 100644 --- a/config/config.e2e.mainnet.yaml +++ b/config/config.e2e.mainnet.yaml @@ -24,7 +24,6 @@ flags: useRequestCaching: true useKeepAliveAgent: true useTracing: false - indexer-v3: true collectionPropertiesFromGateway: false urls: self: 'https://api.multiversx.com' diff --git a/config/config.mainnet.yaml b/config/config.mainnet.yaml index 35212848d..020316e01 100644 --- a/config/config.mainnet.yaml +++ b/config/config.mainnet.yaml @@ -18,7 +18,6 @@ flags: useRequestLogging: false useVmQueryTracing: false processNfts: true - indexer-v3: false collectionPropertiesFromGateway: false features: eventsNotifier: @@ -169,4 +168,4 @@ inflation: - 719203 nftProcess: parallelism: 1 - maxRetries: 3 \ No newline at end of file + maxRetries: 3 diff --git a/config/config.testnet.yaml b/config/config.testnet.yaml index 7a59131d4..cd72ece09 100644 --- a/config/config.testnet.yaml +++ b/config/config.testnet.yaml @@ -18,7 +18,6 @@ flags: useRequestLogging: false useVmQueryTracing: false processNfts: true - indexer-v3: true collectionPropertiesFromGateway: false features: eventsNotifier: diff --git a/src/common/api-config/api.config.service.ts b/src/common/api-config/api.config.service.ts index 951de2dc1..aae84f9c3 100644 --- a/src/common/api-config/api.config.service.ts +++ b/src/common/api-config/api.config.service.ts @@ -367,10 +367,6 @@ export class ApiConfigService { return this.configService.get('features.processNfts.enabled') ?? this.configService.get('flags.processNfts') ?? false; } - getIsIndexerV3FlagActive(): boolean { - return this.configService.get('flags.indexer-v3') ?? false; - } - isGraphQlActive(): boolean { return this.configService.get('api.graphql') ?? false; } diff --git a/src/common/indexer/elastic/elastic.indexer.helper.ts b/src/common/indexer/elastic/elastic.indexer.helper.ts index 75e107bb0..6d7ca2e8f 100644 --- a/src/common/indexer/elastic/elastic.indexer.helper.ts +++ b/src/common/indexer/elastic/elastic.indexer.helper.ts @@ -83,51 +83,45 @@ export class ElasticIndexerHelper { .withMustMultiShouldCondition(Object.values(NftType), type => QueryType.Match('type', type)); if (address) { - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - elasticQuery = elasticQuery.withMustCondition(QueryType.Should( - [ - QueryType.Match('currentOwner', address), - QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTCreate', address)]), - QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTBurn', address)]), - QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTAddQuantity', address)]), - QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTUpdateAttributes', address)]), - QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTAddURI', address)]), - QueryType.Nested('roles', [new MatchQuery('roles.ESDTTransferRole', address)]), - ] - )); - } else { - elasticQuery = elasticQuery.withMustCondition(QueryType.Match('currentOwner', address)); - } + elasticQuery = elasticQuery.withMustCondition(QueryType.Should( + [ + QueryType.Match('currentOwner', address), + QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTCreate', address)]), + QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTBurn', address)]), + QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTAddQuantity', address)]), + QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTUpdateAttributes', address)]), + QueryType.Nested('roles', [new MatchQuery('roles.ESDTRoleNFTAddURI', address)]), + QueryType.Nested('roles', [new MatchQuery('roles.ESDTTransferRole', address)]), + ] + )); } if (filter.before || filter.after) { elasticQuery = elasticQuery.withDateRangeFilter('timestamp', filter.before, filter.after); } - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - if (filter.canCreate !== undefined) { - elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTCreate', address, filter.canCreate); - } + if (filter.canCreate !== undefined) { + elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTCreate', address, filter.canCreate); + } - if (filter.canBurn !== undefined) { - elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTBurn', address, filter.canBurn); - } + if (filter.canBurn !== undefined) { + elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTBurn', address, filter.canBurn); + } - if (filter.canAddQuantity !== undefined) { - elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTAddQuantity', address, filter.canAddQuantity); - } + if (filter.canAddQuantity !== undefined) { + elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTAddQuantity', address, filter.canAddQuantity); + } - if (filter.canUpdateAttributes !== undefined) { - elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTUpdateAttributes', address, filter.canUpdateAttributes); - } + if (filter.canUpdateAttributes !== undefined) { + elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTUpdateAttributes', address, filter.canUpdateAttributes); + } - if (filter.canAddUri !== undefined) { - elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTAddURI', address, filter.canAddUri); - } + if (filter.canAddUri !== undefined) { + elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTRoleNFTAddURI', address, filter.canAddUri); + } - if (filter.canTransferRole !== undefined) { - elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTTransferRole', address, filter.canTransferRole); - } + if (filter.canTransferRole !== undefined) { + elasticQuery = this.getRoleCondition(elasticQuery, 'ESDTTransferRole', address, filter.canTransferRole); } if (filter.excludeMetaESDT === true) { @@ -219,7 +213,7 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withMustCondition(QueryType.Should(filter.identifiers.map(identifier => QueryType.Match('identifier', identifier, QueryOperator.AND)))); } - if (filter.isWhitelistedStorage !== undefined && this.apiConfigService.getIsIndexerV3FlagActive()) { + if (filter.isWhitelistedStorage !== undefined) { elasticQuery = elasticQuery.withMustCondition(QueryType.Nested("data", [new MatchQuery("data.whiteListedStorage", filter.isWhitelistedStorage)])); } @@ -329,7 +323,7 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withMustMultiShouldCondition(filter.tokens, token => QueryType.Match('tokens', token, QueryOperator.AND)); } - if (filter.functions && filter.functions.length > 0 && this.apiConfigService.getIsIndexerV3FlagActive()) { + if (filter.functions && filter.functions.length > 0) { if (filter.functions.length === 1 && filter.functions[0] === '') { elasticQuery = elasticQuery.withMustNotExistCondition('function'); } else { @@ -459,10 +453,7 @@ export class ElasticIndexerHelper { if (address) { shouldQueries.push(QueryType.Match('sender', address)); shouldQueries.push(QueryType.Match('receiver', address)); - - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - shouldQueries.push(QueryType.Match('receivers', address)); - } + shouldQueries.push(QueryType.Match('receivers', address)); } const elasticQuery = ElasticQuery.create() @@ -484,7 +475,7 @@ export class ElasticIndexerHelper { .withMustMultiShouldCondition(filter.tokens, token => QueryType.Match('tokens', token, QueryOperator.AND)) .withDateRangeFilter('timestamp', filter.before, filter.after); - if (filter.functions && filter.functions.length > 0 && this.apiConfigService.getIsIndexerV3FlagActive()) { + if (filter.functions && filter.functions.length > 0) { if (filter.functions.length === 1 && filter.functions[0] === '') { elasticQuery = elasticQuery.withMustNotExistCondition('function'); } else { @@ -508,10 +499,7 @@ export class ElasticIndexerHelper { } if (filter.receivers) { - const keys = ['receiver']; - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - keys.push('receivers'); - } + const keys = ['receiver', 'receivers']; for (const receiver of filter.receivers) { for (const key of keys) { @@ -523,11 +511,7 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withMustMatchCondition('sender', filter.sender); if (filter.receivers) { - const keys = ['receiver']; - - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - keys.push('receivers'); - } + const keys = ['receiver', 'receivers']; const queries: AbstractQuery[] = []; @@ -542,11 +526,7 @@ export class ElasticIndexerHelper { } if (address) { - const keys: string[] = ['sender', 'receiver']; - - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - keys.push('receivers'); - } + const keys: string[] = ['sender', 'receiver', 'receivers']; elasticQuery = elasticQuery.withMustMultiShouldCondition(keys, key => QueryType.Match(key, address)); } @@ -655,7 +635,7 @@ export class ElasticIndexerHelper { elasticQuery = elasticQuery.withShouldCondition(QueryType.Match('receiver', filter.receiver)); } - if (filter.functions && filter.functions.length > 0 && this.apiConfigService.getIsIndexerV3FlagActive()) { + if (filter.functions && filter.functions.length > 0) { if (filter.functions.length === 1 && filter.functions[0] === '') { elasticQuery = elasticQuery.withMustNotExistCondition('function'); } else { diff --git a/src/common/indexer/elastic/elastic.indexer.service.ts b/src/common/indexer/elastic/elastic.indexer.service.ts index c7efb8b9e..0bc3b7f72 100644 --- a/src/common/indexer/elastic/elastic.indexer.service.ts +++ b/src/common/indexer/elastic/elastic.indexer.service.ts @@ -1,6 +1,5 @@ import { HttpStatus, Injectable } from "@nestjs/common"; import { BinaryUtils } from "@multiversx/sdk-nestjs-common"; -import { ApiService } from "@multiversx/sdk-nestjs-http"; import { ElasticService, ElasticQuery, QueryOperator, QueryType, QueryConditionOptions, ElasticSortOrder, ElasticSortProperty, TermsQuery, RangeGreaterThanOrEqual, MatchQuery } from "@multiversx/sdk-nestjs-elastic"; import { IndexerInterface } from "../indexer.interface"; import { ApiConfigService } from "src/common/api-config/api.config.service"; @@ -36,7 +35,6 @@ export class ElasticIndexerService implements IndexerInterface { private readonly apiConfigService: ApiConfigService, private readonly elasticService: ElasticService, private readonly indexerHelper: ElasticIndexerHelper, - private readonly apiService: ApiService, ) { } async getAccountsCount(filter: AccountQueryOptions): Promise { @@ -653,17 +651,12 @@ export class ElasticIndexerService implements IndexerInterface { } async getNftsForAddress(address: string, filter: NftFilter, pagination: QueryPagination): Promise { - let elasticQuery = this.indexerHelper.buildElasticNftFilter(filter, undefined, address) - .withPagination(pagination); - - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - elasticQuery = elasticQuery.withSort([ + const elasticQuery = this.indexerHelper.buildElasticNftFilter(filter, undefined, address) + .withPagination(pagination) + .withSort([ { name: 'timestamp', order: ElasticSortOrder.descending }, { name: 'tokenNonce', order: ElasticSortOrder.descending }, ]); - } else { - elasticQuery = elasticQuery.withSort([{ name: '_id', order: ElasticSortOrder.ascending }]); - } return await this.elasticService.getList('accountsesdt', 'identifier', elasticQuery); } @@ -760,22 +753,6 @@ export class ElasticIndexerService implements IndexerInterface { return undefined; } - private indexerV5Active: boolean | undefined = undefined; - - async isIndexerV5Active(): Promise { - if (this.indexerV5Active !== undefined) { - return this.indexerV5Active; - } - - const mappingsResult = await this.apiService.get(`${this.apiConfigService.getElasticUrl()}/tokens/_mappings`); - const mappings = mappingsResult.data?.tokens?.mappings?.properties ?? mappingsResult.data['tokens-000001']?.mappings?.properties; - - const currentOwnerType = mappings?.currentOwner?.type; - - this.indexerV5Active = currentOwnerType === 'keyword'; - return this.indexerV5Active; - } - async getCollectionsForAddress( address: string, filter: CollectionFilter, @@ -786,8 +763,6 @@ export class ElasticIndexerService implements IndexerInterface { types.push(NftType.MetaESDT); } - const isIndexerV5Active = await this.isIndexerV5Active(); - const elasticQuery = ElasticQuery.create() .withMustExistCondition('identifier') .withMustMatchCondition('address', address) @@ -806,7 +781,7 @@ export class ElasticIndexerService implements IndexerInterface { { collection: { terms: { - field: isIndexerV5Active ? 'token' : 'token.keyword', + field: 'token', }, }, }, diff --git a/src/endpoints/accounts/account.controller.ts b/src/endpoints/accounts/account.controller.ts index 92cdca1f3..82c66390b 100644 --- a/src/endpoints/accounts/account.controller.ts +++ b/src/endpoints/accounts/account.controller.ts @@ -27,7 +27,6 @@ import { AccountHistory } from "./entities/account.history"; import { AccountEsdtHistory } from "./entities/account.esdt.history"; import { EsdtDataSource } from '../esdt/entities/esdt.data.source'; import { TransferService } from '../transfers/transfer.service'; -import { ApiConfigService } from 'src/common/api-config/api.config.service'; import { Transaction } from '../transactions/entities/transaction'; import { ProviderStake } from '../stake/entities/provider.stake'; import { TokenDetailedWithBalance } from '../tokens/entities/token.detailed.with.balance'; @@ -74,7 +73,6 @@ export class AccountController { private readonly scResultService: SmartContractResultService, private readonly collectionService: CollectionService, private readonly transferService: TransferService, - private readonly apiConfigService: ApiConfigService, private readonly delegationService: DelegationService, ) { } @@ -973,10 +971,6 @@ export class AccountController { @Query('withOperations', new ParseBoolPipe) withOperations?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, ): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - const options = TransactionQueryOptions.applyDefaultOptions( size, { withScamInfo, withUsername, withBlockInfo, withOperations, withLogs, withActionTransferValue }); @@ -1032,10 +1026,6 @@ export class AccountController { @Query('after', ParseIntPipe) after?: number, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, ): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - return await this.transferService.getTransfersCount(new TransactionFilter({ address, senders: sender, @@ -1070,10 +1060,6 @@ export class AccountController { @Query('after', ParseIntPipe) after?: number, @Query('senderOrReceiver', ParseAddressPipe) senderOrReceiver?: string, ): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - return await this.transferService.getTransfersCount(new TransactionFilter({ address, senders: sender, diff --git a/src/endpoints/accounts/account.service.ts b/src/endpoints/accounts/account.service.ts index fa69bf327..df8183d11 100644 --- a/src/endpoints/accounts/account.service.ts +++ b/src/endpoints/accounts/account.service.ts @@ -7,13 +7,11 @@ import { AccountDeferred } from './entities/account.deferred'; import { QueryPagination } from 'src/common/entities/query.pagination'; import { AccountKey } from './entities/account.key'; import { DeployedContract } from './entities/deployed.contract'; -import { TransactionService } from '../transactions/transaction.service'; import { PluginService } from 'src/common/plugins/plugin.service'; import { AccountEsdtHistory } from "./entities/account.esdt.history"; import { AccountHistory } from "./entities/account.history"; import { StakeService } from '../stake/stake.service'; import { TransferService } from '../transfers/transfer.service'; -import { SmartContractResultService } from '../sc-results/scresult.service'; import { TransactionType } from '../transactions/entities/transaction.type'; import { AssetsService } from 'src/common/assets/assets.service'; import { TransactionFilter } from '../transactions/entities/transaction.filter'; @@ -48,16 +46,12 @@ export class AccountService { private readonly cachingService: CacheService, private readonly vmQueryService: VmQueryService, private readonly apiConfigService: ApiConfigService, - @Inject(forwardRef(() => TransactionService)) - private readonly transactionService: TransactionService, @Inject(forwardRef(() => PluginService)) private readonly pluginService: PluginService, @Inject(forwardRef(() => StakeService)) private readonly stakeService: StakeService, @Inject(forwardRef(() => TransferService)) private readonly transferService: TransferService, - @Inject(forwardRef(() => SmartContractResultService)) - private readonly smartContractResultService: SmartContractResultService, private readonly assetsService: AssetsService, private readonly usernameService: UsernameService, private readonly apiService: ApiService, @@ -217,18 +211,10 @@ export class AccountService { } async getAccountTxCount(address: string): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - return this.transactionService.getTransactionCountForAddress(address); - } - return await this.transferService.getTransfersCount(new TransactionFilter({ address, type: TransactionType.Transaction })); } async getAccountScResults(address: string): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - return await this.smartContractResultService.getAccountScResultsCount(address); - } - return await this.transferService.getTransfersCount(new TransactionFilter({ address, type: TransactionType.SmartContractResult })); } diff --git a/src/endpoints/collections/collection.service.ts b/src/endpoints/collections/collection.service.ts index b981f213d..8fd59355b 100644 --- a/src/endpoints/collections/collection.service.ts +++ b/src/endpoints/collections/collection.service.ts @@ -247,11 +247,7 @@ export class CollectionService { } async getNftCollectionRoles(elasticCollection: any): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - return await this.getNftCollectionRolesFromEsdtContract(elasticCollection.token); - } - - return this.getNftCollectionRolesFromElasticResponse(elasticCollection); + return await this.getNftCollectionRolesFromElasticResponse(elasticCollection); } async getNftCollectionRolesFromGateway(elasticCollection: any): Promise { diff --git a/src/endpoints/esdt/esdt.address.service.ts b/src/endpoints/esdt/esdt.address.service.ts index fb847c134..de7c1dfc2 100644 --- a/src/endpoints/esdt/esdt.address.service.ts +++ b/src/endpoints/esdt/esdt.address.service.ts @@ -1,4 +1,4 @@ -import { BadRequestException, forwardRef, Inject, Injectable } from "@nestjs/common"; +import { forwardRef, Inject, Injectable } from "@nestjs/common"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { QueryPagination } from "src/common/entities/query.pagination"; import { GatewayComponentRequest } from "src/common/gateway/entities/gateway.component.request"; @@ -100,10 +100,6 @@ export class EsdtAddressService { } async getCollectionsForAddress(address: string, filter: CollectionFilter, pagination: QueryPagination): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive() && (filter.canCreate !== undefined || filter.canBurn !== undefined || filter.canAddQuantity !== undefined || filter.canUpdateAttributes !== undefined || filter.canAddUri !== undefined || filter.canTransferRole !== undefined)) { - throw new BadRequestException('canCreate / canBurn / canAddQuantity / canUpdateAttributes / canAddUri / canTransferRole filter not supported when fetching account collections from elastic'); - } - const tokenCollections = await this.indexerService.getNftCollections(pagination, filter, address); const collectionsIdentifiers = tokenCollections.map((collection) => collection.token); @@ -155,27 +151,22 @@ export class EsdtAddressService { } } - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - for (const collection of collectionsWithRoles) { - if (collection.type === NftType.NonFungibleESDT) { - //@ts-ignore - delete collection.canAddQuantity; - } - - if (collection.timestamp === 0) { - // @ts-ignore - delete accountCollection.timestamp; - } + for (const collection of collectionsWithRoles) { + if (collection.type === NftType.NonFungibleESDT) { + //@ts-ignore + delete collection.canAddQuantity; } - return collectionsWithRoles; - } else { - await this.applyRolesToAccountCollections(address, collectionsWithRoles); + if (collection.timestamp === 0) { + // @ts-ignore + delete accountCollection.timestamp; + } } return collectionsWithRoles; } + //@ts-ignore ( TBD ) private async applyRolesToAccountCollections(address: string, collections: NftCollectionWithRoles[]): Promise { const rolesResult = await this.gatewayService.getAddressEsdtRoles(address); const roles = rolesResult.roles; diff --git a/src/endpoints/esdt/esdt.service.ts b/src/endpoints/esdt/esdt.service.ts index feb2fd2a4..7d1cb7b54 100644 --- a/src/endpoints/esdt/esdt.service.ts +++ b/src/endpoints/esdt/esdt.service.ts @@ -85,8 +85,7 @@ export class EsdtService { async getEsdtTokenPropertiesRaw(identifier: string): Promise { const getCollectionPropertiesFromGateway = this.apiConfigService.getCollectionPropertiesFromGateway(); - const isIndexerV5Active = await this.elasticIndexerService.isIndexerV5Active(); - if (isIndexerV5Active && !getCollectionPropertiesFromGateway) { + if (!getCollectionPropertiesFromGateway) { return await this.getEsdtTokenPropertiesRawFromElastic(identifier); } else { return await this.getEsdtTokenPropertiesRawFromGateway(identifier); @@ -176,8 +175,7 @@ export class EsdtService { } async getAllFungibleTokenProperties(): Promise { - const isIndexerV5Active = await this.elasticIndexerService.isIndexerV5Active(); - if (isIndexerV5Active && !this.apiConfigService.getCollectionPropertiesFromGateway()) { + if (!this.apiConfigService.getCollectionPropertiesFromGateway()) { return await this.getAllFungibleTokenPropertiesFromElastic(); } else { return await this.getAllFungibleTokenPropertiesFromGateway(); diff --git a/src/endpoints/nfts/nft.service.ts b/src/endpoints/nfts/nft.service.ts index ecf237dfd..1c357d8ef 100644 --- a/src/endpoints/nfts/nft.service.ts +++ b/src/endpoints/nfts/nft.service.ts @@ -365,11 +365,7 @@ export class NftService { } } - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - nft.isWhitelistedStorage = elasticNft.data.whiteListedStorage; - } else { - nft.isWhitelistedStorage = nft.url.startsWith(this.NFT_THUMBNAIL_PREFIX); - } + nft.isWhitelistedStorage = elasticNft.data.whiteListedStorage; } nfts.push(nft); diff --git a/src/endpoints/tokens/token.controller.ts b/src/endpoints/tokens/token.controller.ts index 4eb9f3a9a..60feeb3d0 100644 --- a/src/endpoints/tokens/token.controller.ts +++ b/src/endpoints/tokens/token.controller.ts @@ -12,7 +12,6 @@ import { Transaction } from "../transactions/entities/transaction"; import { TokenSupplyResult } from "./entities/token.supply.result"; import { TokenSort } from "./entities/token.sort"; import { SortTokens } from "src/common/entities/sort.tokens"; -import { ApiConfigService } from "src/common/api-config/api.config.service"; import { TransferService } from "../transfers/transfer.service"; import { QueryPagination } from "src/common/entities/query.pagination"; import { TokenFilter } from "./entities/token.filter"; @@ -31,7 +30,6 @@ export class TokenController { constructor( private readonly tokenService: TokenService, private readonly transactionService: TransactionService, - private readonly apiConfigService: ApiConfigService, private readonly transferService: TransferService, ) { } @@ -394,10 +392,6 @@ export class TokenController { @Query('withBlockInfo', new ParseBoolPipe) withBlockInfo?: boolean, @Query('withActionTransferValue', ParseBoolPipe) withActionTransferValue?: boolean, ): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - const isToken = await this.tokenService.isToken(identifier); if (!isToken) { throw new NotFoundException('Token not found'); @@ -451,10 +445,6 @@ export class TokenController { @Query('before', ParseIntPipe) before?: number, @Query('after', ParseIntPipe) after?: number, ): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - const isToken = await this.tokenService.isToken(identifier); if (!isToken) { throw new NotFoundException('Token not found'); @@ -490,10 +480,6 @@ export class TokenController { @Query('before', ParseIntPipe) before?: number, @Query('after', ParseIntPipe) after?: number, ): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - const isToken = await this.tokenService.isToken(identifier); if (!isToken) { throw new NotFoundException('Token not found'); diff --git a/src/endpoints/tokens/token.service.ts b/src/endpoints/tokens/token.service.ts index 163b0b707..4e30a6623 100644 --- a/src/endpoints/tokens/token.service.ts +++ b/src/endpoints/tokens/token.service.ts @@ -464,49 +464,31 @@ export class TokenService { } async getTokenRoles(identifier: string): Promise { - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - return await this.getTokenRolesFromElastic(identifier); - } - - return await this.esdtService.getEsdtAddressesRoles(identifier); + return await this.getTokenRolesFromElastic(identifier); } async getTokenRolesForIdentifierAndAddress(identifier: string, address: string): Promise { - if (this.apiConfigService.getIsIndexerV3FlagActive()) { - const token = await this.indexerService.getToken(identifier); + const token = await this.indexerService.getToken(identifier); - if (!token) { - return undefined; - } + if (!token) { + return undefined; + } - if (!token.roles) { - return undefined; - } + if (!token.roles) { + return undefined; + } - const addressRoles: TokenRoles = new TokenRoles(); - addressRoles.address = address; - for (const role of Object.keys(token.roles)) { - const addresses = token.roles[role].distinct(); - if (addresses.includes(address)) { - TokenHelpers.setTokenRole(addressRoles, role); - } + const addressRoles: TokenRoles = new TokenRoles(); + addressRoles.address = address; + for (const role of Object.keys(token.roles)) { + const addresses = token.roles[role].distinct(); + if (addresses.includes(address)) { + TokenHelpers.setTokenRole(addressRoles, role); } - - //@ts-ignore - delete addressRoles.address; - - return addressRoles; } - const tokenAddressesRoles = await this.esdtService.getEsdtAddressesRoles(identifier); - let addressRoles = tokenAddressesRoles?.find((role: TokenRoles) => role.address === address); - if (addressRoles) { - // clone - addressRoles = new TokenRoles(JSON.parse(JSON.stringify(addressRoles))); - - //@ts-ignore - delete addressRoles?.address; - } + //@ts-ignore + delete addressRoles.address; return addressRoles; } diff --git a/src/graphql/entities/transfers/transfers.query.ts b/src/graphql/entities/transfers/transfers.query.ts index 0fc3fdcbe..7138d97de 100644 --- a/src/graphql/entities/transfers/transfers.query.ts +++ b/src/graphql/entities/transfers/transfers.query.ts @@ -1,4 +1,3 @@ -import { HttpException, HttpStatus } from "@nestjs/common"; import { Args, Float, Query, Resolver } from "@nestjs/graphql"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { QueryPagination } from "src/common/entities/query.pagination"; @@ -17,10 +16,6 @@ export class TransferQuery { @Query(() => [Transaction], { name: "transfers", description: "Retrieve all transfers for the given input." }) public async getTransfers(@Args("input", { description: "Input to retreive the given transfers for." }) input: GetTransfersInput): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - const options = TransactionQueryOptions.applyDefaultOptions(input.size, { withScamInfo: input.withScamInfo, withUsername: input.withUsername }); return await this.transferService.getTransfers( @@ -42,10 +37,6 @@ export class TransferQuery { @Query(() => Float, { name: "transfersCount", description: "Retrieve all transfers count for the given input." }) public async getTransfersCount(@Args("input", { description: "Input to retrieve the given transfers count for." }) input: GetTransfersCountInput): Promise { - if (!this.apiConfigService.getIsIndexerV3FlagActive()) { - throw new HttpException('Endpoint not live yet', HttpStatus.NOT_IMPLEMENTED); - } - return await this.transferService.getTransfersCount(GetTransfersCountInput.resolve(input)); } } diff --git a/src/graphql/schema/schema.gql b/src/graphql/schema/schema.gql index a2b450417..31910231f 100644 --- a/src/graphql/schema/schema.gql +++ b/src/graphql/schema/schema.gql @@ -3649,8 +3649,14 @@ type TokenAssets { """Token assets price source object type.""" type TokenAssetsPriceSource { + """(Optional) path to fetch the price info in case of customUrl type""" + path: String + """Type of price source""" type: String + + """URL of price source in case of customUrl type""" + url: String } """TokenDetailed object type.""" diff --git a/src/main.ts b/src/main.ts index 72f8d64b1..9f148d904 100644 --- a/src/main.ts +++ b/src/main.ts @@ -173,7 +173,6 @@ async function bootstrap() { logger.log(`Use tracing: ${apiConfigService.getUseTracingFlag()}`); logger.log(`Process NFTs flag: ${apiConfigService.getIsProcessNftsFlagActive()}`); - logger.log(`Indexer v3 flag: ${apiConfigService.getIsIndexerV3FlagActive()}`); logger.log(`Staking v4 enabled: ${apiConfigService.isStakingV4Enabled()}`); logger.log(`Events notifier enabled: ${apiConfigService.isEventsNotifierFeatureActive()}`); logger.log(`Guest caching enabled: ${apiConfigService.isGuestCacheFeatureActive()}`); @@ -279,7 +278,7 @@ async function configurePublicApp(publicApp: NestExpressApplication, apiConfigSe const config = documentBuilder.build(); const options = { customSiteTitle: 'Multiversx API', - customCss: `.topbar-wrapper img + customCss: `.topbar-wrapper img { content:url(\'/img/mvx-ledger-icon-mint.png\'); width:100px; height:auto; } @@ -353,4 +352,3 @@ RedisClient.prototype.on_error = function (err: any) { // then we should try to reconnect. this.connection_gone('error', err); }; - diff --git a/src/test/unit/services/accounts.spec.ts b/src/test/unit/services/accounts.spec.ts index bd8e9eecf..659773a5a 100644 --- a/src/test/unit/services/accounts.spec.ts +++ b/src/test/unit/services/accounts.spec.ts @@ -88,7 +88,6 @@ describe('Account Service', () => { provide: ApiConfigService, useValue: { getVerifierUrl: jest.fn(), - getIsIndexerV3FlagActive: jest.fn(), getDelegationContractAddress: jest.fn(), getAuctionContractAddress: jest.fn(), getStakingContractAddress: jest.fn(), @@ -314,25 +313,10 @@ describe('Account Service', () => { }); describe('getAccountTxCount', () => { - it('should return account transactions count from transaction service if indexer-v3 is false', async () => { + it('should return account transactions count from transfer service', async () => { const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; const expectedTxCount = 100; - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(false); - jest.spyOn(transactionService, 'getTransactionCountForAddress').mockResolvedValue(expectedTxCount); - - const result = await service.getAccountTxCount(address); - - expect(transactionService.getTransactionCountForAddress).toHaveBeenCalledWith(address); - expect(transferService.getTransfersCount).not.toHaveBeenCalled(); - expect(result).toStrictEqual(expectedTxCount); - }); - - it('should return account transactions count from transfer service if indexer-v3 is true', async () => { - const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; - const expectedTxCount = 100; - - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(true); jest.spyOn(transferService, 'getTransfersCount').mockResolvedValue(expectedTxCount); const result = await service.getAccountTxCount(address); @@ -346,27 +330,11 @@ describe('Account Service', () => { }); describe('getAccountScResults', () => { - it('should return account smart contract results from smartContractResult service if indexer-v3 is false', - async () => { - const address = "erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz"; - const expectedTxCount = 100; - - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(false); - jest.spyOn(smartContractResultService, 'getAccountScResultsCount').mockResolvedValue(expectedTxCount); - - const result = await service.getAccountScResults(address); - - expect(smartContractResultService.getAccountScResultsCount).toHaveBeenCalledWith(address); - expect(transferService.getTransfersCount).not.toHaveBeenCalled(); - expect(result).toStrictEqual(expectedTxCount); - }); - - it('should return account smart contract results from transfer service if indexer-v3 is true', + it('should return account smart contract results from transfer service', async () => { const address = "erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz"; const expectedTxCount = 100; - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(true); jest.spyOn(transferService, 'getTransfersCount').mockResolvedValue(expectedTxCount); const result = await service.getAccountScResults(address); diff --git a/src/test/unit/services/api.config.spec.ts b/src/test/unit/services/api.config.spec.ts index f287aa84b..80dce0ab5 100644 --- a/src/test/unit/services/api.config.spec.ts +++ b/src/test/unit/services/api.config.spec.ts @@ -726,26 +726,6 @@ describe('API Config', () => { }); }); - describe("getIsIndexerV3FlagActive", () => { - it("should return indexer V3 flag active", () => { - jest - .spyOn(ConfigService.prototype, "get") - .mockImplementation(jest.fn(() => true)); - - const results = apiConfigService.getIsIndexerV3FlagActive(); - expect(results).toEqual(true); - }); - - it("should return default value because test simulates that indexer V3 flag active is not defined", () => { - jest - .spyOn(ConfigService.prototype, 'get') - .mockImplementation(jest.fn(() => undefined)); - - const results = apiConfigService.getIsIndexerV3FlagActive(); - expect(results).toEqual(false); - }); - }); - describe("getIsPublicApiActive", () => { it("should return is public api active flag", () => { jest diff --git a/src/test/unit/services/esdt.address.spec.ts b/src/test/unit/services/esdt.address.spec.ts index d0b30b427..778baa2f2 100644 --- a/src/test/unit/services/esdt.address.spec.ts +++ b/src/test/unit/services/esdt.address.spec.ts @@ -1,28 +1,21 @@ import { CacheService } from "@multiversx/sdk-nestjs-cache"; import { MetricsService } from "@multiversx/sdk-nestjs-monitoring"; -import { BadRequestException } from "@nestjs/common"; import { Test } from "@nestjs/testing"; import { ApiConfigService } from "src/common/api-config/api.config.service"; import { AssetsService } from "src/common/assets/assets.service"; -import { QueryPagination } from "src/common/entities/query.pagination"; import { GatewayService } from "src/common/gateway/gateway.service"; import { IndexerService } from "src/common/indexer/indexer.service"; import { ProtocolService } from "src/common/protocol/protocol.service"; import { CollectionService } from "src/endpoints/collections/collection.service"; import { CollectionFilter } from "src/endpoints/collections/entities/collection.filter"; -import { NftCollection } from "src/endpoints/collections/entities/nft.collection"; import { EsdtAddressService } from "src/endpoints/esdt/esdt.address.service"; import { EsdtService } from "src/endpoints/esdt/esdt.service"; import { NftFilter } from "src/endpoints/nfts/entities/nft.filter"; -import { NftType } from "src/endpoints/nfts/entities/nft.type"; import { NftExtendedAttributesService } from "src/endpoints/nfts/nft.extendedattributes.service"; -import { TokenAssetStatus } from "src/endpoints/tokens/entities/token.asset.status"; describe('EsdtAddressService', () => { let service: EsdtAddressService; let indexerService: IndexerService; - let apiConfigService: ApiConfigService; - let collectionService: CollectionService; let cacheService: CacheService; let metricsService: MetricsService; let protocolService: ProtocolService; @@ -45,7 +38,6 @@ describe('EsdtAddressService', () => { useValue: { getExternalMediaUrl: jest.fn(), - getIsIndexerV3FlagActive: jest.fn(), }, }, { @@ -107,8 +99,6 @@ describe('EsdtAddressService', () => { service = moduleRef.get(EsdtAddressService); indexerService = moduleRef.get(IndexerService); - apiConfigService = moduleRef.get(ApiConfigService); - collectionService = moduleRef.get(CollectionService); cacheService = moduleRef.get(CacheService); metricsService = moduleRef.get(MetricsService); protocolService = moduleRef.get(ProtocolService); @@ -212,129 +202,6 @@ describe('EsdtAddressService', () => { }); describe('EsdtAddressService - getCollectionsForAddress', () => { - const indexerCollectionMock = { - _id: 'XDAY23TEAM-f7a346', - name: 'XDAY2023TEAM', - ticker: 'XDAY23TEAM', - token: 'XDAY23TEAM-f7a346', - issuer: 'erd178ah2z70a442g9hrt39w2ld67lav62jq72gzp3r9tu5egz4hr4cswr5unp', - currentOwner: 'erd178ah2z70a442g9hrt39w2ld67lav62jq72gzp3r9tu5egz4hr4cswr5unp', - numDecimals: 0, - type: 'NonFungibleESDT', - timestamp: 1696923978, - ownersHistory: [ - { - address: 'erd178ah2z70a442g9hrt39w2ld67lav62jq72gzp3r9tu5egz4hr4cswr5unp', - timestamp: 1696923978, - }, - ], - properties: { - canMint: false, - canBurn: false, - canUpgrade: true, - canTransferNFTCreateRole: true, - canAddSpecialRoles: true, - canPause: true, - canFreeze: true, - canWipe: true, - canChangeOwner: false, - canCreateMultiShard: false, - }, - nft_hasTraitSummary: true, - roles: { - ESDTRoleNFTCreate: ['erd178ah2z70a442g9hrt39w2ld67lav62jq72gzp3r9tu5egz4hr4cswr5unp'], - ESDTTransferRole: ['erd178ah2z70a442g9hrt39w2ld67lav62jq72gzp3r9tu5egz4hr4cswr5unp'], - ESDTRoleNFTBurn: ['erd178ah2z70a442g9hrt39w2ld67lav62jq72gzp3r9tu5egz4hr4cswr5unp'], - }, - nft_hasRarities: false, - api_holderCount: 101, - api_isVerified: true, - api_nftCount: 131, - }; - - const propertiesToCollectionsMock: NftCollection = { - collection: 'XDAY23TEAM-f7a346', - type: NftType.NonFungibleESDT, - subType: undefined, - name: 'xPortalAchievements', - ticker: 'XDAY23TEAM', - owner: 'erd1lpc6wjh2hav6q50p8y6a44r2lhtnseqksygakjfgep6c9uduchkqphzu6t', - timestamp: 0, - canFreeze: true, - canWipe: true, - canPause: true, - canTransferNftCreateRole: true, - canChangeOwner: false, - canUpgrade: false, - canAddSpecialRoles: false, - decimals: undefined, - assets: { - website: 'https://xday.com', - description: - 'Test description.', - status: TokenAssetStatus.active, - pngUrl: 'https://media.elrond.com/tokens/asset/XDAY23TEAM-f7a346/logo.png', - name: '', - svgUrl: 'https://media.elrond.com/tokens/asset/XDAY23TEAM-f7a346/logo.svg', - extraTokens: [''], - ledgerSignature: '', - priceSource: undefined, - preferredRankAlgorithm: undefined, - lockedAccounts: undefined, - }, - scamInfo: undefined, - traits: [], - auctionStats: undefined, - isVerified: undefined, - holderCount: undefined, - nftCount: undefined, - }; - - it('should throw BadRequestException when IndexerV3Flag is inactive and specific filters are used', async () => { - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(false); - - const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; - const filter = { canCreate: true }; - - await expect(service.getCollectionsForAddress(address, filter, new QueryPagination())).rejects.toThrow(BadRequestException); - }); - - it('should return collections for a given address with IndexerV3Flag active', async () => { - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(true); - jest.spyOn(indexerService, 'getNftCollections').mockResolvedValue([indexerCollectionMock]); - jest.spyOn(collectionService, 'applyPropertiesToCollections').mockResolvedValue([propertiesToCollectionsMock]); - - const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; - const filter = new CollectionFilter(); - const pagination = new QueryPagination(); - - const results = await service.getCollectionsForAddress(address, filter, pagination); - - expect(results).toHaveLength(1); - expect(apiConfigService.getIsIndexerV3FlagActive).toHaveBeenCalled(); - expect(apiConfigService.getIsIndexerV3FlagActive).toHaveBeenCalledTimes(2); - expect(indexerService.getNftCollections).toHaveBeenCalledWith(pagination, filter, address); - expect(indexerService.getNftCollections).toHaveBeenCalledTimes(1); - expect(collectionService.applyPropertiesToCollections).toHaveBeenCalled(); - }); - - it('should correctly apply roles to collections for a given address with IndexerV3Flag active', async () => { - jest.spyOn(apiConfigService, 'getIsIndexerV3FlagActive').mockReturnValue(true); - jest.spyOn(indexerService, 'getNftCollections').mockResolvedValue([indexerCollectionMock]); - jest.spyOn(collectionService, 'applyPropertiesToCollections').mockResolvedValue([propertiesToCollectionsMock]); - - const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; - const filter = new CollectionFilter(); - const pagination = new QueryPagination(); - - const results = await service.getCollectionsForAddress(address, filter, pagination); - - expect(results).toHaveLength(1); - const firstCollection = results[0]; - expect(firstCollection.canTransfer).toBe(false); - expect(firstCollection.role.canBurn).toBe(false); - }); - it('should return cached ESDTs for a given address', async () => { const address = 'erd1qga7ze0l03chfgru0a32wxqf2226nzrxnyhzer9lmudqhjgy7ycqjjyknz'; const cachedEsdts = {