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-72: first integration of chain simulator #1381

Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
96d3a1c
added dockerfile, workflow and entrypoint (#1364)
dragos-rebegea Oct 29, 2024
a815b28
Add guardianData to GatewayComponentRequest in GatewayService (#1377)
cfaur09 Nov 12, 2024
74c71ea
API-72: first integration of chain simulator
bogdan-rosianu Nov 14, 2024
f6638e9
API-72: npm init
bogdan-rosianu Nov 14, 2024
1aaeeac
API-72: refactoring
bogdan-rosianu Nov 14, 2024
7bd5b43
API-72: fix workflow file + cs start script
bogdan-rosianu Nov 14, 2024
7e105f4
API-72: fix workflow file
bogdan-rosianu Nov 14, 2024
ccc4712
API-72: update chain simulator tests and configuration
cfaur09 Nov 14, 2024
2cc680f
Enhance e2e test workflow: add API startup delay and shutdown step; i…
cfaur09 Nov 14, 2024
ed50e0f
Replace accounts e2e tests with new blocks e2e tests for improved cov…
cfaur09 Nov 15, 2024
4672d97
Update blocks e2e test to filter by nonce 0 for accurate count valida…
cfaur09 Nov 15, 2024
b6ad48a
Update blocks e2e test to adjust epoch filter and add validation for …
cfaur09 Nov 15, 2024
2dee24d
Add e2e test for GET /blocks/latest endpoint with property and type v…
cfaur09 Nov 15, 2024
58b9539
Add e2e test for blocks count with high epoch and nonce values
cfaur09 Nov 15, 2024
b211e0b
Remove scheduledRootHash from expected properties and type validation…
cfaur09 Nov 15, 2024
38083fb
Add e2e tests for GET /blocks and GET /miniblocks endpoints with stat…
cfaur09 Nov 15, 2024
e5258e4
Add e2e tests for GET /miniblocks endpoint with pagination and type f…
cfaur09 Nov 15, 2024
9554a75
Add e2e tests for GET /rounds
cfaur09 Nov 15, 2024
7672364
small refactoring
cfaur09 Nov 15, 2024
1d0494d
small refactoring
cfaur09 Nov 15, 2024
09362f1
small refactoring_2
cfaur09 Nov 15, 2024
d511195
small refactoring_2
cfaur09 Nov 15, 2024
44d34c0
update file formatting
cfaur09 Nov 15, 2024
b8bf473
Create results.cs-e2e.ts
cfaur09 Nov 15, 2024
fa18b04
Update results.cs-e2e.ts
cfaur09 Nov 16, 2024
6b64688
Update results.cs-e2e.ts
cfaur09 Nov 16, 2024
874aa18
Add issueMultipleESDT + tokens.cs-e2e.ts
cfaur09 Nov 16, 2024
fce09a0
Update tokens.cs-e2e.ts
cfaur09 Nov 16, 2024
db89051
Update tokens.cs-e2e.ts
cfaur09 Nov 16, 2024
cd618d2
Update tokens.cs-e2e.ts
cfaur09 Nov 17, 2024
f7b19d8
Update tokens.cs-e2e.ts
cfaur09 Nov 17, 2024
92ce317
API-72: fix workflow file (#1385)
dragos-rebegea Nov 18, 2024
470a829
Merge main development (#1386)
dragos-rebegea Nov 18, 2024
820bbf2
Merge branch 'main' into development
dragos-rebegea Nov 18, 2024
9037a37
Development (#1387)
dragos-rebegea Nov 18, 2024
dfc65cf
add EOL
cfaur09 Nov 20, 2024
540331f
add stop-chain-simulator script
cfaur09 Nov 20, 2024
a4cbeb0
API-91: type + subType fixes (#1390)
bogdan-rosianu Nov 21, 2024
3733c7d
fix get profile (#1391)
dragos-rebegea Nov 22, 2024
9638379
Merge branch 'main' into development
dragos-rebegea Nov 22, 2024
83876fb
Merge pull request #1392 from multiversx/development
dragos-rebegea Nov 22, 2024
5cf7be0
fix fields query in transactions (#1397)
cfaur09 Nov 27, 2024
429c410
hotfix
bogdan-rosianu Nov 27, 2024
f8ec9c1
Merge pull request #1398 from multiversx/hotfix-empty-token-type-from…
bogdan-rosianu Nov 28, 2024
36dd6bc
Update load-tests.yml
bogdan-rosianu Nov 28, 2024
b7ee557
Merge pull request #1400 from multiversx/update-load-test-workflow-tr…
bogdan-rosianu Nov 28, 2024
3f1bb7f
Multi transfer EGLD-000000 support (#1401)
dragos-rebegea Dec 2, 2024
bf46995
Merge branch 'development' into API-72-first-integration-of-cs-in-api…
cfaur09 Dec 2, 2024
768cb95
refactorin + adding utils checks
cfaur09 Dec 2, 2024
d185d50
move chain simulator operations into utils
cfaur09 Dec 2, 2024
a29e5f2
add issueMultipleNftsCollections + env Alice Address
cfaur09 Dec 2, 2024
8b3384b
update tokens and collections tests + added bob address in config
cfaur09 Dec 2, 2024
cd3eddb
Update collections.cs-e2e.ts
cfaur09 Dec 2, 2024
41e7039
update docker file + overridable-config
cfaur09 Dec 3, 2024
41c5aa5
revert chainsimulator image
cfaur09 Dec 3, 2024
f604ab9
update chainsimulator image
cfaur09 Dec 3, 2024
de7a2ca
fixes after review
cfaur09 Dec 3, 2024
91290e3
Update .gitignore
cfaur09 Dec 3, 2024
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: 2 additions & 2 deletions .github/workflows/chain-simulator-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ jobs:

- name: Run e2e tests
run: npm run test:cs-e2e

- name: Stop API after tests
run: |
echo "Stopping the API..."
kill $(lsof -t -i:3001)
kill $(lsof -t -i:3001)
2 changes: 0 additions & 2 deletions .github/workflows/load-tests.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: Load Tests

on:
push:
branches: [main, development]
pull_request:
branches: [main, development]

Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ lerna-debug.log*

/src/plugins

.env
.env

# CS Environment variables
src/test/chain-simulator/config/.env
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@
"copy-e2e-mocked-mainnet-config:nix": "cp ./config/config.e2e-mocked.mainnet.yaml ./config/config.yaml",
"copy-e2e-mainnet-config:windows": "copy .\\config\\config.e2e.mainnet.yaml .\\config\\config.yaml",
"copy-e2e-mocked-mainnet-config:windows": "copy .\\config\\config.e2e-mocked.mainnet.yaml .\\config\\config.yaml",
"start-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" up -d --build"
"start-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" up -d --build",
"stop-chain-simulator": "docker compose -f \"src/test/chain-simulator/docker/docker-compose.yml\" down"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.54.0",
Expand Down Expand Up @@ -214,4 +215,4 @@
"node_modules"
]
}
}
}
3 changes: 1 addition & 2 deletions src/common/assets/assets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,7 @@ export class AssetsService {

const allAssets: { [key: string]: KeybaseIdentity } = {};
for (const asset of assets) {
const { identity, ...details } = asset;
allAssets[identity] = new KeybaseIdentity(details);
allAssets[asset.identity] = new KeybaseIdentity(asset);
}

return allAssets;
Expand Down
10 changes: 5 additions & 5 deletions src/common/keybase/keybase.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ export class KeybaseService {

async confirmIdentityProfiles(): Promise<void> {
const identities = await this.getDistinctIdentities();
const keybaseIdentities = identities.map(identity => this.getProfile(identity));
const keybaseIdentities = await Promise.all(identities.map(identity => this.getProfile(identity)));
await this.cachingService.set(CacheInfo.IdentityProfilesKeybases.key, keybaseIdentities, CacheInfo.IdentityProfilesKeybases.ttl);
}

getProfile(identity: string): KeybaseIdentity | null {
const keybaseLocal = this.getProfileFromAssets(identity);
async getProfile(identity: string): Promise<KeybaseIdentity | null> {
const keybaseLocal = await this.getProfileFromAssets(identity);
if (keybaseLocal) {
this.logger.log(`Got profile details from assets for identity '${identity}'`);
return keybaseLocal;
Expand All @@ -116,8 +116,8 @@ export class KeybaseService {
return identityInfo;
}

getProfileFromAssets(identity: string): KeybaseIdentity | null {
const info = this.readIdentityInfo(identity);
async getProfileFromAssets(identity: string): Promise<KeybaseIdentity | null> {
const info = await this.readIdentityInfo(identity);
if (!info) {
return null;
}
Expand Down
14 changes: 8 additions & 6 deletions src/endpoints/accounts/account.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ export class AccountController {
@UseInterceptors(DeepHistoryInterceptor)
@ApiOperation({ summary: 'Account details', description: 'Returns account details for a given address' })
@ApiQuery({ name: 'withGuardianInfo', description: 'Returns guardian data for a given address', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false })
@ApiQuery({ name: 'timestamp', description: 'Retrieve entry from timestamp', required: false, type: Number })
@ApiOkResponse({ type: AccountDetailed })
async getAccountDetails(
Expand Down 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 Expand Up @@ -613,7 +615,7 @@ export class AccountController {
@ApiQuery({ name: 'withScamInfo', description: 'Include scam info in the response', required: false, type: Boolean })
@ApiQuery({ name: 'computeScamInfo', description: 'Compute scam info in the response', required: false, type: Boolean })
@ApiQuery({ name: 'excludeMetaESDT', description: 'Exclude NFTs of type "MetaESDT" in the response', required: false, type: Boolean })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false })
@ApiQuery({ name: 'isScam', description: 'Filter by scam status', required: false, type: Boolean })
@ApiQuery({ name: 'scamType', description: 'Filter by type (scam/potentialScam)', required: false })
@ApiQuery({ name: 'timestamp', description: 'Retrieve entry from timestamp', required: false, type: Number })
Expand Down Expand Up @@ -747,7 +749,7 @@ export class AccountController {
@Get("/accounts/:address/nfts/:nft")
@UseInterceptors(DeepHistoryInterceptor)
@ApiOperation({ summary: 'Account NFT/SFT token details', description: 'Returns details about a specific fungible token for a given address' })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false })
@ApiQuery({ name: 'extract', description: 'Extract a specific field', required: false })
@ApiQuery({ name: 'timestamp', description: 'Retrieve entry from timestamp', required: false, type: Number })
@ApiOkResponse({ type: NftAccount })
Expand Down Expand Up @@ -849,7 +851,7 @@ export class AccountController {
@ApiQuery({ name: 'status', description: 'Status of the transaction (success / pending / invalid / fail)', required: false, enum: TransactionStatus })
@ApiQuery({ name: 'function', description: 'Filter transactions by function name', required: false })
@ApiQuery({ name: 'order', description: 'Sort order (asc/desc)', required: false, enum: SortOrder })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false })
@ApiQuery({ name: 'before', description: 'Before timestamp', required: false })
@ApiQuery({ name: 'after', description: 'After timestamp', required: false })
@ApiQuery({ name: 'round', description: 'Round number', required: false })
Expand Down Expand Up @@ -984,7 +986,7 @@ export class AccountController {
@ApiQuery({ name: 'before', description: 'Before timestamp', required: false })
@ApiQuery({ name: 'after', description: 'After timestamp', required: false })
@ApiQuery({ name: 'round', description: 'Round number', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false })
@ApiQuery({ name: 'relayer', description: 'Address of the relayer', required: false })
@ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean })
@ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transactions', required: false, type: Boolean })
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
6 changes: 3 additions & 3 deletions src/endpoints/tokens/token.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ export class TokenController {
}

@Get("/tokens/:identifier/roles/:address")
@ApiOperation({ summary: 'Token address roles', description: 'Returns roles detalils for a specific address of a given token', deprecated: true })
@ApiOperation({ summary: 'Token address roles', description: 'Returns roles details for a specific address of a given token', deprecated: true })
@ApiOkResponse({ type: TokenRoles })
@ApiNotFoundResponse({ description: 'Token not found' })
async getTokenRolesForAddress(
Expand Down Expand Up @@ -379,7 +379,7 @@ export class TokenController {
@ApiQuery({ name: 'before', description: 'Before timestamp', required: false })
@ApiQuery({ name: 'after', description: 'After timestamp', required: false })
@ApiQuery({ name: 'round', description: 'Filter by round number', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false })
@ApiQuery({ name: 'fields', description: 'List of fields to filter by', required: false, isArray: true, style: 'form', explode: false })
@ApiQuery({ name: 'withScamInfo', description: 'Returns scam information', required: false, type: Boolean })
@ApiQuery({ name: 'withUsername', description: 'Integrates username in assets for all addresses present in the transactions', required: false, type: Boolean })
@ApiQuery({ name: 'withBlockInfo', description: 'Returns sender / receiver block details', required: false, type: Boolean })
Expand Down Expand Up @@ -435,7 +435,7 @@ export class TokenController {
}

@Get("/tokens/:identifier/transfers/count")
@ApiOperation({ summary: 'Account transfer count', description: 'Return total count of tranfers triggerred by a user account (type = Transaction), as well as transfers triggerred by smart contracts (type = SmartContractResult)' })
@ApiOperation({ summary: 'Account transfer count', description: 'Return total count of transfers triggerred by a user account (type = Transaction), as well as transfers triggerred by smart contracts (type = SmartContractResult)' })
@ApiOkResponse({ type: Number })
@ApiQuery({ name: 'sender', description: 'Address of the transfer sender', required: false })
@ApiQuery({ name: 'receiver', description: 'Search by multiple receiver addresses, comma-separated', required: false })
Expand Down
66 changes: 57 additions & 9 deletions src/endpoints/tokens/token.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,14 @@ 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];
private readonly egldIdentifierInMultiTransfer = 'EGLD-000000';

constructor(
private readonly esdtService: EsdtService,
private readonly indexerService: IndexerService,
Expand Down Expand Up @@ -113,7 +117,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 All @@ -123,7 +127,9 @@ export class TokenService {
this.applyTickerFromAssets(token);
}

return tokens.map(item => ApiUtils.mergeObjects(new TokenDetailed(), item));
return tokens
.map(item => ApiUtils.mergeObjects(new TokenDetailed(), item))
.filter(t => t.identifier !== this.egldIdentifierInMultiTransfer);
}

applyTickerFromAssets(token: Token) {
Expand All @@ -141,6 +147,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 +360,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,11 +408,36 @@ 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,
};

if (esdt.type === '') { // empty type can come from gateway
tokenWithBalance.type = token.type;
}

tokensWithBalance.push(tokenWithBalance);
}

Expand Down Expand Up @@ -658,8 +693,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 +745,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 +779,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 @@ -807,6 +841,20 @@ export class TokenService {
token => token.transactions ?? 0,
);

const egldToken = new TokenDetailed({
identifier: this.egldIdentifierInMultiTransfer,
name: 'EGLD',
type: TokenType.FungibleESDT,
assets: await this.assetsService.getTokenAssets(this.egldIdentifierInMultiTransfer),
decimals: 18,
isLowLiquidity: false,
price: await this.dataApiService.getEgldPrice(),
supply: '0',
circulatingSupply: '0',
marketCap: 0,
});
tokens = [...tokens, egldToken];

return tokens;
}

Expand Down Expand Up @@ -921,9 +969,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
Loading
Loading