Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API-91: type + subType fixes #1390

Merged
merged 2 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/endpoints/accounts/account.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ export class AccountController {
@ApiQuery({ name: 'from', description: 'Number of items to skip for the result set', required: false })
@ApiQuery({ name: 'size', description: 'Number of items to retrieve', required: false })
@ApiQuery({ name: 'type', description: 'Token type', required: false, enum: TokenType })
@ApiQuery({ name: 'subType', description: 'Token sub type', required: false, enum: NftSubType })
@ApiQuery({ name: 'search', description: 'Search by collection identifier', required: false })
@ApiQuery({ name: 'name', description: 'Search by token name', required: false })
@ApiQuery({ name: 'identifier', description: 'Search by token identifier', required: false })
Expand All @@ -253,6 +254,7 @@ export class AccountController {
@Query('from', new DefaultValuePipe(0), ParseIntPipe) from: number,
@Query('size', new DefaultValuePipe(25), ParseIntPipe) size: number,
@Query('type', new ParseEnumPipe(TokenType)) type?: TokenType,
@Query('subType', new ParseEnumPipe(NftSubType)) subType?: NftSubType,
@Query('search') search?: string,
@Query('name') name?: string,
@Query('identifier') identifier?: string,
Expand All @@ -262,7 +264,7 @@ export class AccountController {
@Query('mexPairType', new ParseEnumArrayPipe(MexPairType)) mexPairType?: MexPairType[],
): Promise<TokenWithBalance[]> {
try {
return await this.tokenService.getTokensForAddress(address, new QueryPagination({ from, size }), new TokenFilter({ type, search, name, identifier, identifiers, includeMetaESDT, mexPairType }));
return await this.tokenService.getTokensForAddress(address, new QueryPagination({ from, size }), new TokenFilter({ type, subType, search, name, identifier, identifiers, includeMetaESDT, mexPairType }));
} catch (error) {
this.logger.error(`Error in getAccountTokens for address ${address}`);
this.logger.error(error);
Expand Down
4 changes: 4 additions & 0 deletions src/endpoints/nfts/entities/nft.sub.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export enum NftSubType {
DynamicNonFungibleESDT = 'DynamicNonFungibleESDT',
DynamicSemiFungibleESDT = 'DynamicSemiFungibleESDT',
DynamicMetaESDT = 'DynamicMetaESDT',
None = '',
}

registerEnumType(NftSubType, {
Expand Down Expand Up @@ -35,5 +36,8 @@ registerEnumType(NftSubType, {
DynamicMetaESDT: {
description: 'Dynamic meta ESDT NFT type.',
},
None: {
description: '',
},
},
});
3 changes: 3 additions & 0 deletions src/endpoints/tokens/entities/token.filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { TokenType } from "src/common/indexer/entities";
import { TokenSort } from "./token.sort";
import { MexPairType } from "src/endpoints/mex/entities/mex.pair.type";
import { TokenAssetsPriceSourceType } from "src/common/assets/entities/token.assets.price.source.type";
import { NftSubType } from "../../nfts/entities/nft.sub.type";

export class TokenFilter {
constructor(init?: Partial<TokenFilter>) {
Expand All @@ -11,6 +12,8 @@ export class TokenFilter {

type?: TokenType;

subType?: NftSubType;

search?: string;

name?: string;
Expand Down
4 changes: 4 additions & 0 deletions src/endpoints/tokens/entities/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { TokenType } from "src/common/indexer/entities";
import { TokenAssets } from "../../../common/assets/entities/token.assets";
import { MexPairType } from "src/endpoints/mex/entities/mex.pair.type";
import { TokenOwnersHistory } from "./token.owner.history";
import { NftSubType } from "../../nfts/entities/nft.sub.type";

export class Token {
constructor(init?: Partial<Token>) {
Expand All @@ -13,6 +14,9 @@ export class Token {
@ApiProperty({ enum: TokenType })
type: TokenType = TokenType.FungibleESDT;

@ApiProperty({ enum: NftSubType })
subType: NftSubType = NftSubType.None;

@ApiProperty({ type: String })
identifier: string = '';

Expand Down
45 changes: 36 additions & 9 deletions src/endpoints/tokens/token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ import { TransferService } from "../transfers/transfer.service";
import { MexPairService } from "../mex/mex.pair.service";
import { MexPairState } from "../mex/entities/mex.pair.state";
import { MexTokenType } from "../mex/entities/mex.token.type";
import { NftSubType } from "../nfts/entities/nft.sub.type";

@Injectable()
export class TokenService {
private readonly logger = new OriginLogger(TokenService.name);
private readonly nftSubTypes = [NftSubType.DynamicNonFungibleESDT, NftSubType.DynamicMetaESDT, NftSubType.NonFungibleESDTv2, NftSubType.DynamicSemiFungibleESDT];

constructor(
private readonly esdtService: EsdtService,
private readonly indexerService: IndexerService,
Expand Down Expand Up @@ -113,7 +116,7 @@ export class TokenService {
}

async getTokens(queryPagination: QueryPagination, filter: TokenFilter): Promise<TokenDetailed[]> {
const { from, size } = queryPagination;
const {from, size} = queryPagination;

let tokens = await this.getFilteredTokens(filter);

Expand Down Expand Up @@ -141,6 +144,10 @@ export class TokenService {
tokens = tokens.filter(token => token.type === filter.type);
}

if (filter.subType) {
tokens = tokens.filter(token => token.subType.toString() === filter.subType?.toString());
}

if (filter.search) {
const searchLower = filter.search.toLowerCase();

Expand Down Expand Up @@ -350,11 +357,11 @@ export class TokenService {
if (TokenUtils.isNft(identifier)) {
const nftData = await this.gatewayService.getAddressNft(address, identifier);

tokenWithBalance = new TokenDetailedWithBalance({ ...token, ...nftData });
tokenWithBalance = new TokenDetailedWithBalance({...token, ...nftData});
} else {
const esdtData = await this.gatewayService.getAddressEsdt(address, identifier);

tokenWithBalance = new TokenDetailedWithBalance({ ...token, ...esdtData });
tokenWithBalance = new TokenDetailedWithBalance({...token, ...esdtData});
}

// eslint-disable-next-line require-await
Expand Down Expand Up @@ -398,6 +405,27 @@ export class TokenService {
continue;
}

if (esdt.type && this.nftSubTypes.includes(esdt.type)) {
switch (esdt.type as NftSubType) {
case NftSubType.DynamicNonFungibleESDT:
case NftSubType.NonFungibleESDTv2:
esdt.type = NftSubType.NonFungibleESDT;
esdt.subType = esdt.type;
break;
case NftSubType.DynamicMetaESDT:
esdt.type = NftType.MetaESDT;
esdt.subType = NftSubType.DynamicMetaESDT;
break;
case NftSubType.DynamicSemiFungibleESDT:
esdt.type = NftType.SemiFungibleESDT;
esdt.subType = NftSubType.DynamicSemiFungibleESDT;
break;
default:
esdt.subType = NftSubType.None;
break;
}
}

const tokenWithBalance = {
...token,
...esdt,
Expand Down Expand Up @@ -658,8 +686,6 @@ export class TokenService {
return result;
}



private async getLogo(identifier: string): Promise<TokenLogo | undefined> {
const assets = await this.assetsService.getTokenAssets(identifier);
if (!assets) {
Expand Down Expand Up @@ -712,7 +738,7 @@ export class TokenService {
return await this.cachingService.getOrSet(
CacheInfo.AllEsdtTokens.key,
async () => await this.getAllTokensRaw(),
CacheInfo.AllEsdtTokens.ttl
CacheInfo.AllEsdtTokens.ttl,
);
}

Expand Down Expand Up @@ -746,6 +772,7 @@ export class TokenService {
for (const collection of collections) {
tokens.push(new TokenDetailed({
type: TokenType.MetaESDT,
subType: collection.subType,
identifier: collection.collection,
name: collection.name,
timestamp: collection.timestamp,
Expand Down Expand Up @@ -908,7 +935,7 @@ export class TokenService {

private async getAllTokensFromApi(): Promise<TokenDetailed[]> {
try {
const { data } = await this.apiService.get(`${this.apiConfigService.getTokensFetchServiceUrl()}/tokens`, { params: { size: 10000 } });
const {data} = await this.apiService.get(`${this.apiConfigService.getTokensFetchServiceUrl()}/tokens`, {params: {size: 10000}});

return data;
} catch (error) {
Expand All @@ -921,9 +948,9 @@ export class TokenService {

private async getTotalTransactions(token: TokenDetailed): Promise<{ count: number, lastUpdatedAt: number } | undefined> {
try {
const count = await this.transactionService.getTransactionCount(new TransactionFilter({ tokens: [token.identifier, ...token.assets?.extraTokens ?? []] }));
const count = await this.transactionService.getTransactionCount(new TransactionFilter({tokens: [token.identifier, ...token.assets?.extraTokens ?? []]}));

return { count, lastUpdatedAt: new Date().getTimeInSeconds() };
return {count, lastUpdatedAt: new Date().getTimeInSeconds()};
} catch (error) {
this.logger.error(`An unhandled error occurred when getting transaction count for token '${token.identifier}'`);
this.logger.error(error);
Expand Down
1 change: 1 addition & 0 deletions src/test/unit/services/tokens.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,7 @@ describe('Token Service', () => {
mockNftCollections.forEach(collection => {
mockTokens.push(new TokenDetailed({
type: TokenType.MetaESDT,
subType: collection.subType,
identifier: collection.collection,
name: collection.name,
timestamp: collection.timestamp,
Expand Down
Loading