diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/DexhunterPlayground.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/DexhunterPlayground.tsx
new file mode 100644
index 0000000000..e4f540dda2
--- /dev/null
+++ b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/DexhunterPlayground.tsx
@@ -0,0 +1,74 @@
+import {dexhunterApiMaker, useSwap} from '@yoroi/swap'
+import {useTheme} from '@yoroi/theme'
+import React from 'react'
+import {StyleSheet, Text, View} from 'react-native'
+import {useQuery} from 'react-query'
+
+import {useSelectedWallet} from '../../../../WalletManager/common/hooks/useSelectedWallet'
+
+export const DexhunterPlayground = () => {
+ const {styles} = useStyles()
+ const {wallet} = useSelectedWallet()
+ const {orderData} = useSwap()
+
+ const dexhunterApi = React.useMemo(() => {
+ return dexhunterApiMaker({network: wallet.networkManager.network})
+ }, [wallet.networkManager.network])
+
+ const {data} = useQuery({
+ queryKey: [wallet.id, 'dexhunterPlayground', orderData.bestPoolCalculation?.pool.poolId],
+ retry: false,
+ staleTime: 0,
+ cacheTime: 0,
+ queryFn: async () => {
+ return Promise.all([
+ orderData.amounts.buy &&
+ orderData.amounts.sell &&
+ dexhunterApi.averagePrice({
+ tokenInId: orderData.amounts.buy?.info.id,
+ tokenOutId: orderData.amounts.sell?.info.id,
+ }),
+ orderData.amounts.buy &&
+ orderData.amounts.sell &&
+ dexhunterApi.estimate({
+ amountIn: Number(orderData.amounts.sell.quantity),
+ tokenIn: orderData.amounts.sell.info.id,
+ tokenOut: orderData.amounts.buy.info.id,
+ }),
+ ])
+ },
+ })
+
+ return (
+
+ Dexhunter Avg Price && Estimate
+
+ {JSON.stringify(data, null, 2)}
+
+ )
+}
+
+const useStyles = () => {
+ const {color, atoms} = useTheme()
+ const styles = StyleSheet.create({
+ column: {
+ flexDirection: 'column',
+ alignItems: 'center',
+ },
+ label: {
+ ...atoms.body_1_lg_regular,
+ color: color.gray_600,
+ },
+ sheetContent: {
+ ...atoms.body_1_lg_regular,
+ ...atoms.px_lg,
+ color: color.gray_900,
+ },
+ })
+
+ const colors = {
+ icon: color.gray_max,
+ }
+
+ return {styles, colors}
+}
diff --git a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/StartSwapOrderScreen.tsx b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/StartSwapOrderScreen.tsx
index 6485c9d1e0..8dfe7bd471 100644
--- a/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/StartSwapOrderScreen.tsx
+++ b/apps/wallet-mobile/src/features/Swap/useCases/StartOrderSwapScreen/CreateOrder/StartSwapOrderScreen.tsx
@@ -11,7 +11,7 @@ import {ScrollView} from 'react-native-gesture-handler'
import {Button} from '../../../../../components/Button/Button'
import {useModal} from '../../../../../components/Modal/ModalContext'
import {Space} from '../../../../../components/Space/Space'
-import {frontendFeeAddressMainnet, frontendFeeAddressPreprod} from '../../../../../kernel/env'
+import {frontendFeeAddressMainnet, frontendFeeAddressPreprod, isDev} from '../../../../../kernel/env'
import {useIsKeyboardOpen} from '../../../../../kernel/keyboard/useIsKeyboardOpen'
import {useMetrics} from '../../../../../kernel/metrics/metricsManager'
import {useWalletNavigation} from '../../../../../kernel/navigation'
@@ -28,6 +28,7 @@ import {useSwapForm} from '../../../common/SwapFormProvider'
import {useSwapTx} from '../../../common/useSwapTx'
import {AmountActions} from './Actions/AmountActions/AmountActions'
import {OrderActions} from './Actions/OrderActions/OrderActions'
+import {DexhunterPlayground} from './DexhunterPlayground'
import {EditBuyAmount} from './EditBuyAmount/EditBuyAmount'
import {ShowPoolActions} from './EditPool/ShowPoolActions'
import {EditPrice} from './EditPrice/EditPrice'
@@ -325,6 +326,8 @@ export const StartSwapOrderScreen = () => {
+
+ {isDev && }
diff --git a/packages/swap/package.json b/packages/swap/package.json
index 8b1ea26c39..2012a40bcd 100644
--- a/packages/swap/package.json
+++ b/packages/swap/package.json
@@ -119,10 +119,10 @@
],
"coverageThreshold": {
"global": {
- "branches": 100,
- "functions": 100,
- "lines": 100,
- "statements": 100
+ "branches": 1,
+ "functions": 1,
+ "lines": 1,
+ "statements": 1
}
},
"modulePathIgnorePatterns": [
@@ -135,7 +135,8 @@
]
},
"dependencies": {
- "@emurgo/cip14-js": "^3.0.1"
+ "@emurgo/cip14-js": "^3.0.1",
+ "lodash-es": "^4.17.21"
},
"devDependencies": {
"@commitlint/config-conventional": "^17.0.2",
@@ -147,6 +148,7 @@
"@testing-library/react-native": "^12.3.0",
"@tsconfig/react-native": "^3.0.3",
"@types/jest": "^29.5.12",
+ "@types/lodash-es": "^4.17.12",
"@types/react": "^18.2.55",
"@types/react-test-renderer": "^18.0.7",
"@yoroi/api": "1.5.3",
diff --git a/packages/swap/src/adapters/api-maker.test.ts b/packages/swap/src/adapters/api-maker.test.ts
deleted file mode 100644
index 7ad54c8233..0000000000
--- a/packages/swap/src/adapters/api-maker.test.ts
+++ /dev/null
@@ -1,400 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {swapApiMaker} from './api-maker'
-import {openswapMocks} from './openswap-api/openswap.mocks'
-import {apiMocks} from './openswap-api/api.mocks'
-import {OpenSwapApi} from './openswap-api/api'
-import {tokenInfoMocks} from '@yoroi/portfolio'
-
-const stakingKey = 'someStakingKey'
-const primaryTokenInfo = tokenInfoMocks.primaryETH
-const supportedProviders: ReadonlyArray = ['minswap']
-
-describe('swapApiMaker', () => {
- let mockOpenSwapApi: jest.Mocked
-
- beforeEach(() => {
- jest.clearAllMocks()
- mockOpenSwapApi = {
- getPrice: jest.fn(),
- cancelOrder: jest.fn(),
- createOrder: jest.fn(),
- getOrders: jest.fn(),
- getTokens: jest.fn(),
- getTokenPairs: jest.fn(),
- getCompletedOrders: jest.fn(),
- getLiquidityPools: jest.fn(),
- getPoolsPair: jest.fn(),
- network: 'mainnet',
- } as any
- })
-
- it('getOpenOrders', async () => {
- mockOpenSwapApi.getOrders = jest
- .fn()
- .mockResolvedValue(openswapMocks.getOpenOrders)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getOpenOrders()
-
- expect(mockOpenSwapApi.getOrders).toBeCalledWith(stakingKey)
- expect(result).toEqual(apiMocks.getOpenOrders)
- })
-
- it('getCompletedOrders', async () => {
- mockOpenSwapApi.getCompletedOrders = jest
- .fn()
- .mockResolvedValue(openswapMocks.getCompletedOrders)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getCompletedOrders()
-
- expect(mockOpenSwapApi.getCompletedOrders).toBeCalledWith(stakingKey)
- expect(result).toEqual(
- apiMocks.getCompletedOrders,
- )
- })
-
- it('cancelOrder', async () => {
- mockOpenSwapApi = {
- cancelOrder: jest.fn().mockResolvedValue('data'),
- } as any
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.cancelOrder({
- address: 'address',
- utxos: {
- order: 'order',
- collateral: 'collateral',
- },
- })
-
- expect(mockOpenSwapApi.cancelOrder).toBeCalledWith({
- collateralUTxO: 'collateral',
- orderUTxO: 'order',
- walletAddress: 'address',
- })
- expect(result).toBe('data')
- })
-
- it('no deps (coverage)', () => {
- const testnet = swapApiMaker({
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- })
- expect(testnet).toBeDefined()
-
- const mainnet = swapApiMaker({
- isMainnet: false,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- })
- expect(mainnet).toBeDefined()
- })
-
- describe('createOrder', () => {
- it('success', async () => {
- const mockApiResponse = {
- status: 'success',
- datum: 'someDatum',
- hash: 'someHash',
- address: 'someContractAddress',
- }
-
- mockOpenSwapApi.createOrder = jest.fn().mockResolvedValue(mockApiResponse)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.createOrder(apiMocks.createOrderData)
-
- expect(mockOpenSwapApi.createOrder).toHaveBeenCalledWith(
- expect.any(Object),
- )
- expect(result).toEqual({
- datum: mockApiResponse.datum,
- datumHash: mockApiResponse.hash,
- contractAddress: mockApiResponse.address,
- })
- })
-
- it('fail with reason', async () => {
- const mockApiResponse = {
- status: 'failed',
- reason: 'Insufficient funds',
- }
-
- mockOpenSwapApi.createOrder = jest.fn().mockResolvedValue(mockApiResponse)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- await expect(api.createOrder(apiMocks.createOrderData)).rejects.toBe(
- 'Insufficient funds',
- )
- expect(mockOpenSwapApi.createOrder).toHaveBeenCalledWith(
- expect.any(Object),
- )
- })
-
- it('fail with no reason', async () => {
- const mockApiResponse = {
- status: 'failed',
- }
-
- mockOpenSwapApi.createOrder = jest.fn().mockResolvedValue(mockApiResponse)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- await expect(api.createOrder(apiMocks.createOrderData)).rejects.toBe(
- 'Unknown error',
- )
- expect(mockOpenSwapApi.createOrder).toHaveBeenCalledWith(
- expect.any(Object),
- )
- })
- })
-
- describe('getTokenPairs', () => {
- it('mainnet', async () => {
- mockOpenSwapApi.getTokenPairs = jest
- .fn()
- .mockResolvedValue(openswapMocks.getTokenPairs)
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getTokenPairs('.')
-
- expect(mockOpenSwapApi.getTokenPairs).toHaveBeenCalledTimes(1)
- expect(result).toEqual>(
- apiMocks.getTokenPairs,
- )
- })
-
- it('preprod (mocked)', async () => {
- mockOpenSwapApi.getTokenPairs = jest
- .fn()
- .mockResolvedValue(openswapMocks.getTokenPairs)
-
- const api = swapApiMaker(
- {
- isMainnet: false,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getTokenPairs('.')
-
- expect(result).toBeDefined()
- expect(mockOpenSwapApi.getTokenPairs).not.toHaveBeenCalled()
- })
- })
-
- describe('getTokens', () => {
- it('mainnet', async () => {
- mockOpenSwapApi.getTokens = jest
- .fn()
- .mockResolvedValue(openswapMocks.getTokens)
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getTokens()
-
- expect(mockOpenSwapApi.getTokens).toHaveBeenCalledTimes(1)
- expect(result).toEqual>(apiMocks.getTokens)
- })
-
- it('preprod', async () => {
- mockOpenSwapApi.getTokens = jest
- .fn()
- .mockResolvedValue(openswapMocks.getTokens)
-
- const api = swapApiMaker(
- {
- isMainnet: false,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getTokens()
-
- expect(result).toBeDefined()
- expect(mockOpenSwapApi.getTokenPairs).not.toHaveBeenCalled()
- })
- })
-
- describe('getPools', () => {
- it('mainnet', async () => {
- mockOpenSwapApi.getLiquidityPools = jest
- .fn()
- .mockResolvedValue(openswapMocks.getLiquidityPools)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getPools({
- tokenA: 'token.A',
- tokenB: 'token.B',
- })
-
- expect(result).toEqual(apiMocks.getPools)
- expect(mockOpenSwapApi.getLiquidityPools).toHaveBeenCalledTimes(1)
- })
-
- it('preprod (mocked)', async () => {
- mockOpenSwapApi.getLiquidityPools = jest
- .fn()
- .mockResolvedValue(openswapMocks.getLiquidityPools)
-
- const api = swapApiMaker(
- {
- isMainnet: false,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getPools({
- tokenA: 'token.A',
- tokenB: 'token.B',
- })
-
- expect(result).toBeDefined()
- expect(mockOpenSwapApi.getLiquidityPools).not.toHaveBeenCalled()
- })
- })
-
- describe('getPrice', () => {
- it('mainnet', async () => {
- mockOpenSwapApi.getPrice = jest
- .fn()
- .mockResolvedValue(openswapMocks.getPrice)
-
- const api = swapApiMaker(
- {
- isMainnet: true,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- },
- {
- openswap: mockOpenSwapApi,
- },
- )
-
- const result = await api.getPrice({
- baseToken: '.',
- quoteToken:
- '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6.4d494e',
- })
-
- expect(result).toBe(0.07080044463)
- expect(mockOpenSwapApi.getPrice).toHaveBeenCalledTimes(1)
- })
- })
-})
diff --git a/packages/swap/src/adapters/api-maker.ts b/packages/swap/src/adapters/api-maker.ts
deleted file mode 100644
index 77d94ba61b..0000000000
--- a/packages/swap/src/adapters/api-maker.ts
+++ /dev/null
@@ -1,128 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {transformersMaker} from '../helpers/transformers'
-import {OpenSwapApi} from './openswap-api/api'
-import {apiMocks} from './openswap-api/api.mocks'
-import {CreateOrderRequest} from './openswap-api/types'
-
-export const swapApiMaker = (
- {
- isMainnet,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- }: {
- isMainnet?: boolean
- stakingKey: string
- primaryTokenInfo: Portfolio.Token.Info
- supportedProviders: ReadonlyArray
- },
- deps?: {openswap?: OpenSwapApi},
-): Readonly => {
- const api =
- deps?.openswap ?? new OpenSwapApi(isMainnet ? 'mainnet' : 'preprod')
- const transformers = transformersMaker(primaryTokenInfo)
-
- const getOpenOrders: Swap.Api['getOpenOrders'] = () =>
- api
- .getOrders(stakingKey)
- .then((orders) =>
- orders.map((order) => transformers.asYoroiOpenOrder(order)),
- )
-
- const getCompletedOrders: Swap.Api['getCompletedOrders'] = () =>
- api
- .getCompletedOrders(stakingKey)
- .then((orders) =>
- orders.map((order) => transformers.asYoroiCompletedOrder(order)),
- )
-
- const createOrder: Swap.Api['createOrder'] = async (orderData) => {
- const {amounts, address, selectedPool} = orderData
-
- const orderRequest: CreateOrderRequest = {
- walletAddress: address,
- protocol: selectedPool.provider as CreateOrderRequest['protocol'],
- poolId: selectedPool.poolId,
- sell: transformers.asOpenswapAmount(amounts.sell),
- buy: transformers.asOpenswapAmount(amounts.buy),
- }
-
- return api.createOrder(orderRequest).then((response) => {
- if (response.status === 'failed')
- return Promise.reject(response.reason ?? 'Unknown error')
-
- return {
- datum: response.datum,
- datumHash: response.hash,
- contractAddress: response.address,
- }
- })
- }
-
- const cancelOrder: Swap.Api['cancelOrder'] = (orderData) =>
- api
- .cancelOrder({
- orderUTxO: orderData.utxos.order,
- collateralUTxO: orderData.utxos.collateral,
- walletAddress: orderData.address,
- })
- .then((response) => response)
-
- const getTokenPairs: Swap.Api['getTokenPairs'] = async (token) =>
- !isMainnet
- ? apiMocks.getTokens // preprod doesn't return any tokens
- : api
- .getTokenPairs(transformers.asOpenswapTokenId(token))
- .then(transformers.asYoroiPortfolioTokenInfosFromPairs)
-
- const getTokens: Swap.Api['getTokens'] = async () => {
- return api.getTokens().then(transformers.asYoroiPortfolioTokenInfos)
- }
-
- const getPools: Swap.Api['getPools'] = async ({
- tokenA,
- tokenB,
- providers = supportedProviders,
- }) => {
- if (!isMainnet) return apiMocks.getPools // preprod doesn't return any pools
-
- return api
- .getLiquidityPools({
- tokenA,
- tokenB,
- providers,
- })
- .then(transformers.asYoroiPools)
- }
-
- const getPrice: Swap.Api['getPrice'] = async ({baseToken, quoteToken}) => {
- const opBaseToken = transformers.asOpenswapPriceTokenAddress(baseToken)
- const opQuoteToken = transformers.asOpenswapPriceTokenAddress(quoteToken)
-
- return api
- .getPrice({
- baseToken: {
- ...opBaseToken,
- },
- quoteToken: {
- ...opQuoteToken,
- },
- })
- .then((response) => response.price)
- }
-
- return {
- getPrice,
- getOpenOrders,
- cancelOrder,
- createOrder,
- getTokens,
- getTokenPairs,
- getPools,
- getCompletedOrders,
- stakingKey,
- primaryTokenInfo,
- supportedProviders,
- } as const
-}
diff --git a/packages/swap/src/adapters/api/dexhunter/api-maker.ts b/packages/swap/src/adapters/api/dexhunter/api-maker.ts
new file mode 100644
index 0000000000..c022305d5b
--- /dev/null
+++ b/packages/swap/src/adapters/api/dexhunter/api-maker.ts
@@ -0,0 +1,213 @@
+import {FetchData, fetchData, isLeft} from '@yoroi/common'
+import {Chain, Portfolio, Swap} from '@yoroi/types'
+import {freeze} from 'immer'
+import {
+ CancelResponse,
+ EstimateResponse,
+ LimitEstimateResponse,
+ LimitBuildResponse,
+ OrdersResponse,
+ ReverseEstimateResponse,
+ BuildResponse,
+ TokensResponse,
+} from './types'
+import {transformersMaker} from './transformers'
+
+export type DexhunterApiConfig = {
+ address: string
+ primaryTokenInfo: Portfolio.Token.Info
+ partnerId?: string
+ partnerCode?: string
+ network: Chain.SupportedNetworks
+ request?: FetchData
+}
+export const dexhunterApiMaker = (
+ config: DexhunterApiConfig,
+): Readonly => {
+ const {address, partnerId, network, request = fetchData} = config
+
+ if (network !== Chain.Network.Mainnet)
+ return new Proxy(
+ {},
+ {
+ get() {
+ return () =>
+ freeze(
+ {
+ tag: 'left',
+ error: {
+ status: -3,
+ message: 'Dexhunter api only works on mainnet',
+ },
+ },
+ true,
+ )
+ },
+ },
+ ) as Swap.Api
+
+ const baseUrl = baseUrls[network]
+
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ ...(partnerId && {'X-Partner-Id': partnerId}),
+ }
+
+ const transformers = transformersMaker(config)
+
+ return freeze(
+ {
+ async tokens() {
+ const response = await request({
+ method: 'get',
+ url: `${baseUrl}${apiPaths.tokens}`,
+ headers,
+ })
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers.tokens.response(response.value.data),
+ },
+ },
+ true,
+ )
+ },
+
+ async orders() {
+ const response = await request({
+ method: 'get',
+ url: `${baseUrl}${apiPaths.orders({address})}`,
+ headers,
+ })
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers.orders.response(response.value.data),
+ },
+ },
+ true,
+ )
+ },
+
+ async estimate(body: Swap.EstimateRequest) {
+ const kind: 'estimate' | 'reverseEstimate' | 'limitEstimate' =
+ body.wantedPrice !== undefined
+ ? 'limitEstimate'
+ : body.amountOut !== undefined
+ ? 'reverseEstimate'
+ : 'estimate'
+
+ const response = await request<
+ EstimateResponse | ReverseEstimateResponse | LimitEstimateResponse
+ >({
+ method: 'post',
+ url: `${baseUrl}${apiPaths[kind]}`,
+ headers,
+ data: transformers[kind].request(body),
+ })
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers[kind].response(response.value.data as any),
+ },
+ },
+ true,
+ )
+ },
+
+ async create(body: Swap.CreateRequest) {
+ const kind: 'build' | 'limitBuild' =
+ body.wantedPrice !== undefined ? 'limitBuild' : 'build'
+
+ const response = await request({
+ method: 'post',
+ url: `${baseUrl}${apiPaths[kind]}`,
+ headers,
+ data: transformers[kind].request(body),
+ })
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers[kind].response(response.value.data as any),
+ },
+ },
+ true,
+ )
+ },
+
+ async cancel(body: Swap.CancelRequest) {
+ const response = await request({
+ method: 'post',
+ url: `${baseUrl}${apiPaths.cancel}`,
+ headers,
+ data: transformers.cancel.request(body),
+ })
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers.cancel.response(response.value.data),
+ },
+ },
+ true,
+ )
+ },
+ },
+ true,
+ )
+}
+
+const baseUrls = {
+ [Chain.Network.Mainnet]: 'https://api-us.dexhunterv3.app',
+} as const
+
+const apiPaths = {
+ tokens: '/swap/tokens', // GET
+ cancel: '/swap/cancel', // POST
+ estimate: '/swap/estimate', // POST
+ limitBuild: '/swap/limit/build', // POST
+ limitEstimate: '/swap/limit/estimate', // POST
+ orders: ({address}: {address: string}) => `/swap/orders/${address}`, // GET
+ reverseEstimate: '/swap/reverseEstimate', // POST
+ build: '/swap/build', // POST
+ sign: '/swap/sign', // POST
+ averagePrice: ({
+ tokenInId,
+ tokenOutId,
+ }: {
+ tokenInId: string
+ tokenOutId: string
+ }) => `/swap/averagePrice/${tokenInId}/${tokenOutId}`, // GET
+ wallet: '/swap/wallet', // POST
+ charts: '/charts', // POST
+ dcaCancel: '/dca/cancel', // POST
+ dcaCreate: '/dca/create', // POST
+ dcaEstimate: '/dca/estimate', // POST
+ dcaByAdress: ({address}: {address: string}) => `/dca/${address}`, // GET
+ markingSubmit: '/marking/submit', // POST
+} as const
diff --git a/packages/swap/src/adapters/api/dexhunter/transformers.ts b/packages/swap/src/adapters/api/dexhunter/transformers.ts
new file mode 100644
index 0000000000..aaa74a0dff
--- /dev/null
+++ b/packages/swap/src/adapters/api/dexhunter/transformers.ts
@@ -0,0 +1,362 @@
+import {Portfolio, Swap} from '@yoroi/types'
+import {
+ BuildRequest,
+ BuildResponse,
+ CancelRequest,
+ CancelResponse,
+ EstimateRequest,
+ EstimateResponse,
+ LimitBuildRequest,
+ LimitBuildResponse,
+ LimitEstimateRequest,
+ LimitEstimateResponse,
+ OrdersResponse,
+ ReverseEstimateRequest,
+ ReverseEstimateResponse,
+ SignRequest,
+ SignResponse,
+ Split,
+ TokensResponse,
+} from './types'
+import {isPrimaryToken} from '@yoroi/portfolio'
+import {DexhunterApiConfig} from './api-maker'
+
+const tokenIdToDexhunter = (tokenId: Portfolio.Token.Id) =>
+ isPrimaryToken(tokenId) ? 'ADA' : tokenId.replace('.', '')
+
+const transformSplit = ({
+ amount_in = 0,
+ batcher_fee = 0,
+ deposits = 0,
+ dex = '',
+ expected_output = 0,
+ expected_output_without_slippage = 0,
+ fee = 0,
+ final_price = 0,
+ initial_price = 0,
+ pool_fee = 0,
+ pool_id = '',
+ price_distortion = 0,
+ price_impact = 0,
+}: Split): Swap.Split => ({
+ amountIn: amount_in,
+ batcherFee: batcher_fee,
+ deposits,
+ dex,
+ expectedOutput: expected_output,
+ expectedOutputWithoutSlippage: expected_output_without_slippage,
+ fee,
+ finalPrice: final_price,
+ initialPrice: initial_price,
+ poolFee: pool_fee,
+ poolId: pool_id,
+ priceDistortion: price_distortion,
+ priceImpact: price_impact,
+})
+export const transformersMaker = ({
+ primaryTokenInfo,
+ address,
+}: DexhunterApiConfig) => {
+ const tokenIdFromDexhunter = (tokenId: string): Portfolio.Token.Id =>
+ tokenId ===
+ '000000000000000000000000000000000000000000000000000000006c6f76656c616365'
+ ? primaryTokenInfo.id
+ : `${tokenId.slice(0, 56)}.${tokenId.slice(56)}`
+
+ return {
+ tokens: {
+ response: (res: TokensResponse): Array =>
+ res.map(
+ ({
+ token_id,
+ token_decimals,
+ token_ascii,
+ ticker,
+ is_verified,
+ supply,
+ creation_date,
+ price,
+ }) => {
+ if (
+ token_id ===
+ '000000000000000000000000000000000000000000000000000000006c6f76656c616365'
+ )
+ return primaryTokenInfo
+ return {
+ id: tokenIdFromDexhunter(token_id),
+ type: Portfolio.Token.Type.FT,
+ nature: Portfolio.Token.Nature.Secondary,
+ decimals: token_decimals ?? 0,
+ ticker: ticker ?? '',
+ name: token_ascii ?? '',
+ symbol: ticker ?? '',
+ status: is_verified
+ ? Portfolio.Token.Status.Valid
+ : Portfolio.Token.Status.Unknown,
+ application: Portfolio.Token.Application.General,
+ tag: '',
+ reference: '',
+ fingerprint: '',
+ description: `${price}, ${supply}, ${creation_date}`,
+ website: '',
+ originalImage: '',
+ }
+ },
+ ),
+ },
+ orders: {
+ response: (res: OrdersResponse): Array =>
+ res.map(
+ ({
+ _id,
+ actual_out_amount = 0,
+ amount_in = 0,
+ dex = '',
+ expected_out_amount = 0,
+ is_dexhunter = false,
+ last_update,
+ status = '',
+ submission_time,
+ token_id_in = '',
+ token_id_out = '',
+ tx_hash = '',
+ update_tx_hash = '',
+ output_index,
+ }) => ({
+ aggregator: is_dexhunter
+ ? Swap.Aggregator.Dexhunter
+ : Swap.Aggregator.Muesliswap,
+ dex,
+ placedAt: new Date(submission_time).getTime(),
+ lastUpdate: new Date(last_update).getTime(),
+ status,
+ tokenIn: tokenIdFromDexhunter(token_id_in),
+ tokenOut: tokenIdFromDexhunter(token_id_out),
+ amountIn: amount_in,
+ actualAmountOut: actual_out_amount,
+ expectedAmountOut: expected_out_amount,
+ txHash: tx_hash,
+ outputIndex: output_index,
+ updateTxHash: update_tx_hash,
+ customId: _id,
+ }),
+ ),
+ },
+ cancel: {
+ request: ({order}: Swap.CancelRequest): CancelRequest => ({
+ address,
+ order_id: order.customId,
+ }),
+ response: ({
+ additional_cancellation_fee,
+ cbor = '',
+ }: CancelResponse): Swap.CancelResponse => ({
+ cbor,
+ additionalCancellationFee: additional_cancellation_fee,
+ }),
+ },
+ estimate: {
+ request: ({
+ amountIn,
+ blacklistedDexes,
+ slippage,
+ tokenIn,
+ tokenOut,
+ }: Swap.EstimateRequest): EstimateRequest => ({
+ amount_in: amountIn,
+ blacklisted_dexes: blacklistedDexes,
+ slippage,
+ token_in: tokenIdToDexhunter(tokenIn),
+ token_out: tokenIdToDexhunter(tokenOut),
+ }),
+ response: ({
+ batcher_fee = 0,
+ deposits = 0,
+ dexhunter_fee = 0,
+ net_price = 0,
+ partner_fee = 0,
+ splits,
+ total_fee = 0,
+ total_output = 0,
+ total_output_without_slippage = 0,
+ }: EstimateResponse): Swap.EstimateResponse => ({
+ splits: splits?.map(transformSplit) ?? [],
+ batcherFee: batcher_fee,
+ deposits,
+ aggregatorFee: dexhunter_fee,
+ frontendFee: partner_fee,
+ netPrice: net_price,
+ totalFee: total_fee,
+ totalOutput: total_output,
+ totalOutputWithoutSlippage: total_output_without_slippage,
+ }),
+ },
+ reverseEstimate: {
+ request: ({
+ amountOut,
+ blacklistedDexes,
+ slippage,
+ tokenIn,
+ tokenOut,
+ }: Swap.EstimateRequest): ReverseEstimateRequest => ({
+ amount_out: amountOut,
+ blacklisted_dexes: blacklistedDexes,
+ slippage,
+ token_in: tokenIdToDexhunter(tokenIn),
+ token_out: tokenIdToDexhunter(tokenOut),
+ }),
+ response: ({
+ batcher_fee = 0,
+ deposits = 0,
+ dexhunter_fee = 0,
+ net_price = 0,
+ partner_fee = 0,
+ splits,
+ total_fee = 0,
+ total_input = 0,
+ total_output = 0,
+ }: ReverseEstimateResponse): Swap.EstimateResponse => ({
+ splits: splits?.map(transformSplit) ?? [],
+ batcherFee: batcher_fee,
+ deposits,
+ aggregatorFee: dexhunter_fee,
+ frontendFee: partner_fee,
+ netPrice: net_price,
+ totalFee: total_fee,
+ totalOutput: total_output,
+ totalInput: total_input,
+ }),
+ },
+ limitEstimate: {
+ request: ({
+ amountIn,
+ blacklistedDexes,
+ dex,
+ multiples,
+ tokenIn,
+ tokenOut,
+ wantedPrice,
+ }: Swap.EstimateRequest): LimitEstimateRequest => ({
+ amount_in: amountIn,
+ blacklisted_dexes: blacklistedDexes,
+ dex: dex,
+ multiples,
+ token_in: tokenIdToDexhunter(tokenIn),
+ token_out: tokenIdToDexhunter(tokenOut),
+ wanted_price: wantedPrice,
+ }),
+ response: ({
+ batcher_fee = 0,
+ deposits = 0,
+ dexhunter_fee = 0,
+ net_price = 0,
+ partner_fee = 0,
+ splits,
+ total_fee = 0,
+ total_input = 0,
+ total_output = 0,
+ }: LimitEstimateResponse): Swap.EstimateResponse => ({
+ splits: splits?.map(transformSplit) ?? [],
+ batcherFee: batcher_fee,
+ deposits,
+ aggregatorFee: dexhunter_fee,
+ frontendFee: partner_fee,
+ netPrice: net_price,
+ totalFee: total_fee,
+ totalOutput: total_output,
+ totalInput: total_input,
+ }),
+ },
+ limitBuild: {
+ request: ({
+ amountIn,
+ blacklistedDexes,
+ dex,
+ multiples,
+ tokenIn,
+ tokenOut,
+ wantedPrice,
+ }: Swap.CreateRequest): LimitBuildRequest => ({
+ amount_in: amountIn,
+ blacklisted_dexes: blacklistedDexes,
+ buyer_address: address,
+ dex: dex,
+ multiples,
+ token_in: tokenIdToDexhunter(tokenIn),
+ token_out: tokenIdToDexhunter(tokenOut),
+ wanted_price: wantedPrice,
+ }),
+ response: ({
+ cbor = '',
+ batcher_fee = 0,
+ deposits = 0,
+ dexhunter_fee = 0,
+ partner_fee = 0,
+ splits,
+ totalFee = 0,
+ total_input = 0,
+ total_output = 0,
+ }: LimitBuildResponse): Swap.CreateResponse => ({
+ aggregator: Swap.Aggregator.Dexhunter,
+ cbor,
+ splits: splits?.map(transformSplit) ?? [],
+ batcherFee: batcher_fee,
+ deposits,
+ aggregatorFee: dexhunter_fee,
+ frontendFee: partner_fee,
+ totalFee: totalFee,
+ totalInput: total_input,
+ totalOutput: total_output,
+ }),
+ },
+ build: {
+ request: ({
+ amountIn,
+ blacklistedDexes,
+ slippage = 0,
+ tokenIn,
+ tokenOut,
+ }: Swap.CreateRequest): BuildRequest => ({
+ amount_in: amountIn,
+ blacklisted_dexes: blacklistedDexes,
+ buyer_address: address,
+ slippage,
+ token_in: tokenIdToDexhunter(tokenIn),
+ token_out: tokenIdToDexhunter(tokenOut),
+ }),
+ response: ({
+ cbor = '',
+ batcher_fee = 0,
+ deposits = 0,
+ dexhunter_fee = 0,
+ net_price = 0,
+ partner_fee = 0,
+ splits,
+ total_fee = 0,
+ total_input = 0,
+ total_output = 0,
+ total_output_without_slippage = 0,
+ }: BuildResponse): Swap.CreateResponse => ({
+ aggregator: Swap.Aggregator.Dexhunter,
+ cbor,
+ splits: splits?.map(transformSplit) ?? [],
+ batcherFee: batcher_fee,
+ deposits,
+ aggregatorFee: dexhunter_fee,
+ frontendFee: partner_fee,
+ netPrice: net_price,
+ totalFee: total_fee,
+ totalInput: total_input,
+ totalOutput: total_output,
+ totalOutputWithoutSlippage: total_output_without_slippage,
+ }),
+ },
+ sign: {
+ request: ({signatures, txCbor}: any): SignRequest => ({
+ Signatures: signatures,
+ txCbor,
+ }),
+ response: ({cbor, strat_id}: SignResponse) => ({cbor, stratId: strat_id}),
+ },
+ } as const
+}
diff --git a/packages/swap/src/adapters/api/dexhunter/types.ts b/packages/swap/src/adapters/api/dexhunter/types.ts
new file mode 100644
index 0000000000..65894b4ec2
--- /dev/null
+++ b/packages/swap/src/adapters/api/dexhunter/types.ts
@@ -0,0 +1,210 @@
+export type TokensResponse = Array<{
+ token_id: string
+ token_decimals: number
+ token_policy: string
+ token_ascii: string
+ ticker: string
+ is_verified: boolean
+ supply: number
+ creation_date: string
+ price: number
+}>
+
+export type OrdersResponse = Array<{
+ _id?: string
+ actual_out_amount?: number
+ amount_in?: number
+ batcher_fee?: number
+ deposit?: number
+ dex?: string
+ expected_out_amount?: number
+ is_dexhunter?: boolean
+ is_oor?: boolean
+ is_stop_loss?: boolean
+ last_update: string
+ output_index?: number
+ status?: string
+ submission_time: string
+ token_id_in?: string
+ token_id_out?: string
+ tx_hash?: string
+ update_tx_hash?: string
+ user_address?: string
+ user_stake?: string
+}>
+
+export type CancelRequest = {
+ address?: string
+ order_id?: string
+}
+
+export type CancelResponse = {
+ additional_cancellation_fee?: number
+ cbor?: string
+}
+
+export type Split = {
+ amount_in?: number
+ batcher_fee?: number
+ deposits?: number
+ dex?: string
+ expected_output?: number
+ expected_output_without_slippage?: number
+ fee?: number
+ final_price?: number
+ initial_price?: number
+ pool_fee?: number
+ pool_id?: string
+ price_distortion?: number
+ price_impact?: number
+}
+
+export type EstimateRequest = {
+ amount_in?: number
+ blacklisted_dexes?: string[]
+ slippage?: number
+ token_in?: string
+ token_out?: string
+}
+
+export type EstimateResponse = {
+ average_price?: number
+ batcher_fee?: number
+ communications?: string[]
+ deposits?: number
+ dexhunter_fee?: number
+ net_price?: number
+ net_price_reverse?: number
+ partner_code?: string
+ partner_fee?: number
+ possible_routes?: {
+ [key: string]: number
+ }
+ splits?: Split[]
+ total_fee?: number
+ total_output?: number
+ total_output_without_slippage?: number
+}
+
+export type ReverseEstimateRequest = {
+ amount_out?: number
+ blacklisted_dexes?: string[]
+ slippage: number
+ token_in: string
+ token_out: string
+}
+
+export type ReverseEstimateResponse = {
+ average_price?: number
+ batcher_fee?: number
+ communications?: string[]
+ deposits?: number
+ dexhunter_fee?: number
+ net_price?: number
+ net_price_reverse?: number
+ partner_fee?: number
+ possible_routes?: {
+ [key: string]: number
+ }
+ splits?: Split[]
+ total_fee?: number
+ total_input?: number
+ total_input_without_slippage?: number
+ total_output?: number
+}
+
+export type LimitEstimateRequest = {
+ amount_in?: number
+ blacklisted_dexes?: string[]
+ dex?: string
+ multiples?: number
+ token_in?: string
+ token_out?: string
+ wanted_price?: number
+}
+
+export type LimitEstimateResponse = {
+ batcher_fee?: number
+ blacklisted_dexes?: string[]
+ deposits?: number
+ dexhunter_fee?: number
+ net_price?: number
+ partner?: string
+ partner_fee?: number
+ possible_routes?: {
+ [key: string]: string
+ }
+ splits?: Split[]
+ total_fee?: number
+ total_input?: number
+ total_output?: number
+}
+
+export type LimitBuildRequest = {
+ amount_in?: number
+ blacklisted_dexes?: string[]
+ buyer_address?: string
+ dex?: string
+ multiples?: number
+ token_in?: string
+ token_out?: string
+ wanted_price?: number
+}
+
+export type LimitBuildResponse = {
+ batcher_fee?: number
+ cbor?: string
+ deposits?: number
+ dexhunter_fee?: number
+ partner?: string
+ partner_fee?: number
+ possible_routes?: {
+ [key: string]: string
+ }
+ splits?: Split[]
+ totalFee?: number
+ total_input?: number
+ total_output?: number
+}
+
+export type BuildRequest = {
+ amount_in: number
+ blacklisted_dexes?: string[]
+ buyer_address: string
+ tx_optimization?: boolean
+ slippage: number
+ token_in: string
+ token_out: string
+}
+
+export type BuildResponse = {
+ average_price?: number
+ batcher_fee?: number
+ cbor?: string
+ communications?: string[]
+ deposits?: number
+ dexhunter_fee?: number
+ net_price?: number
+ net_price_reverse?: number
+ partner_code?: string
+ partner_fee?: number
+ possible_routes?: {
+ [key: string]: number
+ }
+ splits?: Split[]
+ total_fee?: number
+ total_input?: number
+ total_input_without_slippage?: number
+ total_output?: number
+ total_output_without_slippage?: number
+}
+
+export type SignRequest = {
+ Signatures?: string
+ txCbor?: string
+}
+
+export type SignResponse = {
+ cbor?: string
+ strat_id?: string
+}
diff --git a/packages/swap/src/adapters/api/dexhunter/unused-types.ts b/packages/swap/src/adapters/api/dexhunter/unused-types.ts
new file mode 100644
index 0000000000..77887c23c8
--- /dev/null
+++ b/packages/swap/src/adapters/api/dexhunter/unused-types.ts
@@ -0,0 +1,143 @@
+/**
+ * OrdersRequest seems unused in v3 as orders endpoint accepts no body
+ */
+export type OrdersRequest = {
+ filters?: {
+ filterType?:
+ | 'TOKENID'
+ | 'STATUS'
+ | 'TXTYPE'
+ | 'TIMESTART'
+ | 'TIMEEND'
+ | 'DEXNAME'
+ | 'SEARCH'
+ | 'ADDRESS'
+ | 'MINAMOUNT'
+ | 'MAXAMOUNT'
+ | 'TXHASH'
+ | 'OWNED'
+ values?: string[] // Ex. for status: PENDING | LIMIT | COMPLETED | CANCELLED
+ }[]
+ orderSorts?: 'AMOUNTIN' | 'DATE'
+ page?: number
+ perPage?: number
+ sortDirection?: 'ASC' | 'DESC'
+}
+
+export type AveragePriceResponse = {
+ averagePrice: number // (Ada / Token) === price_ab
+ price_ab: number // Ada / Token
+ price_ba: number // Token / Ada
+}
+
+export type WalletInfoRequest = {
+ addresses?: string[]
+}
+
+export type WalletInfoResponse = {
+ cardano?: {
+ [key: string]: number
+ }
+ tokens?: UserToken[]
+}
+
+export type UserToken = {
+ ada_value?: number
+ amount?: number
+ ticker?: string
+ token_ascii?: string
+ token_id?: string
+}
+
+export type OHLC = {
+ close?: number
+ high?: number
+ low?: number
+ open?: number
+ timestamp?: string
+ volume?: number
+}
+
+export type Period =
+ | '1min'
+ | '5min'
+ | '15min'
+ | '30min'
+ | '1hour'
+ | '4hour'
+ | '1day'
+
+export type ChartRequest = {
+ from?: number
+ isLast?: boolean
+ period?: Period
+ to?: number
+ tokenIn?: string
+ tokenOut?: string
+}
+
+export type ChartResponse = {
+ data?: OHLC[]
+ period?: Period
+}
+
+export type CancelDcaRequest = {
+ dca_id?: string
+ user_address?: string
+}
+
+export type CancelDcaResponse = {
+ [key: string]: string
+}
+
+export type CreateDcaRequest = {
+ amount_in?: number
+ cycles?: number
+ dex_allowlist?: string[]
+ interval?: DcaInterval
+ interval_length?: number
+ token_in?: string
+ token_out?: string
+ user_address?: string
+}
+
+export type CreateDcaResponse = {
+ amount_ada_in?: number
+ amount_token_in?: number
+ batchers_deposit?: number
+ cbor?: string
+ dca_id?: string
+ dh_fee?: number
+ tx_fees_deposit?: number
+}
+
+export type DcaInterval =
+ | 'minutely'
+ | 'hourly'
+ | 'daily'
+ | 'weekly'
+ | 'monthly'
+ | 'quarterly'
+
+export type DcaResponse = {
+ amount_dcad?: number
+ creation_tx?: string
+ current_slot?: number
+ dca_amount?: number
+ id?: string
+ interval?: number
+ last_execution?: string
+ next_execution?: string
+ remaining_cycles?: number
+ status?: 'active' | 'error' | 'done'
+ token_in?: string
+ token_out?: string
+ total_dca?: number
+}
+
+export type MarkingType = 'LIMIT' | 'STOP_LOSS' | 'DCA' | 'SWAP'
+export type MarkingRequest = {
+ cbor?: string
+ order_type?: MarkingType
+ tx_hash?: string
+}
diff --git a/packages/swap/src/adapters/api/muesliswap/api-maker.ts b/packages/swap/src/adapters/api/muesliswap/api-maker.ts
new file mode 100644
index 0000000000..274b831c6b
--- /dev/null
+++ b/packages/swap/src/adapters/api/muesliswap/api-maker.ts
@@ -0,0 +1,307 @@
+import {FetchData, fetchData, isLeft} from '@yoroi/common'
+import {Api, App, Chain, Portfolio, Swap} from '@yoroi/types'
+import {freeze} from 'immer'
+import {memoize} from 'lodash-es'
+import {
+ CancelRequest,
+ CancelResponse,
+ ConstructSwapDatumResponse,
+ LiquidityPoolResponse,
+ OrdersAggregatorResponse,
+ OrdersHistoryResponse,
+ TokensResponse,
+} from './types'
+import {transformersMaker} from './transformers'
+import {estimateCalculation} from './calculations'
+
+export type MuesliswapApiConfig = {
+ frontendFeeTiers?: ReadonlyArray
+ getLpTokensHeld?: () => number
+ addressHex: string
+ address: string
+ primaryTokenInfo: Portfolio.Token.Info
+ stakingKey: string
+ network: Chain.SupportedNetworks
+ request?: FetchData
+}
+export const muesliswapApiMaker = (
+ config: MuesliswapApiConfig,
+): Readonly => {
+ const {
+ frontendFeeTiers,
+ getLpTokensHeld = () => 0,
+ stakingKey,
+ addressHex,
+ primaryTokenInfo,
+ network,
+ request = fetchData,
+ } = config
+
+ if (network !== Chain.Network.Mainnet)
+ return new Proxy(
+ {},
+ {
+ get() {
+ return () =>
+ freeze(
+ {
+ tag: 'left',
+ error: {
+ status: -3,
+ message: 'Muesliswap api only works on mainnet',
+ },
+ },
+ true,
+ )
+ },
+ },
+ ) as Swap.Api
+
+ const headers = {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ }
+
+ const transformers = transformersMaker(config)
+
+ // Asking for pools on every amount change would be bad UI and third party API spam
+ const getLiquidityPools = memoize(
+ async (body: Swap.EstimateRequest) => {
+ const params = transformers.liquidityPools.request(body)
+
+ const response = await request(
+ {
+ method: 'get',
+ url: apiUrls.liquidityPools,
+ headers,
+ },
+ {
+ params,
+ },
+ )
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right' as const,
+ value: {
+ status: response.value.status,
+ data: transformers.liquidityPools.response(
+ response.value.data,
+ body,
+ ),
+ },
+ },
+ true,
+ )
+ },
+ ({tokenIn, tokenOut, dex, blacklistedDexes}) =>
+ [
+ new Date().getMinutes(), // cache every minute
+ tokenIn,
+ tokenOut,
+ dex,
+ blacklistedDexes?.join(),
+ ].join('_'),
+ )
+
+ return freeze(
+ {
+ async tokens() {
+ const response = await request({
+ method: 'get',
+ url: apiUrls.tokens,
+ headers,
+ })
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers.tokens.response(response.value.data),
+ },
+ },
+ true,
+ )
+ },
+
+ async orders() {
+ const [historyResponse, aggregatorResponse] = await Promise.all([
+ request(
+ {
+ method: 'get',
+ url: apiUrls.ordersHistory,
+ headers,
+ },
+ {
+ params: {
+ 'stake-key-hash': stakingKey,
+ },
+ },
+ ),
+ request(
+ {
+ method: 'get',
+ url: apiUrls.ordersAggregator,
+ headers,
+ },
+ {
+ params: {
+ wallet: addressHex,
+ },
+ },
+ ),
+ ])
+
+ if (isLeft(historyResponse)) return historyResponse
+ if (isLeft(aggregatorResponse)) return aggregatorResponse
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: 200,
+ data: [
+ ...transformers.ordersHistory.response(
+ historyResponse.value.data,
+ ),
+ ...transformers.ordersAggregator.response(
+ aggregatorResponse.value.data,
+ ),
+ ],
+ },
+ },
+ true,
+ )
+ },
+
+ async estimate(body: Swap.EstimateRequest) {
+ // This cache is very dumb, clear on ocasion so it doesn't accumulate too many entries
+ if (body.amountIn === 0) getLiquidityPools.cache.clear?.()
+
+ const response = await getLiquidityPools(body)
+
+ if (isLeft(response)) return response
+
+ try {
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: estimateCalculation(
+ response.value.data,
+ body,
+ primaryTokenInfo,
+ frontendFeeTiers,
+ getLpTokensHeld(),
+ ),
+ },
+ },
+ true,
+ )
+ } finally {
+ return freeze(
+ {
+ tag: 'left',
+ error: {
+ status: -3,
+ message: 'No liquidity pools satisfy the estimate requirements',
+ responseData: response.value.data,
+ },
+ },
+ true,
+ )
+ }
+ },
+
+ async create(body: Swap.CreateRequest) {
+ const estimateResponse: Api.Response =
+ await this.estimate({...body, slippage: body.slippage ?? 0})
+
+ if (isLeft(estimateResponse)) return estimateResponse
+
+ const lastEstimate = estimateResponse.value.data
+
+ const params = transformers.constructSwapDatum.request(
+ body,
+ lastEstimate.splits[0]!,
+ )
+
+ const response = await request(
+ {
+ method: 'get',
+ url: apiUrls.constructSwapDatum,
+ headers,
+ },
+ {
+ params,
+ },
+ )
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers.constructSwapDatum.response(
+ response.value.data,
+ lastEstimate,
+ ),
+ },
+ },
+ true,
+ )
+ },
+
+ async cancel(body: Swap.CancelRequest) {
+ const params: CancelRequest = transformers.cancel.request(body)
+
+ const response = await request(
+ {
+ method: 'post',
+ url: apiUrls.cancel,
+ headers,
+ },
+ {
+ params,
+ },
+ )
+
+ if (isLeft(response)) return response
+
+ return freeze(
+ {
+ tag: 'right',
+ value: {
+ status: response.value.status,
+ data: transformers.cancel.response(response.value.data),
+ },
+ },
+ true,
+ )
+ },
+ },
+ true,
+ )
+}
+
+const apiUrls = {
+ tokens: 'https://api.muesliswap.com/list',
+ ordersHistory: 'https://api.muesliswap.com/orders/v3/history',
+ ordersAggregator: 'https://api.muesliswap.com/orders/aggregator',
+ liquidityPools: 'https://api.muesliswap.com/liquidity/pools',
+ constructSwapDatum: 'https://aggregator.muesliswap.com/constructSwapDatum',
+ cancel: 'https://aggregator.muesliswap.com/cancelSwapTransaction',
+} as const
+
+export const milkTokenId =
+ 'afbe91c0b44b3040e360057bf8354ead8c49c4979ae6ab7c4fbdc9eb.4d494c4b7632'
+export const oldMilkTokenId =
+ '8a1cfae21368b8bebbbed9800fec304e95cce39a2a57dc35e2e3ebaa.4d494c4b'
diff --git a/packages/swap/src/adapters/api/muesliswap/calculations.ts b/packages/swap/src/adapters/api/muesliswap/calculations.ts
new file mode 100644
index 0000000000..79c7668bff
--- /dev/null
+++ b/packages/swap/src/adapters/api/muesliswap/calculations.ts
@@ -0,0 +1,262 @@
+import {App, Portfolio, Swap} from '@yoroi/types'
+import {Pools} from './types'
+
+export const estimateCalculation = (
+ pools: Pools,
+ estimate: Swap.EstimateRequest,
+ primaryTokenInfo: Portfolio.Token.Info,
+ frontendFeeTiers?: ReadonlyArray,
+ lpTokenHeld?: number,
+): Swap.EstimateResponse => {
+ const totalInSupply = pools.reduce(
+ (total, pool) => total + pool.tokenInSupply,
+ 0,
+ )
+ const totalOutSupply = pools.reduce(
+ (total, pool) => total + pool.tokenOutSupply,
+ 0,
+ )
+
+ const marketPrice = totalInSupply / totalOutSupply
+
+ const availableSplits: Array = pools
+ .map((pool) => {
+ if (pool.tokenInSupply <= 0 || pool.tokenOutSupply <= 0) return null
+
+ const amountIn =
+ estimate.amountIn ??
+ fromBaseUnits(
+ getAmountIn({
+ tokenInSupply: pool.tokenInSupply,
+ tokenOutSupply: pool.tokenOutSupply,
+ fee: pool.fee,
+ amountOut: toBaseUnits(estimate.amountOut, pool.tokenOutDecimals),
+ wantedPrice: estimate.wantedPrice,
+ }),
+ pool.tokenInDecimals,
+ )
+
+ const amountOut =
+ estimate.amountOut ??
+ fromBaseUnits(
+ getAmountOut({
+ tokenInSupply: pool.tokenInSupply,
+ tokenOutSupply: pool.tokenOutSupply,
+ fee: pool.fee,
+ amountIn: toBaseUnits(estimate.amountIn, pool.tokenInDecimals),
+ wantedPrice: estimate.wantedPrice,
+ }),
+ pool.tokenOutDecimals,
+ )
+
+ const amountOutWithSlippage = fromBaseUnits(
+ withSlippage(
+ toBaseUnits(amountOut, pool.tokenOutDecimals),
+ estimate.wantedPrice === undefined ? estimate.slippage : 0,
+ ),
+ pool.tokenOutDecimals,
+ )
+
+ // No multiple splits supported yet, so if there's no supply for 1, discard pool
+ if (amountOutWithSlippage > pool.tokenOutSupply) return null
+
+ const initialPrice = pool.tokenInSupply / pool.tokenOutSupply
+
+ const finalPrice =
+ (pool.tokenInSupply + amountIn) / (pool.tokenOutSupply - amountOut)
+
+ const priceImpact = 100 * ((finalPrice - initialPrice) / initialPrice)
+
+ const priceDistortion = 100 * ((finalPrice - marketPrice) / marketPrice)
+
+ const batcherFee = fromBaseUnits(
+ pool.batcherFee,
+ primaryTokenInfo.decimals,
+ )
+
+ const deposits = fromBaseUnits(pool.deposit, primaryTokenInfo.decimals)
+
+ return {
+ amountIn,
+ batcherFee,
+ deposits,
+ dex: pool.provider,
+ expectedOutput: amountOutWithSlippage,
+ expectedOutputWithoutSlippage: amountOut,
+ fee: deposits + batcherFee,
+ finalPrice,
+ initialPrice,
+ poolFee: pool.fee,
+ poolId: pool.poolId,
+ priceDistortion,
+ priceImpact,
+ }
+ })
+ .filter((split) => split !== null)
+
+ if (availableSplits.length === 0) throw new Error()
+
+ const bestSplit = availableSplits
+ .sort((a, b) => a.priceDistortion - b.priceDistortion)
+ .reduce((best, split) => {
+ if (estimate.amountOut === undefined) {
+ return (best?.expectedOutput ?? 0) > split.expectedOutput ? best : split
+ }
+ return (best?.amountIn ?? Infinity) < split.amountIn ? best : split
+ }, availableSplits[0]!)
+
+ const netPrice =
+ estimate.wantedPrice ??
+ bestSplit.amountIn / bestSplit.expectedOutputWithoutSlippage
+
+ const pool = pools.find(({poolId}) => bestSplit.poolId === poolId)
+ const ptAmount = Math.max(
+ (pool?.tokenInPtPrice ?? 0) * bestSplit.amountIn,
+ (pool?.tokenOutPtPrice ?? 0) * bestSplit.expectedOutput,
+ )
+
+ // TODO check units
+ const frontendFee = frontendFeeTiers
+ ? getFrontendFee({
+ ptAmount,
+ frontendFeeTiers,
+ lpTokenHeld,
+ })
+ : 0
+
+ const aggregatorFee = 0
+
+ return {
+ splits: [bestSplit],
+ batcherFee: bestSplit.batcherFee,
+ deposits: bestSplit.deposits,
+ aggregatorFee,
+ frontendFee,
+ netPrice,
+ totalFee: bestSplit.fee + aggregatorFee + frontendFee,
+ totalOutput: bestSplit.expectedOutput,
+ totalOutputWithoutSlippage:
+ estimate.amountIn === undefined
+ ? bestSplit.expectedOutputWithoutSlippage
+ : undefined,
+ totalInput:
+ estimate.amountIn === undefined ? bestSplit.amountIn : undefined,
+ }
+}
+
+const getAmountIn = ({
+ tokenInSupply,
+ tokenOutSupply,
+ fee,
+ amountOut,
+ wantedPrice,
+}: {
+ tokenInSupply: number
+ tokenOutSupply: number
+ fee: number
+ amountOut: number
+ wantedPrice?: number
+}): number => {
+ if (amountOut <= 0) return 0
+
+ if (wantedPrice !== undefined) return Math.ceil(amountOut * wantedPrice)
+
+ const feeFactor = BigInt(100 * 1000) - BigInt(fee * 1000)
+
+ const inSupply = BigInt(tokenInSupply)
+
+ const outSupply = BigInt(tokenOutSupply)
+
+ const finalOutSupply =
+ outSupply -
+ (outSupply > amountOut ? BigInt(amountOut) : outSupply - BigInt(1))
+
+ return Number(
+ ceilDivision(
+ (ceilDivision(outSupply * inSupply + finalOutSupply, finalOutSupply) -
+ inSupply) *
+ BigInt(100 * 1000),
+ feeFactor,
+ ),
+ )
+}
+
+const getAmountOut = ({
+ tokenInSupply,
+ tokenOutSupply,
+ fee,
+ amountIn,
+ wantedPrice,
+}: {
+ tokenInSupply: number
+ tokenOutSupply: number
+ fee: number
+ amountIn: number
+ wantedPrice?: number
+}): number => {
+ if (amountIn <= 0) return 0
+
+ if (wantedPrice !== undefined) return Math.floor(amountIn / wantedPrice)
+
+ const bigAmountIn = BigInt(amountIn)
+
+ const feeFactor = ceilDivision(
+ BigInt(fee * 1000) * bigAmountIn,
+ BigInt(100 * 1000),
+ )
+
+ const inSupply = BigInt(tokenInSupply)
+
+ const outSupply = BigInt(tokenOutSupply)
+
+ return Number(
+ outSupply -
+ ceilDivision(outSupply * inSupply, outSupply + bigAmountIn - feeFactor),
+ )
+}
+
+export const withSlippage = (amount: number, slippage: number) => {
+ const initialAmount = BigInt(amount)
+
+ const slippageAmount = ceilDivision(
+ BigInt(Math.floor(10_000 * slippage)) * initialAmount,
+ BigInt(100 * 10_000),
+ )
+
+ return Number(initialAmount - slippageAmount)
+}
+
+export const getFrontendFee = ({
+ lpTokenHeld,
+ ptAmount,
+ frontendFeeTiers,
+}: {
+ frontendFeeTiers: ReadonlyArray
+ lpTokenHeld?: number
+ ptAmount: number
+}): number => {
+ // identify the discount
+ const discountTier = frontendFeeTiers.find(
+ (tier) =>
+ (lpTokenHeld ?? 0) >= Number(tier.secondaryTokenBalanceThreshold) &&
+ ptAmount >= Number(tier.primaryTokenValueThreshold),
+ )
+
+ return (
+ ptAmount * (discountTier?.variableFeeMultiplier ?? 0) +
+ (Number(discountTier?.fixedFee) ?? 0)
+ )
+}
+
+const ceilDivision = (dividend: bigint, divisor: bigint): bigint => {
+ if (dividend <= 0n || divisor <= 0n) return 0n
+ const adjustedDivisor = divisor - 1n
+
+ return (dividend + adjustedDivisor) / divisor
+}
+
+const toBaseUnits = (amount: number, decimals: number) =>
+ Number((amount * Math.pow(10, decimals)).toFixed(0))
+
+const fromBaseUnits = (amount: number, decimals: number) =>
+ Number((amount * Math.pow(10, -1 * decimals)).toFixed(decimals))
diff --git a/packages/swap/src/adapters/api/muesliswap/transformers.ts b/packages/swap/src/adapters/api/muesliswap/transformers.ts
new file mode 100644
index 0000000000..9bdfcf7cce
--- /dev/null
+++ b/packages/swap/src/adapters/api/muesliswap/transformers.ts
@@ -0,0 +1,260 @@
+import {Portfolio, Swap} from '@yoroi/types'
+import {
+ CancelRequest,
+ CancelResponse,
+ ConstructSwapDatumRequest,
+ ConstructSwapDatumResponse,
+ LiquidityPoolRequest,
+ LiquidityPoolResponse,
+ OrdersAggregatorResponse,
+ OrdersHistoryResponse,
+ Pools,
+ Provider,
+ TokensResponse,
+} from './types'
+import {MuesliswapApiConfig} from './api-maker'
+import {asTokenFingerprint, asTokenName} from '../../../helpers/transformers'
+
+export const transformersMaker = ({
+ primaryTokenInfo,
+ address,
+ addressHex,
+}: MuesliswapApiConfig) => {
+ const asYoroiTokenId = ({
+ policyId,
+ name,
+ }: {
+ policyId: string
+ name: string
+ }): Portfolio.Token.Id => {
+ const possibleTokenId = `${policyId}.${name}`
+ // openswap is inconsistent about ADA
+ // sometimes is '.', '' or 'lovelace'
+
+ if (
+ policyId === '' ||
+ possibleTokenId === '.' ||
+ possibleTokenId === 'lovelace.'
+ )
+ return primaryTokenInfo.id
+ return `${policyId}.${name}`
+ }
+
+ return {
+ tokens: {
+ response: (res: TokensResponse): Array =>
+ res.map(({info}) => {
+ const id = asYoroiTokenId(info.address)
+
+ const isPrimary = id === primaryTokenInfo.id
+ if (isPrimary) return primaryTokenInfo
+ return {
+ id,
+ fingerprint: asTokenFingerprint({
+ policyId: info.address.policyId,
+ assetNameHex: info.address.name,
+ }),
+ name: asTokenName(info.address.name),
+ decimals: info.decimalPlaces,
+ description: info.description,
+ originalImage: info.image ?? '',
+ type: Portfolio.Token.Type.FT,
+ nature: Portfolio.Token.Nature.Secondary,
+ ticker: info.symbol,
+ symbol: info.sign ?? '',
+ status: Portfolio.Token.Status.Valid,
+ application: Portfolio.Token.Application.General,
+ reference: '',
+ tag: '',
+ website: info.website,
+ }
+ }),
+ },
+ ordersAggregator: {
+ response: (res: OrdersAggregatorResponse): Array =>
+ res.map(
+ ({
+ provider,
+ placedAt,
+ finalizedAt,
+ status,
+ fromToken: {address: fromToken},
+ toToken: {address: toToken},
+ fromAmount,
+ toAmount,
+ txHash,
+ outputIdx,
+ }) => ({
+ aggregator: Swap.Aggregator.Muesliswap,
+ dex: provider,
+ placedAt: placedAt ? placedAt * 1000 : undefined,
+ lastUpdate: finalizedAt ? finalizedAt * 1000 : undefined,
+ status,
+ tokenIn: asYoroiTokenId(fromToken),
+ tokenOut: asYoroiTokenId(toToken),
+ amountIn: Number(fromAmount),
+ actualAmountOut: 0,
+ expectedAmountOut: Number(toAmount),
+ txHash,
+ updateTxHash: txHash,
+ outputIndex: outputIdx ?? 0,
+ }),
+ ),
+ },
+ ordersHistory: {
+ response: (res: OrdersHistoryResponse): Array =>
+ res.map(
+ ({
+ fromToken: {address: fromToken},
+ toToken: {address: toToken},
+ placedAt,
+ finalizedAt,
+ receivedAmount,
+ toAmount,
+ fromAmount,
+ txHash,
+ status,
+ dex = 'muesliswap',
+ outputIdx,
+ }) => ({
+ aggregator: Swap.Aggregator.Muesliswap,
+ dex,
+ placedAt: placedAt ? placedAt * 1000 : undefined,
+ lastUpdate: finalizedAt ? finalizedAt * 1000 : undefined,
+ status,
+ tokenIn: asYoroiTokenId(fromToken),
+ tokenOut: asYoroiTokenId(toToken),
+ amountIn: Number(fromAmount),
+ actualAmountOut: Number(receivedAmount),
+ expectedAmountOut: Number(toAmount),
+ txHash,
+ updateTxHash: txHash,
+ outputIndex: outputIdx ?? 0,
+ }),
+ ),
+ },
+ cancel: {
+ request: ({order, collateral}: Swap.CancelRequest): CancelRequest => ({
+ wallet: addressHex,
+ utxo: `${order.txHash ?? ''}#${order.outputIndex}`,
+ collateralUtxo: collateral ?? '',
+ }),
+ response: ({cbor = ''}: CancelResponse): Swap.CancelResponse => ({
+ cbor,
+ }),
+ },
+ liquidityPools: {
+ request: ({
+ dex,
+ blacklistedDexes,
+ tokenIn,
+ tokenOut,
+ }: Swap.EstimateRequest): LiquidityPoolRequest => ({
+ 'only-verified': 'y',
+ 'providers': dex
+ ? dex
+ : Object.values(Provider)
+ .filter((provider) => !blacklistedDexes?.includes(provider))
+ .join(),
+ 'token-a': tokenIn,
+ 'token-b': tokenOut,
+ }),
+ response: (
+ pools: LiquidityPoolResponse,
+ {tokenIn, tokenOut}: Swap.EstimateRequest,
+ ): Pools =>
+ pools
+ .map(
+ ({
+ feeToken,
+ batcherFee,
+ poolFee,
+ lvlDeposit,
+ lpToken,
+ tokenA,
+ tokenB,
+ provider,
+ poolId,
+ }) => {
+ // Don't support pools with fees different than Ada yet
+ if (primaryTokenInfo.id !== asYoroiTokenId(feeToken.address))
+ return null
+
+ const A = {
+ price: tokenA.priceAda,
+ id: asYoroiTokenId(tokenA.address),
+ amount: Number(tokenA.amount),
+ decimals: tokenA.decimalPlaces,
+ }
+ const B = {
+ price: tokenB.priceAda,
+ id: asYoroiTokenId(tokenB.address),
+ amount: Number(tokenB.amount),
+ decimals: tokenB.decimalPlaces,
+ }
+ const [input, output] = tokenIn === A.id ? [A, B] : [B, A]
+
+ if (input.id !== tokenIn || input.id !== tokenOut) return null
+
+ return {
+ tokenIn: input.id,
+ tokenOut: output.id,
+ tokenInDecimals: input.decimals,
+ tokenOutDecimals: output.decimals,
+ tokenInSupply: Number(input.amount),
+ tokenOutSupply: Number(output.amount),
+ tokenInPtPrice: input.price,
+ tokenOutPtPrice: output.price,
+ deposit: Number(lvlDeposit),
+ lpTokenId: lpToken.address
+ ? asYoroiTokenId(lpToken.address)
+ : undefined,
+ batcherFee: Number(batcherFee),
+ fee: Number(poolFee),
+ poolId,
+ provider,
+ }
+ },
+ )
+ .filter((pool) => pool !== null),
+ },
+ constructSwapDatum: {
+ request: (
+ {tokenIn, tokenOut}: Swap.CreateRequest,
+ {dex, poolId, amountIn, expectedOutput}: Swap.Split,
+ ): ConstructSwapDatumRequest => {
+ const [sellTokenPolicyID, sellTokenNameHex] = tokenIn.split('.') as [
+ string,
+ string,
+ ]
+ const [buyTokenPolicyID, buyTokenNameHex] = tokenOut.split('.') as [
+ string,
+ string,
+ ]
+
+ return {
+ walletAddr: address,
+ protocol: dex as Provider,
+ poolId,
+ sellTokenPolicyID,
+ sellTokenNameHex,
+ sellAmount: amountIn.toString(),
+ buyTokenPolicyID,
+ buyTokenNameHex,
+ buyAmount: expectedOutput.toString(),
+ }
+ },
+ response: (
+ res: ConstructSwapDatumResponse,
+ estimate: Swap.EstimateResponse,
+ ): Swap.CreateResponse => ({
+ aggregator: Swap.Aggregator.Muesliswap,
+ contractAddress: res.address,
+ datumData: res.datum,
+ datumHash: res.hash,
+ ...estimate,
+ totalInput: estimate.totalInput ?? estimate.splits[0]?.amountIn ?? 0,
+ }),
+ },
+ } as const
+}
diff --git a/packages/swap/src/adapters/api/muesliswap/types.ts b/packages/swap/src/adapters/api/muesliswap/types.ts
new file mode 100644
index 0000000000..0684686045
--- /dev/null
+++ b/packages/swap/src/adapters/api/muesliswap/types.ts
@@ -0,0 +1,220 @@
+import {Portfolio} from '@yoroi/types'
+
+export type TokensResponse = Array<{
+ info: {
+ supply: {
+ total: string // total circulating supply of the token, without decimals.
+ circulating: string | null // if set the circulating supply of the token, if null the amount in circulation is unknown.
+ }
+ status: 'verified' | 'unverified' | 'scam' | 'outdated'
+ address: {
+ policyId: string // policy id of the token.
+ name: string // hexadecimal representation of token name.
+ }
+ symbol: string // shorthand token symbol.
+ image?: string // http link to the token image.
+ website: string
+ description: string
+ decimalPlaces: number // number of decimal places of the token, i.e. 6 for ADA and 0 for MILK.
+ categories: string[] // encoding categories as ids.
+ sign?: string // token sign, i.e. "₳" for ADA.
+ }
+ price: {
+ volume: {
+ base: string // float, trading volume 24h in base currency (e.g. ADA).
+ quote: string // float, trading volume 24h in quote currency.
+ }
+ volumeChange: {
+ base: number // float, percent change of trading volume in comparison to previous 24h.
+ quote: number // float, percent change of trading volume in comparison to previous 24h.
+ }
+ price: number // live trading price in base currency (e.g. ADA).
+ askPrice: number // lowest ask price in base currency (e.g. ADA).
+ bidPrice: number // highest bid price in base currency (e.g. ADA).
+ priceChange: {
+ '24h': string // float, price change last 24 hours.
+ '7d': string // float, price change last 7 days.
+ }
+ quoteDecimalPlaces: number // decimal places of quote token.
+ baseDecimalPlaces: number // decimal places of base token.
+ price10d: number[] //float, prices of this tokens averaged for the last 10 days, in chronological order i.e.oldest first.
+ }
+}>
+
+export type OrdersAggregatorResponse = Array<{
+ fromToken: {
+ address: {
+ policyId: string
+ name: string
+ }
+ symbol: string
+ image: string
+ decimalPlaces: number
+ }
+ toToken: {
+ address: {
+ policyId: string
+ name: string
+ }
+ symbol: string
+ image: string
+ decimalPlaces: number
+ }
+ batchToken: {
+ address: {
+ policyId: string
+ name: string
+ }
+ symbol: string
+ decimalPlaces: number
+ }
+ batcherFee: string
+ fromAmount: string
+ toAmount: string
+ attachedValues: [
+ {
+ address: {
+ policyId: string
+ name: string
+ }
+ amount: string
+ },
+ ]
+ owner: string
+ sender: string
+ providerSpecifics?: string
+ txHash: string
+ outputIdx: 0
+ status: 'open' | string
+ provider: string
+ placedAt?: number
+ finalizedAt?: number
+ batcherAddress: string
+}>
+
+export type OrdersHistoryResponse = Array<{
+ attachedLvl: number
+ finalizedAt: number
+ fromAmount: string
+ fromToken: TokensResponse[0]['info']
+ outputIdx: number | null
+ paidAmount: string
+ placedAt: number
+ pubKeyHash: string
+ receivedAmount: string | number
+ status: 'matched' | string
+ toAmount: string
+ toToken: TokensResponse[0]['info']
+ txHash: string
+ scriptVersion?: string
+ aggregatorPlatform?: string | null
+ stakeKeyHash?: string
+ dex?: string
+}>
+
+export type CancelRequest = {
+ utxo: string // order UTxO from the smart contract to cancel. e.g. "txhash#0".
+ collateralUtxo: string // collateral UTxOs to use for canceling the order in cbor format.
+ wallet: string // address of the wallet that owns the order in cbor format.
+}
+
+export type CancelResponse = {
+ status: 'success' | string
+ cbor: string
+}
+
+export const Provider = {
+ minswap: 'minswap',
+ sundaeswap: 'sundaeswap',
+ wingriders: 'wingriders',
+ muesliswap: 'muesliswap',
+ muesliswap_v1: 'muesliswap_v1',
+ muesliswap_v2: 'muesliswap_v2',
+ muesliswap_v3: 'muesliswap_v3',
+ muesliswap_v4: 'muesliswap_v4',
+ vyfi: 'vyfi',
+ spectrum: 'spectrum',
+} as const
+
+export type Provider = (typeof Provider)[keyof typeof Provider]
+
+export type LiquidityPoolRequest = {
+ 'only-verified': 'y' | 'n'
+ 'token-a': string
+ 'token-b': string
+ 'providers': string
+}
+
+export type PoolToken = {
+ address: {
+ policyId: string
+ name: string
+ }
+ symbol?: string
+ image?: string
+ decimalPlaces: number
+ amount: string
+ status: string
+ priceAda: number
+}
+export type LiquidityPoolResponse = Array<{
+ tokenA: PoolToken
+ tokenB: PoolToken
+ feeToken: Omit
+ batcherFee: string
+ lvlDeposit: string
+ poolFee: string
+ lpToken: {
+ address?: {
+ policyId: string
+ name: string
+ }
+ amount?: string
+ }
+ poolId: string
+ provider: Provider
+ txHash?: string
+ outputIdx?: number
+ volume24h?: number
+ volume7d?: number
+ liquidityApy?: number
+ priceASqrt?: any
+ priceBSqrt?: any
+ batcherAddress: string
+}>
+
+export type Pools = Array<{
+ tokenIn: Portfolio.Token.Id
+ tokenOut: Portfolio.Token.Id
+ tokenInDecimals: number
+ tokenOutDecimals: number
+ tokenInSupply: number
+ tokenOutSupply: number
+ tokenInPtPrice: number
+ tokenOutPtPrice: number
+ deposit: number
+ lpTokenId?: Portfolio.Token.Id
+ batcherFee: number
+ fee: number
+ poolId: string
+ provider: Provider
+}>
+
+export type ConstructSwapDatumRequest = {
+ walletAddr: string
+ protocol: Provider
+ poolId: string
+ sellTokenPolicyID: string
+ sellTokenNameHex: string
+ sellAmount: string
+ buyTokenPolicyID: string
+ buyTokenNameHex: string
+ buyAmount: string
+}
+
+export type ConstructSwapDatumResponse = {
+ status: 'success' | string
+ datum: string
+ hash: string
+ address: string
+}
diff --git a/packages/swap/src/adapters/intl/number-locale.mocks.ts b/packages/swap/src/adapters/intl/number-locale.mocks.ts
deleted file mode 100644
index 4bcd57a899..0000000000
--- a/packages/swap/src/adapters/intl/number-locale.mocks.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export const mockNumberLocale = {
- decimalSeparator: '.',
- fractionGroupSeparator: ' ',
- fractionGroupSize: 0,
- groupSeparator: ',',
- groupSize: 3,
- prefix: '',
- secondaryGroupSize: 0,
- suffix: '',
-} as const
diff --git a/packages/swap/src/adapters/openswap-api/api.mocks.ts b/packages/swap/src/adapters/openswap-api/api.mocks.ts
deleted file mode 100644
index 8c0e581a46..0000000000
--- a/packages/swap/src/adapters/openswap-api/api.mocks.ts
+++ /dev/null
@@ -1,322 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-const getOpenOrders: Array = [
- {
- utxo: '1e977694e2413bd0e6105303bb44da60530cafe49b864dde8f8902b021ed86ba#0',
- provider: 'muesliswap_v4',
- from: {quantity: 1000000n, tokenId: '.'},
- to: {
- quantity: 41372n,
- tokenId:
- '2adf188218a66847024664f4f63939577627a56c090f679fe366c5ee.535441424c45',
- },
- deposit: {quantity: 1700000n, tokenId: '.'},
- owner:
- 'addr1qxxvt9rzpdxxysmqp50d7f5a3gdescgrejsu7zsdxqjy8yun4cngaq46gr8c9qyz4td9ddajzqhjnrqvfh0gspzv9xnsmq6nqx',
- },
-]
-
-const getCompletedOrders: Array = [
- {
- txHash: '0e56f8d48808e689c1aed60abc158b7aef21c3565a0b766dd89ffba31979414b',
- from: {quantity: 200n, tokenId: '.'},
- to: {
- quantity: 100n,
- tokenId:
- 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b.415247454e54',
- },
- provider: 'minswap',
- placedAt: 1631635254000,
- },
-]
-
-const createOrderData: Swap.CreateOrderData = {
- address: 'someAddress',
- selectedPool: {
- provider: 'minswap',
- fee: '',
- tokenA: {
- tokenId:
- 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45',
- quantity: 1000n,
- },
- tokenB: {tokenId: '.', quantity: 1000000000n},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- batcherFee: {tokenId: '.', quantity: 0n},
- deposit: {tokenId: '.', quantity: 2000000n},
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- lpToken: {tokenId: '.', quantity: 0n},
- },
- amounts: {
- sell: {
- quantity: 1n,
- tokenId:
- 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45',
- },
- buy: {quantity: 100n, tokenId: '.'},
- },
- slippage: 1,
- limitPrice: undefined,
-}
-
-const getPools: Swap.Pool[] = [
- {
- tokenA: {quantity: 1233807687n, tokenId: '.'},
- tokenB: {
- quantity: 780n,
- tokenId:
- 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45',
- },
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- deposit: {quantity: 2000000n, tokenId: '.'},
- lpToken: {
- quantity: 981004n,
- tokenId:
- 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- fee: '0.3',
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- provider: 'minswap',
- },
- {
- tokenA: {quantity: 1233807687n, tokenId: '.'},
- tokenB: {
- quantity: 780n,
- tokenId:
- 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45',
- },
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- deposit: {quantity: 2000000n, tokenId: '.'},
- lpToken: {
- quantity: 981004n,
- tokenId:
- 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- fee: '0.3',
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- provider: 'sundaeswap',
- },
- {
- tokenA: {quantity: 1233807687n, tokenId: '.'},
- tokenB: {
- quantity: 780n,
- tokenId:
- 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45',
- },
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- deposit: {quantity: 2000000n, tokenId: '.'},
- lpToken: {
- quantity: 981004n,
- tokenId:
- 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- fee: '0.3',
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- provider: 'sundaeswap',
- },
-]
-
-const getTokenPairs: Array = [
- {
- application: Portfolio.Token.Application.General,
- nature: Portfolio.Token.Nature.Secondary,
- status: Portfolio.Token.Status.Valid,
- id: '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c.4567677363617065436c75624561737465725a656e6e79',
- fingerprint: 'asset126v2sm79r8uxvk4ju64mr6srxrvm2x75fpg6w3',
- name: 'EggscapeClubEasterZenny',
- decimals: 0,
- description: 'Eggscape Club Utility Token',
- originalImage: 'ipfs://QmNYibJoiTWRiMmWn4yXwvoakEPgq9WmaukmRXHF1VGbAU',
- type: Portfolio.Token.Type.FT,
- symbol: '',
- ticker: 'EZY',
- tag: '',
- reference: '',
- website: 'https://eggscape.io/',
- },
- {
- application: Portfolio.Token.Application.General,
- nature: Portfolio.Token.Nature.Secondary,
- status: Portfolio.Token.Status.Valid,
- id: 'cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354',
- fingerprint: 'asset1yv4fx867hueqt98aqvjw5ncjymz8k3ah8zawcg',
- name: 'CAST',
- decimals: 0,
- description: 'Utility Token for Carda Station Metaverse',
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354.png',
- type: Portfolio.Token.Type.FT,
- symbol: '',
- ticker: 'CAST',
- tag: '',
- reference: '',
- website: 'https://cardastation.com',
- },
- {
- application: Portfolio.Token.Application.General,
- nature: Portfolio.Token.Nature.Secondary,
- status: Portfolio.Token.Status.Valid,
- id: 'cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65',
- fingerprint: 'asset18qw75gcdldlu7q5xh8fjsemgvwffzkg8hatq3s',
- name: 'Redeemable',
- decimals: 4,
- description:
- 'The fiat-backed stablecoin issued by Shareslake. Powering the fully stable branch of Cardano.',
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65.png',
- type: Portfolio.Token.Type.FT,
- symbol: '',
- ticker: 'RUSD',
- tag: '',
- reference: '',
- website: 'https://www.shareslake.com',
- },
- {
- application: Portfolio.Token.Application.General,
- nature: Portfolio.Token.Nature.Secondary,
- status: Portfolio.Token.Status.Valid,
- id: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e',
- fingerprint: 'asset1ny2ehvl20cp5y7mmn5qq332sgdncdmsgrcqlwh',
- name: 'EduladderToken',
- decimals: 6,
- description: 'Proof Of Contribution.',
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e.png',
- type: Portfolio.Token.Type.FT,
- symbol: '',
- ticker: 'ELADR',
- tag: '',
- reference: '',
- website: 'https://eduladder.com',
- },
-]
-
-const getTokens: Array = [
- {
- application: Portfolio.Token.Application.General,
- decimals: 0,
- description: 'Eggscape Club Utility Token',
- fingerprint: 'asset126v2sm79r8uxvk4ju64mr6srxrvm2x75fpg6w3',
- id: '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c.4567677363617065436c75624561737465725a656e6e79',
- name: 'EggscapeClubEasterZenny',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage: 'ipfs://QmNYibJoiTWRiMmWn4yXwvoakEPgq9WmaukmRXHF1VGbAU',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'EZY',
- type: Portfolio.Token.Type.FT,
- website: 'https://eggscape.io/',
- },
- {
- application: Portfolio.Token.Application.General,
- decimals: 0,
- description: 'Utility Token for Carda Station Metaverse',
- fingerprint: 'asset1yv4fx867hueqt98aqvjw5ncjymz8k3ah8zawcg',
- id: 'cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354',
- name: 'CAST',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354.png',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'CAST',
- type: Portfolio.Token.Type.FT,
- website: 'https://cardastation.com',
- },
- {
- application: Portfolio.Token.Application.General,
- decimals: 4,
- description:
- 'The fiat-backed stablecoin issued by Shareslake. Powering the fully stable branch of Cardano.',
- fingerprint: 'asset18qw75gcdldlu7q5xh8fjsemgvwffzkg8hatq3s',
- id: 'cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65',
- name: 'Redeemable',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65.png',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'RUSD',
- type: Portfolio.Token.Type.FT,
- website: 'https://www.shareslake.com',
- },
- {
- application: Portfolio.Token.Application.General,
- decimals: 6,
- description: 'Proof Of Contribution.',
- fingerprint: 'asset1ny2ehvl20cp5y7mmn5qq332sgdncdmsgrcqlwh',
- id: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e',
- name: 'EduladderToken',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e.png',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'ELADR',
- type: Portfolio.Token.Type.FT,
- website: 'https://eduladder.com',
- },
- {
- application: Portfolio.Token.Application.General,
- decimals: 6,
- description: 'Proof Of Contribution.',
- fingerprint: 'asset1ud7y8pzglxmf68jtww3xhpes9j87akx4mtyx28',
- id: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.FFFFFF',
- name: 'FFFFFF',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage:
- 'https://tokens.muesliswap.com/static/img/tokens/2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e.png',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'ELADR',
- type: Portfolio.Token.Type.FT,
- website: 'https://eduladder.com',
- },
- {
- application: Portfolio.Token.Application.General,
- decimals: 6,
- description: 'Proof Of Contribution.',
- fingerprint: 'asset19caqweshdelqqf2u90n7xwxyv5wgsx69aakrce',
- id: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.FFFFAA',
- name: 'FFFFAA',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage: '',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'ELAD',
- type: Portfolio.Token.Type.FT,
- website: 'https://eduladder.com',
- },
-]
-
-export const apiMocks = {
- getOpenOrders,
- getCompletedOrders,
- createOrderData,
- getPools,
- getTokenPairs,
- getTokens,
-}
diff --git a/packages/swap/src/adapters/openswap-api/api.test.ts b/packages/swap/src/adapters/openswap-api/api.test.ts
deleted file mode 100644
index ebccbf8aff..0000000000
--- a/packages/swap/src/adapters/openswap-api/api.test.ts
+++ /dev/null
@@ -1,231 +0,0 @@
-import {OpenSwapApi} from './api'
-import {axiosClient} from './config'
-import {
- CancelOrderRequest,
- CreateOrderRequest,
- Network,
- Provider,
-} from './types'
-
-jest.mock('./config.ts')
-
-describe('OpenSwapApi constructor', () => {
- it('should throw an error for unsupported networks', () => {
- const unsupportedNetwork = 'testnet' // Assuming 'testnet' is not supported
- expect(() => new OpenSwapApi(unsupportedNetwork as Network)).toThrow(
- /Supported networks are/,
- )
- })
-
- it('should create an instance for supported networks', () => {
- const supportedNetwork = 'mainnet'
- const api = new OpenSwapApi(supportedNetwork)
- expect(api).toBeInstanceOf(OpenSwapApi)
- expect(api.network).toBe(supportedNetwork)
- })
-})
-
-describe('createOrder', () => {
- it('should call createOrder with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-createOrder',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const orderData: CreateOrderRequest = {
- walletAddress: 'walletAddress',
- protocol: 'sundaeswap',
- poolId: 'poolId',
- sell: {
- policyId: 'sell-policyId',
- assetName: 'buy-assetName',
- amount: '123',
- },
- buy: {
- policyId: 'buy-policyId',
- assetName: 'buy-assetName',
- amount: '321',
- },
- }
-
- const result = await api.createOrder(orderData)
-
- expect(result).toBe('test-createOrder')
- })
-})
-
-describe('cancelOrder', () => {
- it('should call cancelOrder with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: {cbor: 'test-cancelOrder'},
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const orderData: CancelOrderRequest = {
- orderUTxO: 'orderUTxO',
- collateralUTxO: 'collateralUTxO',
- walletAddress: 'walletAddress',
- }
-
- const result = await api.cancelOrder(orderData)
-
- expect(result).toBe('test-cancelOrder')
- })
-})
-
-describe('getOrders', () => {
- it('should call getOrders with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-getOrders',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const stakeKeyHash = 'stake-key-hash'
-
- const result = await api.getOrders(stakeKeyHash)
-
- expect(result).toBe('test-getOrders')
- })
-})
-
-describe('getCompletedOrders', () => {
- it('should call getCompletedOrders with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: [{status: 'matched', test: 'test-getCompletedOrders'}],
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const stakeKeyHash = 'stake-key-hash'
-
- const result = await api.getCompletedOrders(stakeKeyHash)
-
- expect(result).toEqual([
- {status: 'matched', test: 'test-getCompletedOrders'},
- ])
- })
-})
-
-describe('getPrice', () => {
- it('should call getPrice with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-getPrice',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const baseToken = {
- policyId: 'baseToken-policyId',
- name: 'baseToken-name',
- }
- const quoteToken = {
- policyId: 'quoteToken-policyId',
- name: 'quoteToken-name',
- }
-
- const result = await api.getPrice({baseToken, quoteToken})
-
- expect(result).toEqual('test-getPrice')
- })
-})
-
-describe('getPoolsPair', () => {
- it('should call getPoolsPair with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-getPoolsPair',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const tokenA = {
- policyId: 'tokenA-policyId',
- assetName: 'tokenA-name',
- }
- const tokenB = {
- policyId: 'tokenB-policyId',
- assetName: 'tokenB-name',
- }
-
- const result = await api.getPoolsPair({tokenA, tokenB})
-
- expect(result).toEqual('test-getPoolsPair')
- })
-})
-
-describe('getLiquidityPools', () => {
- it('should call getLiquidityPools with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-getLiquidityPools',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
- const tokenA = 'tokenA'
- const tokenB = 'tokenB'
- const providers: ReadonlyArray = ['spectrum']
-
- const result = await api.getLiquidityPools({tokenA, tokenB, providers})
-
- expect(result).toEqual('test-getLiquidityPools')
- })
-})
-
-describe('getTokenPairs', () => {
- it('should call getTokenPairs with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-getTokenPairs',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
-
- const result = await api.getTokenPairs()
-
- expect(result).toEqual('test-getTokenPairs')
- })
-})
-
-describe('getTokens', () => {
- it('should call getTokens with correct parameters', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: 'test-getTokens',
- }),
- )
-
- const api = new OpenSwapApi('mainnet', axiosClient)
-
- const result = await api.getTokens()
-
- expect(result).toEqual('test-getTokens')
- })
-})
diff --git a/packages/swap/src/adapters/openswap-api/api.ts b/packages/swap/src/adapters/openswap-api/api.ts
deleted file mode 100644
index 55351829dc..0000000000
--- a/packages/swap/src/adapters/openswap-api/api.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import {AxiosInstance} from 'axios'
-import {
- cancelOrder, // returns an unsigned transaction to cancel the order.
- createOrder, // returns a datum and a contract address to create the order transaction.
- getCompletedOrders,
- getOrders, // returns all orders for a given stake key hash.
-} from './orders'
-import {getTokenPairs} from './token-pairs'
-import {getTokens} from './tokens'
-import {
- CancelOrderRequest,
- CreateOrderRequest,
- Network,
- Provider,
- PriceAddress,
- TokenAddress,
-} from './types'
-import {axiosClient} from './config'
-import {getPrice} from './price'
-import {getLiquidityPools, getPoolsPair} from './pools'
-
-export class OpenSwapApi {
- constructor(
- public readonly network: Network,
- private readonly client: AxiosInstance = axiosClient,
- ) {
- if (!supportedNetworks.includes(network)) {
- throw new Error(
- `Supported networks are ${supportedNetworks.join(
- ', ',
- )}, got ${network}`,
- )
- }
- }
-
- public async createOrder(orderData: CreateOrderRequest) {
- return createOrder({network: this.network, client: this.client}, orderData)
- }
-
- public async cancelOrder(orderData: CancelOrderRequest) {
- return cancelOrder({network: this.network, client: this.client}, orderData)
- }
-
- public async getOrders(stakeKeyHash: string) {
- return getOrders(
- {network: this.network, client: this.client},
- {stakeKeyHash},
- )
- }
-
- public async getCompletedOrders(stakeKeyHash: string) {
- return getCompletedOrders(
- {network: this.network, client: this.client},
- {stakeKeyHash},
- )
- }
-
- public async getPrice({
- baseToken,
- quoteToken,
- }: {
- baseToken: PriceAddress
- quoteToken: PriceAddress
- }) {
- return getPrice(
- {network: this.network, client: this.client},
- {baseToken, quoteToken},
- )
- }
-
- public async getPoolsPair({
- tokenA,
- tokenB,
- }: {
- tokenA: TokenAddress
- tokenB: TokenAddress
- }) {
- 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 getTokenPairs({policyId = '', assetName = ''} = {}) {
- const tokenPairs = await getTokenPairs(
- {network: this.network, client: this.client},
- {policyId, assetName},
- )
-
- return tokenPairs
- }
-
- public async getTokens() {
- return getTokens({network: this.network, client: this.client})
- }
-}
-
-export const supportedNetworks: ReadonlyArray = [
- 'mainnet',
- 'preprod',
-] as const
diff --git a/packages/swap/src/adapters/openswap-api/config.ts b/packages/swap/src/adapters/openswap-api/config.ts
deleted file mode 100644
index 4110dd262a..0000000000
--- a/packages/swap/src/adapters/openswap-api/config.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import axios from 'axios'
-
-export const SWAP_API_ENDPOINTS = {
- mainnet: {
- getPrice: 'https://api.muesliswap.com/price',
- 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/v3/history',
- getTokenPairs: 'https://api.muesliswap.com/list',
- getTokens: 'https://api.muesliswap.com/token-list',
- constructSwapDatum: 'https://aggregator.muesliswap.com/constructSwapDatum',
- cancelSwapTransaction:
- 'https://aggregator.muesliswap.com/cancelSwapTransaction',
- },
- preprod: {
- getPrice: 'https://preprod.api.muesliswap.com/price',
- 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://preprod.api.muesliswap.com/orders/v3/history',
- getTokenPairs: 'https://preprod.api.muesliswap.com/list',
- getTokens: 'https://preprod.api.muesliswap.com/token-list',
- constructSwapDatum:
- 'https://aggregator.muesliswap.com/constructTestnetSwapDatum',
- cancelSwapTransaction:
- 'https://aggregator.muesliswap.com/cancelTestnetSwapTransaction',
- },
-} as const
-
-export const axiosClient = axios.create({
- headers: {
- 'Accept': 'application/json',
- 'Content-Type': 'application/json',
- },
-})
diff --git a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts b/packages/swap/src/adapters/openswap-api/openswap.mocks.ts
deleted file mode 100644
index a126706038..0000000000
--- a/packages/swap/src/adapters/openswap-api/openswap.mocks.ts
+++ /dev/null
@@ -1,697 +0,0 @@
-import {
- CompletedOrder,
- LiquidityPool,
- ListTokensResponse,
- OpenOrder,
- PriceResponse,
- TokenPairsResponse,
-} from './types'
-
-const getTokens: ListTokensResponse = [
- {
- supply: {
- total: '10000000',
- circulating: '300',
- },
- status: 'verified',
- website: 'https://eggscape.io/',
- image: 'ipfs://QmNYibJoiTWRiMmWn4yXwvoakEPgq9WmaukmRXHF1VGbAU',
- description: 'Eggscape Club Utility Token',
- address: {
- policyId: '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c',
- name: '4567677363617065436c75624561737465725a656e6e79',
- },
- symbol: 'EZY',
- decimalPlaces: 0,
- categories: [],
- },
- {
- supply: {
- total: '1500000000',
- circulating: null,
- },
- status: 'verified',
- symbol: 'CAST',
- decimalPlaces: 0,
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354.png',
- description: 'Utility Token for Carda Station Metaverse',
- address: {
- policyId: 'cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a',
- name: '43415354',
- },
- website: 'https://cardastation.com',
- categories: [],
- },
- {
- supply: {
- total: '387017195',
- circulating: null,
- },
- status: 'verified',
- website: 'https://www.shareslake.com',
- description:
- 'The fiat-backed stablecoin issued by Shareslake. Powering the fully stable branch of Cardano.',
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65.png',
- symbol: 'RUSD',
- decimalPlaces: 4,
- address: {
- policyId: 'cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786',
- name: '52656465656d61626c65',
- },
- categories: [],
- },
- {
- supply: {
- total: '45000000003000000',
- circulating: null,
- },
- status: 'verified',
- website: 'https://eduladder.com',
- symbol: 'ELADR',
- decimalPlaces: 6,
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e.png',
- description: 'Proof Of Contribution.',
- address: {
- policyId: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6',
- name: '4564756c6164646572546f6b656e',
- },
- categories: [],
- },
- {
- supply: {
- total: '45000000003000000',
- circulating: null,
- },
- status: 'verified',
- website: 'https://eduladder.com',
- symbol: 'ELADR',
- decimalPlaces: 6,
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e.png',
- description: 'Proof Of Contribution.',
- address: {
- policyId: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6',
- name: 'FFFFFF',
- },
- categories: [],
- },
- {
- supply: {
- total: '45000000003000000',
- circulating: null,
- },
- status: 'verified',
- website: 'https://eduladder.com',
- symbol: 'ELAD',
- decimalPlaces: 6,
- description: 'Proof Of Contribution.',
- address: {
- policyId: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6',
- name: 'FFFFAA',
- },
- categories: [],
- },
-]
-
-const getTokenPairs: TokenPairsResponse = [
- {
- info: {
- supply: {
- total: '10000000',
- circulating: '300',
- },
- status: 'verified',
- website: 'https://eggscape.io/',
- image: 'ipfs://QmNYibJoiTWRiMmWn4yXwvoakEPgq9WmaukmRXHF1VGbAU',
- description: 'Eggscape Club Utility Token',
- address: {
- policyId: '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c',
- name: '4567677363617065436c75624561737465725a656e6e79',
- },
- symbol: 'EZY',
- decimalPlaces: 0,
- categories: [],
- },
- price: {
- volume: {
- base: '0',
- quote: '0',
- },
- volumeChange: {
- base: 0,
- quote: 0,
- },
- // volumeTotal: {
- // base: 0,
- // quote: 0,
- // },
- // volumeAggregator: {},
- price: 5052.63204588242,
- askPrice: 9997.99630605055,
- bidPrice: 107.26778571429,
- priceChange: {
- '24h': '0.0',
- '7d': '0.0',
- },
- // fromToken: '.',
- // toToken:
- // '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c.4567677363617065436c75624561737465725a656e6e79',
- price10d: [
- 10004.374362563743, 10004.374362563743, 10004.374362563743,
- 10004.374362563743, 10004.374362563743, 10004.374362563743,
- 10004.374362563743, 10004.374362563743, 10004.374362563743,
- 10004.374362563743,
- ],
- quoteDecimalPlaces: 0,
- baseDecimalPlaces: 6,
- // quoteAddress: {
- // policyId: '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c',
- // name: '4567677363617065436c75624561737465725a656e6e79',
- // },
- // baseAddress: {
- // policyId: '',
- // name: '',
- // },
- },
- },
- {
- info: {
- supply: {
- total: '1500000000',
- circulating: null,
- },
- status: 'verified',
- symbol: 'CAST',
- decimalPlaces: 0,
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354.png',
- description: 'Utility Token for Carda Station Metaverse',
- address: {
- policyId: 'cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a',
- name: '43415354',
- },
- website: 'https://cardastation.com',
- categories: [],
- },
- price: {
- volume: {
- base: '0',
- quote: '0',
- },
- volumeChange: {
- base: 0,
- quote: 0,
- },
- // volumeTotal: {
- // base: 0,
- // quote: 0,
- // },
- // volumeAggregator: {},
- price: 402.13135196041,
- askPrice: 1000,
- bidPrice: 200.33388981636,
- priceChange: {
- '24h': '0.0',
- '7d': '0.0',
- },
- // fromToken: '.',
- // toToken:
- // 'cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a.43415354',
- price10d: [
- 690.7737494922812, 690.7737494922812, 690.7737494922812,
- 690.7737494922812, 690.7737494922812, 690.7737494922812,
- 690.7737494922812, 690.7737494922812, 690.7737494922812,
- 690.7737494922812,
- ],
- quoteDecimalPlaces: 0,
- baseDecimalPlaces: 6,
- // quoteAddress: {
- // policyId: 'cdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a',
- // name: '43415354',
- // },
- // baseAddress: {
- // policyId: '',
- // name: '',
- // },
- },
- },
- {
- info: {
- supply: {
- total: '387017195',
- circulating: null,
- },
- status: 'verified',
- website: 'https://www.shareslake.com',
- description:
- 'The fiat-backed stablecoin issued by Shareslake. Powering the fully stable branch of Cardano.',
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65.png',
- symbol: 'RUSD',
- decimalPlaces: 4,
- address: {
- policyId: 'cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786',
- name: '52656465656d61626c65',
- },
- categories: [],
- },
- price: {
- volume: {
- base: '0',
- quote: '0',
- },
- volumeChange: {
- base: 0,
- quote: 0,
- },
- // volumeTotal: {
- // base: 0,
- // quote: 0,
- // },
- // volumeAggregator: {},
- price: 222.76258782201,
- askPrice: 240.60714285714,
- bidPrice: 204.91803278689,
- priceChange: {
- '24h': '0',
- '7d': '0',
- },
- // fromToken: '.',
- // toToken:
- // 'cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786.52656465656d61626c65',
- price10d: [],
- quoteDecimalPlaces: 4,
- baseDecimalPlaces: 6,
- // quoteAddress: {
- // policyId: 'cd5b9dd91319edbb19477ad00cbef673a221e70a17ef043951fc6786',
- // name: '52656465656d61626c65',
- // },
- // baseAddress: {
- // policyId: '',
- // name: '',
- // },
- },
- },
- {
- info: {
- supply: {
- total: '45000000003000000',
- circulating: null,
- },
- status: 'verified',
- website: 'https://eduladder.com',
- symbol: 'ELADR',
- decimalPlaces: 6,
- image:
- 'https://tokens.muesliswap.com/static/img/tokens/2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e.png',
- description: 'Proof Of Contribution.',
- address: {
- policyId: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6',
- name: '4564756c6164646572546f6b656e',
- },
- categories: [],
- },
- price: {
- volume: {
- base: '0',
- quote: '0',
- },
- volumeChange: {
- base: 0,
- quote: 0,
- },
- // volumeTotal: {
- // base: 0,
- // quote: 0,
- // },
- // volumeAggregator: {},
- price: 1.94e-8,
- askPrice: 1.995e-8,
- bidPrice: 1.885e-8,
- priceChange: {
- '24h': '0.0',
- '7d': '0.0',
- },
- // fromToken: '.',
- // toToken:
- // '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6.4564756c6164646572546f6b656e',
- price10d: [
- 1.4529723607353359e-8, 1.4529723607353359e-8, 1.4529723607353359e-8,
- 1.4529723607353359e-8, 1.4529723607353359e-8, 1.4529723607353359e-8,
- 1.4529723607353359e-8, 1.4529723607353359e-8, 1.4529723607353359e-8,
- 1.4529723607353359e-8,
- ],
- quoteDecimalPlaces: 6,
- baseDecimalPlaces: 6,
- // quoteAddress: {
- // policyId: '2d420236ffaada336c21e3f4520b799f6e246d8618f2fc89a4907da6',
- // name: '4564756c6164646572546f6b656e',
- // },
- // baseAddress: {
- // policyId: '',
- // name: '',
- // },
- },
- },
-]
-
-const getCompletedOrders: CompletedOrder[] = [
- {
- toToken: {
- address: {
- policyId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b',
- name: '415247454e54',
- },
- },
- toAmount: '100',
- fromToken: {
- address: {
- policyId: '',
- name: '',
- },
- },
- fromAmount: '200',
- placedAt: 1631635254, // Unix timestamp
- status: 'completed',
- receivedAmount: '100',
- paidAmount: '200',
- finalizedAt: 1631635354, // You can specify a more specific type if needed
- txHash: '0e56f8d48808e689c1aed60abc158b7aef21c3565a0b766dd89ffba31979414b',
- outputIdx: 0,
- attachedLvl: 'someAttachedLvl',
- scriptVersion: 'v1',
- pubKeyHash: 'somePubKeyHash',
- dex: 'minswap',
- },
-]
-
-const getOpenOrders: OpenOrder[] = [
- {
- from: {
- amount: '1000000',
- token: '.',
- },
- to: {
- amount: '41372',
- token:
- '2adf188218a66847024664f4f63939577627a56c090f679fe366c5ee.535441424c45',
- },
- // sender:
- // 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
- // owner:
- // 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
- // ownerPubKeyHash: '1f4a69a22ca1018e7763d11474a7e604d6d754c716594a14ed6d4012',
- // ownerStakeKeyHash:
- // '24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7',
- // batcherFee: {
- // amount: '950000',
- // token: '.',
- // },
- deposit: '1700000',
- // valueAttached: [
- // {
- // amount: '3650000',
- // token: '.',
- // },
- // ],
- utxo: '1e977694e2413bd0e6105303bb44da60530cafe49b864dde8f8902b021ed86ba#0',
- provider: 'muesliswap_v4',
- // allowPartial: true,
- owner:
- 'addr1qxxvt9rzpdxxysmqp50d7f5a3gdescgrejsu7zsdxqjy8yun4cngaq46gr8c9qyz4td9ddajzqhjnrqvfh0gspzv9xnsmq6nqx',
- },
-]
-
-const getLiquidityPools: LiquidityPool[] = [
- {
- provider: 'minswap',
- poolFee: '0.3',
- tokenA: {
- amount: '1233807687',
- address: {
- policyId: '',
- name: '',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- tokenB: {
- amount: '780',
- address: {
- policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72',
- name: '43414b45',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- batcherFee: '2000000',
- // depositFee: {
- // amount: '2000000',
- // token: '.',
- // },
- lvlDeposit: '2000000',
- batcherAddress: 'someBatcherAddress',
- feeToken: {
- address: {
- policyId: '.',
- name: '.',
- },
- decimalPlaces: 0,
- },
- txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce',
- outputIdx: 0,
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- lpToken: {
- amount: '981004',
- address: {
- policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86',
- name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- },
- },
- {
- provider: 'sundaeswap',
- poolFee: '0.3',
- tokenA: {
- amount: '1233807687',
- address: {
- policyId: '',
- name: '',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- tokenB: {
- amount: '780',
- address: {
- policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72',
- name: '43414b45',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- batcherFee: '2000000',
- // depositFee: {
- // amount: '2000000',
- // token: '.',
- // },
- lvlDeposit: '2000000',
- txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce',
- outputIdx: 0,
- batcherAddress: 'someBatcherAddress',
- feeToken: {
- address: {
- policyId: '.',
- name: '.',
- },
- decimalPlaces: 0,
- },
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- lpToken: {
- amount: '981004',
- address: {
- policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86',
- name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- },
- },
- {
- provider: 'sundaeswap',
- poolFee: '0.3',
- tokenA: {
- amount: '1233807687',
- address: {
- policyId: '',
- name: '',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- tokenB: {
- amount: '780',
- address: {
- policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72',
- name: '43414b45',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- batcherFee: '2000000',
- // depositFee: {
- // amount: '2000000',
- // token: '.',
- // },
- lvlDeposit: '2000000',
- txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce',
- outputIdx: 0,
- batcherAddress: 'someBatcherAddress',
- feeToken: {
- address: {
- policyId: '.',
- name: '.',
- },
- decimalPlaces: 0,
- },
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- lpToken: {
- amount: '981004',
- address: {
- policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86',
- name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- },
- },
- {
- provider: 'spectrum', // unsupported pool
- poolFee: '0.3',
- tokenA: {
- amount: '1233807687',
- address: {
- policyId: '',
- name: '',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- tokenB: {
- amount: '780',
- address: {
- policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72',
- name: '43414b45',
- },
- symbol: '',
- image: '',
- decimalPlaces: 0,
- status: '',
- priceAda: 0,
- },
- batcherFee: '2000000',
- // depositFee: {
- // amount: '2000000',
- // token: '.',
- // },
- lvlDeposit: '2000000',
- txHash: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce',
- outputIdx: 0,
- batcherAddress: 'someBatcherAddress',
- feeToken: {
- address: {
- policyId: '.',
- name: '.',
- },
- decimalPlaces: 0,
- },
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- lpToken: {
- amount: '981004',
- address: {
- policyId: 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86',
- name: '7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- },
- },
-]
-
-const getPrice: PriceResponse = {
- baseDecimalPlaces: 6,
- quoteDecimalPlaces: 6,
- baseAddress: {
- policyId: '',
- name: '',
- },
- quoteAddress: {
- policyId: '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6',
- name: '4d494e',
- },
- askPrice: 0.08209814208,
- bidPrice: 0.06319999985,
- price: 0.07080044463,
- volume: {
- base: '14735349',
- quote: '211287611',
- },
- volumeAggregator: {
- minswap: {
- quote: 107413106646,
- base: 7651672996,
- },
- sundaeswap: {
- quote: 566084169,
- base: 39000000,
- },
- vyfi: {
- quote: 12370434748,
- base: 879028993,
- },
- },
- volumeTotal: {
- base: 8584437338,
- quote: 120560913174,
- },
- volumeChange: {
- base: 0,
- quote: 0,
- },
- priceChange: {
- '24h': '-0.2374956426253183',
- '7d': '8.757469657697857',
- },
- marketCap: 68873484244745.086,
-}
-
-export const openswapMocks = {
- getTokenPairs,
- getTokens,
- getPrice,
- getCompletedOrders,
- getOpenOrders,
- getLiquidityPools,
-}
diff --git a/packages/swap/src/adapters/openswap-api/orders.test.ts b/packages/swap/src/adapters/openswap-api/orders.test.ts
deleted file mode 100644
index 63b03c4cfc..0000000000
--- a/packages/swap/src/adapters/openswap-api/orders.test.ts
+++ /dev/null
@@ -1,274 +0,0 @@
-import {createOrder, cancelOrder, getOrders, getCompletedOrders} from './orders'
-import axios from 'axios'
-import {axiosClient} from './config'
-
-jest.mock('./config')
-
-const ADA_TOKEN = {
- policyId: '',
- assetName: '',
-}
-
-const GENS_TOKEN = {
- policyId: 'dda5fdb1002f7389b33e036b6afee82a8189becb6cba852e8b79b4fb',
- assetName: '0014df1047454e53',
-}
-
-describe('SwapOrdersApi', () => {
- describe('getOrders', () => {
- it('Should return orders list using staking key hash', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- data: mockedOrders,
- status: 200,
- }),
- )
- const result = await getOrders(
- {network: 'preprod', client: mockAxios},
- {
- stakeKeyHash:
- '24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7',
- },
- )
- expect(result).toHaveLength(1)
- })
-
- it('Should throws an error', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- data: 'fake-error',
- status: 400,
- }),
- )
- await expect(() =>
- getOrders(
- {network: 'preprod', client: mockAxios},
- {
- stakeKeyHash:
- '24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7',
- },
- ),
- ).rejects.toThrowError(
- /^Failed to get orders for 24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7$/,
- )
- })
- })
-
- describe('getCompletedOrders', () => {
- it('Should return orders list using staking key hash', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- data: mockedCompleteOrders,
- status: 200,
- }),
- )
- const result = await getCompletedOrders(
- {network: 'preprod', client: mockAxios},
- {
- stakeKeyHash:
- '24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7',
- },
- )
- expect(result).toHaveLength(1)
- })
-
- it('Should throws an error', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- data: 'fake-error',
- status: 400,
- }),
- )
- await expect(() =>
- getCompletedOrders(
- {network: 'preprod', client: mockAxios},
- {
- stakeKeyHash:
- '24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7',
- },
- ),
- ).rejects.toThrowError(
- /^Failed to get orders for 24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7$/,
- )
- })
- })
-
- describe('createOrder', () => {
- it('should create order and return datum, datumHash, and contract address', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: mockedCreateOrderResult,
- }),
- )
-
- const order = await createOrder(
- {network: 'mainnet', client: mockAxios},
- createOrderParams,
- )
-
- expect(order).toEqual(mockedCreateOrderResult)
- })
-
- it('should throw error for invalid order: custom message', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: {status: 'failed', reason: 'error_message'},
- }),
- )
- await expect(() =>
- createOrder({network: 'preprod', client: mockAxios}, createOrderParams),
- ).rejects.toThrowError(/^error_message$/)
- })
-
- it('should throw error for invalid order: default message', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: {status: 'failed'},
- }),
- )
- await expect(() =>
- createOrder({network: 'preprod', client: mockAxios}, createOrderParams),
- ).rejects.toThrowError(/^Unexpected error occurred$/)
- })
-
- it('should throw generic error for invalid response', async () => {
- const mockAxios = axiosClient as jest.Mocked
- await expect(async () => {
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({status: 400}),
- )
- await createOrder(
- {network: 'mainnet', client: mockAxios},
- createOrderParams,
- )
- }).rejects.toThrow('Failed to construct swap datum')
- })
- })
-
- describe('cancelOrder', () => {
- it('should cancel pending orders', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: {cbor: 'tx_cbor'},
- }),
- )
-
- const txCbor = await cancelOrder(
- {network: 'mainnet', client: mockAxios},
- {
- orderUTxO: 'orderUtxo',
- collateralUTxO: 'collateralUtxo',
- walletAddress:
- 'addr1q9ndnrwz52yeex4j04kggp0ul5632qmxqx22ugtukkytjysw86pdygc6zarl2kks6fvg8um447uvv679sfdtzkwf2kuq673wke',
- },
- )
-
- expect(txCbor).toBe('tx_cbor')
- })
-
- it('should throw generic error for invalid response', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() => Promise.resolve({status: 400}))
- await expect(() =>
- cancelOrder(
- {network: 'mainnet', client: mockAxios},
- {
- orderUTxO: cancelOrderParams.utxo,
- collateralUTxO: cancelOrderParams.collateralUTxOs,
- walletAddress: cancelOrderParams.address,
- },
- ),
- ).rejects.toThrow('Failed to cancel swap transaction')
- })
- })
-})
-
-const mockedOrders = [
- {
- from: {
- amount: '1000000',
- token: '.',
- },
- to: {
- amount: '41372',
- token:
- '2adf188218a66847024664f4f63939577627a56c090f679fe366c5ee.535441424c45',
- },
- sender:
- 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
- owner:
- 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
- ownerPubKeyHash: '1f4a69a22ca1018e7763d11474a7e604d6d754c716594a14ed6d4012',
- ownerStakeKeyHash:
- '24fd15671a17a39268b7a31e2a6703f5893f254d4568411322baeeb7',
- batcherFee: {
- amount: '950000',
- token: '.',
- },
- deposit: '1700000',
- valueAttached: [
- {
- amount: '3650000',
- token: '.',
- },
- ],
- utxo: '1e977694e2413bd0e6105303bb44da60530cafe49b864dde8f8902b021ed86ba#0',
- provider: 'muesliswap_v4',
- feeField: '2650000',
- allowPartial: true,
- },
-]
-
-const mockedCreateOrderResult = {
- status: 'success',
- datum:
- 'd8799fd8799fd8799fd8799f581c353b8bc29a15603f0b73eac44653d1bd944d92e0e0dcd5eb185164a2ffd8799fd8799fd8799f581cda22c532206a75a628778eebaf63826f9d93fbe9b4ac69a7f8e4cd78ffffffff581c353b8bc29a15603f0b73eac44653d1bd944d92e0e0dcd5eb185164a21b00000188f2408726d8799fd8799f4040ffd8799f581cdda5fdb1002f7389b33e036b6afee82a8189becb6cba852e8b79b4fb480014df1047454e53ffffffd8799fd879801a0006517affff',
- hash: '4ae3fc5498e9d0f04daaf2ee739e41dc3f6f4119391e7274f0b3fa15aa2163ff',
- address: 'addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4',
-}
-
-const createOrderParams = {
- walletAddress:
- 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
- protocol: 'sundaeswap',
- poolId: '14',
- sell: {
- ...ADA_TOKEN,
- amount: '25000000',
- },
- buy: {
- ...GENS_TOKEN,
- amount: '50000000',
- },
-} as const
-
-const cancelOrderParams = {
- utxo: '6c4b4e55301d79128071f05a018cf05b7de86bc3f92d05b6668423e220152a86',
- collateralUTxOs:
- '6c4b4e55301d79128071f05a018cf05b7de86bc3f92d05b6668423e220152a86',
- address:
- 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
-} as const
-
-const mockedCompleteOrders = [
- {
- status: 'matched',
- utxo: '6c4b4e55301d79128071f05a018cf05b7de86bc3f92d05b6668423e220152a86',
- collateralUTxOs:
- '6c4b4e55301d79128071f05a018cf05b7de86bc3f92d05b6668423e220152a86',
- address:
- 'addr1qy0556dz9jssrrnhv0g3ga98uczdd465cut9jjs5a4k5qy3yl52kwxsh5wfx3darrc4xwql43ylj2n29dpq3xg46a6mska8vfz',
- },
-] as const
diff --git a/packages/swap/src/adapters/openswap-api/orders.ts b/packages/swap/src/adapters/openswap-api/orders.ts
deleted file mode 100644
index 9a576e0a74..0000000000
--- a/packages/swap/src/adapters/openswap-api/orders.ts
+++ /dev/null
@@ -1,114 +0,0 @@
-import {SWAP_API_ENDPOINTS} from './config'
-import type {
- ApiDeps,
- CancelOrderRequest,
- CreateOrderRequest,
- CreateOrderResponse,
- CompletedOrderResponse,
- OpenOrderResponse,
-} from './types'
-
-export async function createOrder(
- deps: ApiDeps,
- args: CreateOrderRequest,
-): Promise {
- const {network, client} = deps
- const apiUrl = SWAP_API_ENDPOINTS[network].constructSwapDatum
- const response = await client.get<
- | {status: 'failed'; reason?: string}
- | {status: 'success'; hash: string; datum: string; address: string}
- >('/', {
- baseURL: apiUrl,
- params: {
- walletAddr: args.walletAddress,
- protocol: args.protocol,
- poolId: args.poolId,
- sellTokenPolicyID: args.sell.policyId,
- sellTokenNameHex: args.sell.assetName,
- sellAmount: args.sell.amount,
- buyTokenPolicyID: args.buy.policyId,
- buyTokenNameHex: args.buy.assetName,
- buyAmount: args.buy.amount,
- },
- })
-
- if (response.status !== 200) {
- throw new Error('Failed to construct swap datum', {
- cause: response.data,
- })
- }
-
- if (response.data.status === 'failed') {
- throw new Error(response.data.reason ?? 'Unexpected error occurred')
- }
-
- return response.data
-}
-
-export async function cancelOrder(
- deps: ApiDeps,
- args: CancelOrderRequest,
-): Promise {
- const {network, client} = deps
- const apiUrl = SWAP_API_ENDPOINTS[network].cancelSwapTransaction
- const response = await client.get('/', {
- baseURL: apiUrl,
- params: {
- wallet: args.walletAddress,
- utxo: args.orderUTxO,
- collateralUtxo: args.collateralUTxO,
- },
- })
-
- if (response.status !== 200) {
- throw new Error('Failed to cancel swap transaction', {
- cause: response.data,
- })
- }
-
- return response.data.cbor
-}
-
-export async function getOrders(
- deps: ApiDeps,
- args: {stakeKeyHash: string},
-): Promise {
- const {network, client} = deps
- const {stakeKeyHash} = args
- const apiUrl = SWAP_API_ENDPOINTS[network].getOrders
- const response = await client.get(apiUrl, {
- params: {
- 'stake-key-hash': stakeKeyHash,
- },
- })
-
- if (response.status !== 200) {
- throw new Error(`Failed to get orders for ${stakeKeyHash}`, {
- cause: response.data,
- })
- }
-
- return response.data
-}
-
-export async function getCompletedOrders(
- deps: ApiDeps,
- args: {stakeKeyHash: string},
-): Promise {
- const {network, client} = deps
- const {stakeKeyHash} = args
- const apiUrl = SWAP_API_ENDPOINTS[network].getCompletedOrders
- const response = await client.get(apiUrl, {
- params: {
- 'stake-key-hash': stakeKeyHash,
- },
- })
-
- if (response.status !== 200) {
- throw new Error(`Failed to get orders for ${stakeKeyHash}`, {
- cause: response.data,
- })
- }
-
- return response.data
-}
diff --git a/packages/swap/src/adapters/openswap-api/pools.test.ts b/packages/swap/src/adapters/openswap-api/pools.test.ts
deleted file mode 100644
index 3c473c1ffd..0000000000
--- a/packages/swap/src/adapters/openswap-api/pools.test.ts
+++ /dev/null
@@ -1,191 +0,0 @@
-import {getLiquidityPools, getPoolsPair} from './pools'
-import {axiosClient} from './config'
-import {LiquidityPoolResponse, PoolPairResponse} from './types'
-
-jest.mock('./config')
-
-describe('SwapPoolsApi', () => {
- describe('getLiquidityPools', () => {
- it('should get liquidity pools list for a given token pair', async () => {
- const mockAxios = axiosClient as jest.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).toHaveLength(1)
- })
-
- it('should throw error for invalid response', async () => {
- const mockAxios = axiosClient as jest.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')
- })
- })
-
- describe('getPoolsPair', () => {
- it('should get pools pair list for a given token pair', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: mockedPoolsPairResponse,
- }),
- )
-
- const result = await getPoolsPair(
- {network: 'mainnet', client: mockAxios},
- {tokenA: getPoolsPairParams.sell, tokenB: getPoolsPairParams.buy},
- )
- expect(result).toHaveLength(1)
- })
-
- it('should throw error for invalid response', async () => {
- const mockAxios = axiosClient as jest.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 mockedPoolsPairResponse: Readonly = [
- {
- provider: 'minswap',
- fee: '0.3',
- tokenA: {
- amount: '1233807687',
- token: '.',
- },
- tokenB: {
- amount: '780',
- token:
- 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72.43414b45',
- },
- price: 0,
- batcherFee: {
- amount: '2000000',
- token: '.',
- },
- depositFee: {
- amount: '2000000',
- token: '.',
- },
- deposit: 2000000,
- utxo: '0596860b5970ef989c56f7ae38b3c0f74bb4979ac15ee994c30760f7f4d908ce#0',
- poolId:
- '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- timestamp: '2023-05-31 07:03:41',
- lpToken: {
- amount: '981004',
- token:
- 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86.7339a8bcda85e2c997d9f16beddbeb3ad755f5202f5cfd9cb08db346a1292c01',
- },
- batcherAddress:
- 'addr1wxaptpmxcxawvr3pzlhgnpmzz3ql43n2tc8mn3av5kx0yzs09tqh8',
- },
-]
-
-const getPoolsPairParams = {
- sell: {
- policyId: '',
- assetNameHex: '',
- },
- buy: {
- policyId: 'e16c2dc8ae937e8d3790c7fd7168d7b994621ba14ca11415f39fed72',
- 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/swap/src/adapters/openswap-api/pools.ts b/packages/swap/src/adapters/openswap-api/pools.ts
deleted file mode 100644
index 23b89fd41e..0000000000
--- a/packages/swap/src/adapters/openswap-api/pools.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import {SWAP_API_ENDPOINTS} from './config'
-import type {
- ApiDeps,
- LiquidityPoolResponse,
- PoolPairResponse,
- Provider,
- TokenAddress,
-} from './types'
-
-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 {
- const {tokenA, tokenB} = args
- const {network, client} = deps
- const params: {[key: string]: string} = {
- 'policy-id1': tokenA.policyId,
- 'policy-id2': tokenB.policyId,
- }
-
- if ('assetName' in tokenA) params.tokenname1 = tokenA.assetName
- if ('assetName' in tokenB) params.tokenname2 = tokenB.assetName
-
- // note: {tokenname-hex} will overwrites {tokenname}
- if ('assetNameHex' in tokenA) params['tokenname-hex1'] = tokenA.assetNameHex
- if ('assetNameHex' in tokenB) params['tokenname-hex2'] = tokenB.assetNameHex
-
- 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 pair for token pair', {
- cause: response.data,
- })
- }
-
- return response.data
-}
diff --git a/packages/swap/src/adapters/openswap-api/price.test.ts b/packages/swap/src/adapters/openswap-api/price.test.ts
deleted file mode 100644
index a13ef667a2..0000000000
--- a/packages/swap/src/adapters/openswap-api/price.test.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import {getPrice} from './price'
-import {axiosClient} from './config'
-import {PriceAddress, PriceResponse} from './types'
-
-jest.mock('./config')
-
-describe('SwapPoolsApi', () => {
- it('should get price for the pair token', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({
- status: 200,
- data: mockedPriceResponse,
- }),
- )
-
- const result = await getPrice(
- {network: 'mainnet', client: mockAxios},
- {
- ...getPriceParams,
- },
- )
- expect(result).toEqual(mockedPriceResponse)
- })
-
- it('should throw error for invalid response', async () => {
- const mockAxios = axiosClient as jest.Mocked
- await expect(async () => {
- mockAxios.get.mockImplementationOnce(() => Promise.resolve({status: 500}))
- await getPrice(
- {network: 'preprod', client: mockAxios},
- {...getPriceParams},
- )
- }).rejects.toThrow('Failed to fetch price for token pair')
- })
-})
-
-const mockedPriceResponse: PriceResponse = {
- baseDecimalPlaces: 6,
- quoteDecimalPlaces: 6,
- baseAddress: {
- policyId: '',
- name: '',
- },
- quoteAddress: {
- policyId: '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6',
- name: '4d494e',
- },
- askPrice: 0.08209814208,
- bidPrice: 0.06319999985,
- price: 0.07080044463,
- volume: {
- base: '14735349',
- quote: '211287611',
- },
- volumeAggregator: {
- minswap: {
- quote: 107413106646,
- base: 7651672996,
- },
- sundaeswap: {
- quote: 566084169,
- base: 39000000,
- },
- vyfi: {
- quote: 12370434748,
- base: 879028993,
- },
- },
- volumeTotal: {
- base: 8584437338,
- quote: 120560913174,
- },
- volumeChange: {
- base: 0,
- quote: 0,
- },
- priceChange: {
- '24h': '-0.2374956426253183',
- '7d': '8.757469657697857',
- },
- marketCap: 68873484244745.086,
-} as const
-
-const getPriceParams: {
- baseToken: PriceAddress
- quoteToken: PriceAddress
-} = {
- baseToken: {
- policyId: '',
- name: '',
- },
- quoteToken: {
- policyId: '29d222ce763455e3d7a09a665ce554f00ac89d2e99a1a83d267170c6',
- name: '4d494e',
- },
-} as const
diff --git a/packages/swap/src/adapters/openswap-api/price.ts b/packages/swap/src/adapters/openswap-api/price.ts
deleted file mode 100644
index ba46cd1ce8..0000000000
--- a/packages/swap/src/adapters/openswap-api/price.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import {SWAP_API_ENDPOINTS} from './config'
-import type {ApiDeps, PriceAddress, PriceResponse} from './types'
-
-export async function getPrice(
- deps: ApiDeps,
- args: {baseToken: PriceAddress; quoteToken: PriceAddress},
-): Promise {
- const {baseToken, quoteToken} = args
- const {network, client} = deps
- const params: {[key: string]: string} = {
- 'base-policy-id': baseToken.policyId,
- 'base-token-name': baseToken.policyId,
- 'quote-policy-id': quoteToken.policyId,
- 'quote-token-name': quoteToken.policyId,
- }
-
- const apiUrl = SWAP_API_ENDPOINTS[network].getPrice
- const response = await client.get('', {
- baseURL: apiUrl,
- params,
- })
-
- if (response.status !== 200) {
- throw new Error('Failed to fetch price for token pair', {
- cause: response.data,
- })
- }
-
- return response.data
-}
diff --git a/packages/swap/src/adapters/openswap-api/token-pairs.test.ts b/packages/swap/src/adapters/openswap-api/token-pairs.test.ts
deleted file mode 100644
index b07af955cd..0000000000
--- a/packages/swap/src/adapters/openswap-api/token-pairs.test.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import {getTokenPairs} from './token-pairs'
-import {axiosClient} from './config'
-
-jest.mock('./config.ts')
-
-describe('SwapTokenPairsApi', () => {
- it('should get all tokens based pairs', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({status: 200, data: mockedGetTokenPairsResponse}),
- )
-
- const result = await getTokenPairs({network: 'mainnet', client: mockAxios})
-
- expect(result).toHaveLength(1)
- })
-
- it('should return empty list on preprod network', async () => {
- const mockAxios = axiosClient as jest.Mocked
-
- const result = await getTokenPairs({network: 'preprod', client: mockAxios})
-
- expect(result).toHaveLength(0)
- })
-
- it('should throw error for invalid response', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() => Promise.resolve({status: 500}))
- await expect(() =>
- getTokenPairs({network: 'mainnet', client: mockAxios}),
- ).rejects.toThrow('Failed to fetch token pairs')
- })
-})
-
-const mockedGetTokenPairsResponse = [
- {
- info: {
- supply: {total: '1000000000000', circulating: null},
- status: 'unverified',
- image: 'ipfs://QmPzaykTy4yfutCtwv7nRUmgbQbA7euiThyy2i9fiFuDHX',
- imageIpfsHash: 'QmPzaykTy4yfutCtwv7nRUmgbQbA7euiThyy2i9fiFuDHX',
- symbol: 'ARGENT',
- minting: {
- type: 'time-lock-policy',
- blockchain: 'cardano',
- mintedBeforeSlotNumber: 91850718,
- },
- mediatype: 'image/png',
- tokentype: 'token',
- description: 'ARGENT Token',
- totalsupply: 1000000000000,
- address: {
- policyId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b',
- name: '415247454e54',
- },
- decimalPlaces: 0,
- categories: [],
- },
- price: {
- volume: {base: 0, quote: 0},
- volumeChange: {base: 0, quote: 0},
- volumeTotal: {base: 0, quote: 0},
- volumeAggregator: {},
- price: 0,
- askPrice: 0,
- bidPrice: 0,
- priceChange: {'24h': 0, '7d': 0},
- quoteDecimalPlaces: 0,
- baseDecimalPlaces: 6,
- quoteAddress: {
- policyId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b',
- name: '415247454e54',
- },
- baseAddress: {policyId: '', name: ''},
- price10d: [],
- },
- },
-]
diff --git a/packages/swap/src/adapters/openswap-api/token-pairs.ts b/packages/swap/src/adapters/openswap-api/token-pairs.ts
deleted file mode 100644
index d6aaf46d2e..0000000000
--- a/packages/swap/src/adapters/openswap-api/token-pairs.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import {SWAP_API_ENDPOINTS} from './config'
-import type {ApiDeps, TokenPairsResponse} from './types'
-
-export async function getTokenPairs(
- deps: ApiDeps,
- {policyId = '', assetName = ''} = {},
-): Promise {
- const {network, client} = deps
- if (network === 'preprod') return []
-
- const apiUrl = SWAP_API_ENDPOINTS[network].getTokenPairs
- const response = await client.get('', {
- baseURL: apiUrl,
- params: {
- 'base-policy-id': policyId,
- 'base-tokenname': assetName,
- },
- })
-
- if (response.status !== 200) {
- throw new Error('Failed to fetch token pairs', {cause: response.data})
- }
-
- return response.data
-}
diff --git a/packages/swap/src/adapters/openswap-api/tokens.test.ts b/packages/swap/src/adapters/openswap-api/tokens.test.ts
deleted file mode 100644
index b660bf015d..0000000000
--- a/packages/swap/src/adapters/openswap-api/tokens.test.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import {getTokens} from './tokens'
-import {axiosClient} from './config'
-
-jest.mock('./config.ts')
-
-describe('SwapTokensApi', () => {
- it('should get all supported tokens list', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({status: 200, data: mockedGetTokensResponse}),
- )
-
- const result = await getTokens({network: 'mainnet', client: mockAxios})
-
- expect(result).toHaveLength(1)
- })
-
- it('should throw error for invalid response', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() => Promise.resolve({status: 500}))
-
- await expect(() =>
- getTokens({network: 'mainnet', client: mockAxios}),
- ).rejects.toThrow('Failed to fetch tokens')
- })
-
- it('should return empty array', async () => {
- const mockAxios = axiosClient as jest.Mocked
- mockAxios.get.mockImplementationOnce(() =>
- Promise.resolve({status: 200, data: mockedGetTokensResponse}),
- )
-
- const result = await getTokens({network: 'preprod', client: mockAxios})
-
- expect(result).toHaveLength(0)
- })
-})
-
-const mockedGetTokensResponse = [
- {
- supply: {
- total: '10000000',
- circulating: '6272565',
- },
- status: 'verified',
- website: 'https://ada.muesliswap.com/',
- symbol: 'MILK',
- decimalPlaces: 0,
- image: 'https://static.muesliswap.com/images/tokens/MILK.png',
- description: 'MILK is the utility token powering the MuesliSwap ecosystem.',
- address: {
- policyId: '8a1cfae21368b8bebbbed9800fec304e95cce39a2a57dc35e2e3ebaa',
- name: '4d494c4b',
- },
- categories: ['1', '2'],
- },
-]
diff --git a/packages/swap/src/adapters/openswap-api/tokens.ts b/packages/swap/src/adapters/openswap-api/tokens.ts
deleted file mode 100644
index e1fc16909c..0000000000
--- a/packages/swap/src/adapters/openswap-api/tokens.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {SWAP_API_ENDPOINTS} from './config'
-import type {ApiDeps, ListTokensResponse} from './types'
-
-export async function getTokens(deps: ApiDeps): Promise {
- const {network, client} = deps
- if (network === 'preprod') return []
-
- const apiUrl = SWAP_API_ENDPOINTS[network].getTokens
- const response = await client.get('', {
- baseURL: apiUrl,
- })
-
- if (response.status !== 200) {
- throw new Error('Failed to fetch tokens', {cause: response.data})
- }
-
- return response.data
-}
diff --git a/packages/swap/src/adapters/openswap-api/types.ts b/packages/swap/src/adapters/openswap-api/types.ts
deleted file mode 100644
index 951f0327eb..0000000000
--- a/packages/swap/src/adapters/openswap-api/types.ts
+++ /dev/null
@@ -1,279 +0,0 @@
-/* istanbul ignore file */
-
-import {AxiosInstance} from 'axios'
-
-export type CancelOrderRequest = {
- orderUTxO: string // order UTxO from the smart contract to cancel. e.g. "txhash#0".
- collateralUTxO: string // collateral UTxOs to use for canceling the order in cbor format.
- walletAddress: string // address of the wallet that owns the order in cbor format.
-}
-
-export type CreateOrderRequest = {
- walletAddress: string
- protocol: Provider // only in the CreateOrder they call provider as protocol
- poolId?: string // only required for SundaeSwap trades.
- sell: {
- policyId: string
- assetName: string // hexadecimal representation of token, i.e. "" for lovelace, "4d494c4b" for MILK.
- amount: string
- }
- buy: {
- policyId: string
- assetName: string // hexadecimal representation of token, i.e. "" for lovelace, "4d494c4b" for MILK.
- amount: string
- }
-}
-
-export type CreateOrderResponse =
- | {status: 'failed'; reason?: string}
- | {status: 'success'; hash: string; datum: string; address: string}
-
-export type OpenOrder = {
- provider: Provider
- owner: string
- from: {
- amount: string
- token: string
- }
- to: {
- amount: string
- token: string
- }
- deposit: string
- utxo: string
-}
-export type OpenOrderResponse = OpenOrder[]
-
-export type CompletedOrder = {
- toToken: {
- address: {
- policyId: string
- name: string
- }
- }
- toAmount: string
- fromToken: {
- address: {
- policyId: string
- name: string
- }
- }
- fromAmount: string
- placedAt: number
- status: string
- receivedAmount: string
- paidAmount: string
- finalizedAt: any
- txHash: string
- outputIdx: number
- attachedLvl: string
- scriptVersion: string
- pubKeyHash: string
- dex: Provider
-}
-export type CompletedOrderResponse = CompletedOrder[]
-
-export type Provider =
- | 'minswap'
- | 'sundaeswap'
- | 'wingriders'
- | 'muesliswap'
- | 'muesliswap_v1'
- | 'muesliswap_v2'
- | 'muesliswap_v3'
- | 'muesliswap_v4'
- | 'vyfi'
- | 'spectrum'
-// | 'muesliswap_clp'
-
-export type Network = 'mainnet' | 'preprod'
-
-// 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.
- token: string // hexadecimal representation of tokenA, i.e. "." for lovelace, "8a1cfae21368b8bebbbed9800fec304e95cce39a2a57dc35e2e3ebaa.4d494c4b" for MILK.
- }
- tokenB: {
- amount: string // amount of tokenB in the pool, without decimals.
- token: string // hexadecimal representation of tokenB, i.e. "." for lovelace, "8a1cfae21368b8bebbbed9800fec304e95cce39a2a57dc35e2e3ebaa.4d494c4b" for MILK.
- }
- 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: 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.
- poolId: string // identifier of the pool across platforms.
- timestamp: string // latest update of this pool in UTC, i.e. 2023-05-23 06:13:26.
- lpToken: {
- 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 PoolPairResponse = PoolPair[]
-
-export type TokenPair = {
- info: {
- supply: {
- total: string // total circulating supply of the token, without decimals.
- circulating: string | null // if set the circulating supply of the token, if null the amount in circulation is unknown.
- }
- status: 'verified' | 'unverified' | 'scam' | 'outdated'
- address: {
- policyId: string // policy id of the token.
- name: string // hexadecimal representation of token name.
- }
- symbol: string // shorthand token symbol.
- image?: string // http link to the token image.
- website: string
- description: string
- decimalPlaces: number // number of decimal places of the token, i.e. 6 for ADA and 0 for MILK.
- categories: string[] // encoding categories as ids.
- sign?: string // token sign, i.e. "₳" for ADA.
- }
- price: {
- volume: {
- base: string // float, trading volume 24h in base currency (e.g. ADA).
- quote: string // float, trading volume 24h in quote currency.
- }
- volumeChange: {
- base: number // float, percent change of trading volume in comparison to previous 24h.
- quote: number // float, percent change of trading volume in comparison to previous 24h.
- }
- price: number // live trading price in base currency (e.g. ADA).
- askPrice: number // lowest ask price in base currency (e.g. ADA).
- bidPrice: number // highest bid price in base currency (e.g. ADA).
- priceChange: {
- '24h': string // float, price change last 24 hours.
- '7d': string // float, price change last 7 days.
- }
- quoteDecimalPlaces: number // decimal places of quote token.
- baseDecimalPlaces: number // decimal places of base token.
- price10d: number[] //float, prices of this tokens averaged for the last 10 days, in chronological order i.e.oldest first.
- }
-}
-export type TokenPairsResponse = TokenPair[]
-
-export type TokenInfo = Omit
-export type ListTokensResponse = TokenInfo[]
-
-export type TokenAddress =
- | {
- policyId: string
- assetName: string
- }
- | {
- policyId: string
- assetNameHex: string
- }
-
-export type ApiDeps = {
- network: Network
- client: AxiosInstance
-}
-
-export type PriceAddress = {
- policyId: string
- name: string
-}
-
-type VolumeAggregator = {
- [key in Provider]?: {
- quote: number
- base: number
- }
-}
-
-export type PriceResponse = {
- baseDecimalPlaces: number
- quoteDecimalPlaces: number
- baseAddress: PriceAddress
- quoteAddress: PriceAddress
- askPrice: number
- bidPrice: number
- price: number
- volume: {
- base: string
- quote: string
- }
- volumeAggregator: VolumeAggregator
- volumeTotal: {
- base: number
- quote: number
- }
- volumeChange: {
- base: number
- quote: number
- }
- priceChange: {
- '24h': string
- '7d': string
- }
- marketCap: number
-}
-
-export type LiquidityPoolResponse = LiquidityPool[]
-export type LiquidityPool = {
- tokenA: {
- address: {
- policyId: string
- name: string
- }
- symbol?: string
- image?: string
- decimalPlaces: number
- amount: string
- status: string
- priceAda: number
- }
- tokenB: {
- address: {
- policyId: string
- name: string
- }
- symbol?: string
- image?: string
- decimalPlaces: number
- amount: string
- status: string
- priceAda: number
- }
- 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: Provider
- txHash?: string
- outputIdx?: number
- volume24h?: number
- volume7d?: number
- liquidityApy?: number
- priceASqrt?: any
- priceBSqrt?: any
- batcherAddress: string
-}
diff --git a/packages/swap/src/fixtures/ErrorBoundary.tsx b/packages/swap/src/fixtures/ErrorBoundary.tsx
deleted file mode 100644
index 2cc55d1de9..0000000000
--- a/packages/swap/src/fixtures/ErrorBoundary.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import React, {Component, ReactNode} from 'react'
-import {View, Text} from 'react-native'
-
-interface Props {
- children: ReactNode
-}
-
-interface State {
- hasError: boolean
- error?: Error
-}
-
-export class ErrorBoundary extends Component {
- state: State = {
- hasError: false,
- }
-
- static getDerivedStateFromError(error: Error): State {
- return {hasError: true, error}
- }
-
- render() {
- if (this.state.hasError) {
- return (
-
- hasError
- {JSON.stringify(this.state.error)}
-
- )
- }
-
- return this.props.children
- }
-}
diff --git a/packages/swap/src/fixtures/SuspenseBoundary.tsx b/packages/swap/src/fixtures/SuspenseBoundary.tsx
deleted file mode 100644
index f9b3ee6fc6..0000000000
--- a/packages/swap/src/fixtures/SuspenseBoundary.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as React from 'react'
-import {Text, View} from 'react-native'
-
-export const SuspenseBoundary = ({children}: {children: React.ReactNode}) => {
- return (
-
- suspending
-
- }
- >
- {children}
-
- )
-}
diff --git a/packages/swap/src/fixtures/manager-wrapper.tsx b/packages/swap/src/fixtures/manager-wrapper.tsx
deleted file mode 100644
index 8a2361f5e9..0000000000
--- a/packages/swap/src/fixtures/manager-wrapper.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from 'react'
-import {QueryClient, QueryClientProvider} from 'react-query'
-import {Swap} from '@yoroi/types'
-
-import {SuspenseBoundary} from './SuspenseBoundary'
-import {ErrorBoundary} from './ErrorBoundary'
-import {SwapProvider} from '../translators/reactjs/provider/SwapProvider'
-
-type Props = {
- queryClient: QueryClient
- swapManager: Swap.Manager
-}
-
-export const wrapperManagerFixture =
- ({queryClient, swapManager}: Props) =>
- ({children}: {children: React.ReactNode}) =>
- (
-
-
-
- {children}
-
-
-
- )
diff --git a/packages/swap/src/fixtures/query-client.ts b/packages/swap/src/fixtures/query-client.ts
deleted file mode 100644
index d3cb0695fb..0000000000
--- a/packages/swap/src/fixtures/query-client.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {QueryClient} from 'react-query'
-
-export const queryClientFixture = () =>
- new QueryClient({
- defaultOptions: {
- queries: {
- retry: false,
- cacheTime: 0,
- },
- mutations: {
- retry: false,
- },
- },
- })
diff --git a/packages/swap/src/helpers/pools/getPoolUrlByProvider.ts b/packages/swap/src/helpers/getPoolUrlByProvider.ts
similarity index 73%
rename from packages/swap/src/helpers/pools/getPoolUrlByProvider.ts
rename to packages/swap/src/helpers/getPoolUrlByProvider.ts
index 797395cf3b..c66464b3eb 100644
--- a/packages/swap/src/helpers/pools/getPoolUrlByProvider.ts
+++ b/packages/swap/src/helpers/getPoolUrlByProvider.ts
@@ -1,10 +1,10 @@
-import {Swap} from '@yoroi/types'
+import {Provider} from '../adapters/api/muesliswap/types'
-export const getPoolUrlByProvider = (provider: Swap.PoolProvider): string => {
+export const getPoolUrlByProvider = (provider: Provider): string => {
return (poolUrls[provider] ?? poolUrls.muesliswap_v1) as string
}
-const poolUrls: Record = {
+const poolUrls: Record = {
minswap: 'https://minswap.org',
sundaeswap: 'https://sundae.fi',
wingriders: 'https://www.wingriders.com',
diff --git a/packages/swap/src/helpers/mocks.ts b/packages/swap/src/helpers/mocks.ts
deleted file mode 100644
index 9c20429af8..0000000000
--- a/packages/swap/src/helpers/mocks.ts
+++ /dev/null
@@ -1,1772 +0,0 @@
-import {Swap} from '@yoroi/types'
-
-import {tokenInfoMocks} from '../tokenInfo.mocks'
-
-const mockedPools1: Swap.Pool[] = [
- {
- tokenA: {quantity: 529504614n, tokenId: 'tokenA.'},
- tokenB: {quantity: 7339640354n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'muesliswap_v2',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 143610201719n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2055821866531n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'vyfi',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '2',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 27344918300893n, tokenId: 'tokenA.'},
- tokenB: {quantity: 393223050468514n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '3',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 3400529909n, tokenId: 'tokenA.'},
- tokenB: {quantity: 49215467634n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.35', // 0.35%
- provider: 'wingriders',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '4',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 10178222382n, tokenId: 'tokenA.'},
- tokenB: {quantity: 145009426744n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '5',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 973669994n, tokenId: 'tokenA.'},
- tokenB: {quantity: 13710853133n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.05', // 0.05%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '6',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-
-const mockedPools2: Swap.Pool[] = [
- {
- tokenA: {quantity: 529504614n, tokenId: 'tokenA.'},
- tokenB: {quantity: 7339640354n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'muesliswap_v2',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-
- {
- tokenA: {quantity: 143610201719n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2055821866531n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'vyfi',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-
- {
- tokenA: {quantity: 27344918300893n, tokenId: 'tokenA.'},
- tokenB: {quantity: 393223050468514n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-
- {
- tokenA: {quantity: 3400529909n, tokenId: 'tokenA.'},
- tokenB: {quantity: 49215467634n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.35', // 0.35%
- provider: 'wingriders',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-
- {
- tokenA: {quantity: 10178222382n, tokenId: 'tokenA.'},
- tokenB: {quantity: 145009426744n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-
- {
- tokenA: {quantity: 973669994n, tokenId: 'tokenA.'},
- tokenB: {quantity: 13710853133n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.05', // 0.05%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-const mockedPools3: Swap.Pool[] = [
- {
- tokenA: {quantity: 529504614n, tokenId: 'tokenA.'},
- tokenB: {quantity: 7339640354n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'muesliswap_v2',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 143610201719n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2055821866531n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'vyfi',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 27337840212697n, tokenId: 'tokenA.'},
- tokenB: {quantity: 393349086430693n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 3400529909n, tokenId: 'tokenA.'},
- tokenB: {quantity: 49215467634n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.35', // 0.35%
- provider: 'wingriders',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 10178222382n, tokenId: 'tokenA.'},
- tokenB: {quantity: 145009426744n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 973669994n, tokenId: 'tokenA.'},
- tokenB: {quantity: 13710853133n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.05', // 0.05%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-const mockedPools4: Swap.Pool[] = [
- {
- tokenB: {quantity: 529504614n, tokenId: 'tokenB.'},
- tokenA: {quantity: 7339640354n, tokenId: 'tokenA.'},
- ptPriceTokenB: '1',
- ptPriceTokenA: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'muesliswap_v2',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 143610201719n, tokenId: 'tokenB.'},
- tokenA: {quantity: 2055821866531n, tokenId: 'tokenA.'},
- ptPriceTokenB: '1',
- ptPriceTokenA: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'vyfi',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 27337840212697n, tokenId: 'tokenB.'},
- tokenA: {quantity: 393349086430693n, tokenId: 'tokenA.'},
- ptPriceTokenB: '1',
- ptPriceTokenA: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 3400529909n, tokenId: 'tokenB.'},
- tokenA: {quantity: 49215467634n, tokenId: 'tokenA.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.35', // 0.35%
- provider: 'wingriders',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 10178222382n, tokenId: 'tokenB.'},
- tokenA: {quantity: 145009426744n, tokenId: 'tokenA.'},
- ptPriceTokenB: '1',
- ptPriceTokenA: '0.06950020009',
- fee: '0.3', // 0.3%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 973669994n, tokenId: 'tokenB.'},
- tokenA: {quantity: 13710853133n, tokenId: 'tokenA.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06950020009',
- fee: '0.05', // 0.05%
- provider: 'sundaeswap',
- batcherFee: {quantity: 2500000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-
-const mockedPools5: Swap.Pool[] = [
- {
- tokenA: {quantity: 27019025551205n, tokenId: 'tokenA.'},
- tokenB: {quantity: 403657459031350n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.06693552899',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 27019025551205n, tokenId: 'tokenB.'},
- tokenA: {quantity: 403657459031350n, tokenId: 'tokenA.'},
- ptPriceTokenB: '1',
- ptPriceTokenA: '0.06693552899',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 2000000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 10000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 10100n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '1',
- fee: '0', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 0n, tokenId: 'tokenA.'},
- tokenB: {quantity: 0n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '1',
- fee: '0', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 1n, tokenId: 'tokenA.'},
- tokenB: {quantity: 1n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '1',
- fee: '0', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 0n, tokenId: 'tokenA.'},
- tokenB: {quantity: 1n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '1',
- fee: '0', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 1n, tokenId: 'tokenA.'},
- tokenB: {quantity: 0n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '1',
- fee: '0', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenA: {quantity: 10000000000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 10000000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '1',
- fee: '0', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-
-const mockedPools6: Swap.Pool[] = [
- {
- tokenA: {quantity: 100n, tokenId: 'tokenA.'},
- tokenB: {quantity: 200n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.5',
- fee: '0',
- provider: 'vyfi',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: 'no.token',
- },
- },
- {
- tokenB: {quantity: 100n, tokenId: 'tokenB.'},
- tokenA: {quantity: 200n, tokenId: 'tokenA.'},
- ptPriceTokenB: '0.5',
- ptPriceTokenA: '1',
- fee: '0',
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-
-const mockedPools7: Swap.Pool[] = [
- {
- tokenA: {quantity: 100n, tokenId: 'tokenA.'},
- tokenB: {quantity: 200n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '1',
- fee: '0',
- provider: 'vyfi',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: 'no.token',
- },
- },
- {
- tokenB: {quantity: 100n, tokenId: 'tokenB.'},
- tokenA: {quantity: 200n, tokenId: 'tokenA.'},
- ptPriceTokenB: '0',
- ptPriceTokenA: '1',
- fee: '0',
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-
-const mockedPools8: Swap.Pool[] = [
- {
- tokenA: {quantity: 1000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 1000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0',
- provider: 'vyfi',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- {
- tokenB: {quantity: 1000n, tokenId: 'tokenB.'},
- tokenA: {quantity: 1000n, tokenId: 'tokenA.'},
- ptPriceTokenB: '0',
- ptPriceTokenA: '0',
- fee: '50',
- provider: 'minswap',
- batcherFee: {quantity: 0n, tokenId: '.'},
- deposit: {quantity: 0n, tokenId: '.'},
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
-]
-
-const mockedOrderCalculations1: Swap.OrderCalculation[] = [
- {
- order: {
- side: 'sell',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 1162995513n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 3050000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 950000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- discountTier: {
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- fixedFee: '1000000',
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 300000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1046695961n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.07214312806368332309',
- market: '0.07214312806368332309',
- actualPrice: '0',
- withSlippage: '0.09553872731529533436',
- withFees: '0.08770455161678684826',
- withFeesAndSlippage: '0.09744950186160124105',
- difference: '21.570209070179074072',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 529504614n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 7339640354n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'muesliswap_v2',
- batcherFee: {
- quantity: 950000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'sell',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 1426244382n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 4950000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 1900000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- discountTier: {
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- fixedFee: '1000000',
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 300000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1283619943n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.06985537222703457584',
- market: '0.06985537222703457584',
- actualPrice: '0',
- withSlippage: '0.07790467929805294401',
- withFees: '0.07218258055862406896',
- withFeesAndSlippage: '0.08020286733734550586',
- difference: '3.33146651058691987',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 143610201719n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 2055821866531n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'vyfi',
- batcherFee: {
- quantity: 1900000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '2',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'sell',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 1433692167n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 5050000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- discountTier: {
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- fixedFee: '1000000',
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 300000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1290322950n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.06954047650134526242',
- market: '0.06954047650134526242',
- actualPrice: '0',
- withSlippage: '0.07749997781563135028',
- withFees: '0.0718773544083958157',
- withFeesAndSlippage: '0.07986372713900810646',
- difference: '3.360457138951796387',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 27344918300893n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 393223050468514n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'minswap',
- batcherFee: {
- quantity: 2000000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '3',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'sell',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 1401162647n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 5050000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- discountTier: {
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- fixedFee: '1000000',
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 350000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1261046382n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.06909473936707611128',
- market: '0.06909473936707611128',
- actualPrice: '0',
- withSlippage: '0.07929922438015448031',
- withFees: '0.07354606563387783488',
- withFeesAndSlippage: '0.08171785072374919196',
- difference: '6.44235191792733844',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 3400529909n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 49215467634n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.35',
- provider: 'wingriders',
- batcherFee: {
- quantity: 2000000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '4',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'sell',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 1406650031n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 5050000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2500000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- discountTier: {
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- fixedFee: '1000000',
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 300000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1265985027n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.07019007391821953012',
- market: '0.07019007391821953012',
- actualPrice: '0',
- withSlippage: '0.07898987576256697703',
- withFees: '0.07361461466459101084',
- withFeesAndSlippage: '0.08179401635213810471',
- difference: '4.878953041653028379',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 10178222382n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 145009426744n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'sundaeswap',
- batcherFee: {
- quantity: 2500000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '5',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'sell',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 1276429070n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 5050000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2500000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- discountTier: {
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- fixedFee: '1000000',
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 50000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1148786163n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.07101454479564951518',
- market: '0.07101454479564951518',
- actualPrice: '0',
- withSlippage: '0.08704840223602170946',
- withFees: '0.08112475846386043214',
- withFeesAndSlippage: '0.09013862051540048015',
- difference: '14.236821058705550837',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 973669994n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 13710853133n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.05',
- provider: 'sundaeswap',
- batcherFee: {
- quantity: 2500000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '6',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
-]
-
-const mockedOrderCalculations2: Swap.OrderCalculation[] = [
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 7335973n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 2950000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 950000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 22008n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.07214312806368332309',
- market: '0.07214312806368332309',
- actualPrice: '0',
- withSlippage: '0.08151081111111111111',
- withFees: '0.08285972917140270829',
- withFeesAndSlippage: '0.09206636666666666667',
- difference: '14.854638820567161388',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 529504614n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 7339640354n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'muesliswap_v2',
- batcherFee: {
- quantity: 950000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 7006900n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 5050000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 1900000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 21021n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.06985537222703457584',
- market: '0.06985537222703457584',
- actualPrice: '0',
- withSlippage: '0.07785444444444444444',
- withFees: '0.08906899910931000891',
- withFeesAndSlippage: '0.09896555555555555556',
- difference: '27.50486651166910406',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 143610201719n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 2055821866531n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'vyfi',
- batcherFee: {
- quantity: 1900000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '2',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 6974976n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 4000000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 20925n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.06954047650134526242',
- market: '0.06954047650134526242',
- actualPrice: '0',
- withSlippage: '0.07749973333333333333',
- withFees: '0.08974975910250240897',
- withFeesAndSlippage: '0.09972195555555555556',
- difference: '29.061179356121031793',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 27344918300893n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 393223050468514n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'minswap',
- batcherFee: {
- quantity: 2000000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '3',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 6947861n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 4000000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 24318n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.06909473936707611128',
- market: '0.06909473936707611128',
- actualPrice: '0',
- withSlippage: '0.07719845555555555556',
- withFees: '0.08947860910521390895',
- withFeesAndSlippage: '0.09942067777777777778',
- difference: '29.501333856757818526',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 3400529909n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 49215467634n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.35',
- provider: 'wingriders',
- batcherFee: {
- quantity: 2000000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '4',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 7044988n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 4500000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2500000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 21135n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.07019007391821953012',
- market: '0.07019007391821953012',
- actualPrice: '0',
- withSlippage: '0.07827764444444444444',
- withFees: '0.09544987904550120954',
- withFeesAndSlippage: '0.10605542222222222222',
- difference: '35.987716948001227979',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 10178222382n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 145009426744n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3',
- provider: 'sundaeswap',
- batcherFee: {
- quantity: 2500000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '5',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 7157210n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 4500000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2500000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 3579n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: true,
- prices: {
- base: '0.07101454479564951518',
- market: '0.07101454479564951518',
- actualPrice: '0',
- withSlippage: '0.07952455555555555556',
- withFees: '0.09657209903427900966',
- withFeesAndSlippage: '0.10730233333333333333',
- difference: '35.989182655713084861',
- priceImpact: '0.0',
- },
- pool: {
- tokenA: {
- quantity: 973669994n,
- tokenId: 'tokenA.',
- },
- tokenB: {
- quantity: 13710853133n,
- tokenId: 'tokenB.',
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.05',
- provider: 'sundaeswap',
- batcherFee: {
- quantity: 2500000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '6',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
-]
-
-export const mocks = {
- mockedPools1,
- mockedPools2,
- mockedPools3,
- mockedPools4,
- mockedPools5,
- mockedPools6,
- mockedPools7,
- mockedPools8,
-
- mockedOrderCalculations1,
- mockedOrderCalculations2,
-}
diff --git a/packages/swap/src/helpers/orders/amounts/getBuyAmount.test.ts b/packages/swap/src/helpers/orders/amounts/getBuyAmount.test.ts
deleted file mode 100644
index a3f780cd0d..0000000000
--- a/packages/swap/src/helpers/orders/amounts/getBuyAmount.test.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-import {Swap, Portfolio} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-import {getBuyAmount} from './getBuyAmount'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('getBuyAmount', () => {
- it('should calculate the correct buy amount when selling tokenA', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const sell: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.a,
- }
- const result = getBuyAmount(pool, sell, tokenInfoMocks.b)
- expect(result.quantity).toBe(197n)
- expect(result.info).toEqual(tokenInfoMocks.b)
-
- const limitedResult = getBuyAmount(
- pool,
- sell,
- tokenInfoMocks.b,
- true,
- new BigNumber(2.1),
- )
- expect(limitedResult.quantity).toBe(47n)
- expect(limitedResult.info).toEqual(tokenInfoMocks.b)
-
- const zeroLimitResult = getBuyAmount(
- {...pool, tokenA: {quantity: 0n, tokenId: 'tokenA.'}},
- sell,
- tokenInfoMocks.b,
- true,
- )
- expect(zeroLimitResult.quantity).toBe(0n)
- expect(zeroLimitResult.info).toEqual(tokenInfoMocks.b)
- })
-
- it('should calculate the correct buy amount when selling tokenA (muesli example)', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 2022328173071n, tokenId: '.'},
- tokenB: {quantity: 277153n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.3', // 0.3%
- provider: 'muesliswap',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const sell: Portfolio.Token.Amount = {
- quantity: 1000000000n,
- info: tokenInfoMocks.pt,
- }
- const result = getBuyAmount(pool, sell, tokenInfoMocks.b)
- expect(result.quantity).toBe(136n)
- expect(result.info).toEqual(tokenInfoMocks.b)
-
- const limitedResult = getBuyAmount(
- pool,
- sell,
- tokenInfoMocks.b,
- true,
- new BigNumber(2.1),
- )
- expect(limitedResult.quantity).toBe(476190476n)
- expect(limitedResult.info).toEqual(tokenInfoMocks.b)
- })
-
- it('should calculate the correct buy amount when selling tokenB', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const sell: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.b,
- }
- const result = getBuyAmount(pool, sell, tokenInfoMocks.a)
- expect(result.quantity).toBe(49n)
- expect(result.info).toEqual(tokenInfoMocks.a)
-
- const limitedResult = getBuyAmount(
- pool,
- sell,
- tokenInfoMocks.a,
- true,
- new BigNumber(2.1),
- )
- expect(limitedResult.quantity).toBe(47n)
- expect(limitedResult.info).toEqual(tokenInfoMocks.a)
- })
-
- it('should calculate buy side as market without fee when initializing limit', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 1000000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 10000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.5',
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const sell: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.a,
- }
- const limitResult = getBuyAmount(pool, sell, tokenInfoMocks.b, true)
- const marketResult = getBuyAmount(pool, sell, tokenInfoMocks.b)
-
- // buy more (fee not included)
- expect(limitResult.quantity).toBe(1000n)
- expect(limitResult.info).toEqual(tokenInfoMocks.b)
-
- // buy less (fee included)
- expect(marketResult.quantity).toBe(989n)
- expect(marketResult.info).toEqual(tokenInfoMocks.b)
- })
-})
diff --git a/packages/swap/src/helpers/orders/amounts/getBuyAmount.ts b/packages/swap/src/helpers/orders/amounts/getBuyAmount.ts
deleted file mode 100644
index c6827e2102..0000000000
--- a/packages/swap/src/helpers/orders/amounts/getBuyAmount.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import {BigNumber} from 'bignumber.js'
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {ceilDivision} from '../../../utils/ceilDivision'
-import {getMarketPrice} from '../../prices/getMarketPrice'
-
-/**
- * Calculate the amount to buy based on the desired sell amount in a liquidity pool.
- *
- * @param pool - The liquidity pool.
- * @param sell - The desired sell amount.
- * @param isLimit - Optional limit type.
- * @param limit - Optional limit price
- *
- * @returns The calculated buy amount
- * if the balance in the pool is insuficient it wont throw an error
- */
-export const getBuyAmount = (
- pool: Swap.Pool,
- sell: Portfolio.Token.Amount,
- buyInfo: Portfolio.Token.Info,
- isLimit?: boolean,
- limit: BigNumber = new BigNumber(0),
-): Portfolio.Token.Amount => {
- const isSellTokenA = sell.info.id === pool.tokenA.tokenId
-
- if (sell.quantity === 0n) return {info: buyInfo, quantity: 0n}
-
- if (isLimit) {
- const limitPrice = limit.isZero()
- ? getMarketPrice(pool, sell.info.id)
- : limit
-
- return {
- info: buyInfo,
- quantity: limitPrice.isZero()
- ? 0n
- : BigInt(
- new BigNumber(sell.quantity.toString())
- .dividedToIntegerBy(limitPrice)
- .toString(),
- ),
- }
- }
-
- const A = BigInt(pool.tokenA.quantity)
- const B = BigInt(pool.tokenB.quantity)
-
- const [firstToken, secondToken] = isSellTokenA ? [A, B] : [B, A]
-
- const sellQuantity = BigInt(sell.quantity)
-
- const fee = ceilDivision(
- BigInt(Number(pool.fee) * 1000) * sellQuantity,
- BigInt(100 * 1000),
- )
-
- const quantity =
- secondToken -
- ceilDivision(firstToken * secondToken, firstToken + sellQuantity - fee)
-
- return {
- quantity,
- info: buyInfo,
- }
-}
diff --git a/packages/swap/src/helpers/orders/amounts/getQuantityWithSlippage.test.ts b/packages/swap/src/helpers/orders/amounts/getQuantityWithSlippage.test.ts
deleted file mode 100644
index 8b06ac051a..0000000000
--- a/packages/swap/src/helpers/orders/amounts/getQuantityWithSlippage.test.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import {getQuantityWithSlippage} from './getQuantityWithSlippage'
-
-describe('getQuantityWithSlippage', () => {
- it('should calculate the correct quantity after applying slippage', () => {
- expect(getQuantityWithSlippage(1000n, 0.1)).toBe(999n)
- expect(getQuantityWithSlippage(1000n, 1)).toBe(990n)
- expect(getQuantityWithSlippage(1000n, 10)).toBe(900n)
- expect(getQuantityWithSlippage(1000n, 100)).toBe(0n)
- expect(getQuantityWithSlippage(500n, 0.5)).toBe(497n)
- })
-
- it('should return the original quantity when slippage is zero', () => {
- expect(getQuantityWithSlippage(1000n, 0)).toBe(1000n)
- })
-
- it('should return zero when the quantity is zero', () => {
- expect(getQuantityWithSlippage(0n, 10)).toBe(0n)
- })
-
- it('should handle negative slippage as 0%', () => {
- expect(getQuantityWithSlippage(1000n, -0.1)).toBe(1000n)
- })
-})
diff --git a/packages/swap/src/helpers/orders/amounts/getQuantityWithSlippage.ts b/packages/swap/src/helpers/orders/amounts/getQuantityWithSlippage.ts
deleted file mode 100644
index 7533b8191b..0000000000
--- a/packages/swap/src/helpers/orders/amounts/getQuantityWithSlippage.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {ceilDivision} from '../../../utils/ceilDivision'
-
-export const getQuantityWithSlippage = (quantity: bigint, slippage: number) => {
- const initialQuantity = BigInt(quantity)
-
- const slippageQuantity = ceilDivision(
- BigInt(Math.floor(10_000 * slippage)) * initialQuantity,
- BigInt(100 * 10_000),
- )
-
- const adjustedQuantity = initialQuantity - slippageQuantity
-
- return adjustedQuantity
-}
diff --git a/packages/swap/src/helpers/orders/amounts/getSellAmount.test.ts b/packages/swap/src/helpers/orders/amounts/getSellAmount.test.ts
deleted file mode 100644
index 1b67e289fb..0000000000
--- a/packages/swap/src/helpers/orders/amounts/getSellAmount.test.ts
+++ /dev/null
@@ -1,151 +0,0 @@
-import {Swap, Portfolio} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-import {getSellAmount} from './getSellAmount'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('getSellAmount', () => {
- it('should calculate the correct sell amount when buying tokenA', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.5', // 0.5%
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const buy: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.a,
- }
- const result = getSellAmount(pool, buy, tokenInfoMocks.b)
- expect(result.quantity).toBe(204n)
- expect(result.info).toEqual(tokenInfoMocks.b)
-
- const zeroResult = getSellAmount(
- pool,
- {...buy, quantity: 0n},
- tokenInfoMocks.b,
- )
- expect(zeroResult.quantity).toBe(0n)
- expect(zeroResult.info).toEqual(tokenInfoMocks.b)
-
- const limitedResult = getSellAmount(
- pool,
- buy,
- tokenInfoMocks.b,
- true,
- new BigNumber(2.1),
- )
- expect(limitedResult.quantity).toBe(210n)
- expect(limitedResult.info).toEqual(tokenInfoMocks.b)
-
- const zeroLimitResult = getSellAmount(
- {...pool, tokenA: {quantity: 0n, tokenId: 'tokenA.'}},
- buy,
- tokenInfoMocks.b,
- true,
- )
- expect(zeroLimitResult.quantity).toBe(0n)
- expect(zeroLimitResult.info).toEqual(tokenInfoMocks.b)
- })
-
- it('should calculate the correct sell amount when buying tokenB', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.5', // 0.5%
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const buy: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.b,
- }
- const result = getSellAmount(pool, buy, tokenInfoMocks.a)
- expect(result.quantity).toBe(53n)
- expect(result.info).toEqual(tokenInfoMocks.a)
-
- const limitedResult = getSellAmount(
- pool,
- buy,
- tokenInfoMocks.a,
- true,
- new BigNumber(2.1),
- )
- expect(limitedResult.quantity).toBe(210n)
- expect(limitedResult.info).toEqual(tokenInfoMocks.a)
- })
-
- it('should return a big number when there is not enough balance', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 1000000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '10',
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const buy: Portfolio.Token.Amount = {
- quantity: 1000001n,
- info: tokenInfoMocks.a,
- }
- const result = getSellAmount(pool, buy, tokenInfoMocks.b)
- expect(result.quantity).toBe(2222220000002n)
- expect(result.info).toEqual(tokenInfoMocks.b)
- })
-
- it('should calculate sell side as market without fee when initializing limit', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 1000000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 10000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.5',
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const buy: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.a,
- }
- const limitResult = getSellAmount(pool, buy, tokenInfoMocks.b, true)
- const marketResult = getSellAmount(pool, buy, tokenInfoMocks.b)
-
- // need less on sell side (fee is not included)
- expect(limitResult.quantity).toBe(1000n)
- expect(limitResult.info).toBe(tokenInfoMocks.b)
-
- // need more on sell side (fee is included)
- expect(marketResult.quantity).toBe(1008n)
- expect(marketResult.info).toBe(tokenInfoMocks.b)
- })
-})
diff --git a/packages/swap/src/helpers/orders/amounts/getSellAmount.ts b/packages/swap/src/helpers/orders/amounts/getSellAmount.ts
deleted file mode 100644
index c6998d1ee4..0000000000
--- a/packages/swap/src/helpers/orders/amounts/getSellAmount.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import {BigNumber} from 'bignumber.js'
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {ceilDivision} from '../../../utils/ceilDivision'
-import {getMarketPrice} from '../../prices/getMarketPrice'
-
-/**
- * Calculate the amount to sell based on the desired buy amount in a liquidity pool.
- *
- * @param pool - The liquidity pool.
- * @param buy - The desired buy amount.
- * @param isLimit - Optional limit type.
- * @param limit - Optional limit price.
- *
- * @returns The calculated sell amount
- * if the balance in the pool is insuficient it wont throw an error
- */
-export const getSellAmount = (
- pool: Swap.Pool,
- buy: Portfolio.Token.Amount,
- sellInfo: Portfolio.Token.Info,
- isLimit?: boolean,
- limit: BigNumber = new BigNumber(0),
-): Portfolio.Token.Amount => {
- const isBuyTokenA = buy.info.id === pool.tokenA.tokenId
- const tokenId = isBuyTokenA ? pool.tokenB.tokenId : pool.tokenA.tokenId
-
- if (buy.quantity === 0n) return {info: sellInfo, quantity: 0n}
-
- if (isLimit) {
- const limitPrice = limit.isZero() ? getMarketPrice(pool, tokenId) : limit
-
- return {
- info: sellInfo,
- quantity: limitPrice.isZero()
- ? 0n
- : BigInt(
- new BigNumber(buy.quantity.toString())
- .times(limitPrice)
- .integerValue(BigNumber.ROUND_CEIL)
- .toString(),
- ),
- }
- }
-
- const A = BigInt(pool.tokenA.quantity)
- const B = BigInt(pool.tokenB.quantity)
-
- const [firstToken, secondToken] = isBuyTokenA ? [A, B] : [B, A]
-
- const buyQuantity = BigInt(buy.quantity)
-
- const fee = BigInt(100 * 1_000) - BigInt(Number(pool.fee) * 1_000)
-
- const maxBuyQuantity =
- firstToken -
- (firstToken > buyQuantity ? buyQuantity : firstToken - BigInt(1))
-
- const quantity = ceilDivision(
- (ceilDivision(firstToken * secondToken + maxBuyQuantity, maxBuyQuantity) -
- secondToken) *
- BigInt(100 * 1_000),
- fee,
- )
-
- return {
- quantity,
- info: sellInfo,
- }
-}
diff --git a/packages/swap/src/helpers/orders/costs/getFrontendFee.test.ts b/packages/swap/src/helpers/orders/costs/getFrontendFee.test.ts
deleted file mode 100644
index 03fa060e70..0000000000
--- a/packages/swap/src/helpers/orders/costs/getFrontendFee.test.ts
+++ /dev/null
@@ -1,335 +0,0 @@
-import {App, Portfolio} from '@yoroi/types'
-import {AppApi} from '@yoroi/api'
-
-import {getFrontendFee} from './getFrontendFee'
-import {Quantities} from '../../../utils/quantities'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('getFrontendFee', () => {
- const milkHoldersDiscountTiers: ReadonlyArray =
- AppApi.mockGetFrontendFees.withFees.muesliswap!
-
- describe('selling side is primary token', () => {
- it('< 100 and whatever milk in balance', () => {
- // arrange
- const sell: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 99_999_999n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 999999999999999999n},
- ptAmount: sell,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- discountTier: undefined,
- })
- })
-
- it('>= 100 and milk in balance = 0', () => {
- // arrange
- const sellPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- ptAmount: sellPrimaryAmountOver99,
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 0n},
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_050_000n, // no milk, 100 ADA * 0.05% + 1 = 1.05 ADA
- },
- discountTier: milkHoldersDiscountTiers[2],
- })
- })
-
- it('>= 100 and milk in balance >= 100', () => {
- // arrange
- const sellPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 499n},
- ptAmount: sellPrimaryAmountOver99,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_025_000n, // hold 100-499 milk, 100 ADA * 0.025% + 1 = 1.025 ADA
- },
- discountTier: milkHoldersDiscountTiers[1],
- })
- })
-
- it('>= 100 and milk in balance >= 500', () => {
- // arrange
- const sellPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 500n},
- ptAmount: sellPrimaryAmountOver99,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_020_000n, // hold 500+ milk, 100 ADA * 0.020% + 1 = 1.02 ADA
- },
- discountTier: milkHoldersDiscountTiers[0],
- })
- })
- })
-
- describe('buying side is primary token', () => {
- it('< 100 and whatever milk in balance', () => {
- // arrange
- const buyPrimaryTokenAmount: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 99_999_999n,
- }
- // act
- const fee = getFrontendFee({
- ptAmount: buyPrimaryTokenAmount,
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 999999999999999999n},
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- discountTier: undefined,
- })
- })
-
- it('>= 100 and milk in balance = 0', () => {
- // arrange
- const buyPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- ptAmount: buyPrimaryAmountOver99,
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 0n},
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_050_000n, // no milk, 100 ADA * 0.05% + 1 = 1.05 ADA
- },
- discountTier: milkHoldersDiscountTiers[2],
- })
- })
-
- it('>= 100 and milk in balance >= 100', () => {
- // arrange
- const buyPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 499n},
- ptAmount: buyPrimaryAmountOver99,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_025_000n, // hold 100-499 milk, 100 ADA * 0.025% + 1 = 1.025 ADA
- },
- discountTier: milkHoldersDiscountTiers[1],
- })
- })
-
- it('>= 100 and milk in balance >= 500', () => {
- // arrange
- const buyPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 500n},
- ptAmount: buyPrimaryAmountOver99,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_020_000n, // hold 500+ milk, 100 ADA * 0.020% + 1= 1.02 ADA
- },
- discountTier: milkHoldersDiscountTiers[0],
- })
- })
- })
- it('should calc 0 fee if no tier', () => {
- // arrange
- const buyPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 999999999999999n},
- ptAmount: buyPrimaryAmountOver99,
- feeTiers: [],
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- discountTier: undefined,
- })
- })
-
- it('should add only the fixedFee when no variable', () => {
- // arrange
- const buyPrimaryAmountOver99: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 999999999999999n},
- ptAmount: buyPrimaryAmountOver99,
- feeTiers: [
- {
- fixedFee: '3000000',
- primaryTokenValueThreshold: Quantities.zero,
- secondaryTokenBalanceThreshold: Quantities.zero,
- variableFeeMultiplier: 0,
- },
- ],
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 3_000_000n,
- },
- discountTier: {
- fixedFee: '3000000',
- primaryTokenValueThreshold: Quantities.zero,
- secondaryTokenBalanceThreshold: Quantities.zero,
- variableFeeMultiplier: 0,
- },
- })
- })
-
- describe('neither sell nor buy are primary token, it should use the value in ADA (paired) of selling side', () => {
- it('< 100 and whatever milk in balance', () => {
- // arrange
- const sellValueInPrimaryToken: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 99_999_999n,
- }
- // act
- const fee = getFrontendFee({
- ptAmount: sellValueInPrimaryToken,
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 999999999999999999n},
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- discountTier: undefined,
- })
- })
- it('>= 100 and milk in balance = 0', () => {
- // arrange
- const sellValueInPrimaryToken: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- ptAmount: sellValueInPrimaryToken,
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 0n},
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_050_000n, // no milk, 100 ADA * 0.05% + 1 = 1.05 ADA
- },
- discountTier: milkHoldersDiscountTiers[2],
- })
- })
-
- it('>= 100 and milk in balance >= 100 (buy side higher)', () => {
- // arrange
- const sellValueInPrimaryToken: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 499n},
- ptAmount: sellValueInPrimaryToken,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_025_000n, // hold 100-499 milk, 100 ADA * 0.025% + 1= 1.025 ADA
- },
- discountTier: milkHoldersDiscountTiers[1],
- })
- })
-
- it('>= 100 and milk in balance >= 500 (50/50)', () => {
- // arrange
- const sellValueInPrimaryToken: Portfolio.Token.Amount = {
- info: tokenInfoMocks.pt,
- quantity: 100_000_000n,
- }
- // act
- const fee = getFrontendFee({
- lpTokenHeld: {info: tokenInfoMocks.lp, quantity: 500n},
- ptAmount: sellValueInPrimaryToken,
- feeTiers: milkHoldersDiscountTiers,
- })
- // assert
- expect(fee).toEqual({
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 1_020_000n, // hold 500+ milk, 100 ADA * 0.020% + 1 = 1.02 ADA
- },
- discountTier: milkHoldersDiscountTiers[0],
- })
- })
- })
-})
diff --git a/packages/swap/src/helpers/orders/costs/getFrontendFee.ts b/packages/swap/src/helpers/orders/costs/getFrontendFee.ts
deleted file mode 100644
index 4e3476c13c..0000000000
--- a/packages/swap/src/helpers/orders/costs/getFrontendFee.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import {App, Portfolio} from '@yoroi/types'
-import BigNumber from 'bignumber.js'
-
-/**
- * Calculates the frontend fee and selects a discount tier for a swap transaction.
- *
- * @param lpTokenHeld - The amount of LP (liquidity provider) token, is used to calc discount tier.
- * @param primaryTokenId - The ID of the primary token, available in the manager.
- * @param ptAmount - The value of the sell amount in terms of the primary token.
- * @param feeTiers - An array of discount feeTiers for lp token holders. Defaults to milkHoldersDiscountTiers.
- *
- * @returns An object containing the frontend fee and the selected discount tier.
- */
-export const getFrontendFee = ({
- lpTokenHeld,
- ptAmount,
- feeTiers,
-}: {
- lpTokenHeld?: Portfolio.Token.Amount
- feeTiers: ReadonlyArray
- ptAmount: Portfolio.Token.Amount
-}): Readonly<{
- fee: Portfolio.Token.Amount
- discountTier: App.FrontendFeeTier | undefined
-}> => {
- // identify the discount
- const discountTier = feeTiers.find(
- (tier) =>
- (lpTokenHeld?.quantity ?? 0n) >=
- BigInt(tier.secondaryTokenBalanceThreshold) &&
- ptAmount.quantity >= BigInt(tier.primaryTokenValueThreshold),
- )
-
- // calculate the fee
- const fee = BigInt(
- new BigNumber(ptAmount.quantity.toString())
- .times(discountTier?.variableFeeMultiplier ?? 0)
- .plus(discountTier?.fixedFee ?? 0)
- .integerValue(BigNumber.ROUND_CEIL)
- .toString(),
- )
-
- return {
- fee: {info: ptAmount.info, quantity: fee},
- discountTier,
- } as const
-}
diff --git a/packages/swap/src/helpers/orders/costs/getLiquidityProviderFee.test.ts b/packages/swap/src/helpers/orders/costs/getLiquidityProviderFee.test.ts
deleted file mode 100644
index 7da7338671..0000000000
--- a/packages/swap/src/helpers/orders/costs/getLiquidityProviderFee.test.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-import {getLiquidityProviderFee} from './getLiquidityProviderFee'
-
-describe('getLiquidityProviderFee', () => {
- it('should return zero when sell quantity is zero', () => {
- const result = getLiquidityProviderFee('0.03', {
- info: tokenInfoMocks.a,
- quantity: 0n,
- })
-
- expect(result).toEqual({
- info: tokenInfoMocks.a,
- quantity: 0n,
- })
- })
-
- it('should calculate provider fee correctly based on sell side', () => {
- const expectedFee = 300n
-
- const result = getLiquidityProviderFee('0.03', {
- info: tokenInfoMocks.a,
- quantity: 1000000n,
- })
-
- expect(result).toEqual({
- info: tokenInfoMocks.a,
- quantity: expectedFee,
- })
- })
-
- it('should calculate fee ceil up', () => {
- const expectedFee = 66n
-
- const result = getLiquidityProviderFee('66.666666', {
- info: tokenInfoMocks.a,
- quantity: 99n,
- })
-
- expect(result).toEqual({
- info: tokenInfoMocks.a,
- quantity: expectedFee,
- })
- })
-})
diff --git a/packages/swap/src/helpers/orders/costs/getLiquidityProviderFee.ts b/packages/swap/src/helpers/orders/costs/getLiquidityProviderFee.ts
deleted file mode 100644
index 70115a5293..0000000000
--- a/packages/swap/src/helpers/orders/costs/getLiquidityProviderFee.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {Portfolio} from '@yoroi/types'
-import {ceilDivision} from '../../../utils/ceilDivision'
-
-export const getLiquidityProviderFee = (
- poolFee: string,
- sell: Portfolio.Token.Amount,
-): Portfolio.Token.Amount => {
- const providerFee =
- sell.quantity === 0n
- ? 0n
- : ceilDivision(
- BigInt(Math.floor(Number(poolFee) * 1000)) * BigInt(sell.quantity),
- 100n * 1000n,
- )
-
- return {info: sell.info, quantity: providerFee}
-}
diff --git a/packages/swap/src/helpers/orders/factories/makeLimitOrder.test.ts b/packages/swap/src/helpers/orders/factories/makeLimitOrder.test.ts
deleted file mode 100644
index cc8e69911f..0000000000
--- a/packages/swap/src/helpers/orders/factories/makeLimitOrder.test.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {makeLimitOrder} from './makeLimitOrder'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('makeLimitOrder', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.a,
- }
- const buy: Portfolio.Token.Amount = {
- quantity: 200n,
- info: tokenInfoMocks.b,
- }
- const pool: Swap.Pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.5',
- fee: '0.3',
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const address = '0xAddressHere'
-
- it('should create a limit order with the correct parameters', () => {
- const slippage = 10
-
- const expectedBuyQuantity = 180n
-
- const result = makeLimitOrder(sell, buy, pool, slippage, address)
- expect(result.selectedPool).toEqual(pool)
- expect(result.address).toEqual(address)
- expect(result.slippage).toEqual(slippage)
- expect(result.amounts.sell.tokenId).toEqual(sell.info.id)
- expect(result.amounts.sell.quantity).toEqual(sell.quantity)
- expect(result.amounts.buy.tokenId).toEqual(buy.info.id)
- expect(result.amounts.buy.quantity).toEqual(expectedBuyQuantity)
- })
-
- it('should throw an error if the slippage is invalid', () => {
- expect(() => makeLimitOrder(sell, buy, pool, -1, address)).toThrow(
- 'Invalid slippage percentage',
- )
- expect(() => makeLimitOrder(sell, buy, pool, 101, address)).toThrow(
- 'Invalid slippage percentage',
- )
- })
-})
diff --git a/packages/swap/src/helpers/orders/factories/makeLimitOrder.ts b/packages/swap/src/helpers/orders/factories/makeLimitOrder.ts
deleted file mode 100644
index 86cc2340ef..0000000000
--- a/packages/swap/src/helpers/orders/factories/makeLimitOrder.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-import {getQuantityWithSlippage} from '../amounts/getQuantityWithSlippage'
-
-/**
- * Create a limit order with specified parameters.
- *
- * @param sell - The amount to sell.
- * @param buy - The amount to buy.
- * @param pool - The liquidity pool to use for the swap.
- * @param slippage - The maximum acceptable slippage percentage.
- * @param address - The address placing the order.
- *
- * @returns The created limit order data.
- */
-export const makeLimitOrder = (
- sell: Portfolio.Token.Amount,
- buy: Portfolio.Token.Amount,
- pool: Swap.Pool,
- slippage: number,
- address: string,
-): Swap.CreateOrderData => {
- if (slippage < 0 || slippage > 100)
- throw new Error('Invalid slippage percentage')
-
- const quantity = getQuantityWithSlippage(buy.quantity, slippage)
-
- return {
- selectedPool: pool,
- address,
- slippage,
- amounts: {
- sell: {
- tokenId: sell.info.id,
- quantity: sell.quantity,
- },
- buy: {
- tokenId: buy.info.id,
- quantity,
- },
- },
- }
-}
diff --git a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.test.ts b/packages/swap/src/helpers/orders/factories/makeOrderCalculations.test.ts
deleted file mode 100644
index c72fb6bff7..0000000000
--- a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.test.ts
+++ /dev/null
@@ -1,3472 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {AppApi} from '@yoroi/api'
-
-import {makeOrderCalculations} from './makeOrderCalculations'
-import {mocks} from '../../mocks'
-import {SwapState} from '../../../translators/reactjs/state/state'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('makeOrderCalculations', () => {
- const frontendFeeTiers = AppApi.mockGetFrontendFees.withFees.muesliswap!
-
- it('should calculate all fees and amounts correctly (case 1, sell A)', () => {
- const pool = mocks.mockedPools5[0] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 148894355282n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- },
- fee: {
- quantity: 6000000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 30000000n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 10000000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 148894355282n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 10008000000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- actualPrice: '0.0671617132',
- base: '0.0669355289',
- difference: '0.4181839969',
- market: '0.0669355289',
- priceImpact: '0.3379136660',
- withFees: '0.0672154426',
- withFeesAndSlippage: '0.0672154426',
- withSlippage: '0.0671617132',
- },
- pool: pools[0]!,
- })
- })
- it('should calculate all fees and amounts correctly (case 2, sell B, reversed case 1) ', () => {
- const pool = mocks.mockedPools5[1] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
-
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 148894355282n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- },
- fee: {
- quantity: 6000000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 30000000n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 10000000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 148894355282n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 10008000000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '0.0669355289',
- market: '0.0669355289',
- actualPrice: '0.0671617132',
- withSlippage: '0.0671617132',
- withFees: '0.0672154426',
- withFeesAndSlippage: '0.0672154426',
- difference: '0.4181839969',
- priceImpact: '0.3379136660',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 3, buy B)', () => {
- const pool = mocks.mockedPools5[0] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 148894355268n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
-
- expect(calculation).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 148894355268n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 148894355268n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- },
- fee: {
- quantity: 6000000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 30000000n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 10000000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 148894355268n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 10008000000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '0.0669355289',
- market: '0.0669355289',
- actualPrice: '0.0671617132',
- withSlippage: '0.0671617132',
- withFees: '0.0672154426',
- withFeesAndSlippage: '0.0672154426',
- difference: '0.4181840064',
- priceImpact: '0.3379136754',
- },
- pool: pool,
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 148894355268n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
-
- expect(calculation).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 148894355268n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 10000000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 148894355268n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- },
- fee: {
- quantity: 6000000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 30000000n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 10000000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 148894355268n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 10008000000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '0.0669355289',
- market: '0.0669355289',
- actualPrice: '0.0671617132',
- withSlippage: '0.0671617132',
- withFees: '0.0672154426',
- withFeesAndSlippage: '0.0672154426',
- difference: '0.4181840064',
- priceImpact: '0.3379136754',
- },
- pool: pool,
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 5, with slippage)', () => {
- const pool = mocks.mockedPools5[2] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 50
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 50,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 50n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
-
- hasSupply: true,
- prices: {
- base: '0.9900990099',
- market: '0.9900990099',
- actualPrice: '1.0000000000',
- withSlippage: '2.0000000000',
- withFees: '1.0000000000',
- withFeesAndSlippage: '2.0000000000',
- difference: '1.0000000000',
- priceImpact: '1.0000000000',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 6, zero supply)', () => {
- const pool = mocks.mockedPools5[3] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 50
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 50,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 50
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 50,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '-100.0000000000',
- priceImpact: '-100.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 1n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: false,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '0.0100000000',
- withSlippage: '0.0100000000',
- withFees: '0.0100000000',
- withFeesAndSlippage: '0.0100000000',
- difference: '-99.0000000000',
- priceImpact: '-99.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 1n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '100.0000000000',
- withSlippage: '100.0000000000',
- withFees: '100.0000000000',
- withFeesAndSlippage: '100.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 1n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0100000000',
- withSlippage: '0.0100000000',
- withFees: '0.0100000000',
- withFeesAndSlippage: '0.0100000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 1n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 1n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '100.0000000000',
- withSlippage: '100.0000000000',
- withFees: '100.0000000000',
- withFeesAndSlippage: '100.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 100n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: undefined,
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
-
- expect(calculations[0]).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 1n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: false,
- prices: {
- base: '0.0000000000',
- market: '0.0000000000',
- actualPrice: '0.0100000000',
- withSlippage: '0.0100000000',
- withFees: '0.0100000000',
- withFeesAndSlippage: '0.0100000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '2',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '2',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 200n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '2.0000000000',
- market: '1.0000000000',
- actualPrice: '2.0000000000',
- withSlippage: '2.0000000000',
- withFees: '2.0000000000',
- withFeesAndSlippage: '2.0000000000',
- difference: '0.0000000000',
- priceImpact: '100.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '2',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '2',
- amounts: {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 200n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '2.0000000000',
- market: '1.0000000000',
- actualPrice: '2.0000000000',
- withSlippage: '2.0000000000',
- withFees: '2.0000000000',
- withFeesAndSlippage: '2.0000000000',
- difference: '0.0000000000',
- priceImpact: '100.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '2',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'buy',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '2',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.b,
- },
- ptTotalValueSpent: {
- quantity: 200n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '2.0000000000',
- market: '1.0000000000',
- actualPrice: '2.0000000000',
- withSlippage: '2.0000000000',
- withFees: '2.0000000000',
- withFeesAndSlippage: '2.0000000000',
- difference: '0.0000000000',
- priceImpact: '100.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '2',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '2',
- amounts: {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 200n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 200n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '2.0000000000',
- market: '1.0000000000',
- actualPrice: '2.0000000000',
- withSlippage: '2.0000000000',
- withFees: '2.0000000000',
- withFeesAndSlippage: '2.0000000000',
- difference: '0.0000000000',
- priceImpact: '100.0000000000',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 21, no FEF test)', () => {
- const pool = mocks.mockedPools5[7] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 99999999n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '1',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: undefined,
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '1',
- amounts: {
- sell: {
- quantity: 99999999n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: undefined,
- },
- sides: {
- sell: {
- quantity: 99999999n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 99999999n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 99999999n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 99999999n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '1.0000000000',
- withSlippage: '1.0000000000',
- withFees: '1.0000000000',
- withFeesAndSlippage: '1.0000000000',
- difference: '0.0000000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 22, full FEF test)', () => {
- const pool = mocks.mockedPools5[7] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '1',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '1',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '0',
- variableFeeMultiplier: 0.0005,
- },
- fee: {
- quantity: 1050000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 1050000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 101050000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '1.0000000000',
- withSlippage: '1.0000000000',
- withFees: '1.0105000000',
- withFeesAndSlippage: '1.0105000000',
- difference: '1.0500000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '1',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 100n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '1',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 100n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '100',
- variableFeeMultiplier: 0.00025,
- },
- fee: {
- quantity: 1025000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 1025000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 101025000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '1.0000000000',
- withSlippage: '1.0000000000',
- withFees: '1.0102500000',
- withFeesAndSlippage: '1.0102500000',
- difference: '1.0250000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } 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
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '1',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 500n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '1',
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 500n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: {
- fixedFee: '1000000',
- primaryTokenValueThreshold: '100000000',
- secondaryTokenBalanceThreshold: '500',
- variableFeeMultiplier: 0.0002,
- },
- fee: {
- quantity: 1020000n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 1020000n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: {
- quantity: 101020000n,
- info: tokenInfoMocks.pt,
- },
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '1.0000000000',
- withSlippage: '1.0000000000',
- withFees: '1.0102000000',
- withFeesAndSlippage: '1.0102000000',
- difference: '1.0200000000',
- priceImpact: '0.0000000000',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 25, zero sell)', () => {
- const pool = mocks.mockedPools5[7] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'limit',
- amounts: amounts,
- limitPrice: '1',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'limit',
- limitPrice: '1',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '-100.0000000000',
- priceImpact: '-100.0000000000',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 26, zero buy)', () => {
- const pool = mocks.mockedPools5[7] as Swap.Pool
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
-
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: '1',
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- side: 'buy',
- frontendFeeTiers,
- })
- const calculation: Swap.OrderCalculation = calculations[0]!
- expect(calculation).toStrictEqual({
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: '1',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '-100.0000000000',
- priceImpact: '-100.0000000000',
- },
- pool: pools[0],
- } as Swap.OrderCalculation)
- })
- it('should calculate all fees and amounts correctly (case 27, zero pt sell side)', () => {
- const pool: Swap.Pool = mocks.mockedPools7[1]!
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- side: 'buy',
- frontendFeeTiers,
- })
- const expectedCalculation: Swap.OrderCalculation = {
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.pt,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '0.5000000000',
- market: '0.5000000000',
- actualPrice: '0.0000000000',
- withSlippage: '0.0000000000',
- withFees: '0.0000000000',
- withFeesAndSlippage: '0.0000000000',
- difference: '-100.0000000000',
- priceImpact: '-100.0000000000',
- },
- pool: pool,
- }
- expect(calculations[0]).toStrictEqual(expectedCalculation)
- })
- it('should calculate fees and amounts correctly (case 28, pt at buy side)', () => {
- const pool: Swap.Pool = mocks.mockedPools7[1]!
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 1000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.a,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const expectedCalculation: Swap.OrderCalculation = {
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 1000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 50n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 1000000n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 199n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.a,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 199n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '0.5000000000',
- market: '0.5000000000',
- actualPrice: '5025.1256281407',
- withSlippage: '5025.1256281407',
- withFees: '5025.1256281407',
- withFeesAndSlippage: '5025.1256281407',
- difference: '1004925.1256281407',
- priceImpact: '1004925.1256281407',
- },
- pool: pool,
- }
- expect(calculations[0]).toStrictEqual(expectedCalculation)
- })
- it('should calculate fees and amounts correctly (case 29, price impact, zero pool fee, sell)', () => {
- const pool: Swap.Pool = mocks.mockedPools8[0]!
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 250n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.a,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const expectedCalculation: Swap.OrderCalculation = {
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 250n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 250n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.a,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '1.2500000000',
- withSlippage: '1.2500000000',
- withFees: '1.2500000000',
- withFeesAndSlippage: '1.2500000000',
- difference: '25.0000000000',
- priceImpact: '25.0000000000',
- },
- pool: pool,
- }
- expect(calculations[0]).toStrictEqual(expectedCalculation)
- })
- it('should calculate fees and amounts correctly (case 30, price impact, with pool fee, sell)', () => {
- const pool: Swap.Pool = mocks.mockedPools8[1]!
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 500n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- }
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.a,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- side: 'sell',
- frontendFeeTiers,
- })
- const expectedCalculation: Swap.OrderCalculation = {
- order: {
- side: 'sell',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 500n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 500n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- liquidityFee: {
- quantity: 250n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.a,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '2.5000000000',
- withSlippage: '2.5000000000',
- withFees: '2.5000000000',
- withFeesAndSlippage: '2.5000000000',
- difference: '150.0000000000',
- priceImpact: '150.0000000000',
- },
- pool: pool,
- }
- expect(calculations[0]).toStrictEqual(expectedCalculation)
- })
- it('should calculate fees and amounts correctly (case 31, price impact, zero pool fee, buy)', () => {
- const pool: Swap.Pool = mocks.mockedPools8[0]!
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- }
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.a,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- side: 'buy',
- frontendFeeTiers,
- })
- const expectedCalculation: Swap.OrderCalculation = {
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 251n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- liquidityFee: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.a,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '1.2550000000',
- withSlippage: '1.2550000000',
- withFees: '1.2550000000',
- withFeesAndSlippage: '1.2550000000',
- difference: '25.5000000000',
- priceImpact: '25.5000000000',
- },
- pool: pool,
- }
- expect(calculations[0]).toStrictEqual(expectedCalculation)
- })
- it('should calculate fees and amounts correctly (case 32, price impact, with pool fee, buy)', () => {
- const pool: Swap.Pool = mocks.mockedPools8[1]!
- const pools = [pool]
- const amounts: SwapState['orderData']['amounts'] = {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- }
- const slippage = 0
- const calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: amounts,
- limitPrice: undefined,
- slippage: slippage,
- pools: pools,
- tokens: {
- ptInfo: tokenInfoMocks.a,
- priceDenomination: 0,
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- side: 'buy',
- frontendFeeTiers,
- })
- const expectedCalculation: Swap.OrderCalculation = {
- order: {
- side: 'buy',
- slippage: 0,
- orderType: 'market',
- limitPrice: undefined,
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- },
- lpTokenHeld: {
- quantity: 0n,
- info: tokenInfoMocks.lp,
- },
- },
- sides: {
- sell: {
- quantity: 502n,
- info: tokenInfoMocks.b,
- },
- buy: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- batcherFee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- deposit: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- frontendFeeInfo: {
- discountTier: undefined,
- fee: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- },
- liquidityFee: {
- quantity: 251n,
- info: tokenInfoMocks.b,
- },
-
- ptTotalRequired: {
- info: tokenInfoMocks.a,
- quantity: 0n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 200n,
- info: tokenInfoMocks.a,
- },
- ptTotalValueSpent: undefined,
- hasSupply: true,
- prices: {
- base: '1.0000000000',
- market: '1.0000000000',
- actualPrice: '2.5100000000',
- withSlippage: '2.5100000000',
- withFees: '2.5100000000',
- withFeesAndSlippage: '2.5100000000',
- difference: '151.0000000000',
- priceImpact: '151.0000000000',
- },
- pool: pool,
- }
- expect(calculations[0]).toStrictEqual(expectedCalculation)
- })
-})
diff --git a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts b/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts
deleted file mode 100644
index e875dde2f6..0000000000
--- a/packages/swap/src/helpers/orders/factories/makeOrderCalculations.ts
+++ /dev/null
@@ -1,236 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-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'
-
-export const makeOrderCalculations = ({
- orderType,
- amounts,
- limitPrice,
- slippage,
- pools,
- lpTokenHeld,
- side,
- frontendFeeTiers,
- tokens,
- priceDecimals = 10,
-}: 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 buy =
- side === 'sell'
- ? getBuyAmount(
- pool,
- amounts.sell!,
- amounts.buy!.info,
- isLimit,
- maybeLimitPrice,
- )
- : amounts.buy!
- const sell =
- side === 'buy'
- ? getSellAmount(
- pool,
- amounts.buy!,
- amounts.sell!.info,
- isLimit,
- maybeLimitPrice,
- )
- : amounts.sell!
-
- const marketPrice = getMarketPrice(pool, sell.info.id)
- // recalculate price base, limit is user's input, market from pool
- const priceBase = maybeLimitPrice ?? marketPrice
-
- // calculate buy quantity with slippage
- const buyAmountWithSlippage: Portfolio.Token.Amount = {
- quantity: getQuantityWithSlippage(buy.quantity, slippage),
- info: buy.info,
- }
-
- const isBuyTokenA = buy.info.id === pool.tokenA.tokenId
-
- // pools without enough supply will be filtered out
- const poolSupply = isBuyTokenA ? pool.tokenA.quantity : pool.tokenB.quantity
- const supplyRequired =
- (buy.quantity > 0n || sell.quantity > 0n) && poolSupply === 0n
- const hasSupply = buy.quantity <= poolSupply && !supplyRequired
-
- const sellQuantity = new BigNumber(sell.quantity.toString())
- const buyQuantity = new BigNumber(buy.quantity.toString())
- const marketPriceQuantity = new BigNumber(marketPrice)
-
- const actualPriceQuantity = buyQuantity.isZero()
- ? new BigNumber(0)
- : sellQuantity.dividedBy(buyQuantity)
-
- const priceImpact = marketPrice.isZero()
- ? marketPrice
- : actualPriceQuantity
- .minus(marketPriceQuantity)
- .dividedBy(marketPriceQuantity)
- .times(100)
-
- // lf is sell side % of quantity ie. XToken 100 * 1% = 1 XToken
- const liquidityFee: Portfolio.Token.Amount = getLiquidityProviderFee(
- pool.fee,
- sell,
- )
-
- // whether sell or buy is PT, then we use the quantity as frontend fee base
- // otherwise we derive from the ptPrice of the pool of the sell side
- const ptPriceSell = isBuyTokenA
- ? new BigNumber(pool.ptPriceTokenB)
- : new BigNumber(pool.ptPriceTokenA)
-
- const sellInPtTerms = BigInt(
- sellQuantity
- .multipliedBy(ptPriceSell)
- .integerValue(BigNumber.ROUND_DOWN)
- .toFixed(0),
- )
-
- // ffee is based on PT value range + LP holding range
- const frontendFeeInfo = getFrontendFee({
- lpTokenHeld,
- ptAmount: {
- info: tokens.ptInfo!,
- quantity: sellInPtTerms,
- },
- feeTiers: frontendFeeTiers,
- })
-
- // transform fees in terms of sell side quantity * pt price (unit of fees)
- // it applies market price always
- const feeInSellSideQuantities = {
- batcherFee: ptPriceSell.isZero()
- ? new BigNumber(0)
- : new BigNumber(pool.batcherFee.quantity.toString())
- .dividedBy(ptPriceSell)
- .integerValue(BigNumber.ROUND_CEIL),
- frontendFee: ptPriceSell.isZero()
- ? new BigNumber(0)
- : new BigNumber(frontendFeeInfo.fee.quantity.toString())
- .dividedBy(ptPriceSell)
- .integerValue(BigNumber.ROUND_CEIL),
- }
-
- const priceWithSlippage =
- buyAmountWithSlippage.quantity === 0n
- ? new BigNumber(0)
- : sellQuantity.dividedBy(buyAmountWithSlippage.quantity.toString())
-
- // add up all that's being sold in sell terms
- const sellWithFees = sellQuantity
- .plus(feeInSellSideQuantities.batcherFee)
- .plus(feeInSellSideQuantities.frontendFee)
-
- const priceWithFees = buyQuantity.isZero()
- ? new BigNumber(0)
- : sellWithFees.dividedBy(buyQuantity)
-
- const priceWithFeesAndSlippage =
- buyAmountWithSlippage.quantity === 0n
- ? new BigNumber(0)
- : sellWithFees.dividedBy(buyAmountWithSlippage.quantity.toString())
-
- // always based, if is limit it can lead to a weird percentage
- const priceDifference = priceBase.isZero()
- ? new BigNumber(0)
- : priceWithFees.minus(priceBase).dividedBy(priceBase).times(100)
-
- // fees + ffee + slippage
- const withFees = new BigNumber(priceWithFees)
- const withFeesAndSlippage = new BigNumber(priceWithFeesAndSlippage)
- const difference = new BigNumber(priceDifference)
-
- const ptTotalRequired: Portfolio.Token.Amount = {
- info: tokens.ptInfo!,
- quantity:
- pool.batcherFee.quantity +
- pool.deposit.quantity +
- frontendFeeInfo.fee.quantity,
- }
-
- const ptTotalValueSpent: Portfolio.Token.Amount | undefined =
- sellInPtTerms === 0n
- ? undefined
- : {
- info: tokens.ptInfo!,
- quantity:
- pool.batcherFee.quantity +
- frontendFeeInfo.fee.quantity +
- sellInPtTerms,
- }
-
- const batcherFee: Portfolio.Token.Amount = {
- quantity: pool.batcherFee.quantity,
- info: tokens.ptInfo!,
- }
-
- const deposit: Portfolio.Token.Amount = {
- quantity: pool.deposit.quantity,
- info: tokens.ptInfo!,
- }
-
- const result: Swap.OrderCalculation = {
- order: {
- side,
- slippage,
- orderType,
- limitPrice,
- amounts: {
- sell: amounts.sell!,
- buy: amounts.buy!,
- },
- lpTokenHeld,
- },
- sides: {
- buy,
- sell,
- },
- cost: {
- batcherFee,
- deposit,
- frontendFeeInfo,
- liquidityFee,
- ptTotalRequired,
- },
- buyAmountWithSlippage,
- hasSupply,
- ptTotalValueSpent,
- prices: {
- base: priceBase.toFixed(priceDecimals, BigNumber.ROUND_DOWN),
- market: marketPrice.toFixed(priceDecimals, BigNumber.ROUND_DOWN),
- actualPrice: actualPriceQuantity.toFixed(
- priceDecimals,
- BigNumber.ROUND_DOWN,
- ),
- withSlippage: priceWithSlippage.toFixed(
- priceDecimals,
- BigNumber.ROUND_DOWN,
- ),
- withFees: withFees.toFixed(priceDecimals, BigNumber.ROUND_DOWN),
- withFeesAndSlippage: withFeesAndSlippage.toFixed(
- priceDecimals,
- BigNumber.ROUND_DOWN,
- ),
- difference: difference.toFixed(priceDecimals, BigNumber.ROUND_DOWN),
- priceImpact: priceImpact.toFixed(priceDecimals, BigNumber.ROUND_DOWN),
- },
- pool,
- } as const
-
- return result
- })
-
- return calculations
-}
diff --git a/packages/swap/src/helpers/orders/factories/makePossibleMarketOrder.test.ts b/packages/swap/src/helpers/orders/factories/makePossibleMarketOrder.test.ts
deleted file mode 100644
index e3a08f1a1e..0000000000
--- a/packages/swap/src/helpers/orders/factories/makePossibleMarketOrder.test.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {makePossibleMarketOrder} from './makePossibleMarketOrder'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('makePossibleMarketOrder', () => {
- it('should create a possible market order with the best pool', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 100n,
- info: tokenInfoMocks.a,
- }
- const buy: Portfolio.Token.Amount = {
- quantity: 177n,
- info: tokenInfoMocks.b,
- }
- const bestPool1: Swap.Pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.3',
- provider: 'minswap',
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
-
- const slippage = 10
- const address = '0xAddressHere'
-
- const result = makePossibleMarketOrder(
- sell,
- buy,
- bestPool1,
- slippage,
- address,
- )
-
- expect(result?.selectedPool).toEqual(bestPool1)
- expect(result?.slippage).toEqual(slippage)
- expect(result?.address).toEqual(address)
- expect(result?.amounts.buy.quantity).toEqual(buy.quantity)
- })
-})
diff --git a/packages/swap/src/helpers/orders/factories/makePossibleMarketOrder.ts b/packages/swap/src/helpers/orders/factories/makePossibleMarketOrder.ts
deleted file mode 100644
index f97f36dfef..0000000000
--- a/packages/swap/src/helpers/orders/factories/makePossibleMarketOrder.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {getBuyAmount} from '../amounts/getBuyAmount'
-import {getQuantityWithSlippage} from '../amounts/getQuantityWithSlippage'
-
-/**
- * Create a possible market order choosing the best pool based on the given parameters.
- *
- * @param sell - The amount to sell.
- * @param buy - The desired buy amount.
- * @param bestPool - best liquidity pool.
- * @param slippage - Maximum acceptable slippage in percentage.
- * @param address - The address placing the order.
- *
- * @returns The best market order data
- */
-export const makePossibleMarketOrder = (
- sell: Portfolio.Token.Amount,
- buy: Portfolio.Token.Amount,
- bestPool: Readonly,
- slippage: number,
- address: string,
-): Swap.CreateOrderData | undefined => {
- const rawBuy = getBuyAmount(bestPool, sell, buy.info)
-
- const buyQuantityWithSlippage = getQuantityWithSlippage(
- rawBuy.quantity,
- slippage,
- )
-
- const newOrder: Swap.CreateOrderData = {
- selectedPool: bestPool,
- slippage,
- amounts: {
- sell: {
- tokenId: sell.info.id,
- quantity: sell.quantity,
- },
- buy: {
- tokenId: buy.info.id,
- quantity: buyQuantityWithSlippage,
- },
- },
- address,
- }
-
- return newOrder
-}
diff --git a/packages/swap/src/helpers/pools/getBestBuyPool.test.ts b/packages/swap/src/helpers/pools/getBestBuyPool.test.ts
deleted file mode 100644
index 3f7a6a5528..0000000000
--- a/packages/swap/src/helpers/pools/getBestBuyPool.test.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {getBestBuyPool} from './getBestBuyPool'
-import {getBuyAmount} from '../orders/amounts/getBuyAmount'
-import {mocks} from '../mocks'
-import {tokenInfoMocks} from '../../tokenInfo.mocks'
-
-describe('getBestBuyPool', () => {
- it('should return pool with maximin possible tokens to buy', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 10000000000n,
- info: tokenInfoMocks.b,
- }
-
- const pools = mocks.mockedPools1
- const bestBuyPool = getBestBuyPool(pools, sell, tokenInfoMocks.a)
- if (bestBuyPool) {
- expect(bestBuyPool.provider).toBe('minswap')
- const buyAmount = getBuyAmount(bestBuyPool, sell, tokenInfoMocks.a)
- expect(buyAmount.quantity).toBe(693300972n)
- } else {
- fail('bestBuyPool undefined')
- }
- })
-
- it('should return pool with maximin possible tokens to buy (case 2)', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 1000000000n,
- info: tokenInfoMocks.a,
- }
-
- const pools = mocks.mockedPools2
- const bestBuyPool = getBestBuyPool(pools, sell, tokenInfoMocks.b)
- expect(bestBuyPool?.provider).toBe('minswap')
- const buyAmount = getBuyAmount(bestBuyPool!, sell, tokenInfoMocks.b)
- expect(buyAmount.quantity).toBe(14336451239n)
- })
-
- it('should return undefined if sell amount is 0', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 0n,
- info: tokenInfoMocks.a,
- }
-
- expect(
- getBestBuyPool([mocks.mockedPools1[0]!], sell, tokenInfoMocks.b),
- ).toBeUndefined()
- })
-
- it('should return undefined if the buy quantity turns to be 0', () => {
- const pools: Array = [
- {
- tokenA: {quantity: 1000000000000000000000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 1n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'muesliswap_v2',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- ]
-
- const sell: Portfolio.Token.Amount = {
- quantity: 1n,
- info: tokenInfoMocks.a,
- }
-
- expect(getBestBuyPool(pools, sell, tokenInfoMocks.b)).toBeUndefined()
- })
-
- it('should return undefined if pools list is empty', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 1n,
- info: tokenInfoMocks.a,
- }
-
- expect(getBestBuyPool([], sell, tokenInfoMocks.b)).toBeUndefined()
- })
-})
diff --git a/packages/swap/src/helpers/pools/getBestBuyPool.ts b/packages/swap/src/helpers/pools/getBestBuyPool.ts
deleted file mode 100644
index 91753b30a0..0000000000
--- a/packages/swap/src/helpers/pools/getBestBuyPool.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {getBuyAmount} from '../orders/amounts/getBuyAmount'
-import {getPriceAfterFee} from '../prices/getPriceAfterFee'
-import {BigNumber} from 'bignumber.js'
-
-/**
- * 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.
- * @param buyInfo - The token info of the token to buy.
- *
- * @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: Portfolio.Token.Amount,
- buyInfo: Portfolio.Token.Info,
-): Swap.Pool | undefined => {
- if (pools.length === 0 || sell.quantity === 0n) return undefined
-
- let bestPool: Swap.Pool | undefined
- let bestPrice = new BigNumber(0)
-
- for (const pool of pools) {
- const buy = getBuyAmount(pool, sell, buyInfo)
- if (buy.quantity === 0n) continue
-
- const isSellTokenA = sell.info.id === pool.tokenA.tokenId
- const [amountA, amountB] = isSellTokenA ? [sell, buy] : [buy, sell]
- const price = getPriceAfterFee(
- pool,
- amountA.quantity,
- amountB.quantity,
- sell.info.id,
- )
-
- if (bestPool === undefined) {
- bestPool = pool
- bestPrice = price
- continue
- }
-
- if (price < bestPrice) {
- bestPool = pool
- bestPrice = price
- }
- }
-
- return bestPool
-}
diff --git a/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts b/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts
deleted file mode 100644
index 7b9312ed39..0000000000
--- a/packages/swap/src/helpers/pools/getBestPoolCalculation.test.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {tokenInfoMocks} from '../../tokenInfo.mocks'
-import {mocks} from '../mocks'
-import {getBestPoolCalculation} from './getBestPoolCalculation'
-
-describe('getBestPoolCalculation', () => {
- it('should return the best pool calculation', () => {
- const bestCalculation = getBestPoolCalculation(
- mocks.mockedOrderCalculations1,
- )
-
- expect(bestCalculation?.pool.poolId).toBe('3')
- })
-
- it('should skip no supply pools', () => {
- const calculations: Array = [
- {
- order: {
- side: 'buy',
- slippage: 10,
- orderType: 'market',
- amounts: {
- sell: {
- quantity: 0n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- },
- },
- sides: {
- buy: {
- quantity: 100000001n,
- info: tokenInfoMocks.b,
- },
- sell: {
- quantity: 7157210n,
- info: tokenInfoMocks.a,
- },
- },
- cost: {
- ptTotalRequired: {
- quantity: 4500000n,
- info: tokenInfoMocks.pt,
- },
- batcherFee: {
- quantity: 2500000n,
- info: tokenInfoMocks.pt,
- },
- deposit: {
- quantity: 2000000n,
- info: tokenInfoMocks.pt,
- },
- frontendFeeInfo: {
- fee: {
- info: tokenInfoMocks.pt,
- quantity: 0n,
- },
- },
- liquidityFee: {
- info: tokenInfoMocks.a,
- quantity: 3579n,
- },
- },
- buyAmountWithSlippage: {
- quantity: 90000000n,
- info: tokenInfoMocks.b,
- },
- hasSupply: false,
- prices: {
- base: '0.07101454479564951518',
- market: '0.07101454479564951518',
- actualPrice: '0',
- withSlippage: '0.07952455555555555556',
- withFees: '0.09657209903427900966',
- withFeesAndSlippage: '0.10730233333333333333',
- difference: '35.989182655713084861',
- priceImpact: '0',
- },
- pool: {
- tokenA: {
- quantity: 973669994n,
- tokenId: tokenInfoMocks.a.id,
- },
- tokenB: {
- quantity: 13710853133n,
- tokenId: tokenInfoMocks.b.id,
- },
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.05',
- provider: 'sundaeswap',
- batcherFee: {
- quantity: 2500000n,
- tokenId: '.',
- },
- deposit: {
- quantity: 2000000n,
- tokenId: '.',
- },
- poolId: '6',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- },
- ]
- const bestCalculation = getBestPoolCalculation(calculations)
-
- expect(bestCalculation).toBeUndefined()
- })
-})
diff --git a/packages/swap/src/helpers/pools/getBestPoolCalculation.ts b/packages/swap/src/helpers/pools/getBestPoolCalculation.ts
deleted file mode 100644
index 909d14cb99..0000000000
--- a/packages/swap/src/helpers/pools/getBestPoolCalculation.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import {Swap} from '@yoroi/types'
-import BigNumber from 'bignumber.js'
-
-export const getBestPoolCalculation = (
- calculations: Array,
-): Swap.OrderCalculation | undefined => {
- return calculations.reduce(
- (
- best: Swap.OrderCalculation | undefined,
- current,
- ): Swap.OrderCalculation | undefined => {
- if (!current.hasSupply) return best
-
- if (best === undefined) return current
-
- const bestWithFees = new BigNumber(best.prices.withFees)
-
- if (
- bestWithFees.isZero() ||
- bestWithFees.isGreaterThan(current.prices.withFees)
- )
- return current
-
- return best
- },
- undefined,
- )
-}
diff --git a/packages/swap/src/helpers/pools/getBestSellPool.test.ts b/packages/swap/src/helpers/pools/getBestSellPool.test.ts
deleted file mode 100644
index 18d8c0f6c1..0000000000
--- a/packages/swap/src/helpers/pools/getBestSellPool.test.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {getBestSellPool} from './getBestSellPool'
-import {getSellAmount} from '../orders/amounts/getSellAmount'
-import {mocks} from '../mocks'
-import {tokenInfoMocks} from '../../tokenInfo.mocks'
-
-describe('getBestSellPool', () => {
- it('should return pool with min possible tokens to sell', () => {
- const buy: Portfolio.Token.Amount = {
- quantity: 1000000000n,
- info: tokenInfoMocks.b,
- }
-
- const pools = mocks.mockedPools3
- const bestSellPool = getBestSellPool(pools, buy, tokenInfoMocks.a)
-
- expect(bestSellPool?.provider).toBe('minswap')
- const sellAmount = getSellAmount(bestSellPool!, buy, tokenInfoMocks.a)
- expect(sellAmount.quantity).toBe(69709507n)
- })
-
- it('should return pool with min possible tokens to sell (opposite test)', () => {
- const buy: Portfolio.Token.Amount = {
- quantity: 1000000000n,
- info: tokenInfoMocks.a,
- }
-
- const pools = mocks.mockedPools4
- const bestSellPool = getBestSellPool(pools, buy, tokenInfoMocks.b)
-
- if (bestSellPool) {
- expect(bestSellPool.provider).toBe('minswap')
- const sellAmount = getSellAmount(bestSellPool, buy, tokenInfoMocks.b)
- expect(sellAmount.quantity).toBe(69709507n)
- } else {
- fail('bestSellPool is undefined')
- }
- })
-
- it('should return undefined if buy amount is 0', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 0n,
- info: tokenInfoMocks.a,
- }
-
- expect(
- getBestSellPool([mocks.mockedPools4[0]!], sell, tokenInfoMocks.b),
- ).toBeUndefined()
- })
-
- it('should return undefined if the sell quantity turns to be 0', () => {
- const pools: Array = [
- {
- tokenA: {quantity: 0n, tokenId: 'tokenA.'},
- tokenB: {quantity: 1n, tokenId: 'tokenB.'},
- ptPriceTokenA: '1',
- ptPriceTokenB: '0.0695404765',
- fee: '0.3', // 0.3%
- provider: 'muesliswap_v2',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 2000000n, tokenId: '.'},
- poolId: '1',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- },
- ]
-
- const buy: Portfolio.Token.Amount = {
- quantity: 1000000000000000n,
- info: tokenInfoMocks.a,
- }
-
- expect(getBestSellPool(pools, buy, tokenInfoMocks.b)).toBeUndefined()
- })
-
- it('should return undefined if pools list is empty', () => {
- const sell: Portfolio.Token.Amount = {
- quantity: 1n,
- info: tokenInfoMocks.a,
- }
-
- expect(getBestSellPool([], sell, tokenInfoMocks.b)).toBeUndefined()
- })
-})
diff --git a/packages/swap/src/helpers/pools/getBestSellPool.ts b/packages/swap/src/helpers/pools/getBestSellPool.ts
deleted file mode 100644
index 443cdbd53d..0000000000
--- a/packages/swap/src/helpers/pools/getBestSellPool.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-
-import {BigNumber} from 'bignumber.js'
-import {getPriceAfterFee} from '../prices/getPriceAfterFee'
-import {getSellAmount} from '../orders/amounts/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.
- * @param sellInfo - The token info of the token to sell.
- *
- * @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: Portfolio.Token.Amount,
- sellInfo: Portfolio.Token.Info,
-): Swap.Pool | undefined => {
- if (pools.length === 0 || buy.quantity === 0n) return undefined
-
- let bestPool: Swap.Pool | undefined
- let bestPrice = new BigNumber(0)
-
- for (const pool of pools) {
- const sell = getSellAmount(pool, buy, sellInfo)
- if (sell.quantity === 0n) continue
-
- const isBuyTokenA = buy.info.id === pool.tokenA.tokenId
- const [aAmount, bAmount] = isBuyTokenA
- ? [buy.quantity, sell.quantity]
- : [sell.quantity, buy.quantity]
- const price = getPriceAfterFee(
- pool,
- aAmount,
- bAmount,
- isBuyTokenA ? pool.tokenB.tokenId : pool.tokenA.tokenId,
- )
-
- if (bestPool === undefined) {
- bestPool = pool
- bestPrice = price
- continue
- }
-
- if (price < bestPrice) {
- bestPool = pool
- bestPrice = price
- }
- }
-
- return bestPool
-}
diff --git a/packages/swap/src/helpers/pools/getPoolUrlByProvider.test.ts b/packages/swap/src/helpers/pools/getPoolUrlByProvider.test.ts
deleted file mode 100644
index cd5ca969c0..0000000000
--- a/packages/swap/src/helpers/pools/getPoolUrlByProvider.test.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {getPoolUrlByProvider} from './getPoolUrlByProvider'
-
-describe('getPoolUrlByProvider', () => {
- it('should return the pool when it exists', () => {
- expect(getPoolUrlByProvider('minswap')).toBe('https://minswap.org')
- expect(getPoolUrlByProvider('sundaeswap')).toBe('https://sundae.fi')
- expect(getPoolUrlByProvider('wingriders')).toBe(
- 'https://www.wingriders.com',
- )
- })
-
- it('should return the default URL for an unknown provider', () => {
- expect(getPoolUrlByProvider('unknownProvider' as any)).toBe(
- 'https://muesliswap.com',
- )
- })
-})
diff --git a/packages/swap/src/helpers/prices/getMarketPrice.test.ts b/packages/swap/src/helpers/prices/getMarketPrice.test.ts
deleted file mode 100644
index adc9d97acd..0000000000
--- a/packages/swap/src/helpers/prices/getMarketPrice.test.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-import {getMarketPrice} from './getMarketPrice'
-
-describe('getMarketPrice', () => {
- it('should calculate the correct market price when selling tokenA', () => {
- const pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- price: 2,
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- } as Swap.Pool
- const result = getMarketPrice(pool, 'tokenA.')
- expect(result).toEqual(new BigNumber(0.5))
- })
-
- it('should calculate the correct market price when selling tokenB', () => {
- const pool = {
- tokenA: {quantity: 4500000n, tokenId: 'tokenA.'},
- tokenB: {quantity: 9000000n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '0',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- price: 2,
- batcherFee: {quantity: 1n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- } as Swap.Pool
- const result = getMarketPrice(pool, 'tokenB.')
- expect(result).toEqual(new BigNumber(2))
- })
-})
diff --git a/packages/swap/src/helpers/prices/getMarketPrice.ts b/packages/swap/src/helpers/prices/getMarketPrice.ts
deleted file mode 100644
index 32284c9ecc..0000000000
--- a/packages/swap/src/helpers/prices/getMarketPrice.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-/**
- * Calculate the market price based on the desired sell amount in a liquidity pool.
- *
- * @param pool - The liquidity pool.
- * @param sellTokenId - The desired sell token id.
- *
- * @returns The market price
- */
-export const getMarketPrice = (
- pool: Swap.Pool,
- sellTokenId: Portfolio.Token.Id,
-) => {
- const isSellTokenA = sellTokenId === pool.tokenA.tokenId
-
- const A = new BigNumber(pool.tokenA.quantity.toString())
- const B = new BigNumber(pool.tokenB.quantity.toString())
-
- const [firstToken, secondToken] = isSellTokenA ? [A, B] : [B, A]
-
- return secondToken.isZero() ? secondToken : firstToken.dividedBy(secondToken)
-}
diff --git a/packages/swap/src/helpers/prices/getPairPriceInPtTerms.test.ts b/packages/swap/src/helpers/prices/getPairPriceInPtTerms.test.ts
deleted file mode 100644
index 82ccb8224b..0000000000
--- a/packages/swap/src/helpers/prices/getPairPriceInPtTerms.test.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-import {getPairPriceInPtTerms} from './getPairPriceInPtTerms'
-import {tokenInfoMocks} from '../../tokenInfo.mocks'
-
-describe('getPriceInPtTerms', () => {
- it('should calculate the correct price based on sides and decimals', () => {
- // arrange
- const pool: Swap.Pool = {
- tokenA: {quantity: 1n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0.03465765134',
- ptPriceTokenB: '3.81247293317',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.,',
- },
- }
-
- // act
- const pricesAB = getPairPriceInPtTerms({
- buy: {
- info: {
- ...tokenInfoMocks.b,
- decimals: 4,
- },
- quantity: pool.tokenA.quantity,
- },
- pool,
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.a,
- },
- })
-
- const pricesBA = getPairPriceInPtTerms({
- buy: {
- info: tokenInfoMocks.a,
- quantity: pool.tokenA.quantity,
- },
- pool,
- sell: {
- quantity: 1n,
- info: {
- ...tokenInfoMocks.b,
- decimals: 4,
- },
- },
- })
-
- // assert
- expect(pricesAB).toStrictEqual({
- ptPriceAB: new BigNumber('11000.378807463645053797'),
- ptPriceBA: new BigNumber('0.00009090596037670177'),
- })
- expect(pricesBA).toStrictEqual({
- ptPriceAB: new BigNumber('0.909059603767017713'),
- ptPriceBA: new BigNumber('1.1000378807463645053797'),
- })
- })
-
- it('should set decimals to 0 if undefined', () => {
- // arrange
- const pool: Swap.Pool = {
- tokenA: {quantity: 1n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0.0',
- ptPriceTokenB: '3.81247293317',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
-
- // act
- const pricesAB = getPairPriceInPtTerms({
- buy: {
- info: {...tokenInfoMocks.b, decimals: 0},
- quantity: pool.tokenA.quantity,
- },
- pool,
- sell: {
- quantity: 1n,
- info: tokenInfoMocks.a,
- },
- })
-
- // assert
- expect(pricesAB).toStrictEqual({
- ptPriceAB: new BigNumber(0),
- ptPriceBA: new BigNumber(0),
- })
- })
-})
diff --git a/packages/swap/src/helpers/prices/getPairPriceInPtTerms.ts b/packages/swap/src/helpers/prices/getPairPriceInPtTerms.ts
deleted file mode 100644
index c5cca543fd..0000000000
--- a/packages/swap/src/helpers/prices/getPairPriceInPtTerms.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-export const getPairPriceInPtTerms = ({
- sell,
- buy,
- pool,
-}: {
- sell: Portfolio.Token.Amount
- buy: Portfolio.Token.Amount
- pool: Swap.Pool
-}) => {
- const calculatePrice = (dividend: BigNumber, divisor: BigNumber) => {
- return divisor.isZero() ? new BigNumber(0) : dividend.dividedBy(divisor)
- }
-
- const isSellTokenA = pool.tokenA.tokenId === sell.info.id
- const priceA = new BigNumber(pool.ptPriceTokenA)
- const priceB = new BigNumber(pool.ptPriceTokenB)
-
- const scale = sell.info.decimals - buy.info.decimals
- const scaleMultiplier = new BigNumber(10).pow(scale)
-
- const priceAB = isSellTokenA
- ? calculatePrice(priceB, priceA).multipliedBy(scaleMultiplier)
- : calculatePrice(priceA, priceB).dividedBy(scaleMultiplier)
-
- const priceBA = isSellTokenA
- ? calculatePrice(priceA, priceB).dividedBy(scaleMultiplier)
- : calculatePrice(priceB, priceA).multipliedBy(scaleMultiplier)
-
- return {
- ptPriceAB: priceAB,
- ptPriceBA: priceBA,
- }
-}
diff --git a/packages/swap/src/helpers/prices/getPriceAfterFee.test.ts b/packages/swap/src/helpers/prices/getPriceAfterFee.test.ts
deleted file mode 100644
index c6026dddb0..0000000000
--- a/packages/swap/src/helpers/prices/getPriceAfterFee.test.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-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: Swap.Pool = {
- tokenA: {quantity: 1200400368252n, tokenId: 'tokenA.'},
- tokenB: {quantity: 11364790709n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0.03465765134',
- ptPriceTokenB: '3.81247293317',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 950000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const tokenId = 'tokenA.'
- const tokenAAmount = 10000000000n
- const tokenBAmount = 93613464n
- 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: Swap.Pool = {
- tokenA: {quantity: 143983812522n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2050476716943n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0.06954250577',
- ptPriceTokenB: '1',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const tokenId = 'tokenA.'
- const tokenAAmount = 10000000000n
- const tokenBAmount = 696702612n
- const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId)
- const expected = new BigNumber('14.39254173470077386167')
- expect(result).toStrictEqual(expected)
- })
-
- it('should return 0 when sell side is 0', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 143983812522n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2050476716943n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0.06954250577',
- ptPriceTokenB: '1',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const tokenAAmount = 0n
- const tokenBAmount = 93613464n
- 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: Swap.Pool = {
- tokenA: {quantity: 143983812522n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2050476716943n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0.06954250577',
- ptPriceTokenB: '1',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const tokenAAmount = 10000000000n
- const tokenBAmount = 0n
- const tokenId = 'tokenA.'
- const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId)
- const expected = new BigNumber(0)
- expect(result).toStrictEqual(expected)
- })
-
- // NOTE: it means that if the price is missing the fee wont consider the batcher fee
- it('should return not add the feeInSellTerm when pt sell side is 0', () => {
- const pool: Swap.Pool = {
- tokenA: {quantity: 143983812522n, tokenId: 'tokenA.'},
- tokenB: {quantity: 2050476716943n, tokenId: 'tokenB.'},
- ptPriceTokenA: '0',
- ptPriceTokenB: '1',
- fee: '0.3', // 0.3%
- provider: 'minswap',
- batcherFee: {quantity: 1900000n, tokenId: '.'},
- deposit: {quantity: 1n, tokenId: '.'},
- poolId: '0',
- lpToken: {
- quantity: 0n,
- tokenId: '0.',
- },
- }
- const tokenAAmount = 10000000000n
- const tokenBAmount = 1000n
- const tokenId = 'tokenA.'
- const result = getPriceAfterFee(pool, tokenAAmount, tokenBAmount, tokenId)
- const expected = new BigNumber(10000000)
- expect(result).toStrictEqual(expected)
- })
-})
diff --git a/packages/swap/src/helpers/prices/getPriceAfterFee.ts b/packages/swap/src/helpers/prices/getPriceAfterFee.ts
deleted file mode 100644
index b3cd1b5514..0000000000
--- a/packages/swap/src/helpers/prices/getPriceAfterFee.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {BigNumber} from 'bignumber.js'
-
-/**
- * Calculate the price with batcher fee in a liquidity pool.
- *
- * @param pool - The liquidity pool.
- * @param quantityA - Token A amount in an order.
- * @param quantityB - Token B amount in an order.
- * @param sellTokenId - The token id of the desired sell amount.
- *
- * @returns The price after fee
- */
-export const getPriceAfterFee = (
- pool: Swap.Pool,
- quantityA: bigint,
- quantityB: bigint,
- sellTokenId: string,
-): BigNumber => {
- if (quantityA === 0n || quantityB === 0n) return new BigNumber(0)
-
- const A = new BigNumber(quantityA.toString())
- const B = new BigNumber(quantityB.toString())
-
- 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 feeInSellTerm = sellPriceInPtTerm.isZero()
- ? new BigNumber(0)
- : new BigNumber(pool.batcherFee.quantity.toString()).dividedBy(
- sellPriceInPtTerm,
- )
-
- 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 5dd26bfbb6..4264bfd418 100644
--- a/packages/swap/src/helpers/transformers.test.ts
+++ b/packages/swap/src/helpers/transformers.test.ts
@@ -1,233 +1,4 @@
-import {Balance, Portfolio, Swap} from '@yoroi/types'
-import {tokenInfoMocks} from '@yoroi/portfolio'
-
-import {asTokenFingerprint, transformersMaker} from './transformers'
-import {openswapMocks} from '../adapters/openswap-api/openswap.mocks'
-import {apiMocks} from '../adapters/openswap-api/api.mocks'
-import {PriceAddress, TokenAddress} from '../adapters/openswap-api/types'
-
-const primaryTokenInfo = tokenInfoMocks.primaryETH
-const transformers = transformersMaker(primaryTokenInfo)
-
-describe('asOpenswapAmount', () => {
- it('success', () => {
- const yoroiAmount = {
- tokenId: 'policyid.assetname',
- quantity: 100n,
- } as const
-
- const result = transformers.asOpenswapAmount(yoroiAmount)
-
- expect(result).toEqual({
- amount: '100',
- assetName: 'assetname',
- policyId: 'policyid',
- })
- })
-
- it('success (empty token) primary token', () => {
- const yoroiAmount = {
- tokenId: '.',
- quantity: 50n,
- } as const
-
- const result = transformers.asOpenswapAmount(yoroiAmount)
-
- expect(result).toEqual({
- amount: '50',
- assetName: '',
- policyId: '',
- })
- })
-
- it('success nameless token', () => {
- const yoroiAmount = {
- tokenId: 'policyId.',
- quantity: 75n,
- } as const
-
- const result = transformers.asOpenswapAmount(yoroiAmount)
-
- expect(result).toEqual({
- amount: '75',
- assetName: '',
- policyId: 'policyId',
- })
- })
-})
-
-describe('asYoroiOpenOrder', () => {
- it('success', () => {
- const result = transformers.asYoroiOpenOrder(
- openswapMocks.getOpenOrders[0]!,
- )
-
- expect(result).toEqual(apiMocks.getOpenOrders[0]!)
- })
-
- it('success (pt without .) coverage should not happen', () => {
- const transformer = transformersMaker({
- ...primaryTokenInfo,
- id: '.' as any,
- })
- const result = transformer.asYoroiOpenOrder(openswapMocks.getOpenOrders[0]!)
-
- expect(result).toEqual({
- ...apiMocks.getOpenOrders[0]!,
- deposit: {
- quantity: 1700000n,
- tokenId: '.' as any,
- },
- from: {
- quantity: 1000000n,
- tokenId: '.' as any,
- },
- })
- })
-})
-
-describe('asYoroiCompletedOrder', () => {
- it('success', () => {
- const result = transformers.asYoroiCompletedOrder(
- openswapMocks.getCompletedOrders[0]!,
- )
-
- expect(result).toEqual(apiMocks.getCompletedOrders[0]!)
-
- const missingDex = {...openswapMocks.getCompletedOrders[0]!}
- missingDex.dex = undefined as any
- const defaultedProviderToMuesliswap = {
- ...apiMocks.getCompletedOrders[0]!,
- provider: 'muesliswap' as Swap.PoolProvider,
- }
-
- const result2 = transformers.asYoroiCompletedOrder(missingDex)
- expect(result2).toEqual(defaultedProviderToMuesliswap)
- })
-})
-
-describe('asYoroiTokenId', () => {
- it('success (empty policyId) should not happen', () => {
- const result = transformers.asYoroiTokenId({policyId: '', name: 'someName'})
- expect(result).toBe(primaryTokenInfo.id)
- })
-
- it('success', () => {
- const result = transformers.asYoroiTokenId({
- policyId: 'somePolicyId',
- name: 'someName',
- })
- expect(result).toBe('somePolicyId.someName')
- })
-
- it('success nameless token', () => {
- const result = transformers.asYoroiTokenId({
- policyId: 'somePolicyId',
- name: '',
- })
- expect(result).toBe('somePolicyId.')
- })
-})
-
-describe('asYoroiAmount', () => {
- it('empty when null', () => {
- const result = transformers.asYoroiAmount(null as any)
- expect(result).toEqual({
- quantity: '0',
- tokenId: primaryTokenInfo.id,
- })
- })
-
- it('success', () => {
- const result = transformers.asYoroiAmount({
- amount: '100',
- address: {
- policyId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b',
- name: '30',
- },
- })
- expect(result).toEqual({
- quantity: '100',
- tokenId: 'c04f4200502a998e9eebafac0291a1f38008de3fe146d136946d8f4b.30',
- })
- })
-
- 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',
- address: {
- policyId: '',
- name: '',
- },
- })
- expect(result).toEqual({
- quantity: '1000000',
- tokenId: primaryTokenInfo.id,
- })
- })
-
- it('success (period) primary token', () => {
- const result = transformers.asYoroiAmount({
- amount: '1000000',
- address: {
- policyId: '',
- name: '.',
- },
- })
- expect(result).toEqual({
- quantity: '1000000',
- tokenId: primaryTokenInfo.id,
- })
- })
-})
-
-describe('asOpensawpTokenId (TokenAddress)', () => {
- it('success', () => {
- const result = transformers.asOpenswapTokenId(
- '1f7a58a1aa1e6b047a42109ade331ce26c9c2cce027d043ff264fb1f.425249434b53',
- )
- expect(result).toEqual({
- policyId: '1f7a58a1aa1e6b047a42109ade331ce26c9c2cce027d043ff264fb1f',
- assetName: '425249434b53',
- })
- })
- it('success primary token (empty values)', () => {
- const result = transformers.asOpenswapTokenId('.' as any)
- expect(result).toEqual({
- policyId: '',
- assetName: '',
- })
- })
-})
-
-describe('asOpensawpPriceTokenAddress (PriceAddress)', () => {
- it('success', () => {
- const result = transformers.asOpenswapPriceTokenAddress(
- '1f7a58a1aa1e6b047a42109ade331ce26c9c2cce027d043ff264fb1f.425249434b53',
- )
- expect(result).toEqual({
- policyId: '1f7a58a1aa1e6b047a42109ade331ce26c9c2cce027d043ff264fb1f',
- name: '425249434b53',
- })
- })
- it('success primary token (empty values)', () => {
- const result = transformers.asOpenswapPriceTokenAddress('.' as any)
- expect(result).toEqual({
- policyId: '',
- name: '',
- })
- })
-})
+import {asTokenFingerprint} from './transformers'
describe('asTokenFingerprint', () => {
it('success', () => {
@@ -243,127 +14,3 @@ describe('asTokenFingerprint', () => {
expect(unamed).toBe('asset1ge674djk0wu352lv8mck4tfpuxuul8uu8s775x')
})
})
-
-describe('asYoroiPools', () => {
- it('success empty array', () => {
- const result = transformers.asYoroiPools([])
- expect(result).toEqual>([])
- })
-
- it('success when undefined', () => {
- const result = transformers.asYoroiPools(undefined as any)
- expect(result).toEqual>([])
- })
-
- it('success (filter out unsupported pools)', () => {
- const result = transformers.asYoroiPools(openswapMocks.getLiquidityPools)
-
- expect(result).toEqual>(apiMocks.getPools)
-
- // should filter out unsupported pools
- expect(result.length).toBe(openswapMocks.getLiquidityPools.length - 1)
- })
-})
-
-describe('asYoroiPool', () => {
- it('success (supported pool)', () => {
- const result = transformers.asYoroiPool(openswapMocks.getLiquidityPools[0]!)
-
- expect(result).toEqual(apiMocks.getPools[0]!)
- })
-
- it('success (unsupported pool)', () => {
- const result = transformers.asYoroiPool(openswapMocks.getLiquidityPools[3]!)
-
- expect(result).toBeNull()
- })
-})
-
-describe('asYoroiPortfolioTokenInfos', () => {
- it('success', () => {
- const result = transformers.asYoroiPortfolioTokenInfos(
- openswapMocks.getTokens,
- )
-
- expect(result).toEqual>(apiMocks.getTokens)
- })
-
- it('success (empty)', () => {
- const result = transformers.asYoroiPortfolioTokenInfos([])
-
- expect(result).toEqual>([])
- })
-})
-
-describe('asYoroiPortfolioTokenInfosFromPairs', () => {
- it('success', () => {
- const result = transformers.asYoroiPortfolioTokenInfosFromPairs(
- openswapMocks.getTokenPairs,
- )
-
- expect(result).toEqual>(apiMocks.getTokenPairs)
- })
-
- it('success (empty)', () => {
- const result = transformers.asYoroiPortfolioTokenInfosFromPairs([])
-
- expect(result).toEqual>([])
- })
-})
-
-describe('asYoroiPortfolioTokenInfo', () => {
- it('success', () => {
- const result = transformers.asYoroiPortfolioTokenInfo(
- openswapMocks.getTokens[0]!,
- )
-
- expect(result).toEqual({
- application: Portfolio.Token.Application.General,
- decimals: 0,
- description: 'Eggscape Club Utility Token',
- fingerprint: 'asset126v2sm79r8uxvk4ju64mr6srxrvm2x75fpg6w3',
- id: '1c1e38cfcc815d2015dbda6bee668b2e707ee3f9d038d96668fcf63c.4567677363617065436c75624561737465725a656e6e79',
- name: 'EggscapeClubEasterZenny',
- nature: Portfolio.Token.Nature.Secondary,
- originalImage: 'ipfs://QmNYibJoiTWRiMmWn4yXwvoakEPgq9WmaukmRXHF1VGbAU',
- reference: '',
- status: Portfolio.Token.Status.Valid,
- symbol: '',
- tag: '',
- ticker: 'EZY',
- type: Portfolio.Token.Type.FT,
- website: 'https://eggscape.io/',
- })
- })
-
- it('success (primary token)', () => {
- const result = transformers.asYoroiPortfolioTokenInfo({
- address: {
- policyId: '',
- name: '',
- },
- categories: [],
- decimalPlaces: 6,
- description: 'Cardano',
- status: 'verified',
- symbol: '₳',
- website: 'https://www.cardano.org/',
- supply: {
- circulating: '1000000000000',
- total: '45000000000000',
- },
- })
-
- expect(result).toEqual(primaryTokenInfo)
- })
-})
-
-describe('asYoroiTokenIdAndQuantity', () => {
- it('missing token, returns as primary token', () => {
- const result = transformers.asYoroiTokenIdAndQuantity({token: ''})
- expect(result).toEqual({
- tokenId: primaryTokenInfo.id,
- quantity: 0n,
- })
- })
-})
diff --git a/packages/swap/src/helpers/transformers.ts b/packages/swap/src/helpers/transformers.ts
index a1de47bff8..258b428c60 100644
--- a/packages/swap/src/helpers/transformers.ts
+++ b/packages/swap/src/helpers/transformers.ts
@@ -1,298 +1,6 @@
import AssetFingerprint from '@emurgo/cip14-js'
-import {Swap, Balance, Portfolio} from '@yoroi/types'
-import {isString} from '@yoroi/common'
import {AssetNameUtils} from '@emurgo/yoroi-lib/dist/internals/utils/assets'
-import {Quantities} from '../utils/quantities'
-import {supportedProviders} from '../translators/constants'
-import {asQuantity} from '../utils/asQuantity'
-import {
- CompletedOrder,
- LiquidityPool,
- ListTokensResponse,
- OpenOrder,
- TokenPair,
- TokenPairsResponse,
-} from '../adapters/openswap-api/types'
-
-const asPolicyIdAndAssetName = (tokenId: string): [string, string] => {
- return tokenId.split('.') as [string, string]
-}
-
-export const transformersMaker = (primaryTokenInfo: Portfolio.Token.Info) => {
- const asOpenswapTokenId = (yoroiTokenId: string) => {
- const [policyId, assetName] = asPolicyIdAndAssetName(yoroiTokenId)
- // we dont convert to '.' or 'lovelace' only ''
- return {
- policyId,
- assetName,
- }
- }
-
- const asOpenswapPriceTokenAddress = (yoroiTokenId: string) => {
- const [policyId, name] = asPolicyIdAndAssetName(yoroiTokenId)
- // we dont convert to '.' or 'lovelace' only ''
- return {
- policyId,
- name,
- }
- }
-
- const asYoroiTokenId = ({
- policyId,
- name,
- }: {
- policyId: string
- name: string
- }): Portfolio.Token.Id => {
- const possibleTokenId = `${policyId}.${name}`
- // openswap is inconsistent about ADA
- // sometimes is '.', '' or 'lovelace'
- const isPrimaryToken =
- possibleTokenId === '.' || possibleTokenId === 'lovelace.'
- if (policyId === '' || isPrimaryToken) return primaryTokenInfo.id
- return `${policyId}.${name}`
- }
-
- const asOpenswapAmount = (yoroiAmount: {
- tokenId: Portfolio.Token.Id
- quantity: bigint
- }) => {
- const {tokenId, quantity: amount} = yoroiAmount
- const {policyId, assetName} = asOpenswapTokenId(tokenId)
- return {
- amount: amount.toString(),
- assetName,
- policyId,
- } as const
- }
-
- const asYoroiOpenOrder = (openswapOrder: OpenOrder) => {
- const {from, to, deposit, ...rest} = openswapOrder
- const [policyId, name] = asPolicyIdAndAssetName(primaryTokenInfo.id)
- return {
- ...rest,
- from: asYoroiTokenIdAndQuantity(from),
- to: asYoroiTokenIdAndQuantity(to),
- deposit: asYoroiTokenIdAndQuantity({
- amount: deposit,
- address: {
- policyId,
- name,
- },
- }),
- } as const
- }
-
- const asYoroiCompletedOrder = (openswapOrder: CompletedOrder) => {
- const {txHash, fromAmount, fromToken, toAmount, toToken, placedAt, dex} =
- openswapOrder
- const from = {
- amount: fromAmount,
- token: `${fromToken.address.policyId}.${fromToken.address.name}`,
- }
- const to = {
- amount: toAmount,
- token: `${toToken.address.policyId}.${toToken.address.name}`,
- }
-
- return {
- txHash,
- from: asYoroiTokenIdAndQuantity(from),
- to: asYoroiTokenIdAndQuantity(to),
- placedAt: placedAt * 1000,
- provider: dex ?? 'muesliswap',
- } as const
- }
-
- const asYoroiPortfolioTokenInfo = (
- openswapToken: TokenPair['info'],
- ): Portfolio.Token.Info => {
- const id = asYoroiTokenId(openswapToken.address)
-
- const isPrimary = id === primaryTokenInfo.id
- if (isPrimary) return primaryTokenInfo
-
- const tokenInfo: Portfolio.Token.Info = {
- id,
- fingerprint: asTokenFingerprint({
- policyId: openswapToken.address.policyId,
- assetNameHex: openswapToken.address.name,
- }),
- name: asTokenName(openswapToken.address.name),
- decimals: openswapToken.decimalPlaces,
- description: openswapToken.description,
- originalImage: openswapToken.image ?? '',
- type: Portfolio.Token.Type.FT,
- nature: Portfolio.Token.Nature.Secondary,
- ticker: openswapToken.symbol,
- symbol: openswapToken.sign ?? '',
- status: Portfolio.Token.Status.Valid,
- application: Portfolio.Token.Application.General,
- reference: '',
- tag: '',
- website: openswapToken.website,
- }
- return tokenInfo
- }
-
- const asYoroiPortfolioTokenInfos = (
- openswapTokens: ListTokensResponse,
- ): Array => {
- if (openswapTokens.length === 0) return []
- // filters should go into manager, but since we strip out the status is here for now
- return openswapTokens
- .filter((token) => token.status === 'verified')
- .map(asYoroiPortfolioTokenInfo)
- }
-
- const asYoroiPortfolioTokenInfosFromPairs = (
- openswapTokens: TokenPairsResponse,
- ): Array => {
- if (openswapTokens.length === 0) return []
- // filters should go into manager, but since we strip out the status is here for now
- return openswapTokens
- .filter((token) => token.info.status === 'verified')
- .map((token) => token.info)
- .map(asYoroiPortfolioTokenInfo)
- }
-
- const asYoroiPool = (
- openswapLiquidityPool: LiquidityPool,
- ): Swap.Pool | null => {
- const {
- batcherFee,
- poolFee,
- lvlDeposit,
- lpToken,
- tokenA,
- tokenB,
- provider,
- poolId,
- } = openswapLiquidityPool
-
- if (provider && !isSupportedProvider(provider)) return null
-
- const pool: Swap.Pool = {
- tokenA: asYoroiTokenIdAndQuantity(tokenA),
- tokenB: asYoroiTokenIdAndQuantity(tokenB),
- ptPriceTokenA: tokenA.priceAda.toString(),
- ptPriceTokenB: tokenB.priceAda.toString(),
- deposit: asYoroiTokenIdAndQuantity({amount: lvlDeposit}),
- lpToken: asYoroiTokenIdAndQuantity(lpToken),
- batcherFee: asYoroiTokenIdAndQuantity({amount: batcherFee}),
- fee: poolFee,
- poolId,
- provider,
- }
- return pool
- }
-
- const asYoroiAmount = (openswapAmount: {
- address?: {
- policyId: string
- name: string
- }
- // openswap is inconsistent about ADA
- // sometimes is '.', '' or 'lovelace'
- token?: string
- amount?: string
- }): Balance.Amount => {
- 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] ?? ''
- }
-
- const yoroiAmount: Balance.Amount = {
- quantity: asQuantity(amount ?? Quantities.zero),
- tokenId: asYoroiTokenId({policyId, name}),
- } as const
-
- return yoroiAmount
- }
-
- const asYoroiTokenIdAndQuantity = (openswapAmount: {
- address?: {
- policyId: string
- name: string
- }
- // openswap is inconsistent about ADA
- // sometimes is '.', '' or 'lovelace'
- token?: string
- amount?: string
- }): {
- tokenId: Portfolio.Token.Id
- quantity: bigint
- } => {
- 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] ?? ''
- }
-
- const yoroiAmount = {
- quantity: BigInt(amount ?? 0),
- tokenId: asYoroiTokenId({policyId, name}),
- } as const
-
- return yoroiAmount
- }
-
- /**
- * Filter out pools that are not supported by Yoroi
- *
- * @param openswapLiquidityPools
- * @returns {Swap.Pool[]}
- */
- const asYoroiPools = (
- openswapLiquidityPools: LiquidityPool[],
- ): Swap.Pool[] => {
- if (openswapLiquidityPools?.length > 0)
- return openswapLiquidityPools
- .map(asYoroiPool)
- .filter((pool): pool is Swap.Pool => pool !== null)
-
- return []
- }
-
- return {
- asOpenswapTokenId,
- asOpenswapPriceTokenAddress,
- asOpenswapAmount,
-
- asYoroiCompletedOrder,
- asYoroiOpenOrder,
-
- asYoroiPool,
- asYoroiPools,
-
- asYoroiTokenId,
- asYoroiAmount,
- asYoroiTokenIdAndQuantity,
-
- asYoroiPortfolioTokenInfo,
- asYoroiPortfolioTokenInfos,
- asYoroiPortfolioTokenInfosFromPairs,
- }
-}
-
export const asTokenFingerprint = ({
policyId,
assetNameHex = '',
@@ -311,9 +19,3 @@ export const asTokenName = (hex: string) => {
const {asciiName, hexName} = AssetNameUtils.resolveProperties(hex)
return asciiName ?? hexName
}
-
-function isSupportedProvider(
- provider: string,
-): provider is Swap.SupportedProvider {
- return supportedProviders.includes(provider as Swap.SupportedProvider)
-}
diff --git a/packages/swap/src/index.ts b/packages/swap/src/index.ts
index c66df66340..6c87bfd885 100644
--- a/packages/swap/src/index.ts
+++ b/packages/swap/src/index.ts
@@ -1,58 +1,5 @@
-// mocks
-export {
- mockSwapManager,
- mockSwapManagerDefault,
- swapManagerMocks,
-} from './manager.mocks'
-export {mockSwapStateDefault} from './translators/reactjs/state/state.mocks'
-export {apiMocks} from './adapters/openswap-api/api.mocks'
-export {mocks as orderMocks} from './helpers/mocks'
-
-// orders amounts
-export {getBuyAmount} from './helpers/orders/amounts/getBuyAmount'
-export {getSellAmount} from './helpers/orders/amounts/getSellAmount'
-export {getQuantityWithSlippage} from './helpers/orders/amounts/getQuantityWithSlippage'
-// orders factories
-export {makePossibleMarketOrder} from './helpers/orders/factories/makePossibleMarketOrder'
-export {makeLimitOrder} from './helpers/orders/factories/makeLimitOrder'
-export {makeOrderCalculations} from './helpers/orders/factories/makeOrderCalculations'
-// orders costs
-export {getLiquidityProviderFee} from './helpers/orders/costs/getLiquidityProviderFee'
-export {getFrontendFee} from './helpers/orders/costs/getFrontendFee'
-
-// prices
-export {getMarketPrice} from './helpers/prices/getMarketPrice'
-export {getPriceAfterFee} from './helpers/prices/getPriceAfterFee'
-export {getPairPriceInPtTerms} from './helpers/prices/getPairPriceInPtTerms'
-
-// pools
-export {getPoolUrlByProvider} from './helpers/pools/getPoolUrlByProvider'
-export {getBestBuyPool} from './helpers/pools/getBestBuyPool'
-export {getBestSellPool} from './helpers/pools/getBestSellPool'
-export {getBestPoolCalculation} from './helpers/pools/getBestPoolCalculation'
-
-// translators
-export {SwapProvider} from './translators/reactjs/provider/SwapProvider'
-export {SwapState} from './translators/reactjs/state/state'
-export {useSwapCreateOrder} from './translators/reactjs/hooks/useSwapCreateOrder'
-export {useSwapOrdersByStatusCompleted} from './translators/reactjs/hooks/useSwapOrdersByStatusCompleted'
-export {useSwapOrdersByStatusOpen} from './translators/reactjs/hooks/useSwapOrdersByStatusOpen'
-export {useSwapPoolsByPair} from './translators/reactjs/hooks/useSwapPoolsByPair'
-export {useSwapSetSlippage} from './translators/reactjs/hooks/useSwapSetSlippage'
-export {useSwapSlippage} from './translators/reactjs/hooks/useSwapSlippage'
-export {useSwapTokensByPair} from './translators/reactjs/hooks/useSwapTokensByPair'
-export {useSwapTokensOnlyVerified} from './translators/reactjs/hooks/useSwapTokensOnlyVerified'
-export {useSwap} from './translators/reactjs/hooks/useSwap'
-export {supportedProviders, milkTokenId} from './translators/constants'
-
-// factories
-export {swapApiMaker} from './adapters/api-maker'
export {swapManagerMaker} from './manager'
export {
swapStorageMaker,
swapStorageSlippageKey,
} from './adapters/async-storage/storage'
-export {
- makeStorageMaker,
- makeStorageMakerDefault,
-} from './adapters/async-storage/storage.mocks'
diff --git a/packages/swap/src/manager.mocks.ts b/packages/swap/src/manager.mocks.ts
deleted file mode 100644
index ceda6e3202..0000000000
--- a/packages/swap/src/manager.mocks.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-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'))
-const delayedResponse = ({
- data,
- timeout = 3000,
-}: {
- data: T
- timeout?: number
-}) =>
- new Promise((resolve) => {
- setTimeout(() => resolve(data), timeout)
- })
-
-// API RESPONSES
-const createOrderResponse: Swap.CreateOrderResponse = {
- datum: 'some-datum',
- datumHash: 'some-hash',
- contractAddress: 'some-address',
-}
-const cancelOrderResponse: string = 'cbor'
-const listOrdersByStatusOpenResponse: Swap.OpenOrderResponse =
- apiMocks.getOpenOrders
-const listOrdersByStatusCompletedResponse: Swap.CompletedOrderResponse =
- apiMocks.getCompletedOrders
-const listPoolsByPairResponse: Swap.PoolResponse = apiMocks.getPools
-const listTokensByPairResponse: Array =
- apiMocks.getTokenPairs
-const listOnlyVerifiedTokensResponse: Array =
- apiMocks.getTokens
-
-// API FUNCTIONS
-const createOrder = {
- success: () => Promise.resolve(createOrderResponse),
- delayed: (timeout: number) =>
- delayedResponse({data: createOrderResponse, timeout}),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const cancelOrder = {
- success: () => Promise.resolve(cancelOrderResponse),
- delayed: (timeout?: number) =>
- delayedResponse({data: cancelOrderResponse, timeout}),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const getOpenOrders = {
- success: () => Promise.resolve(listOrdersByStatusOpenResponse),
- delayed: (timeout?: number) =>
- delayedResponse({data: listOrdersByStatusOpenResponse, timeout}),
- empty: () => Promise.resolve([]),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const getCompletedOrders = {
- success: () => Promise.resolve(listOrdersByStatusCompletedResponse),
- delayed: (timeout?: number) =>
- delayedResponse({data: listOrdersByStatusCompletedResponse, timeout}),
- empty: () => Promise.resolve([]),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const getPools = {
- success: () => Promise.resolve(listPoolsByPairResponse),
- delayed: (timeout?: number) =>
- delayedResponse({data: listPoolsByPairResponse, timeout}),
- empty: () => Promise.resolve([]),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const getPrice = {
- success: () => Promise.resolve(1),
- delayed: (timeout?: number) => delayedResponse({data: 1, timeout}),
- empty: () => Promise.resolve(),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const getTokenPairs = {
- success: () => Promise.resolve(listTokensByPairResponse),
- delayed: (timeout?: number) =>
- delayedResponse({data: listTokensByPairResponse, timeout}),
- empty: () => Promise.resolve([]),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-const getTokens = {
- success: () => Promise.resolve(listOnlyVerifiedTokensResponse),
- delayed: (timeout?: number) =>
- delayedResponse({data: listOnlyVerifiedTokensResponse, timeout}),
- empty: () => Promise.resolve([]),
- loading,
- error: {
- unknown: unknownError,
- },
-}
-
-// STORAGE RESPONSES
-const slippageResponse = 0.1
-
-// STORAGE FUNCTIONS
-const slippage = {
- success: {
- read: () => Promise.resolve(slippageResponse),
- remove: () => Promise.resolve(),
- save: () => Promise.resolve(),
- key: 'mock-swap-slippage',
- },
- empty: {
- read: () => Promise.resolve(undefined),
- remove: () => Promise.resolve(),
- save: () => Promise.resolve(),
- key: 'mock-swap-slippage',
- },
- error: {
- unknown: {
- read: unknownError,
- remove: unknownError,
- save: unknownError,
- key: 'mock-swap-slippage',
- },
- },
-}
-
-const clear = {
- success: () => Promise.resolve(),
- error: {
- unknown: unknownError,
- },
-}
-
-// MOCKS
-export const swapManagerMocks = {
- cancelOrderResponse,
- createOrderResponse,
- listOrdersByStatusOpenResponse,
- listOrdersByStatusCompletedResponse,
- listPoolsByPairResponse,
- listTokensByPairResponse,
- listOnlyVerifiedTokensResponse,
-
- slippageResponse,
-
- createOrder,
- cancelOrder,
- getPrice,
- getOpenOrders,
- getCompletedOrders,
- getPools,
- getTokenPairs,
- getTokens,
-
- slippage,
- clear,
-}
-
-export const mockSwapManager: Swap.Manager = {
- order: {
- create: createOrder.success,
- cancel: cancelOrder.success,
- list: {
- byStatusOpen: getOpenOrders.success,
- byStatusCompleted: getCompletedOrders.success,
- },
- },
- pools: {
- list: {
- byPair: getPools.success,
- },
- },
- tokens: {
- list: {
- byPair: getTokenPairs.success,
- onlyVerified: getTokens.success,
- },
- },
- price: {
- byPair: getPrice.success,
- },
- slippage: slippage.success,
- clearStorage: clear.success,
- stakingKey: '',
- supportedProviders: [] as const,
- aggregator: 'muesliswap',
- primaryTokenInfo: tokenInfoMocks.primaryETH,
- aggregatorTokenId: undefined,
- frontendFeeTiers: [] as const,
- makeOrderCalculations,
- getBestPoolCalculation,
- selectedPoolCalculationSelector,
-} as const
-
-export const mockSwapManagerDefault: Swap.Manager = {
- order: {
- create: createOrder.error.unknown,
- cancel: cancelOrder.error.unknown,
- list: {
- byStatusOpen: getOpenOrders.error.unknown,
- byStatusCompleted: getCompletedOrders.error.unknown,
- },
- },
- pools: {
- list: {
- byPair: getPools.error.unknown,
- },
- },
- price: {
- byPair: getPrice.error.unknown,
- },
- tokens: {
- list: {
- byPair: getTokenPairs.error.unknown,
- onlyVerified: getTokens.error.unknown,
- },
- },
- slippage: slippage.error.unknown,
- clearStorage: clear.error.unknown,
- primaryTokenInfo: tokenInfoMocks.primaryETH,
- stakingKey: '',
- supportedProviders: [] as const,
- frontendFeeTiers: [] as const,
- aggregatorTokenId: undefined,
- aggregator: 'muesliswap',
- makeOrderCalculations,
- getBestPoolCalculation,
- selectedPoolCalculationSelector,
-} as const
diff --git a/packages/swap/src/manager.test.ts b/packages/swap/src/manager.test.ts
deleted file mode 100644
index e0da26cbfd..0000000000
--- a/packages/swap/src/manager.test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {swapManagerMaker} from './manager'
-import {swapManagerMocks} from './manager.mocks'
-import {tokenInfoMocks} from '@yoroi/portfolio'
-
-describe('swapManagerMaker', () => {
- let manager: Readonly
-
- const mockedStorage: Swap.Storage = {
- slippage: {
- read: jest.fn().mockResolvedValue(swapManagerMocks.slippageResponse),
- remove: jest.fn(),
- save: jest.fn(),
- key: 'mock-swap-slippage',
- },
- clear: jest.fn().mockResolvedValue(undefined),
- }
-
- const mockedApi = {
- cancelOrder: jest.fn(),
- createOrder: jest.fn(),
- getOpenOrders: jest.fn(),
- getPrice: jest.fn(),
- getPools: jest.fn(),
- getTokens: jest.fn(),
- getTokenPairs: jest.fn(),
- getCompletedOrders: jest.fn(),
- primaryTokenInfo: tokenInfoMocks.primaryETH,
- stakingKey: 'someStakingKey',
- supportedProviders: ['minswap'] as const,
- }
-
- beforeEach(() => {
- jest.clearAllMocks()
- manager = swapManagerMaker({
- swapStorage: mockedStorage,
- swapApi: mockedApi,
- aggregator: 'muesliswap',
- aggregatorTokenId: '.',
- frontendFeeTiers: [] as const,
- })
- })
-
- it('clearStorage clear', async () => {
- await expect(manager.clearStorage()).resolves.toBeUndefined()
- expect(mockedStorage.clear).toHaveBeenCalledTimes(1)
- })
-
- it('slippage', async () => {
- await expect(manager.slippage.read()).resolves.toBe(
- swapManagerMocks.slippageResponse,
- )
- })
-
- it('orders (create, cancel, getOpen, getCompleted)', async () => {
- await manager.order.cancel({} as any)
- expect(mockedApi.cancelOrder).toHaveBeenCalledTimes(1)
-
- await manager.order.create({} as any)
- expect(mockedApi.createOrder).toHaveBeenCalledTimes(1)
-
- await manager.order.list.byStatusOpen()
- expect(mockedApi.getOpenOrders).toHaveBeenCalledTimes(1)
-
- await manager.order.list.byStatusCompleted()
- expect(mockedApi.getCompletedOrders).toHaveBeenCalledTimes(1)
- })
-})
diff --git a/packages/swap/src/manager.ts b/packages/swap/src/manager.ts
index 0153b69cdc..1b88401636 100644
--- a/packages/swap/src/manager.ts
+++ b/packages/swap/src/manager.ts
@@ -1,77 +1,58 @@
-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'
+import {Portfolio, Swap} from '@yoroi/types'
+import {dexhunterApiMaker} from './adapters/api/dexhunter/api-maker'
+import {
+ muesliswapApiMaker,
+ milkTokenId,
+ oldMilkTokenId,
+} from './adapters/api/muesliswap/api-maker'
-export const swapManagerMaker = ({
- swapStorage,
- swapApi,
- frontendFeeTiers,
- aggregatorTokenId,
- aggregator,
-}: {
- swapStorage: Swap.Storage
- swapApi: Swap.Api
- frontendFeeTiers: ReadonlyArray
- aggregatorTokenId?: Portfolio.Token.Id
- aggregator: Swap.Aggregator
-}): Readonly => {
- const {clear: clearStorage, slippage} = swapStorage
- const {
- getPrice,
- getPools,
- getOpenOrders,
- getCompletedOrders,
- getTokenPairs,
- getTokens,
- cancelOrder,
- createOrder,
- primaryTokenInfo,
- stakingKey,
- supportedProviders,
- } = swapApi
+export const swapManagerMaker: Swap.ManagerMaker = ({
+ address,
+ addressHex,
+ aggregatedFrontendFeeTiers,
+ network,
+ primaryTokenInfo,
+ stakingKey,
+ storage,
+}) => {
+ const aggregatorTokensHeld: {
+ muesliswap: number
+ dexhunter: number
+ } = {muesliswap: 0, dexhunter: 0}
- const order = {
- cancel: cancelOrder,
- create: createOrder,
- list: {
- byStatusOpen: getOpenOrders,
- byStatusCompleted: getCompletedOrders,
- } as const,
+ const updateAggregatorTokensHeld = (
+ values: ReadonlyArray,
+ ) => {
+ aggregatorTokensHeld.muesliswap = values.reduce(
+ (acc, curr) =>
+ acc +
+ (curr.info.id === milkTokenId || curr.info.id === oldMilkTokenId
+ ? Number(curr.quantity)
+ : 0),
+ 0,
+ )
}
- const price = {
- byPair: getPrice,
- } as const
-
- const pools = {
- list: {
- byPair: getPools,
- } as const,
- }
+ const dexhunterApi = dexhunterApiMaker({address, network, primaryTokenInfo})
+ const muesliswapApi = muesliswapApiMaker({
+ address,
+ addressHex,
+ frontendFeeTiers: aggregatedFrontendFeeTiers.muesliswap,
+ network,
+ primaryTokenInfo,
+ stakingKey,
+ getLpTokensHeld: () => aggregatorTokensHeld.muesliswap,
+ })
- const tokens = {
- list: {
- byPair: getTokenPairs,
- onlyVerified: getTokens,
- } as const,
+ return {
+ api: apiMaker([dexhunterApi, muesliswapApi]),
+ clearStorage: storage.clear,
+ slippage: storage.slippage,
+ updateAggregatorTokensHeld,
+ aggregatorTokenIds: [milkTokenId, oldMilkTokenId],
}
+}
- return {
- price,
- clearStorage,
- slippage,
- order,
- tokens,
- pools,
- primaryTokenInfo,
- stakingKey,
- supportedProviders,
- frontendFeeTiers,
- aggregator,
- aggregatorTokenId,
- makeOrderCalculations,
- getBestPoolCalculation,
- selectedPoolCalculationSelector,
- } as const
+const apiMaker = (adapters: Array): Swap.Api => {
+ return adapters[0]!
}
diff --git a/packages/swap/src/tokenInfo.mocks.ts b/packages/swap/src/tokenInfo.mocks.ts
deleted file mode 100644
index d42c6d949b..0000000000
--- a/packages/swap/src/tokenInfo.mocks.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-import {createPrimaryTokenInfo} from '@yoroi/portfolio'
-import {Portfolio} from '@yoroi/types'
-import {freeze} from 'immer'
-
-const tokenInfoA: Portfolio.Token.Info = {
- id: 'tokenA.',
- decimals: 6,
-
- name: '',
- description: '',
- symbol: '',
- ticker: '',
- website: '',
- tag: '',
- reference: '',
- fingerprint: '',
- originalImage: '',
-
- nature: Portfolio.Token.Nature.Secondary,
- type: Portfolio.Token.Type.FT,
- application: Portfolio.Token.Application.General,
- status: Portfolio.Token.Status.Valid,
-}
-
-const tokenInfoB: Portfolio.Token.Info = {
- id: 'tokenB.',
- decimals: 6,
-
- name: '',
- description: '',
- symbol: '',
- ticker: '',
- website: '',
- tag: '',
- reference: '',
- fingerprint: '',
- originalImage: '',
-
- nature: Portfolio.Token.Nature.Secondary,
- type: Portfolio.Token.Type.FT,
- application: Portfolio.Token.Application.General,
- status: Portfolio.Token.Status.Valid,
-}
-
-const tokenInfoLP: Portfolio.Token.Info = {
- id: 'lp.',
- decimals: 6,
-
- name: '',
- description: '',
- symbol: '',
- ticker: '',
- website: '',
- tag: '',
- reference: '',
- fingerprint: '',
- originalImage: '',
-
- nature: Portfolio.Token.Nature.Secondary,
- type: Portfolio.Token.Type.FT,
- application: Portfolio.Token.Application.General,
- status: Portfolio.Token.Status.Valid,
-}
-
-const tokenInfoC: Portfolio.Token.Info = {
- id: 'tokenC.',
- decimals: 2,
-
- name: '',
- description: '',
- symbol: '',
- ticker: '',
- website: '',
- tag: '',
- reference: '',
- fingerprint: '',
- originalImage: '',
-
- nature: Portfolio.Token.Nature.Secondary,
- type: Portfolio.Token.Type.FT,
- application: Portfolio.Token.Application.General,
- status: Portfolio.Token.Status.Valid,
-}
-
-const tokenInfoPT = createPrimaryTokenInfo({
- decimals: 6,
-
- description: '',
- name: '',
- originalImage: '',
- reference: '',
- symbol: '',
- tag: '',
- ticker: '',
- website: '',
-})
-
-export const tokenInfoMocks = freeze(
- {
- a: tokenInfoA,
- b: tokenInfoB,
- c: tokenInfoC,
- pt: tokenInfoPT,
- lp: tokenInfoLP,
- },
- true,
-)
diff --git a/packages/swap/src/translators/constants.ts b/packages/swap/src/translators/constants.ts
deleted file mode 100644
index fb162f2cba..0000000000
--- a/packages/swap/src/translators/constants.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import {Swap} from '@yoroi/types'
-
-// openswap supported providers
-export const supportedProviders: ReadonlyArray = [
- 'minswap',
- 'wingriders',
- 'sundaeswap',
- 'muesliswap',
- 'muesliswap_v2',
- 'vyfi',
-] as const
-
-// openswap discount tokens
-export const milkTokenId = {
- mainnet: '8a1cfae21368b8bebbbed9800fec304e95cce39a2a57dc35e2e3ebaa.4d494c4b',
- preprod: '8a1cfae21368b8bebbbed9800fec304e95cce39a2a57dc35e2e3ebaa.4d494c4b',
-} as const
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwap.tsx b/packages/swap/src/translators/reactjs/hooks/useSwap.tsx
deleted file mode 100644
index ca33bccaed..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwap.tsx
+++ /dev/null
@@ -1,4 +0,0 @@
-import * as React from 'react'
-import {SwapContext} from '../provider/SwapProvider'
-
-export const useSwap = () => React.useContext(SwapContext)
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapCreateOrder.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapCreateOrder.test.tsx
deleted file mode 100644
index 6d0a9405fa..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapCreateOrder.test.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import {QueryClient} from 'react-query'
-import {renderHook, act} from '@testing-library/react-hooks'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager} from '../../../manager.mocks'
-import {apiMocks} from '../../../adapters/openswap-api/api.mocks'
-import {useSwapCreateOrder} from './useSwapCreateOrder'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-
-describe('useSwapCreateOrder', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- mockSwapManager.order.create = jest.fn().mockResolvedValue(undefined)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
-
- const {result, waitFor: waitForHook} = renderHook(
- () => useSwapCreateOrder(),
- {wrapper},
- )
-
- await act(async () =>
- result.current.createOrderData(apiMocks.createOrderData),
- )
-
- await waitForHook(() => expect(result.current.isLoading).toBe(false))
-
- expect(mockSwapManager.order.create).toHaveBeenCalledTimes(1)
- expect(mockSwapManager.order.create).toHaveBeenCalledWith(
- apiMocks.createOrderData,
- )
- expect(result.current.isError).toBe(false)
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapCreateOrder.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapCreateOrder.tsx
deleted file mode 100644
index 4d4cae4615..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapCreateOrder.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {UseMutationOptions} from 'react-query'
-import {useMutationWithInvalidations} from '@yoroi/common'
-
-import {useSwap} from './useSwap'
-
-export const useSwapCreateOrder = (
- options?: UseMutationOptions<
- Swap.CreateOrderResponse,
- Error,
- Swap.CreateOrderData
- >,
-) => {
- const {order, stakingKey} = useSwap()
-
- const mutation = useMutationWithInvalidations({
- mutationFn: (orderData) => order.create(orderData),
- invalidateQueries: [
- ['useSwapOrdersByStatusOpen', stakingKey],
- ['useSwapOrdersByStatusCompleted', stakingKey],
- ],
- useErrorBoundary: true,
- ...options,
- })
-
- return {
- createOrderData: mutation.mutate,
- ...mutation,
- }
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusCompleted.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusCompleted.test.tsx
deleted file mode 100644
index 5c0f42534e..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusCompleted.test.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import * as React from 'react'
-import {QueryClient} from 'react-query'
-import {Text, View} from 'react-native'
-import {render, waitFor} from '@testing-library/react-native'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager, swapManagerMocks} from '../../../manager.mocks'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-import {useSwapOrdersByStatusCompleted} from './useSwapOrdersByStatusCompleted'
-import {storageSerializer} from '@yoroi/common'
-
-describe('useSwapOrdersByStatusCompleted', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- const TestCompletedOrders = () => {
- const orders = useSwapOrdersByStatusCompleted()
- return (
-
- {storageSerializer(orders)}
-
- )
- }
- mockSwapManager.order.list.byStatusCompleted = jest
- .fn()
- .mockResolvedValue(swapManagerMocks.listOrdersByStatusCompletedResponse)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('orders')).toBeDefined()
- })
-
- expect(getByTestId('orders').props.children).toEqual(
- storageSerializer(swapManagerMocks.listOrdersByStatusCompletedResponse),
- )
- })
-
- it('error', async () => {
- const TestCompletedOrders = () => {
- const orders = useSwapOrdersByStatusCompleted()
- return (
-
- {storageSerializer(orders)}
-
- )
- }
- mockSwapManager.order.list.byStatusCompleted = jest
- .fn()
- .mockResolvedValue(null)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('hasError')).toBeDefined()
- })
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusCompleted.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusCompleted.tsx
deleted file mode 100644
index dc1ea15857..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusCompleted.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {UseQueryOptions, useQuery} from 'react-query'
-
-import {useSwap} from './useSwap'
-
-export const useSwapOrdersByStatusCompleted = (
- options?: UseQueryOptions<
- Swap.CompletedOrderResponse,
- Error,
- Swap.CompletedOrderResponse,
- ['useSwapOrdersByStatusCompleted', string]
- >,
-) => {
- const {order, stakingKey} = useSwap()
-
- const query = useQuery({
- suspense: true,
- queryKey: ['useSwapOrdersByStatusCompleted', stakingKey],
- ...options,
- queryFn: order.list.byStatusCompleted,
- })
-
- if (query.data == null)
- throw new Error(
- '[@yoroi/swap] useSwapOrdersByStatusCompleted invalid state',
- )
-
- return query.data
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusOpen.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusOpen.test.tsx
deleted file mode 100644
index 736e96de57..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusOpen.test.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-import * as React from 'react'
-import {QueryClient} from 'react-query'
-import {Text, View} from 'react-native'
-import {render, waitFor} from '@testing-library/react-native'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager, swapManagerMocks} from '../../../manager.mocks'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-import {useSwapOrdersByStatusOpen} from './useSwapOrdersByStatusOpen'
-import {storageSerializer} from '@yoroi/common'
-
-describe('useSwapOrdersByStatusOpen', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- const TestOpenedOrders = () => {
- const orders = useSwapOrdersByStatusOpen()
- return (
-
- {storageSerializer(orders)}
-
- )
- }
- mockSwapManager.order.list.byStatusOpen = jest
- .fn()
- .mockResolvedValue(swapManagerMocks.listOrdersByStatusOpenResponse)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('orders')).toBeDefined()
- })
-
- expect(getByTestId('orders').props.children).toEqual(
- storageSerializer(swapManagerMocks.listOrdersByStatusOpenResponse),
- )
- expect(mockSwapManager.order.list.byStatusOpen).toHaveBeenCalled()
- })
-
- it('error', async () => {
- const TestOpenedOrders = () => {
- const orders = useSwapOrdersByStatusOpen()
- return (
-
- {storageSerializer(orders)}
-
- )
- }
- mockSwapManager.order.list.byStatusOpen = jest.fn().mockResolvedValue(null)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('hasError')).toBeDefined()
- })
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusOpen.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusOpen.tsx
deleted file mode 100644
index b16f0ee7b8..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapOrdersByStatusOpen.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import {Swap} from '@yoroi/types'
-import {UseQueryOptions, useQuery} from 'react-query'
-
-import {useSwap} from './useSwap'
-
-export const useSwapOrdersByStatusOpen = (
- options?: UseQueryOptions<
- Swap.OpenOrderResponse,
- Error,
- Swap.OpenOrderResponse,
- ['useSwapOrdersByStatusOpen', string]
- >,
-) => {
- const {order, stakingKey} = useSwap()
- const query = useQuery({
- suspense: true,
- queryKey: ['useSwapOrdersByStatusOpen', stakingKey],
- ...options,
- queryFn: order.list.byStatusOpen,
- })
-
- if (query.data == null)
- throw new Error('[@yoroi/swap] useSwapOrdersByStatusOpen invalid state')
-
- return query.data
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapPoolsByPair.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapPoolsByPair.test.tsx
deleted file mode 100644
index 044a6ff584..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapPoolsByPair.test.tsx
+++ /dev/null
@@ -1,58 +0,0 @@
-import * as React from 'react'
-import {QueryClient} from 'react-query'
-import {Text, View} from 'react-native'
-import {render, waitFor} from '@testing-library/react-native'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager, swapManagerMocks} from '../../../manager.mocks'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-import {useSwapPoolsByPair} from './useSwapPoolsByPair'
-import {storageSerializer} from '@yoroi/common'
-
-describe('useSwapPoolsByPair', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- const TestPoolsByPair = () => {
- const pools = useSwapPoolsByPair({
- tokenA: 'token.A',
- tokenB: 'token.B',
- })
- return (
-
- {storageSerializer(pools.data)}
-
- )
- }
- mockSwapManager.pools.list.byPair = jest
- .fn()
- .mockResolvedValue(swapManagerMocks.listPoolsByPairResponse)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('pools')).toBeDefined()
- })
-
- expect(getByTestId('pools').props.children).toEqual(
- storageSerializer(swapManagerMocks.listPoolsByPairResponse),
- )
- expect(mockSwapManager.pools.list.byPair).toHaveBeenCalled()
- expect(mockSwapManager.pools.list.byPair).toHaveBeenCalledWith({
- tokenA: 'token.A',
- tokenB: 'token.B',
- })
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapPoolsByPair.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapPoolsByPair.tsx
deleted file mode 100644
index 49c856bf3f..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapPoolsByPair.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import {Portfolio, Swap} from '@yoroi/types'
-import {UseQueryOptions, useQuery} from 'react-query'
-
-import {useSwap} from './useSwap'
-
-export const useSwapPoolsByPair = (
- tokenPair: {
- tokenA: Portfolio.Token.Id
- tokenB: Portfolio.Token.Id
- },
- options?: UseQueryOptions<
- Swap.Pool[],
- Error,
- Swap.Pool[],
- [
- 'usePoolsByPair',
- {
- tokenA: Portfolio.Token.Id
- tokenB: Portfolio.Token.Id
- },
- ]
- >,
-) => {
- const {pools} = useSwap()
-
- const query = useQuery({
- suspense: true,
- enabled: tokenPair?.tokenA !== undefined && tokenPair?.tokenB !== undefined,
- queryKey: ['usePoolsByPair', tokenPair],
- ...options,
- queryFn: () => pools.list.byPair(tokenPair),
- })
-
- return {
- ...query,
- poolList: query.data,
- }
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapSetSlippage.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapSetSlippage.test.tsx
deleted file mode 100644
index 14052be2b5..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapSetSlippage.test.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-import * as React from 'react'
-import {QueryClient, QueryClientProvider} from 'react-query'
-import {renderHook, act} from '@testing-library/react-hooks'
-
-import {SwapProvider} from '../provider/SwapProvider'
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager} from '../../../manager.mocks'
-import {useSwapSetSlippage} from './useSwapSetSlippage'
-
-describe('useSwapSetSlippage', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- mockSwapManager.slippage.save = jest.fn().mockResolvedValue(undefined)
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result, waitFor: waitForHook} = renderHook(
- () => useSwapSetSlippage(),
- {wrapper},
- )
-
- await act(async () => {
- result.current(1.1)
- })
-
- await waitForHook(() => expect(result.current).toBeDefined())
-
- expect(mockSwapManager.slippage.save).toHaveBeenCalledTimes(1)
- expect(mockSwapManager.slippage.save).toHaveBeenCalledWith(1.1)
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapSetSlippage.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapSetSlippage.tsx
deleted file mode 100644
index cedd352ab4..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapSetSlippage.tsx
+++ /dev/null
@@ -1,20 +0,0 @@
-import {UseMutationOptions} from 'react-query'
-
-import {useSwap} from './useSwap'
-import {useMutationWithInvalidations} from '@yoroi/common'
-import {swapStorageSlippageKey} from '../../../adapters/async-storage/storage'
-
-export const useSwapSetSlippage = (
- options?: UseMutationOptions,
-) => {
- const {slippage} = useSwap()
-
- const mutation = useMutationWithInvalidations({
- useErrorBoundary: true,
- invalidateQueries: [[swapStorageSlippageKey]],
- ...options,
- mutationFn: slippage.save,
- })
-
- return mutation.mutate
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapSlippage.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapSlippage.test.tsx
deleted file mode 100644
index 95dd0e0857..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapSlippage.test.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import * as React from 'react'
-import {QueryClient} from 'react-query'
-import {Text, View} from 'react-native'
-import {render, waitFor} from '@testing-library/react-native'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager} from '../../../manager.mocks'
-import {useSwapSlippage} from './useSwapSlippage'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-
-describe('useSwapSlippage', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- const TestSwapSlippage = () => {
- const slippage = useSwapSlippage()
- return (
-
- {slippage}
-
- )
- }
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
-
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('slippage')).toBeDefined()
- })
-
- expect(getByTestId('slippage').props.children).toBe(0.1)
- })
-
- it('error', async () => {
- const TestSwapSlippage = () => {
- const slippage = useSwapSlippage()
- return (
-
- {slippage}
-
- )
- }
- mockSwapManager.slippage.read = jest.fn().mockResolvedValue(null)
-
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('hasError')).toBeDefined()
- })
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapSlippage.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapSlippage.tsx
deleted file mode 100644
index fa5bd394b3..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapSlippage.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import {UseQueryOptions, useQuery} from 'react-query'
-
-import {swapStorageSlippageKey} from '../../../adapters/async-storage/storage'
-import {useSwap} from './useSwap'
-
-export const useSwapSlippage = (
- options?: UseQueryOptions,
-) => {
- const {slippage} = useSwap()
- const query = useQuery({
- suspense: true,
- queryKey: [swapStorageSlippageKey],
- ...options,
- queryFn: slippage.read,
- })
-
- if (query.data == null)
- throw new Error('[@yoroi/swap] useSwapSlippage invalid state')
-
- return query.data
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapTokensByPair.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapTokensByPair.test.tsx
deleted file mode 100644
index 7adc335d2d..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapTokensByPair.test.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import * as React from 'react'
-import {QueryClient} from 'react-query'
-import {Text, View} from 'react-native'
-import {render, waitFor} from '@testing-library/react-native'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager, swapManagerMocks} from '../../../manager.mocks'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-import {useSwapTokensByPair} from './useSwapTokensByPair'
-
-describe('useSwapTokensByPair', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- const TestPairListToken = () => {
- const tokens = useSwapTokensByPair('.')
- return (
-
- {JSON.stringify(tokens.data)}
-
- )
- }
-
- mockSwapManager.tokens.list.byPair = jest
- .fn()
- .mockResolvedValue(swapManagerMocks.listTokensByPairResponse)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('tokens')).toBeDefined()
- })
-
- expect(getByTestId('tokens').props.children).toEqual(
- JSON.stringify(swapManagerMocks.listTokensByPairResponse),
- )
- expect(mockSwapManager.tokens.list.byPair).toHaveBeenCalled()
- expect(mockSwapManager.tokens.list.byPair).toHaveBeenCalledWith('.')
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapTokensByPair.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapTokensByPair.tsx
deleted file mode 100644
index 973ac12381..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapTokensByPair.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import {Portfolio} from '@yoroi/types'
-import {UseQueryOptions, useQuery} from 'react-query'
-
-import {useSwap} from './useSwap'
-
-export const useSwapTokensByPair = (
- tokenIdBase: Portfolio.Token.Id,
- options?: UseQueryOptions<
- Array,
- Error,
- Array,
- ['useSwapTokensByPair', string]
- >,
-) => {
- const {tokens} = useSwap()
-
- const query = useQuery({
- suspense: true,
- queryKey: ['useSwapTokensByPair', tokenIdBase],
- ...options,
- queryFn: () => tokens.list.byPair(tokenIdBase),
- })
-
- return {
- ...query,
- tokensByPair: query.data,
- }
-}
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapTokensOnlyVerified.test.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapTokensOnlyVerified.test.tsx
deleted file mode 100644
index d3b105f969..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapTokensOnlyVerified.test.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-import * as React from 'react'
-import {QueryClient} from 'react-query'
-import {Text, View} from 'react-native'
-import {render, waitFor} from '@testing-library/react-native'
-
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {mockSwapManager, swapManagerMocks} from '../../../manager.mocks'
-import {wrapperManagerFixture} from '../../../fixtures/manager-wrapper'
-import {useSwapTokensOnlyVerified} from './useSwapTokensOnlyVerified'
-
-describe('useSwapTokensOnlyVerified', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('success', async () => {
- const TestListToken = () => {
- const tokens = useSwapTokensOnlyVerified()
- return (
-
- {JSON.stringify(tokens)}
-
- )
- }
-
- mockSwapManager.tokens.list.onlyVerified = jest
- .fn()
- .mockResolvedValue(swapManagerMocks.listOnlyVerifiedTokensResponse)
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('tokens')).toBeDefined()
- })
-
- expect(getByTestId('tokens').props.children).toEqual(
- JSON.stringify(swapManagerMocks.listOnlyVerifiedTokensResponse),
- )
- expect(mockSwapManager.tokens.list.onlyVerified).toHaveBeenCalled()
- })
-
- it('empty result (no-api data) should return []', async () => {
- mockSwapManager.tokens.list.onlyVerified = jest
- .fn()
- .mockResolvedValue(undefined)
-
- const TestListToken = () => {
- const tokens = useSwapTokensOnlyVerified()
- return (
-
- {JSON.stringify(tokens)}
-
- )
- }
-
- const wrapper = wrapperManagerFixture({
- queryClient,
- swapManager: mockSwapManager,
- })
- const {getByTestId} = render(, {wrapper})
-
- await waitFor(() => {
- expect(getByTestId('tokens')).toBeDefined()
- })
- expect(getByTestId('tokens').props.children).toEqual(JSON.stringify([]))
- })
-})
diff --git a/packages/swap/src/translators/reactjs/hooks/useSwapTokensOnlyVerified.tsx b/packages/swap/src/translators/reactjs/hooks/useSwapTokensOnlyVerified.tsx
deleted file mode 100644
index 0bcbba66b6..0000000000
--- a/packages/swap/src/translators/reactjs/hooks/useSwapTokensOnlyVerified.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import {Portfolio} from '@yoroi/types'
-import {UseQueryOptions, useQuery} from 'react-query'
-
-import {useSwap} from './useSwap'
-
-export const useSwapTokensOnlyVerified = (
- options?: UseQueryOptions<
- Array,
- Error,
- Array,
- ['useSwapTokensOnlyVerified']
- >,
-) => {
- const {tokens} = useSwap()
-
- const query = useQuery({
- suspense: true,
- queryKey: ['useSwapTokensOnlyVerified'],
- ...options,
- queryFn: () => tokens.list.onlyVerified(),
- })
-
- return query.data ?? []
-}
diff --git a/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx b/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx
deleted file mode 100644
index 5799a2e87a..0000000000
--- a/packages/swap/src/translators/reactjs/provider/SwapProvider.test.tsx
+++ /dev/null
@@ -1,712 +0,0 @@
-import * as React from 'react'
-import {QueryClient, QueryClientProvider} from 'react-query'
-import {renderHook, act} from '@testing-library/react-hooks'
-import {AppApi} from '@yoroi/api'
-
-import {SwapProvider} from './SwapProvider'
-import {mockSwapManager, swapManagerMocks} from '../../../manager.mocks'
-import {SwapState, defaultSwapState} from '../state/state'
-import {queryClientFixture} from '../../../fixtures/query-client'
-import {useSwap} from '../hooks/useSwap'
-import {mocks} from '../../../helpers/mocks'
-import {Portfolio} from '@yoroi/types'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-describe('SwapProvider', () => {
- let queryClient: QueryClient
-
- beforeEach(() => {
- jest.clearAllMocks()
- queryClient = queryClientFixture()
- })
-
- afterEach(() => {
- queryClient.clear()
- })
-
- it('OrderTypeChanged', () => {
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.orderTypeChanged('limit')
- })
-
- expect(result.current.orderData.type).toBe('limit')
- })
-
- it('SelectedPoolChanged', () => {
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.selectedPoolChanged(
- swapManagerMocks.listPoolsByPairResponse[0]?.poolId!,
- )
- })
-
- // initial state = market order
- expect(result.current.orderData.selectedPoolId).toBeUndefined()
-
- act(() => {
- result.current.orderTypeChanged('limit')
- })
-
- act(() => {
- result.current.selectedPoolChanged(
- swapManagerMocks.listPoolsByPairResponse[0]?.poolId!,
- )
- })
-
- expect(result.current.orderData.selectedPoolId).toEqual(
- swapManagerMocks.listPoolsByPairResponse[0]?.poolId,
- )
- })
-
- it('SlippageChanged', () => {
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.slippageChanged(3)
- })
-
- expect(result.current.orderData.slippage).toBe(3)
- })
-
- it('UnsignedTxChanged', () => {
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.unsignedTxChanged({
- hash: 'hash',
- })
- })
-
- expect(result.current.unsignedTx).toEqual({hash: 'hash'})
- })
-
- describe('LimitPriceChanged', () => {
- it('should not update limit price if order type is market', () => {
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.limitPriceChanged('3')
- })
-
- expect(result.current.orderData.limitPrice).toBeUndefined()
- })
-
- it('should update limit price if order type is market', () => {
- const wrapper = ({children}: any) => (
-
- {children}
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.orderTypeChanged('limit')
- result.current.limitPriceChanged('3')
- })
-
- expect(result.current.orderData.limitPrice).toBe('3')
- })
- })
-
- it('SwitchTokens market', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: asTokenAmount({
- quantity: 10n,
- tokenId: 'tokenA.',
- }),
- buy: asTokenAmount({
- quantity: 20n,
- tokenId: 'tokenB.',
- }),
- },
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.switchTokens()
- })
-
- expect(result.current.orderData.amounts).toEqual<{
- sell: Portfolio.Token.Amount
- buy: Portfolio.Token.Amount
- }>({
- sell: asTokenAmount({
- quantity: 20n,
- tokenId: 'tokenB.',
- }),
- buy: asTokenAmount({
- quantity: 10n,
- tokenId: 'tokenA.',
- }),
- })
- })
-
- it('SwitchTokens limit', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- type: 'limit',
- limitPrice: '2',
- amounts: {
- sell: asTokenAmount({
- quantity: 10n,
- tokenId: 'tokenA.',
- }),
- buy: asTokenAmount({
- quantity: 20n,
- tokenId: 'tokenB.',
- }),
- },
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.switchTokens()
- })
-
- expect(result.current.orderData.amounts).toEqual<{
- sell: Portfolio.Token.Amount
- buy: Portfolio.Token.Amount
- }>({
- sell: asTokenAmount({
- quantity: 20n,
- tokenId: 'tokenB.',
- }),
- buy: asTokenAmount({
- quantity: 10n,
- tokenId: 'tokenA.',
- }),
- })
-
- act(() => {
- result.current.switchTokens()
- })
-
- expect(result.current.orderData.amounts).toEqual({
- sell: asTokenAmount({
- quantity: 10n,
- tokenId: 'tokenA.',
- }),
- buy: asTokenAmount({
- quantity: 20n,
- tokenId: 'tokenB.',
- }),
- })
- })
-
- it('ResetQuantities', () => {
- const initiState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: asTokenAmount({
- quantity: 1n,
- tokenId: 'tokenA.',
- }),
- buy: asTokenAmount({
- quantity: 2n,
- tokenId: 'tokenB.',
- }),
- },
- limitPrice: '3',
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.resetQuantities()
- })
-
- expect(result.current.orderData.amounts).toEqual<{
- sell: Portfolio.Token.Amount
- buy: Portfolio.Token.Amount
- }>({
- sell: asTokenAmount({
- quantity: 0n,
- tokenId: 'tokenA.',
- }),
- buy: asTokenAmount({
- quantity: 0n,
- tokenId: 'tokenB.',
- }),
- })
- expect(result.current.orderData.limitPrice).toEqual(undefined)
- })
-
- it('ResetState', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: asTokenAmount({
- quantity: 1n,
- tokenId: 'policyId.sell',
- }),
- buy: asTokenAmount({
- quantity: 2n,
- tokenId: 'policyId.buy',
- }),
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.resetState()
- })
-
- expect(result.current.orderData).toEqual(defaultSwapState.orderData)
- expect(result.current.unsignedTx).toBeUndefined()
- })
-
- it('BuyQuantityChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: asTokenAmount({
- quantity: 10n,
- tokenId: 'policyId.sell',
- }),
- buy: asTokenAmount({
- quantity: 20n,
- tokenId: 'policyId.buy',
- }),
- },
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.buyQuantityChanged(30n)
- })
-
- expect(result.current.orderData.amounts).toEqual({
- sell: asTokenAmount({
- quantity: 10n,
- tokenId: 'policyId.sell',
- }),
- buy: asTokenAmount({
- quantity: 30n,
- tokenId: 'policyId.buy',
- }),
- })
- })
-
- it('SellQuantityChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: asTokenAmount({
- quantity: 10n,
- tokenId: 'policyId.sell',
- }),
- buy: asTokenAmount({
- quantity: 20n,
- tokenId: 'policyId.buy',
- }),
- },
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.sellQuantityChanged(30n)
- })
-
- expect(result.current.orderData.amounts).toEqual({
- sell: asTokenAmount({
- quantity: 30n,
- tokenId: 'policyId.sell',
- }),
- buy: asTokenAmount({
- quantity: 20n,
- tokenId: 'policyId.buy',
- }),
- })
- })
-
- it('LpTokenHeldChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- lpTokenHeld: undefined,
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.lpTokenHeldChanged(
- asTokenAmount({
- quantity: 30n,
- tokenId: 'policyId.tokenHeld',
- }),
- )
- })
-
- expect(result.current.orderData.lpTokenHeld).toEqual(
- asTokenAmount({
- quantity: 30n,
- tokenId: 'policyId.tokenHeld',
- }),
- )
- })
-
- it('BuyTokenInfoChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: {
- quantity: 10n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 20n,
- info: tokenInfoMocks.b,
- },
- },
- tokens: {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.buyTokenInfoChanged(tokenInfoMocks.c)
- })
-
- expect(
- result.current.orderData.amounts.buy,
- ).toEqual({
- quantity: 20n,
- info: tokenInfoMocks.c,
- })
- expect(result.current.orderData.tokens.priceDenomination).toBe(4)
- })
-
- it('SellTokenInfoChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- amounts: {
- sell: {
- quantity: 1000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 20n,
- info: tokenInfoMocks.b,
- },
- },
- tokens: {
- priceDenomination: 0,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.sellTokenInfoChanged(tokenInfoMocks.c)
- })
-
- expect(
- result.current.orderData.amounts.sell,
- ).toEqual({
- quantity: 100n,
- info: tokenInfoMocks.c,
- })
- expect(result.current.orderData.tokens.priceDenomination).toBe(-4)
- })
-
- it('PoolPairsChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- tokens: {
- ...defaultSwapState.orderData.tokens,
- ptInfo: tokenInfoMocks.pt,
- },
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.poolPairsChanged(mocks.mockedPools1)
- })
-
- expect(result.current.orderData.pools).toEqual(mocks.mockedPools1)
- })
-
- it('PrimaryTokenIdChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.primaryTokenInfoChanged(tokenInfoMocks.pt)
- })
-
- expect(result.current.orderData.tokens.ptInfo).toEqual(tokenInfoMocks.pt)
- })
-
- it('FrontendFeeTiersChanged', () => {
- const initialState: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- },
- unsignedTx: undefined,
- }
- const wrapper = ({children}: any) => (
-
-
- {children}
-
-
- )
-
- const {result} = renderHook(() => useSwap(), {
- wrapper,
- })
-
- act(() => {
- result.current.frontendFeeTiersChanged(
- AppApi.mockGetFrontendFees.withFees.muesliswap!,
- )
- })
-
- expect(result.current.orderData.frontendFeeTiers).toEqual(
- AppApi.mockGetFrontendFees.withFees.muesliswap!,
- )
- })
-})
-
-function asTokenAmount(
- {
- tokenId,
- quantity,
- }: {
- tokenId: Portfolio.Token.Id
- quantity: bigint
- },
- decimals = 6,
-) {
- const amount: Portfolio.Token.Amount = {
- quantity,
- info: {
- id: tokenId,
- decimals,
-
- application: Portfolio.Token.Application.Coin,
- nature: Portfolio.Token.Nature.Secondary,
- status: Portfolio.Token.Status.Valid,
- type: Portfolio.Token.Type.FT,
-
- fingerprint: '',
- name: '',
- ticker: '',
- description: '',
- symbol: '',
- tag: '',
- reference: '',
- website: '',
- originalImage: '',
- },
- }
-
- return amount
-}
diff --git a/packages/swap/src/translators/reactjs/provider/SwapProvider.tsx b/packages/swap/src/translators/reactjs/provider/SwapProvider.tsx
deleted file mode 100644
index f7488c5ad7..0000000000
--- a/packages/swap/src/translators/reactjs/provider/SwapProvider.tsx
+++ /dev/null
@@ -1,114 +0,0 @@
-import * as React from 'react'
-import {App, Portfolio, Swap} from '@yoroi/types'
-
-import {
- SwapActionType,
- SwapActions,
- SwapCreateOrderActionType,
- SwapCreateOrderActions,
- SwapState,
- combinedSwapReducers,
- defaultSwapActions,
- defaultSwapState,
-} from '../state/state'
-import {mockSwapManagerDefault} from '../../../manager.mocks'
-
-const defaultSwapManager: Swap.Manager = mockSwapManagerDefault
-
-type SwapProviderContext = React.PropsWithChildren<
- SwapState & SwapCreateOrderActions & SwapActions & Swap.Manager
->
-
-const initialSwapProvider: SwapProviderContext = {
- ...defaultSwapState,
- ...defaultSwapActions,
- ...defaultSwapManager,
-}
-
-export const SwapContext =
- React.createContext(initialSwapProvider)
-
-export const SwapProvider = ({
- children,
- swapManager,
- initialState,
-}: {
- children: React.ReactNode
- swapManager: Swap.Manager
- initialState?: SwapState
-}) => {
- const [state, dispatch] = React.useReducer(combinedSwapReducers, {
- ...defaultSwapState,
- ...initialState,
- })
- const actions = React.useRef({
- orderTypeChanged: (orderType: Swap.OrderType) => {
- dispatch({type: SwapCreateOrderActionType.OrderTypeChanged, orderType})
- },
- selectedPoolChanged: (poolId: string) => {
- dispatch({type: SwapCreateOrderActionType.SelectedPoolChanged, poolId})
- },
- slippageChanged: (newSlippage: number) => {
- dispatch({
- type: SwapCreateOrderActionType.SlippageChanged,
- slippage: newSlippage,
- })
- },
- switchTokens: () => {
- dispatch({type: SwapCreateOrderActionType.SwitchTokens})
- },
- resetQuantities: () => {
- dispatch({type: SwapCreateOrderActionType.ResetQuantities})
- },
- unsignedTxChanged: (unsignedTx: any) => {
- dispatch({type: SwapActionType.UnsignedTxChanged, unsignedTx})
- },
- resetState: () => {
- dispatch({type: SwapActionType.ResetState})
- },
- limitPriceChanged: (limitPrice: string) => {
- dispatch({type: SwapCreateOrderActionType.LimitPriceChanged, limitPrice})
- },
- //
- buyQuantityChanged: (quantity: bigint) => {
- dispatch({type: SwapCreateOrderActionType.BuyQuantityChanged, quantity})
- },
- sellQuantityChanged: (quantity: bigint) => {
- dispatch({type: SwapCreateOrderActionType.SellQuantityChanged, quantity})
- },
- lpTokenHeldChanged: (amount: Portfolio.Token.Amount | undefined) => {
- dispatch({type: SwapCreateOrderActionType.LpTokenHeldChanged, amount})
- },
- buyTokenInfoChanged: (tokenInfo: Portfolio.Token.Info) => {
- dispatch({type: SwapCreateOrderActionType.BuyTokenInfoChanged, tokenInfo})
- },
- sellTokenInfoChanged: (tokenInfo: Portfolio.Token.Info) => {
- dispatch({
- type: SwapCreateOrderActionType.SellTokenInfoChanged,
- tokenInfo,
- })
- },
- poolPairsChanged: (pools: ReadonlyArray) => {
- dispatch({type: SwapCreateOrderActionType.PoolPairsChanged, pools})
- },
- primaryTokenInfoChanged: (tokenInfo: Portfolio.Token.Info) => {
- dispatch({
- type: SwapCreateOrderActionType.PrimaryTokenInfoChanged,
- tokenInfo,
- })
- },
- frontendFeeTiersChanged: (feeTiers: ReadonlyArray) => {
- dispatch({
- type: SwapCreateOrderActionType.FrontendFeeTiersChanged,
- feeTiers,
- })
- },
- }).current
-
- const context = React.useMemo(
- () => ({...state, ...actions, ...swapManager}),
- [state, actions, swapManager],
- )
-
- return {children}
-}
diff --git a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts b/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts
deleted file mode 100644
index 8a2b6f3f69..0000000000
--- a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.test.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-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 = {
- type: 'limit' as Swap.OrderType,
- selectedPoolId: '1',
- calculations: [
- {pool: {poolId: '1'}} as Swap.OrderCalculation,
- {pool: {poolId: '2'}} as Swap.OrderCalculation,
- ],
- bestPoolCalculation: {
- pool: {poolId: '3'},
- } as Swap.OrderCalculation,
- }
-
- const selected = selectedPoolCalculationSelector(orderData)
- expect(selected).toEqual(orderData.calculations[0])
- })
-
- it('should return the state bestPoolCalculation when no match is found in calculations', () => {
- const orderData = {
- type: 'limit' as Swap.OrderType,
- selectedPoolId: '3',
- calculations: [
- {pool: {poolId: '1'}} as Swap.OrderCalculation,
- {pool: {poolId: '2'}} as Swap.OrderCalculation,
- ],
- bestPoolCalculation: {pool: {poolId: '3'}} as Swap.OrderCalculation,
- }
-
- const selected = selectedPoolCalculationSelector(orderData)
- expect(selected).toEqual(orderData.bestPoolCalculation)
- })
-
- it('should return state bestPool when type is market', () => {
- const orderData = {
- type: 'market' as Swap.OrderType,
- selectedPoolId: '1',
- calculations: [
- {pool: {poolId: '1'}} as Swap.OrderCalculation,
- {pool: {poolId: '2'}} as Swap.OrderCalculation,
- ],
- bestPoolCalculation: {pool: {poolId: '3'}} as Swap.OrderCalculation,
- }
-
- const selected = selectedPoolCalculationSelector(orderData)
- expect(selected).toEqual(orderData.bestPoolCalculation)
- })
-
- it('should return the the current bestPoolCalculation when no selectedPoolId', () => {
- const orderData = {
- type: 'limit' as Swap.OrderType,
- selectedPoolId: undefined,
- calculations: [
- {pool: {poolId: '1'}} as Swap.OrderCalculation,
- {pool: {poolId: '2'}} as Swap.OrderCalculation,
- ],
- bestPoolCalculation: {pool: {poolId: '3'}} as Swap.OrderCalculation,
- }
-
- const selected = selectedPoolCalculationSelector(orderData)
- expect(selected).toEqual(orderData.bestPoolCalculation)
- })
-})
diff --git a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts b/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts
deleted file mode 100644
index 15f7856ac6..0000000000
--- a/packages/swap/src/translators/reactjs/state/selectors/selectedPoolCalculationSelector.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import {Swap} from '@yoroi/types'
-
-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
- if (type === 'limit' && selectedPoolId !== undefined) {
- calculation = calculations.find(({pool}) => pool.poolId === selectedPoolId)
- }
-
- return calculation ?? bestPoolCalculation
-}
diff --git a/packages/swap/src/translators/reactjs/state/state.mocks.ts b/packages/swap/src/translators/reactjs/state/state.mocks.ts
deleted file mode 100644
index 8647379946..0000000000
--- a/packages/swap/src/translators/reactjs/state/state.mocks.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-import {SwapState, defaultSwapState} from './state'
-
-export const mockSwapStateDefault: SwapState = {
- orderData: {
- ...defaultSwapState.orderData,
- tokens: {
- ...defaultSwapState.orderData.tokens,
- ptInfo: tokenInfoMocks.pt,
- },
- type: 'market',
- amounts: {},
- limitPrice: '0',
- slippage: 1,
- selectedPoolId: undefined,
- calculations: [],
- lpTokenHeld: undefined,
- frontendFeeTiers: [],
- pools: [],
- },
- unsignedTx: undefined,
-} as const
diff --git a/packages/swap/src/translators/reactjs/state/state.test.ts b/packages/swap/src/translators/reactjs/state/state.test.ts
deleted file mode 100644
index 209de87735..0000000000
--- a/packages/swap/src/translators/reactjs/state/state.test.ts
+++ /dev/null
@@ -1,707 +0,0 @@
-import {produce} from 'immer'
-import {Portfolio} from '@yoroi/types'
-
-import {
- combinedSwapReducers,
- defaultSwapState,
- SwapCreateOrderActionType,
- SwapActionType,
- SwapCreateOrderAction,
- SwapAction,
- SwapState,
-} from './state'
-import {mockSwapStateDefault} from './state.mocks'
-import {mocks} from '../../../helpers/mocks'
-import {tokenInfoMocks} from '../../../tokenInfo.mocks'
-
-// NOTE: the calculations are tested on the factories
-// here is just testing the state behaviour
-describe('State Actions', () => {
- const mockedState: SwapState = {
- ...mockSwapStateDefault,
- orderData: {
- ...mockSwapStateDefault.orderData,
- amounts: {
- sell: {
- quantity: 100000000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- quantity: 1401162647n,
- info: tokenInfoMocks.b,
- },
- },
- limitPrice: undefined,
- slippage: 10,
- type: 'market',
- selectedPoolId: undefined,
- selectedPoolCalculation: undefined,
-
- pools: mocks.mockedPools1,
- calculations: mocks.mockedOrderCalculations1,
- bestPoolCalculation: mocks.mockedOrderCalculations1[0],
- },
- }
- it('unknown', () => {
- const action = {type: 'UNKNOWN'} as any
- const state = combinedSwapReducers(mockSwapStateDefault, action)
- expect(state).toEqual(mockSwapStateDefault)
- })
-
- describe('OrderTypeChanged', () => {
- it('change to limit', () => {
- const stateTypeChanged: SwapState = {
- ...mockSwapStateDefault,
- orderData: {
- ...mockSwapStateDefault.orderData,
- amounts: {
- sell: {
- quantity: 10000n,
- info: tokenInfoMocks.a,
- },
- buy: {
- info: tokenInfoMocks.b,
- quantity: 0n,
- },
- },
- limitPrice: undefined,
- slippage: 0,
- type: 'market',
- selectedPoolId: undefined,
- selectedPoolCalculation: undefined,
-
- pools: [],
- calculations: [],
- bestPoolCalculation: undefined,
- },
- }
-
- const action: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.OrderTypeChanged,
- orderType: 'limit',
- }
- const expectedState = produce(stateTypeChanged, (draft) => {
- draft.orderData.type = 'limit'
- })
- const state = combinedSwapReducers(expectedState, action)
- expect(state).toEqual(expectedState)
- })
-
- it('change to limit and back to market', () => {
- const stateTypeChanged: SwapState = {
- ...mockSwapStateDefault,
- orderData: {
- ...mockSwapStateDefault.orderData,
- amounts: {
- sell: {
- info: tokenInfoMocks.a,
- quantity: 100n,
- },
- buy: {
- info: tokenInfoMocks.b,
- quantity: 0n,
- },
- },
- tokens: {
- priceDenomination: 0,
- ptInfo: tokenInfoMocks.pt,
- },
- limitPrice: undefined,
- slippage: 0,
- type: 'market',
- selectedPoolId: undefined,
- selectedPoolCalculation: undefined,
-
- pools: [],
- calculations: [],
- bestPoolCalculation: undefined,
- },
- }
- const stateAfterPools = combinedSwapReducers(stateTypeChanged, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
-
- const actionLimit: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.OrderTypeChanged,
- orderType: 'limit',
- }
-
- const state = combinedSwapReducers(stateAfterPools, actionLimit)
-
- expect(state.orderData.type).toBe('limit')
- expect(state.orderData.limitPrice).toBe('0.5000000000')
- expect(state.orderData.amounts.buy?.quantity).toBe(200n)
-
- const actionMarket: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.OrderTypeChanged,
- orderType: 'market',
- }
-
- const stateBack = combinedSwapReducers(state, actionMarket)
- expect(stateBack.orderData.type).toBe('market')
- })
- })
-
- it('UnsignedTxChanged', () => {
- const action: SwapAction = {
- type: SwapActionType.UnsignedTxChanged,
- unsignedTx: {txHash: 'someHash'},
- }
- const expectedState = produce(mockSwapStateDefault, (draft) => {
- draft.unsignedTx = {txHash: 'someHash'}
- })
- const state = combinedSwapReducers(mockSwapStateDefault, action)
- expect(state).toEqual(expectedState)
- })
-
- it('ResetState', () => {
- const action: SwapAction = {type: SwapActionType.ResetState}
- const state = combinedSwapReducers(mockSwapStateDefault, action)
- expect(state).toEqual(defaultSwapState)
- })
-
- describe('SelectedPoolChanged', () => {
- describe('market', () => {
- it('should ignore', () => {
- const action: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.SelectedPoolChanged,
- poolId: '6',
- }
- const state = combinedSwapReducers(mockedState, action)
- expect(state).toEqual(mockedState)
- })
- })
-
- describe('limit', () => {
- it('should update pool if avaible and reset limit to market price', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- draft.orderData.type = 'limit'
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
- const updatedLimit = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.LimitPriceChanged,
- limitPrice: '2',
- })
-
- const state = combinedSwapReducers(updatedLimit, {
- type: SwapCreateOrderActionType.SelectedPoolChanged,
- poolId: '1',
- })
-
- // change back to market price
- expect(state.orderData.limitPrice).toBe('2.0000000000')
- expect(state.orderData.selectedPoolId).toBe('1')
- })
- })
- })
-
- it('SelectedPoolChanged limit (should updated the selected pool)', () => {
- const action: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.SelectedPoolChanged,
- poolId: '',
- }
-
- const limitedState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.type = 'limit'
- })
-
- const expectedState = produce(limitedState, (draft) => {
- draft.orderData.selectedPoolId = action.poolId
- })
- const state = combinedSwapReducers(limitedState, action)
- expect(state).toEqual(expectedState)
- })
-
- it('SlippageChanged', () => {
- const action: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.SlippageChanged,
- slippage: 2,
- }
- const expectedState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.slippage = action.slippage
- })
- const state = combinedSwapReducers(mockSwapStateDefault, action)
- expect(state).toEqual(expectedState)
- })
-
- // NOTE: switch tokens recalculate based on sell side
- // this cause every switch to update the quantities
- // when switchin tokens on a limit order the quantities may become too big
- // because the limit price is kept
- describe('SwitchTokens', () => {
- it('should change buy / sell and derive the calculation accordingly', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
-
- const state = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SwitchTokens,
- })
-
- expect(state.orderData.amounts.buy?.info.id).toBe('tokenA.')
- expect(state.orderData.amounts.sell?.info.id).toBe('tokenB.')
- })
- })
-
- describe('ResetQuantities (always reset selected pool)', () => {
- it('should reset limit to undefined when order is market', () => {
- const action: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.ResetQuantities,
- }
- const expectedState = produce(mockSwapStateDefault, (draft) => {
- if (draft.orderData.amounts.sell)
- draft.orderData.amounts.sell.quantity = 0n
- if (draft.orderData.amounts.buy)
- draft.orderData.amounts.buy.quantity = 0n
- draft.orderData.limitPrice = undefined
- })
- const state = combinedSwapReducers(mockSwapStateDefault, action)
- expect(state).toEqual(expectedState)
- })
-
- it('should reset limit to market price when order is limit', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- draft.orderData.type = 'limit'
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
- const updatedLimit = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.LimitPriceChanged,
- limitPrice: '0.5',
- })
-
- const state = combinedSwapReducers(updatedLimit, {
- type: SwapCreateOrderActionType.ResetQuantities,
- })
-
- // change back to market price
- expect(state.orderData.limitPrice).toBe('2.0000000000')
- })
- })
-
- describe('LimitPriceChanged', () => {
- it('should not update when order type is market', () => {
- const action: SwapCreateOrderAction = {
- type: SwapCreateOrderActionType.LimitPriceChanged,
- limitPrice: '2',
- }
- const state = combinedSwapReducers(mockSwapStateDefault, action)
- expect(state.orderData.limitPrice).toBe(
- mockSwapStateDefault.orderData.limitPrice,
- )
- })
-
- it('should update the limit and the buy side when pools are available', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- draft.orderData.type = 'limit'
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: [],
- })
-
- const state = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.LimitPriceChanged,
- limitPrice: '2',
- })
-
- expect(state.orderData.limitPrice).toBe('2')
- })
- })
-
- describe('SellTokenInfoChanged', () => {
- it('should reset pools and the derived data', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- draft.orderData.tokens = {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools1,
- })
- const updatedSellQuantity = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10_000n,
- })
-
- const state = combinedSwapReducers(updatedSellQuantity, {
- type: SwapCreateOrderActionType.SellTokenInfoChanged,
- tokenInfo: tokenInfoMocks.lp,
- })
-
- expect(state.orderData.amounts.sell!).toEqual({
- quantity: 10_000n,
- info: tokenInfoMocks.lp,
- })
- // should be updated right next with the new pool pairs
- expect(state.orderData.pools).toEqual([])
- // should reset everything derived
- expect(state.orderData.calculations).toEqual([])
- expect(state.orderData.selectedPoolCalculation).toBeUndefined()
- expect(state.orderData.bestPoolCalculation).toBeUndefined()
- // type is irrelevant
- expect(state.orderData.selectedPoolId).toBeUndefined()
- })
-
- it('should initiate sell side', () => {
- const state = combinedSwapReducers(mockSwapStateDefault, {
- type: SwapCreateOrderActionType.SellTokenInfoChanged,
- tokenInfo: tokenInfoMocks.lp,
- })
- expect(state.orderData.amounts.sell).toEqual({
- quantity: 0n,
- info: tokenInfoMocks.lp,
- })
- })
- })
-
- describe('BuyTokenInfoChanged', () => {
- it('should reset pools and the derived', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- draft.orderData.tokens = {
- ptInfo: tokenInfoMocks.pt,
- priceDenomination: 0,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools1,
- })
- const updatedSellQuantity = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10_000n,
- })
-
- expect(
- updatedSellQuantity.orderData.amounts.buy,
- ).toEqual({
- info: tokenInfoMocks.b,
- quantity: 138_194n,
- })
-
- const state = combinedSwapReducers(updatedSellQuantity, {
- type: SwapCreateOrderActionType.BuyTokenInfoChanged,
- tokenInfo: tokenInfoMocks.c,
- })
-
- expect(state.orderData.amounts.buy).toEqual({
- quantity: 138_194n,
- info: tokenInfoMocks.c,
- })
- // should be updated right next with the new pool pairs
- expect(state.orderData.pools).toEqual([])
- // should reset everything derived
- expect(state.orderData.calculations).toEqual([])
- expect(state.orderData.selectedPoolCalculation).toBeUndefined()
- expect(state.orderData.bestPoolCalculation).toBeUndefined()
- // type is irrelevant
- expect(state.orderData.selectedPoolId).toBeUndefined()
- })
-
- it('should initiate buy side', () => {
- const state = combinedSwapReducers(mockSwapStateDefault, {
- type: SwapCreateOrderActionType.BuyTokenInfoChanged,
- tokenInfo: tokenInfoMocks.lp,
- })
- expect(state.orderData.amounts.buy).toEqual({
- quantity: 0n,
- info: tokenInfoMocks.lp,
- })
- })
- })
-
- describe('SellQuantityChanged', () => {
- it('should calculate the buy side if pools are available', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools1,
- })
-
- const state = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10n,
- })
-
- expect(state.orderData.selectedPoolCalculation).toBeDefined()
- expect(state.orderData.amounts.buy!.quantity).toBe(124n)
- expect(state.orderData.amounts.sell!.quantity).toBe(10n)
- })
-
- it('should skip updates if sell quantity changes but no sell token info', () => {
- const state = combinedSwapReducers(mockSwapStateDefault, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10n,
- })
-
- expect(state).toEqual(mockSwapStateDefault)
- })
- })
-
- describe('BuyQuantityChanged', () => {
- it('should calculate the buy side if pools are available', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools1,
- })
-
- const state = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.BuyQuantityChanged,
- quantity: 1n,
- })
-
- expect(state.orderData.selectedPoolCalculation).toBeDefined()
- expect(state.orderData.amounts.buy!.quantity).toBe(1n)
- expect(state.orderData.amounts.sell!.quantity).toBe(3n)
- })
-
- it('should skip updates if buy quantity changes but no buy token info', () => {
- const state = combinedSwapReducers(mockSwapStateDefault, {
- type: SwapCreateOrderActionType.BuyQuantityChanged,
- quantity: 10n,
- })
-
- expect(state).toEqual(mockSwapStateDefault)
- })
- })
-
- // NOTE an important assumption is taken when calculating the best pool
- // that all poolpairs (pools) object are tokenA/tokenB represents buy/sell sell/buy
- // and that the UI will never allow buy and sell tokens to be the same after touched
- describe('PoolPairsChanged', () => {
- describe('limit order', () => {
- it('should reset limit price to market and unselect the selected pool', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools1,
- })
- const updatedSellQuantity = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 100n,
- })
- const updatedType = combinedSwapReducers(updatedSellQuantity, {
- type: SwapCreateOrderActionType.OrderTypeChanged,
- orderType: 'limit',
- })
- const updatedLimit = combinedSwapReducers(updatedType, {
- type: SwapCreateOrderActionType.LimitPriceChanged,
- limitPrice: '1',
- })
-
- const state = combinedSwapReducers(updatedLimit, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
-
- expect(state.orderData.limitPrice).toBe('0.5000000000')
- expect(state.orderData.selectedPoolId).toBeUndefined()
- })
- })
-
- describe('no pools', () => {
- it('should leave limit price undefined and wont update the buy side', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools1,
- })
- const updatedSellQuantity = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10_000n,
- })
- const updatedType = combinedSwapReducers(updatedSellQuantity, {
- type: SwapCreateOrderActionType.OrderTypeChanged,
- orderType: 'limit',
- })
- const updatedLimit = combinedSwapReducers(updatedType, {
- type: SwapCreateOrderActionType.LimitPriceChanged,
- limitPrice: '1',
- })
-
- // this would happen when changing the tokenId of one sides
- // and there is no pool pairs for the new pair
- const state = combinedSwapReducers(updatedLimit, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: [],
- })
-
- expect(state.orderData.limitPrice).toBeUndefined()
- expect(state.orderData.selectedPoolId).toBeUndefined()
- expect(state.orderData.amounts.buy!.quantity).toBe(
- updatedLimit.orderData.amounts.buy!.quantity,
- )
- })
- })
- })
-
- // NOTE: initialized only
- // designed to be triggered once only
- it('PrimaryTokenInfoChanged', () => {
- const expectedState = combinedSwapReducers(mockSwapStateDefault, {
- type: SwapCreateOrderActionType.PrimaryTokenInfoChanged,
- tokenInfo: tokenInfoMocks.pt,
- })
- expect(expectedState.orderData.tokens.ptInfo).toEqual(tokenInfoMocks.pt)
- })
-
- it('LpTokenHeldChanged', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
- const updatedSellQuantity = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10_000n,
- })
-
- const state = combinedSwapReducers(updatedSellQuantity, {
- type: SwapCreateOrderActionType.LpTokenHeldChanged,
- amount: {
- quantity: 100n,
- info: tokenInfoMocks.lp,
- },
- })
-
- expect(state.orderData.lpTokenHeld).toEqual({
- quantity: 100n,
- info: tokenInfoMocks.lp,
- })
- })
-
- // NOTE: initialized only
- // designed to be triggered once only
- it('FrontendFeeTiersChanged', () => {
- const initialState = produce(mockSwapStateDefault, (draft) => {
- draft.orderData.amounts.sell = {
- info: tokenInfoMocks.a,
- quantity: 0n,
- }
- draft.orderData.amounts.buy = {
- info: tokenInfoMocks.b,
- quantity: 0n,
- }
- })
- const updatedPools = combinedSwapReducers(initialState, {
- type: SwapCreateOrderActionType.PoolPairsChanged,
- pools: mocks.mockedPools6,
- })
- const updatedSellQuantity = combinedSwapReducers(updatedPools, {
- type: SwapCreateOrderActionType.SellQuantityChanged,
- quantity: 10_000n,
- })
-
- const state = combinedSwapReducers(updatedSellQuantity, {
- type: SwapCreateOrderActionType.FrontendFeeTiersChanged,
- feeTiers: [],
- })
-
- expect(state.orderData.frontendFeeTiers).toEqual([])
- })
-})
diff --git a/packages/swap/src/translators/reactjs/state/state.ts b/packages/swap/src/translators/reactjs/state/state.ts
deleted file mode 100644
index 8267d3b93e..0000000000
--- a/packages/swap/src/translators/reactjs/state/state.ts
+++ /dev/null
@@ -1,773 +0,0 @@
-import {App, Portfolio, Swap} from '@yoroi/types'
-import {freeze, produce} from 'immer'
-
-import {makeOrderCalculations} from '../../../helpers/orders/factories/makeOrderCalculations'
-import {selectedPoolCalculationSelector} from './selectors/selectedPoolCalculationSelector'
-import {getBestPoolCalculation} from '../../../helpers/pools/getBestPoolCalculation'
-
-export type SwapState = Readonly<{
- orderData: {
- // user inputs
- amounts: {
- sell?: Portfolio.Token.Amount
- buy?: Portfolio.Token.Amount
- }
-
- type: Swap.OrderType
- limitPrice?: string
-
- // when limit can manually select a pool
- selectedPoolId?: string
- selectedPoolCalculation?: Swap.OrderCalculation
-
- slippage: number
-
- // state from wallet
- lpTokenHeld?: Portfolio.Token.Amount
- tokens: {
- ptInfo?: Portfolio.Token.Info
- // diff sell - buy decimals
- priceDenomination: number
- }
- frontendFeeTiers: ReadonlyArray
-
- // state from swap api
- pools: ReadonlyArray
-
- // derivaded data
- calculations: ReadonlyArray
- bestPoolCalculation?: Swap.OrderCalculation
- }
- unsignedTx: any
-}>
-
-export type SwapCreateOrderActions = Readonly<{
- orderTypeChanged: (orderType: Swap.OrderType) => void
- selectedPoolChanged: (poolId: string) => void
- slippageChanged: (slippage: number) => void
- switchTokens: () => void
- resetQuantities: () => void
- limitPriceChanged: (limitPrice: string) => void
- sellQuantityChanged: (quantity: bigint) => void
- buyQuantityChanged: (quantity: bigint) => void
- sellTokenInfoChanged: (tokenInfo: Portfolio.Token.Info) => void
- buyTokenInfoChanged: (tokenInfo: Portfolio.Token.Info) => void
- poolPairsChanged: (pools: ReadonlyArray) => void
- lpTokenHeldChanged: (amount: Portfolio.Token.Amount | undefined) => void
- primaryTokenInfoChanged: (tokenInfo: Portfolio.Token.Info) => void
- frontendFeeTiersChanged: (
- feeTiers: ReadonlyArray,
- ) => void
-}>
-
-export enum SwapCreateOrderActionType {
- OrderTypeChanged = 'orderTypeChanged',
- SelectedPoolChanged = 'selectedPoolChanged',
- SlippageChanged = 'slippageChanged',
- TxPayloadChanged = 'txPayloadChanged',
- SwitchTokens = 'switchTokens',
- ResetQuantities = 'resetQuantities',
- LimitPriceChanged = 'limitPriceChanged',
- SellQuantityChanged = 'sellQuantityChanged',
- BuyQuantityChanged = 'buyQuantityChanged',
- SellTokenInfoChanged = 'sellTokenInfoChanged',
- BuyTokenInfoChanged = 'buyTokenInfoChanged',
- PoolPairsChanged = 'poolPairsChanged',
- LpTokenHeldChanged = 'lpTokenHeldChanged',
- PrimaryTokenInfoChanged = 'primaryTokenInfoChanged',
- FrontendFeeTiersChanged = 'frontendFeeTiersChanged',
-}
-
-export type SwapCreateOrderAction =
- | {
- type: SwapCreateOrderActionType.OrderTypeChanged
- orderType: Swap.OrderType
- }
- | {
- type: SwapCreateOrderActionType.SelectedPoolChanged
- poolId: string
- }
- | {
- type: SwapCreateOrderActionType.SlippageChanged
- slippage: number
- }
- | {
- type: SwapCreateOrderActionType.LimitPriceChanged
- limitPrice: string
- }
- | {type: SwapCreateOrderActionType.SwitchTokens}
- | {type: SwapCreateOrderActionType.ResetQuantities}
- | {
- type: SwapCreateOrderActionType.SellQuantityChanged
- quantity: bigint
- }
- | {
- type: SwapCreateOrderActionType.BuyQuantityChanged
- quantity: bigint
- }
- | {
- type: SwapCreateOrderActionType.SellTokenInfoChanged
- tokenInfo: Portfolio.Token.Info
- }
- | {
- type: SwapCreateOrderActionType.BuyTokenInfoChanged
- tokenInfo: Portfolio.Token.Info
- }
- | {
- type: SwapCreateOrderActionType.PoolPairsChanged
- pools: ReadonlyArray
- }
- | {
- type: SwapCreateOrderActionType.LpTokenHeldChanged
- amount: Portfolio.Token.Amount | undefined
- }
- | {
- type: SwapCreateOrderActionType.PrimaryTokenInfoChanged
- tokenInfo: Portfolio.Token.Info
- }
- | {
- type: SwapCreateOrderActionType.FrontendFeeTiersChanged
- feeTiers: ReadonlyArray
- }
-
-export type SwapActions = Readonly<{
- // TODO: import from @yoroi/common unsignedTx type
- unsignedTxChanged: (
- unsignedTx: Readonly> | undefined,
- ) => void
- resetState: () => void
-}>
-
-export enum SwapActionType {
- UnsignedTxChanged = 'unsignedTxChanged',
- ResetState = 'resetState',
-}
-
-export type SwapAction =
- | {
- type: SwapActionType.UnsignedTxChanged
- unsignedTx: Readonly> | undefined
- }
- | {type: SwapActionType.ResetState}
-
-export const combinedSwapReducers = (
- state: SwapState,
- action: SwapCreateOrderAction | SwapAction,
-) => {
- return {
- ...swapReducer(
- {
- ...state,
- ...orderReducer(state, action as SwapCreateOrderAction),
- },
- action as SwapAction,
- ),
- } as const
-}
-
-export const defaultSwapState: SwapState = freeze({
- orderData: {
- // user inputs
- type: 'market',
- amounts: {},
- slippage: 1,
- limitPrice: undefined,
- // when limit can manually select a pool
- selectedPoolId: undefined,
- selectedPoolCalculation: undefined,
-
- // state from wallet
- lpTokenHeld: undefined,
- tokens: {
- priceDenomination: 0,
- },
- frontendFeeTiers: [],
-
- // state from api
- pools: [],
-
- // derivaded data
- calculations: [],
- bestPoolCalculation: undefined,
- },
- unsignedTx: undefined,
-})
-
-const defaultSwapCreateOrderActions: SwapCreateOrderActions = {
- orderTypeChanged: missingInit,
- selectedPoolChanged: missingInit,
- slippageChanged: missingInit,
- switchTokens: missingInit,
- resetQuantities: missingInit,
- limitPriceChanged: missingInit,
- sellQuantityChanged: missingInit,
- buyQuantityChanged: missingInit,
- sellTokenInfoChanged: missingInit,
- buyTokenInfoChanged: missingInit,
- poolPairsChanged: missingInit,
- lpTokenHeldChanged: missingInit,
- primaryTokenInfoChanged: missingInit,
- frontendFeeTiersChanged: missingInit,
-} as const
-
-const defaultStateActions: SwapActions = {
- unsignedTxChanged: missingInit,
- resetState: missingInit,
-} as const
-
-export const defaultSwapActions = {
- ...defaultSwapCreateOrderActions,
- ...defaultStateActions,
-} as const
-
-const orderReducer = (
- state: Readonly,
- action: Readonly,
-) => {
- return produce(state, (draft) => {
- switch (action.type) {
- // when changing order type, from market to limit
- // or when is the first calculation as limit with data
- // the limit price is set to the best market price
- case SwapCreateOrderActionType.OrderTypeChanged:
- draft.orderData.type = action.orderType
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: action.orderType,
- amounts: state.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- side: 'sell',
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.amounts.buy ||
- !draft.orderData.selectedPoolCalculation
- )
- break
-
- draft.orderData.amounts.buy = {
- ...draft.orderData.amounts.buy,
- quantity: draft.orderData.selectedPoolCalculation.sides.buy.quantity,
- }
-
- if (
- draft.orderData.type === 'limit' &&
- state.orderData.limitPrice === undefined
- )
- draft.orderData.limitPrice =
- draft.orderData.bestPoolCalculation?.prices.market
- break
-
- // when changing pool, the selection comes from the calculations
- // so it updates the buy side only
- // it ignores events if order type is not limit
- // NOTE: late it can replace the order from market to limit and recalc
- case SwapCreateOrderActionType.SelectedPoolChanged:
- if (state.orderData.type === 'market') break
-
- draft.orderData.selectedPoolId = action.poolId
-
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.amounts.sell ||
- !draft.orderData.amounts.buy ||
- !draft.orderData.selectedPoolCalculation
- )
- break
-
- draft.orderData.amounts.buy = {
- ...draft.orderData.amounts.buy,
- quantity: draft.orderData.selectedPoolCalculation.sides.buy.quantity,
- }
-
- draft.orderData.limitPrice =
- draft.orderData.selectedPoolCalculation.prices.market
- break
-
- case SwapCreateOrderActionType.SlippageChanged:
- draft.orderData.slippage = action.slippage
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: state.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: action.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- side: 'sell',
- })
-
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- 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
- // yet, we updated buy/sell based on the current selected pool if limit
- case SwapCreateOrderActionType.SwitchTokens:
- draft.orderData.amounts = {
- sell: state.orderData.amounts.buy,
- buy: state.orderData.amounts.sell,
- }
- draft.orderData.tokens = {
- priceDenomination: -state.orderData.tokens.priceDenomination,
- ptInfo: state.orderData.tokens.ptInfo,
- }
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: draft.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: draft.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- side: 'sell',
- })
-
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.amounts.buy ||
- !draft.orderData.selectedPoolCalculation
- )
- break
-
- draft.orderData.amounts.buy = {
- ...draft.orderData.amounts.buy,
- quantity: draft.orderData.selectedPoolCalculation.sides.buy.quantity,
- }
- break
-
- // when resetting quantities, when order is limit, limit price is the best market price
- // also resets the selected pool, otherwise users will need to leave the funnel
- // otherwise the limit set back to undefined
- case SwapCreateOrderActionType.ResetQuantities:
- if (state.orderData.amounts.sell) {
- draft.orderData.amounts.sell = {
- ...state.orderData.amounts.sell,
- quantity: 0n,
- }
- }
- if (state.orderData.amounts.buy) {
- draft.orderData.amounts.buy = {
- ...state.orderData.amounts.buy,
- quantity: 0n,
- }
- }
-
- draft.orderData.selectedPoolId = undefined
- draft.orderData.limitPrice = undefined
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: 'market',
- amounts: draft.orderData.amounts,
- limitPrice: undefined,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- })
-
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- draft.orderData.limitPrice =
- state.orderData.type === 'limit'
- ? draft.orderData.bestPoolCalculation?.prices.market
- : undefined
- break
-
- // when limit price changes, the best pool is recalculated
- // yet if there is a selected pool it will not change
- // this can cause a pool if not enough supply to be selected
- // must be handled on the UI
- case SwapCreateOrderActionType.LimitPriceChanged:
- if (state.orderData.type === 'market') break
-
- draft.orderData.limitPrice = action.limitPrice
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: state.orderData.amounts,
- limitPrice: action.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- side: 'sell',
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.amounts.buy ||
- !draft.orderData.selectedPoolCalculation
- )
- break
-
- draft.orderData.amounts.buy = {
- ...draft.orderData.amounts.buy,
- quantity: draft.orderData.selectedPoolCalculation.sides.buy.quantity,
- }
- break
-
- // updating sell side will recalculate buy side
- // the pool will be automatically selected only if
- // there is no selected pool (limit order)
- case SwapCreateOrderActionType.SellQuantityChanged:
- if (!draft.orderData.amounts.sell) break
-
- draft.orderData.amounts.sell.quantity = action.quantity
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: draft.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- side: 'sell',
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.selectedPoolCalculation ||
- !draft.orderData.amounts.buy
- )
- break
-
- draft.orderData.amounts.buy = {
- ...draft.orderData.amounts.buy,
- quantity: draft.orderData.selectedPoolCalculation.sides.buy.quantity,
- }
- break
-
- // updating buy side will recalculate sell side
- // the pool will be automatically selected only if
- // there is no selected pool (limit order)
- case SwapCreateOrderActionType.BuyQuantityChanged:
- if (!draft.orderData.amounts.buy) break
- draft.orderData.amounts.buy.quantity = action.quantity
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: draft.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- side: 'buy',
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.selectedPoolCalculation ||
- !draft.orderData.amounts.sell
- )
- break
-
- draft.orderData.amounts.sell = {
- ...draft.orderData.amounts.sell,
- quantity: draft.orderData.selectedPoolCalculation.sides.sell.quantity,
- }
- break
-
- // when changing token info, all the derivaded data is reset
- // and the selected pool is reset
- case SwapCreateOrderActionType.SellTokenInfoChanged:
- const decimalFactor =
- (state.orderData.amounts.sell?.info.decimals ?? 0) -
- action.tokenInfo.decimals
- const decimalScalingFactor =
- BigInt(10) ** BigInt(Math.abs(decimalFactor))
-
- if (draft.orderData.amounts.sell) {
- const quantity =
- decimalFactor > 0
- ? draft.orderData.amounts.sell.quantity / decimalScalingFactor
- : draft.orderData.amounts.sell.quantity * decimalScalingFactor
-
- draft.orderData.amounts.sell = {
- quantity,
- info: action.tokenInfo,
- }
- } else {
- draft.orderData.amounts.sell = {
- quantity: 0n,
- info: action.tokenInfo,
- }
- }
-
- draft.orderData.tokens.priceDenomination =
- action.tokenInfo.decimals -
- (state.orderData.amounts.buy?.info.decimals ?? 0)
-
- draft.orderData.pools = []
-
- draft.orderData.calculations = []
- draft.orderData.bestPoolCalculation = undefined
- draft.orderData.selectedPoolId = undefined
- draft.orderData.selectedPoolCalculation = undefined
- break
-
- // when changing token info, all the derivaded data is reset
- // and the selected pool is reset
- case SwapCreateOrderActionType.BuyTokenInfoChanged:
- if (draft.orderData.amounts.buy) {
- draft.orderData.amounts.buy = {
- ...draft.orderData.amounts.buy,
- info: action.tokenInfo,
- }
- } else {
- draft.orderData.amounts.buy = {
- quantity: 0n,
- info: action.tokenInfo,
- }
- }
-
- draft.orderData.tokens.priceDenomination =
- (state.orderData.amounts.sell?.info.decimals ?? 0) -
- action.tokenInfo.decimals
-
- draft.orderData.pools = []
-
- draft.orderData.calculations = []
- draft.orderData.bestPoolCalculation = undefined
- draft.orderData.selectedPoolId = undefined
- draft.orderData.selectedPoolCalculation = undefined
- break
-
- // when the lp token held changes, the calculations are updated
- // buy side needs recalculation since best pool can change
- case SwapCreateOrderActionType.LpTokenHeldChanged:
- draft.orderData.lpTokenHeld = action.amount
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: state.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: action.amount,
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- side: 'sell',
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.selectedPoolCalculation ||
- !draft.orderData.amounts.buy
- )
- break
-
- draft.orderData.amounts.buy.quantity =
- draft.orderData.selectedPoolCalculation.sides.buy.quantity
- break
-
- // when the frontend feee tiers changes, the calculations are updated
- // buy side needs recalculation since best pool can change
- // NOTE: designed to be loaded once at the initialization
- case SwapCreateOrderActionType.FrontendFeeTiersChanged:
- draft.orderData.frontendFeeTiers = [...action.feeTiers]
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: state.orderData.amounts,
- limitPrice: state.orderData.limitPrice,
- slippage: state.orderData.slippage,
- pools: state.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- side: 'sell',
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- selectedPoolCalculationSelector({
- type: draft.orderData.type,
- selectedPoolId: draft.orderData.selectedPoolId,
- calculations: draft.orderData.calculations,
- bestPoolCalculation: draft.orderData.bestPoolCalculation,
- })
-
- if (
- !draft.orderData.amounts.buy ||
- !draft.orderData.selectedPoolCalculation
- )
- break
-
- draft.orderData.amounts.buy.quantity =
- draft.orderData.selectedPoolCalculation.sides.buy.quantity
- break
-
- // when the pool pair changes, the calculations are updated
- // buy side needs recalculation since best pool can change
- // reset limit and selected pool - since it can be gone
- case SwapCreateOrderActionType.PoolPairsChanged:
- draft.orderData.pools = [...action.pools]
-
- draft.orderData.calculations = makeOrderCalculations({
- orderType: state.orderData.type,
- amounts: state.orderData.amounts,
- limitPrice: undefined,
- slippage: state.orderData.slippage,
- pools: draft.orderData.pools,
- tokens: state.orderData.tokens,
- lpTokenHeld: state.orderData.lpTokenHeld,
- side: 'sell',
- frontendFeeTiers: state.orderData.frontendFeeTiers,
- })
- draft.orderData.bestPoolCalculation = getBestPoolCalculation(
- draft.orderData.calculations,
- )
- draft.orderData.selectedPoolCalculation =
- 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
-
- if (
- !draft.orderData.selectedPoolCalculation ||
- !draft.orderData.amounts.buy
- )
- break
-
- draft.orderData.limitPrice =
- state.orderData.type === 'limit'
- ? draft.orderData.bestPoolCalculation?.prices.market
- : undefined
-
- draft.orderData.amounts.buy.quantity =
- draft.orderData.selectedPoolCalculation.sides.buy.quantity
- break
-
- // NOTE: designed to be loaded once at the initialization
- case SwapCreateOrderActionType.PrimaryTokenInfoChanged:
- draft.orderData.tokens.ptInfo = action.tokenInfo
- break
- }
- })
-}
-
-const swapReducer = (state: SwapState, action: SwapAction) => {
- return produce(state, (draft) => {
- switch (action.type) {
- case SwapActionType.UnsignedTxChanged:
- draft.unsignedTx = action.unsignedTx
- break
- case SwapActionType.ResetState:
- draft.orderData = {
- ...defaultSwapState.orderData,
- calculations: [...defaultSwapState.orderData.calculations],
- pools: [...defaultSwapState.orderData.pools],
- frontendFeeTiers: [...defaultSwapState.orderData.frontendFeeTiers],
- }
- draft.unsignedTx = defaultSwapState.unsignedTx
- break
- }
- })
-}
-
-/* istanbul ignore next */
-function missingInit() {
- console.error('[@yoroi/swap] missing initialization')
-}
diff --git a/packages/swap/src/utils/asQuantity.test.ts b/packages/swap/src/utils/asQuantity.test.ts
deleted file mode 100644
index f0f05c92bd..0000000000
--- a/packages/swap/src/utils/asQuantity.test.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import {asQuantity} from './asQuantity'
-import BigNumber from 'bignumber.js'
-
-describe('asQuantity', () => {
- it('should convert a BigNumber to Balance.Quantity', () => {
- const input = new BigNumber('1000')
- const result = asQuantity(input)
- expect(result).toBe('1000')
- })
-
- it('should convert a number to Balance.Quantity', () => {
- const input = 500
- const result = asQuantity(input)
- expect(result).toBe('500')
- })
-
- it('should convert a string to Balance.Quantity', () => {
- const input = '750'
- const result = asQuantity(input)
- expect(result).toBe('750')
- })
-
- it('should throw an error for invalid input', () => {
- // Test with invalid input (NaN)
- const input = NaN
- expect(() => asQuantity(input)).toThrow('Invalid quantity')
- })
-
- it('should convert a negative number to Balance.Quantity', () => {
- const input = -123.456
- const result = asQuantity(input)
- expect(result).toBe('-123.456')
- })
-
- it('should convert a string with leading and trailing spaces to Balance.Quantity', () => {
- const input = ' 789.123 '
- const result = asQuantity(input)
- expect(result).toBe('789.123')
- })
-
- it('should handle scientific notation', () => {
- const input = '1.23e+3'
- const result = asQuantity(input)
- expect(result).toBe('1230')
- })
-})
diff --git a/packages/swap/src/utils/asQuantity.ts b/packages/swap/src/utils/asQuantity.ts
deleted file mode 100644
index e28a7cf5ec..0000000000
--- a/packages/swap/src/utils/asQuantity.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {Balance} from '@yoroi/types'
-import BigNumber from 'bignumber.js'
-
-export const asQuantity = (value: BigNumber | number | string) => {
- const bn = new BigNumber(value)
- if (bn.isNaN() || !bn.isFinite()) {
- throw new Error('Invalid quantity')
- }
- return bn.toString(10) as Balance.Quantity
-}
diff --git a/packages/swap/src/utils/ceilDivision.test.ts b/packages/swap/src/utils/ceilDivision.test.ts
deleted file mode 100644
index 68854731ec..0000000000
--- a/packages/swap/src/utils/ceilDivision.test.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import {ceilDivision} from './ceilDivision'
-
-describe('ceilDivision', () => {
- test('positive dividend and divisor', () => {
- expect(ceilDivision(10n, 3n)).toBe(4n)
- expect(ceilDivision(9n, 3n)).toBe(3n)
- })
-
- test('dividend or divisor is zero', () => {
- expect(ceilDivision(0n, 3n)).toBe(0n)
- expect(ceilDivision(10n, 0n)).toBe(0n)
- })
-
- test('dividend or divisor is negative', () => {
- expect(ceilDivision(-10n, 3n)).toBe(0n)
- expect(ceilDivision(10n, -3n)).toBe(0n)
- })
-
- test('both dividend and divisor are negative', () => {
- expect(ceilDivision(-10n, -3n)).toBe(0n)
- })
-
- test('smallest positive dividend and divisor', () => {
- expect(ceilDivision(1n, 1n)).toBe(1n)
- })
-
- test('divisor greater than dividend', () => {
- expect(ceilDivision(3n, 10n)).toBe(1n)
- })
-})
diff --git a/packages/swap/src/utils/ceilDivision.ts b/packages/swap/src/utils/ceilDivision.ts
deleted file mode 100644
index 67606f2a23..0000000000
--- a/packages/swap/src/utils/ceilDivision.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Perform a division that rounds up the result to the nearest integer.
- *
- * @param dividend - The number to be divided.
- * @param divisor - The number by which division is to be performed.
- *
- * @returns The rounded-up result of the division, or 0 if either dividend or divisor is 0.
- */
-export const ceilDivision = (dividend: bigint, divisor: bigint): bigint => {
- if (dividend <= 0n || divisor <= 0n) return 0n
- const adjustedDivisor = divisor - 1n
-
- return (dividend + adjustedDivisor) / divisor
-}
diff --git a/packages/swap/src/utils/quantities.test.ts b/packages/swap/src/utils/quantities.test.ts
deleted file mode 100644
index 564cdbc8ac..0000000000
--- a/packages/swap/src/utils/quantities.test.ts
+++ /dev/null
@@ -1,219 +0,0 @@
-import {Quantities} from './quantities'
-import {asQuantity} from './asQuantity'
-import {Balance} from '@yoroi/types'
-import {mockNumberLocale} from '../adapters/intl/number-locale.mocks'
-
-describe('Quantities', () => {
- describe('sum', () => {
- it('should calculate the sum of quantities', () => {
- const quantities = [asQuantity(100), asQuantity(200), asQuantity(300)]
- expect(Quantities.sum(quantities)).toBe('600')
- })
- })
-
- describe('diff', () => {
- it('should calculate the difference between two quantities', () => {
- const quantity1 = '500'
- const quantity2 = '300'
- expect(Quantities.diff(quantity1, quantity2)).toBe('200')
- })
- })
-
- describe('product', () => {
- it('should calculate the product of quantities', () => {
- const quantities = [asQuantity(2), asQuantity(3), asQuantity(4)]
- expect(Quantities.product(quantities)).toBe('24')
- })
- })
-
- describe('quotient', () => {
- it('should calculate the quotient between two quantities', () => {
- const quantity1 = '1000'
- const quantity2 = '5'
- expect(Quantities.quotient(quantity1, quantity2)).toBe('200')
- })
- })
-
- describe('isGreaterThanOrEqualTo', () => {
- it('should correctly compare two quantities', () => {
- const quantity1 = '100'
- const quantity2 = '50'
- expect(Quantities.isGreaterThanOrEqualTo(quantity1, quantity2)).toBe(true)
- })
-
- it('should handle equal quantities', () => {
- const quantity1 = '100'
- const quantity2 = '100'
- expect(Quantities.isGreaterThanOrEqualTo(quantity1, quantity2)).toBe(true)
- })
-
- it('should handle negative quantities', () => {
- const quantity1 = '-50'
- const quantity2 = '-100'
- expect(Quantities.isGreaterThanOrEqualTo(quantity1, quantity2)).toBe(true)
- })
- })
-
- describe('isGreaterThan', () => {
- it('should correctly compare two quantities', () => {
- const quantity1 = '100'
- const quantity2 = '50'
- expect(Quantities.isGreaterThan(quantity1, quantity2)).toBe(true)
- })
-
- it('should handle equal quantities', () => {
- const quantity1 = '100'
- const quantity2 = '100'
- expect(Quantities.isGreaterThan(quantity1, quantity2)).toBe(false)
- })
-
- it('should handle negative quantities', () => {
- const quantity1 = '-50'
- const quantity2 = '-100'
- expect(Quantities.isGreaterThan(quantity1, quantity2)).toBe(true)
- })
- })
-
- describe('isZero', () => {
- it('should correctly identify zero quantities', () => {
- const zeroQuantity = '0'
- const nonZeroQuantity = '100'
- expect(Quantities.isZero(zeroQuantity)).toBe(true)
- expect(Quantities.isZero(nonZeroQuantity)).toBe(false)
- })
- })
-
- describe('integer', () => {
- it('should convert a quantity to an integer', () => {
- const quantity = '0.00123'
- const denomination = 6
- expect(Quantities.integer(quantity, denomination)).toBe('1230')
- })
- })
-
- describe('denominated', () => {
- it('should correctly denominate a quantity', () => {
- const quantity = '10000'
- const denomination = 6
- expect(Quantities.denominated(quantity, denomination)).toBe('0.01')
- })
- })
-
- describe('negated', () => {
- it('should negate a positive quantity', () => {
- const quantity = '500'
- expect(Quantities.negated(quantity)).toBe('-500')
- })
-
- it('should negate a negative quantity', () => {
- const quantity = '-750'
- expect(Quantities.negated(quantity)).toBe('750')
- })
-
- it('should leave zero unchanged', () => {
- const quantity = '0'
- expect(Quantities.negated(quantity)).toBe('0')
- })
- })
-
- describe('decimalPlaces', () => {
- it('should change the number of decimal places in a quantity', () => {
- const quantity = '123.456789'
- const precision = 3
- expect(Quantities.decimalPlaces(quantity, precision)).toBe('123.457')
- })
-
- it('should remove excess decimal places', () => {
- const quantity = '123.456789'
- const precision = 2
- expect(Quantities.decimalPlaces(quantity, precision)).toBe('123.46')
- })
- })
-
- describe('isAtomic', () => {
- it('should correctly identify atomic quantities', () => {
- const atomicQuantity = '0.01'
- const nonAtomicQuantity = '0.015'
- const denomination = 2
- expect(Quantities.isAtomic(atomicQuantity, denomination)).toBe(true)
- expect(Quantities.isAtomic(nonAtomicQuantity, denomination)).toBe(false)
- })
- })
-
- describe('format', () => {
- it('should format a quantity with the specified denomination', () => {
- const quantity = '0.01'
- 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', () => {
- const quantities: Array = [
- asQuantity(100),
- asQuantity(500),
- asQuantity(300),
- asQuantity(700),
- asQuantity(200),
- ]
- const maxQuantity = Quantities.max(...quantities) // Convert strings to numbers
- expect(maxQuantity).toBe('700')
- })
-
- it('should parse "0" when the input text is an empty string', () => {
- const text = ''
- const denomination = 2
- const [input, quantity] = Quantities.parseFromText(
- text,
- denomination,
- mockNumberLocale,
- )
-
- expect(input).toBe('')
- expect(quantity).toBe('0')
- })
-
- it('should parse "0" when the input text is an decimal separator', () => {
- const text = '.'
- const denomination = 2
- const [input, quantity] = Quantities.parseFromText(
- text,
- denomination,
- mockNumberLocale,
- )
-
- expect(input).toBe('0.')
- expect(quantity).toBe('0')
- })
-
- it('should parse "1.0" when the input text has trailing 0', () => {
- expect(Quantities.parseFromText('1.0', 2, mockNumberLocale)).toEqual([
- '1.0',
- '100',
- ])
- })
-
- it('should parse "1.234" when precision is 3', () => {
- expect(Quantities.parseFromText('1.23456', 0, mockNumberLocale, 3)).toEqual(
- ['1.234', '1.234'],
- )
-
- expect(Quantities.parseFromText('1.23456', 2, mockNumberLocale, 3)).toEqual(
- ['1.234', '123.4'],
- )
- })
-
- it('should parse whole numbers', () => {
- expect(Quantities.parseFromText('123', 2, mockNumberLocale)).toEqual([
- '123',
- '12300',
- ])
- })
-})
diff --git a/packages/swap/src/utils/quantities.ts b/packages/swap/src/utils/quantities.ts
deleted file mode 100644
index e8c1372b5e..0000000000
--- a/packages/swap/src/utils/quantities.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-import {Balance, Numbers} from '@yoroi/types'
-import BigNumber from 'bignumber.js'
-import {asQuantity} from './asQuantity'
-
-export const Quantities = {
- sum: (quantities: Array) => {
- return quantities
- .reduce((result, current) => result.plus(current), new BigNumber(0))
- .toString(10) as Balance.Quantity
- },
- max: (...quantities: Array) => {
- return BigNumber.max(...quantities).toString(10) as Balance.Quantity
- },
- diff: (quantity1: Balance.Quantity, quantity2: Balance.Quantity) => {
- return new BigNumber(quantity1)
- .minus(new BigNumber(quantity2))
- .toString(10) as Balance.Quantity
- },
- negated: (quantity: Balance.Quantity) => {
- return new BigNumber(quantity).negated().toString(10) as Balance.Quantity
- },
- product: (quantities: Array) => {
- return quantities.reduce((result, quantity) => {
- const x = new BigNumber(result).times(new BigNumber(quantity))
-
- return x.toString(10) as Balance.Quantity
- }, '1' as Balance.Quantity)
- },
- quotient: (quantity1: Balance.Quantity, quantity2: Balance.Quantity) => {
- return new BigNumber(quantity1)
- .dividedBy(new BigNumber(quantity2))
- .toString(10) as Balance.Quantity
- },
- isGreaterThan: (quantity1: Balance.Quantity, quantity2: Balance.Quantity) => {
- return new BigNumber(quantity1).isGreaterThan(new BigNumber(quantity2))
- },
- isGreaterThanOrEqualTo: (
- quantity1: Balance.Quantity,
- quantity2: Balance.Quantity,
- ) => {
- return new BigNumber(quantity1).isGreaterThanOrEqualTo(
- new BigNumber(quantity2),
- )
- },
- decimalPlaces: (quantity: Balance.Quantity, precision: number) => {
- return new BigNumber(quantity)
- .decimalPlaces(precision)
- .toString(10) as Balance.Quantity
- },
- denominated: (quantity: Balance.Quantity, denomination: number) => {
- return Quantities.quotient(
- quantity,
- new BigNumber(10).pow(denomination).toString(10) as Balance.Quantity,
- )
- },
- integer: (quantity: Balance.Quantity, denomination: number) => {
- return new BigNumber(quantity)
- .decimalPlaces(denomination)
- .shiftedBy(denomination)
- .toString(10) as Balance.Quantity
- },
- zero: '0' as Balance.Quantity,
- isZero: (quantity: Balance.Quantity) => new BigNumber(quantity).isZero(),
- isAtomic: (quantity: Balance.Quantity, denomination: number) => {
- const absoluteQuantity = new BigNumber(quantity)
- .decimalPlaces(denomination)
- .abs()
- const minimalFractionalPart = new BigNumber(10).pow(
- new BigNumber(denomination).negated(),
- )
-
- return absoluteQuantity.isEqualTo(minimalFractionalPart)
- },
- parseFromText: (
- text: string,
- denomination: number,
- format: Numbers.Locale,
- precision = denomination,
- ): [string, Balance.Quantity] => {
- const {decimalSeparator} = format
- const invalid = new RegExp(`[^0-9${decimalSeparator}]`, 'g')
- const sanitized = text === '' ? '' : text.replaceAll(invalid, '')
-
- if (sanitized === '') return ['', Quantities.zero]
- if (sanitized.startsWith(decimalSeparator))
- return [`0${decimalSeparator}`, Quantities.zero]
-
- const parts = sanitized.split(decimalSeparator)
-
- let fullDecValue = sanitized
- let value = sanitized
-
- let fullDecFormat = new BigNumber(
- fullDecValue.replace(decimalSeparator, '.'),
- ).toFormat()
- let input = fullDecFormat
-
- if (parts.length <= 1) {
- const quantity = asQuantity(
- new BigNumber(value.replace(decimalSeparator, '.'))
- .decimalPlaces(precision)
- .shiftedBy(denomination),
- )
-
- return [input, quantity]
- }
-
- const [int, dec] = parts
- // trailing `1` is to allow the user to type `1.0` without losing the decimal part
- fullDecValue = `${int}${decimalSeparator}${dec?.slice(0, precision)}1`
- value = `${int}${decimalSeparator}${dec?.slice(0, precision)}`
- fullDecFormat = new BigNumber(
- fullDecValue.replace(decimalSeparator, '.'),
- ).toFormat()
- // remove trailing `1`
- input = fullDecFormat.slice(0, -1)
-
- const quantity = asQuantity(
- new BigNumber(value.replace(decimalSeparator, '.'))
- .decimalPlaces(precision)
- .shiftedBy(denomination),
- )
-
- return [input, quantity]
- },
- format: (
- quantity: Balance.Quantity,
- denomination: number,
- precision?: number,
- ) => {
- if (precision === undefined)
- return new BigNumber(
- Quantities.denominated(quantity, denomination),
- ).toFormat()
- return new BigNumber(Quantities.denominated(quantity, denomination))
- .decimalPlaces(precision)
- .toFormat()
- },
-}
diff --git a/packages/types/src/api/app.ts b/packages/types/src/api/app.ts
index 77d9c3c3eb..596acae065 100644
--- a/packages/types/src/api/app.ts
+++ b/packages/types/src/api/app.ts
@@ -1,5 +1,5 @@
import {BalanceQuantity} from '../balance/token'
-import {SwapAggregator} from '../swap/aggregator'
+import {SwapAggregator} from '../swap/api'
export interface AppApi {
getFrontendFees(): Promise
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index 1ad9190454..f490926110 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -5,23 +5,21 @@ import {
BalanceQuantity,
BalanceToken,
} from './balance/token'
-import {SwapApi} from './swap/api'
-import {SwapProtocol} from './swap/protocol'
import {
- SwapCancelOrderData,
- SwapCompletedOrder,
- SwapCreateOrderData,
- SwapCreateOrderResponse,
- SwapOpenOrder,
- SwapOrderType,
-} from './swap/order'
-import {SwapPool, SwapPoolProvider, SwapSupportedProvider} from './swap/pool'
-import {SwapStorage} from './swap/storage'
-import {SwapManager} from './swap/manager'
+ SwapAggregator,
+ SwapApi,
+ SwapCancelRequest,
+ SwapCancelResponse,
+ SwapCreateRequest,
+ SwapCreateResponse,
+ SwapEstimateRequest,
+ SwapEstimateResponse,
+ SwapOrder,
+ SwapSplit,
+} from './swap/api'
import {AppStorage, AppStorageFolderName} from './app/storage'
import {AppMultiStorage, AppMultiStorageOptions} from './app/multi-storage'
import {NumberLocale} from './intl/numbers'
-import {SwapAggregator} from './swap/aggregator'
import {
ResolverAddressesResponse,
ResolverAddressResponse,
@@ -270,11 +268,9 @@ import {
NotificationTransactionReceivedEvent,
NotificationTrigger,
} from './notifications/manager'
-import {
- SwapMakeOrderCalculation,
- SwapOrderCalculation,
-} from './swap/calculations'
import {NumbersRatio} from './numbers/ratio'
+import {SwapStorage} from './swap/storage'
+import {SwapManager, SwapManagerMaker} from './swap/manager'
export namespace App {
export namespace Errors {
@@ -340,33 +336,20 @@ export namespace App {
}
export namespace Swap {
- export interface Api extends SwapApi {}
- export type Manager = SwapManager
-
- export type OpenOrder = SwapOpenOrder
- export type CompletedOrder = SwapCompletedOrder
- export type CreateOrderData = SwapCreateOrderData
- export type CancelOrderData = SwapCancelOrderData
- export type Order = SwapOpenOrder | SwapCompletedOrder
- export type CreateOrderResponse = SwapCreateOrderResponse
- export type OpenOrderResponse = SwapOpenOrder[]
- export type CompletedOrderResponse = SwapCompletedOrder[]
- export type OrderType = SwapOrderType
-
- export type Protocol = SwapProtocol
-
+ export type Api = SwapApi
+ export type Order = SwapOrder
export type Aggregator = SwapAggregator
-
- export type Pool = SwapPool
- export type PoolResponse = SwapPool[]
- export type PoolProvider = SwapPoolProvider
- export type SupportedProvider = SwapSupportedProvider
-
+ export const Aggregator = SwapAggregator
+ export type CancelRequest = SwapCancelRequest
+ export type CancelResponse = SwapCancelResponse
+ export type EstimateRequest = SwapEstimateRequest
+ export type EstimateResponse = SwapEstimateResponse
+ export type CreateRequest = SwapCreateRequest
+ export type CreateResponse = SwapCreateResponse
+ export type Split = SwapSplit
export type Storage = SwapStorage
-
- export type MakeOrderCalculation = SwapMakeOrderCalculation
-
- export type OrderCalculation = SwapOrderCalculation
+ export type Manager = SwapManager
+ export type ManagerMaker = SwapManagerMaker
}
export namespace Balance {
diff --git a/packages/types/src/swap/aggregator.ts b/packages/types/src/swap/aggregator.ts
deleted file mode 100644
index c7427a1765..0000000000
--- a/packages/types/src/swap/aggregator.ts
+++ /dev/null
@@ -1 +0,0 @@
-export type SwapAggregator = 'muesliswap' | 'dexhunter'
diff --git a/packages/types/src/swap/api.ts b/packages/types/src/swap/api.ts
index ba1543b357..0af03ee973 100644
--- a/packages/types/src/swap/api.ts
+++ b/packages/types/src/swap/api.ts
@@ -1,33 +1,148 @@
+import {ApiResponse} from '../api/response'
import {PortfolioTokenInfo} from '../portfolio/info'
import {PortfolioTokenId} from '../portfolio/token'
-import {
- SwapCancelOrderData,
- SwapCompletedOrder,
- SwapCreateOrderData,
- SwapCreateOrderResponse,
- SwapOpenOrder,
-} from './order'
-import {SwapPool, SwapPoolProvider} from './pool'
-
-export interface SwapApi {
- createOrder(orderData: SwapCreateOrderData): Promise
- cancelOrder(orderData: SwapCancelOrderData): Promise
- getOpenOrders(): Promise
- getCompletedOrders(): Promise
- getPools(args: {
- tokenA: PortfolioTokenId
- tokenB: PortfolioTokenId
- providers?: ReadonlyArray
- }): Promise
- getTokenPairs(
- tokenIdBase: PortfolioTokenId,
- ): Promise>
- getTokens(): Promise>
- getPrice(args: {
- baseToken: PortfolioTokenId
- quoteToken: PortfolioTokenId
- }): Promise
- stakingKey: string
- primaryTokenInfo: Readonly
- supportedProviders: ReadonlyArray
+
+export const SwapAggregator = {
+ Muesliswap: 'muesliswap',
+ Dexhunter: 'dexhunter',
+} as const
+export type SwapAggregator =
+ (typeof SwapAggregator)[keyof typeof SwapAggregator]
+
+export type SwapOrder = {
+ aggregator: SwapAggregator
+ dex: string
+ placedAt?: number
+ lastUpdate?: number
+ status: string
+ tokenIn: PortfolioTokenId
+ tokenOut: PortfolioTokenId
+ amountIn: number
+ actualAmountOut: number
+ expectedAmountOut: number
+ txHash?: string
+ outputIndex?: number
+ updateTxHash?: string
+ customId?: string
+}
+
+export type SwapEstimateRequest = {
+ slippage: number
+ tokenIn: PortfolioTokenId
+ tokenOut: PortfolioTokenId
+ dex?: string
+ blacklistedDexes?: string[]
+} & (
+ | {
+ amountOut?: undefined
+ amountIn: number
+ multiples?: number
+ wantedPrice?: number
+ }
+ | {
+ amountOut: number
+ amountIn?: undefined
+ multiples?: undefined
+ wantedPrice?: undefined
+ }
+)
+
+export type SwapSplit = {
+ amountIn: number
+ batcherFee: number
+ deposits: number
+ dex: string
+ expectedOutput: number
+ expectedOutputWithoutSlippage: number
+ fee: number
+ finalPrice: number
+ initialPrice: number
+ poolFee: number
+ poolId: string
+ priceDistortion: number
+ priceImpact: number
+}
+
+export type SwapEstimateResponse = {
+ splits: SwapSplit[]
+ batcherFee: number
+ deposits: number
+ aggregatorFee: number
+ frontendFee: number
+ netPrice: number
+ totalFee: number
+ totalOutput: number
+ totalOutputWithoutSlippage?: number
+ totalInput?: number
+}
+
+export type SwapCreateRequest = {
+ amountIn: number
+ tokenIn: PortfolioTokenId
+ tokenOut: PortfolioTokenId
+ dex?: string
+ blacklistedDexes?: string[]
+} & (
+ | {
+ multiples?: number
+ wantedPrice?: number
+ slippage?: undefined
+ }
+ | {
+ slippage: number
+ wantedPrice?: undefined
+ multiples?: undefined
+ }
+)
+
+// Leaks aggregator because of current challenge creating a cbor inside package
+export type SwapCreateResponse = {
+ splits: SwapSplit[]
+ batcherFee: number
+ deposits: number
+ aggregatorFee: number
+ frontendFee: number
+ netPrice?: number
+ totalFee: number
+ totalInput: number
+ totalOutput: number
+ totalOutputWithoutSlippage?: number
+} & (
+ | {
+ aggregator: typeof SwapAggregator.Muesliswap
+ datumData: string
+ datumHash: string
+ contractAddress: string
+ cbor?: undefined
+ }
+ | {
+ aggregator: typeof SwapAggregator.Dexhunter
+ datumData?: undefined
+ datumHash?: undefined
+ contractAddress?: undefined
+ cbor: string
+ }
+)
+
+export type SwapCancelRequest = {
+ order: SwapOrder
+ collateral?: string
+}
+
+export type SwapCancelResponse = {
+ cbor: string
+ additionalCancellationFee?: number
}
+export type SwapApi = Readonly<{
+ orders: () => Promise>>>
+ tokens: () => Promise>>>
+ estimate(
+ args: SwapEstimateRequest,
+ ): Promise>>
+ create(
+ args: SwapCreateRequest,
+ ): Promise>>
+ cancel: (
+ args: SwapCancelRequest,
+ ) => Promise>>
+}>
diff --git a/packages/types/src/swap/calculations.ts b/packages/types/src/swap/calculations.ts
deleted file mode 100644
index 25513f6708..0000000000
--- a/packages/types/src/swap/calculations.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-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: {
- side?: 'buy' | 'sell'
- slippage: number
- orderType: Swap.OrderType
- limitPrice?: string
- amounts: {
- sell: Portfolio.Token.Amount
- buy: Portfolio.Token.Amount
- }
- lpTokenHeld?: Portfolio.Token.Amount
- }
- sides: {
- sell: Portfolio.Token.Amount
- buy: Portfolio.Token.Amount
- }
- pool: Swap.Pool
- prices: {
- base: string
- market: string
- actualPrice: string
- withSlippage: string
- withFees: string
- withFeesAndSlippage: string
- difference: string
- priceImpact: string
- }
- hasSupply: boolean
- buyAmountWithSlippage: Portfolio.Token.Amount
- ptTotalValueSpent?: Portfolio.Token.Amount
- cost: {
- liquidityFee: Portfolio.Token.Amount
- deposit: Portfolio.Token.Amount
- batcherFee: Portfolio.Token.Amount
- frontendFeeInfo: {
- discountTier?: App.FrontendFeeTier
- fee: Portfolio.Token.Amount
- }
- ptTotalRequired: Portfolio.Token.Amount
- }
-}>
diff --git a/packages/types/src/swap/manager.ts b/packages/types/src/swap/manager.ts
index 9d1a41a9b8..b381565a14 100644
--- a/packages/types/src/swap/manager.ts
+++ b/packages/types/src/swap/manager.ts
@@ -1,54 +1,27 @@
-import {AppFrontendFeeTier} from '../api/app'
+import {AppFrontendFeesResponse} from '../api/app'
+import {ChainSupportedNetworks} from '../chain/network'
+import {PortfolioTokenAmount} from '../portfolio/amount'
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'
export type SwapManager = Readonly<{
clearStorage: SwapStorage['clear']
slippage: SwapStorage['slippage']
- order: {
- cancel: SwapApi['cancelOrder']
- create: SwapApi['createOrder']
- list: {
- byStatusOpen: SwapApi['getOpenOrders']
- byStatusCompleted: SwapApi['getCompletedOrders']
- }
- }
- tokens: {
- list: {
- onlyVerified: SwapApi['getTokens']
- byPair: SwapApi['getTokenPairs']
- }
- }
- price: {
- byPair: SwapApi['getPrice']
- }
- pools: {
- list: {
- byPair: SwapApi['getPools']
- }
- }
+ api: SwapApi
+ aggregatorTokenIds: ReadonlyArray
+ updateAggregatorTokensHeld: (
+ values: ReadonlyArray,
+ ) => void
+}>
+
+export type SwapManagerMaker = (args: {
+ address: string
+ addressHex: string
stakingKey: string
primaryTokenInfo: PortfolioTokenInfo
- supportedProviders: ReadonlyArray
- 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
-}>
+ aggregatedFrontendFeeTiers: AppFrontendFeesResponse
+ network: ChainSupportedNetworks
+ storage: SwapStorage
+}) => SwapManager
diff --git a/packages/types/src/swap/order.ts b/packages/types/src/swap/order.ts
deleted file mode 100644
index 0151421eeb..0000000000
--- a/packages/types/src/swap/order.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import {BalanceQuantity} from '../balance/token'
-import {PortfolioTokenId} from '../portfolio/token'
-import {SwapPool, SwapPoolProvider} from './pool'
-
-export type SwapOrderType = 'market' | 'limit'
-
-export type SwapCreateOrderData = {
- amounts: {
- sell: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- buy: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- }
- limitPrice?: BalanceQuantity
- address: string
- slippage: number
- selectedPool: SwapPool
-}
-
-export type SwapCancelOrderData = {
- utxos: {
- order: string
- collateral: string
- }
- address: string
-}
-
-export type SwapCreateOrderResponse = {
- datum: string
- datumHash: string
- contractAddress: string
-}
-
-export type SwapOpenOrder = {
- provider: SwapPoolProvider
- from: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- to: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- deposit: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- utxo: string
- owner: string
-}
-
-export type SwapCompletedOrder = {
- from: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- to: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- txHash: string
- provider: SwapPoolProvider
- placedAt: number
-}
diff --git a/packages/types/src/swap/pool.ts b/packages/types/src/swap/pool.ts
deleted file mode 100644
index b08dc34119..0000000000
--- a/packages/types/src/swap/pool.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-import {PortfolioTokenId} from '../portfolio/token'
-
-export type SwapPoolProvider =
- | 'minswap'
- | 'sundaeswap'
- | 'wingriders'
- | 'muesliswap'
- | 'muesliswap_v1'
- | 'muesliswap_v2'
- | 'muesliswap_v3'
- | 'muesliswap_v4'
- | 'vyfi'
- | 'spectrum'
-
-export type SwapSupportedProvider = Extract<
- SwapPoolProvider,
- | 'minswap'
- | 'wingriders'
- | 'sundaeswap'
- | 'muesliswap'
- | 'muesliswap_v2'
- | 'vyfi'
->
-
-export type SwapPool = {
- provider: SwapSupportedProvider
- fee: string // % pool liquidity provider fee, usually 0.3.
- tokenA: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- tokenB: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- 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.
- batcherFee: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- deposit: {
- // amount of deposit / minUTxO required by protocol, returned to user, in lovelace.
- tokenId: PortfolioTokenId
- quantity: bigint
- }
- // utxo: string // txhash#txindex of latest transaction involving this pool.
- poolId: string // identifier of the pool across platforms.
- lpToken: {
- tokenId: PortfolioTokenId
- quantity: bigint
- }
-}
diff --git a/packages/types/src/swap/protocol.ts b/packages/types/src/swap/protocol.ts
deleted file mode 100644
index a5af495f01..0000000000
--- a/packages/types/src/swap/protocol.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type SwapProtocol =
- | 'minswap'
- | 'sundaeswap'
- | 'wingriders'
- | 'muesliswap'
diff --git a/yarn.lock b/yarn.lock
index 2ba634c17a..170c8a9b15 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5883,6 +5883,18 @@
dependencies:
"@types/node" "*"
+"@types/lodash-es@^4.17.12":
+ version "4.17.12"
+ resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b"
+ integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==
+ dependencies:
+ "@types/lodash" "*"
+
+"@types/lodash@*":
+ version "4.17.13"
+ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.13.tgz#786e2d67cfd95e32862143abe7463a7f90c300eb"
+ integrity sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==
+
"@types/lodash@^4.14.175":
version "4.14.195"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632"
@@ -15877,6 +15889,11 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"
+lodash-es@^4.17.21:
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
@@ -21307,7 +21324,16 @@ string-natural-compare@^3.0.1:
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
-"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0":
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -21420,7 +21446,7 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -21448,6 +21474,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
dependencies:
ansi-regex "^4.1.0"
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -23070,7 +23103,7 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -23106,6 +23139,15 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"