From f7549e528536d2a476afe5c6c02f673eea9d6e28 Mon Sep 17 00:00:00 2001 From: jorbuedo Date: Tue, 15 Oct 2024 14:00:43 +0200 Subject: [PATCH] Move swap calculate to manager --- .../TransactionSummary.stories.tsx | 5 +- apps/wallet-mobile/src/kernel/config.ts | 2 +- packages/swap/src/helpers/mocks.ts | 5 +- .../factories/makeOrderCalculations.test.ts | 117 +++++++++--------- .../orders/factories/makeOrderCalculations.ts | 24 +--- .../pools/getBestPoolCalculation.test.ts | 4 +- .../helpers/pools/getBestPoolCalculation.ts | 10 +- packages/swap/src/index.ts | 3 - packages/swap/src/manager.mocks.ts | 9 ++ packages/swap/src/manager.ts | 6 + .../selectedPoolCalculationSelector.test.ts | 48 ++++--- .../selectedPoolCalculationSelector.ts | 20 +-- .../src/translators/reactjs/state/state.ts | 84 ++++++++++--- packages/types/src/index.ts | 8 ++ .../src/swap/calculations.ts} | 21 +++- packages/types/src/swap/manager.ts | 14 +++ 16 files changed, 235 insertions(+), 145 deletions(-) rename packages/{swap/src/types.ts => types/src/swap/calculations.ts} (66%) diff --git a/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/TransactionSummary.stories.tsx b/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/TransactionSummary.stories.tsx index 68d0f74e02..227a9e8c31 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/TransactionSummary.stories.tsx +++ b/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/TransactionSummary.stories.tsx @@ -1,6 +1,7 @@ import {storiesOf} from '@storybook/react-native' import {tokenInfoMocks} from '@yoroi/portfolio' -import {mockSwapManager, mockSwapStateDefault, orderMocks, SwapOrderCalculation, SwapProvider} from '@yoroi/swap' +import {mockSwapManager, mockSwapStateDefault, orderMocks, SwapProvider} from '@yoroi/swap' +import {Swap} from '@yoroi/types' import React from 'react' import {StyleSheet, View} from 'react-native' @@ -33,7 +34,7 @@ storiesOf('TransactionSummary', module) // ) }) -const TxSummary = ({calculation}: {calculation: SwapOrderCalculation}) => { +const TxSummary = ({calculation}: {calculation: Swap.OrderCalculation}) => { return ( { frontendFeeTiers, }) - expect(calculations[0]).toStrictEqual({ + expect(calculations[0]).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -150,9 +149,9 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! + const calculation: Swap.OrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -231,7 +230,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.3379136660', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 3, buy B)', () => { const pool = mocks.mockedPools5[0] as Swap.Pool @@ -262,9 +261,9 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! + const calculation: Swap.OrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + expect(calculation).toStrictEqual({ order: { side: 'buy', slippage: 0, @@ -343,7 +342,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.3379136754', }, pool: pool, - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 4, buy A, reversed case 3) ', () => { const pool = mocks.mockedPools5[1] as Swap.Pool @@ -374,9 +373,9 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! + const calculation: Swap.OrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + expect(calculation).toStrictEqual({ order: { side: 'buy', slippage: 0, @@ -455,7 +454,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.3379136754', }, pool: pool, - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 5, with slippage)', () => { const pool = mocks.mockedPools5[2] as Swap.Pool @@ -562,7 +561,7 @@ describe('makeOrderCalculations', () => { priceImpact: '1.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 6, zero supply)', () => { const pool = mocks.mockedPools5[3] as Swap.Pool @@ -667,7 +666,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 7, sell A, not enough supply)', () => { const pool = mocks.mockedPools5[4] as Swap.Pool @@ -773,7 +772,7 @@ describe('makeOrderCalculations', () => { priceImpact: '-100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 8, buy A, not enough supply)', () => { const pool = mocks.mockedPools5[4] as Swap.Pool @@ -879,7 +878,7 @@ describe('makeOrderCalculations', () => { priceImpact: '-99.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 9, sell A, A supply is zero)', () => { const pool = mocks.mockedPools5[5] as Swap.Pool @@ -985,7 +984,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 10, sell A, B supply is zero)', () => { const pool = mocks.mockedPools5[6] as Swap.Pool @@ -1091,7 +1090,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 11, buy A, A supply is zero)', () => { const pool = mocks.mockedPools5[5] as Swap.Pool @@ -1194,7 +1193,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 12, buy A, B supply is zero)', () => { const pool = mocks.mockedPools5[6] as Swap.Pool @@ -1300,7 +1299,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 13, sell B, B supply is zero)', () => { const pool = mocks.mockedPools5[6] as Swap.Pool @@ -1406,7 +1405,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 14, sell B, A supply is zero)', () => { const pool = mocks.mockedPools5[5] as Swap.Pool @@ -1512,7 +1511,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 15, buy B, B supply is zero)', () => { const pool = mocks.mockedPools5[6] as Swap.Pool @@ -1615,7 +1614,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 16, buy B, A supply is zero)', () => { const pool = mocks.mockedPools5[5] as Swap.Pool @@ -1721,7 +1720,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 17, buy A, limit price)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -1752,8 +1751,8 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'buy', slippage: 0, @@ -1827,7 +1826,7 @@ describe('makeOrderCalculations', () => { priceImpact: '100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 18, sell A, limit price)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -1858,8 +1857,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -1933,7 +1932,7 @@ describe('makeOrderCalculations', () => { priceImpact: '100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 19, buy B, limit price)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -1964,8 +1963,8 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'buy', slippage: 0, @@ -2039,7 +2038,7 @@ describe('makeOrderCalculations', () => { priceImpact: '100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 20, sell B, limit price)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2070,8 +2069,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -2145,7 +2144,7 @@ describe('makeOrderCalculations', () => { priceImpact: '100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 21, no FEF test)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2176,8 +2175,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -2251,7 +2250,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 22, full FEF test)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2285,8 +2284,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -2368,7 +2367,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 23, discount 1 FEF test)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2402,8 +2401,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -2485,7 +2484,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 24, discount 2 FEF test)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2519,8 +2518,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -2602,7 +2601,7 @@ describe('makeOrderCalculations', () => { priceImpact: '0.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 25, zero sell)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2636,8 +2635,8 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'sell', slippage: 0, @@ -2711,7 +2710,7 @@ describe('makeOrderCalculations', () => { priceImpact: '-100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 26, zero buy)', () => { const pool = mocks.mockedPools5[7] as Swap.Pool @@ -2745,8 +2744,8 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const calculation: SwapOrderCalculation = calculations[0]! - expect(calculation).toStrictEqual({ + const calculation: Swap.OrderCalculation = calculations[0]! + expect(calculation).toStrictEqual({ order: { side: 'buy', slippage: 0, @@ -2820,7 +2819,7 @@ describe('makeOrderCalculations', () => { priceImpact: '-100.0000000000', }, pool: pools[0], - } as SwapOrderCalculation) + } as Swap.OrderCalculation) }) it('should calculate all fees and amounts correctly (case 27, zero pt sell side)', () => { const pool: Swap.Pool = mocks.mockedPools7[1]! @@ -2853,7 +2852,7 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const expectedCalculation: SwapOrderCalculation = { + const expectedCalculation: Swap.OrderCalculation = { order: { side: 'buy', slippage: 0, @@ -2961,7 +2960,7 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const expectedCalculation: SwapOrderCalculation = { + const expectedCalculation: Swap.OrderCalculation = { order: { side: 'sell', slippage: 0, @@ -3069,7 +3068,7 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const expectedCalculation: SwapOrderCalculation = { + const expectedCalculation: Swap.OrderCalculation = { order: { side: 'sell', slippage: 0, @@ -3177,7 +3176,7 @@ describe('makeOrderCalculations', () => { side: 'sell', frontendFeeTiers, }) - const expectedCalculation: SwapOrderCalculation = { + const expectedCalculation: Swap.OrderCalculation = { order: { side: 'sell', slippage: 0, @@ -3285,7 +3284,7 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const expectedCalculation: SwapOrderCalculation = { + const expectedCalculation: Swap.OrderCalculation = { order: { side: 'buy', slippage: 0, @@ -3393,7 +3392,7 @@ describe('makeOrderCalculations', () => { side: 'buy', frontendFeeTiers, }) - const expectedCalculation: SwapOrderCalculation = { + const expectedCalculation: Swap.OrderCalculation = { order: { side: 'buy', slippage: 0, diff --git a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts b/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts index a413057d1f..e875dde2f6 100644 --- a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts +++ b/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts @@ -1,13 +1,11 @@ -import {App, Portfolio, Swap} from '@yoroi/types' +import {Portfolio, Swap} from '@yoroi/types' import {BigNumber} from 'bignumber.js' -import {SwapState} from '../../../translators/reactjs/state/state' import {getQuantityWithSlippage} from '../amounts/getQuantityWithSlippage' import {getLiquidityProviderFee} from '../costs/getLiquidityProviderFee' import {getFrontendFee} from '../costs/getFrontendFee' import {getMarketPrice} from '../../prices/getMarketPrice' import {getBuyAmount} from '../amounts/getBuyAmount' import {getSellAmount} from '../amounts/getSellAmount' -import {SwapOrderCalculation} from '../../../types' export const makeOrderCalculations = ({ orderType, @@ -20,27 +18,13 @@ export const makeOrderCalculations = ({ frontendFeeTiers, tokens, priceDecimals = 10, -}: Readonly<{ - orderType: Swap.OrderType - amounts: { - sell?: Portfolio.Token.Amount - buy?: Portfolio.Token.Amount - } - limitPrice?: string - pools: ReadonlyArray - lpTokenHeld?: Portfolio.Token.Amount - slippage: number - side?: 'buy' | 'sell' - frontendFeeTiers: ReadonlyArray - tokens: SwapState['orderData']['tokens'] - priceDecimals?: number -}>): Array => { +}: Swap.MakeOrderCalculation): Array => { if (!amounts.sell || !amounts.buy || !tokens.ptInfo) return [] const isLimit = orderType === 'limit' const maybeLimitPrice = isLimit ? new BigNumber(limitPrice ?? 0) : undefined - const calculations = pools.map((pool) => { + const calculations = pools.map((pool) => { const buy = side === 'sell' ? getBuyAmount( @@ -197,7 +181,7 @@ export const makeOrderCalculations = ({ info: tokens.ptInfo!, } - const result: SwapOrderCalculation = { + const result: Swap.OrderCalculation = { order: { side, slippage, diff --git a/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts b/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts index 4528586e02..7b9312ed39 100644 --- a/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts +++ b/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts @@ -1,5 +1,5 @@ +import {Swap} from '@yoroi/types' import {tokenInfoMocks} from '../../tokenInfo.mocks' -import {SwapOrderCalculation} from '../../types' import {mocks} from '../mocks' import {getBestPoolCalculation} from './getBestPoolCalculation' @@ -13,7 +13,7 @@ describe('getBestPoolCalculation', () => { }) it('should skip no supply pools', () => { - const calculations: ReadonlyArray = [ + const calculations: Array = [ { order: { side: 'buy', diff --git a/packages/swap/src/helpers/pools/getBestPoolCalculation.ts b/packages/swap/src/helpers/pools/getBestPoolCalculation.ts index f069ad3c90..909d14cb99 100644 --- a/packages/swap/src/helpers/pools/getBestPoolCalculation.ts +++ b/packages/swap/src/helpers/pools/getBestPoolCalculation.ts @@ -1,14 +1,14 @@ +import {Swap} from '@yoroi/types' import BigNumber from 'bignumber.js' -import {SwapOrderCalculation} from '../../types' export const getBestPoolCalculation = ( - calculations: ReadonlyArray, -): SwapOrderCalculation | undefined => { + calculations: Array, +): Swap.OrderCalculation | undefined => { return calculations.reduce( ( - best: SwapOrderCalculation | undefined, + best: Swap.OrderCalculation | undefined, current, - ): SwapOrderCalculation | undefined => { + ): Swap.OrderCalculation | undefined => { if (!current.hasSupply) return best if (best === undefined) return current diff --git a/packages/swap/src/index.ts b/packages/swap/src/index.ts index 7d07aaa91b..c66df66340 100644 --- a/packages/swap/src/index.ts +++ b/packages/swap/src/index.ts @@ -45,9 +45,6 @@ export {useSwapTokensOnlyVerified} from './translators/reactjs/hooks/useSwapToke export {useSwap} from './translators/reactjs/hooks/useSwap' export {supportedProviders, milkTokenId} from './translators/constants' -// types -export * from './types' - // factories export {swapApiMaker} from './adapters/api-maker' export {swapManagerMaker} from './manager' diff --git a/packages/swap/src/manager.mocks.ts b/packages/swap/src/manager.mocks.ts index 60f2f3bcc9..ceda6e3202 100644 --- a/packages/swap/src/manager.mocks.ts +++ b/packages/swap/src/manager.mocks.ts @@ -1,6 +1,9 @@ import {Portfolio, Swap} from '@yoroi/types' import {apiMocks} from './adapters/openswap-api/api.mocks' import {tokenInfoMocks} from '@yoroi/portfolio' +import {makeOrderCalculations} from './helpers/orders/factories/makeOrderCalculations' +import {getBestPoolCalculation} from './helpers/pools/getBestPoolCalculation' +import {selectedPoolCalculationSelector} from './translators/reactjs/state/selectors/selectedPoolCalculationSelector' const loading = () => new Promise(() => {}) const unknownError = () => Promise.reject(new Error('Unknown error')) @@ -208,6 +211,9 @@ export const mockSwapManager: Swap.Manager = { primaryTokenInfo: tokenInfoMocks.primaryETH, aggregatorTokenId: undefined, frontendFeeTiers: [] as const, + makeOrderCalculations, + getBestPoolCalculation, + selectedPoolCalculationSelector, } as const export const mockSwapManagerDefault: Swap.Manager = { @@ -241,4 +247,7 @@ export const mockSwapManagerDefault: Swap.Manager = { frontendFeeTiers: [] as const, aggregatorTokenId: undefined, aggregator: 'muesliswap', + makeOrderCalculations, + getBestPoolCalculation, + selectedPoolCalculationSelector, } as const diff --git a/packages/swap/src/manager.ts b/packages/swap/src/manager.ts index 779df62ec2..0153b69cdc 100644 --- a/packages/swap/src/manager.ts +++ b/packages/swap/src/manager.ts @@ -1,4 +1,7 @@ import {App, Portfolio, Swap} from '@yoroi/types' +import {makeOrderCalculations} from './helpers/orders/factories/makeOrderCalculations' +import {getBestPoolCalculation} from './helpers/pools/getBestPoolCalculation' +import {selectedPoolCalculationSelector} from './translators/reactjs/state/selectors/selectedPoolCalculationSelector' export const swapManagerMaker = ({ swapStorage, @@ -67,5 +70,8 @@ export const swapManagerMaker = ({ frontendFeeTiers, aggregator, aggregatorTokenId, + makeOrderCalculations, + getBestPoolCalculation, + selectedPoolCalculationSelector, } as const } diff --git a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts b/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts index b73593c105..8a2b6f3f69 100644 --- a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts +++ b/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts @@ -1,21 +1,18 @@ -import {SwapOrderCalculation} from '../../../../types' -import {SwapState} from '../state' // adjust the import path -import {mockSwapStateDefault} from '../state.mocks' +import {Swap} from '@yoroi/types' import {selectedPoolCalculationSelector} from './selectedPoolCalculationSelector' describe('selectedPoolCalculationSelector', () => { it('should return the best pool from calculations when type is limit and selectedPoolId matches', () => { - const orderData: SwapState['orderData'] = { - ...mockSwapStateDefault.orderData, - type: 'limit', + const orderData = { + type: 'limit' as Swap.OrderType, selectedPoolId: '1', calculations: [ - {pool: {poolId: '1'}} as SwapOrderCalculation, - {pool: {poolId: '2'}} as SwapOrderCalculation, + {pool: {poolId: '1'}} as Swap.OrderCalculation, + {pool: {poolId: '2'}} as Swap.OrderCalculation, ], bestPoolCalculation: { pool: {poolId: '3'}, - } as SwapOrderCalculation, + } as Swap.OrderCalculation, } const selected = selectedPoolCalculationSelector(orderData) @@ -23,15 +20,14 @@ describe('selectedPoolCalculationSelector', () => { }) it('should return the state bestPoolCalculation when no match is found in calculations', () => { - const orderData: SwapState['orderData'] = { - ...mockSwapStateDefault.orderData, - type: 'limit', + const orderData = { + type: 'limit' as Swap.OrderType, selectedPoolId: '3', calculations: [ - {pool: {poolId: '1'}} as SwapOrderCalculation, - {pool: {poolId: '2'}} as SwapOrderCalculation, + {pool: {poolId: '1'}} as Swap.OrderCalculation, + {pool: {poolId: '2'}} as Swap.OrderCalculation, ], - bestPoolCalculation: {pool: {poolId: '3'}} as SwapOrderCalculation, + bestPoolCalculation: {pool: {poolId: '3'}} as Swap.OrderCalculation, } const selected = selectedPoolCalculationSelector(orderData) @@ -39,15 +35,14 @@ describe('selectedPoolCalculationSelector', () => { }) it('should return state bestPool when type is market', () => { - const orderData: SwapState['orderData'] = { - ...mockSwapStateDefault.orderData, - type: 'market', + const orderData = { + type: 'market' as Swap.OrderType, selectedPoolId: '1', calculations: [ - {pool: {poolId: '1'}} as SwapOrderCalculation, - {pool: {poolId: '2'}} as SwapOrderCalculation, + {pool: {poolId: '1'}} as Swap.OrderCalculation, + {pool: {poolId: '2'}} as Swap.OrderCalculation, ], - bestPoolCalculation: {pool: {poolId: '3'}} as SwapOrderCalculation, + bestPoolCalculation: {pool: {poolId: '3'}} as Swap.OrderCalculation, } const selected = selectedPoolCalculationSelector(orderData) @@ -55,15 +50,14 @@ describe('selectedPoolCalculationSelector', () => { }) it('should return the the current bestPoolCalculation when no selectedPoolId', () => { - const orderData: SwapState['orderData'] = { - ...mockSwapStateDefault.orderData, - type: 'limit', + const orderData = { + type: 'limit' as Swap.OrderType, selectedPoolId: undefined, calculations: [ - {pool: {poolId: '1'}} as SwapOrderCalculation, - {pool: {poolId: '2'}} as SwapOrderCalculation, + {pool: {poolId: '1'}} as Swap.OrderCalculation, + {pool: {poolId: '2'}} as Swap.OrderCalculation, ], - bestPoolCalculation: {pool: {poolId: '3'}} as SwapOrderCalculation, + bestPoolCalculation: {pool: {poolId: '3'}} as Swap.OrderCalculation, } const selected = selectedPoolCalculationSelector(orderData) diff --git a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts b/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts index ae32960e71..15f7856ac6 100644 --- a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts +++ b/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts @@ -1,11 +1,17 @@ -import {SwapOrderCalculation} from '../../../../types' -import {SwapState} from '../state' +import {Swap} from '@yoroi/types' -export const selectedPoolCalculationSelector = ( - orderData: SwapState['orderData'], -): SwapOrderCalculation | undefined => { - const {type, selectedPoolId, calculations, bestPoolCalculation} = orderData - let calculation: SwapOrderCalculation | undefined +export const selectedPoolCalculationSelector = ({ + type, + selectedPoolId, + calculations, + bestPoolCalculation, +}: { + type: Swap.OrderType + selectedPoolId?: string + calculations: Array + bestPoolCalculation?: Swap.OrderCalculation +}): Swap.OrderCalculation | undefined => { + let calculation: Swap.OrderCalculation | undefined // can only select a pool if is a limit order type // otherwise will return the current state value for it diff --git a/packages/swap/src/translators/reactjs/state/state.ts b/packages/swap/src/translators/reactjs/state/state.ts index 8d16215ca2..8267d3b93e 100644 --- a/packages/swap/src/translators/reactjs/state/state.ts +++ b/packages/swap/src/translators/reactjs/state/state.ts @@ -4,7 +4,6 @@ import {freeze, produce} from 'immer' import {makeOrderCalculations} from '../../../helpers/orders/factories/makeOrderCalculations' import {selectedPoolCalculationSelector} from './selectors/selectedPoolCalculationSelector' import {getBestPoolCalculation} from '../../../helpers/pools/getBestPoolCalculation' -import {SwapOrderCalculation} from '../../../types' export type SwapState = Readonly<{ orderData: { @@ -19,7 +18,7 @@ export type SwapState = Readonly<{ // when limit can manually select a pool selectedPoolId?: string - selectedPoolCalculation?: SwapOrderCalculation + selectedPoolCalculation?: Swap.OrderCalculation slippage: number @@ -36,8 +35,8 @@ export type SwapState = Readonly<{ pools: ReadonlyArray // derivaded data - calculations: ReadonlyArray - bestPoolCalculation?: SwapOrderCalculation + calculations: ReadonlyArray + bestPoolCalculation?: Swap.OrderCalculation } unsignedTx: any }> @@ -248,7 +247,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.amounts.buy || @@ -279,7 +283,12 @@ const orderReducer = ( draft.orderData.selectedPoolId = action.poolId draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.amounts.sell || @@ -316,7 +325,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) break // when switching and the type is limit can end up with weird amounts @@ -347,7 +361,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.amounts.buy || @@ -396,7 +415,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) draft.orderData.limitPrice = state.orderData.type === 'limit' @@ -428,7 +452,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.amounts.buy || @@ -465,7 +494,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.selectedPoolCalculation || @@ -501,7 +535,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.selectedPoolCalculation || @@ -600,7 +639,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.selectedPoolCalculation || @@ -633,7 +677,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) if ( !draft.orderData.amounts.buy || @@ -666,7 +715,12 @@ const orderReducer = ( draft.orderData.calculations, ) draft.orderData.selectedPoolCalculation = - selectedPoolCalculationSelector(draft.orderData) + selectedPoolCalculationSelector({ + type: draft.orderData.type, + selectedPoolId: draft.orderData.selectedPoolId, + calculations: draft.orderData.calculations, + bestPoolCalculation: draft.orderData.bestPoolCalculation, + }) draft.orderData.limitPrice = undefined draft.orderData.selectedPoolId = undefined diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index e7d72fcf35..9107804cbc 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -259,6 +259,10 @@ import { PortfolioTokenHistory, PortfolioTokenHistoryPeriod, } from './portfolio/history' +import { + SwapMakeOrderCalculation, + SwapOrderCalculation, +} from './swap/calculations' export namespace App { export namespace Errors { @@ -347,6 +351,10 @@ export namespace Swap { export type SupportedProvider = SwapSupportedProvider export type Storage = SwapStorage + + export type MakeOrderCalculation = SwapMakeOrderCalculation + + export type OrderCalculation = SwapOrderCalculation } export namespace Balance { diff --git a/packages/swap/src/types.ts b/packages/types/src/swap/calculations.ts similarity index 66% rename from packages/swap/src/types.ts rename to packages/types/src/swap/calculations.ts index 2f471a3a5a..25513f6708 100644 --- a/packages/swap/src/types.ts +++ b/packages/types/src/swap/calculations.ts @@ -1,4 +1,23 @@ -import {App, Portfolio, Swap} from '@yoroi/types' +import {App, Portfolio, Swap} from '..' + +export type SwapMakeOrderCalculation = Readonly<{ + orderType: Swap.OrderType + amounts: { + sell?: Portfolio.Token.Amount + buy?: Portfolio.Token.Amount + } + limitPrice?: string + pools: ReadonlyArray + lpTokenHeld?: Portfolio.Token.Amount + slippage: number + side?: 'buy' | 'sell' + frontendFeeTiers: ReadonlyArray + tokens: { + ptInfo?: Portfolio.Token.Info + priceDenomination: number + } + priceDecimals?: number +}> export type SwapOrderCalculation = Readonly<{ order: { diff --git a/packages/types/src/swap/manager.ts b/packages/types/src/swap/manager.ts index 85861f1cf3..9d1a41a9b8 100644 --- a/packages/types/src/swap/manager.ts +++ b/packages/types/src/swap/manager.ts @@ -3,6 +3,8 @@ import {PortfolioTokenInfo} from '../portfolio/info' import {PortfolioTokenId} from '../portfolio/token' import {SwapAggregator} from './aggregator' import {SwapApi} from './api' +import {SwapMakeOrderCalculation, SwapOrderCalculation} from './calculations' +import {SwapOrderType} from './order' import {SwapPoolProvider} from './pool' import {SwapStorage} from './storage' @@ -37,4 +39,16 @@ export type SwapManager = Readonly<{ aggregator: SwapAggregator aggregatorTokenId?: PortfolioTokenId frontendFeeTiers: ReadonlyArray + makeOrderCalculations( + args: SwapMakeOrderCalculation, + ): Array + getBestPoolCalculation( + calculations: Array, + ): SwapOrderCalculation | undefined + selectedPoolCalculationSelector(args: { + type: SwapOrderType + selectedPoolId?: string + calculations: Array + bestPoolCalculation?: SwapOrderCalculation + }): SwapOrderCalculation | undefined }>