Skip to content
This repository has been archived by the owner on Jun 3, 2022. It is now read-only.

Commit

Permalink
feature(controller): Resolve PoolSwap from/to from AccountHistory (#…
Browse files Browse the repository at this point in the history
…824)

* dex price resolution

* deprecated no Data postfix interface

* fix import

* optimize poolpair.service.ts

* add new verbose option
  • Loading branch information
fuxingloh authored Mar 4, 2022
1 parent c5b9f37 commit 18c1d69
Show file tree
Hide file tree
Showing 5 changed files with 271 additions and 25 deletions.
1 change: 1 addition & 0 deletions .idea/dictionaries/fuxing.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 91 additions & 9 deletions packages/whale-api-client/__tests__/api/poolpairs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { StubWhaleApiClient } from '../stub.client'
import { StubService } from '../stub.service'
import { ApiPagedResponse, WhaleApiClient, WhaleApiException } from '../../src'
import { addPoolLiquidity, createPoolPair, createToken, getNewAddress, mintTokens, poolSwap } from '@defichain/testing'
import { PoolPairData, PoolSwap, PoolSwapAggregated, PoolSwapAggregatedInterval } from '../../src/api/poolpairs'
import { PoolPairData, PoolSwapAggregatedData, PoolSwapAggregatedInterval, PoolSwapData } from '../../src/api/poolpairs'
import { Testing } from '@defichain/jellyfish-testing'

