From d4a19d15a9ba04e318e5baa3b266cacb92dc6cac Mon Sep 17 00:00:00 2001 From: Ashwin Phatak Date: Thu, 29 Jul 2021 18:12:35 +0530 Subject: [PATCH] Implemented query resolvers for entities Burn and Factory. (#171) Co-authored-by: nabarun --- packages/erc20-watcher/src/indexer.ts | 6 +-- packages/uni-info-watcher/src/database.ts | 45 ++++++++++++++++++- packages/uni-info-watcher/src/indexer.ts | 14 ++++-- .../uni-info-watcher/src/mock/resolvers.ts | 6 +-- packages/uni-info-watcher/src/resolvers.ts | 22 +++++++-- 5 files changed, 76 insertions(+), 17 deletions(-) diff --git a/packages/erc20-watcher/src/indexer.ts b/packages/erc20-watcher/src/indexer.ts index 32a99b47..01115eab 100644 --- a/packages/erc20-watcher/src/indexer.ts +++ b/packages/erc20-watcher/src/indexer.ts @@ -116,8 +116,7 @@ export class Indexer { if (this._serverMode === ETH_CALL_MODE) { const contract = new ethers.Contract(token, this._abi, this._ethProvider); - const { block } = await this._ethClient.getBlockByHash(blockHash); - const { number } = block; + const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = BigNumber.from(number).toNumber(); // eth_call doesnt support calling method by blockHash https://eth.wiki/json-rpc/API#the-default-block-parameter @@ -154,8 +153,7 @@ export class Indexer { if (this._serverMode === ETH_CALL_MODE) { const contract = new ethers.Contract(token, this._abi, this._ethProvider); - const { block } = await this._ethClient.getBlockByHash(blockHash); - const { number } = block; + const { block: { number } } = await this._ethClient.getBlockByHash(blockHash); const blockNumber = BigNumber.from(number).toNumber(); const value = await contract.allowance(owner, spender, { blockTag: blockNumber }); diff --git a/packages/uni-info-watcher/src/database.ts b/packages/uni-info-watcher/src/database.ts index ad52cb1c..9ddd5a67 100644 --- a/packages/uni-info-watcher/src/database.ts +++ b/packages/uni-info-watcher/src/database.ts @@ -25,6 +25,17 @@ import { BlockProgress } from './entity/BlockProgress'; import { Block } from './events'; import { SyncStatus } from './entity/SyncStatus'; +export enum OrderDirection { + asc = 'asc', + desc = 'desc' +} + +export interface QueryOptions { + limit?: number; + orderBy?: string; + orderDirection?: OrderDirection; +} + export class Database { _config: ConnectionOptions _conn!: Connection @@ -343,7 +354,7 @@ export class Database { return entity; } - async getFactories ({ blockHash }: DeepPartial, queryOptions: { [key: string]: any }): Promise> { + async getFactories ({ blockHash, blockNumber }: Partial, queryOptions: QueryOptions): Promise> { const repo = this._conn.getRepository(Factory); let selectQueryBuilder = repo.createQueryBuilder('factory') @@ -359,6 +370,10 @@ export class Database { .orWhere('block_number <= :canonicalBlockNumber', { canonicalBlockNumber }); } + if (blockNumber) { + selectQueryBuilder = selectQueryBuilder.where('block_number <= :blockNumber', { blockNumber }); + } + const { limit } = queryOptions; if (limit) { @@ -368,7 +383,7 @@ export class Database { return selectQueryBuilder.getMany(); } - async getBundles ({ blockHash, blockNumber }: DeepPartial, queryOptions: { [key: string]: any }): Promise> { + async getBundles ({ blockHash, blockNumber }: Partial, queryOptions: QueryOptions): Promise> { const repo = this._conn.getRepository(Bundle); let selectQueryBuilder = repo.createQueryBuilder('bundle') @@ -397,6 +412,32 @@ export class Database { return selectQueryBuilder.getMany(); } + async getBurns (where: Partial = {}, queryOptions: QueryOptions): Promise> { + const repo = this._conn.getRepository(Burn); + + let selectQueryBuilder = repo.createQueryBuilder('burn') + .distinctOn(['burn.id']) + .orderBy('burn.id') + .addOrderBy('burn.block_number', 'DESC') + .innerJoinAndSelect('burn.pool', 'pool'); + + Object.entries(where).forEach(([field, value]) => { + selectQueryBuilder = selectQueryBuilder.andWhere(`burn.${field} = :value`, { value }); + }); + + const { limit, orderBy, orderDirection } = queryOptions; + + if (limit) { + selectQueryBuilder = selectQueryBuilder.limit(limit); + } + + if (orderBy) { + selectQueryBuilder = selectQueryBuilder.addOrderBy(orderBy, orderDirection === 'desc' ? 'DESC' : 'ASC'); + } + + return selectQueryBuilder.getMany(); + } + async saveFactory (factory: Factory, block: Block): Promise { return this._conn.transaction(async (tx) => { const repo = tx.getRepository(Factory); diff --git a/packages/uni-info-watcher/src/indexer.ts b/packages/uni-info-watcher/src/indexer.ts index a839c8ed..456bd2c9 100644 --- a/packages/uni-info-watcher/src/indexer.ts +++ b/packages/uni-info-watcher/src/indexer.ts @@ -14,7 +14,7 @@ import { convertTokenToDecimal, loadTransaction, safeDiv } from './utils'; import { createTick } from './utils/tick'; import Decimal from 'decimal.js'; import { Position } from './entity/Position'; -import { Database } from './database'; +import { Database, QueryOptions } from './database'; import { Event } from './entity/Event'; import { ResultEvent, Block, Transaction, PoolCreatedEvent, InitializeEvent, MintEvent, BurnEvent, SwapEvent, IncreaseLiquidityEvent, DecreaseLiquidityEvent, CollectEvent, TransferEvent } from './events'; import { Factory } from './entity/Factory'; @@ -193,8 +193,16 @@ export class Indexer { return this._db.getBundle({ id, blockHash: block.hash }); } - async getBundles (first: string, block: BlockHeight): Promise { - return this._db.getBundles({ blockHash: block.hash, blockNumber: block.number }, { limit: first }); + async getBundles (block: BlockHeight, queryOptions: QueryOptions): Promise { + return this._db.getBundles({ blockHash: block.hash, blockNumber: block.number }, queryOptions); + } + + async getBurns (where: Partial, queryOptions: QueryOptions): Promise { + return this._db.getBurns(where, queryOptions); + } + + async getFactories (block: BlockHeight, queryOptions: QueryOptions): Promise { + return this._db.getFactories({ blockHash: block.hash, blockNumber: block.number }, queryOptions); } async _fetchAndSaveEvents (block: Block): Promise { diff --git a/packages/uni-info-watcher/src/mock/resolvers.ts b/packages/uni-info-watcher/src/mock/resolvers.ts index 0eba03ef..491d23e5 100644 --- a/packages/uni-info-watcher/src/mock/resolvers.ts +++ b/packages/uni-info-watcher/src/mock/resolvers.ts @@ -4,14 +4,10 @@ import BigInt from 'apollo-type-bigint'; import { Data, Entity, NO_OF_BLOCKS } from './data'; import { BlockHeight } from '../resolvers'; +import { OrderDirection } from '../database'; const log = debug('vulcanize:test'); -enum OrderDirection { - asc, - desc -} - enum BurnOrderBy { timestamp } diff --git a/packages/uni-info-watcher/src/resolvers.ts b/packages/uni-info-watcher/src/resolvers.ts index 4f634038..cc27f80a 100644 --- a/packages/uni-info-watcher/src/resolvers.ts +++ b/packages/uni-info-watcher/src/resolvers.ts @@ -3,9 +3,13 @@ import BigInt from 'apollo-type-bigint'; import debug from 'debug'; import { Indexer } from './indexer'; +import { Burn } from './entity/Burn'; +import { OrderDirection } from './database'; const log = debug('vulcanize:resolver'); +const DEFAULT_LIMIT = 100; + export interface BlockHeight { number?: number; hash?: string; @@ -24,10 +28,22 @@ export const createResolvers = async (indexer: Indexer): Promise => { return indexer.getBundle(id, block); }, - bundles: async (_: any, { first, block = {} }: { first: string, block: BlockHeight }) => { - log('bundles', first, block); + bundles: async (_: any, { block = {}, first = DEFAULT_LIMIT }: { first: number, block: BlockHeight }) => { + log('bundles', block, first); - return indexer.getBundles(first, block); + return indexer.getBundles(block, { limit: first }); + }, + + burns: async (_: any, { first = DEFAULT_LIMIT, orderBy, orderDirection, where }: { first: number, orderBy: string, orderDirection: OrderDirection, where: Partial }) => { + log('burns', first, orderBy, orderDirection, where); + + return indexer.getBurns(where, { limit: first, orderBy, orderDirection }); + }, + + factories: async (_: any, { block = {}, first = DEFAULT_LIMIT }: { first: number, block: BlockHeight }) => { + log('factories', block, first); + + return indexer.getFactories(block, { limit: first }); } } };