From 47950e1b1e1b15de948424a1f12b819a91e0aa31 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 2 Oct 2023 10:55:43 +0900 Subject: [PATCH 01/19] impl get basic best pool --- .../swap/src/helpers/orders/getBestBuyPoll.ts | 42 ++++ .../src/helpers/orders/getBestBuyPool.test.ts | 226 ++++++++++++++++++ .../helpers/orders/getBestSellPool.test.ts | 116 +++++++++ .../src/helpers/orders/getBestSellPool.ts | 42 ++++ 4 files changed, 426 insertions(+) create mode 100644 packages/swap/src/helpers/orders/getBestBuyPoll.ts create mode 100644 packages/swap/src/helpers/orders/getBestBuyPool.test.ts create mode 100644 packages/swap/src/helpers/orders/getBestSellPool.test.ts create mode 100644 packages/swap/src/helpers/orders/getBestSellPool.ts diff --git a/packages/swap/src/helpers/orders/getBestBuyPoll.ts b/packages/swap/src/helpers/orders/getBestBuyPoll.ts new file mode 100644 index 0000000000..a5bdf5adc3 --- /dev/null +++ b/packages/swap/src/helpers/orders/getBestBuyPoll.ts @@ -0,0 +1,42 @@ +import {Balance, Swap} from '@yoroi/types' + +import {Quantities} from '../../utils/quantities' +import {getBuyAmount} from './getBuyAmount' + +/** + * Find the best pool to buy based on the desired sell amount in a liquidity pool. + * + * @param pools - The liquidity pool list. + * @param sell - The desired sell amount. + * + * @returns The best pool to sell + * if the balance in the pool is insuficient it wont throw an error + * if the pools balance is 0 it will return undefined + * if the pool list is empty it will return undefined + */ +export const getBestBuyPool = ( + pools: Swap.Pool[], + sell: Balance.Amount, +): Swap.Pool | undefined => { + if (pools != null && pools.length === 0) { + return undefined + } + let bestPool + let bestBuyAmount = 0n + for (const pool of pools) { + const buyAmount = getBuyAmount(pool, sell) + if (Quantities.isZero(buyAmount.quantity)) { + continue + } + if (bestPool === undefined) { + bestPool = pool + bestBuyAmount = BigInt(buyAmount.quantity) + continue + } + if (BigInt(buyAmount.quantity) > bestBuyAmount) { + bestPool = pool + bestBuyAmount = BigInt(buyAmount.quantity) + } + } + return bestPool +} diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts new file mode 100644 index 0000000000..f005d3c9a8 --- /dev/null +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -0,0 +1,226 @@ +import {Swap, Balance} from '@yoroi/types' + +import {getBestBuyPool} from './getBestBuyPoll' +import {getBuyAmount} from './getBuyAmount' + +describe('getBestBuyPool', () => { + it('should return poll with maximin possible tokens to buy', () => { + const pool1 = { + tokenA: {quantity: '522195900', tokenId: 'tokenA'}, + tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'muesliswap_v2', + price: 0, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool2 = { + tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, + tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'vyfi', + price: 0, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool3 = { + tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, + tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'minswap', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool4 = { + tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, + tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, + fee: '0.35', // 0.3% + provider: 'wingriders', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const pool5 = { + tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, + tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, + fee: '0.35', // 0.35% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const pool6 = { + tokenA: {quantity: '934171347', tokenId: 'tokenA'}, + tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, + fee: '0.05', // 0.05% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const sell: Balance.Amount = { + quantity: '100000000', + tokenId: 'tokenA', + } + + const pools = [pool1, pool2, pool3, pool4, pool5, pool6] + const bestBuyPool = getBestBuyPool(pools, sell) + expect(bestBuyPool?.provider).toBe('vyfi') + + if (bestBuyPool) { + const buyAmount = getBuyAmount(bestBuyPool, sell) + expect(buyAmount.quantity).toBe('1537882262') + } + }) + + it('should return poll with maximin possible tokens to buy (case 2)', () => { + const pool1 = { + tokenA: {quantity: '522195900', tokenId: 'tokenA'}, + tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'muesliswap_v2', + price: 0, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool2 = { + tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, + tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'vyfi', + price: 0, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool3 = { + tokenA: {quantity: '27278040255177', tokenId: 'tokenA'}, + tokenB: {quantity: '419697172209171', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'minswap', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool4 = { + tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, + tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, + fee: '0.35', // 0.3% + provider: 'wingriders', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const pool5 = { + tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, + tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, + fee: '0.35', // 0.35% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const pool6 = { + tokenA: {quantity: '934171347', tokenId: 'tokenA'}, + tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, + fee: '0.05', // 0.05% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const sell: Balance.Amount = { + quantity: '1000000000', + tokenId: 'tokenA', + } + + const pools = [pool1, pool2, pool3, pool4, pool5, pool6] + const bestBuyPool = getBestBuyPool(pools, sell) + expect(bestBuyPool?.provider).toBe('minswap') + + if (bestBuyPool) { + const buyAmount = getBuyAmount(bestBuyPool, sell) + expect(buyAmount.quantity).toBe('15339180660') + } + }) +}) diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts new file mode 100644 index 0000000000..0511f1abab --- /dev/null +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -0,0 +1,116 @@ +import {Swap, Balance} from '@yoroi/types' + +import {getBestSellPool} from './getBestSellPool' +import {getSellAmount} from './getSellAmount' + +describe('getBestSellPool', () => { + it('should return poll with min possible tokens to sell', () => { + const pool1 = { + tokenA: {quantity: '522195900', tokenId: 'tokenA'}, + tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'muesliswap_v2', + price: 0, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool2 = { + tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, + tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'vyfi', + price: 0, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool3 = { + tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, + tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'minswap', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const pool4 = { + tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, + tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, + fee: '0.35', // 0.3% + provider: 'wingriders', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const pool5 = { + tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, + tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, + fee: '0.35', // 0.35% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const pool6 = { + tokenA: {quantity: '934171347', tokenId: 'tokenA'}, + tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, + fee: '0.05', // 0.05% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const buy: Balance.Amount = { + quantity: '1000000000', + tokenId: 'tokenB', + } + + const pools = [pool1, pool2, pool3, pool4, pool5, pool6] + const bestSellPool = getBestSellPool(pools, buy) + expect(bestSellPool?.provider).toBe('vyfi') + + if (bestSellPool) { + const sellAmount = getSellAmount(bestSellPool, buy) + expect(sellAmount.quantity).toBe('65010104') + } + }) +}) diff --git a/packages/swap/src/helpers/orders/getBestSellPool.ts b/packages/swap/src/helpers/orders/getBestSellPool.ts new file mode 100644 index 0000000000..aa986d6a64 --- /dev/null +++ b/packages/swap/src/helpers/orders/getBestSellPool.ts @@ -0,0 +1,42 @@ +import {Balance, Swap} from '@yoroi/types' + +import {Quantities} from '../../utils/quantities' +import {getSellAmount} from './getSellAmount' + +/** + * Find the best pool to sell based on the desired sell amount in a liquidity pool. + * + * @param pools - The liquidity pool list. + * @param buy - The desired buy amount. + * + * @returns The best pool to sell + * if the balance in the pool is insuficient it wont throw an error + * if the pools balance is 0 it will return undefined + * if the pool list is empty it will return undefined + */ +export const getBestSellPool = ( + pools: Swap.Pool[], + buy: Balance.Amount, +): Swap.Pool | undefined => { + if (pools != null && pools.length === 0) { + return undefined + } + let bestPool + let bestSellAmount = 0n + for (const pool of pools) { + const sellAmount = getSellAmount(pool, buy) + if (Quantities.isZero(sellAmount.quantity)) { + continue + } + if (bestPool === undefined) { + bestPool = pool + bestSellAmount = BigInt(sellAmount.quantity) + continue + } + if (BigInt(sellAmount.quantity) < bestSellAmount) { + bestPool = pool + bestSellAmount = BigInt(sellAmount.quantity) + } + } + return bestPool +} From a67088b83a69b27e1cba5cf7b9c19afa09ee96a4 Mon Sep 17 00:00:00 2001 From: lisicky Date: Mon, 2 Oct 2023 11:04:23 +0900 Subject: [PATCH 02/19] add test for buy amount --- .../src/helpers/orders/getBuyAmount.test.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packages/swap/src/helpers/orders/getBuyAmount.test.ts b/packages/swap/src/helpers/orders/getBuyAmount.test.ts index 449ae00c6d..76c6d09f76 100644 --- a/packages/swap/src/helpers/orders/getBuyAmount.test.ts +++ b/packages/swap/src/helpers/orders/getBuyAmount.test.ts @@ -32,6 +32,35 @@ describe('getBuyAmount', () => { expect(limitedResult.tokenId).toBe('tokenB') }) + it('should calculate the correct buy amount when selling tokenA (muesli example)', () => { + const pool = { + tokenA: {quantity: '2022328173071', tokenId: ''}, + tokenB: {quantity: '277153', tokenId: 'tokenB'}, + fee: '0.3', // 0.3% + provider: 'muesliswap', + price: 7296793.37070499, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const sell: Balance.Amount = { + quantity: '1000000000', + tokenId: '', + } + const result = getBuyAmount(pool, sell) + expect(result.quantity).toBe('136') + expect(result.tokenId).toBe('tokenB') + + const limitedResult = getBuyAmount(pool, sell, '2.1') + //expect(limitedResult.quantity).toBe('47') + expect(limitedResult.tokenId).toBe('tokenB') + }) + it('should calculate the correct buy amount when selling tokenB', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, From f018864b1e01e8d9641f4e565b073034f8e116c7 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 4 Oct 2023 15:41:34 +0900 Subject: [PATCH 03/19] typo fix --- packages/swap/src/helpers/orders/getBestBuyPool.test.ts | 6 +++--- .../helpers/orders/{getBestBuyPoll.ts => getBestBuyPool.ts} | 0 packages/swap/src/helpers/orders/getBestSellPool.test.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename packages/swap/src/helpers/orders/{getBestBuyPoll.ts => getBestBuyPool.ts} (100%) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index f005d3c9a8..d3d703a854 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -1,10 +1,10 @@ import {Swap, Balance} from '@yoroi/types' -import {getBestBuyPool} from './getBestBuyPoll' +import {getBestBuyPool} from './getBestBuyPool' import {getBuyAmount} from './getBuyAmount' describe('getBestBuyPool', () => { - it('should return poll with maximin possible tokens to buy', () => { + it('should return pool with maximin possible tokens to buy', () => { const pool1 = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, @@ -114,7 +114,7 @@ describe('getBestBuyPool', () => { } }) - it('should return poll with maximin possible tokens to buy (case 2)', () => { + it('should return pool with maximin possible tokens to buy (case 2)', () => { const pool1 = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, diff --git a/packages/swap/src/helpers/orders/getBestBuyPoll.ts b/packages/swap/src/helpers/orders/getBestBuyPool.ts similarity index 100% rename from packages/swap/src/helpers/orders/getBestBuyPoll.ts rename to packages/swap/src/helpers/orders/getBestBuyPool.ts diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index 0511f1abab..f45f930127 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -4,7 +4,7 @@ import {getBestSellPool} from './getBestSellPool' import {getSellAmount} from './getSellAmount' describe('getBestSellPool', () => { - it('should return poll with min possible tokens to sell', () => { + it('should return pool with min possible tokens to sell', () => { const pool1 = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, From 87187734958131c761fb4d2e4815eca3af306920 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 4 Oct 2023 19:12:27 +0900 Subject: [PATCH 04/19] fix variable initiation --- .../src/helpers/orders/getBestBuyPool.test.ts | 48 ++++++++++--------- .../helpers/orders/getBestSellPool.test.ts | 2 +- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index d3d703a854..c8f80b9cdd 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -5,7 +5,7 @@ import {getBuyAmount} from './getBuyAmount' describe('getBestBuyPool', () => { it('should return pool with maximin possible tokens to buy', () => { - const pool1 = { + const pool1: Swap.Pool = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, fee: '0.3', // 0.3% @@ -19,9 +19,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool2 = { + const pool2: Swap.Pool = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, fee: '0.3', // 0.3% @@ -35,9 +35,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool3 = { + const pool3: Swap.Pool = { tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, fee: '0.3', // 0.3% @@ -51,9 +51,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool4 = { + const pool4: Swap.Pool = { tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, fee: '0.35', // 0.3% @@ -67,8 +67,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool - const pool5 = { + } + + const pool5: Swap.Pool = { tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, fee: '0.35', // 0.35% @@ -82,8 +83,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool - const pool6 = { + } + + const pool6: Swap.Pool = { tokenA: {quantity: '934171347', tokenId: 'tokenA'}, tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, fee: '0.05', // 0.05% @@ -115,7 +117,7 @@ describe('getBestBuyPool', () => { }) it('should return pool with maximin possible tokens to buy (case 2)', () => { - const pool1 = { + const pool1: Swap.Pool = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, fee: '0.3', // 0.3% @@ -131,7 +133,7 @@ describe('getBestBuyPool', () => { }, } as Swap.Pool - const pool2 = { + const pool2: Swap.Pool = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, fee: '0.3', // 0.3% @@ -145,9 +147,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool3 = { + const pool3: Swap.Pool = { tokenA: {quantity: '27278040255177', tokenId: 'tokenA'}, tokenB: {quantity: '419697172209171', tokenId: 'tokenB'}, fee: '0.3', // 0.3% @@ -161,9 +163,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool4 = { + const pool4: Swap.Pool = { tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, fee: '0.35', // 0.3% @@ -177,8 +179,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool - const pool5 = { + } + + const pool5: Swap.Pool = { tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, fee: '0.35', // 0.35% @@ -192,8 +195,9 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool - const pool6 = { + } + + const pool6: Swap.Pool = { tokenA: {quantity: '934171347', tokenId: 'tokenA'}, tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, fee: '0.05', // 0.05% @@ -207,7 +211,7 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } const sell: Balance.Amount = { quantity: '1000000000', diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index f45f930127..ed05c88e2e 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -5,7 +5,7 @@ import {getSellAmount} from './getSellAmount' describe('getBestSellPool', () => { it('should return pool with min possible tokens to sell', () => { - const pool1 = { + const pool1: Swap.Pool = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, fee: '0.3', // 0.3% From 5fa1f8181d10a85cedfd26cf0fdaa04d8dc4cb27 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 4 Oct 2023 19:25:25 +0900 Subject: [PATCH 05/19] fix variable initiation --- packages/swap/src/helpers/orders/getBestBuyPool.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index c8f80b9cdd..00aa564c16 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -131,7 +131,7 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } const pool2: Swap.Pool = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, From 247b1699e87094e2e7afeea6c28f8ce4afbe0a36 Mon Sep 17 00:00:00 2001 From: lisicky Date: Wed, 4 Oct 2023 20:29:06 +0900 Subject: [PATCH 06/19] fix variable initiation --- packages/swap/src/helpers/orders/getBestBuyPool.ts | 2 +- packages/swap/src/helpers/orders/getBestSellPool.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.ts b/packages/swap/src/helpers/orders/getBestBuyPool.ts index a5bdf5adc3..aa2e504317 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.ts @@ -21,7 +21,7 @@ export const getBestBuyPool = ( if (pools != null && pools.length === 0) { return undefined } - let bestPool + let bestPool: Swap.Pool | undefined let bestBuyAmount = 0n for (const pool of pools) { const buyAmount = getBuyAmount(pool, sell) diff --git a/packages/swap/src/helpers/orders/getBestSellPool.ts b/packages/swap/src/helpers/orders/getBestSellPool.ts index aa986d6a64..f2612a7fc0 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.ts @@ -21,7 +21,7 @@ export const getBestSellPool = ( if (pools != null && pools.length === 0) { return undefined } - let bestPool + let bestPool: Swap.Pool | undefined let bestSellAmount = 0n for (const pool of pools) { const sellAmount = getSellAmount(pool, buy) From 84d1d844f51b73fd98186716a8b587e731d79e7e Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 5 Oct 2023 02:57:08 +0900 Subject: [PATCH 07/19] add token price to pool --- .../SelectPoolFromList.stories.tsx | 4 ++++ .../src/features/Swap/common/mocks.ts | 2 ++ .../src/adapters/openswap-api/api.mocks.ts | 8 +++++++ .../src/helpers/orders/getBestBuyPool.test.ts | 24 +++++++++++++++++++ .../helpers/orders/getBestSellPool.test.ts | 12 ++++++++++ .../src/helpers/orders/getBuyAmount.test.ts | 6 +++++ .../src/helpers/orders/getMarketPrice.test.ts | 4 ++++ .../src/helpers/orders/getSellAmount.test.ts | 6 +++++ .../src/helpers/orders/makeLimitOrder.test.ts | 2 ++ .../orders/makePossibleMarketOrder.test.ts | 4 ++++ packages/swap/src/helpers/transformers.ts | 2 ++ .../translators/reactjs/state/state.mocks.ts | 2 ++ .../translators/reactjs/state/state.test.ts | 4 ++++ packages/types/src/swap/pool.ts | 2 ++ 14 files changed, 82 insertions(+) diff --git a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx index ba194e6fe5..afe22122f3 100644 --- a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx +++ b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx @@ -18,6 +18,8 @@ storiesOf('Swap List Pool', module) { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -33,6 +35,8 @@ storiesOf('Swap List Pool', module) { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'sundaeswap', price: 6, diff --git a/apps/wallet-mobile/src/features/Swap/common/mocks.ts b/apps/wallet-mobile/src/features/Swap/common/mocks.ts index c336ec767f..f129e04500 100644 --- a/apps/wallet-mobile/src/features/Swap/common/mocks.ts +++ b/apps/wallet-mobile/src/features/Swap/common/mocks.ts @@ -39,6 +39,8 @@ export const mocks = { quantity: asQuantity(231696922), tokenId: '208a2ca888886921513cb777bb832a8dc685c04de990480151f12150.53484942414441', }, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', }, slippage: 1, type: 'market' as Type, diff --git a/packages/swap/src/adapters/openswap-api/api.mocks.ts b/packages/swap/src/adapters/openswap-api/api.mocks.ts index 1799259552..656579aff6 100644 --- a/packages/swap/src/adapters/openswap-api/api.mocks.ts +++ b/packages/swap/src/adapters/openswap-api/api.mocks.ts @@ -39,6 +39,8 @@ const createOrderData: Swap.CreateOrderData = { quantity: '1000', }, tokenB: {tokenId: '', quantity: '1000000000'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', price: 0, batcherFee: {tokenId: '', quantity: '0'}, deposit: {tokenId: '', quantity: '2000000'}, @@ -67,6 +69,8 @@ const getPools: Swap.Pool[] = [ tokenId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', deposit: {quantity: '2000000', tokenId: ''}, lpToken: { quantity: '981004', @@ -88,6 +92,8 @@ const getPools: Swap.Pool[] = [ tokenId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', deposit: {quantity: '2000000', tokenId: ''}, lpToken: { quantity: '981004', @@ -109,6 +115,8 @@ const getPools: Swap.Pool[] = [ tokenId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', deposit: {quantity: '2000000', tokenId: ''}, lpToken: { quantity: '981004', diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index 00aa564c16..0f7861b2f9 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -8,6 +8,8 @@ describe('getBestBuyPool', () => { const pool1: Swap.Pool = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '1', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -24,6 +26,8 @@ describe('getBestBuyPool', () => { const pool2: Swap.Pool = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -40,6 +44,8 @@ describe('getBestBuyPool', () => { const pool3: Swap.Pool = { tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -56,6 +62,8 @@ describe('getBestBuyPool', () => { const pool4: Swap.Pool = { tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.35', // 0.3% provider: 'wingriders', price: 0, @@ -72,6 +80,8 @@ describe('getBestBuyPool', () => { const pool5: Swap.Pool = { tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.35', // 0.35% provider: 'sundaeswap', price: 0, @@ -88,6 +98,8 @@ describe('getBestBuyPool', () => { const pool6: Swap.Pool = { tokenA: {quantity: '934171347', tokenId: 'tokenA'}, tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, @@ -120,6 +132,8 @@ describe('getBestBuyPool', () => { const pool1: Swap.Pool = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -136,6 +150,8 @@ describe('getBestBuyPool', () => { const pool2: Swap.Pool = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -152,6 +168,8 @@ describe('getBestBuyPool', () => { const pool3: Swap.Pool = { tokenA: {quantity: '27278040255177', tokenId: 'tokenA'}, tokenB: {quantity: '419697172209171', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -168,6 +186,8 @@ describe('getBestBuyPool', () => { const pool4: Swap.Pool = { tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.35', // 0.3% provider: 'wingriders', price: 0, @@ -184,6 +204,8 @@ describe('getBestBuyPool', () => { const pool5: Swap.Pool = { tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.35', // 0.35% provider: 'sundaeswap', price: 0, @@ -200,6 +222,8 @@ describe('getBestBuyPool', () => { const pool6: Swap.Pool = { tokenA: {quantity: '934171347', tokenId: 'tokenA'}, tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index ed05c88e2e..e822a2465c 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -8,6 +8,8 @@ describe('getBestSellPool', () => { const pool1: Swap.Pool = { tokenA: {quantity: '522195900', tokenId: 'tokenA'}, tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -24,6 +26,8 @@ describe('getBestSellPool', () => { const pool2 = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -40,6 +44,8 @@ describe('getBestSellPool', () => { const pool3 = { tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -56,6 +62,8 @@ describe('getBestSellPool', () => { const pool4 = { tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.35', // 0.3% provider: 'wingriders', price: 0, @@ -71,6 +79,8 @@ describe('getBestSellPool', () => { const pool5 = { tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.35', // 0.35% provider: 'sundaeswap', price: 0, @@ -86,6 +96,8 @@ describe('getBestSellPool', () => { const pool6 = { tokenA: {quantity: '934171347', tokenId: 'tokenA'}, tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, diff --git a/packages/swap/src/helpers/orders/getBuyAmount.test.ts b/packages/swap/src/helpers/orders/getBuyAmount.test.ts index 76c6d09f76..718c415306 100644 --- a/packages/swap/src/helpers/orders/getBuyAmount.test.ts +++ b/packages/swap/src/helpers/orders/getBuyAmount.test.ts @@ -7,6 +7,8 @@ describe('getBuyAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -36,6 +38,8 @@ describe('getBuyAmount', () => { const pool = { tokenA: {quantity: '2022328173071', tokenId: ''}, tokenB: {quantity: '277153', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'muesliswap', price: 7296793.37070499, @@ -65,6 +69,8 @@ describe('getBuyAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/getMarketPrice.test.ts b/packages/swap/src/helpers/orders/getMarketPrice.test.ts index 98960122d1..f6d4c7e234 100644 --- a/packages/swap/src/helpers/orders/getMarketPrice.test.ts +++ b/packages/swap/src/helpers/orders/getMarketPrice.test.ts @@ -7,6 +7,8 @@ describe('getMarketPrice', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -31,6 +33,8 @@ describe('getMarketPrice', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/getSellAmount.test.ts b/packages/swap/src/helpers/orders/getSellAmount.test.ts index 19443ea441..56636f1565 100644 --- a/packages/swap/src/helpers/orders/getSellAmount.test.ts +++ b/packages/swap/src/helpers/orders/getSellAmount.test.ts @@ -7,6 +7,8 @@ describe('getSellAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.5', // 0.5% provider: 'minswap', price: 2, @@ -40,6 +42,8 @@ describe('getSellAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.5', // 0.5% provider: 'minswap', price: 2, @@ -69,6 +73,8 @@ describe('getSellAmount', () => { const pool = { tokenA: {quantity: '1000000', tokenId: 'tokenA'}, tokenB: {quantity: '2000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '10', provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/makeLimitOrder.test.ts b/packages/swap/src/helpers/orders/makeLimitOrder.test.ts index 922d53f884..f47b942e5c 100644 --- a/packages/swap/src/helpers/orders/makeLimitOrder.test.ts +++ b/packages/swap/src/helpers/orders/makeLimitOrder.test.ts @@ -14,6 +14,8 @@ describe('makeLimitOrder', () => { const pool: Swap.Pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts b/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts index 31037da639..33ab300d95 100644 --- a/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts +++ b/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts @@ -15,6 +15,8 @@ describe('makePossibleMarketOrder', () => { const pool1: Swap.Pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', provider: 'minswap', price: 2, @@ -30,6 +32,8 @@ describe('makePossibleMarketOrder', () => { const pool2: Swap.Pool = { tokenA: {quantity: '5500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', fee: '0.3', provider: 'sundaeswap', price: 2, diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts index 880dda8b1d..5cddf718af 100644 --- a/packages/swap/src/helpers/transformers.ts +++ b/packages/swap/src/helpers/transformers.ts @@ -127,6 +127,8 @@ export const transformersMaker = ( const pool: Swap.Pool = { tokenA: asYoroiAmount(tokenA), tokenB: asYoroiAmount(tokenB), + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', deposit: asYoroiAmount({amount: deposit.toString(), token: ''}), lpToken: asYoroiAmount(lpToken), batcherFee: asYoroiAmount(batcherFee), diff --git a/packages/swap/src/translators/reactjs/state/state.mocks.ts b/packages/swap/src/translators/reactjs/state/state.mocks.ts index 9c8748a40c..2af8920cbe 100644 --- a/packages/swap/src/translators/reactjs/state/state.mocks.ts +++ b/packages/swap/src/translators/reactjs/state/state.mocks.ts @@ -24,6 +24,8 @@ export const mockSwapStateDefault: SwapState = { fee: '', tokenA: {tokenId: '', quantity: '0'}, tokenB: {tokenId: '', quantity: '0'}, + tokenAPriceLovelace: '0', + tokenBPriceLovelace: '0', price: 0, batcherFee: {tokenId: '', quantity: '0'}, deposit: {tokenId: '', quantity: '0'}, diff --git a/packages/swap/src/translators/reactjs/state/state.test.ts b/packages/swap/src/translators/reactjs/state/state.test.ts index 691d166b72..7334798b01 100644 --- a/packages/swap/src/translators/reactjs/state/state.test.ts +++ b/packages/swap/src/translators/reactjs/state/state.test.ts @@ -163,6 +163,8 @@ describe('State Actions', () => { price: 1, tokenA: {tokenId: '', quantity: '1'}, tokenB: {tokenId: '', quantity: '1'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '1', }, } const expectedState = produce(mockSwapStateDefault, (draft) => { @@ -188,6 +190,8 @@ describe('State Actions', () => { price: 1, tokenA: {tokenId: '', quantity: '1'}, tokenB: {tokenId: '', quantity: '1'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '1', }, } diff --git a/packages/types/src/swap/pool.ts b/packages/types/src/swap/pool.ts index 4baa839c3f..a3122e18dd 100644 --- a/packages/types/src/swap/pool.ts +++ b/packages/types/src/swap/pool.ts @@ -27,6 +27,8 @@ export type SwapPool = { fee: string // % pool liquidity provider fee, usually 0.3. tokenA: BalanceAmount tokenB: BalanceAmount + tokenAPriceLovelace: string // float, current price in lovelace of tokenA, i.e. 0.000000000000000000. + tokenBPriceLovelace: string // float, current price in lovelace of tokenB, i.e. 0.000000000000000000. price: number // float, current price in tokenA / tokenB according to the pool, NOT SUITABLE for price calculations, just for display purposes, i.e. 0.9097362621640215. batcherFee: BalanceAmount deposit: BalanceAmount // amount of deposit / minUTxO required by protocol, returned to user, in lovelace. From f5a8bf636809995cb25479e769fbe03fc35449a5 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 5 Oct 2023 04:30:48 +0900 Subject: [PATCH 08/19] add price after fee function --- .../helpers/orders/getPriceAfterFee.test.ts | 57 +++++++++++++++++++ .../src/helpers/orders/getPriceAfterFee.ts | 41 +++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 packages/swap/src/helpers/orders/getPriceAfterFee.test.ts create mode 100644 packages/swap/src/helpers/orders/getPriceAfterFee.ts diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts new file mode 100644 index 0000000000..dff777da7b --- /dev/null +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts @@ -0,0 +1,57 @@ +import {Swap} from '@yoroi/types' +import {getPriceAfterFee} from './getPriceAfterFee' +import BigNumber from 'bignumber.js' + +describe('getPriceAfterFee', () => { + it('should calculate the correct price after fee when selling tokenA', () => { + const pool = { + tokenA: {quantity: '1200400368252', tokenId: 'tokenA'}, + tokenB: {quantity: '11364790709', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0.03465765134', + tokenBPriceLovelace: '3.81247293317', + fee: '0.3', // 0.3% + provider: 'minswap', + price: 2, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '1', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const tokenId = 'tokenA' + const tokenAAmount = '10000000000' + const tokenBAmount = '93613464' + const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId) + const expected = new BigNumber('107.11505104205276356717') + expect(result).toStrictEqual(expected) + }) + + it('should calculate the correct price after fee when selling tokenB', () => { + const pool = { + tokenA: {quantity: '143983812522', tokenId: 'tokenA'}, + tokenB: {quantity: '2050476716943', tokenId: 'tokenB'}, + tokenAPriceLovelace: '0.06954250577', + tokenBPriceLovelace: '1', + fee: '0.3', // 0.3% + provider: 'minswap', + price: 2, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '1', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const tokenId = 'tokenA' + const tokenAAmount = '10000000000' + const tokenBAmount = '696702612' + const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId) + const expected = new BigNumber('14.39254173470077386167') + expect(result).toStrictEqual(expected) + }) +}) diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.ts new file mode 100644 index 0000000000..09db055d81 --- /dev/null +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.ts @@ -0,0 +1,41 @@ +import {Swap} from '@yoroi/types' +import BigNumber from 'bignumber.js' + +import {BalanceQuantity} from '@yoroi/types/src/balance/token' + +/** + * Calculate the price with batcher fee in a liquidity pool. + * + * @param pool - The liquidity pool. + * @param tokenAAmount - Token A amount in an order. + * @param tokenBAmount - Token B amount in an order. + * @param tokenId - The token id of the desired sell amount. + * + * @returns The price after fee + */ +export const getPriceAfterFee = ( + pool: Swap.Pool, + tokenAAmount: BalanceQuantity, + tokenBAmount: BalanceQuantity, + tokenId: string, +): BigNumber => { + const isSellTokenA = tokenId === pool.tokenA.tokenId + + const A = new BigNumber(tokenAAmount) + const B = new BigNumber(tokenBAmount) + + const [firstToken, secondToken] = isSellTokenA ? [A, B] : [B, A] + const sellTokenPriceLovlace = new BigNumber( + isSellTokenA ? pool.tokenAPriceLovelace : pool.tokenBPriceLovelace, + ) + + const feeInTokenEquivalent = sellTokenPriceLovlace.isZero() + ? new BigNumber(0) + : new BigNumber(pool.batcherFee.quantity).dividedBy(sellTokenPriceLovlace) + + const firstTokenWithFee = firstToken.plus(feeInTokenEquivalent) + + return secondToken.isZero() + ? new BigNumber(0) + : firstTokenWithFee.dividedBy(secondToken) +} From 9659bfb1c212ab5feea9cd1eefaedec60482c6ac Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 5 Oct 2023 04:34:33 +0900 Subject: [PATCH 09/19] fix type initiation --- .../helpers/orders/getBestSellPool.test.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index e822a2465c..806b3be3ed 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -21,9 +21,9 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool2 = { + const pool2: Swap.Pool = { tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, tokenAPriceLovelace: '0', @@ -39,9 +39,9 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool3 = { + const pool3: Swap.Pool = { tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, tokenAPriceLovelace: '0', @@ -57,9 +57,9 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } - const pool4 = { + const pool4: Swap.Pool = { tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, tokenAPriceLovelace: '0', @@ -75,8 +75,9 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool - const pool5 = { + } + + const pool5: Swap.Pool = { tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, tokenAPriceLovelace: '0', @@ -92,8 +93,9 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool - const pool6 = { + } + + const pool6: Swap.Pool = { tokenA: {quantity: '934171347', tokenId: 'tokenA'}, tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, tokenAPriceLovelace: '0', @@ -109,7 +111,7 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } as Swap.Pool + } const buy: Balance.Amount = { quantity: '1000000000', From 9a0fe707eea1b02ee6c41194abbb7a36498b5dcb Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 5 Oct 2023 15:37:29 +0900 Subject: [PATCH 10/19] update "best pool" fuctions --- .../src/helpers/orders/getBestBuyPool.test.ts | 114 +++++------ .../swap/src/helpers/orders/getBestBuyPool.ts | 17 +- .../helpers/orders/getBestSellPool.test.ts | 182 +++++++++++++++--- .../src/helpers/orders/getBestSellPool.ts | 23 ++- .../src/helpers/orders/getPriceAfterFee.ts | 12 +- 5 files changed, 248 insertions(+), 100 deletions(-) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index 0f7861b2f9..3a23d4de5c 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -6,10 +6,10 @@ import {getBuyAmount} from './getBuyAmount' describe('getBestBuyPool', () => { it('should return pool with maximin possible tokens to buy', () => { const pool1: Swap.Pool = { - tokenA: {quantity: '522195900', tokenId: 'tokenA'}, - tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, + tokenA: {quantity: '529504614', tokenId: 'tokenA'}, + tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, tokenAPriceLovelace: '1', - tokenBPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -24,10 +24,10 @@ describe('getBestBuyPool', () => { } const pool2: Swap.Pool = { - tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, - tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '143610201719', tokenId: 'tokenA'}, + tokenB: {quantity: '2055821866531', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -42,10 +42,10 @@ describe('getBestBuyPool', () => { } const pool3: Swap.Pool = { - tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, - tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '27344918300893', tokenId: 'tokenA'}, + tokenB: {quantity: '393223050468514', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -60,11 +60,11 @@ describe('getBestBuyPool', () => { } const pool4: Swap.Pool = { - tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, - tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', - fee: '0.35', // 0.3% + tokenA: {quantity: '3400529909', tokenId: 'tokenA'}, + tokenB: {quantity: '49215467634', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', + fee: '0.35', // 0.35% provider: 'wingriders', price: 0, batcherFee: {quantity: '2000000', tokenId: ''}, @@ -78,11 +78,11 @@ describe('getBestBuyPool', () => { } const pool5: Swap.Pool = { - tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, - tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', - fee: '0.35', // 0.35% + tokenA: {quantity: '10178222382', tokenId: 'tokenA'}, + tokenB: {quantity: '145009426744', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', + fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, batcherFee: {quantity: '2500000', tokenId: ''}, @@ -96,10 +96,10 @@ describe('getBestBuyPool', () => { } const pool6: Swap.Pool = { - tokenA: {quantity: '934171347', tokenId: 'tokenA'}, - tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '973669994', tokenId: 'tokenA'}, + tokenB: {quantity: '13710853133', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, @@ -114,26 +114,26 @@ describe('getBestBuyPool', () => { } as Swap.Pool const sell: Balance.Amount = { - quantity: '100000000', - tokenId: 'tokenA', + quantity: '10000000000', + tokenId: 'tokenB', } const pools = [pool1, pool2, pool3, pool4, pool5, pool6] const bestBuyPool = getBestBuyPool(pools, sell) - expect(bestBuyPool?.provider).toBe('vyfi') + expect(bestBuyPool?.provider).toBe('minswap') if (bestBuyPool) { const buyAmount = getBuyAmount(bestBuyPool, sell) - expect(buyAmount.quantity).toBe('1537882262') + expect(buyAmount.quantity).toBe('693300972') } }) it('should return pool with maximin possible tokens to buy (case 2)', () => { const pool1: Swap.Pool = { - tokenA: {quantity: '522195900', tokenId: 'tokenA'}, - tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '529504614', tokenId: 'tokenA'}, + tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -148,10 +148,10 @@ describe('getBestBuyPool', () => { } const pool2: Swap.Pool = { - tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, - tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '143610201719', tokenId: 'tokenA'}, + tokenB: {quantity: '2055821866531', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -166,10 +166,10 @@ describe('getBestBuyPool', () => { } const pool3: Swap.Pool = { - tokenA: {quantity: '27278040255177', tokenId: 'tokenA'}, - tokenB: {quantity: '419697172209171', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '27344918300893', tokenId: 'tokenA'}, + tokenB: {quantity: '393223050468514', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -184,11 +184,11 @@ describe('getBestBuyPool', () => { } const pool4: Swap.Pool = { - tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, - tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', - fee: '0.35', // 0.3% + tokenA: {quantity: '3400529909', tokenId: 'tokenA'}, + tokenB: {quantity: '49215467634', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', + fee: '0.35', // 0.35% provider: 'wingriders', price: 0, batcherFee: {quantity: '2000000', tokenId: ''}, @@ -202,11 +202,11 @@ describe('getBestBuyPool', () => { } const pool5: Swap.Pool = { - tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, - tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', - fee: '0.35', // 0.35% + tokenA: {quantity: '10178222382', tokenId: 'tokenA'}, + tokenB: {quantity: '145009426744', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', + fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, batcherFee: {quantity: '2500000', tokenId: ''}, @@ -220,10 +220,10 @@ describe('getBestBuyPool', () => { } const pool6: Swap.Pool = { - tokenA: {quantity: '934171347', tokenId: 'tokenA'}, - tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '973669994', tokenId: 'tokenA'}, + tokenB: {quantity: '13710853133', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.0695404765', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, @@ -235,7 +235,7 @@ describe('getBestBuyPool', () => { quantity: '0', tokenId: '0', }, - } + } as Swap.Pool const sell: Balance.Amount = { quantity: '1000000000', @@ -248,7 +248,7 @@ describe('getBestBuyPool', () => { if (bestBuyPool) { const buyAmount = getBuyAmount(bestBuyPool, sell) - expect(buyAmount.quantity).toBe('15339180660') + expect(buyAmount.quantity).toBe('14336451239') } }) }) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.ts b/packages/swap/src/helpers/orders/getBestBuyPool.ts index aa2e504317..da2c41dc37 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.ts @@ -2,6 +2,8 @@ import {Balance, Swap} from '@yoroi/types' import {Quantities} from '../../utils/quantities' import {getBuyAmount} from './getBuyAmount' +import {getPriceAfterFee} from './getPriceAfterFee' +import BigNumber from 'bignumber.js' /** * Find the best pool to buy based on the desired sell amount in a liquidity pool. @@ -22,20 +24,27 @@ export const getBestBuyPool = ( return undefined } let bestPool: Swap.Pool | undefined - let bestBuyAmount = 0n + let bestPrice = new BigNumber(0) for (const pool of pools) { + const isSellTokenA = sell.tokenId === pool.tokenA.tokenId const buyAmount = getBuyAmount(pool, sell) if (Quantities.isZero(buyAmount.quantity)) { continue } + const [aAmount, bAmount] = isSellTokenA + ? [sell.quantity, buyAmount.quantity] + : [buyAmount.quantity, sell.quantity] + + const price = getPriceAfterFee(pool, aAmount, bAmount, sell.tokenId) if (bestPool === undefined) { bestPool = pool - bestBuyAmount = BigInt(buyAmount.quantity) + bestPrice = price continue } - if (BigInt(buyAmount.quantity) > bestBuyAmount) { + + if (price < bestPrice) { bestPool = pool - bestBuyAmount = BigInt(buyAmount.quantity) + bestPrice = price } } return bestPool diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index 806b3be3ed..3ef114cf66 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -6,10 +6,10 @@ import {getSellAmount} from './getSellAmount' describe('getBestSellPool', () => { it('should return pool with min possible tokens to sell', () => { const pool1: Swap.Pool = { - tokenA: {quantity: '522195900', tokenId: 'tokenA'}, - tokenB: {quantity: '7442057385', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '529504614', tokenId: 'tokenA'}, + tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -24,10 +24,10 @@ describe('getBestSellPool', () => { } const pool2: Swap.Pool = { - tokenA: {quantity: '157622738316', tokenId: 'tokenA'}, - tokenB: {quantity: '2432884054682', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '143610201719', tokenId: 'tokenA'}, + tokenB: {quantity: '2055821866531', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -42,10 +42,10 @@ describe('getBestSellPool', () => { } const pool3: Swap.Pool = { - tokenA: {quantity: '27273832383672', tokenId: 'tokenA'}, - tokenB: {quantity: '419770997375770', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '27337840212697', tokenId: 'tokenA'}, + tokenB: {quantity: '393349086430693', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -60,11 +60,11 @@ describe('getBestSellPool', () => { } const pool4: Swap.Pool = { - tokenA: {quantity: '3324463783', tokenId: 'tokenA'}, - tokenB: {quantity: '50335968991', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', - fee: '0.35', // 0.3% + tokenA: {quantity: '3400529909', tokenId: 'tokenA'}, + tokenB: {quantity: '49215467634', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', + fee: '0.35', // 0.35% provider: 'wingriders', price: 0, batcherFee: {quantity: '2000000', tokenId: ''}, @@ -78,11 +78,11 @@ describe('getBestSellPool', () => { } const pool5: Swap.Pool = { - tokenA: {quantity: '9776356330', tokenId: 'tokenA'}, - tokenB: {quantity: '149474209737', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', - fee: '0.35', // 0.35% + tokenA: {quantity: '10178222382', tokenId: 'tokenA'}, + tokenB: {quantity: '145009426744', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', + fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, batcherFee: {quantity: '2500000', tokenId: ''}, @@ -96,10 +96,10 @@ describe('getBestSellPool', () => { } const pool6: Swap.Pool = { - tokenA: {quantity: '934171347', tokenId: 'tokenA'}, - tokenB: {quantity: '14274535204', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenA: {quantity: '973669994', tokenId: 'tokenA'}, + tokenB: {quantity: '13710853133', tokenId: 'tokenB'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, @@ -111,7 +111,7 @@ describe('getBestSellPool', () => { quantity: '0', tokenId: '0', }, - } + } as Swap.Pool const buy: Balance.Amount = { quantity: '1000000000', @@ -120,11 +120,135 @@ describe('getBestSellPool', () => { const pools = [pool1, pool2, pool3, pool4, pool5, pool6] const bestSellPool = getBestSellPool(pools, buy) - expect(bestSellPool?.provider).toBe('vyfi') + expect(bestSellPool?.provider).toBe('minswap') + + if (bestSellPool) { + const sellAmount = getSellAmount(bestSellPool, buy) + expect(sellAmount.quantity).toBe('69709507') + } + }) + + it('should return pool with min possible tokens to sell (opposite test)', () => { + const pool1: Swap.Pool = { + tokenB: {quantity: '529504614', tokenId: 'tokenB'}, + tokenA: {quantity: '7339640354', tokenId: 'tokenA'}, + tokenBPriceLovelace: '1', + tokenAPriceLovelace: '0.06950020009', + fee: '0.3', // 0.3% + provider: 'muesliswap_v2', + price: 0, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const pool2: Swap.Pool = { + tokenB: {quantity: '143610201719', tokenId: 'tokenB'}, + tokenA: {quantity: '2055821866531', tokenId: 'tokenA'}, + tokenBPriceLovelace: '1', + tokenAPriceLovelace: '0.06950020009', + fee: '0.3', // 0.3% + provider: 'vyfi', + price: 0, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const pool3: Swap.Pool = { + tokenB: {quantity: '27337840212697', tokenId: 'tokenB'}, + tokenA: {quantity: '393349086430693', tokenId: 'tokenA'}, + tokenBPriceLovelace: '1', + tokenAPriceLovelace: '0.06950020009', + fee: '0.3', // 0.3% + provider: 'minswap', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const pool4: Swap.Pool = { + tokenB: {quantity: '3400529909', tokenId: 'tokenB'}, + tokenA: {quantity: '49215467634', tokenId: 'tokenA'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', + fee: '0.35', // 0.35% + provider: 'wingriders', + price: 0, + batcherFee: {quantity: '2000000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const pool5: Swap.Pool = { + tokenB: {quantity: '10178222382', tokenId: 'tokenB'}, + tokenA: {quantity: '145009426744', tokenId: 'tokenA'}, + tokenBPriceLovelace: '1', + tokenAPriceLovelace: '0.06950020009', + fee: '0.3', // 0.3% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const pool6: Swap.Pool = { + tokenB: {quantity: '973669994', tokenId: 'tokenB'}, + tokenA: {quantity: '13710853133', tokenId: 'tokenA'}, + tokenAPriceLovelace: '1', + tokenBPriceLovelace: '0.06950020009', + fee: '0.05', // 0.05% + provider: 'sundaeswap', + price: 0, + batcherFee: {quantity: '2500000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lastUpdate: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + + const buy: Balance.Amount = { + quantity: '1000000000', + tokenId: 'tokenA', + } + + const pools = [pool1, pool2, pool3, pool4, pool5, pool6] + const bestSellPool = getBestSellPool(pools, buy) + expect(bestSellPool?.provider).toBe('minswap') if (bestSellPool) { const sellAmount = getSellAmount(bestSellPool, buy) - expect(sellAmount.quantity).toBe('65010104') + expect(sellAmount.quantity).toBe('69709507') } }) }) diff --git a/packages/swap/src/helpers/orders/getBestSellPool.ts b/packages/swap/src/helpers/orders/getBestSellPool.ts index f2612a7fc0..4668c2f811 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.ts @@ -1,6 +1,8 @@ import {Balance, Swap} from '@yoroi/types' import {Quantities} from '../../utils/quantities' +import BigNumber from 'bignumber.js' +import {getPriceAfterFee} from './getPriceAfterFee' import {getSellAmount} from './getSellAmount' /** @@ -22,20 +24,33 @@ export const getBestSellPool = ( return undefined } let bestPool: Swap.Pool | undefined - let bestSellAmount = 0n + let bestPrice = new BigNumber(0) for (const pool of pools) { + const isBuyTokenA = buy.tokenId === pool.tokenA.tokenId const sellAmount = getSellAmount(pool, buy) if (Quantities.isZero(sellAmount.quantity)) { continue } + const [aAmount, bAmount] = isBuyTokenA + ? [buy.quantity, sellAmount.quantity] + : [sellAmount.quantity, buy.quantity] + + const price = getPriceAfterFee( + pool, + aAmount, + bAmount, + isBuyTokenA ? pool.tokenB.tokenId : pool.tokenA.tokenId, + ) + if (bestPool === undefined) { bestPool = pool - bestSellAmount = BigInt(sellAmount.quantity) + bestPrice = price continue } - if (BigInt(sellAmount.quantity) < bestSellAmount) { + + if (price < bestPrice) { bestPool = pool - bestSellAmount = BigInt(sellAmount.quantity) + bestPrice = price } } return bestPool diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.ts index 09db055d81..afeb888f83 100644 --- a/packages/swap/src/helpers/orders/getPriceAfterFee.ts +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.ts @@ -9,7 +9,7 @@ import {BalanceQuantity} from '@yoroi/types/src/balance/token' * @param pool - The liquidity pool. * @param tokenAAmount - Token A amount in an order. * @param tokenBAmount - Token B amount in an order. - * @param tokenId - The token id of the desired sell amount. + * @param sellTokenId - The token id of the desired sell amount. * * @returns The price after fee */ @@ -17,21 +17,21 @@ export const getPriceAfterFee = ( pool: Swap.Pool, tokenAAmount: BalanceQuantity, tokenBAmount: BalanceQuantity, - tokenId: string, + sellTokenId: string, ): BigNumber => { - const isSellTokenA = tokenId === pool.tokenA.tokenId + const isSellTokenA = sellTokenId === pool.tokenA.tokenId const A = new BigNumber(tokenAAmount) const B = new BigNumber(tokenBAmount) const [firstToken, secondToken] = isSellTokenA ? [A, B] : [B, A] - const sellTokenPriceLovlace = new BigNumber( + const sellTokenPriceLovelace = new BigNumber( isSellTokenA ? pool.tokenAPriceLovelace : pool.tokenBPriceLovelace, ) - const feeInTokenEquivalent = sellTokenPriceLovlace.isZero() + const feeInTokenEquivalent = sellTokenPriceLovelace.isZero() ? new BigNumber(0) - : new BigNumber(pool.batcherFee.quantity).dividedBy(sellTokenPriceLovlace) + : new BigNumber(pool.batcherFee.quantity).dividedBy(sellTokenPriceLovelace) const firstTokenWithFee = firstToken.plus(feeInTokenEquivalent) From 73e4f9ba9c37cb2edec5e3fc674d541562983b90 Mon Sep 17 00:00:00 2001 From: lisicky Date: Thu, 5 Oct 2023 15:43:34 +0900 Subject: [PATCH 11/19] remove null check --- packages/swap/src/helpers/orders/getBestBuyPool.ts | 2 +- packages/swap/src/helpers/orders/getBestSellPool.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.ts b/packages/swap/src/helpers/orders/getBestBuyPool.ts index da2c41dc37..82ac2cbd58 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.ts @@ -20,7 +20,7 @@ export const getBestBuyPool = ( pools: Swap.Pool[], sell: Balance.Amount, ): Swap.Pool | undefined => { - if (pools != null && pools.length === 0) { + if (pools.length === 0) { return undefined } let bestPool: Swap.Pool | undefined diff --git a/packages/swap/src/helpers/orders/getBestSellPool.ts b/packages/swap/src/helpers/orders/getBestSellPool.ts index 4668c2f811..932b19a4a2 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.ts @@ -20,7 +20,7 @@ export const getBestSellPool = ( pools: Swap.Pool[], buy: Balance.Amount, ): Swap.Pool | undefined => { - if (pools != null && pools.length === 0) { + if (pools.length === 0) { return undefined } let bestPool: Swap.Pool | undefined From 596ce7f9682c736c9abc1cc16968a83c69b3b8bf Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 02:30:30 +0900 Subject: [PATCH 12/19] switch endpoint for getting pools list --- .../SelectPoolFromList.stories.tsx | 2 - .../src/features/Swap/common/mocks.ts | 1 - packages/openswap/src/api.ts | 4 +- packages/openswap/src/config.ts | 2 + packages/openswap/src/index.ts | 4 +- packages/openswap/src/pools.spec.ts | 2 +- packages/openswap/src/poolsV2.ts | 61 ++++++ packages/openswap/src/types.ts | 57 +++++ .../src/adapters/openswap-api/api.mocks.ts | 10 +- .../adapters/openswap-api/openswap.mocks.ts | 196 +++++++++++++----- .../src/helpers/orders/getBestBuyPool.test.ts | 12 -- .../helpers/orders/getBestSellPool.test.ts | 12 -- .../src/helpers/orders/getBuyAmount.test.ts | 3 - .../src/helpers/orders/getMarketPrice.test.ts | 2 - .../helpers/orders/getPriceAfterFee.test.ts | 2 - .../src/helpers/orders/getSellAmount.test.ts | 3 - .../src/helpers/orders/makeLimitOrder.test.ts | 1 - .../orders/makePossibleMarketOrder.test.ts | 2 - .../swap/src/helpers/transformers.test.ts | 15 +- packages/swap/src/helpers/transformers.ts | 44 ++-- .../reactjs/provider/SwapProvider.test.tsx | 3 - .../translators/reactjs/state/state.mocks.ts | 1 - .../translators/reactjs/state/state.test.ts | 2 - packages/types/src/swap/pool.ts | 1 - 24 files changed, 309 insertions(+), 133 deletions(-) create mode 100644 packages/openswap/src/poolsV2.ts diff --git a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx index afe22122f3..e7d5619501 100644 --- a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx +++ b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx @@ -26,7 +26,6 @@ storiesOf('Swap List Pool', module) batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -43,7 +42,6 @@ storiesOf('Swap List Pool', module) batcherFee: {quantity: '122', tokenId: ''}, deposit: {quantity: '432', tokenId: ''}, poolId: '23455', - lastUpdate: '235', lpToken: { quantity: '13524', tokenId: '1355', diff --git a/apps/wallet-mobile/src/features/Swap/common/mocks.ts b/apps/wallet-mobile/src/features/Swap/common/mocks.ts index f129e04500..5921c90293 100644 --- a/apps/wallet-mobile/src/features/Swap/common/mocks.ts +++ b/apps/wallet-mobile/src/features/Swap/common/mocks.ts @@ -26,7 +26,6 @@ export const mocks = { batcherFee: {quantity: asQuantity(2500000), tokenId: ''}, deposit: {quantity: asQuantity(2000000), tokenId: ''}, fee: '0.05', - lastUpdate: '2023-09-08 09:56:13', lpToken: { quantity: asQuantity(68917682), tokenId: '0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913.6c702083', diff --git a/packages/openswap/src/api.ts b/packages/openswap/src/api.ts index 80a2d9eb60..74e4379b4c 100644 --- a/packages/openswap/src/api.ts +++ b/packages/openswap/src/api.ts @@ -5,7 +5,6 @@ import { getCompletedOrders, getOrders, // returns all orders for a given stake key hash. } from './orders' -import {getPools} from './pools' import {getTokens} from './tokens' import { CancelOrderRequest, @@ -14,6 +13,7 @@ import { TokenAddress, } from './types' import {axiosClient} from './config' +import {getPoolsV2} from './poolsV2' export class OpenSwapApi { constructor( @@ -58,7 +58,7 @@ export class OpenSwapApi { tokenA: TokenAddress tokenB: TokenAddress }) { - return getPools( + return getPoolsV2( {network: this.network, client: this.client}, {tokenA, tokenB}, ) diff --git a/packages/openswap/src/config.ts b/packages/openswap/src/config.ts index 67ec4d65e8..792f5813ad 100644 --- a/packages/openswap/src/config.ts +++ b/packages/openswap/src/config.ts @@ -3,6 +3,7 @@ import axios from 'axios' export const SWAP_API_ENDPOINTS = { mainnet: { getPools: 'https://onchain2.muesliswap.com/pools/pair', + getPoolsV2: 'https://api.muesliswap.com/liquidity/pools', getOrders: 'https://onchain2.muesliswap.com/orders/all/', getCompletedOrders: 'https://api.muesliswap.com/orders/v2', getTokens: 'https://api.muesliswap.com/list', @@ -12,6 +13,7 @@ export const SWAP_API_ENDPOINTS = { }, preprod: { getPools: 'https://preprod.pools.muesliswap.com/pools/pair', + getPoolsV2: 'https://preprod.api.muesliswap.com/liquidity/pools', getOrders: 'https://preprod.pools.muesliswap.com/orders/all/', getCompletedOrders: 'https://api.muesliswap.com/orders/v2', getTokens: 'https://preprod.api.muesliswap.com/list', diff --git a/packages/openswap/src/index.ts b/packages/openswap/src/index.ts index 5ff63bff32..3335719675 100644 --- a/packages/openswap/src/index.ts +++ b/packages/openswap/src/index.ts @@ -15,8 +15,8 @@ export namespace OpenSwap { export type CompletedOrderResponse = Types.CompletedOrderResponse // Pool - export type Pool = Types.Pool - export type PoolResponse = Types.PoolResponse + export type Pool = Types.PoolV2 + export type PoolResponse = Types.PoolResponseV2 // Token export type Token = Types.Token diff --git a/packages/openswap/src/pools.spec.ts b/packages/openswap/src/pools.spec.ts index 02d34ba80e..c209778e95 100644 --- a/packages/openswap/src/pools.spec.ts +++ b/packages/openswap/src/pools.spec.ts @@ -46,7 +46,7 @@ const mockedPoolRes = [ token: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, - price: 1581804.726923077, + price: 0, batcherFee: { amount: '2000000', token: '.', diff --git a/packages/openswap/src/poolsV2.ts b/packages/openswap/src/poolsV2.ts new file mode 100644 index 0000000000..56951fedf0 --- /dev/null +++ b/packages/openswap/src/poolsV2.ts @@ -0,0 +1,61 @@ +import {SWAP_API_ENDPOINTS} from './config' +import type {ApiDeps, PoolResponseV2, TokenAddress} from './types' + +export async function getPoolsV2( + deps: ApiDeps, + args: {tokenA: TokenAddress; tokenB: TokenAddress}, +): Promise { + const {tokenA, tokenB} = args + const {network, client} = deps + + const providers = [ + 'minswap', + 'sundaeswap', + 'wingriders', + 'muesliswap_v1', + 'muesliswap_v2', + 'muesliswap_v3', + 'muesliswap_v4', + 'vyfi', + 'spectrum', + ] + + const params: {[key: string]: string} = { + 'token-a': normaliseTokenAddress(tokenA), + 'token-b': normaliseTokenAddress(tokenB), + 'providers': providers.join(','), + } + + const apiUrl = SWAP_API_ENDPOINTS[network].getPoolsV2 + const response = await client.get('', { + baseURL: apiUrl, + params, + }) + + if (response.status !== 200) { + throw new Error('Failed to fetch pools for token pair', { + cause: response.data, + }) + } + + return response.data +} + +function normaliseTokenAddress(tokenA: TokenAddress): string { + const hexName = + 'assetNameHex' in tokenA + ? tokenA.assetNameHex + : stringToHex(tokenA.assetName) + return `${tokenA.policyId}.${hexName}` +} + +function stringToHex(str: string): string { + let hex = '' + for (let i = 0; i < str.length; i++) { + const charCode = str.charCodeAt(i) + const hexValue = charCode.toString(16) + + hex += hexValue.padStart(2, '0') + } + return hex +} diff --git a/packages/openswap/src/types.ts b/packages/openswap/src/types.ts index 29d8ea7124..28e10ca803 100644 --- a/packages/openswap/src/types.ts +++ b/packages/openswap/src/types.ts @@ -176,3 +176,60 @@ export type ApiDeps = { network: Network client: AxiosInstance } + +export type PoolResponseV2 = PoolV2[] +export type PoolV2 = { + tokenA: { + address: { + policyId: string + name: string + } + symbol?: string + image?: string + decimalPlaces: number + amount: string + status: string + priceAda: string + } + tokenB: { + address: { + policyId: string + name: string + } + symbol?: string + image?: string + decimalPlaces: number + amount: string + status: string + priceAda: string + } + feeToken: { + address: { + policyId: string + name: string + } + symbol?: string + image?: string + decimalPlaces: number + } + batcherFee: string + lvlDeposit: string + poolFee: string + lpToken: { + address?: { + policyId: string + name: string + } + amount?: string + } + poolId: string + provider: Protocol + txHash?: string + outputIdx?: number + volume24h?: number + volume7d?: number + liquidityApy?: number + priceASqrt?: any + priceBSqrt?: any + batcherAddress: string +} diff --git a/packages/swap/src/adapters/openswap-api/api.mocks.ts b/packages/swap/src/adapters/openswap-api/api.mocks.ts index 656579aff6..475d71bd1d 100644 --- a/packages/swap/src/adapters/openswap-api/api.mocks.ts +++ b/packages/swap/src/adapters/openswap-api/api.mocks.ts @@ -46,7 +46,6 @@ const createOrderData: Swap.CreateOrderData = { deposit: {tokenId: '', quantity: '2000000'}, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', - lastUpdate: '1694691081066', lpToken: {tokenId: '', quantity: '0'}, }, amounts: { @@ -78,9 +77,8 @@ const getPools: Swap.Pool[] = [ 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', }, batcherFee: {quantity: '2000000', tokenId: ''}, - lastUpdate: '2023-05-31 07:03:41', fee: '0.3', - price: 1581804.726923077, + price: 0, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', provider: 'minswap', @@ -101,9 +99,8 @@ const getPools: Swap.Pool[] = [ 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', }, batcherFee: {quantity: '2000000', tokenId: ''}, - lastUpdate: '2023-05-31 07:03:41', fee: '0.3', - price: 1581804.726923077, + price: 0, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', provider: 'sundaeswap', @@ -124,9 +121,8 @@ const getPools: Swap.Pool[] = [ 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', }, batcherFee: {quantity: '2000000', tokenId: ''}, - lastUpdate: '2023-05-31 07:03:41', fee: '0.3', - price: 1581804.726923077, + price: 0, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', provider: 'sundaeswap', diff --git a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts index ed914fd720..cfec2bc273 100644 --- a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts +++ b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts @@ -313,130 +313,214 @@ const getOpenOrders: OpenSwap.OpenOrder[] = [ const getPools: OpenSwap.Pool[] = [ { provider: 'minswap', - fee: '0.3', + poolFee: '0.3', tokenA: { amount: '1233807687', - token: '.', + address: { + policyId: '', + name: '', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, tokenB: { amount: '780', - token: - 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', - }, - price: 1581804.726923077, - batcherFee: { - amount: '2000000', - token: '.', + address: { + policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72', + name: '43414b45', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, + batcherFee: '2000000', // depositFee: { // amount: '2000000', // token: '.', // }, - deposit: 2000000, - utxo: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce#0', + lvlDeposit: '2000000', + batcherAddress: 'someBatcherAddress', + feeToken: { + address: { + policyId: '.', + name: '.', + }, + decimalPlaces: 0, + }, + txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce', + outputIdx: 0, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', - timestamp: '2023-05-31 07:03:41', lpToken: { amount: '981004', - token: - 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + address: { + policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86', + name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + }, }, }, { provider: 'sundaeswap', - fee: '0.3', + poolFee: '0.3', tokenA: { amount: '1233807687', - token: '.', + address: { + policyId: '', + name: '', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, tokenB: { amount: '780', - token: - 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', - }, - price: 1581804.726923077, - batcherFee: { - amount: '2000000', - token: '.', + address: { + policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72', + name: '43414b45', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, + batcherFee: '2000000', // depositFee: { // amount: '2000000', // token: '.', // }, - deposit: 2000000, - utxo: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce#0', + lvlDeposit: '2000000', + txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce', + outputIdx: 0, + batcherAddress: 'someBatcherAddress', + feeToken: { + address: { + policyId: '.', + name: '.', + }, + decimalPlaces: 0, + }, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', - timestamp: '2023-05-31 07:03:41', lpToken: { amount: '981004', - token: - 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + address: { + policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86', + name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + }, }, }, { provider: 'sundaeswap', - fee: '0.3', + poolFee: '0.3', tokenA: { amount: '1233807687', - token: '.', + address: { + policyId: '', + name: '', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, tokenB: { amount: '780', - token: - 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', - }, - price: 1581804.726923077, - batcherFee: { - amount: '2000000', - token: '.', + address: { + policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72', + name: '43414b45', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, + batcherFee: '2000000', // depositFee: { // amount: '2000000', // token: '.', // }, - deposit: 2000000, - utxo: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce#0', + lvlDeposit: '2000000', + txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce', + outputIdx: 0, + batcherAddress: 'someBatcherAddress', + feeToken: { + address: { + policyId: '.', + name: '.', + }, + decimalPlaces: 0, + }, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', - timestamp: '2023-05-31 07:03:41', lpToken: { amount: '981004', - token: - 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + address: { + policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86', + name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + }, }, }, { provider: 'spectrum', // unsupported pool - fee: '0.3', + poolFee: '0.3', tokenA: { amount: '1233807687', - token: '.', + address: { + policyId: '', + name: '', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, tokenB: { amount: '780', - token: - 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', - }, - price: 1581804.726923077, - batcherFee: { - amount: '2000000', - token: '.', + address: { + policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72', + name: '43414b45', + }, + symbol: '', + image: '', + decimalPlaces: 0, + status: '', + priceAda: '1111', }, + batcherFee: '2000000', // depositFee: { // amount: '2000000', // token: '.', // }, - deposit: 2000000, - utxo: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce#0', + lvlDeposit: '2000000', + txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce', + outputIdx: 0, + batcherAddress: 'someBatcherAddress', + feeToken: { + address: { + policyId: '.', + name: '.', + }, + decimalPlaces: 0, + }, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', - timestamp: '2023-05-31 07:03:41', lpToken: { amount: '981004', - token: - 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + address: { + policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86', + name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', + }, }, }, ] diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index 3a23d4de5c..7b9f08e957 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -16,7 +16,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '950000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -34,7 +33,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '1900000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -52,7 +50,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -70,7 +67,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -88,7 +84,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -106,7 +101,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -140,7 +134,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '950000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -158,7 +151,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '1900000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -176,7 +168,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -194,7 +185,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -212,7 +202,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -230,7 +219,6 @@ describe('getBestBuyPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index 3ef114cf66..b132c8c360 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -16,7 +16,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '950000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -34,7 +33,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '1900000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -52,7 +50,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -70,7 +67,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -88,7 +84,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -106,7 +101,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -140,7 +134,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '950000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -158,7 +151,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '1900000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -176,7 +168,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -194,7 +185,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2000000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -212,7 +202,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -230,7 +219,6 @@ describe('getBestSellPool', () => { batcherFee: {quantity: '2500000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/getBuyAmount.test.ts b/packages/swap/src/helpers/orders/getBuyAmount.test.ts index 718c415306..006a0a84e0 100644 --- a/packages/swap/src/helpers/orders/getBuyAmount.test.ts +++ b/packages/swap/src/helpers/orders/getBuyAmount.test.ts @@ -15,7 +15,6 @@ describe('getBuyAmount', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -46,7 +45,6 @@ describe('getBuyAmount', () => { batcherFee: {quantity: '950000', tokenId: ''}, deposit: {quantity: '2000000', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -77,7 +75,6 @@ describe('getBuyAmount', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/getMarketPrice.test.ts b/packages/swap/src/helpers/orders/getMarketPrice.test.ts index f6d4c7e234..f31e1dfc1c 100644 --- a/packages/swap/src/helpers/orders/getMarketPrice.test.ts +++ b/packages/swap/src/helpers/orders/getMarketPrice.test.ts @@ -15,7 +15,6 @@ describe('getMarketPrice', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -41,7 +40,6 @@ describe('getMarketPrice', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts index dff777da7b..3a4c17f630 100644 --- a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts @@ -15,7 +15,6 @@ describe('getPriceAfterFee', () => { batcherFee: {quantity: '950000', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -41,7 +40,6 @@ describe('getPriceAfterFee', () => { batcherFee: {quantity: '1900000', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/getSellAmount.test.ts b/packages/swap/src/helpers/orders/getSellAmount.test.ts index 56636f1565..b72db6581a 100644 --- a/packages/swap/src/helpers/orders/getSellAmount.test.ts +++ b/packages/swap/src/helpers/orders/getSellAmount.test.ts @@ -15,7 +15,6 @@ describe('getSellAmount', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -50,7 +49,6 @@ describe('getSellAmount', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -81,7 +79,6 @@ describe('getSellAmount', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/makeLimitOrder.test.ts b/packages/swap/src/helpers/orders/makeLimitOrder.test.ts index f47b942e5c..e62d60b1e4 100644 --- a/packages/swap/src/helpers/orders/makeLimitOrder.test.ts +++ b/packages/swap/src/helpers/orders/makeLimitOrder.test.ts @@ -22,7 +22,6 @@ describe('makeLimitOrder', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts b/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts index 33ab300d95..111bbb8a61 100644 --- a/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts +++ b/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts @@ -23,7 +23,6 @@ describe('makePossibleMarketOrder', () => { batcherFee: {quantity: '1', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', @@ -40,7 +39,6 @@ describe('makePossibleMarketOrder', () => { batcherFee: {quantity: '10', tokenId: ''}, deposit: {quantity: '1', tokenId: ''}, poolId: '0', - lastUpdate: '0', lpToken: { quantity: '0', tokenId: '0', diff --git a/packages/swap/src/helpers/transformers.test.ts b/packages/swap/src/helpers/transformers.test.ts index 77c797cb37..427c825ad5 100644 --- a/packages/swap/src/helpers/transformers.test.ts +++ b/packages/swap/src/helpers/transformers.test.ts @@ -107,7 +107,10 @@ describe('asYoroiAmount', () => { it('success', () => { const result = transformers.asYoroiAmount({ amount: '100', - token: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b.30', + address: { + policyId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b', + name: '30', + }, }) expect(result).toEqual({ quantity: '100', @@ -118,7 +121,10 @@ describe('asYoroiAmount', () => { it('success (lovelace) primary token', () => { const result = transformers.asYoroiAmount({ amount: '1000000', - token: 'lovelace', + address: { + policyId: '', + name: '', + }, }) expect(result).toEqual({quantity: '1000000', tokenId: ''}) }) @@ -126,7 +132,10 @@ describe('asYoroiAmount', () => { it('success (period) primary token', () => { const result = transformers.asYoroiAmount({ amount: '1000000', - token: '.', + address: { + policyId: '', + name: '.', + }, }) expect(result).toEqual({quantity: '1000000', tokenId: ''}) }) diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts index 5cddf718af..1c7c26ece2 100644 --- a/packages/swap/src/helpers/transformers.ts +++ b/packages/swap/src/helpers/transformers.ts @@ -49,11 +49,18 @@ export const transformersMaker = ( const asYoroiOpenOrder = (openswapOrder: OpenSwap.OpenOrder) => { const {from, to, deposit, ...rest} = openswapOrder + const [policyId, name = ''] = primaryTokenId.split('.') as [string, string?] return { ...rest, from: asYoroiAmount(from), to: asYoroiAmount(to), - deposit: asYoroiAmount({amount: deposit, token: primaryTokenId}), + deposit: asYoroiAmount({ + amount: deposit, + address: { + policyId, + name, + }, + }), } as const } @@ -111,14 +118,12 @@ export const transformersMaker = ( const asYoroiPool = (openswapPool: OpenSwap.Pool): Swap.Pool | null => { const { batcherFee, - fee, - deposit, + poolFee, + lvlDeposit, lpToken, tokenA, tokenB, - timestamp, provider, - price, poolId, } = openswapPool @@ -129,12 +134,11 @@ export const transformersMaker = ( tokenB: asYoroiAmount(tokenB), tokenAPriceLovelace: '0', tokenBPriceLovelace: '0', - deposit: asYoroiAmount({amount: deposit.toString(), token: ''}), + deposit: asYoroiAmount({amount: lvlDeposit, address: undefined}), lpToken: asYoroiAmount(lpToken), - batcherFee: asYoroiAmount(batcherFee), - lastUpdate: timestamp, - fee, - price, + batcherFee: asYoroiAmount({amount: batcherFee, address: undefined}), + fee: poolFee, + price: 0, poolId, provider, } @@ -142,17 +146,27 @@ export const transformersMaker = ( } const asYoroiAmount = (openswapAmount: { - amount: string - token: string + address?: { + policyId: string + name: string + } + token?: string + amount?: string }): Balance.Amount => { if (isString(openswapAmount?.amount)) { // openswap is inconsistent about ADA // sometimes is '.', '' or 'lovelace' - const {amount, token} = openswapAmount - const [policyId, name = ''] = token.split('.') as [string, string?] + const {amount, address, token} = openswapAmount + const [policyId, name = ''] = + address == null + ? token?.split('.') ?? (['', ''] as [string, string?]) + : [address.policyId, address.name] return { quantity: amount as Balance.Quantity, - tokenId: asYoroiTokenId({policyId, name}), + tokenId: asYoroiTokenId({ + policyId: policyId ?? '', + name: name ?? '', + }), } as const } return {quantity: Quantities.zero, tokenId: ''} as const diff --git a/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx b/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx index 57aa64942a..5bfbd9a760 100644 --- a/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx +++ b/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx @@ -206,7 +206,6 @@ describe('SwapProvider', () => { fee: '0.5', batcherFee: {tokenId: '', quantity: '1'}, deposit: {tokenId: '', quantity: '1'}, - lastUpdate: '123', lpToken: {tokenId: '', quantity: '1'}, poolId: '1', price: 2, @@ -263,7 +262,6 @@ describe('SwapProvider', () => { fee: '0.5', batcherFee: {tokenId: '', quantity: '1'}, deposit: {tokenId: '', quantity: '1'}, - lastUpdate: '123', lpToken: {tokenId: '', quantity: '1'}, poolId: '1', price: 2, @@ -333,7 +331,6 @@ describe('SwapProvider', () => { fee: '0.5', batcherFee: {tokenId: '', quantity: '1'}, deposit: {tokenId: '', quantity: '1'}, - lastUpdate: '123', lpToken: {tokenId: '', quantity: '1'}, poolId: '1', price: 1, diff --git a/packages/swap/src/translators/reactjs/state/state.mocks.ts b/packages/swap/src/translators/reactjs/state/state.mocks.ts index 2af8920cbe..bea576db1c 100644 --- a/packages/swap/src/translators/reactjs/state/state.mocks.ts +++ b/packages/swap/src/translators/reactjs/state/state.mocks.ts @@ -30,7 +30,6 @@ export const mockSwapStateDefault: SwapState = { batcherFee: {tokenId: '', quantity: '0'}, deposit: {tokenId: '', quantity: '0'}, poolId: '', - lastUpdate: '', lpToken: {tokenId: '', quantity: '0'}, }, }, diff --git a/packages/swap/src/translators/reactjs/state/state.test.ts b/packages/swap/src/translators/reactjs/state/state.test.ts index 7334798b01..d40a16c12a 100644 --- a/packages/swap/src/translators/reactjs/state/state.test.ts +++ b/packages/swap/src/translators/reactjs/state/state.test.ts @@ -157,7 +157,6 @@ describe('State Actions', () => { fee: '0.5', batcherFee: {tokenId: '', quantity: '1'}, deposit: {tokenId: '', quantity: '1'}, - lastUpdate: '123', lpToken: {tokenId: '', quantity: '1'}, poolId: '1', price: 1, @@ -184,7 +183,6 @@ describe('State Actions', () => { fee: '0.5', batcherFee: {tokenId: '', quantity: '1'}, deposit: {tokenId: '', quantity: '1'}, - lastUpdate: '123', lpToken: {tokenId: '', quantity: '1'}, poolId: '1', price: 1, diff --git a/packages/types/src/swap/pool.ts b/packages/types/src/swap/pool.ts index a3122e18dd..c340402e54 100644 --- a/packages/types/src/swap/pool.ts +++ b/packages/types/src/swap/pool.ts @@ -34,6 +34,5 @@ export type SwapPool = { deposit: BalanceAmount // amount of deposit / minUTxO required by protocol, returned to user, in lovelace. // utxo: string // txhash#txindex of latest transaction involving this pool. poolId: string // identifier of the pool across platforms. - lastUpdate: string // latest update of this pool in UTC, i.e. 2023-05-23 06:13:26. lpToken: BalanceAmount } From f76be252012053cb535c2e51ea859259c2c3ae9e Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 02:42:15 +0900 Subject: [PATCH 13/19] add price mapping --- packages/swap/src/helpers/transformers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts index 1c7c26ece2..f75fc00c0d 100644 --- a/packages/swap/src/helpers/transformers.ts +++ b/packages/swap/src/helpers/transformers.ts @@ -132,8 +132,8 @@ export const transformersMaker = ( const pool: Swap.Pool = { tokenA: asYoroiAmount(tokenA), tokenB: asYoroiAmount(tokenB), - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + tokenAPriceLovelace: tokenA.priceAda, + tokenBPriceLovelace: tokenB.priceAda, deposit: asYoroiAmount({amount: lvlDeposit, address: undefined}), lpToken: asYoroiAmount(lpToken), batcherFee: asYoroiAmount({amount: batcherFee, address: undefined}), From 10bd46d1e3a7c5737450676c9c076c6f87f1ec4b Mon Sep 17 00:00:00 2001 From: lisicky Date: Fri, 6 Oct 2023 03:27:18 +0900 Subject: [PATCH 14/19] test fix --- .../src/adapters/openswap-api/openswap.mocks.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts index cfec2bc273..acb57932dd 100644 --- a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts +++ b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts @@ -324,7 +324,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, tokenB: { amount: '780', @@ -336,7 +336,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, batcherFee: '2000000', // depositFee: { @@ -377,7 +377,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, tokenB: { amount: '780', @@ -389,7 +389,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, batcherFee: '2000000', // depositFee: { @@ -430,7 +430,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, tokenB: { amount: '780', @@ -442,7 +442,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, batcherFee: '2000000', // depositFee: { @@ -483,7 +483,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, tokenB: { amount: '780', @@ -495,7 +495,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '1111', + priceAda: '0', }, batcherFee: '2000000', // depositFee: { From 385386d585507265160ce2a8491d2f88b3504fa4 Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Fri, 6 Oct 2023 14:15:48 +0100 Subject: [PATCH 15/19] chore: proto->provider, colocated pools --- packages/openswap/src/api.ts | 39 ++++++- packages/openswap/src/config.ts | 8 +- packages/openswap/src/index.ts | 14 +-- packages/openswap/src/pools.spec.ts | 160 +++++++++++++++++++++++----- packages/openswap/src/pools.ts | 46 ++++++-- packages/openswap/src/poolsV2.ts | 61 ----------- packages/openswap/src/types.ts | 39 ++++--- 7 files changed, 241 insertions(+), 126 deletions(-) delete mode 100644 packages/openswap/src/poolsV2.ts diff --git a/packages/openswap/src/api.ts b/packages/openswap/src/api.ts index 74e4379b4c..1b5bc17e48 100644 --- a/packages/openswap/src/api.ts +++ b/packages/openswap/src/api.ts @@ -10,10 +10,11 @@ import { CancelOrderRequest, CreateOrderRequest, Network, + Provider, TokenAddress, } from './types' import {axiosClient} from './config' -import {getPoolsV2} from './poolsV2' +import {getLiquidityPools, getPoolsPair} from './pools' export class OpenSwapApi { constructor( @@ -51,19 +52,34 @@ export class OpenSwapApi { ) } - public async getPools({ + public async getPoolsPair({ tokenA, tokenB, }: { tokenA: TokenAddress tokenB: TokenAddress }) { - return getPoolsV2( + return getPoolsPair( {network: this.network, client: this.client}, {tokenA, tokenB}, ) } + public async getLiquidityPools({ + tokenA, + tokenB, + providers, + }: { + tokenA: string + tokenB: string + providers: ReadonlyArray + }) { + return getLiquidityPools( + {network: this.network, client: this.client}, + {tokenA, tokenB, providers}, + ) + } + public async getTokens({policyId = '', assetName = ''} = {}) { const tokens = await getTokens( {network: this.network, client: this.client}, @@ -74,4 +90,19 @@ export class OpenSwapApi { } } -const supportedNetworks: Network[] = ['mainnet', 'preprod'] +export const supportedNetworks: ReadonlyArray = [ + 'mainnet', + 'preprod', +] as const + +export const supportedProviders: ReadonlyArray = [ + 'minswap', + 'muesliswap_v1', + 'muesliswap_v2', + 'muesliswap_v3', + 'muesliswap_v4', + 'spectrum', + 'sundaeswap', + 'vyfi', + 'wingriders', +] as const diff --git a/packages/openswap/src/config.ts b/packages/openswap/src/config.ts index 792f5813ad..4cde8a0202 100644 --- a/packages/openswap/src/config.ts +++ b/packages/openswap/src/config.ts @@ -2,8 +2,8 @@ import axios from 'axios' export const SWAP_API_ENDPOINTS = { mainnet: { - getPools: 'https://onchain2.muesliswap.com/pools/pair', - getPoolsV2: 'https://api.muesliswap.com/liquidity/pools', + getPoolsPair: 'https://onchain2.muesliswap.com/pools/pair', + getLiquidityPools: 'https://api.muesliswap.com/liquidity/pools', getOrders: 'https://onchain2.muesliswap.com/orders/all/', getCompletedOrders: 'https://api.muesliswap.com/orders/v2', getTokens: 'https://api.muesliswap.com/list', @@ -12,8 +12,8 @@ export const SWAP_API_ENDPOINTS = { 'https://aggregator.muesliswap.com/cancelSwapTransaction', }, preprod: { - getPools: 'https://preprod.pools.muesliswap.com/pools/pair', - getPoolsV2: 'https://preprod.api.muesliswap.com/liquidity/pools', + getPoolsPair: 'https://preprod.pools.muesliswap.com/pools/pair', + getLiquidityPools: 'https://preprod.api.muesliswap.com/liquidity/pools', getOrders: 'https://preprod.pools.muesliswap.com/orders/all/', getCompletedOrders: 'https://api.muesliswap.com/orders/v2', getTokens: 'https://preprod.api.muesliswap.com/list', diff --git a/packages/openswap/src/index.ts b/packages/openswap/src/index.ts index 3335719675..e7bf1e3e66 100644 --- a/packages/openswap/src/index.ts +++ b/packages/openswap/src/index.ts @@ -2,10 +2,10 @@ export * from './api' import * as Types from './types' export namespace OpenSwap { - export type Protocol = Types.Protocol + export type Provider = Types.Provider export type Network = Types.Network - // Order + // Orders export type CreateOrderRequest = Types.CreateOrderRequest export type CreateOrderResponse = Types.CreateOrderResponse export type CancelOrderRequest = Types.CancelOrderRequest @@ -14,11 +14,13 @@ export namespace OpenSwap { export type CompletedOrder = Types.CompletedOrder export type CompletedOrderResponse = Types.CompletedOrderResponse - // Pool - export type Pool = Types.PoolV2 - export type PoolResponse = Types.PoolResponseV2 + // Pools + export type PoolPair = Types.PoolPair + export type PoolPairResponse = Types.PoolPairResponse + export type LiquidityPool = Types.LiquidityPool + export type LiquidityPoolResponse = Types.LiquidityPoolResponse - // Token + // Tokens export type Token = Types.Token export type TokenResponse = Types.TokenResponse export type TokenAddress = Types.TokenAddress diff --git a/packages/openswap/src/pools.spec.ts b/packages/openswap/src/pools.spec.ts index c209778e95..ad09bd9101 100644 --- a/packages/openswap/src/pools.spec.ts +++ b/packages/openswap/src/pools.spec.ts @@ -1,39 +1,83 @@ import {describe, expect, it, vi, Mocked} from 'vitest' -import {getPools} from './pools' +import {getLiquidityPools, getPoolsPair} from './pools' import {axiosClient} from './config' +import {LiquidityPoolResponse, PoolPairResponse} from './types' vi.mock('./config.ts') describe('SwapPoolsApi', () => { - it('should get pools list for a given token pair', async () => { - const mockAxios = axiosClient as Mocked - mockAxios.get.mockImplementationOnce(() => - Promise.resolve({ - status: 200, - data: mockedPoolRes, - }), - ) + describe('getLiquidityPools', () => { + it('should get liquidity pools list for a given token pair', async () => { + const mockAxios = axiosClient as Mocked + mockAxios.get.mockImplementationOnce(() => + Promise.resolve({ + status: 200, + data: mockedLiquidityPoolsResponse, + }), + ) + + const result = await getLiquidityPools( + {network: 'mainnet', client: mockAxios}, + { + tokenA: getLiquidityPoolsParams.sell, + tokenB: getLiquidityPoolsParams.buy, + providers: getLiquidityPoolsParams.providers, + }, + ) + expect(result).to.be.of.lengthOf(1) + }) - const result = await getPools( - {network: 'mainnet', client: mockAxios}, - {tokenA: getPoolsParams.sell, tokenB: getPoolsParams.buy}, - ) - expect(result).to.be.of.lengthOf(1) + it('should throw error for invalid response', async () => { + const mockAxios = axiosClient as Mocked + await expect(async () => { + mockAxios.get.mockImplementationOnce(() => + Promise.resolve({status: 500}), + ) + await getLiquidityPools( + {network: 'preprod', client: mockAxios}, + { + tokenA: getLiquidityPoolsParams.sell, + tokenB: getLiquidityPoolsParams.buy, + providers: getLiquidityPoolsParams.providers, + }, + ) + }).rejects.toThrow('Failed to fetch liquidity pools for token pair') + }) }) - it('should throw error for invalid response', async () => { - const mockAxios = axiosClient as Mocked - await expect(async () => { - mockAxios.get.mockImplementationOnce(() => Promise.resolve({status: 500})) - await getPools( - {network: 'preprod', client: mockAxios}, - {tokenA: getPoolsParams.sell, tokenB: getPoolsParams.buy}, + describe('getPoolsPair', () => { + it('should get pools pair list for a given token pair', async () => { + const mockAxios = axiosClient as Mocked + mockAxios.get.mockImplementationOnce(() => + Promise.resolve({ + status: 200, + data: mockedPoolsPairResponse, + }), + ) + + const result = await getPoolsPair( + {network: 'mainnet', client: mockAxios}, + {tokenA: getPoolsPairParams.sell, tokenB: getPoolsPairParams.buy}, ) - }).rejects.toThrow('Failed to fetch pools for token pair') + expect(result).to.be.of.lengthOf(1) + }) + + it('should throw error for invalid response', async () => { + const mockAxios = axiosClient as Mocked + await expect(async () => { + mockAxios.get.mockImplementationOnce(() => + Promise.resolve({status: 500}), + ) + await getPoolsPair( + {network: 'preprod', client: mockAxios}, + {tokenA: getPoolsPairParams.sell, tokenB: getPoolsPairParams.buy}, + ) + }).rejects.toThrow('Failed to fetch pools pair for token pair') + }) }) }) -const mockedPoolRes = [ +const mockedPoolsPairResponse: Readonly = [ { provider: 'minswap', fee: '0.3', @@ -65,10 +109,12 @@ const mockedPoolRes = [ token: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01', }, + batcherAddress: + 'addr1wxaptpmxcxawvr3pzlhgnpmzz3ql43n2tc8mn3av5kx0yzs09tqh8', }, ] -const getPoolsParams = { +const getPoolsPairParams = { sell: { policyId: '', assetNameHex: '', @@ -78,3 +124,69 @@ const getPoolsParams = { assetNameHex: '43414b45', }, } as const + +const mockedLiquidityPoolsResponse: Readonly = [ + { + tokenA: { + address: { + policyId: '', + name: '', + }, + symbol: 'ADA', + image: 'https://static.muesliswap.com/images/tokens/ada.png', + decimalPlaces: 6, + amount: '1000000', + status: 'verified', + priceAda: 1, + }, + tokenB: { + address: { + policyId: '9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77', + name: '53554e444145', + }, + symbol: 'SUNDAE', + image: + 'https://tokens.muesliswap.com/static/img/tokens/9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d77.53554e444145.png', + decimalPlaces: 6, + amount: '100000', + status: 'verified', + priceAda: 0.02567846556, + }, + feeToken: { + address: { + policyId: '', + name: '', + }, + symbol: 'ADA', + image: 'https://static.muesliswap.com/images/tokens/ada.png', + decimalPlaces: 6, + }, + batcherFee: '2500000', + lvlDeposit: '2000000', + poolFee: '1.00', + lpToken: { + address: { + policyId: '0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913', + name: '6c7020dc', + }, + amount: '316227', + }, + poolId: '0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913.7020dc', + provider: 'sundaeswap', + txHash: 'f2c5186fc53546db16a52c3bec25598e69518aaa8486919074c42e8927533f4c', + outputIdx: 1, + volume24h: 0, + volume7d: 0, + liquidityApy: 0, + priceASqrt: null, + priceBSqrt: null, + batcherAddress: + 'addr1wxaptpmxcxawvr3pzlhgnpmzz3ql43n2tc8mn3av5kx0yzs09tqh8', + }, +] + +const getLiquidityPoolsParams = { + sell: '', + buy: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', + providers: ['minswap'], +} as const diff --git a/packages/openswap/src/pools.ts b/packages/openswap/src/pools.ts index 8da62645fd..23b89fd41e 100644 --- a/packages/openswap/src/pools.ts +++ b/packages/openswap/src/pools.ts @@ -1,10 +1,44 @@ import {SWAP_API_ENDPOINTS} from './config' -import type {ApiDeps, PoolResponse, TokenAddress} from './types' +import type { + ApiDeps, + LiquidityPoolResponse, + PoolPairResponse, + Provider, + TokenAddress, +} from './types' -export async function getPools( +export async function getLiquidityPools( + deps: ApiDeps, + args: {tokenA: string; tokenB: string; providers: ReadonlyArray}, +): Promise { + const {tokenA, tokenB, providers} = args + const {network, client} = deps + + const params: {[key: string]: string} = { + 'token-a': tokenA, + 'token-b': tokenB, + 'providers': providers.join(','), + } + + const apiUrl = SWAP_API_ENDPOINTS[network].getLiquidityPools + const response = await client.get('', { + baseURL: apiUrl, + params, + }) + + if (response.status !== 200) { + throw new Error('Failed to fetch liquidity pools for token pair', { + cause: response.data, + }) + } + + return response.data +} + +export async function getPoolsPair( deps: ApiDeps, args: {tokenA: TokenAddress; tokenB: TokenAddress}, -): Promise { +): Promise { const {tokenA, tokenB} = args const {network, client} = deps const params: {[key: string]: string} = { @@ -19,14 +53,14 @@ export async function getPools( if ('assetNameHex' in tokenA) params['tokenname-hex1'] = tokenA.assetNameHex if ('assetNameHex' in tokenB) params['tokenname-hex2'] = tokenB.assetNameHex - const apiUrl = SWAP_API_ENDPOINTS[network].getPools - const response = await client.get('', { + const apiUrl = SWAP_API_ENDPOINTS[network].getPoolsPair + const response = await client.get('', { baseURL: apiUrl, params, }) if (response.status !== 200) { - throw new Error('Failed to fetch pools for token pair', { + throw new Error('Failed to fetch pools pair for token pair', { cause: response.data, }) } diff --git a/packages/openswap/src/poolsV2.ts b/packages/openswap/src/poolsV2.ts deleted file mode 100644 index 56951fedf0..0000000000 --- a/packages/openswap/src/poolsV2.ts +++ /dev/null @@ -1,61 +0,0 @@ -import {SWAP_API_ENDPOINTS} from './config' -import type {ApiDeps, PoolResponseV2, TokenAddress} from './types' - -export async function getPoolsV2( - deps: ApiDeps, - args: {tokenA: TokenAddress; tokenB: TokenAddress}, -): Promise { - const {tokenA, tokenB} = args - const {network, client} = deps - - const providers = [ - 'minswap', - 'sundaeswap', - 'wingriders', - 'muesliswap_v1', - 'muesliswap_v2', - 'muesliswap_v3', - 'muesliswap_v4', - 'vyfi', - 'spectrum', - ] - - const params: {[key: string]: string} = { - 'token-a': normaliseTokenAddress(tokenA), - 'token-b': normaliseTokenAddress(tokenB), - 'providers': providers.join(','), - } - - const apiUrl = SWAP_API_ENDPOINTS[network].getPoolsV2 - const response = await client.get('', { - baseURL: apiUrl, - params, - }) - - if (response.status !== 200) { - throw new Error('Failed to fetch pools for token pair', { - cause: response.data, - }) - } - - return response.data -} - -function normaliseTokenAddress(tokenA: TokenAddress): string { - const hexName = - 'assetNameHex' in tokenA - ? tokenA.assetNameHex - : stringToHex(tokenA.assetName) - return `${tokenA.policyId}.${hexName}` -} - -function stringToHex(str: string): string { - let hex = '' - for (let i = 0; i < str.length; i++) { - const charCode = str.charCodeAt(i) - const hexValue = charCode.toString(16) - - hex += hexValue.padStart(2, '0') - } - return hex -} diff --git a/packages/openswap/src/types.ts b/packages/openswap/src/types.ts index 28e10ca803..acba276b19 100644 --- a/packages/openswap/src/types.ts +++ b/packages/openswap/src/types.ts @@ -8,7 +8,7 @@ export type CancelOrderRequest = { export type CreateOrderRequest = { walletAddress: string - protocol: Protocol + protocol: Provider // only in the CreateOrder they call provider as protocol poolId?: string // only required for SundaeSwap trades. sell: { policyId: string @@ -27,7 +27,7 @@ export type CreateOrderResponse = | {status: 'success'; hash: string; datum: string; address: string} export type OpenOrder = { - provider: Protocol + provider: Provider owner: string from: { amount: string @@ -71,7 +71,7 @@ export type CompletedOrder = { } export type CompletedOrderResponse = CompletedOrder[] -export type Protocol = +export type Provider = | 'minswap' | 'sundaeswap' | 'wingriders' @@ -84,17 +84,9 @@ export type Protocol = export type Network = 'mainnet' | 'preprod' -export type Pool = { - provider: - | 'minswap' - | 'sundaeswap' - | 'wingriders' - | 'muesliswap_v1' - | 'muesliswap_v2' - | 'muesliswap_v3' - | 'muesliswap_v4' - | 'vyfi' - | 'spectrum' +// NOTE: TBR +export type PoolPair = { + provider: Provider fee: string // % pool liquidity provider fee, usually 0.3. tokenA: { amount: string // amount of tokenA in the pool, without decimals. @@ -107,7 +99,7 @@ export type Pool = { price: number // float, current price in tokenA / tokenB according to the pool, NOT SUITABLE for price calculations, just for display purposes, i.e. 0.9097362621640215. batcherFee: { amount: string // amount of fee taken by protocol batchers, in lovelace. - token: '.' + token: string // most likely "." for lovelace. } deposit: number // amount of deposit / minUTxO required by protocol, returned to user, in lovelace. utxo: string // txhash#txindex of latest transaction involving this pool. @@ -117,8 +109,13 @@ export type Pool = { amount: string // amount of lpToken minted by the pool, without decimals. token: string // hexadecimal representation of lpToken, } + depositFee: { + amount: string // amount of fee taken by protocol batchers, in lovelace. + token: string // most likely "." for lovelace. + } + batcherAddress: string // address of the protocol batcher. } -export type PoolResponse = Pool[] +export type PoolPairResponse = PoolPair[] export type Token = { info: { @@ -177,8 +174,8 @@ export type ApiDeps = { client: AxiosInstance } -export type PoolResponseV2 = PoolV2[] -export type PoolV2 = { +export type LiquidityPoolResponse = LiquidityPool[] +export type LiquidityPool = { tokenA: { address: { policyId: string @@ -189,7 +186,7 @@ export type PoolV2 = { decimalPlaces: number amount: string status: string - priceAda: string + priceAda: number } tokenB: { address: { @@ -201,7 +198,7 @@ export type PoolV2 = { decimalPlaces: number amount: string status: string - priceAda: string + priceAda: number } feeToken: { address: { @@ -223,7 +220,7 @@ export type PoolV2 = { amount?: string } poolId: string - provider: Protocol + provider: Provider txHash?: string outputIdx?: number volume24h?: number From 1c04af4c456a8ebfd8c8daa4565a41b972bd0b8a Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Fri, 6 Oct 2023 15:08:21 +0100 Subject: [PATCH 16/19] refactor: primary token within yoroi --- .../SelectPoolFromList.stories.tsx | 8 ++-- .../src/features/Swap/common/mocks.ts | 4 +- .../src/adapters/openswap-api/api.mocks.ts | 16 +++---- .../src/helpers/orders/getBestBuyPool.test.ts | 48 +++++++++---------- .../helpers/orders/getBestSellPool.test.ts | 48 +++++++++---------- .../src/helpers/orders/getBuyAmount.test.ts | 12 ++--- .../src/helpers/orders/getMarketPrice.test.ts | 8 ++-- .../helpers/orders/getPriceAfterFee.test.ts | 8 ++-- .../src/helpers/orders/getPriceAfterFee.ts | 2 +- .../src/helpers/orders/getSellAmount.test.ts | 12 ++--- .../src/helpers/orders/makeLimitOrder.test.ts | 4 +- .../orders/makePossibleMarketOrder.test.ts | 8 ++-- packages/swap/src/helpers/transformers.ts | 4 +- .../translators/reactjs/state/state.mocks.ts | 4 +- .../translators/reactjs/state/state.test.ts | 8 ++-- packages/types/src/swap/pool.ts | 4 +- 16 files changed, 99 insertions(+), 99 deletions(-) diff --git a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx index e7d5619501..24f5de36b7 100644 --- a/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx +++ b/apps/wallet-mobile/src/features/Swap/common/SelectPool/SelectPoolFromList/SelectPoolFromList.stories.tsx @@ -18,8 +18,8 @@ storiesOf('Swap List Pool', module) { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -34,8 +34,8 @@ storiesOf('Swap List Pool', module) { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'sundaeswap', price: 6, diff --git a/apps/wallet-mobile/src/features/Swap/common/mocks.ts b/apps/wallet-mobile/src/features/Swap/common/mocks.ts index 5921c90293..d81ec192ca 100644 --- a/apps/wallet-mobile/src/features/Swap/common/mocks.ts +++ b/apps/wallet-mobile/src/features/Swap/common/mocks.ts @@ -38,8 +38,8 @@ export const mocks = { quantity: asQuantity(231696922), tokenId: '208a2ca888886921513cb777bb832a8dc685c04de990480151f12150.53484942414441', }, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', }, slippage: 1, type: 'market' as Type, diff --git a/packages/swap/src/adapters/openswap-api/api.mocks.ts b/packages/swap/src/adapters/openswap-api/api.mocks.ts index 475d71bd1d..a38ee77bca 100644 --- a/packages/swap/src/adapters/openswap-api/api.mocks.ts +++ b/packages/swap/src/adapters/openswap-api/api.mocks.ts @@ -39,8 +39,8 @@ const createOrderData: Swap.CreateOrderData = { quantity: '1000', }, tokenB: {tokenId: '', quantity: '1000000000'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', price: 0, batcherFee: {tokenId: '', quantity: '0'}, deposit: {tokenId: '', quantity: '2000000'}, @@ -68,8 +68,8 @@ const getPools: Swap.Pool[] = [ tokenId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', deposit: {quantity: '2000000', tokenId: ''}, lpToken: { quantity: '981004', @@ -90,8 +90,8 @@ const getPools: Swap.Pool[] = [ tokenId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', deposit: {quantity: '2000000', tokenId: ''}, lpToken: { quantity: '981004', @@ -112,8 +112,8 @@ const getPools: Swap.Pool[] = [ tokenId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45', }, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', deposit: {quantity: '2000000', tokenId: ''}, lpToken: { quantity: '981004', diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index 7b9f08e957..a85fdcc1d6 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -8,8 +8,8 @@ describe('getBestBuyPool', () => { const pool1: Swap.Pool = { tokenA: {quantity: '529504614', tokenId: 'tokenA'}, tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -25,8 +25,8 @@ describe('getBestBuyPool', () => { const pool2: Swap.Pool = { tokenA: {quantity: '143610201719', tokenId: 'tokenA'}, tokenB: {quantity: '2055821866531', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -42,8 +42,8 @@ describe('getBestBuyPool', () => { const pool3: Swap.Pool = { tokenA: {quantity: '27344918300893', tokenId: 'tokenA'}, tokenB: {quantity: '393223050468514', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -59,8 +59,8 @@ describe('getBestBuyPool', () => { const pool4: Swap.Pool = { tokenA: {quantity: '3400529909', tokenId: 'tokenA'}, tokenB: {quantity: '49215467634', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.35', // 0.35% provider: 'wingriders', price: 0, @@ -76,8 +76,8 @@ describe('getBestBuyPool', () => { const pool5: Swap.Pool = { tokenA: {quantity: '10178222382', tokenId: 'tokenA'}, tokenB: {quantity: '145009426744', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, @@ -93,8 +93,8 @@ describe('getBestBuyPool', () => { const pool6: Swap.Pool = { tokenA: {quantity: '973669994', tokenId: 'tokenA'}, tokenB: {quantity: '13710853133', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, @@ -126,8 +126,8 @@ describe('getBestBuyPool', () => { const pool1: Swap.Pool = { tokenA: {quantity: '529504614', tokenId: 'tokenA'}, tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -143,8 +143,8 @@ describe('getBestBuyPool', () => { const pool2: Swap.Pool = { tokenA: {quantity: '143610201719', tokenId: 'tokenA'}, tokenB: {quantity: '2055821866531', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -160,8 +160,8 @@ describe('getBestBuyPool', () => { const pool3: Swap.Pool = { tokenA: {quantity: '27344918300893', tokenId: 'tokenA'}, tokenB: {quantity: '393223050468514', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -177,8 +177,8 @@ describe('getBestBuyPool', () => { const pool4: Swap.Pool = { tokenA: {quantity: '3400529909', tokenId: 'tokenA'}, tokenB: {quantity: '49215467634', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.35', // 0.35% provider: 'wingriders', price: 0, @@ -194,8 +194,8 @@ describe('getBestBuyPool', () => { const pool5: Swap.Pool = { tokenA: {quantity: '10178222382', tokenId: 'tokenA'}, tokenB: {quantity: '145009426744', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, @@ -211,8 +211,8 @@ describe('getBestBuyPool', () => { const pool6: Swap.Pool = { tokenA: {quantity: '973669994', tokenId: 'tokenA'}, tokenB: {quantity: '13710853133', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.0695404765', + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index b132c8c360..ca253d3628 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -8,8 +8,8 @@ describe('getBestSellPool', () => { const pool1: Swap.Pool = { tokenA: {quantity: '529504614', tokenId: 'tokenA'}, tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -25,8 +25,8 @@ describe('getBestSellPool', () => { const pool2: Swap.Pool = { tokenA: {quantity: '143610201719', tokenId: 'tokenA'}, tokenB: {quantity: '2055821866531', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -42,8 +42,8 @@ describe('getBestSellPool', () => { const pool3: Swap.Pool = { tokenA: {quantity: '27337840212697', tokenId: 'tokenA'}, tokenB: {quantity: '393349086430693', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -59,8 +59,8 @@ describe('getBestSellPool', () => { const pool4: Swap.Pool = { tokenA: {quantity: '3400529909', tokenId: 'tokenA'}, tokenB: {quantity: '49215467634', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.35', // 0.35% provider: 'wingriders', price: 0, @@ -76,8 +76,8 @@ describe('getBestSellPool', () => { const pool5: Swap.Pool = { tokenA: {quantity: '10178222382', tokenId: 'tokenA'}, tokenB: {quantity: '145009426744', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, @@ -93,8 +93,8 @@ describe('getBestSellPool', () => { const pool6: Swap.Pool = { tokenA: {quantity: '973669994', tokenId: 'tokenA'}, tokenB: {quantity: '13710853133', tokenId: 'tokenB'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, @@ -126,8 +126,8 @@ describe('getBestSellPool', () => { const pool1: Swap.Pool = { tokenB: {quantity: '529504614', tokenId: 'tokenB'}, tokenA: {quantity: '7339640354', tokenId: 'tokenA'}, - tokenBPriceLovelace: '1', - tokenAPriceLovelace: '0.06950020009', + ptPriceTokenB: '1', + ptPriceTokenA: '0.06950020009', fee: '0.3', // 0.3% provider: 'muesliswap_v2', price: 0, @@ -143,8 +143,8 @@ describe('getBestSellPool', () => { const pool2: Swap.Pool = { tokenB: {quantity: '143610201719', tokenId: 'tokenB'}, tokenA: {quantity: '2055821866531', tokenId: 'tokenA'}, - tokenBPriceLovelace: '1', - tokenAPriceLovelace: '0.06950020009', + ptPriceTokenB: '1', + ptPriceTokenA: '0.06950020009', fee: '0.3', // 0.3% provider: 'vyfi', price: 0, @@ -160,8 +160,8 @@ describe('getBestSellPool', () => { const pool3: Swap.Pool = { tokenB: {quantity: '27337840212697', tokenId: 'tokenB'}, tokenA: {quantity: '393349086430693', tokenId: 'tokenA'}, - tokenBPriceLovelace: '1', - tokenAPriceLovelace: '0.06950020009', + ptPriceTokenB: '1', + ptPriceTokenA: '0.06950020009', fee: '0.3', // 0.3% provider: 'minswap', price: 0, @@ -177,8 +177,8 @@ describe('getBestSellPool', () => { const pool4: Swap.Pool = { tokenB: {quantity: '3400529909', tokenId: 'tokenB'}, tokenA: {quantity: '49215467634', tokenId: 'tokenA'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.35', // 0.35% provider: 'wingriders', price: 0, @@ -194,8 +194,8 @@ describe('getBestSellPool', () => { const pool5: Swap.Pool = { tokenB: {quantity: '10178222382', tokenId: 'tokenB'}, tokenA: {quantity: '145009426744', tokenId: 'tokenA'}, - tokenBPriceLovelace: '1', - tokenAPriceLovelace: '0.06950020009', + ptPriceTokenB: '1', + ptPriceTokenA: '0.06950020009', fee: '0.3', // 0.3% provider: 'sundaeswap', price: 0, @@ -211,8 +211,8 @@ describe('getBestSellPool', () => { const pool6: Swap.Pool = { tokenB: {quantity: '973669994', tokenId: 'tokenB'}, tokenA: {quantity: '13710853133', tokenId: 'tokenA'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '0.06950020009', + ptPriceTokenA: '1', + ptPriceTokenB: '0.06950020009', fee: '0.05', // 0.05% provider: 'sundaeswap', price: 0, diff --git a/packages/swap/src/helpers/orders/getBuyAmount.test.ts b/packages/swap/src/helpers/orders/getBuyAmount.test.ts index 006a0a84e0..1095a3b903 100644 --- a/packages/swap/src/helpers/orders/getBuyAmount.test.ts +++ b/packages/swap/src/helpers/orders/getBuyAmount.test.ts @@ -7,8 +7,8 @@ describe('getBuyAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -37,8 +37,8 @@ describe('getBuyAmount', () => { const pool = { tokenA: {quantity: '2022328173071', tokenId: ''}, tokenB: {quantity: '277153', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'muesliswap', price: 7296793.37070499, @@ -67,8 +67,8 @@ describe('getBuyAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/getMarketPrice.test.ts b/packages/swap/src/helpers/orders/getMarketPrice.test.ts index f31e1dfc1c..99c3f6cad0 100644 --- a/packages/swap/src/helpers/orders/getMarketPrice.test.ts +++ b/packages/swap/src/helpers/orders/getMarketPrice.test.ts @@ -7,8 +7,8 @@ describe('getMarketPrice', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -32,8 +32,8 @@ describe('getMarketPrice', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', // 0.3% provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts index 3a4c17f630..bac69dffc5 100644 --- a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts @@ -7,8 +7,8 @@ describe('getPriceAfterFee', () => { const pool = { tokenA: {quantity: '1200400368252', tokenId: 'tokenA'}, tokenB: {quantity: '11364790709', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0.03465765134', - tokenBPriceLovelace: '3.81247293317', + ptPriceTokenA: '0.03465765134', + ptPriceTokenB: '3.81247293317', fee: '0.3', // 0.3% provider: 'minswap', price: 2, @@ -32,8 +32,8 @@ describe('getPriceAfterFee', () => { const pool = { tokenA: {quantity: '143983812522', tokenId: 'tokenA'}, tokenB: {quantity: '2050476716943', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0.06954250577', - tokenBPriceLovelace: '1', + ptPriceTokenA: '0.06954250577', + ptPriceTokenB: '1', fee: '0.3', // 0.3% provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.ts index afeb888f83..13584d90d1 100644 --- a/packages/swap/src/helpers/orders/getPriceAfterFee.ts +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.ts @@ -26,7 +26,7 @@ export const getPriceAfterFee = ( const [firstToken, secondToken] = isSellTokenA ? [A, B] : [B, A] const sellTokenPriceLovelace = new BigNumber( - isSellTokenA ? pool.tokenAPriceLovelace : pool.tokenBPriceLovelace, + isSellTokenA ? pool.ptPriceTokenA : pool.ptPriceTokenB, ) const feeInTokenEquivalent = sellTokenPriceLovelace.isZero() diff --git a/packages/swap/src/helpers/orders/getSellAmount.test.ts b/packages/swap/src/helpers/orders/getSellAmount.test.ts index b72db6581a..90dc10f7a6 100644 --- a/packages/swap/src/helpers/orders/getSellAmount.test.ts +++ b/packages/swap/src/helpers/orders/getSellAmount.test.ts @@ -7,8 +7,8 @@ describe('getSellAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.5', // 0.5% provider: 'minswap', price: 2, @@ -41,8 +41,8 @@ describe('getSellAmount', () => { const pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.5', // 0.5% provider: 'minswap', price: 2, @@ -71,8 +71,8 @@ describe('getSellAmount', () => { const pool = { tokenA: {quantity: '1000000', tokenId: 'tokenA'}, tokenB: {quantity: '2000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '10', provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/makeLimitOrder.test.ts b/packages/swap/src/helpers/orders/makeLimitOrder.test.ts index e62d60b1e4..3e484d5f45 100644 --- a/packages/swap/src/helpers/orders/makeLimitOrder.test.ts +++ b/packages/swap/src/helpers/orders/makeLimitOrder.test.ts @@ -14,8 +14,8 @@ describe('makeLimitOrder', () => { const pool: Swap.Pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', provider: 'minswap', price: 2, diff --git a/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts b/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts index 111bbb8a61..3146240bf9 100644 --- a/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts +++ b/packages/swap/src/helpers/orders/makePossibleMarketOrder.test.ts @@ -15,8 +15,8 @@ describe('makePossibleMarketOrder', () => { const pool1: Swap.Pool = { tokenA: {quantity: '4500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', provider: 'minswap', price: 2, @@ -31,8 +31,8 @@ describe('makePossibleMarketOrder', () => { const pool2: Swap.Pool = { tokenA: {quantity: '5500000', tokenId: 'tokenA'}, tokenB: {quantity: '9000000', tokenId: 'tokenB'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', fee: '0.3', provider: 'sundaeswap', price: 2, diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts index f75fc00c0d..f43e25536a 100644 --- a/packages/swap/src/helpers/transformers.ts +++ b/packages/swap/src/helpers/transformers.ts @@ -132,8 +132,8 @@ export const transformersMaker = ( const pool: Swap.Pool = { tokenA: asYoroiAmount(tokenA), tokenB: asYoroiAmount(tokenB), - tokenAPriceLovelace: tokenA.priceAda, - tokenBPriceLovelace: tokenB.priceAda, + ptPriceTokenA: tokenA.priceAda, + ptPriceTokenB: tokenB.priceAda, deposit: asYoroiAmount({amount: lvlDeposit, address: undefined}), lpToken: asYoroiAmount(lpToken), batcherFee: asYoroiAmount({amount: batcherFee, address: undefined}), diff --git a/packages/swap/src/translators/reactjs/state/state.mocks.ts b/packages/swap/src/translators/reactjs/state/state.mocks.ts index bea576db1c..990f2c1a90 100644 --- a/packages/swap/src/translators/reactjs/state/state.mocks.ts +++ b/packages/swap/src/translators/reactjs/state/state.mocks.ts @@ -24,8 +24,8 @@ export const mockSwapStateDefault: SwapState = { fee: '', tokenA: {tokenId: '', quantity: '0'}, tokenB: {tokenId: '', quantity: '0'}, - tokenAPriceLovelace: '0', - tokenBPriceLovelace: '0', + ptPriceTokenA: '0', + ptPriceTokenB: '0', price: 0, batcherFee: {tokenId: '', quantity: '0'}, deposit: {tokenId: '', quantity: '0'}, diff --git a/packages/swap/src/translators/reactjs/state/state.test.ts b/packages/swap/src/translators/reactjs/state/state.test.ts index d40a16c12a..be8f673c5d 100644 --- a/packages/swap/src/translators/reactjs/state/state.test.ts +++ b/packages/swap/src/translators/reactjs/state/state.test.ts @@ -162,8 +162,8 @@ describe('State Actions', () => { price: 1, tokenA: {tokenId: '', quantity: '1'}, tokenB: {tokenId: '', quantity: '1'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '1', + ptPriceTokenA: '1', + ptPriceTokenB: '1', }, } const expectedState = produce(mockSwapStateDefault, (draft) => { @@ -188,8 +188,8 @@ describe('State Actions', () => { price: 1, tokenA: {tokenId: '', quantity: '1'}, tokenB: {tokenId: '', quantity: '1'}, - tokenAPriceLovelace: '1', - tokenBPriceLovelace: '1', + ptPriceTokenA: '1', + ptPriceTokenB: '1', }, } diff --git a/packages/types/src/swap/pool.ts b/packages/types/src/swap/pool.ts index c340402e54..bf34c0c970 100644 --- a/packages/types/src/swap/pool.ts +++ b/packages/types/src/swap/pool.ts @@ -27,8 +27,8 @@ export type SwapPool = { fee: string // % pool liquidity provider fee, usually 0.3. tokenA: BalanceAmount tokenB: BalanceAmount - tokenAPriceLovelace: string // float, current price in lovelace of tokenA, i.e. 0.000000000000000000. - tokenBPriceLovelace: string // float, current price in lovelace of tokenB, i.e. 0.000000000000000000. + ptPriceTokenA: string // float, current price in lovelace of tokenA, i.e. 0.000000000000000000. + ptPriceTokenB: string // float, current price in lovelace of tokenB, i.e. 0.000000000000000000. price: number // float, current price in tokenA / tokenB according to the pool, NOT SUITABLE for price calculations, just for display purposes, i.e. 0.9097362621640215. batcherFee: BalanceAmount deposit: BalanceAmount // amount of deposit / minUTxO required by protocol, returned to user, in lovelace. From 2a9ad547d1ce6c37a200129b1de9b3d1d5fd78fe Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Fri, 6 Oct 2023 23:12:24 +0100 Subject: [PATCH 17/19] chore: updates + tests --- packages/openswap/src/types.ts | 2 + .../src/adapters/openswap-api/api.test.ts | 28 ++++++++--- .../swap/src/adapters/openswap-api/api.ts | 32 ++++++------ .../adapters/openswap-api/openswap.mocks.ts | 20 ++++---- .../src/helpers/orders/getBestBuyPool.test.ts | 45 +++++++++++++++-- .../swap/src/helpers/orders/getBestBuyPool.ts | 25 ++++++---- .../helpers/orders/getBestSellPool.test.ts | 43 +++++++++++++++- .../src/helpers/orders/getBestSellPool.ts | 19 ++++--- .../helpers/orders/getPriceAfterFee.test.ts | 50 +++++++++++++++++++ .../src/helpers/orders/getPriceAfterFee.ts | 35 ++++++------- .../swap/src/helpers/transformers.test.ts | 8 +-- packages/swap/src/helpers/transformers.ts | 20 +++++--- packages/swap/src/manager.mocks.ts | 2 + packages/swap/src/manager.test.ts | 3 +- packages/swap/src/manager.ts | 2 + packages/types/src/swap/api.ts | 4 +- packages/types/src/swap/manager.ts | 2 + 17 files changed, 248 insertions(+), 92 deletions(-) diff --git a/packages/openswap/src/types.ts b/packages/openswap/src/types.ts index acba276b19..0afb7abf85 100644 --- a/packages/openswap/src/types.ts +++ b/packages/openswap/src/types.ts @@ -75,12 +75,14 @@ export type Provider = | 'minswap' | 'sundaeswap' | 'wingriders' + | 'muesliswap' | 'muesliswap_v1' | 'muesliswap_v2' | 'muesliswap_v3' | 'muesliswap_v4' | 'vyfi' | 'spectrum' +// | 'muesliswap_clp' export type Network = 'mainnet' | 'preprod' diff --git a/packages/swap/src/adapters/openswap-api/api.test.ts b/packages/swap/src/adapters/openswap-api/api.test.ts index 2a015340a7..cddae51e83 100644 --- a/packages/swap/src/adapters/openswap-api/api.test.ts +++ b/packages/swap/src/adapters/openswap-api/api.test.ts @@ -7,6 +7,7 @@ import {apiMocks} from './api.mocks' const stakingKey = 'someStakingKey' const primaryTokenId = '' +const supportedProviders: ReadonlyArray = ['minswap'] describe('swapApiMaker', () => { let mockOpenSwapApi: jest.Mocked @@ -19,7 +20,8 @@ describe('swapApiMaker', () => { getOrders: jest.fn(), getTokens: jest.fn(), getCompletedOrders: jest.fn(), - getPools: jest.fn(), + getLiquidityPools: jest.fn(), + getPoolsPair: jest.fn(), network: 'mainnet', } as any }) @@ -34,6 +36,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -56,6 +59,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -80,6 +84,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -107,6 +112,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }) expect(testnet).toBeDefined() @@ -114,6 +120,7 @@ describe('swapApiMaker', () => { isMainnet: false, stakingKey, primaryTokenId, + supportedProviders, }) expect(mainnet).toBeDefined() }) @@ -134,6 +141,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -165,6 +173,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -191,6 +200,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -216,6 +226,7 @@ describe('swapApiMaker', () => { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -238,6 +249,7 @@ describe('swapApiMaker', () => { isMainnet: false, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -253,15 +265,16 @@ describe('swapApiMaker', () => { describe('getPools', () => { it('mainnet', async () => { - mockOpenSwapApi.getPools = jest + mockOpenSwapApi.getLiquidityPools = jest .fn() - .mockResolvedValue(openswapMocks.getPools) + .mockResolvedValue(openswapMocks.getLiquidityPools) const api = swapApiMaker( { isMainnet: true, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -274,19 +287,20 @@ describe('swapApiMaker', () => { }) expect(result).toEqual(apiMocks.getPools) - expect(mockOpenSwapApi.getPools).toHaveBeenCalledTimes(1) + expect(mockOpenSwapApi.getLiquidityPools).toHaveBeenCalledTimes(1) }) it('preprod (mocked)', async () => { - mockOpenSwapApi.getPools = jest + mockOpenSwapApi.getLiquidityPools = jest .fn() - .mockResolvedValue(openswapMocks.getPools) + .mockResolvedValue(openswapMocks.getLiquidityPools) const api = swapApiMaker( { isMainnet: false, stakingKey, primaryTokenId, + supportedProviders, }, { openswap: mockOpenSwapApi, @@ -299,7 +313,7 @@ describe('swapApiMaker', () => { }) expect(result).toBeDefined() - expect(mockOpenSwapApi.getPools).not.toHaveBeenCalled() + expect(mockOpenSwapApi.getLiquidityPools).not.toHaveBeenCalled() }) }) }) diff --git a/packages/swap/src/adapters/openswap-api/api.ts b/packages/swap/src/adapters/openswap-api/api.ts index bf48cd8b93..00cdbda710 100644 --- a/packages/swap/src/adapters/openswap-api/api.ts +++ b/packages/swap/src/adapters/openswap-api/api.ts @@ -9,7 +9,13 @@ export const swapApiMaker = ( isMainnet, stakingKey, primaryTokenId, - }: {isMainnet?: boolean; stakingKey: string; primaryTokenId: string}, + supportedProviders, + }: { + isMainnet?: boolean + stakingKey: string + primaryTokenId: string + supportedProviders: ReadonlyArray + }, deps?: {openswap?: OpenSwapApi}, ): Readonly => { const api = @@ -35,7 +41,6 @@ export const swapApiMaker = ( const orderRequest: OpenSwap.CreateOrderRequest = { walletAddress: address, - // TODO: check this mistmach of protocol x provider on our end protocol: selectedPool.provider as OpenSwap.CreateOrderRequest['protocol'], poolId: selectedPool.poolId, @@ -71,22 +76,18 @@ export const swapApiMaker = ( .getTokens(transformers.asOpenswapTokenId(token)) .then(transformers.asYoroiBalanceTokens) - const getPools: Swap.Api['getPools'] = async ({tokenA, tokenB}) => { + const getPools: Swap.Api['getPools'] = async ({ + tokenA, + tokenB, + providers = supportedProviders, + }) => { if (!isMainnet) return apiMocks.getPools // preprod doesn't return any pools - const tokenIdA = transformers.asOpenswapTokenId(tokenA) - const tokenIdB = transformers.asOpenswapTokenId(tokenB) - return api - .getPools({ - tokenA: { - policyId: tokenIdA.policyId, - assetNameHex: tokenIdA.assetName, - }, - tokenB: { - policyId: tokenIdB.policyId, - assetNameHex: tokenIdB.assetName, - }, + .getLiquidityPools({ + tokenA, + tokenB, + providers, }) .then(transformers.asYoroiPools) } @@ -100,5 +101,6 @@ export const swapApiMaker = ( getCompletedOrders, stakingKey, primaryTokenId, + supportedProviders, } as const } diff --git a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts index acb57932dd..f2e5512ac7 100644 --- a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts +++ b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts @@ -310,7 +310,7 @@ const getOpenOrders: OpenSwap.OpenOrder[] = [ }, ] -const getPools: OpenSwap.Pool[] = [ +const getLiquidityPools: OpenSwap.LiquidityPool[] = [ { provider: 'minswap', poolFee: '0.3', @@ -324,7 +324,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, tokenB: { amount: '780', @@ -336,7 +336,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, batcherFee: '2000000', // depositFee: { @@ -377,7 +377,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, tokenB: { amount: '780', @@ -389,7 +389,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, batcherFee: '2000000', // depositFee: { @@ -430,7 +430,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, tokenB: { amount: '780', @@ -442,7 +442,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, batcherFee: '2000000', // depositFee: { @@ -483,7 +483,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, tokenB: { amount: '780', @@ -495,7 +495,7 @@ const getPools: OpenSwap.Pool[] = [ image: '', decimalPlaces: 0, status: '', - priceAda: '0', + priceAda: 0, }, batcherFee: '2000000', // depositFee: { @@ -529,5 +529,5 @@ export const openswapMocks = { getTokens, getCompletedOrders, getOpenOrders, - getPools, + getLiquidityPools, } diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts index a85fdcc1d6..0a7eace89c 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.test.ts @@ -114,11 +114,12 @@ describe('getBestBuyPool', () => { const pools = [pool1, pool2, pool3, pool4, pool5, pool6] const bestBuyPool = getBestBuyPool(pools, sell) - expect(bestBuyPool?.provider).toBe('minswap') - if (bestBuyPool) { + expect(bestBuyPool.provider).toBe('minswap') const buyAmount = getBuyAmount(bestBuyPool, sell) expect(buyAmount.quantity).toBe('693300972') + } else { + fail('bestBuyPool undefined') } }) @@ -232,11 +233,47 @@ describe('getBestBuyPool', () => { const pools = [pool1, pool2, pool3, pool4, pool5, pool6] const bestBuyPool = getBestBuyPool(pools, sell) - expect(bestBuyPool?.provider).toBe('minswap') - if (bestBuyPool) { + expect(bestBuyPool.provider).toBe('minswap') const buyAmount = getBuyAmount(bestBuyPool, sell) expect(buyAmount.quantity).toBe('14336451239') + } else { + fail('bestBuyPool undefined') } }) + + it('should return undefined if sell amount is 0', () => { + const pool1: Swap.Pool = { + tokenA: {quantity: '529504614', tokenId: 'tokenA'}, + tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', + fee: '0.3', // 0.3% + provider: 'muesliswap_v2', + price: 0, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const sell: Balance.Amount = { + quantity: '0', + tokenId: 'tokenA', + } + + expect(getBestBuyPool([pool1], sell)).toBeUndefined() + }) + + it('should return undefined if pools list is empty', () => { + const sell: Balance.Amount = { + quantity: '1', + tokenId: 'tokenA', + } + + expect(getBestBuyPool([], sell)).toBeUndefined() + }) }) diff --git a/packages/swap/src/helpers/orders/getBestBuyPool.ts b/packages/swap/src/helpers/orders/getBestBuyPool.ts index 82ac2cbd58..018a6d593a 100644 --- a/packages/swap/src/helpers/orders/getBestBuyPool.ts +++ b/packages/swap/src/helpers/orders/getBestBuyPool.ts @@ -20,22 +20,24 @@ export const getBestBuyPool = ( pools: Swap.Pool[], sell: Balance.Amount, ): Swap.Pool | undefined => { - if (pools.length === 0) { - return undefined - } + if (pools.length === 0 || Quantities.isZero(sell.quantity)) return undefined + let bestPool: Swap.Pool | undefined let bestPrice = new BigNumber(0) + for (const pool of pools) { + const buy = getBuyAmount(pool, sell) + if (Quantities.isZero(buy.quantity)) continue + const isSellTokenA = sell.tokenId === pool.tokenA.tokenId - const buyAmount = getBuyAmount(pool, sell) - if (Quantities.isZero(buyAmount.quantity)) { - continue - } - const [aAmount, bAmount] = isSellTokenA - ? [sell.quantity, buyAmount.quantity] - : [buyAmount.quantity, sell.quantity] + const [amountA, amountB] = isSellTokenA ? [sell, buy] : [buy, sell] + const price = getPriceAfterFee( + pool, + amountA.quantity, + amountB.quantity, + sell.tokenId, + ) - const price = getPriceAfterFee(pool, aAmount, bAmount, sell.tokenId) if (bestPool === undefined) { bestPool = pool bestPrice = price @@ -47,5 +49,6 @@ export const getBestBuyPool = ( bestPrice = price } } + return bestPool } diff --git a/packages/swap/src/helpers/orders/getBestSellPool.test.ts b/packages/swap/src/helpers/orders/getBestSellPool.test.ts index ca253d3628..c98692a907 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.test.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.test.ts @@ -114,11 +114,13 @@ describe('getBestSellPool', () => { const pools = [pool1, pool2, pool3, pool4, pool5, pool6] const bestSellPool = getBestSellPool(pools, buy) - expect(bestSellPool?.provider).toBe('minswap') if (bestSellPool) { + expect(bestSellPool.provider).toBe('minswap') const sellAmount = getSellAmount(bestSellPool, buy) expect(sellAmount.quantity).toBe('69709507') + } else { + fail('bestSellPool is undefined') } }) @@ -232,11 +234,48 @@ describe('getBestSellPool', () => { const pools = [pool1, pool2, pool3, pool4, pool5, pool6] const bestSellPool = getBestSellPool(pools, buy) - expect(bestSellPool?.provider).toBe('minswap') if (bestSellPool) { + expect(bestSellPool.provider).toBe('minswap') const sellAmount = getSellAmount(bestSellPool, buy) expect(sellAmount.quantity).toBe('69709507') + } else { + fail('bestSellPool is undefined') } }) + + it('should return undefined if buy amount is 0', () => { + const pool1: Swap.Pool = { + tokenA: {quantity: '529504614', tokenId: 'tokenA'}, + tokenB: {quantity: '7339640354', tokenId: 'tokenB'}, + ptPriceTokenA: '1', + ptPriceTokenB: '0.0695404765', + fee: '0.3', // 0.3% + provider: 'muesliswap_v2', + price: 0, + batcherFee: {quantity: '950000', tokenId: ''}, + deposit: {quantity: '2000000', tokenId: ''}, + poolId: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } + + const sell: Balance.Amount = { + quantity: '0', + tokenId: 'tokenA', + } + + expect(getBestSellPool([pool1], sell)).toBeUndefined() + }) + + it('should return undefined if pools list is empty', () => { + const sell: Balance.Amount = { + quantity: '1', + tokenId: 'tokenA', + } + + expect(getBestSellPool([], sell)).toBeUndefined() + }) }) diff --git a/packages/swap/src/helpers/orders/getBestSellPool.ts b/packages/swap/src/helpers/orders/getBestSellPool.ts index 932b19a4a2..226d9c9c6d 100644 --- a/packages/swap/src/helpers/orders/getBestSellPool.ts +++ b/packages/swap/src/helpers/orders/getBestSellPool.ts @@ -20,21 +20,19 @@ export const getBestSellPool = ( pools: Swap.Pool[], buy: Balance.Amount, ): Swap.Pool | undefined => { - if (pools.length === 0) { - return undefined - } + if (pools.length === 0 || Quantities.isZero(buy.quantity)) return undefined + let bestPool: Swap.Pool | undefined let bestPrice = new BigNumber(0) + for (const pool of pools) { + const sell = getSellAmount(pool, buy) + if (Quantities.isZero(sell.quantity)) continue + const isBuyTokenA = buy.tokenId === pool.tokenA.tokenId - const sellAmount = getSellAmount(pool, buy) - if (Quantities.isZero(sellAmount.quantity)) { - continue - } const [aAmount, bAmount] = isBuyTokenA - ? [buy.quantity, sellAmount.quantity] - : [sellAmount.quantity, buy.quantity] - + ? [buy.quantity, sell.quantity] + : [sell.quantity, buy.quantity] const price = getPriceAfterFee( pool, aAmount, @@ -53,5 +51,6 @@ export const getBestSellPool = ( bestPrice = price } } + return bestPool } diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts index bac69dffc5..44e24ab60f 100644 --- a/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.test.ts @@ -52,4 +52,54 @@ describe('getPriceAfterFee', () => { const expected = new BigNumber('14.39254173470077386167') expect(result).toStrictEqual(expected) }) + + it('should return 0 when sell side is 0', () => { + const pool = { + tokenA: {quantity: '143983812522', tokenId: 'tokenA'}, + tokenB: {quantity: '2050476716943', tokenId: 'tokenB'}, + ptPriceTokenA: '0.06954250577', + ptPriceTokenB: '1', + fee: '0.3', // 0.3% + provider: 'minswap', + price: 2, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '1', tokenId: ''}, + poolId: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const tokenAAmount = '0' + const tokenBAmount = '93613464' + const tokenId = 'tokenA' + const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId) + const expected = new BigNumber(0) + expect(result).toStrictEqual(expected) + }) + + it('should return 0 when buy side is 0', () => { + const pool = { + tokenA: {quantity: '143983812522', tokenId: 'tokenA'}, + tokenB: {quantity: '2050476716943', tokenId: 'tokenB'}, + ptPriceTokenA: '0.06954250577', + ptPriceTokenB: '1', + fee: '0.3', // 0.3% + provider: 'minswap', + price: 2, + batcherFee: {quantity: '1900000', tokenId: ''}, + deposit: {quantity: '1', tokenId: ''}, + poolId: '0', + lpToken: { + quantity: '0', + tokenId: '0', + }, + } as Swap.Pool + const tokenAAmount = '10000000000' + const tokenBAmount = '0' + const tokenId = 'tokenA' + const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId) + const expected = new BigNumber(0) + expect(result).toStrictEqual(expected) + }) }) diff --git a/packages/swap/src/helpers/orders/getPriceAfterFee.ts b/packages/swap/src/helpers/orders/getPriceAfterFee.ts index 13584d90d1..d9db9bb375 100644 --- a/packages/swap/src/helpers/orders/getPriceAfterFee.ts +++ b/packages/swap/src/helpers/orders/getPriceAfterFee.ts @@ -1,7 +1,6 @@ -import {Swap} from '@yoroi/types' +import {Balance, Swap} from '@yoroi/types' import BigNumber from 'bignumber.js' - -import {BalanceQuantity} from '@yoroi/types/src/balance/token' +import {Quantities} from '../../utils/quantities' /** * Calculate the price with batcher fee in a liquidity pool. @@ -15,27 +14,25 @@ import {BalanceQuantity} from '@yoroi/types/src/balance/token' */ export const getPriceAfterFee = ( pool: Swap.Pool, - tokenAAmount: BalanceQuantity, - tokenBAmount: BalanceQuantity, + quantityA: Balance.Quantity, + quantityB: Balance.Quantity, sellTokenId: string, ): BigNumber => { - const isSellTokenA = sellTokenId === pool.tokenA.tokenId + if (Quantities.isZero(quantityA) || Quantities.isZero(quantityB)) + return new BigNumber(0) - const A = new BigNumber(tokenAAmount) - const B = new BigNumber(tokenBAmount) + const A = new BigNumber(quantityA) + const B = new BigNumber(quantityB) - const [firstToken, secondToken] = isSellTokenA ? [A, B] : [B, A] - const sellTokenPriceLovelace = new BigNumber( - isSellTokenA ? pool.ptPriceTokenA : pool.ptPriceTokenB, - ) + const isSellTokenA = sellTokenId === pool.tokenA.tokenId + const [dividend, divisor] = isSellTokenA ? [A, B] : [B, A] + const sellPriceInPtTerm = isSellTokenA + ? new BigNumber(pool.ptPriceTokenA) + : new BigNumber(pool.ptPriceTokenB) - const feeInTokenEquivalent = sellTokenPriceLovelace.isZero() + const feeInSellTerm = sellPriceInPtTerm.isZero() ? new BigNumber(0) - : new BigNumber(pool.batcherFee.quantity).dividedBy(sellTokenPriceLovelace) + : new BigNumber(pool.batcherFee.quantity).dividedBy(sellPriceInPtTerm) - const firstTokenWithFee = firstToken.plus(feeInTokenEquivalent) - - return secondToken.isZero() - ? new BigNumber(0) - : firstTokenWithFee.dividedBy(secondToken) + return dividend.plus(feeInSellTerm).dividedBy(divisor) } diff --git a/packages/swap/src/helpers/transformers.test.ts b/packages/swap/src/helpers/transformers.test.ts index 427c825ad5..dc458ea0cd 100644 --- a/packages/swap/src/helpers/transformers.test.ts +++ b/packages/swap/src/helpers/transformers.test.ts @@ -187,24 +187,24 @@ describe('asYoroiPools', () => { }) it('success (filter out unsupported pools)', () => { - const result = transformers.asYoroiPools(openswapMocks.getPools) + const result = transformers.asYoroiPools(openswapMocks.getLiquidityPools) expect(result).toEqual>(apiMocks.getPools) // should filter out unsupported pools - expect(result.length).toBe(openswapMocks.getPools.length - 1) + expect(result.length).toBe(openswapMocks.getLiquidityPools.length - 1) }) }) describe('asYoroiPool', () => { it('success (supported pool)', () => { - const result = transformers.asYoroiPool(openswapMocks.getPools[0]!) + const result = transformers.asYoroiPool(openswapMocks.getLiquidityPools[0]!) expect(result).toEqual(apiMocks.getPools[0]!) }) it('success (unsupported pool)', () => { - const result = transformers.asYoroiPool(openswapMocks.getPools[3]!) + const result = transformers.asYoroiPool(openswapMocks.getLiquidityPools[3]!) expect(result).toBeNull() }) diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts index f43e25536a..46bf8bee5b 100644 --- a/packages/swap/src/helpers/transformers.ts +++ b/packages/swap/src/helpers/transformers.ts @@ -115,7 +115,9 @@ export const transformersMaker = ( return balanceToken } - const asYoroiPool = (openswapPool: OpenSwap.Pool): Swap.Pool | null => { + const asYoroiPool = ( + openswapLiquidityPool: OpenSwap.LiquidityPool, + ): Swap.Pool | null => { const { batcherFee, poolFee, @@ -125,15 +127,15 @@ export const transformersMaker = ( tokenB, provider, poolId, - } = openswapPool + } = openswapLiquidityPool if (provider && !isSupportedProvider(provider)) return null const pool: Swap.Pool = { tokenA: asYoroiAmount(tokenA), tokenB: asYoroiAmount(tokenB), - ptPriceTokenA: tokenA.priceAda, - ptPriceTokenB: tokenB.priceAda, + ptPriceTokenA: tokenA.priceAda?.toString() ?? '0', + ptPriceTokenB: tokenB.priceAda?.toString() ?? '0', deposit: asYoroiAmount({amount: lvlDeposit, address: undefined}), lpToken: asYoroiAmount(lpToken), batcherFee: asYoroiAmount({amount: batcherFee, address: undefined}), @@ -175,12 +177,14 @@ export const transformersMaker = ( /** * Filter out pools that are not supported by Yoroi * - * @param openswapPools + * @param openswapLiquidityPools * @returns {Swap.Pool[]} */ - const asYoroiPools = (openswapPools: OpenSwap.Pool[]): Swap.Pool[] => { - if (openswapPools?.length > 0) - return openswapPools + const asYoroiPools = ( + openswapLiquidityPools: OpenSwap.LiquidityPool[], + ): Swap.Pool[] => { + if (openswapLiquidityPools?.length > 0) + return openswapLiquidityPools .map(asYoroiPool) .filter((pool): pool is Swap.Pool => pool !== null) diff --git a/packages/swap/src/manager.mocks.ts b/packages/swap/src/manager.mocks.ts index 1c253f3081..71b020e47b 100644 --- a/packages/swap/src/manager.mocks.ts +++ b/packages/swap/src/manager.mocks.ts @@ -172,6 +172,7 @@ export const mockSwapManager: Swap.Manager = { clearStorage: clear.success, primaryTokenId: '', stakingKey: '', + supportedProviders: [] as const, } as const export const mockSwapManagerDefault: Swap.Manager = { @@ -197,4 +198,5 @@ export const mockSwapManagerDefault: Swap.Manager = { clearStorage: clear.error.unknown, primaryTokenId: '', stakingKey: '', + supportedProviders: [] as const, } as const diff --git a/packages/swap/src/manager.test.ts b/packages/swap/src/manager.test.ts index 520f34d0c2..a40c2a1cff 100644 --- a/packages/swap/src/manager.test.ts +++ b/packages/swap/src/manager.test.ts @@ -24,6 +24,7 @@ describe('swapManagerMaker', () => { getCompletedOrders: jest.fn(), primaryTokenId: '', stakingKey: 'someStakingKey', + supportedProviders: ['minswap'] as const, } beforeEach(() => { @@ -33,7 +34,7 @@ describe('swapManagerMaker', () => { it('clearStorage clear', async () => { await expect(manager.clearStorage()).resolves.toBeUndefined() - await expect(mockedStorage.clear).toHaveBeenCalledTimes(1) + expect(mockedStorage.clear).toHaveBeenCalledTimes(1) }) it('slippage', async () => { diff --git a/packages/swap/src/manager.ts b/packages/swap/src/manager.ts index 9014335e13..eebd615374 100644 --- a/packages/swap/src/manager.ts +++ b/packages/swap/src/manager.ts @@ -14,6 +14,7 @@ export const swapManagerMaker = ( createOrder, primaryTokenId, stakingKey, + supportedProviders, } = swapApi const order = { @@ -45,5 +46,6 @@ export const swapManagerMaker = ( pools, primaryTokenId, stakingKey, + supportedProviders, } as const } diff --git a/packages/types/src/swap/api.ts b/packages/types/src/swap/api.ts index f84ddd0842..ee59c50334 100644 --- a/packages/types/src/swap/api.ts +++ b/packages/types/src/swap/api.ts @@ -6,7 +6,7 @@ import { SwapCreateOrderResponse, SwapOpenOrder, } from './order' -import {SwapPool} from './pool' +import {SwapPool, SwapPoolProvider} from './pool' export interface SwapApi { createOrder(orderData: SwapCreateOrderData): Promise @@ -16,8 +16,10 @@ export interface SwapApi { getPools(args: { tokenA: BalanceToken['info']['id'] tokenB: BalanceToken['info']['id'] + providers?: ReadonlyArray }): Promise getTokens(tokenIdBase: BalanceToken['info']['id']): Promise stakingKey: string primaryTokenId: BalanceToken['info']['id'] + supportedProviders: ReadonlyArray } diff --git a/packages/types/src/swap/manager.ts b/packages/types/src/swap/manager.ts index c5b2ec1b86..9e9359c11b 100644 --- a/packages/types/src/swap/manager.ts +++ b/packages/types/src/swap/manager.ts @@ -1,5 +1,6 @@ import {BalanceToken} from '../balance/token' import {SwapApi} from './api' +import {SwapPoolProvider} from './pool' import {SwapStorage} from './storage' export type SwapManager = Readonly<{ @@ -25,4 +26,5 @@ export type SwapManager = Readonly<{ } stakingKey: string primaryTokenId: BalanceToken['info']['id'] + supportedProviders: ReadonlyArray }> From 21411fa57c6bb3a2aba951674fbe6247db814082 Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Sat, 7 Oct 2023 09:06:58 +0100 Subject: [PATCH 18/19] chore: readability --- .../swap/src/helpers/transformers.test.ts | 10 +++++ packages/swap/src/helpers/transformers.ts | 42 +++++++++++-------- packages/swap/src/utils/quantities.test.ts | 7 ++++ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/packages/swap/src/helpers/transformers.test.ts b/packages/swap/src/helpers/transformers.test.ts index dc458ea0cd..c8d7dfd6a4 100644 --- a/packages/swap/src/helpers/transformers.test.ts +++ b/packages/swap/src/helpers/transformers.test.ts @@ -118,6 +118,16 @@ describe('asYoroiAmount', () => { }) }) + it('success nameless token', () => { + const result = transformers.asYoroiAmount({ + token: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b', + }) + expect(result).toEqual({ + quantity: '0', + tokenId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b.', + }) + }) + it('success (lovelace) primary token', () => { const result = transformers.asYoroiAmount({ amount: '1000000', diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts index 46bf8bee5b..45141a61e6 100644 --- a/packages/swap/src/helpers/transformers.ts +++ b/packages/swap/src/helpers/transformers.ts @@ -5,6 +5,7 @@ import {isString} from '@yoroi/common' import {Quantities} from '../utils/quantities' import {supportedProviders} from '../translators/constants' +import {asQuantity} from '../utils/asQuantity' export const transformersMaker = ( primaryTokenId: Balance.Token['info']['id'], @@ -134,8 +135,8 @@ export const transformersMaker = ( const pool: Swap.Pool = { tokenA: asYoroiAmount(tokenA), tokenB: asYoroiAmount(tokenB), - ptPriceTokenA: tokenA.priceAda?.toString() ?? '0', - ptPriceTokenB: tokenB.priceAda?.toString() ?? '0', + ptPriceTokenA: tokenA.priceAda.toString(), + ptPriceTokenB: tokenB.priceAda.toString(), deposit: asYoroiAmount({amount: lvlDeposit, address: undefined}), lpToken: asYoroiAmount(lpToken), batcherFee: asYoroiAmount({amount: batcherFee, address: undefined}), @@ -152,26 +153,31 @@ export const transformersMaker = ( policyId: string name: string } + // openswap is inconsistent about ADA + // sometimes is '.', '' or 'lovelace' token?: string amount?: string }): Balance.Amount => { - if (isString(openswapAmount?.amount)) { - // openswap is inconsistent about ADA - // sometimes is '.', '' or 'lovelace' - const {amount, address, token} = openswapAmount - const [policyId, name = ''] = - address == null - ? token?.split('.') ?? (['', ''] as [string, string?]) - : [address.policyId, address.name] - return { - quantity: amount as Balance.Quantity, - tokenId: asYoroiTokenId({ - policyId: policyId ?? '', - name: name ?? '', - }), - } as const + const {amount, address, token} = openswapAmount ?? {} + + let policyId = '' + let name = '' + + if (address) { + policyId = address.policyId + name = address.name + } else if (isString(token)) { + const tokenParts = token.split('.') as [string, string?] + policyId = tokenParts[0] + name = tokenParts[1] ?? '' } - return {quantity: Quantities.zero, tokenId: ''} as const + + const yoroiAmount: Balance.Amount = { + quantity: asQuantity(amount ?? Quantities.zero), + tokenId: asYoroiTokenId({policyId, name}), + } as const + + return yoroiAmount } /** diff --git a/packages/swap/src/utils/quantities.test.ts b/packages/swap/src/utils/quantities.test.ts index eda0af30e2..2878e15726 100644 --- a/packages/swap/src/utils/quantities.test.ts +++ b/packages/swap/src/utils/quantities.test.ts @@ -146,6 +146,13 @@ describe('Quantities', () => { const denomination = 2 expect(Quantities.format(quantity, denomination)).toBe('0.0001') }) + + it('should format a quantity with the specified denomination and precision', () => { + const quantity = '0.01' + const denomination = 2 + const precision = 1 + expect(Quantities.format(quantity, denomination, precision)).toBe('0') + }) }) it('should find the maximum quantity from an array of quantities', () => { From 869e8363b495c21c3441933e97f27670507f96ed Mon Sep 17 00:00:00 2001 From: Juliano Lazzarotto <30806844+stackchain@users.noreply.github.com> Date: Sat, 7 Oct 2023 09:52:13 +0100 Subject: [PATCH 19/19] chore: factory update --- .../src/TxHistory/TxHistoryNavigator.tsx | 3 +- .../src/TxHistory/TxHistoryNavigator.json | 112 +++++++++--------- 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx b/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx index 0e560bbff2..17934c92ec 100644 --- a/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx +++ b/apps/wallet-mobile/src/TxHistory/TxHistoryNavigator.tsx @@ -1,5 +1,5 @@ import {createStackNavigator} from '@react-navigation/stack' -import {swapApiMaker, swapManagerMaker, SwapProvider, swapStorageMaker} from '@yoroi/swap' +import {supportedProviders, swapApiMaker, swapManagerMaker, SwapProvider, swapStorageMaker} from '@yoroi/swap' import React from 'react' import {defineMessages, useIntl} from 'react-intl' import {StyleSheet, Text, TouchableOpacity, TouchableOpacityProps} from 'react-native' @@ -53,6 +53,7 @@ export const TxHistoryNavigator = () => { isMainnet: wallet.networkId !== 300, stakingKey, primaryTokenId: wallet.primaryTokenInfo.id, + supportedProviders, }), [wallet.networkId, stakingKey, wallet.primaryTokenInfo.id], ) diff --git a/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json b/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json index 2ed0e5e7e1..3b2e8e6844 100644 --- a/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json +++ b/apps/wallet-mobile/translations/messages/src/TxHistory/TxHistoryNavigator.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Receive", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 266, + "line": 267, "column": 16, - "index": 9262 + "index": 9310 }, "end": { - "line": 269, + "line": 270, "column": 3, - "index": 9351 + "index": 9399 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!Swap", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 270, + "line": 271, "column": 13, - "index": 9366 + "index": 9414 }, "end": { - "line": 273, + "line": 274, "column": 3, - "index": 9439 + "index": 9487 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Swap from", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 274, + "line": 275, "column": 17, - "index": 9458 + "index": 9506 }, "end": { - "line": 277, + "line": 278, "column": 3, - "index": 9535 + "index": 9583 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Swap to", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 278, + "line": 279, "column": 15, - "index": 9552 + "index": 9600 }, "end": { - "line": 281, + "line": 282, "column": 3, - "index": 9625 + "index": 9673 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Slippage Tolerance", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 282, + "line": 283, "column": 21, - "index": 9648 + "index": 9696 }, "end": { - "line": 285, + "line": 286, "column": 3, - "index": 9743 + "index": 9791 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Select pool", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 286, + "line": 287, "column": 14, - "index": 9759 + "index": 9807 }, "end": { - "line": 289, + "line": 290, "column": 3, - "index": 9840 + "index": 9888 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Send", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 290, + "line": 291, "column": 13, - "index": 9855 + "index": 9903 }, "end": { - "line": 293, + "line": 294, "column": 3, - "index": 9935 + "index": 9983 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Scan QR code address", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 294, + "line": 295, "column": 18, - "index": 9955 + "index": 10003 }, "end": { - "line": 297, + "line": 298, "column": 3, - "index": 10056 + "index": 10104 } }, { @@ -124,14 +124,14 @@ "defaultMessage": "!!!Select asset", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 298, + "line": 299, "column": 20, - "index": 10078 + "index": 10126 }, "end": { - "line": 301, + "line": 302, "column": 3, - "index": 10167 + "index": 10215 } }, { @@ -139,14 +139,14 @@ "defaultMessage": "!!!Selected tokens", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 302, + "line": 303, "column": 26, - "index": 10195 + "index": 10243 }, "end": { - "line": 305, + "line": 306, "column": 3, - "index": 10299 + "index": 10347 } }, { @@ -154,14 +154,14 @@ "defaultMessage": "!!!Edit amount", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 306, + "line": 307, "column": 19, - "index": 10320 + "index": 10368 }, "end": { - "line": 309, + "line": 310, "column": 3, - "index": 10413 + "index": 10461 } }, { @@ -169,14 +169,14 @@ "defaultMessage": "!!!Confirm", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 310, + "line": 311, "column": 16, - "index": 10431 + "index": 10479 }, "end": { - "line": 313, + "line": 314, "column": 3, - "index": 10517 + "index": 10565 } }, { @@ -184,14 +184,14 @@ "defaultMessage": "!!!Share this address to receive payments. To protect your privacy, new addresses are generated automatically once you use them.", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 314, + "line": 315, "column": 19, - "index": 10538 + "index": 10586 }, "end": { - "line": 320, + "line": 321, "column": 3, - "index": 10776 + "index": 10824 } }, { @@ -199,14 +199,14 @@ "defaultMessage": "!!!Confirm transaction", "file": "src/TxHistory/TxHistoryNavigator.tsx", "start": { - "line": 321, + "line": 322, "column": 27, - "index": 10805 + "index": 10853 }, "end": { - "line": 324, + "line": 325, "column": 3, - "index": 10898 + "index": 10946 } } ] \ No newline at end of file