From bdd473a594ec6c3b4f5a9b3e152437f215b264bb Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Fri, 29 Mar 2024 18:31:10 +0200 Subject: [PATCH 01/11] add interface and refactor to have multiple service providers --- .../data-integration.controller.ts | 2 +- .../data-integration.service.ts | 79 ++++++----- .../data-integration/entities/index.ts | 4 - apps/api/src/entitites/index.ts | 5 - apps/api/src/entitites/join.exit.event.ts | 57 -------- apps/api/src/entitites/swap.event.ts | 89 ------------ .../src/providers}/entities/asset.response.ts | 2 +- .../common/src/providers/entities}/asset.ts | 0 .../common/src/providers/entities}/block.ts | 0 .../providers}/entities/events.response.ts | 4 +- .../src/providers/entities/general.event.ts | 19 +++ libs/common/src/providers/entities/index.ts | 10 ++ .../src/providers/entities/join.exit.event.ts | 36 +++++ .../entities/latest.block.response.ts | 2 +- .../entities/pair.metadata.ts | 0 .../src/providers}/entities/pair.response.ts | 2 +- .../common/src/providers/entities}/pair.ts | 14 -- .../src/providers/entities/swap.event.ts | 45 ++++++ libs/common/src/providers/index.ts | 2 + libs/common/src/providers/interface.ts | 10 ++ .../xexchange/abis/pair.abi.json | 0 .../xexchange/abis/router.abi.json | 0 .../entities/xexchange.add.liquidity.event.ts | 7 +- .../entities/xexchange.liquidity.event.ts | 28 ++-- .../xexchange/entities/xexchange.pair.ts} | 0 .../xexchange.remove.liquidity.event.ts | 7 +- .../entities/xexchange.swap.event.ts | 23 +-- .../xexchange/index.ts | 2 +- .../xexchange/xexchange.module.ts | 4 +- .../xexchange/xexchange.service.ts | 132 ++++++++++++++++-- libs/common/src/services/index.ts | 2 +- .../src/services/xexchange/entities/index.ts | 6 - .../xexchange/entities/xexchange.event.ts | 7 - 33 files changed, 322 insertions(+), 278 deletions(-) delete mode 100644 apps/api/src/endpoints/data-integration/entities/index.ts delete mode 100644 apps/api/src/entitites/index.ts delete mode 100644 apps/api/src/entitites/join.exit.event.ts delete mode 100644 apps/api/src/entitites/swap.event.ts rename {apps/api/src/endpoints/data-integration => libs/common/src/providers}/entities/asset.response.ts (71%) rename {apps/api/src/entitites => libs/common/src/providers/entities}/asset.ts (100%) rename {apps/api/src/entitites => libs/common/src/providers/entities}/block.ts (100%) rename {apps/api/src/endpoints/data-integration => libs/common/src/providers}/entities/events.response.ts (56%) create mode 100644 libs/common/src/providers/entities/general.event.ts create mode 100644 libs/common/src/providers/entities/index.ts create mode 100644 libs/common/src/providers/entities/join.exit.event.ts rename {apps/api/src/endpoints/data-integration => libs/common/src/providers}/entities/latest.block.response.ts (73%) rename libs/common/src/{services/xexchange => providers}/entities/pair.metadata.ts (100%) rename {apps/api/src/endpoints/data-integration => libs/common/src/providers}/entities/pair.response.ts (71%) rename {apps/api/src/entitites => libs/common/src/providers/entities}/pair.ts (52%) create mode 100644 libs/common/src/providers/entities/swap.event.ts create mode 100644 libs/common/src/providers/index.ts create mode 100644 libs/common/src/providers/interface.ts rename libs/common/src/{services => providers}/xexchange/abis/pair.abi.json (100%) rename libs/common/src/{services => providers}/xexchange/abis/router.abi.json (100%) rename libs/common/src/{services => providers}/xexchange/entities/xexchange.add.liquidity.event.ts (56%) rename libs/common/src/{services => providers}/xexchange/entities/xexchange.liquidity.event.ts (82%) rename libs/common/src/{services/xexchange/entities/pair.ts => providers/xexchange/entities/xexchange.pair.ts} (100%) rename libs/common/src/{services => providers}/xexchange/entities/xexchange.remove.liquidity.event.ts (57%) rename libs/common/src/{services => providers}/xexchange/entities/xexchange.swap.event.ts (80%) rename libs/common/src/{services => providers}/xexchange/index.ts (71%) rename libs/common/src/{services => providers}/xexchange/xexchange.module.ts (84%) rename libs/common/src/{services => providers}/xexchange/xexchange.service.ts (58%) delete mode 100644 libs/common/src/services/xexchange/entities/index.ts delete mode 100644 libs/common/src/services/xexchange/entities/xexchange.event.ts diff --git a/apps/api/src/endpoints/data-integration/data-integration.controller.ts b/apps/api/src/endpoints/data-integration/data-integration.controller.ts index 7b19921..8a6b52f 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.controller.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.controller.ts @@ -1,5 +1,5 @@ import { BadRequestException, Controller, Get, Query } from "@nestjs/common"; -import { AssetResponse, EventsResponse, LatestBlockResponse, PairResponse } from "./entities"; +import { AssetResponse, EventsResponse, LatestBlockResponse, PairResponse } from "@mvx-monorepo/common"; import { ApiResponse } from "@nestjs/swagger"; import { DataIntegrationService } from "./data-integration.service"; import { ParseIntPipe } from "@multiversx/sdk-nestjs-common"; diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index 540460d..be5c04d 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -1,20 +1,25 @@ import { Injectable, NotFoundException } from "@nestjs/common"; -import { AssetResponse, EventsResponse, LatestBlockResponse, PairResponse } from "./entities"; -import { IndexerService, MultiversXApiService, XExchangeAddLiquidityEvent, XExchangeRemoveLiquidityEvent, XExchangeService, XExchangeSwapEvent } from "@mvx-monorepo/common"; -import { Asset, Block, JoinExitEvent, Pair, SwapEvent } from "../../entitites"; -import { ApiConfigService } from "@mvx-monorepo/common"; +import { + ApiConfigService, Asset, AssetResponse, Block, ElasticRound, EventsResponse, + IndexerService, JoinExitEvent, LatestBlockResponse, + MultiversXApiService, PairResponse, SwapEvent, XExchangeService, +} from "@mvx-monorepo/common"; import { OriginLogger } from "@multiversx/sdk-nestjs-common"; +import { IProviderService } from "@mvx-monorepo/common/providers/interface"; +import { GeneralEvent } from "@mvx-monorepo/common/providers/entities/general.event"; @Injectable() export class DataIntegrationService { private readonly logger = new OriginLogger(DataIntegrationService.name); - + private providers: IProviderService[] = []; constructor( private readonly apiConfigService: ApiConfigService, private readonly indexerService: IndexerService, private readonly multiversXApiService: MultiversXApiService, - private readonly xExchangeService: XExchangeService, - ) { } + xExchangeService: XExchangeService, + ) { + this.providers.push(xExchangeService) + } public async getLatestBlock(): Promise { // we are using rounds instead of blocks because the MultiversX blockchain is multi-sharded, @@ -44,22 +49,8 @@ export class DataIntegrationService { }; } - public async getPair(address: string): Promise { - const xExchangePairs = await this.xExchangeService.getPairs(); - const xExchangePair = xExchangePairs.find((p) => p.address === address); - if (!xExchangePair) { - throw new NotFoundException(`Pair with address ${address} not found`); - } - - const pairFeePercent = await this.xExchangeService.getPairFeePercent(address); - - const { deployTxHash, deployedAt } = await this.multiversXApiService.getContractDeployInfo(address); - const round = deployedAt ? await this.indexerService.getRound(deployedAt) : undefined; - - const pair = Pair.fromXExchangePair(xExchangePair, pairFeePercent, { deployTxHash, deployedAt, deployRound: round?.round }); - return { - pair, - }; + public async getPair(identifier: string): Promise { + return this.resolveProvider(identifier).getPair(identifier); } public async getEvents(fromBlockNonce: number, toBlockNonce: number): Promise { @@ -69,43 +60,57 @@ export class DataIntegrationService { events: [], }; } - const after = rounds[0].timestamp; const before = rounds[rounds.length - 1].timestamp; - const xExchangeEvents = await this.xExchangeService.getEvents(before, after); + const response = new EventsResponse(); + for (const provider of this.providers) { + const generalEvents = await provider.getEvents(before, after); + const event = this.processEvents(generalEvents, provider, rounds); + response.events.push(...event); + } + + return response; + } + + private processEvents(generalEvents: GeneralEvent[], provider: IProviderService, rounds: ElasticRound[]): ({ block: Block } & (SwapEvent | JoinExitEvent))[] { const events: ({ block: Block } & (SwapEvent | JoinExitEvent))[] = []; - for (const xExchangeEvent of xExchangeEvents) { + for (const generalEvent of generalEvents) { let event: SwapEvent | JoinExitEvent; - switch (xExchangeEvent.type) { + switch (generalEvent.type) { case "swap": - event = SwapEvent.fromXExchangeSwapEvent(xExchangeEvent as XExchangeSwapEvent); + event = provider.fromSwapEvent(generalEvent) break; case "addLiquidity": - event = JoinExitEvent.fromXExchangeEvent(xExchangeEvent as XExchangeAddLiquidityEvent); - break; case "removeLiquidity": - event = JoinExitEvent.fromXExchangeEvent(xExchangeEvent as XExchangeRemoveLiquidityEvent); + event = provider.fromAddRemoveLiquidityEvent(generalEvent) break; default: - this.logger.error(`Unknown event type: ${xExchangeEvent.type} for event: ${JSON.stringify(xExchangeEvent)}`); + this.logger.error(`Unknown event type: ${generalEvent.type} for event: ${JSON.stringify(generalEvent)}`); continue; } - - const round = rounds.find((round) => round.timestamp === xExchangeEvent.timestamp); + const round = rounds.find((round: { timestamp: number; }) => round.timestamp === generalEvent.timestamp); if (!round) { - this.logger.error(`Round not found for event: ${JSON.stringify(xExchangeEvent)}`); + this.logger.error(`Round not found for event: ${JSON.stringify(generalEvent)}`); continue; } - const block = Block.fromElasticRound(round, { onlyRequiredFields: true }); events.push({ block, ...event, }); } + return events; + } + + private resolveProvider(identifier: string): IProviderService { + const provider = this.providers.find((p) => p.getPair(identifier) !== undefined); + if (!provider) { + this.logger.error(`Provider with identifier ${identifier} not found`); + throw new NotFoundException(`Provider with identifier ${identifier} not found`); + } - return { events }; + return provider; } } diff --git a/apps/api/src/endpoints/data-integration/entities/index.ts b/apps/api/src/endpoints/data-integration/entities/index.ts deleted file mode 100644 index 5c7db45..0000000 --- a/apps/api/src/endpoints/data-integration/entities/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './asset.response'; -export * from './events.response'; -export * from './latest.block.response'; -export * from './pair.response'; diff --git a/apps/api/src/entitites/index.ts b/apps/api/src/entitites/index.ts deleted file mode 100644 index 3d2628e..0000000 --- a/apps/api/src/entitites/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from './asset'; -export * from './block'; -export * from './join.exit.event'; -export * from './pair'; -export * from './swap.event'; diff --git a/apps/api/src/entitites/join.exit.event.ts b/apps/api/src/entitites/join.exit.event.ts deleted file mode 100644 index 7abd15d..0000000 --- a/apps/api/src/entitites/join.exit.event.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { XExchangeAddLiquidityEvent, XExchangeRemoveLiquidityEvent } from "@mvx-monorepo/common"; -import { ApiProperty } from "@nestjs/swagger"; -import BigNumber from "bignumber.js"; - -export class JoinExitEvent { - @ApiProperty() - eventType!: "join" | "exit"; - - @ApiProperty() - txnId!: string; - - @ApiProperty() - txnIndex!: number; - - @ApiProperty() - eventIndex!: number; - - @ApiProperty() - maker!: string; - - @ApiProperty() - pairId!: string; - - @ApiProperty() - amount0!: number | string; - - @ApiProperty() - amount1!: number | string; - - @ApiProperty() - reserves?: { - asset0: number | string; - asset1: number | string; - }; - - @ApiProperty() - metadata?: Record; - - static fromXExchangeEvent(event: XExchangeAddLiquidityEvent | XExchangeRemoveLiquidityEvent): JoinExitEvent { - const eventType = event.type === "addLiquidity" ? "join" : "exit"; - - return { - eventType, - txnId: event.txHash, - txnIndex: event.txOrder, - eventIndex: event.eventOrder, - maker: event.caller, - pairId: event.address, - amount0: new BigNumber(event.firstTokenAmount).shiftedBy(-event.pair.firstTokenDecimals).toFixed(), - amount1: new BigNumber(event.secondTokenAmount).shiftedBy(-event.pair.secondTokenDecimals).toFixed(), - reserves: { - asset0: new BigNumber(event.firstTokenReserves).shiftedBy(-event.pair.firstTokenDecimals).toFixed(), - asset1: new BigNumber(event.secondTokenReserves).shiftedBy(-event.pair.secondTokenDecimals).toFixed(), - }, - }; - } -} diff --git a/apps/api/src/entitites/swap.event.ts b/apps/api/src/entitites/swap.event.ts deleted file mode 100644 index d328a97..0000000 --- a/apps/api/src/entitites/swap.event.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { XExchangeSwapEvent } from "@mvx-monorepo/common"; -import { ApiProperty } from "@nestjs/swagger"; -import BigNumber from "bignumber.js"; - -export class SwapEvent { - @ApiProperty() - eventType!: "swap"; - - @ApiProperty() - txnId!: string; - - @ApiProperty() - txnIndex!: number; - - @ApiProperty() - eventIndex!: number; - - @ApiProperty() - maker!: string; - - @ApiProperty() - pairId!: string; - - @ApiProperty() - asset0In?: number | string; - - @ApiProperty() - asset1In?: number | string; - - @ApiProperty() - asset0Out?: number | string; - - @ApiProperty() - asset1Out?: number | string; - - @ApiProperty() - priceNative!: number | string; - - @ApiProperty() - reserves?: { - asset0: number | string; - asset1: number | string; - }; - - @ApiProperty() - metadata?: Record; - - static fromXExchangeSwapEvent(event: XExchangeSwapEvent): SwapEvent { - let asset0In: string | undefined = undefined; - let asset1In: string | undefined = undefined; - let asset0Out: string | undefined = undefined; - let asset1Out: string | undefined = undefined; - let asset0Reserves: string; - let asset1Reserves: string; - let priceNative: string; - - if (event.pair.firstTokenId === event.tokenInId) { - asset0In = new BigNumber(event.tokenInAmount).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); - asset1Out = new BigNumber(event.tokenOutAmount).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); - asset0Reserves = new BigNumber(event.tokenInReserves).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); - asset1Reserves = new BigNumber(event.tokenOutReserves).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); - priceNative = new BigNumber(asset1Reserves).dividedBy(asset0Reserves).toFixed(); - } else { - asset1In = new BigNumber(event.tokenInAmount).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); - asset0Out = new BigNumber(event.tokenOutAmount).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); - asset0Reserves = new BigNumber(event.tokenOutReserves).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); - asset1Reserves = new BigNumber(event.tokenInReserves).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); - priceNative = new BigNumber(asset1Reserves).dividedBy(asset0Reserves).toFixed(); - } - - return { - eventType: "swap", - txnId: event.txHash, - txnIndex: event.txOrder, - eventIndex: event.eventOrder, - maker: event.caller, - pairId: event.address, - asset0In, - asset1In, - asset0Out, - asset1Out, - priceNative, - reserves: { - asset0: asset0Reserves, - asset1: asset1Reserves, - }, - }; - } -} diff --git a/apps/api/src/endpoints/data-integration/entities/asset.response.ts b/libs/common/src/providers/entities/asset.response.ts similarity index 71% rename from apps/api/src/endpoints/data-integration/entities/asset.response.ts rename to libs/common/src/providers/entities/asset.response.ts index 972e18c..6234ac3 100644 --- a/apps/api/src/endpoints/data-integration/entities/asset.response.ts +++ b/libs/common/src/providers/entities/asset.response.ts @@ -1,5 +1,5 @@ import { ApiProperty } from "@nestjs/swagger"; -import { Asset } from "../../../entitites"; +import { Asset } from "./asset"; export class AssetResponse { @ApiProperty() diff --git a/apps/api/src/entitites/asset.ts b/libs/common/src/providers/entities/asset.ts similarity index 100% rename from apps/api/src/entitites/asset.ts rename to libs/common/src/providers/entities/asset.ts diff --git a/apps/api/src/entitites/block.ts b/libs/common/src/providers/entities/block.ts similarity index 100% rename from apps/api/src/entitites/block.ts rename to libs/common/src/providers/entities/block.ts diff --git a/apps/api/src/endpoints/data-integration/entities/events.response.ts b/libs/common/src/providers/entities/events.response.ts similarity index 56% rename from apps/api/src/endpoints/data-integration/entities/events.response.ts rename to libs/common/src/providers/entities/events.response.ts index d59fdc9..301ec7d 100644 --- a/apps/api/src/endpoints/data-integration/entities/events.response.ts +++ b/libs/common/src/providers/entities/events.response.ts @@ -1,5 +1,7 @@ import { ApiProperty } from "@nestjs/swagger"; -import { Block, JoinExitEvent, SwapEvent } from "../../../entitites"; +import { Block } from "./block"; +import { SwapEvent } from "./swap.event"; +import { JoinExitEvent } from "./join.exit.event"; export class EventsResponse { @ApiProperty() diff --git a/libs/common/src/providers/entities/general.event.ts b/libs/common/src/providers/entities/general.event.ts new file mode 100644 index 0000000..a8e45a7 --- /dev/null +++ b/libs/common/src/providers/entities/general.event.ts @@ -0,0 +1,19 @@ +import { ElasticEvent } from "@mvx-monorepo/common"; + +export class GeneralEvent { + type: string; + address: string; + identifier: string; + topics: string[]; + data: string; + timestamp!: number; + + constructor(event: ElasticEvent, type: "swap" | "addLiquidity" | "removeLiquidity") { + this.address = event.address; + this.identifier = event.identifier; + this.topics = event.topics; + this.data = event.data; + + this.type = type; + } +} diff --git a/libs/common/src/providers/entities/index.ts b/libs/common/src/providers/entities/index.ts new file mode 100644 index 0000000..c7de799 --- /dev/null +++ b/libs/common/src/providers/entities/index.ts @@ -0,0 +1,10 @@ +export * from './pair.metadata'; +export * from './asset.response'; +export * from './events.response'; +export * from './latest.block.response'; +export * from './pair.response'; +export * from './asset'; +export * from './block'; +export * from './join.exit.event'; +export * from './pair'; +export * from './swap.event'; diff --git a/libs/common/src/providers/entities/join.exit.event.ts b/libs/common/src/providers/entities/join.exit.event.ts new file mode 100644 index 0000000..c923f87 --- /dev/null +++ b/libs/common/src/providers/entities/join.exit.event.ts @@ -0,0 +1,36 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class JoinExitEvent { + @ApiProperty() + eventType!: "join" | "exit"; + + @ApiProperty() + txnId!: string; + + @ApiProperty() + txnIndex!: number; + + @ApiProperty() + eventIndex!: number; + + @ApiProperty() + maker!: string; + + @ApiProperty() + pairId!: string; + + @ApiProperty() + amount0!: number | string; + + @ApiProperty() + amount1!: number | string; + + @ApiProperty() + reserves?: { + asset0: number | string; + asset1: number | string; + }; + + @ApiProperty() + metadata?: Record; +} diff --git a/apps/api/src/endpoints/data-integration/entities/latest.block.response.ts b/libs/common/src/providers/entities/latest.block.response.ts similarity index 73% rename from apps/api/src/endpoints/data-integration/entities/latest.block.response.ts rename to libs/common/src/providers/entities/latest.block.response.ts index e652701..4bbd4c3 100644 --- a/apps/api/src/endpoints/data-integration/entities/latest.block.response.ts +++ b/libs/common/src/providers/entities/latest.block.response.ts @@ -1,5 +1,5 @@ import { ApiProperty } from "@nestjs/swagger"; -import { Block } from "../../../entitites"; +import { Block } from "./block"; export class LatestBlockResponse { @ApiProperty() diff --git a/libs/common/src/services/xexchange/entities/pair.metadata.ts b/libs/common/src/providers/entities/pair.metadata.ts similarity index 100% rename from libs/common/src/services/xexchange/entities/pair.metadata.ts rename to libs/common/src/providers/entities/pair.metadata.ts diff --git a/apps/api/src/endpoints/data-integration/entities/pair.response.ts b/libs/common/src/providers/entities/pair.response.ts similarity index 71% rename from apps/api/src/endpoints/data-integration/entities/pair.response.ts rename to libs/common/src/providers/entities/pair.response.ts index 398bb86..2ae25fb 100644 --- a/apps/api/src/endpoints/data-integration/entities/pair.response.ts +++ b/libs/common/src/providers/entities/pair.response.ts @@ -1,5 +1,5 @@ import { ApiProperty } from "@nestjs/swagger"; -import { Pair } from "../../../entitites"; +import { Pair } from "./pair"; export class PairResponse { @ApiProperty() diff --git a/apps/api/src/entitites/pair.ts b/libs/common/src/providers/entities/pair.ts similarity index 52% rename from apps/api/src/entitites/pair.ts rename to libs/common/src/providers/entities/pair.ts index 748929c..2d33300 100644 --- a/apps/api/src/entitites/pair.ts +++ b/libs/common/src/providers/entities/pair.ts @@ -1,4 +1,3 @@ -import { XExchangePair } from "@mvx-monorepo/common"; import { ApiProperty } from "@nestjs/swagger"; export class Pair { @@ -37,17 +36,4 @@ export class Pair { @ApiProperty() metadata?: Record; - - static fromXExchangePair(pair: XExchangePair, feePercent: number, deployInfo?: { deployRound?: number, deployTxHash?: string, deployedAt?: number }): Pair { - return { - id: pair.address, - dexKey: 'xexchange', - asset0Id: pair.firstTokenId, - asset1Id: pair.secondTokenId, - feeBps: feePercent * 100, - createdAtBlockNumber: deployInfo?.deployRound, - createdAtBlockTimestamp: deployInfo?.deployedAt, - createdAtTxnId: deployInfo?.deployTxHash, - }; - } } diff --git a/libs/common/src/providers/entities/swap.event.ts b/libs/common/src/providers/entities/swap.event.ts new file mode 100644 index 0000000..1de592c --- /dev/null +++ b/libs/common/src/providers/entities/swap.event.ts @@ -0,0 +1,45 @@ +import { ApiProperty } from "@nestjs/swagger"; + +export class SwapEvent { + @ApiProperty() + eventType!: "swap"; + + @ApiProperty() + txnId!: string; + + @ApiProperty() + txnIndex!: number; + + @ApiProperty() + eventIndex!: number; + + @ApiProperty() + maker!: string; + + @ApiProperty() + pairId!: string; + + @ApiProperty() + asset0In?: number | string; + + @ApiProperty() + asset1In?: number | string; + + @ApiProperty() + asset0Out?: number | string; + + @ApiProperty() + asset1Out?: number | string; + + @ApiProperty() + priceNative!: number | string; + + @ApiProperty() + reserves?: { + asset0: number | string; + asset1: number | string; + }; + + @ApiProperty() + metadata?: Record; +} diff --git a/libs/common/src/providers/index.ts b/libs/common/src/providers/index.ts new file mode 100644 index 0000000..54c5203 --- /dev/null +++ b/libs/common/src/providers/index.ts @@ -0,0 +1,2 @@ +export * from './xexchange'; +export * from './interface'; \ No newline at end of file diff --git a/libs/common/src/providers/interface.ts b/libs/common/src/providers/interface.ts new file mode 100644 index 0000000..09bab5a --- /dev/null +++ b/libs/common/src/providers/interface.ts @@ -0,0 +1,10 @@ +import { JoinExitEvent, PairResponse, SwapEvent } from "./entities"; +import { GeneralEvent } from "@mvx-monorepo/common/providers/entities/general.event"; + +export interface IProviderService { + getPair(address: string): Promise; + getEvents(fromBlockNonce: number, toBlockNonce: number): Promise; + getProviderName(): string; + fromSwapEvent(event: GeneralEvent): SwapEvent; + fromAddRemoveLiquidityEvent(event: GeneralEvent): JoinExitEvent; +} \ No newline at end of file diff --git a/libs/common/src/services/xexchange/abis/pair.abi.json b/libs/common/src/providers/xexchange/abis/pair.abi.json similarity index 100% rename from libs/common/src/services/xexchange/abis/pair.abi.json rename to libs/common/src/providers/xexchange/abis/pair.abi.json diff --git a/libs/common/src/services/xexchange/abis/router.abi.json b/libs/common/src/providers/xexchange/abis/router.abi.json similarity index 100% rename from libs/common/src/services/xexchange/abis/router.abi.json rename to libs/common/src/providers/xexchange/abis/router.abi.json diff --git a/libs/common/src/services/xexchange/entities/xexchange.add.liquidity.event.ts b/libs/common/src/providers/xexchange/entities/xexchange.add.liquidity.event.ts similarity index 56% rename from libs/common/src/services/xexchange/entities/xexchange.add.liquidity.event.ts rename to libs/common/src/providers/xexchange/entities/xexchange.add.liquidity.event.ts index 2e8e84b..e99baac 100644 --- a/libs/common/src/services/xexchange/entities/xexchange.add.liquidity.event.ts +++ b/libs/common/src/providers/xexchange/entities/xexchange.add.liquidity.event.ts @@ -1,9 +1,12 @@ -import { ElasticEvent, ElasticLog } from "../../indexer"; -import { XExchangePair } from "./pair"; +import { ElasticEvent, ElasticLog } from "@mvx-monorepo/common"; +import { XExchangePair } from "./xexchange.pair"; import { XExchangeLiquidityEvent } from "./xexchange.liquidity.event"; export class XExchangeAddLiquidityEvent extends XExchangeLiquidityEvent { constructor(event: ElasticEvent, log: ElasticLog, pair: XExchangePair) { super(event, log, pair, "addLiquidity"); + + const decodedEvent = this.decodeEvent(); + this.caller = decodedEvent.caller.bech32(); } } diff --git a/libs/common/src/services/xexchange/entities/xexchange.liquidity.event.ts b/libs/common/src/providers/xexchange/entities/xexchange.liquidity.event.ts similarity index 82% rename from libs/common/src/services/xexchange/entities/xexchange.liquidity.event.ts rename to libs/common/src/providers/xexchange/entities/xexchange.liquidity.event.ts index 5b617e2..b5faa65 100644 --- a/libs/common/src/services/xexchange/entities/xexchange.liquidity.event.ts +++ b/libs/common/src/providers/xexchange/entities/xexchange.liquidity.event.ts @@ -1,14 +1,9 @@ import { AddressType, BigUIntType, BinaryCodec, FieldDefinition, StructType, TokenIdentifierType, U64Type } from "@multiversx/sdk-core/out"; -import { ElasticEvent, ElasticLog } from "../../indexer"; -import { XExchangeEvent } from "./xexchange.event"; -import { PairEventTopics } from '@multiversx/sdk-exchange'; -import { XExchangePair } from "./pair"; -export class XExchangeLiquidityEvent extends XExchangeEvent { - address: string; - identifier: string; - topics: string[]; - data: string; - decodedTopics: PairEventTopics; +import { ElasticEvent, ElasticLog } from "@mvx-monorepo/common"; +import { GeneralEvent } from "../../entities/general.event"; +import { XExchangePair } from "./xexchange.pair"; + +export class XExchangeLiquidityEvent extends GeneralEvent { caller: string; firstTokenId: string; firstTokenAmount: string; @@ -21,20 +16,13 @@ export class XExchangeLiquidityEvent extends XExchangeEvent { secondTokenReserves: string; block: number; epoch: number; - timestamp: number; txHash: string; txOrder: number; eventOrder: number; pair: XExchangePair; constructor(event: ElasticEvent, log: ElasticLog, pair: XExchangePair, eventType: "addLiquidity" | "removeLiquidity") { - super(eventType); - - this.address = event.address; - this.identifier = event.identifier; - this.topics = event.topics; - this.data = event.data; - this.decodedTopics = new PairEventTopics(this.topics); + super(event, eventType); const decodedEvent = this.decodeEvent(); this.caller = decodedEvent.caller.bech32(); @@ -69,7 +57,7 @@ export class XExchangeLiquidityEvent extends XExchangeEvent { this.pair = pair; } - private decodeEvent() { + protected decodeEvent() { if (this.data == undefined) { throw new Error('Invalid data field'); } @@ -84,7 +72,7 @@ export class XExchangeLiquidityEvent extends XExchangeEvent { } private getStructure(): StructType { - return new StructType('LiquidityEvent', [ + return new StructType('XexchangeLiquidityEvent', [ new FieldDefinition('caller', '', new AddressType()), new FieldDefinition('firstTokenID', '', new TokenIdentifierType()), new FieldDefinition('firstTokenAmount', '', new BigUIntType()), diff --git a/libs/common/src/services/xexchange/entities/pair.ts b/libs/common/src/providers/xexchange/entities/xexchange.pair.ts similarity index 100% rename from libs/common/src/services/xexchange/entities/pair.ts rename to libs/common/src/providers/xexchange/entities/xexchange.pair.ts diff --git a/libs/common/src/services/xexchange/entities/xexchange.remove.liquidity.event.ts b/libs/common/src/providers/xexchange/entities/xexchange.remove.liquidity.event.ts similarity index 57% rename from libs/common/src/services/xexchange/entities/xexchange.remove.liquidity.event.ts rename to libs/common/src/providers/xexchange/entities/xexchange.remove.liquidity.event.ts index 7c19856..428a177 100644 --- a/libs/common/src/services/xexchange/entities/xexchange.remove.liquidity.event.ts +++ b/libs/common/src/providers/xexchange/entities/xexchange.remove.liquidity.event.ts @@ -1,9 +1,12 @@ -import { ElasticEvent, ElasticLog } from "../../indexer"; -import { XExchangePair } from "./pair"; +import { ElasticEvent, ElasticLog } from "@mvx-monorepo/common"; +import { XExchangePair } from "./xexchange.pair"; import { XExchangeLiquidityEvent } from "./xexchange.liquidity.event"; export class XExchangeRemoveLiquidityEvent extends XExchangeLiquidityEvent { constructor(event: ElasticEvent, log: ElasticLog, pair: XExchangePair) { super(event, log, pair, "removeLiquidity"); + + const decodedEvent = this.decodeEvent(); + this.caller = decodedEvent.caller.bech32(); } } diff --git a/libs/common/src/services/xexchange/entities/xexchange.swap.event.ts b/libs/common/src/providers/xexchange/entities/xexchange.swap.event.ts similarity index 80% rename from libs/common/src/services/xexchange/entities/xexchange.swap.event.ts rename to libs/common/src/providers/xexchange/entities/xexchange.swap.event.ts index 5e668b4..7a62018 100644 --- a/libs/common/src/services/xexchange/entities/xexchange.swap.event.ts +++ b/libs/common/src/providers/xexchange/entities/xexchange.swap.event.ts @@ -1,15 +1,9 @@ import { AddressType, BigUIntType, BinaryCodec, FieldDefinition, StructType, TokenIdentifierType, U64Type } from "@multiversx/sdk-core/out"; -import { ElasticEvent, ElasticLog } from "../../indexer"; -import { PairEventTopics } from '@multiversx/sdk-exchange'; -import { XExchangeEvent } from "./xexchange.event"; -import { XExchangePair } from "./pair"; +import { ElasticEvent, ElasticLog } from "@mvx-monorepo/common"; +import { GeneralEvent } from "../../entities/general.event"; +import { XExchangePair } from "./xexchange.pair"; -export class XExchangeSwapEvent extends XExchangeEvent { - address: string; - identifier: string; - topics: string[]; - data: string; - decodedTopics: PairEventTopics; +export class XExchangeSwapEvent extends GeneralEvent { caller: string; tokenInId: string; tokenInAmount: string; @@ -20,20 +14,13 @@ export class XExchangeSwapEvent extends XExchangeEvent { tokenOutReserves: string; block: number; epoch: number; - timestamp: number; txHash: string; txOrder: number; eventOrder: number; pair: XExchangePair; constructor(event: ElasticEvent, log: ElasticLog, pair: XExchangePair) { - super('swap'); - - this.address = event.address; - this.identifier = event.identifier; - this.topics = event.topics; - this.data = event.data; - this.decodedTopics = new PairEventTopics(this.topics); + super(event, 'swap'); const decodedEvent = this.decodeEvent(); this.caller = decodedEvent.caller.bech32(); diff --git a/libs/common/src/services/xexchange/index.ts b/libs/common/src/providers/xexchange/index.ts similarity index 71% rename from libs/common/src/services/xexchange/index.ts rename to libs/common/src/providers/xexchange/index.ts index dfb368d..b4bcb86 100644 --- a/libs/common/src/services/xexchange/index.ts +++ b/libs/common/src/providers/xexchange/index.ts @@ -1,3 +1,3 @@ -export * from './entities'; +export * from '../entities'; export * from './xexchange.module'; export * from './xexchange.service'; diff --git a/libs/common/src/services/xexchange/xexchange.module.ts b/libs/common/src/providers/xexchange/xexchange.module.ts similarity index 84% rename from libs/common/src/services/xexchange/xexchange.module.ts rename to libs/common/src/providers/xexchange/xexchange.module.ts index 13c5ba1..482c705 100644 --- a/libs/common/src/services/xexchange/xexchange.module.ts +++ b/libs/common/src/providers/xexchange/xexchange.module.ts @@ -1,8 +1,8 @@ import { Module } from "@nestjs/common"; import { DynamicModuleUtils } from "@mvx-monorepo/common"; import { XExchangeService } from "./xexchange.service"; -import { IndexerModule } from "../indexer"; -import { MultiversXApiModule } from "../multiversx.api"; +import { IndexerModule } from "../../services/indexer"; +import { MultiversXApiModule } from "../../services/multiversx.api"; @Module({}) export class XExchangeModule { diff --git a/libs/common/src/services/xexchange/xexchange.service.ts b/libs/common/src/providers/xexchange/xexchange.service.ts similarity index 58% rename from libs/common/src/services/xexchange/xexchange.service.ts rename to libs/common/src/providers/xexchange/xexchange.service.ts index 996a741..12065fc 100644 --- a/libs/common/src/services/xexchange/xexchange.service.ts +++ b/libs/common/src/providers/xexchange/xexchange.service.ts @@ -1,22 +1,38 @@ import { AbiRegistry, Address, Interaction, ResultsParser, SmartContract, TypedOutcomeBundle } from "@multiversx/sdk-core/out"; -import { ApiConfigService, ApiMetricsService, CacheInfo, LogPerformanceAsync, MetricsEvents } from "@mvx-monorepo/common"; -import { Injectable } from "@nestjs/common"; +import { + ApiConfigService, + ApiMetricsService, + CacheInfo, JoinExitEvent, + LogPerformanceAsync, + MetricsEvents, Pair, PairResponse, SwapEvent, +} from "@mvx-monorepo/common"; +import { Injectable, NotFoundException } from "@nestjs/common"; import { ApiService } from "@multiversx/sdk-nestjs-http"; import { ContractQueryResponse } from "@multiversx/sdk-network-providers/out"; import { ContractQueryRequest } from "@multiversx/sdk-network-providers/out/contractQueryRequest"; import pairAbi from "./abis/pair.abi.json"; import routerAbi from "./abis/router.abi.json"; -import { PairMetadata, XExchangeAddLiquidityEvent, XExchangePair, XExchangeRemoveLiquidityEvent, XExchangeSwapEvent } from "./entities"; +import { PairMetadata } from "../entities"; import { CacheService } from "@multiversx/sdk-nestjs-cache"; import BigNumber from "bignumber.js"; -import { IndexerService } from "../indexer"; +import { IndexerService } from "../../services/indexer"; import { BinaryUtils, OriginLogger } from "@multiversx/sdk-nestjs-common"; import { PAIR_EVENTS } from "@multiversx/sdk-exchange"; -import { MultiversXApiService } from "../multiversx.api"; +import { MultiversXApiService } from "../../services/multiversx.api"; import { PerformanceProfiler } from "@multiversx/sdk-nestjs-monitoring"; +import { GeneralEvent } from "@mvx-monorepo/common/providers/entities/general.event"; +import { IProviderService } from "@mvx-monorepo/common/providers"; +import { XExchangePair } from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.pair"; +import { XExchangeSwapEvent } from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.swap.event"; +import { + XExchangeAddLiquidityEvent +} from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.add.liquidity.event"; +import { + XExchangeRemoveLiquidityEvent +} from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.remove.liquidity.event"; @Injectable() -export class XExchangeService { +export class XExchangeService implements IProviderService { private readonly SWAP_FEE_PERCENT_BASE_POINTS = 100000; private readonly logger = new OriginLogger(XExchangeService.name); private readonly resultsParser: ResultsParser; @@ -151,7 +167,7 @@ export class XExchangeService { } @LogPerformanceAsync(MetricsEvents.SetXExchangeDuration) - public async getEvents(before: number, after: number): Promise<(XExchangeSwapEvent | XExchangeAddLiquidityEvent | XExchangeRemoveLiquidityEvent)[]> { + public async getEvents(before: number, after: number): Promise { const pairs = await this.getPairs(); const pairAddresses = pairs.map((p) => p.address); @@ -186,7 +202,6 @@ export class XExchangeService { break; default: this.logger.error(`Unknown event topic ${event.topics[0]}. Event: ${JSON.stringify(event)}`); - continue; } } } @@ -194,6 +209,107 @@ export class XExchangeService { return events; } + public async getPair(identifier: string): Promise { + const xExchangePairs = await this.getPairs(); + const xExchangePair = xExchangePairs.find((p) => p.address === identifier); + if (!xExchangePair) { + this.logger.error(`Pair with address ${identifier} not found`); + throw new NotFoundException(`Pair with address ${identifier} not found`); + } + + const pairFeePercent = await this.getPairFeePercent(identifier); + + const { deployTxHash, deployedAt } = await this.multiversXApiService.getContractDeployInfo(identifier); + const round = deployedAt ? await this.indexerService.getRound(deployedAt) : undefined; + + const pair = this.fromCustomPair(xExchangePair, pairFeePercent, { + deployTxHash, + deployedAt, + deployRound: round?.round + }); + return { + pair, + }; + } + + public getProviderName(): string { + return "xExchange"; + } + + private fromCustomPair(pair: XExchangePair, feePercent: number, deployInfo?: { deployRound?: number, deployTxHash?: string, deployedAt?: number }): Pair { + return { + id: pair.address, + dexKey: this.getProviderName(), + asset0Id: pair.firstTokenId, + asset1Id: pair.secondTokenId, + feeBps: feePercent * 100, + createdAtBlockNumber: deployInfo?.deployRound, + createdAtBlockTimestamp: deployInfo?.deployedAt, + createdAtTxnId: deployInfo?.deployTxHash, + }; + } + + public fromSwapEvent(event: XExchangeSwapEvent): SwapEvent { + let asset0In: string | undefined = undefined; + let asset1In: string | undefined = undefined; + let asset0Out: string | undefined = undefined; + let asset1Out: string | undefined = undefined; + let asset0Reserves: string; + let asset1Reserves: string; + let priceNative: string; + + if (event.pair.firstTokenId === event.tokenInId) { + asset0In = new BigNumber(event.tokenInAmount).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); + asset1Out = new BigNumber(event.tokenOutAmount).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); + asset0Reserves = new BigNumber(event.tokenInReserves).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); + asset1Reserves = new BigNumber(event.tokenOutReserves).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); + priceNative = new BigNumber(asset1Reserves).dividedBy(asset0Reserves).toFixed(); + } else { + asset1In = new BigNumber(event.tokenInAmount).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); + asset0Out = new BigNumber(event.tokenOutAmount).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); + asset0Reserves = new BigNumber(event.tokenOutReserves).shiftedBy(-event.pair.firstTokenDecimals).toFixed(); + asset1Reserves = new BigNumber(event.tokenInReserves).shiftedBy(-event.pair.secondTokenDecimals).toFixed(); + priceNative = new BigNumber(asset1Reserves).dividedBy(asset0Reserves).toFixed(); + } + + return { + eventType: "swap", + txnId: event.txHash, + txnIndex: event.txOrder, + eventIndex: event.eventOrder, + maker: event.caller, + pairId: event.address, + asset0In, + asset1In, + asset0Out, + asset1Out, + priceNative, + reserves: { + asset0: asset0Reserves, + asset1: asset1Reserves, + } + }; + } + + public fromAddRemoveLiquidityEvent(event: XExchangeAddLiquidityEvent | XExchangeRemoveLiquidityEvent): JoinExitEvent { + const eventType = event.type === "addLiquidity" ? "join" : "exit"; + + return { + eventType, + txnId: event.txHash, + txnIndex: event.txOrder, + eventIndex: event.eventOrder, + maker: event.caller, + pairId: event.address, + amount0: new BigNumber(event.firstTokenAmount).shiftedBy(-event.pair.firstTokenDecimals).toFixed(), + amount1: new BigNumber(event.secondTokenAmount).shiftedBy(-event.pair.secondTokenDecimals).toFixed(), + reserves: { + asset0: new BigNumber(event.firstTokenReserves).shiftedBy(-event.pair.firstTokenDecimals).toFixed(), + asset1: new BigNumber(event.secondTokenReserves).shiftedBy(-event.pair.secondTokenDecimals).toFixed(), + }, + }; + } + private isPairInverted(firstTokenId: string, secondTokenId: string): boolean { const wegldIdentifier = this.apiConfigService.getWrappedEGLDIdentifier(); const wusdcIdentifier = this.apiConfigService.getWrappedUSDCIdentifier(); diff --git a/libs/common/src/services/index.ts b/libs/common/src/services/index.ts index d4b163c..f088269 100644 --- a/libs/common/src/services/index.ts +++ b/libs/common/src/services/index.ts @@ -1,3 +1,3 @@ export * from './indexer'; export * from './multiversx.api'; -export * from './xexchange'; +export * from '../providers/xexchange'; diff --git a/libs/common/src/services/xexchange/entities/index.ts b/libs/common/src/services/xexchange/entities/index.ts deleted file mode 100644 index 979f2cf..0000000 --- a/libs/common/src/services/xexchange/entities/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './pair'; -export * from './pair.metadata'; -export * from './xexchange.liquidity.event'; -export * from './xexchange.add.liquidity.event'; -export * from './xexchange.remove.liquidity.event'; -export * from './xexchange.swap.event'; diff --git a/libs/common/src/services/xexchange/entities/xexchange.event.ts b/libs/common/src/services/xexchange/entities/xexchange.event.ts deleted file mode 100644 index a445714..0000000 --- a/libs/common/src/services/xexchange/entities/xexchange.event.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class XExchangeEvent { - public readonly type: string; - - constructor(type: "swap" | "addLiquidity" | "removeLiquidity") { - this.type = type; - } -} From 3844870f19218b0e15f704255bad68675eccc1db Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Fri, 29 Mar 2024 18:37:36 +0200 Subject: [PATCH 02/11] fix linter --- .../data-integration/data-integration.service.ts | 13 +++++++------ libs/common/src/providers/index.ts | 2 +- libs/common/src/providers/interface.ts | 2 +- .../src/providers/xexchange/xexchange.service.ts | 8 ++------ 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index be5c04d..3d39c46 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -18,7 +18,7 @@ export class DataIntegrationService { private readonly multiversXApiService: MultiversXApiService, xExchangeService: XExchangeService, ) { - this.providers.push(xExchangeService) + this.providers.push(xExchangeService); } public async getLatestBlock(): Promise { @@ -50,7 +50,8 @@ export class DataIntegrationService { } public async getPair(identifier: string): Promise { - return this.resolveProvider(identifier).getPair(identifier); + const provider = await this.resolveProvider(identifier); + return provider.getPair(identifier); } public async getEvents(fromBlockNonce: number, toBlockNonce: number): Promise { @@ -80,11 +81,11 @@ export class DataIntegrationService { let event: SwapEvent | JoinExitEvent; switch (generalEvent.type) { case "swap": - event = provider.fromSwapEvent(generalEvent) + event = provider.fromSwapEvent(generalEvent); break; case "addLiquidity": case "removeLiquidity": - event = provider.fromAddRemoveLiquidityEvent(generalEvent) + event = provider.fromAddRemoveLiquidityEvent(generalEvent); break; default: this.logger.error(`Unknown event type: ${generalEvent.type} for event: ${JSON.stringify(generalEvent)}`); @@ -104,8 +105,8 @@ export class DataIntegrationService { return events; } - private resolveProvider(identifier: string): IProviderService { - const provider = this.providers.find((p) => p.getPair(identifier) !== undefined); + private async resolveProvider(identifier: string): Promise { + const provider = this.providers.find(async (p) => await p.getPair(identifier) !== undefined); if (!provider) { this.logger.error(`Provider with identifier ${identifier} not found`); throw new NotFoundException(`Provider with identifier ${identifier} not found`); diff --git a/libs/common/src/providers/index.ts b/libs/common/src/providers/index.ts index 54c5203..c492ba6 100644 --- a/libs/common/src/providers/index.ts +++ b/libs/common/src/providers/index.ts @@ -1,2 +1,2 @@ export * from './xexchange'; -export * from './interface'; \ No newline at end of file +export * from './interface'; diff --git a/libs/common/src/providers/interface.ts b/libs/common/src/providers/interface.ts index 09bab5a..c82a250 100644 --- a/libs/common/src/providers/interface.ts +++ b/libs/common/src/providers/interface.ts @@ -7,4 +7,4 @@ export interface IProviderService { getProviderName(): string; fromSwapEvent(event: GeneralEvent): SwapEvent; fromAddRemoveLiquidityEvent(event: GeneralEvent): JoinExitEvent; -} \ No newline at end of file +} diff --git a/libs/common/src/providers/xexchange/xexchange.service.ts b/libs/common/src/providers/xexchange/xexchange.service.ts index 12065fc..67770e1 100644 --- a/libs/common/src/providers/xexchange/xexchange.service.ts +++ b/libs/common/src/providers/xexchange/xexchange.service.ts @@ -24,12 +24,8 @@ import { GeneralEvent } from "@mvx-monorepo/common/providers/entities/general.ev import { IProviderService } from "@mvx-monorepo/common/providers"; import { XExchangePair } from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.pair"; import { XExchangeSwapEvent } from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.swap.event"; -import { - XExchangeAddLiquidityEvent -} from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.add.liquidity.event"; -import { - XExchangeRemoveLiquidityEvent -} from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.remove.liquidity.event"; +import { XExchangeAddLiquidityEvent } from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.add.liquidity.event"; +import { XExchangeRemoveLiquidityEvent } from "@mvx-monorepo/common/providers/xexchange/entities/xexchange.remove.liquidity.event"; @Injectable() export class XExchangeService implements IProviderService { From e7f56de496e195c10328168a847abd0efb36ebf7 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Fri, 29 Mar 2024 18:40:06 +0200 Subject: [PATCH 03/11] fix linter --- libs/common/src/providers/xexchange/xexchange.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/common/src/providers/xexchange/xexchange.service.ts b/libs/common/src/providers/xexchange/xexchange.service.ts index 67770e1..0907e63 100644 --- a/libs/common/src/providers/xexchange/xexchange.service.ts +++ b/libs/common/src/providers/xexchange/xexchange.service.ts @@ -221,7 +221,7 @@ export class XExchangeService implements IProviderService { const pair = this.fromCustomPair(xExchangePair, pairFeePercent, { deployTxHash, deployedAt, - deployRound: round?.round + deployRound: round?.round, }); return { pair, @@ -283,7 +283,7 @@ export class XExchangeService implements IProviderService { reserves: { asset0: asset0Reserves, asset1: asset1Reserves, - } + }, }; } From ec8b5da349fcb7c5c952723c46bcd378fc713ce2 Mon Sep 17 00:00:00 2001 From: dragosrebegea Date: Fri, 29 Mar 2024 18:42:26 +0200 Subject: [PATCH 04/11] fix linter --- .../data-integration/data-integration.service.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index 3d39c46..4eba2a9 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -106,12 +106,13 @@ export class DataIntegrationService { } private async resolveProvider(identifier: string): Promise { - const provider = this.providers.find(async (p) => await p.getPair(identifier) !== undefined); - if (!provider) { - this.logger.error(`Provider with identifier ${identifier} not found`); - throw new NotFoundException(`Provider with identifier ${identifier} not found`); + for (const provider of this.providers) { + if (await provider.getPair(identifier) !== undefined) { + return provider; + } } - return provider; + this.logger.error(`Provider with identifier ${identifier} not found`); + throw new NotFoundException(`Provider with identifier ${identifier} not found`); } } From a71d717354f10221429f55a390ed29d638f70ae5 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Fri, 29 Mar 2024 19:17:15 +0200 Subject: [PATCH 05/11] fixes --- .../data-integration.service.ts | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index 4eba2a9..91b548b 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -18,7 +18,9 @@ export class DataIntegrationService { private readonly multiversXApiService: MultiversXApiService, xExchangeService: XExchangeService, ) { - this.providers.push(xExchangeService); + this.providers = [ + xExchangeService, + ]; } public async getLatestBlock(): Promise { @@ -50,8 +52,15 @@ export class DataIntegrationService { } public async getPair(identifier: string): Promise { - const provider = await this.resolveProvider(identifier); - return provider.getPair(identifier); + for (const provider of this.providers) { + const pairResponse = await provider.getPair(identifier); + if (pairResponse) { + return pairResponse; + } + } + + this.logger.error(`Pair with identifier ${identifier} not found`); + throw new NotFoundException(`Pair with identifier ${identifier} not found`); } public async getEvents(fromBlockNonce: number, toBlockNonce: number): Promise { @@ -64,15 +73,16 @@ export class DataIntegrationService { const after = rounds[0].timestamp; const before = rounds[rounds.length - 1].timestamp; - const response = new EventsResponse(); - + const allEvents: ({ block: Block } & (SwapEvent | JoinExitEvent))[] = []; for (const provider of this.providers) { const generalEvents = await provider.getEvents(before, after); const event = this.processEvents(generalEvents, provider, rounds); - response.events.push(...event); + allEvents.push(...event); } - return response; + return { + events: allEvents, + }; } private processEvents(generalEvents: GeneralEvent[], provider: IProviderService, rounds: ElasticRound[]): ({ block: Block } & (SwapEvent | JoinExitEvent))[] { @@ -104,15 +114,4 @@ export class DataIntegrationService { } return events; } - - private async resolveProvider(identifier: string): Promise { - for (const provider of this.providers) { - if (await provider.getPair(identifier) !== undefined) { - return provider; - } - } - - this.logger.error(`Provider with identifier ${identifier} not found`); - throw new NotFoundException(`Provider with identifier ${identifier} not found`); - } } From b807d4c01f972b4aa1715abb33ee862d8adc31d2 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Sat, 30 Mar 2024 09:31:22 +0200 Subject: [PATCH 06/11] sort events and apply index --- .../data-integration.service.ts | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index 91b548b..8f36f9d 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -80,8 +80,27 @@ export class DataIntegrationService { allEvents.push(...event); } + const sortedEvents = allEvents.sort((a, b) => { + if (a.block.blockTimestamp !== b.block.blockTimestamp) { + return a.block.blockTimestamp - b.block.blockTimestamp; + } + return a.txnId.localeCompare(b.txnId); + }); + + let txnIndex = 0; + let lastBlockTimestamp = 0; + for (const event of sortedEvents) { + if (event.block.blockTimestamp !== lastBlockTimestamp) { + txnIndex = 0; + } else { + txnIndex++; + } + event.txnIndex = txnIndex; + lastBlockTimestamp = event.block.blockTimestamp; + } + return { - events: allEvents, + events: sortedEvents, }; } From 0e3a96e00528a7e1f97a2d8ed61771d0efa91057 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Fri, 12 Apr 2024 11:04:37 +0300 Subject: [PATCH 07/11] update packages --- package-lock.json | 284 ++++++++++++++++------------------------------ package.json | 18 +-- 2 files changed, 106 insertions(+), 196 deletions(-) diff --git a/package-lock.json b/package-lock.json index c5eba62..051f52b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,14 +11,14 @@ "dependencies": { "@multiversx/sdk-core": "^12.15.0", "@multiversx/sdk-exchange": "^0.2.20", - "@multiversx/sdk-nestjs-auth": "3.2.0", - "@multiversx/sdk-nestjs-cache": "3.2.0", - "@multiversx/sdk-nestjs-common": "3.2.0", - "@multiversx/sdk-nestjs-elastic": "3.2.0", - "@multiversx/sdk-nestjs-http": "3.2.0", - "@multiversx/sdk-nestjs-monitoring": "3.2.0", - "@multiversx/sdk-nestjs-rabbitmq": "3.2.0", - "@multiversx/sdk-nestjs-redis": "3.2.0", + "@multiversx/sdk-nestjs-auth": "3.4.1", + "@multiversx/sdk-nestjs-cache": "3.4.1", + "@multiversx/sdk-nestjs-common": "3.4.1", + "@multiversx/sdk-nestjs-elastic": "3.4.1", + "@multiversx/sdk-nestjs-http": "3.4.1", + "@multiversx/sdk-nestjs-monitoring": "3.4.1", + "@multiversx/sdk-nestjs-rabbitmq": "3.4.1", + "@multiversx/sdk-nestjs-redis": "3.4.1", "@multiversx/sdk-network-providers": "^2.2.0", "@multiversx/sdk-transaction-processor": "^0.1.30", "@nestjs/bull": "^10.0.1", @@ -1796,73 +1796,38 @@ } }, "node_modules/@multiversx/sdk-native-auth-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.7.tgz", - "integrity": "sha512-Fl/4DcM8tJ4dULIu03lMfi875qatGMe8DLg6HglQRB+2s5YoW3NrWkqKNrIbG0CbYCaCH9Sk5nOZkZse8FwNQg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.8.tgz", + "integrity": "sha512-anXcQplVp3/m2rBH4oGQZNIhk0m/J45SomubNMCgSzepJ2PU5E5eQLYletvSDObhTGfRnNCF8edAldkDP9a4Kw==", "dependencies": { - "axios": "^1.6.5" + "axios": "^1.6.8" } }, "node_modules/@multiversx/sdk-native-auth-server": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-1.0.16.tgz", - "integrity": "sha512-z04tbyoZGC1U7FpGJ5kPJXYYz1bMRg0N7LnL0HaTxfEmHNivbqrU01Snp3+kx7CjSyl1yji32ftJrTBQhlXQpg==", + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-1.0.17.tgz", + "integrity": "sha512-jdYTrOaxI75pgXfHP3jlb7n+4OpPOPtx8MPA0KGmk+P0QeCU5z92vhJYbX3GyL20D+BAcXqZqsPhTBzbH8/jTg==", "dependencies": { - "@multiversx/sdk-wallet": "^2.1.1", - "axios": "^1.6.5", + "@multiversx/sdk-wallet": "^4.4.0", + "axios": "^1.6.8", "bech32": "^2.0.0" }, "peerDependencies": { "@multiversx/sdk-core": "^12.x" } }, - "node_modules/@multiversx/sdk-native-auth-server/node_modules/@multiversx/sdk-wallet": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-2.1.3.tgz", - "integrity": "sha512-cCCu3KowX14s6O5ATbZ3hkK6AYoy+lOSaw5IMqJTuTx9QsnFDgLW2G3GyFFueY66qti6fCVXXzWJZ4uGSnnmGQ==", - "dependencies": { - "@multiversx/sdk-bls-wasm": "0.3.5", - "bech32": "1.1.4", - "bip39": "3.0.2", - "blake2b": "2.1.3", - "ed25519-hd-key": "1.1.2", - "ed2curve": "0.3.0", - "keccak": "3.0.1", - "scryptsy": "2.1.0", - "tweetnacl": "1.0.3", - "uuid": "8.3.2" - } - }, - "node_modules/@multiversx/sdk-native-auth-server/node_modules/@multiversx/sdk-wallet/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, "node_modules/@multiversx/sdk-native-auth-server/node_modules/bech32": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" }, - "node_modules/@multiversx/sdk-native-auth-server/node_modules/keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@multiversx/sdk-nestjs-auth": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-3.2.0.tgz", - "integrity": "sha512-R26yq67VmImtGbLLtMiSbkciyNz5BkyQ1Jo9bE1G4SjIpccqDue5WEYfZ2onVFHRSAAvROvo8AlmCC+Km5/eow==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-3.4.1.tgz", + "integrity": "sha512-DcVvo4hX+Co0kWW7SXNvpcEIfozf5/vMwJV2HboQCQmZwfg2KhXsQ1mSRmGglqbsrGQ7cyAXelvfaag6qDmeQQ==", "dependencies": { "@multiversx/sdk-core": "^12.15.0", - "@multiversx/sdk-native-auth-server": "^1.0.14", + "@multiversx/sdk-native-auth-server": "^1.0.17", "@multiversx/sdk-wallet": "^4.2.0", "jsonwebtoken": "^9.0.0" }, @@ -1874,9 +1839,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-3.2.0.tgz", - "integrity": "sha512-8OsemeTmzuatgvGrTBEQq1FyTftvrzKRAihHDq93uuR9n8OTGOo6PO2r48ym5XutyxpG2xf89Otg5xgAMOueNg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-3.4.1.tgz", + "integrity": "sha512-UmcZlX22mTNEEVRXo97aRaSkSCXT3WrZF0ctd/ave2GPJnSHW4VO3/PLeU+UXKqi96HMTqbGRHBrfT/sryO9QQ==", "dependencies": { "lru-cache": "^8.0.4", "moment": "^2.29.4", @@ -1893,12 +1858,12 @@ } }, "node_modules/@multiversx/sdk-nestjs-common": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-3.2.0.tgz", - "integrity": "sha512-ZxvGlD7lkuGLSJnUnIx75+LrY+bB7IhU0uunkgAdTUo6ty40ZdydOrtstb8TACDebTDy/wOhBaQ6a2LqZPLfgA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-3.4.1.tgz", + "integrity": "sha512-0MNMsTcH0SOqVopoKVhGDSVq6MK79vnvSamSCAHohOCu9CS74S1tvP2ED+9myTTxwo9S4QwlXLZpd/gtn5DR9Q==", "dependencies": { "@multiversx/sdk-core": "^12.15.0", - "@multiversx/sdk-network-providers": "^2.2.1", + "@multiversx/sdk-network-providers": "^2.4.3", "nest-winston": "^1.6.2", "uuid": "^8.3.2", "winston": "^3.7.2" @@ -1912,22 +1877,22 @@ } }, "node_modules/@multiversx/sdk-nestjs-elastic": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-3.2.0.tgz", - "integrity": "sha512-sAN27n/xQBxK47eGYcIXLKttINhCdQSQlBqxiYRpjeXdWF5ItYOyYePfq43e0a1z3vOSFoA8qb31llioAx6IqA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-3.4.1.tgz", + "integrity": "sha512-n5HJyuyhrLeNcSEyZToBcB1YRyN7qzMGRPdkcYtyOtgCYKGjAO1bUhTWteQlh8JmE/RQfFwhH4AMbq/41iE0AQ==", "peerDependencies": { - "@multiversx/sdk-nestjs-http": "^3.0.0", + "@multiversx/sdk-nestjs-http": "^3.2.1", "@nestjs/common": "^10.x" } }, "node_modules/@multiversx/sdk-nestjs-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-3.2.0.tgz", - "integrity": "sha512-CVlabuwnI3l1FaKhQ4ngOnBwlucv2mas3eDnpahlOPOSz4gSuavo+ICBbXcjD4MWzbv2bAFsXjeMrarcW+CEDQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-3.4.1.tgz", + "integrity": "sha512-53RwwGUpiR6Pz6CGFATYam0G59kbzJpQhrzjr3mswe1E2hoND/j23k6FXYc6rHJB7fyP1sx4cOm523sCw3jEmw==", "dependencies": { - "@multiversx/sdk-native-auth-client": "^1.0.7", + "@multiversx/sdk-native-auth-client": "^1.0.8", "agentkeepalive": "^4.3.0", - "axios": "^1.6.5" + "axios": "^1.6.8" }, "peerDependencies": { "@multiversx/sdk-nestjs-common": "^3.0.0", @@ -1937,9 +1902,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-monitoring": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-3.2.0.tgz", - "integrity": "sha512-+wITgH41C+njD84VSXTsTcP3+WVTO1wGblQugX1lfdQQcYZeuEFeGs7wmqktLqIM/WxJ7S96T+oHU/EDEIIiLw==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-3.4.1.tgz", + "integrity": "sha512-29V5jl7UJBn4ceqbagv0BW7HdZXudWopyMrQuefI6L2kaPlYPx7Ga69SSk2Lsu1TRvZSMNCBrABlCRO2tGxYqw==", "dependencies": { "prom-client": "^14.0.1", "winston": "^3.7.2", @@ -1950,9 +1915,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-rabbitmq": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-3.2.0.tgz", - "integrity": "sha512-8Jt5yOZedDiIJGkpKHmFesw1ahDy9OB6i8+1TsjTPibQEmGeHm2z29JLuF0iRp3EdfDHSQ3K1PEhtdePu1kBLg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-3.4.1.tgz", + "integrity": "sha512-c3c/9IrGwjLLOh+JnKx4T4M7e06H7EskRAieCpEWhvu3AMIZWfheq/eDqRecJQ/soxkxyXEdikgCeLKUFTeH5A==", "dependencies": { "@golevelup/nestjs-rabbitmq": "4.0.0", "uuid": "^8.3.2" @@ -1963,9 +1928,9 @@ } }, "node_modules/@multiversx/sdk-nestjs-redis": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-3.2.0.tgz", - "integrity": "sha512-MARLdZva0AIIe5IaOn4BaKb2QgOfXnBMra/Rcn4xVLIsTidg6vWThnYh+qOyx6/LkhBu8qwmQkUf6ojedSU+pQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-3.4.1.tgz", + "integrity": "sha512-VbQB/pRi9AzT0/THwiNg1eCjdD+22hGjOJHgxlaSTwvE5ex9LkbYJd5dpW/CHZ65mYDHvsnoSNw3FiQ84isIwA==", "dependencies": { "ioredis": "^5.2.3" }, @@ -1974,27 +1939,17 @@ } }, "node_modules/@multiversx/sdk-network-providers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.3.0.tgz", - "integrity": "sha512-dY7HI3rMgHHulxY9XR/O6/tCWji6ZvkuetW0NmLUjFnfOtkIdnhUzQ0u5wZaMN0SeuJIWf1QPZEsiGN82ilfTQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.4.3.tgz", + "integrity": "sha512-tJmJuxU+BjtC2q29PuzQOM4Qr6aiXujKwQXgIAPHTiuNbMc3Yi6Q4B0DC1PfI3iG+M4DONwfXknvM1uwqnY2zA==", "dependencies": { - "axios": "1.6.5", + "axios": "1.6.8", "bech32": "1.1.4", "bignumber.js": "9.0.1", "buffer": "6.0.3", "json-bigint": "1.0.0" } }, - "node_modules/@multiversx/sdk-network-providers/node_modules/axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", - "dependencies": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/@multiversx/sdk-transaction-decoder": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@multiversx/sdk-transaction-decoder/-/sdk-transaction-decoder-1.0.2.tgz", @@ -2017,9 +1972,9 @@ } }, "node_modules/@multiversx/sdk-wallet": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-4.2.0.tgz", - "integrity": "sha512-EjSb9AnqMcpmDjZ7ebkUpOzpTfxj1plTuVXwZ6AaqJsdpxMfrE2izbPy18+bg5xFlr8V27wYZcW8zOhkBR50BA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-4.4.0.tgz", + "integrity": "sha512-wS4P8a2ts3cNaSLUw9VFf4yhWSMTYng+nyHKi3/9QalLP5lxBumUfD/mUkb9sK13UPJ5Xp/zB3j8a4Qdllw2Ag==", "dependencies": { "@multiversx/sdk-bls-wasm": "0.3.5", "@noble/ed25519": "1.7.3", @@ -12729,78 +12684,45 @@ } }, "@multiversx/sdk-native-auth-client": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.7.tgz", - "integrity": "sha512-Fl/4DcM8tJ4dULIu03lMfi875qatGMe8DLg6HglQRB+2s5YoW3NrWkqKNrIbG0CbYCaCH9Sk5nOZkZse8FwNQg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-client/-/sdk-native-auth-client-1.0.8.tgz", + "integrity": "sha512-anXcQplVp3/m2rBH4oGQZNIhk0m/J45SomubNMCgSzepJ2PU5E5eQLYletvSDObhTGfRnNCF8edAldkDP9a4Kw==", "requires": { - "axios": "^1.6.5" + "axios": "^1.6.8" } }, "@multiversx/sdk-native-auth-server": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-1.0.16.tgz", - "integrity": "sha512-z04tbyoZGC1U7FpGJ5kPJXYYz1bMRg0N7LnL0HaTxfEmHNivbqrU01Snp3+kx7CjSyl1yji32ftJrTBQhlXQpg==", + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-native-auth-server/-/sdk-native-auth-server-1.0.17.tgz", + "integrity": "sha512-jdYTrOaxI75pgXfHP3jlb7n+4OpPOPtx8MPA0KGmk+P0QeCU5z92vhJYbX3GyL20D+BAcXqZqsPhTBzbH8/jTg==", "requires": { - "@multiversx/sdk-wallet": "^2.1.1", - "axios": "^1.6.5", + "@multiversx/sdk-wallet": "^4.4.0", + "axios": "^1.6.8", "bech32": "^2.0.0" }, "dependencies": { - "@multiversx/sdk-wallet": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-2.1.3.tgz", - "integrity": "sha512-cCCu3KowX14s6O5ATbZ3hkK6AYoy+lOSaw5IMqJTuTx9QsnFDgLW2G3GyFFueY66qti6fCVXXzWJZ4uGSnnmGQ==", - "requires": { - "@multiversx/sdk-bls-wasm": "0.3.5", - "bech32": "1.1.4", - "bip39": "3.0.2", - "blake2b": "2.1.3", - "ed25519-hd-key": "1.1.2", - "ed2curve": "0.3.0", - "keccak": "3.0.1", - "scryptsy": "2.1.0", - "tweetnacl": "1.0.3", - "uuid": "8.3.2" - }, - "dependencies": { - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - } - } - }, "bech32": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "keccak": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", - "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } } } }, "@multiversx/sdk-nestjs-auth": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-3.2.0.tgz", - "integrity": "sha512-R26yq67VmImtGbLLtMiSbkciyNz5BkyQ1Jo9bE1G4SjIpccqDue5WEYfZ2onVFHRSAAvROvo8AlmCC+Km5/eow==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-auth/-/sdk-nestjs-auth-3.4.1.tgz", + "integrity": "sha512-DcVvo4hX+Co0kWW7SXNvpcEIfozf5/vMwJV2HboQCQmZwfg2KhXsQ1mSRmGglqbsrGQ7cyAXelvfaag6qDmeQQ==", "requires": { "@multiversx/sdk-core": "^12.15.0", - "@multiversx/sdk-native-auth-server": "^1.0.14", + "@multiversx/sdk-native-auth-server": "^1.0.17", "@multiversx/sdk-wallet": "^4.2.0", "jsonwebtoken": "^9.0.0" } }, "@multiversx/sdk-nestjs-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-3.2.0.tgz", - "integrity": "sha512-8OsemeTmzuatgvGrTBEQq1FyTftvrzKRAihHDq93uuR9n8OTGOo6PO2r48ym5XutyxpG2xf89Otg5xgAMOueNg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-cache/-/sdk-nestjs-cache-3.4.1.tgz", + "integrity": "sha512-UmcZlX22mTNEEVRXo97aRaSkSCXT3WrZF0ctd/ave2GPJnSHW4VO3/PLeU+UXKqi96HMTqbGRHBrfT/sryO9QQ==", "requires": { "lru-cache": "^8.0.4", "moment": "^2.29.4", @@ -12810,37 +12732,37 @@ } }, "@multiversx/sdk-nestjs-common": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-3.2.0.tgz", - "integrity": "sha512-ZxvGlD7lkuGLSJnUnIx75+LrY+bB7IhU0uunkgAdTUo6ty40ZdydOrtstb8TACDebTDy/wOhBaQ6a2LqZPLfgA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-common/-/sdk-nestjs-common-3.4.1.tgz", + "integrity": "sha512-0MNMsTcH0SOqVopoKVhGDSVq6MK79vnvSamSCAHohOCu9CS74S1tvP2ED+9myTTxwo9S4QwlXLZpd/gtn5DR9Q==", "requires": { "@multiversx/sdk-core": "^12.15.0", - "@multiversx/sdk-network-providers": "^2.2.1", + "@multiversx/sdk-network-providers": "^2.4.3", "nest-winston": "^1.6.2", "uuid": "^8.3.2", "winston": "^3.7.2" } }, "@multiversx/sdk-nestjs-elastic": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-3.2.0.tgz", - "integrity": "sha512-sAN27n/xQBxK47eGYcIXLKttINhCdQSQlBqxiYRpjeXdWF5ItYOyYePfq43e0a1z3vOSFoA8qb31llioAx6IqA==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-elastic/-/sdk-nestjs-elastic-3.4.1.tgz", + "integrity": "sha512-n5HJyuyhrLeNcSEyZToBcB1YRyN7qzMGRPdkcYtyOtgCYKGjAO1bUhTWteQlh8JmE/RQfFwhH4AMbq/41iE0AQ==", "requires": {} }, "@multiversx/sdk-nestjs-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-3.2.0.tgz", - "integrity": "sha512-CVlabuwnI3l1FaKhQ4ngOnBwlucv2mas3eDnpahlOPOSz4gSuavo+ICBbXcjD4MWzbv2bAFsXjeMrarcW+CEDQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-http/-/sdk-nestjs-http-3.4.1.tgz", + "integrity": "sha512-53RwwGUpiR6Pz6CGFATYam0G59kbzJpQhrzjr3mswe1E2hoND/j23k6FXYc6rHJB7fyP1sx4cOm523sCw3jEmw==", "requires": { - "@multiversx/sdk-native-auth-client": "^1.0.7", + "@multiversx/sdk-native-auth-client": "^1.0.8", "agentkeepalive": "^4.3.0", - "axios": "^1.6.5" + "axios": "^1.6.8" } }, "@multiversx/sdk-nestjs-monitoring": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-3.2.0.tgz", - "integrity": "sha512-+wITgH41C+njD84VSXTsTcP3+WVTO1wGblQugX1lfdQQcYZeuEFeGs7wmqktLqIM/WxJ7S96T+oHU/EDEIIiLw==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-monitoring/-/sdk-nestjs-monitoring-3.4.1.tgz", + "integrity": "sha512-29V5jl7UJBn4ceqbagv0BW7HdZXudWopyMrQuefI6L2kaPlYPx7Ga69SSk2Lsu1TRvZSMNCBrABlCRO2tGxYqw==", "requires": { "prom-client": "^14.0.1", "winston": "^3.7.2", @@ -12848,44 +12770,32 @@ } }, "@multiversx/sdk-nestjs-rabbitmq": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-3.2.0.tgz", - "integrity": "sha512-8Jt5yOZedDiIJGkpKHmFesw1ahDy9OB6i8+1TsjTPibQEmGeHm2z29JLuF0iRp3EdfDHSQ3K1PEhtdePu1kBLg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-rabbitmq/-/sdk-nestjs-rabbitmq-3.4.1.tgz", + "integrity": "sha512-c3c/9IrGwjLLOh+JnKx4T4M7e06H7EskRAieCpEWhvu3AMIZWfheq/eDqRecJQ/soxkxyXEdikgCeLKUFTeH5A==", "requires": { "@golevelup/nestjs-rabbitmq": "4.0.0", "uuid": "^8.3.2" } }, "@multiversx/sdk-nestjs-redis": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-3.2.0.tgz", - "integrity": "sha512-MARLdZva0AIIe5IaOn4BaKb2QgOfXnBMra/Rcn4xVLIsTidg6vWThnYh+qOyx6/LkhBu8qwmQkUf6ojedSU+pQ==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-nestjs-redis/-/sdk-nestjs-redis-3.4.1.tgz", + "integrity": "sha512-VbQB/pRi9AzT0/THwiNg1eCjdD+22hGjOJHgxlaSTwvE5ex9LkbYJd5dpW/CHZ65mYDHvsnoSNw3FiQ84isIwA==", "requires": { "ioredis": "^5.2.3" } }, "@multiversx/sdk-network-providers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.3.0.tgz", - "integrity": "sha512-dY7HI3rMgHHulxY9XR/O6/tCWji6ZvkuetW0NmLUjFnfOtkIdnhUzQ0u5wZaMN0SeuJIWf1QPZEsiGN82ilfTQ==", + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-network-providers/-/sdk-network-providers-2.4.3.tgz", + "integrity": "sha512-tJmJuxU+BjtC2q29PuzQOM4Qr6aiXujKwQXgIAPHTiuNbMc3Yi6Q4B0DC1PfI3iG+M4DONwfXknvM1uwqnY2zA==", "requires": { - "axios": "1.6.5", + "axios": "1.6.8", "bech32": "1.1.4", "bignumber.js": "9.0.1", "buffer": "6.0.3", "json-bigint": "1.0.0" - }, - "dependencies": { - "axios": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", - "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", - "requires": { - "follow-redirects": "^1.15.4", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - } } }, "@multiversx/sdk-transaction-decoder": { @@ -12912,9 +12822,9 @@ } }, "@multiversx/sdk-wallet": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-4.2.0.tgz", - "integrity": "sha512-EjSb9AnqMcpmDjZ7ebkUpOzpTfxj1plTuVXwZ6AaqJsdpxMfrE2izbPy18+bg5xFlr8V27wYZcW8zOhkBR50BA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@multiversx/sdk-wallet/-/sdk-wallet-4.4.0.tgz", + "integrity": "sha512-wS4P8a2ts3cNaSLUw9VFf4yhWSMTYng+nyHKi3/9QalLP5lxBumUfD/mUkb9sK13UPJ5Xp/zB3j8a4Qdllw2Ag==", "requires": { "@multiversx/sdk-bls-wasm": "0.3.5", "@noble/ed25519": "1.7.3", diff --git a/package.json b/package.json index 79c37eb..6e0b1be 100644 --- a/package.json +++ b/package.json @@ -27,14 +27,14 @@ "dependencies": { "@multiversx/sdk-core": "^12.15.0", "@multiversx/sdk-exchange": "^0.2.20", - "@multiversx/sdk-nestjs-auth": "3.2.0", - "@multiversx/sdk-nestjs-cache": "3.2.0", - "@multiversx/sdk-nestjs-common": "3.2.0", - "@multiversx/sdk-nestjs-elastic": "3.2.0", - "@multiversx/sdk-nestjs-http": "3.2.0", - "@multiversx/sdk-nestjs-monitoring": "3.2.0", - "@multiversx/sdk-nestjs-rabbitmq": "3.2.0", - "@multiversx/sdk-nestjs-redis": "3.2.0", + "@multiversx/sdk-nestjs-auth": "3.4.1", + "@multiversx/sdk-nestjs-cache": "3.4.1", + "@multiversx/sdk-nestjs-common": "3.4.1", + "@multiversx/sdk-nestjs-elastic": "3.4.1", + "@multiversx/sdk-nestjs-http": "3.4.1", + "@multiversx/sdk-nestjs-monitoring": "3.4.1", + "@multiversx/sdk-nestjs-rabbitmq": "3.4.1", + "@multiversx/sdk-nestjs-redis": "3.4.1", "@multiversx/sdk-network-providers": "^2.2.0", "@multiversx/sdk-transaction-processor": "^0.1.30", "@nestjs/bull": "^10.0.1", @@ -123,4 +123,4 @@ "^@mvx-monorepo/common": "/libs/common" } } -} +} \ No newline at end of file From 5f5b0193c485dedcf7172bb5784396a9d83db30b Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Fri, 12 Apr 2024 11:33:20 +0300 Subject: [PATCH 08/11] update elastic query --- libs/common/src/services/indexer/entities/elastic.round.ts | 2 +- libs/common/src/services/indexer/indexer.service.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/common/src/services/indexer/entities/elastic.round.ts b/libs/common/src/services/indexer/entities/elastic.round.ts index 3c756fa..8c9421c 100644 --- a/libs/common/src/services/indexer/entities/elastic.round.ts +++ b/libs/common/src/services/indexer/entities/elastic.round.ts @@ -1,5 +1,5 @@ export interface ElasticRound { round: number; epoch: number; - timestamp: number; + timestamp: string; } diff --git a/libs/common/src/services/indexer/indexer.service.ts b/libs/common/src/services/indexer/indexer.service.ts index ddfec08..80f8c62 100644 --- a/libs/common/src/services/indexer/indexer.service.ts +++ b/libs/common/src/services/indexer/indexer.service.ts @@ -29,7 +29,7 @@ export class IndexerService { const query = ElasticQuery.create() .withPagination({ from: 0, size: 1 }) .withFields(['round', 'epoch', 'timestamp']) - .withMustCondition(new MatchQuery('timestamp', timestamp)); + .withMustCondition(new MatchQuery('timestamp', timestamp.toString())); const rounds = await this.elasticService.getList('rounds', 'id', query); return rounds.length > 0 ? rounds[0] : undefined; From 5364f381d393ab693d53c81b05a84a266c913945 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Fri, 12 Apr 2024 11:42:34 +0300 Subject: [PATCH 09/11] fixes --- .../endpoints/data-integration/data-integration.service.ts | 6 +++--- libs/common/src/providers/entities/block.ts | 4 ++-- libs/common/src/providers/interface.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index 8f36f9d..f21b145 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -70,8 +70,8 @@ export class DataIntegrationService { events: [], }; } - const after = rounds[0].timestamp; - const before = rounds[rounds.length - 1].timestamp; + const after = parseInt(rounds[0].timestamp); + const before = parseInt(rounds[rounds.length - 1].timestamp); const allEvents: ({ block: Block } & (SwapEvent | JoinExitEvent))[] = []; for (const provider of this.providers) { @@ -120,7 +120,7 @@ export class DataIntegrationService { this.logger.error(`Unknown event type: ${generalEvent.type} for event: ${JSON.stringify(generalEvent)}`); continue; } - const round = rounds.find((round: { timestamp: number; }) => round.timestamp === generalEvent.timestamp); + const round = rounds.find((round: { timestamp: string }) => round.timestamp === generalEvent.timestamp.toString()); if (!round) { this.logger.error(`Round not found for event: ${JSON.stringify(generalEvent)}`); continue; diff --git a/libs/common/src/providers/entities/block.ts b/libs/common/src/providers/entities/block.ts index 119ece4..c7a0cc4 100644 --- a/libs/common/src/providers/entities/block.ts +++ b/libs/common/src/providers/entities/block.ts @@ -15,13 +15,13 @@ export class Block { if (options?.onlyRequiredFields) { return { blockNumber: round.round, - blockTimestamp: round.timestamp, + blockTimestamp: parseInt(round.timestamp), }; } return { blockNumber: round.round, - blockTimestamp: round.timestamp, + blockTimestamp: parseInt(round.timestamp), metadata: { epoch: round.epoch.toString(), }, diff --git a/libs/common/src/providers/interface.ts b/libs/common/src/providers/interface.ts index c82a250..f7c6977 100644 --- a/libs/common/src/providers/interface.ts +++ b/libs/common/src/providers/interface.ts @@ -3,7 +3,7 @@ import { GeneralEvent } from "@mvx-monorepo/common/providers/entities/general.ev export interface IProviderService { getPair(address: string): Promise; - getEvents(fromBlockNonce: number, toBlockNonce: number): Promise; + getEvents(before: number, after: number): Promise; getProviderName(): string; fromSwapEvent(event: GeneralEvent): SwapEvent; fromAddRemoveLiquidityEvent(event: GeneralEvent): JoinExitEvent; From 8782be192a6e3fc74b4769c310a193fe0b356eb1 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Fri, 27 Sep 2024 12:17:40 +0300 Subject: [PATCH 10/11] fixes --- .../endpoints/data-integration/data-integration.service.ts | 6 +++--- libs/common/src/providers/entities/block.ts | 4 ++-- libs/common/src/services/indexer/entities/elastic.round.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/api/src/endpoints/data-integration/data-integration.service.ts b/apps/api/src/endpoints/data-integration/data-integration.service.ts index f21b145..e3f2424 100644 --- a/apps/api/src/endpoints/data-integration/data-integration.service.ts +++ b/apps/api/src/endpoints/data-integration/data-integration.service.ts @@ -70,8 +70,8 @@ export class DataIntegrationService { events: [], }; } - const after = parseInt(rounds[0].timestamp); - const before = parseInt(rounds[rounds.length - 1].timestamp); + const after = rounds[0].timestamp; + const before = rounds[rounds.length - 1].timestamp; const allEvents: ({ block: Block } & (SwapEvent | JoinExitEvent))[] = []; for (const provider of this.providers) { @@ -120,7 +120,7 @@ export class DataIntegrationService { this.logger.error(`Unknown event type: ${generalEvent.type} for event: ${JSON.stringify(generalEvent)}`); continue; } - const round = rounds.find((round: { timestamp: string }) => round.timestamp === generalEvent.timestamp.toString()); + const round = rounds.find((round: { timestamp: number }) => round.timestamp === generalEvent.timestamp); if (!round) { this.logger.error(`Round not found for event: ${JSON.stringify(generalEvent)}`); continue; diff --git a/libs/common/src/providers/entities/block.ts b/libs/common/src/providers/entities/block.ts index c7a0cc4..119ece4 100644 --- a/libs/common/src/providers/entities/block.ts +++ b/libs/common/src/providers/entities/block.ts @@ -15,13 +15,13 @@ export class Block { if (options?.onlyRequiredFields) { return { blockNumber: round.round, - blockTimestamp: parseInt(round.timestamp), + blockTimestamp: round.timestamp, }; } return { blockNumber: round.round, - blockTimestamp: parseInt(round.timestamp), + blockTimestamp: round.timestamp, metadata: { epoch: round.epoch.toString(), }, diff --git a/libs/common/src/services/indexer/entities/elastic.round.ts b/libs/common/src/services/indexer/entities/elastic.round.ts index 8c9421c..3c756fa 100644 --- a/libs/common/src/services/indexer/entities/elastic.round.ts +++ b/libs/common/src/services/indexer/entities/elastic.round.ts @@ -1,5 +1,5 @@ export interface ElasticRound { round: number; epoch: number; - timestamp: string; + timestamp: number; } From 8d3a67e9356646f9d68e72c198fa2f2171ba4f24 Mon Sep 17 00:00:00 2001 From: Gabriel Matei Date: Fri, 27 Sep 2024 12:27:07 +0300 Subject: [PATCH 11/11] update readme --- .env.example | 11 ++++++ README.md | 98 ++++++++-------------------------------------------- 2 files changed, 25 insertions(+), 84 deletions(-) create mode 100644 .env.example diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e190aa5 --- /dev/null +++ b/.env.example @@ -0,0 +1,11 @@ +NETWORK='mainnet' + +PUBLIC_API_PORT=3000 +PUBLIC_API_PREFIX='dex-screener-adapter' + +PRIVATE_API_PORT=4000 +OFFLINE_JOBS_PORT=4001 + +API_URL='https://api.multiversx.com' +REDIS_URL='127.0.0.1' +ELASTIC_URL='https://index.multiversx.com' diff --git a/README.md b/README.md index 16ad402..031257c 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,46 @@ -REST API facade template for microservices that interacts with the MultiversX blockchain. +# MultiversX DEX Screener Adapter Service ## Quick start 1. Run `npm install` in the project directory -2. Optionally make edits to `config.yaml` or create `config.custom.yaml` for each microservice +2. Create `.env.mainnet` or `.env.custom` based on the `.env.example` file ## Dependencies -1. Redis Server is required to be installed [docs](https://redis.io/). -2. MySQL Server is required to be installed [docs](https://dev.mysql.com/doc/refman/8.0/en/installing.html). -3. MongoDB Server is required to be installed [docs](https://docs.mongodb.com/). +- Redis Server is required to be installed [docs](https://redis.io/). You can run `docker-compose up` in a separate terminal to use a local Docker container for all these dependencies. After running the sample, you can stop the Docker container with `docker-compose down` -## Available Features - -These features can be enabled/disabled in config file - -### `Public API` - -Endpoints that can be used by anyone (public endpoints). - -### `Private API` - -Endpoints that are not exposed on the internet -For example: We do not want to expose our metrics and cache interactions to anyone (/metrics /cache) - -### `Cache Warmer` - -This is used to keep the application cache in sync with new updates. - -### `Transaction Processor` - -This is used for scanning the transactions from MultiversX Blockchain. - -### `Queue Worker` - -This is used for concurrently processing heavy jobs. - ## Available Scripts This is a MultiversX project built on Nest.js framework. -### `npm run start:mainnet` +### `npm run start:api:mainnet` ​ Runs the app in the production mode. -Make requests to [http://localhost:3001](http://localhost:3001). +Make requests to [http://localhost:3000/dex-screener-adapter](http://localhost:3000/dex-screener-adapter). Redis Server is required to be installed. ## Running the api ```bash -# development watch mode on devnet -$ npm run start:devnet:watch - -# development debug mode on devnet -$ npm run start:devnet:debug - -# development mode on devnet -$ npm run start:devnet - -# production mode -$ npm run start:mainnet -``` - -## Running the transactions-processor - -```bash -# development watch mode on devnet -$ npm run start:transactions-processor:devnet:watch +# development debug mode on mainnet +$ npm run start:api:mainnet -# development debug mode on devnet -$ npm run start:transactions-processor:devnet:debug - -# development mode on devnet -$ npm run start:transactions-processor:devnet - -# production mode -$ npm run start:transactions-processor:mainnet +# development debug mode on a custom network +$ npm run start:api:custom ``` -## Running the queue-worker +## Running the offline-jobs ```bash -# development watch mode on devnet -$ npm run start:queue-worker:devnet:watch - -# development debug mode on devnet -$ npm run start:queue-worker:devnet:debug - -# development mode on devnet -$ npm run start:queue-worker:devnet - -# production mode -$ npm run start:queue-worker:mainnet -``` - -Requests can be made to http://localhost:3001 for the api. The app will reload when you'll make edits (if opened in watch mode). You will also see any lint errors in the console.​ - -### `npm run test` - -```bash -# unit tests -$ npm run test - -# e2e tests -$ npm run test:e2e +# development debug mode on mainnet +$ start:offline-jobs:mainnet -# test coverage -$ npm run test:cov +# development debug mode on a custom network +$ start:offline-jobs:custom ```