From 2c27561f9c224f77293b48694483a74e225eb691 Mon Sep 17 00:00:00 2001 From: Daniel David Sintimbrean <102896754+DanielSintimbrean@users.noreply.github.com> Date: Sun, 19 Nov 2023 23:31:33 +0100 Subject: [PATCH] Add holderScore and bankingPercentage fields to (#11) Holder model and schema --- prisma/schema.prisma | 1 + schema.graphql | 2 ++ src/indexer/index.ts | 51 ++++++++++++++++++++++++++++++++++++++++++++ src/schema/holder.ts | 31 +++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 33c3ddb..aa71eb0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -17,6 +17,7 @@ datasource db { model Holder { id String @id @default(uuid()) address String @unique + holderScore BigInt @default(0) MrCryptosOwned MrCrypto[] E7LTokensOwned E7LToken[] diff --git a/schema.graphql b/schema.graphql index bf6062f..9589f85 100644 --- a/schema.graphql +++ b/schema.graphql @@ -165,6 +165,7 @@ enum Headwear { type Holder { address: String! + bankingPercentage: Float! mrCryptosOwned(first: Int! = 100, order: MrCryptoOrderBy! = {by: tokenId, type: desc}, skip: Int! = 0): [MrCrypto!]! numberOfMrCryptos: Int! } @@ -243,6 +244,7 @@ type Query { e7lCollections: [E7L!]! e7lTokens(first: Int! = 100, skip: Int! = 0): [E7LToken!]! e7lTokensByAddress(address: String!): [E7LToken!]! + holderByAddress(address: String!): Holder! isAuthenticated: Boolean! isIndexerCronJobRunning: Boolean! mrCryptoById(tokenId: Int!): MrCrypto! diff --git a/src/indexer/index.ts b/src/indexer/index.ts index c2edafa..0b4a409 100644 --- a/src/indexer/index.ts +++ b/src/indexer/index.ts @@ -37,6 +37,18 @@ async function indexerCronJob() { process.exit(1); }); + await indexHolderScore().catch((e) => { + console.error( + `Holder Indexer failed ❌ 😭 at ${new Date().toUTCString()};`, + ); + + const { message, stack } = e; + console.error(message); + console.error(stack); + + process.exit(1); + }); + isIndexerCronJobRunning = false; console.log(`Indexer finished ✅ 🎉 😄 at ${new Date().toUTCString()}`); console.log("Waiting 5 minutes for next indexation ⏰ \n\n"); @@ -56,3 +68,42 @@ export async function startIndexation() { indexerCronJob(); return "Indexer cron job started 🏃" as const; } + +async function indexHolderScore() { + const currentBlock = await client.getBlockNumber(); + + const holders = await prisma.holder.findMany({ + where: { + MrCryptosOwned: { some: {} }, + }, + select: { + id: true, + MrCryptosOwned: { + select: { + lastTransferBlock: true, + }, + }, + }, + }); + + for (let holder of holders) { + const currentBlocksCount = + BigInt(holder.MrCryptosOwned.length) * currentBlock; + + const lastBlockTransferCount = holder.MrCryptosOwned.reduce( + (acc, mrcrypto) => acc + mrcrypto.lastTransferBlock, + 0n, + ); + + const score = currentBlocksCount - lastBlockTransferCount; + + await prisma.holder.update({ + where: { + id: holder.id, + }, + data: { + holderScore: score, + }, + }); + } +} diff --git a/src/schema/holder.ts b/src/schema/holder.ts index 04ffaa1..6a147c9 100644 --- a/src/schema/holder.ts +++ b/src/schema/holder.ts @@ -12,6 +12,23 @@ const MrCryptoOrderByEnum = builder.enumType("MrCryptoOrderByEnum", { builder.prismaObject("Holder", { fields: (t) => ({ address: t.exposeString("address"), + bankingPercentage: t.float({ + resolve: async (param) => { + const totalHoldersScore = await prisma.holder.aggregate({ + _sum: { + holderScore: true, + }, + }); + + if (!totalHoldersScore._sum.holderScore) return 0; + + return ( + (Number(param.holderScore) / + Number(totalHoldersScore._sum.holderScore)) * + 100 + ); + }, + }), mrCryptosOwned: t.relation("MrCryptosOwned", { args: { first: t.arg.int({ required: true, defaultValue: 100 }), @@ -69,4 +86,18 @@ builder.queryFields((t) => ({ }); }, }), + holderByAddress: t.prismaField({ + type: "Holder", + args: { + address: t.arg.string({ required: true }), + }, + resolve: (query, _parent, args) => { + return prisma.holder.findUniqueOrThrow({ + ...query, + where: { + address: args.address, + }, + }); + }, + }), }));