From 45445d33c81eed29fb785bd3b35cf40d61baf421 Mon Sep 17 00:00:00 2001 From: Igor Lins e Silva <4753812+igorls@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:16:08 +0000 Subject: [PATCH] add /v2/state/get_top_holders --- .../get_top_holders/get_top_holders.ts | 62 +++++++++++++++++++ api/routes/v2-state/get_top_holders/index.ts | 31 ++++++++++ interfaces/hyperionConfig.ts | 1 + 3 files changed, 94 insertions(+) create mode 100644 api/routes/v2-state/get_top_holders/get_top_holders.ts create mode 100644 api/routes/v2-state/get_top_holders/index.ts diff --git a/api/routes/v2-state/get_top_holders/get_top_holders.ts b/api/routes/v2-state/get_top_holders/get_top_holders.ts new file mode 100644 index 00000000..92df74b3 --- /dev/null +++ b/api/routes/v2-state/get_top_holders/get_top_holders.ts @@ -0,0 +1,62 @@ +import { timedQuery } from "../../../helpers/functions"; +import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify"; +import { getSkipLimit } from "../../v2-history/get_actions/functions"; + +async function getTopHolders(fastify: FastifyInstance, request: FastifyRequest) { + + const query: any = request.query; + + const response: any = { + contract: query.account, + symbol: undefined, + holders: [] + }; + + const { skip, limit } = getSkipLimit(request.query); + + const maxDocs = fastify.manager.config.api.limits.get_top_holders ?? 500; + + const terms: any[] = []; + + + if (query.contract) { + terms.push({ "term": { "code": { "value": query.contract } } }); + } + + if (query.symbol) { + terms.push({ "term": { "symbol": { "value": query.symbol } } }); + } + + + const stateResult = await fastify.elastic.search({ + "index": fastify.manager.chain + '-table-accounts-*', + "size": (limit > maxDocs ? maxDocs : limit) || 50, + "from": skip || 0, + body: { + sort: { + amount: { + order: "desc" + } + }, + query: { bool: { "must": terms } } + } + }); + + response.holders = stateResult.body.hits.hits.map((doc: any) => { + return { + owner: doc._source.scope, + amount: doc._source.amount, + symbol: doc._source.symbol, + updated_on: doc._source.block_num + }; + }); + + return response; + +} + +export function getTopHoldersHandler(fastify: FastifyInstance, route: string) { + return async (request: FastifyRequest, reply: FastifyReply) => { + reply.send(await timedQuery(getTopHolders, fastify, request, route)); + } +} \ No newline at end of file diff --git a/api/routes/v2-state/get_top_holders/index.ts b/api/routes/v2-state/get_top_holders/index.ts new file mode 100644 index 00000000..45215b36 --- /dev/null +++ b/api/routes/v2-state/get_top_holders/index.ts @@ -0,0 +1,31 @@ +import {FastifyInstance} from "fastify"; +import {addApiRoute, extendQueryStringSchema, getRouteName} from "../../../helpers/functions"; +import { getTopHoldersHandler } from "./get_top_holders"; + +export default function (fastify: FastifyInstance, opts: any, next) { + const schema = { + description: 'get the list of top holders for a given token', + summary: 'get top token holders', + tags: ['accounts'], + querystring: extendQueryStringSchema({ + "contract": { + description: 'token contract account name', + type: 'string', + minLength: 1, + maxLength: 12 + }, + "symbol": { + description: 'filter by token symbol', + type: 'string' + }, + }, ["contract"]) + }; + addApiRoute( + fastify, + 'GET', + getRouteName(__filename), + getTopHoldersHandler, + schema + ); + next(); +} \ No newline at end of file diff --git a/interfaces/hyperionConfig.ts b/interfaces/hyperionConfig.ts index 27878890..ca9044c1 100644 --- a/interfaces/hyperionConfig.ts +++ b/interfaces/hyperionConfig.ts @@ -70,6 +70,7 @@ export interface IndexerConfigs { } interface ApiLimits { + get_top_holders?: number; get_links?: number; get_actions?: number; get_blocks?: number;