diff --git a/modules/actions/pool/sync-join-exits.ts b/modules/actions/pool/sync-join-exits.ts index b13085cf8..22a369e2b 100644 --- a/modules/actions/pool/sync-join-exits.ts +++ b/modules/actions/pool/sync-join-exits.ts @@ -67,6 +67,7 @@ export const syncJoinExits = async (vaultSubgraphClient: V3VaultSubgraphClient, userAddress: event.user.id, blockNumber: Number(event.blockNumber), blockTimestamp: Number(event.blockTimestamp), + logPosition: Number(event.id.substring(66)), amountUsd: usd.reduce((acc, token) => acc + Number(token.amountUsd), 0), payload: { tokens: usd, diff --git a/modules/controllers/queries-controller.ts b/modules/controllers/queries-controller.ts new file mode 100644 index 000000000..8f26b51f4 --- /dev/null +++ b/modules/controllers/queries-controller.ts @@ -0,0 +1,72 @@ +/** + * Responsible for handling all the queries – can be split based on models + */ +import { GqlPoolJoinExit, QueryPoolGetJoinExitsArgs } from '../../schema'; +import { prisma } from '../../prisma/prisma-client'; +import { Chain } from '@prisma/client'; + +export function QueriesController(tracer?: any) { + return { + // TODO: I'd like to merge it with the swaps and return all as pool events + getJoinExits: async ({ first, skip, where }: QueryPoolGetJoinExitsArgs): Promise => { + // Setting default values + first = first ?? 5; + skip = skip ?? 0; + where = where ?? {}; + let { chainIn, poolIdIn } = where; + chainIn = chainIn ?? []; // 🤔 when no chain, shouldn't we be returning all the chains? + poolIdIn = poolIdIn ?? []; + + const conditions: { poolId?: { in: string[] }; chain?: { in: Chain[] } } = {}; + if (chainIn.length) { + conditions.chain = { + in: chainIn, + }; + } + if (poolIdIn.length) { + conditions.poolId = { + in: poolIdIn, + }; + } + + const dbJoinExists = await prisma.poolEvent.findMany({ + where: conditions, + take: first, + skip, + orderBy: [ + { + blockNumber: 'desc', + }, + { + logPosition: 'desc', + }, + ], + }); + + const results: GqlPoolJoinExit[] = dbJoinExists.map((joinExit) => { + const payload = joinExit.payload as { + tokens: { address: string; amount: string; amountUsd: string }[]; + }; + + return { + __typename: 'GqlPoolJoinExit', + amounts: payload.tokens.map((token: any) => ({ + address: token.address, + amount: token.amount, + valueUsd: token.amountUsd, + })), + chain: joinExit.chain, + id: joinExit.id, + poolId: joinExit.poolId, + sender: joinExit.userAddress, + timestamp: joinExit.blockTimestamp, + tx: joinExit.tx, + type: joinExit.type === 'JOIN' ? 'Join' : 'Exit', + valueUSD: String(joinExit.amountUsd), + }; + }); + + return results; + }, + }; +} diff --git a/modules/pool/pool.prisma b/modules/pool/pool.prisma index d85916490..91f57732b 100644 --- a/modules/pool/pool.prisma +++ b/modules/pool/pool.prisma @@ -510,6 +510,14 @@ model PoolEvent { userAddress String blockNumber Int blockTimestamp Int + logPosition Int amountUsd Float payload Json + + @@index([type]) + @@index([chain]) + @@index([chain, poolId]) + @@index([userAddress]) + @@index([blockNumber]) + @@index([logPosition]) } diff --git a/modules/pool/pool.resolvers.ts b/modules/pool/pool.resolvers.ts index 7bf0519f3..8389d28dc 100644 --- a/modules/pool/pool.resolvers.ts +++ b/modules/pool/pool.resolvers.ts @@ -4,6 +4,7 @@ import { isAdminRoute } from '../auth/auth-context'; import { prisma } from '../../prisma/prisma-client'; import { networkContext } from '../network/network-context.service'; import { headerChain } from '../context/header-chain'; +import { QueriesController } from '../controllers/queries-controller'; const balancerResolvers: Resolvers = { Query: { @@ -47,7 +48,9 @@ const balancerResolvers: Resolvers = { } else if (!args.where?.chainIn) { throw new Error('poolGetJoinExits error: Provide "where.chainIn" param'); } - return poolService.getPoolJoinExits(args); + const v2events = await poolService.getPoolJoinExits(args); + const v3events = await QueriesController().getJoinExits(args); + return [...v2events, ...v3events]; }, poolGetFeaturedPoolGroups: async (parent, { chains }, context) => { const currentChain = headerChain(); diff --git a/modules/sources/subgraphs/universal-client.ts b/modules/sources/subgraphs/universal-client.ts new file mode 100644 index 000000000..bd67404c9 --- /dev/null +++ b/modules/sources/subgraphs/universal-client.ts @@ -0,0 +1,18 @@ +import { getVaultSubgraphClient } from './balancer-v3-vault'; +import { getPoolsSubgraphClient } from './balancer-v3-pools'; +import { BalancerSubgraphService } from '../../subgraphs/balancer-subgraph/balancer-subgraph.service'; + +export const getBalancerUniversalSubgraphClient = async ( + vaultSubgraphUrl: string, + poolsSubgraphUrl: string, + v2SubgraphUrl: string, + chainId: number, +) => { + const vaultSubgraphClient = getVaultSubgraphClient(vaultSubgraphUrl); + const poolsSubgraphClient = getPoolsSubgraphClient(poolsSubgraphUrl); + const v2SubgraphClient = new BalancerSubgraphService(v2SubgraphUrl, chainId); + + return { + getEvents: async () => {}, + }; +}; diff --git a/prisma/migrations/20240229152312_add_pool_events/migration.sql b/prisma/migrations/20240229152312_add_pool_events/migration.sql deleted file mode 100644 index d4bb13de7..000000000 --- a/prisma/migrations/20240229152312_add_pool_events/migration.sql +++ /dev/null @@ -1,18 +0,0 @@ --- CreateEnum -CREATE TYPE "PoolEventType" AS ENUM ('JOIN', 'EXIT', 'SWAP'); - --- CreateTable -CREATE TABLE "PoolEvent" ( - "id" TEXT NOT NULL, - "tx" TEXT NOT NULL, - "type" "PoolEventType" NOT NULL, - "chain" "Chain" NOT NULL, - "poolId" TEXT NOT NULL, - "userAddress" TEXT NOT NULL, - "blockNumber" INTEGER NOT NULL, - "blockTimestamp" INTEGER NOT NULL, - "amountUsd" DOUBLE PRECISION NOT NULL, - "payload" JSONB NOT NULL, - - CONSTRAINT "PoolEvent_pkey" PRIMARY KEY ("id") -); diff --git a/prisma/migrations/20240304114442_add_pool_events/migration.sql b/prisma/migrations/20240304114442_add_pool_events/migration.sql new file mode 100644 index 000000000..8ac3a2864 --- /dev/null +++ b/prisma/migrations/20240304114442_add_pool_events/migration.sql @@ -0,0 +1,37 @@ +-- CreateEnum +CREATE TYPE "PoolEventType" AS ENUM ('JOIN', 'EXIT', 'SWAP'); + +-- CreateTable +CREATE TABLE "PoolEvent" ( + "id" TEXT NOT NULL, + "tx" TEXT NOT NULL, + "type" "PoolEventType" NOT NULL, + "chain" "Chain" NOT NULL, + "poolId" TEXT NOT NULL, + "userAddress" TEXT NOT NULL, + "blockNumber" INTEGER NOT NULL, + "blockTimestamp" INTEGER NOT NULL, + "logPosition" INTEGER NOT NULL, + "amountUsd" DOUBLE PRECISION NOT NULL, + "payload" JSONB NOT NULL, + + CONSTRAINT "PoolEvent_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "PoolEvent_type_idx" ON "PoolEvent"("type"); + +-- CreateIndex +CREATE INDEX "PoolEvent_chain_idx" ON "PoolEvent"("chain"); + +-- CreateIndex +CREATE INDEX "PoolEvent_chain_poolId_idx" ON "PoolEvent"("chain", "poolId"); + +-- CreateIndex +CREATE INDEX "PoolEvent_userAddress_idx" ON "PoolEvent"("userAddress"); + +-- CreateIndex +CREATE INDEX "PoolEvent_blockNumber_idx" ON "PoolEvent"("blockNumber"); + +-- CreateIndex +CREATE INDEX "PoolEvent_logPosition_idx" ON "PoolEvent"("logPosition"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 22107d7e0..e74011efe 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -557,8 +557,16 @@ model PoolEvent { userAddress String blockNumber Int blockTimestamp Int + logPosition Int amountUsd Float payload Json + + @@index([type]) + @@index([chain]) + @@index([chain, poolId]) + @@index([userAddress]) + @@index([blockNumber]) + @@index([logPosition]) }