From d7e6165b93de6413de0cb7fd0b647c692e3290dd Mon Sep 17 00:00:00 2001 From: Maintain Date: Mon, 7 Oct 2024 15:58:24 +0700 Subject: [PATCH] Fix/total holders (#1207) * change total holder from account balance aggregate --> erc20_contract * split sync native. erc20 token --- .../queues/token/token.processor.ts | 94 ++++++++++++++++--- src/shared/constants/common.ts | 2 +- 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/src/components/queues/token/token.processor.ts b/src/components/queues/token/token.processor.ts index 7b875baa..beb5e124 100644 --- a/src/components/queues/token/token.processor.ts +++ b/src/components/queues/token/token.processor.ts @@ -62,7 +62,7 @@ export class TokenProcessor implements OnModuleInit { QUEUES.TOKEN.JOB_SYNC_ASSET, { explorer }, { - repeat: { cron: `${index + 1}0 * * * * *` }, + repeat: { cron: `${(index + 1) % 6}0 * * * * *` }, }, ); this.tokenQueue.add( @@ -236,10 +236,10 @@ export class TokenProcessor implements OnModuleInit { @Process(QUEUES.TOKEN.JOB_SYNC_NATIVE_ASSET_HOLDER) async syncNativeAssetHolder(job: Job): Promise { try { - const listHolderStatistic = await this.getHolders(job.data.explorer, [ - ASSETS_TYPE.IBC, - ASSETS_TYPE.NATIVE, - ]); + const listHolderStatistic = await this.getNativeHolders( + job.data.explorer, + [ASSETS_TYPE.IBC, ASSETS_TYPE.NATIVE], + ); await this.upsertTokenHolderStatistic(listHolderStatistic); } catch (error) { @@ -261,7 +261,42 @@ export class TokenProcessor implements OnModuleInit { } } - async getHolders( + async getErc20Holders( + explorer: Explorer, + type: string[], + ): Promise { + const listHolder: TokenHolderStatistic[] = []; + const nativeAsset = await this.assetsRepository.find({ + where: { + type: In(type), + explorer: { id: explorer.id }, + }, + }); + + const totalHolders = await this.getErc20HolderWithPagination( + nativeAsset, + explorer, + ); + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + for (const [_index, asset] of nativeAsset.entries()) { + const newTotalHolder = + totalHolders.filter((f) => f.address === asset.denom)[0] + ?.total_holder || 0; + + const newHolderStatistic = new TokenHolderStatistic(); + newHolderStatistic.id = null; + newHolderStatistic.asset = asset; + newHolderStatistic.totalHolder = newTotalHolder; + newHolderStatistic.date = new Date(); + + listHolder.push(newHolderStatistic); + } + + return listHolder; + } + + async getNativeHolders( explorer: Explorer, type: string[], ): Promise { @@ -273,7 +308,7 @@ export class TokenProcessor implements OnModuleInit { }, }); - const totalHolders = await this.getHolderWithPagination( + const totalHolders = await this.getNativeHolderWithPagination( nativeAsset, explorer, ); @@ -361,9 +396,10 @@ export class TokenProcessor implements OnModuleInit { async syncErc20AssetHolder(job: Job): Promise { try { const erc20Asset = await this.getNewErc20Info(job.data.explorer); - const listHolderStatistic = await this.getHolders(job.data.explorer, [ - ASSETS_TYPE.ERC20, - ]); + const listHolderStatistic = await this.getErc20Holders( + job.data.explorer, + [ASSETS_TYPE.ERC20], + ); await this.assetsRepository.save(erc20Asset); await this.upsertTokenHolderStatistic(listHolderStatistic); @@ -433,7 +469,43 @@ export class TokenProcessor implements OnModuleInit { return result; } - async getHolderWithPagination(assets: Asset[], explorer: Explorer) { + async getErc20HolderWithPagination(assets: Asset[], explorer: Explorer) { + const totalHolders = []; + let page = 0; + let index = 0; + const limit = INDEXER_API_V2.MAX_REQUEST; + do { + index = page * limit; + const subQuery = `erc20_contract(limit: $limit, offset: $offset) { + total_holder + address + }`; + + const query = util.format( + INDEXER_API_V2.GRAPH_QL.BASE_QUERY, + explorer.chainDb, + subQuery, + ); + const graphqlQueryTotalHolder: any = { + query, + operationName: INDEXER_API_V2.OPERATION_NAME.BASE_QUERY, + variables: { limit: limit }, + }; + + graphqlQueryTotalHolder.variables.offset = index; + + const holders = ( + await this.serviceUtil.fetchDataFromGraphQL(graphqlQueryTotalHolder) + )?.data[explorer.chainDb].erc20_contract; + + totalHolders.push(holders); + page++; + } while (index < assets.length); + + return totalHolders.flat(); + } + + async getNativeHolderWithPagination(assets: Asset[], explorer: Explorer) { let totalHolders = {}; let page = 0; let index = 0; diff --git a/src/shared/constants/common.ts b/src/shared/constants/common.ts index 26f5d040..2cb92b9d 100644 --- a/src/shared/constants/common.ts +++ b/src/shared/constants/common.ts @@ -351,7 +351,7 @@ export const INDEXER_API_V2 = { } } }`, - BASE_QUERY: `query BaseQuery { + BASE_QUERY: `query BaseQuery($limit: Int = 100, $offset: Int = 0) { %s { %s } }`, LIST_VALIDATOR: `query ListValidator($address: [String!] = null) { %s {