let container: MasterNodeRegTestContainer
Expand Down Expand Up @@ -371,13 +371,95 @@ describe('poolswap', () => {
await container.generate(1)
await service.waitForIndexedHeight(height)

const response: ApiPagedResponse<PoolSwap> = await client.poolpairs.listPoolSwaps('9')
expect(response.length).toStrictEqual(2)
const response: ApiPagedResponse<PoolSwapData> = await client.poolpairs.listPoolSwaps('9')
expect(response.hasNext).toStrictEqual(false)
expect(response[0].fromAmount).toStrictEqual('50.00000000')
expect(response[1].fromAmount).toStrictEqual('25.00000000')
expect(response[0].fromTokenId).toStrictEqual(1)
expect(response[1].fromTokenId).toStrictEqual(1)
expect([...response]).toStrictEqual([
{
id: expect.any(String),
txid: expect.stringMatching(/[0-f]{64}/),
txno: 1,
poolPairId: '9',
sort: expect.any(String),
fromAmount: '50.00000000',
fromTokenId: 1,
block: {
hash: expect.stringMatching(/[0-f]{64}/),
height: expect.any(Number),
time: expect.any(Number),
medianTime: expect.any(Number)
}
},
{
id: expect.any(String),
txid: expect.stringMatching(/[0-f]{64}/),
txno: 3,
poolPairId: '9',
sort: expect.any(String),
fromAmount: '25.00000000',
fromTokenId: 1,
block: {
hash: expect.stringMatching(/[0-f]{64}/),
height: expect.any(Number),
time: expect.any(Number),
medianTime: expect.any(Number)
}
}
])

const verbose: ApiPagedResponse<PoolSwapData> = await client.poolpairs.listPoolSwapsVerbose('9')
expect(verbose.hasNext).toStrictEqual(false)
expect([...verbose]).toStrictEqual([
{
id: expect.any(String),
txid: expect.stringMatching(/[0-f]{64}/),
txno: 1,
poolPairId: '9',
sort: expect.any(String),
fromAmount: '50.00000000',
fromTokenId: 1,
block: {
hash: expect.stringMatching(/[0-f]{64}/),
height: expect.any(Number),
time: expect.any(Number),
medianTime: expect.any(Number)
},
from: {
address: expect.any(String),
symbol: 'A',
amount: '50.00000000'
},
to: {
address: expect.any(String),
amount: '45.71428571',
symbol: 'DFI'
}
},
{
id: expect.any(String),
txid: expect.stringMatching(/[0-f]{64}/),
txno: 3,
poolPairId: '9',
sort: expect.any(String),
fromAmount: '25.00000000',
fromTokenId: 1,
block: {
hash: expect.stringMatching(/[0-f]{64}/),
height: expect.any(Number),
time: expect.any(Number),
medianTime: expect.any(Number)
},
from: {
address: expect.any(String),
symbol: 'A',
amount: '25.00000000'
},
to: {
address: expect.any(String),
amount: '39.99999999',
symbol: 'DFI'
}
}
])

const poolPair: PoolPairData = await client.poolpairs.get('9')
expect(poolPair).toStrictEqual({
Expand Down Expand Up @@ -594,7 +676,7 @@ describe('poolswap aggregated', () => {
await service.waitForIndexedHeight(height)
}

const dayAggregated: ApiPagedResponse<PoolSwapAggregated> = await client.poolpairs.listPoolSwapAggregates('10', PoolSwapAggregatedInterval.ONE_DAY, 10)
const dayAggregated: ApiPagedResponse<PoolSwapAggregatedData> = await client.poolpairs.listPoolSwapAggregates('10', PoolSwapAggregatedInterval.ONE_DAY, 10)
expect([...dayAggregated]).toStrictEqual([
{
aggregated: {
Expand Down Expand Up @@ -631,7 +713,7 @@ describe('poolswap aggregated', () => {

])

const hourAggregated: ApiPagedResponse<PoolSwapAggregated> = await client.poolpairs.listPoolSwapAggregates('10', PoolSwapAggregatedInterval.ONE_HOUR, 3)
const hourAggregated: ApiPagedResponse<PoolSwapAggregatedData> = await client.poolpairs.listPoolSwapAggregates('10', PoolSwapAggregatedInterval.ONE_HOUR, 3)
expect([...hourAggregated]).toStrictEqual([
{
aggregated: {
Expand Down
49 changes: 43 additions & 6 deletions packages/whale-api-client/src/api/poolpairs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,34 @@ export class PoolPairs {
* @param {string} id poolpair id
* @param {number} size of PoolSwap to query
* @param {string} next set of PoolSwap
* @return {Promise<ApiPagedResponse<PoolSwap>>}
* @return {Promise<ApiPagedResponse<PoolSwapData>>}
*/
async listPoolSwaps (id: string, size: number = 30, next?: string): Promise<ApiPagedResponse<PoolSwap>> {
async listPoolSwaps (id: string, size: number = 30, next?: string): Promise<ApiPagedResponse<PoolSwapData>> {
return await this.client.requestList('GET', `poolpairs/${id}/swaps`, size, next)
}

/**
* List pool swaps with from/to
*
* @param {string} id poolpair id
* @param {number} [size=10] of PoolSwap to query, max of 20 per page
* @param {string} next set of PoolSwap
* @return {Promise<ApiPagedResponse<PoolSwapData>>}
*/
async listPoolSwapsVerbose (id: string, size: number = 10, next?: string): Promise<ApiPagedResponse<PoolSwapData>> {
return await this.client.requestList('GET', `poolpairs/${id}/swaps/verbose`, size, next)
}

/**
* List pool swap aggregates
*
* @param {string} id poolpair id
* @param {PoolSwapAggregatedInterval} interval interval
* @param {number} size of PoolSwap to query
* @param {string} next set of PoolSwap
* @return {Promise<ApiPagedResponse<PoolSwapAggregated>>}
* @return {Promise<ApiPagedResponse<PoolSwapAggregatedData>>}
*/
async listPoolSwapAggregates (id: string, interval: PoolSwapAggregatedInterval, size: number = 30, next?: string): Promise<ApiPagedResponse<PoolSwapAggregated>> {
async listPoolSwapAggregates (id: string, interval: PoolSwapAggregatedInterval, size: number = 30, next?: string): Promise<ApiPagedResponse<PoolSwapAggregatedData>> {
return await this.client.requestList('GET', `poolpairs/${id}/swaps/aggregate/${interval as number}`, size, next)
}
}
Expand Down Expand Up @@ -103,7 +115,17 @@ export interface PoolPairData {
}
}

export interface PoolSwap {
/**
* @deprecated use PoolSwapData instead
*/
export type PoolSwap = PoolSwapData

/**
* @deprecated use PoolSwapAggregatedData instead
*/
export type PoolSwapAggregated = PoolSwapAggregatedData

export interface PoolSwapData {
id: string
sort: string
txid: string
Expand All @@ -113,6 +135,15 @@ export interface PoolSwap {
fromAmount: string
fromTokenId: number

/**
* To handle for optional value as Whale service might fail to resolve when indexing
*/
from?: PoolSwapFromToData
/**
* To handle for optional value as Whale service might fail to resolve when indexing
*/
to?: PoolSwapFromToData

block: {
hash: string
height: number
Expand All @@ -121,7 +152,13 @@ export interface PoolSwap {
}
}

export interface PoolSwapAggregated {
export interface PoolSwapFromToData {
address: string
amount: string
symbol: string
}

export interface PoolSwapAggregatedData {
id: string
key: string
bucket: number
Expand Down
41 changes: 33 additions & 8 deletions src/module.api/poolpair.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Controller, Get, NotFoundException, Param, ParseIntPipe, Query } from '
import { JsonRpcClient } from '@defichain/jellyfish-api-jsonrpc'
import { ApiPagedResponse } from '@src/module.api/_core/api.paged.response'
import { DeFiDCache } from '@src/module.api/cache/defid.cache'
import { PoolPairData, PoolSwap, PoolSwapAggregated } from '@whale-api-client/api/poolpairs'
import { PoolPairData, PoolSwapAggregatedData, PoolSwapData } from '@whale-api-client/api/poolpairs'
import { PaginationQuery } from '@src/module.api/_core/api.query'
import { PoolPairService } from './poolpair.service'
import BigNumber from 'bignumber.js'
Expand Down Expand Up @@ -83,9 +83,35 @@ export class PoolPairController {
async listPoolSwaps (
@Param('id', ParseIntPipe) id: string,
@Query() query: PaginationQuery
): Promise<ApiPagedResponse<PoolSwap>> {
const result = await this.poolSwapMapper.query(id, query.size, query.next)
return ApiPagedResponse.of(result, query.size, item => {
): Promise<ApiPagedResponse<PoolSwapData>> {
const items = await this.poolSwapMapper.query(id, query.size, query.next)
return ApiPagedResponse.of(items, query.size, item => {
return item.sort
})
}

/**
* @param {string} id poolpair id
* @param {PaginationQuery} query with size restricted to 20
* @param {number} query.size
* @param {string} [query.next]
* @return {Promise<ApiPagedResponse<PoolPairData>>}
*/
@Get('/:id/swaps/verbose')
async listPoolSwapsVerbose (
@Param('id', ParseIntPipe) id: string,
@Query() query: PaginationQuery
): Promise<ApiPagedResponse<PoolSwapData>> {
query.size = query.size > 20 ? 20 : query.size
const items: PoolSwapData[] = await this.poolSwapMapper.query(id, query.size, query.next)

for (const swap of items) {
const fromTo = await this.poolPairService.findSwapFromTo(swap.block.height, swap.txid, swap.txno)
swap.from = fromTo?.from
swap.to = fromTo?.to
}

return ApiPagedResponse.of(items, query.size, item => {
return item.sort
})
}
Expand All @@ -106,10 +132,10 @@ export class PoolPairController {
@Param('id', ParseIntPipe) id: string,
@Param('interval', ParseIntPipe) interval: string,
@Query() query: PaginationQuery
): Promise<ApiPagedResponse<PoolSwapAggregated>> {
): Promise<ApiPagedResponse<PoolSwapAggregatedData>> {
const lt = query.next === undefined ? undefined : parseInt(query.next)
const aggregates = await this.poolSwapAggregatedMapper.query(`${id}-${interval}`, query.size, lt)
const mapped: Array<Promise<PoolSwapAggregated>> = aggregates.map(async value => {
const mapped: Array<Promise<PoolSwapAggregatedData>> = aggregates.map(async value => {
return {
...value,
aggregated: {
Expand All @@ -126,8 +152,7 @@ export class PoolPairController {
}
}

function mapPoolPair (id: string, info: PoolPairInfo, totalLiquidityUsd?: BigNumber, apr?: PoolPairData['apr'],
volume?: PoolPairData['volume']): PoolPairData {
function mapPoolPair (id: string, info: PoolPairInfo, totalLiquidityUsd?: BigNumber, apr?: PoolPairData['apr'], volume?: PoolPairData['volume']): PoolPairData {
const [symbolA, symbolB] = info.symbol.split('-')

return {
Expand Down
Loading

0 comments on commit 18c1d69

Please sign in to comment.