UNPKG

@yoroi/swap

Version:
854 lines (853 loc) 37.3 kB
"use strict"; import { isPrimaryToken } from '@yoroi/portfolio'; import { Chain, Swap } from '@yoroi/types'; import { api, primaryTokenInfo } from './api.mocks'; import { fromSwapProtocol, ptIdDh, reverse, toPriceImpact, toSwapProtocol, toSwapSplit, transformersMaker } from './transformers'; import { Dex } from './types'; const address = 'addr1q9qhyvkm5fytm5ckgshny0zz08a3urhhh7ckdqxcm27av40eafn3v5lr2w2n2er9uj7c743mt42gpe8tgek6394z9t7qn4yjzl'; const network = Chain.Network.Mainnet; const transformers = transformersMaker({ primaryTokenInfo, address, network, isPrimaryToken }); describe('transformers', () => { describe('tokens', () => { test('should correctly transform the tokens response', () => { expect(transformers.tokens.response([...api.responses.tokens, { token_id: '000000000000000000000000000000000000000000000000000000006c6f76656c616365', token_policy: '00000000000000000000000000000000000000000000000000000000', is_verified: true, supply: 45_000_000_000, creation_date: '0001-01-01T00:00:00Z', price: 0 }])).toEqual([...api.results.tokens, { application: 'coin', decimals: 6, description: '', fingerprint: '', id: '.', name: 'Cardano', nature: 'primary', originalImage: '', reference: '', status: 'valid', symbol: 'ADA', tag: '', ticker: 'ADA', type: 'ft', website: '' }]); }); test('should correctly transform the token id', () => { expect(transformers.tokens.fromId(ptIdDh)).toBe(primaryTokenInfo.id); expect(transformers.tokens.toId(primaryTokenInfo.id)).toBe('ADA'); }); }); describe('orders', () => { test('should correctly transform the orders response', () => { expect(transformers.orders.response([...api.responses.orders, { _id: '66cf043794579f05fc204f72', dex: 'SUNDAESWAP', user_address: 'addr1q9qhyvkm5fytm5ckgshny0zz08a3urhhh7ckdqxcm27av40eafn3v5lr2w2n2er9uj7c743mt42gpe8tgek6394z9t7qn4yjzl', user_stake: 'stake1u8u75eck203489f4v3j7f0v02ca464yqun45vmdgj63z4lqm9pu9k', submission_time: undefined, last_update: undefined, output_index: 0, is_stop_loss: false, is_oor: false, batcher_fee: 2.5, deposit: 2, status: 'PENDING' }])).toEqual([...api.results.orders, { actualAmountOut: 0, aggregator: 'muesliswap', amountIn: 0, customId: '66cf043794579f05fc204f72', expectedAmountOut: 0, lastUpdate: undefined, placedAt: undefined, outputIndex: 0, protocol: 'sundaeswap-v1', status: 'open', tokenIn: '.', tokenOut: '.', txHash: '', updateTxHash: '' }]); }); }); describe('cancel', () => { test('should correctly transform the cancel request', () => { expect(transformers.cancel.request(api.inputs.cancel)).toEqual(api.requests.cancel(address)); }); test('should correctly transform the cancel request to default', () => { expect(transformers.cancel.request(api.inputs.cancel)).toEqual(api.requests.cancel(address)); }); test('should correctly transform the cancel response to default', () => { expect(transformers.cancel.response({ additional_cancellation_fee: 2_000_000 })).toEqual({ cbor: '', additionalCancellationFee: 2_000_000 }); }); test('should correctly transform the cancel response', () => { expect(transformers.cancel.response(api.responses.cancel)).toEqual(api.results.cancel); }); }); describe('estimate', () => { test('should correctly transform the estimate request', () => { expect(transformers.estimate.request(api.inputs.estimate)).toEqual(expect.objectContaining(api.requests.estimate)); }); test('should correctly transform the estimate response', () => { expect(transformers.estimate.response(api.responses.estimate)).toMatchObject(api.results.estimate); }); test('should correctly transform the estimate response 2', () => { expect(transformers.estimate.response({ splits: [{ expected_output: 9223372036854.775, expected_output_without_slippage: 9223372036854.775, fee: 4, dex: 'VYFI', price_impact: 843546.4933049141, initial_price: 0.00011853462095991185, final_price: 1.0000131730805681, pool_id: '000000000000000000000000000000000000000000000000000000006c6f76656c616365af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950VYFIaddr1wx6vzxyapfw4f4ragkvqtk3y473wj4sul3fr98xhguvazlse88lan', batcher_fee: 2, deposits: 2, price_distortion: 841015.5508249996, pool_fee: 0.003 }], total_fee: 4, total_output: 0, deposits: 2, batcher_fee: 2, total_input: 1000000000000000, possible_routes: {}, net_price: 0, net_price_reverse: 0, dexhunter_fee: 1, blacklisted_dexes: null, partner: '', partner_fee: 0 }, true)).toMatchObject({ aggregatorFee: 1, batcherFee: 2, deposits: 2, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [{ amountIn: 0, batcherFee: 2, deposits: 2, expectedOutput: 9223372036854.775, expectedOutputWithoutSlippage: 9223372036854.775, fee: 4, finalPrice: 1.0000131730805681, initialPrice: 0.00011853462095991185, poolFee: 0.003, poolId: '000000000000000000000000000000000000000000000000000000006c6f76656c616365af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950VYFIaddr1wx6vzxyapfw4f4ragkvqtk3y473wj4sul3fr98xhguvazlse88lan', priceDistortion: 841015.5508249996, priceImpact: 843546.4933049141, protocol: 'vyfi-v1' }], totalFee: 3, totalInput: 0, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); test('should correctly transform the estimate response to defaults', () => { expect(transformers.estimate.response({ total_input: 1000000000000000, possible_routes: {}, blacklisted_dexes: null, partner: '' })).toEqual({ aggregatorFee: 0, batcherFee: 0, deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [], totalFee: 0, totalInput: undefined, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); }); describe('reverseEstimate', () => { test('should correctly transform the reverse estimate request', () => { expect(transformers.reverseEstimate.request(api.inputs.reverseEstimate)).toEqual(expect.objectContaining(api.requests.reverseEstimate)); }); test('should correctly transform the reverse estimate response', () => { expect(transformers.reverseEstimate.response(api.responses.reverseEstimate)).toMatchObject(api.results.reverseEstimate); }); test('should correctly transform the reverse estimate response to default', () => { expect(transformers.reverseEstimate.response({ possible_routes: {}, total_input_without_slippage: 0.0045599187141238265 }, true)).toMatchObject({ aggregatorFee: 0, batcherFee: 0, deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [], totalFee: 0, totalInput: undefined, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); test('should correctly transform the reverse estimate response to default with speacial splits', () => { expect(transformers.reverseEstimate.response({ splits: [{ expected_output: 35.288684, expected_output_without_slippage: 37.145984, fee: 4, dex: 'MINSWAP', price_impact: 0.0013874760358920197, initial_price: 0.00012238115855095046, final_price: 0.0001223828565601978, pool_id: '000000000000000000000000000000000000000000000000000000006c6f76656c616365af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950MINSWAPc1245066d133f864ff9220aabb1388bb801986e6da6754b8234ce8fc3c6029f6', batcher_fee: 2, deposits: 2, price_distortion: 0.30161668639221895, pool_fee: 0.003 }], possible_routes: {}, total_input_without_slippage: 0.0045599187141238265, net_price_reverse: 122.75670807707843 })).toMatchObject({ aggregatorFee: 0, batcherFee: 0, deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [{ amountIn: 0, batcherFee: 2, deposits: 2, expectedOutput: 35.288684, expectedOutputWithoutSlippage: 37.145984, fee: 4, finalPrice: 0.0001223828565601978, initialPrice: 0.00012238115855095046, poolFee: 0.003, poolId: '000000000000000000000000000000000000000000000000000000006c6f76656c616365af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950MINSWAPc1245066d133f864ff9220aabb1388bb801986e6da6754b8234ce8fc3c6029f6', priceDistortion: 0.30161668639221895, priceImpact: 0.0013874760358920197, protocol: 'minswap-v1' }], totalInput: 0, totalFee: 0, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); }); describe('limitEstimate', () => { test('should correctly transform the limit estimate request', () => { expect(transformers.limitEstimate.request(api.inputs.limitEstimate)).toEqual(api.requests.limitEstimate); }); test('should correctly transform the limit estimate request to default', () => { expect(transformers.limitEstimate.request({ tokenIn: '.', tokenOut: 'af2e27f580f7f08e93190a81f72462f153026d06450924726645891b.44524950', amountIn: 38, protocol: undefined, blockedProtocols: ['wingriders-v1'], amountOut: undefined, multiples: undefined, wantedPrice: 1, slippage: 0 })).toEqual({ amount_in: 38, blacklisted_dexes: ['WINGRIDER'], dex: 'UNSUPPORTED', multiples: 1, token_in: 'ADA', token_out: 'af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950', wanted_price: 1 }); }); test('should correctly transform the limit estimate response to default', () => { expect(transformers.limitEstimate.response({ total_fee: undefined, total_output: undefined, deposits: undefined, batcher_fee: undefined, total_input: undefined, possible_routes: {}, net_price: undefined, dexhunter_fee: undefined, blacklisted_dexes: null, partner: '', partner_fee: undefined }, false)).toEqual({ aggregatorFee: 0, batcherFee: 0, deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [], totalFee: 0, totalInput: undefined, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); test('should correctly transform the limit estimate response to default with special split case', () => { expect(transformers.limitEstimate.response({ total_fee: undefined, total_output: undefined, deposits: undefined, batcher_fee: undefined, total_input: undefined, possible_routes: {}, net_price: undefined, dexhunter_fee: undefined, blacklisted_dexes: null, partner: '', partner_fee: undefined, splits: [{ expected_output: 9223372036854.775, expected_output_without_slippage: 9223372036854.775, fee: 4, dex: 'VYFI', price_impact: 874011.5392608035, initial_price: 0.00011440337320702896, final_price: 1.0000130865062424, pool_id: '000000000000000000000000000000000000000000000000000000006c6f76656c616365af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950VYFIaddr1wx6vzxyapfw4f4ragkvqtk3y473wj4sul3fr98xhguvazlse88lan', batcher_fee: 2, deposits: 2, price_distortion: 871389.201643021, pool_fee: 0.003 }] }, false)).toMatchObject({ aggregatorFee: 0, batcherFee: 0, deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, totalFee: 0, totalInput: 0, totalOutput: 0, totalOutputWithoutSlippage: 0, splits: [{ amountIn: 0, batcherFee: 2, deposits: 2, expectedOutput: 9223372036854.775, expectedOutputWithoutSlippage: 9223372036854.775, fee: 4, finalPrice: 1.0000130865062424, initialPrice: 0.00011440337320702896, poolFee: 0.003, poolId: '000000000000000000000000000000000000000000000000000000006c6f76656c616365af2e27f580f7f08e93190a81f72462f153026d06450924726645891b44524950VYFIaddr1wx6vzxyapfw4f4ragkvqtk3y473wj4sul3fr98xhguvazlse88lan', priceDistortion: 871389.201643021, priceImpact: 874011.5392608035, protocol: 'vyfi-v1' }] }); }); test('should correctly transform the limit estimate response', () => { expect(transformers.limitEstimate.response(api.responses.limitEstimate, false)).toMatchObject(api.results.limitEstimate); }); }); describe('limitBuild', () => { test('should correctly transform the limit build request to default', () => { expect(transformers.limitBuild.request(api.inputs.create[0])).toEqual(api.requests.limitBuild); }); test('should correctly transform the limit build request', () => { expect(transformers.limitBuild.request({ ...api.inputs.create[0], protocol: 'minswap-v1', amountIn: 1, tokenIn: '.', tokenOut: 'abc.cbr' })).toEqual({ ...api.requests.limitBuild, dex: 'MINSWAP', token_out: 'abccbr' }); }); test('should correctly transform the limit build request alt', () => { expect(transformers.limitBuild.request({ ...api.inputs.create[2], protocol: 'minswap-v1', amountIn: 1, tokenIn: '.', tokenOut: 'abc.cbr' })).toEqual({ ...api.requests.limitBuild, dex: 'MINSWAP', token_out: 'abccbr', wanted_price: 1 }); }); test('should correctly transform the limit build response', () => { expect(transformers.limitBuild.response(api.responses.limitBuild, false)).toMatchObject({ aggregator: 'dexhunter', aggregatorFee: 0, batcherFee: 0, cbor: '84a500838258203976997901257e283cc9da856b9e50174c4eb9dfd8ce55b5be9fbe2f9289577500825820475ffb1f1820eee1790729d86ced473e9f7724ddcd7bf59b477e3293415f16bf03825820e22c3b1fd8e77643612bb2611e8fb74238ba540867dd9d4ecaec1590c613566400018283583911a65ca58a4e9c755fa830173d2a5caed458ac0c73f97db7faae2e7e3b52563c5410bff6a0d43ccebb7c37e1f69f5eb260552521adff33b9c21a004c4b40582079aaea3504c39973f6bd387a2250e3553220722f429ffddbf6dae7f3c7bfb61c825839014747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aecf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdc821a005a5946ac581c2441ab3351c3b80213a98f4e09ddcf7dabe4879c3c94cc4e7205cb63a144464952451909e3581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa144534e454b18cc581c4cb48d60d1f7823d1307c61b9ecf472ff78cf22d1ccc5786d59461f8a1474144414d4f4f4e1a004c3d2e581c8654e8b350e298c80d2451beb5ed80fc9eee9f38ce6b039fb8706bc3a1474c4f42535445521a0010f66f581ca0028f350aaabe0545fdcb56b039bfb08e4bb4d8c4d7c3c7d481c235a145484f534b591a06e8f5c4581cafbe91c0b44b3040e360057bf8354ead8c49c4979ae6ab7c4fbdc9eba1464d494c4b76321a00424fe1581cb788fbee71a32d2efc5ee7d151f3917d99160f78fb1e41a1bbf80d8fa1494c454146544f4b454e1b0000000536f5613f581cc5609c4800c05e82c4219ccf14c7fdf5212e11f83dbbb57ac716e98ea145666c756666186f581cc898c986b97e7ac5b33e999bc11b054a9987f48ec4459f8c1ea0c32ba148435245414d5049451a06a21941581ccdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48aa144434153541911bd581ce0c4c2d7c4a0ed2cf786753fd845dee82c45512cee03e92adfd3fb8da14d6a6176696275656e6f2e61646101581cf0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9aa14d000de1406a6176696275656e6f01021a0003388d0758203ee91922e55ac83b91cdce3d7aa8fb01085e26622a6da92bad3908c29cbffca00b582067cbc9782dbb59e371f3dbc4eeba0b20cdeb91e1b7f53efaccd58f78975a50fba10481d8799fd8799fd8799f581c4747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aeffd8799fd8799fd8799f581ccf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdcffffffffd8799fd8799f581c4747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aeffd8799fd8799fd8799f581ccf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdcffffffffd87a80d8799fd8799f581ccdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a4443415354ff19046aff1a001e84801a001e8480fff5a11902a2783b7b276d7367273a205b274d7565736c69537761702041676772656761746f7220506c61636520437573746f6d204c696d6974204f72646572275d7d', deposits: 2, frontendFee: 0, netPrice: 0.04252918925670425, splits: [{ amountIn: 1, batcherFee: 2, deposits: 2, expectedOutput: 1130, expectedOutputWithoutSlippage: 1130, fee: 0.3, finalPrice: 0.041994, initialPrice: 1130, poolFee: 0.3, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', priceDistortion: 1.258404559451805, priceImpact: 1.258404559451805, protocol: 'minswap-v1' }], priceImpact: 1.258404559451805, totalFee: 0, totalInput: 1, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); test('should correctly transform the limit build response (speacial case)', () => { expect(transformers.limitBuild.response({ cbor: '84a500838258203976997901257e283cc9da856b9e50174c4eb9dfd8ce55b5be9fbe2f9289577500825820475ffb1f1820eee1790729d86ced473e9f7724ddcd7bf59b477e3293415f16bf03825820e22c3b1fd8e77643612bb2611e8fb74238ba540867dd9d4ecaec1590c613566400018283583911a65ca58a4e9c755fa830173d2a5caed458ac0c73f97db7faae2e7e3b52563c5410bff6a0d43ccebb7c37e1f69f5eb260552521adff33b9c21a004c4b40582079aaea3504c39973f6bd387a2250e3553220722f429ffddbf6dae7f3c7bfb61c825839014747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aecf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdc821a005a5946ac581c2441ab3351c3b80213a98f4e09ddcf7dabe4879c3c94cc4e7205cb63a144464952451909e3581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa144534e454b18cc581c4cb48d60d1f7823d1307c61b9ecf472ff78cf22d1ccc5786d59461f8a1474144414d4f4f4e1a004c3d2e581c8654e8b350e298c80d2451beb5ed80fc9eee9f38ce6b039fb8706bc3a1474c4f42535445521a0010f66f581ca0028f350aaabe0545fdcb56b039bfb08e4bb4d8c4d7c3c7d481c235a145484f534b591a06e8f5c4581cafbe91c0b44b3040e360057bf8354ead8c49c4979ae6ab7c4fbdc9eba1464d494c4b76321a00424fe1581cb788fbee71a32d2efc5ee7d151f3917d99160f78fb1e41a1bbf80d8fa1494c454146544f4b454e1b0000000536f5613f581cc5609c4800c05e82c4219ccf14c7fdf5212e11f83dbbb57ac716e98ea145666c756666186f581cc898c986b97e7ac5b33e999bc11b054a9987f48ec4459f8c1ea0c32ba148435245414d5049451a06a21941581ccdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48aa144434153541911bd581ce0c4c2d7c4a0ed2cf786753fd845dee82c45512cee03e92adfd3fb8da14d6a6176696275656e6f2e61646101581cf0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9aa14d000de1406a6176696275656e6f01021a0003388d0758203ee91922e55ac83b91cdce3d7aa8fb01085e26622a6da92bad3908c29cbffca00b582067cbc9782dbb59e371f3dbc4eeba0b20cdeb91e1b7f53efaccd58f78975a50fba10481d8799fd8799fd8799f581c4747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aeffd8799fd8799fd8799f581ccf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdcffffffffd8799fd8799f581c4747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aeffd8799fd8799fd8799f581ccf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdcffffffffd87a80d8799fd8799f581ccdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a4443415354ff19046aff1a001e84801a001e8480fff5a11902a2783b7b276d7367273a205b274d7565736c69537761702041676772656761746f7220506c61636520437573746f6d204c696d6974204f72646572275d7d', deposits: 2, splits: [{ batcher_fee: 2, deposits: 2, expected_output: 1130, expected_output_without_slippage: 1130, fee: 0.3, final_price: 0.041994, initial_price: 0.04252918925670425, pool_fee: 0.3, pool_id: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', price_distortion: 1.258404559451805, price_impact: 1.258404559451805, dex: 'MINSWAP' }], totalFee: 4 }, false)).toMatchObject({ aggregator: 'dexhunter', aggregatorFee: 0, batcherFee: 0, cbor: '84a500838258203976997901257e283cc9da856b9e50174c4eb9dfd8ce55b5be9fbe2f9289577500825820475ffb1f1820eee1790729d86ced473e9f7724ddcd7bf59b477e3293415f16bf03825820e22c3b1fd8e77643612bb2611e8fb74238ba540867dd9d4ecaec1590c613566400018283583911a65ca58a4e9c755fa830173d2a5caed458ac0c73f97db7faae2e7e3b52563c5410bff6a0d43ccebb7c37e1f69f5eb260552521adff33b9c21a004c4b40582079aaea3504c39973f6bd387a2250e3553220722f429ffddbf6dae7f3c7bfb61c825839014747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aecf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdc821a005a5946ac581c2441ab3351c3b80213a98f4e09ddcf7dabe4879c3c94cc4e7205cb63a144464952451909e3581c279c909f348e533da5808898f87f9a14bb2c3dfbbacccd631d927a3fa144534e454b18cc581c4cb48d60d1f7823d1307c61b9ecf472ff78cf22d1ccc5786d59461f8a1474144414d4f4f4e1a004c3d2e581c8654e8b350e298c80d2451beb5ed80fc9eee9f38ce6b039fb8706bc3a1474c4f42535445521a0010f66f581ca0028f350aaabe0545fdcb56b039bfb08e4bb4d8c4d7c3c7d481c235a145484f534b591a06e8f5c4581cafbe91c0b44b3040e360057bf8354ead8c49c4979ae6ab7c4fbdc9eba1464d494c4b76321a00424fe1581cb788fbee71a32d2efc5ee7d151f3917d99160f78fb1e41a1bbf80d8fa1494c454146544f4b454e1b0000000536f5613f581cc5609c4800c05e82c4219ccf14c7fdf5212e11f83dbbb57ac716e98ea145666c756666186f581cc898c986b97e7ac5b33e999bc11b054a9987f48ec4459f8c1ea0c32ba148435245414d5049451a06a21941581ccdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48aa144434153541911bd581ce0c4c2d7c4a0ed2cf786753fd845dee82c45512cee03e92adfd3fb8da14d6a6176696275656e6f2e61646101581cf0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9aa14d000de1406a6176696275656e6f01021a0003388d0758203ee91922e55ac83b91cdce3d7aa8fb01085e26622a6da92bad3908c29cbffca00b582067cbc9782dbb59e371f3dbc4eeba0b20cdeb91e1b7f53efaccd58f78975a50fba10481d8799fd8799fd8799f581c4747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aeffd8799fd8799fd8799f581ccf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdcffffffffd8799fd8799f581c4747a9606da0c06ef08fddf31a89a604fc15584ac00ff1bf88dfc1aeffd8799fd8799fd8799f581ccf085cc39aa4ff52de1ea606ee581aac1dab8166d6830e7a9b6cecdcffffffffd87a80d8799fd8799f581ccdaaee586376139ee8c3cc4061623968810d177ca5c300afb890b48a4443415354ff19046aff1a001e84801a001e8480fff5a11902a2783b7b276d7367273a205b274d7565736c69537761702041676772656761746f7220506c61636520437573746f6d204c696d6974204f72646572275d7d', deposits: 2, frontendFee: 0, priceImpact: 0, netPrice: 0.04252918925670425, splits: [{ amountIn: 0, batcherFee: 2, deposits: 2, expectedOutput: 1130, expectedOutputWithoutSlippage: 1130, fee: 0.3, finalPrice: 0.041994, initialPrice: 0.04252918925670425, poolFee: 0.3, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', priceDistortion: 1.258404559451805, priceImpact: 1.258404559451805, protocol: 'minswap-v1' }], totalFee: 0, totalInput: 0, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); }); describe('build', () => { test('should correctly transform the build request', async () => { expect(transformers.build.request(api.inputs.create[1])).toEqual(api.requests.build); }); test('should correctly transform the build request to default', async () => { expect(transformers.build.request(api.inputs.create[0])).toEqual({ ...api.requests.build, slippage: 0 }); }); test('should correctly transform the build response', async () => { expect(transformers.build.response(api.responses.build)).toMatchObject({ aggregator: 'dexhunter', aggregatorFee: 0.002, batcherFee: 0.001, cbor: 'a1b2c3d4e5f6', deposits: 1000, frontendFee: 0.003, netPrice: 1.23, priceImpact: 1.258404559451805, splits: [{ amountIn: 1, batcherFee: 2, deposits: 2, expectedOutput: 1130, expectedOutputWithoutSlippage: 1130, fee: 0.3, finalPrice: 0.041994, initialPrice: 1130, poolFee: 0.3, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', priceDistortion: 1.258404559451805, priceImpact: 1.258404559451805, protocol: 'minswap-v1' }], totalFee: 0.006, totalInput: 500, totalOutput: 495, totalOutputWithoutSlippage: 500 }); }); test('should correctly transform the build response to defaults', async () => { expect(transformers.build.response({ average_price: 1.234, communications: ['Success', 'Transaction confirmed'], net_price_reverse: 0.812, partner_code: 'PartnerX', possible_routes: { route1: 0.5, route2: 0.3, route3: 0.2 }, splits: [{ amount_in: 1, batcher_fee: 2, deposits: 2, expected_output: 1130, expected_output_without_slippage: 1130, fee: 0.3, final_price: 0.041994, initial_price: 0.04252918925670425, pool_fee: 0.3, pool_id: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', price_distortion: 1.258404559451805, price_impact: 1.258404559451805, dex: 'MINSWAP' }], total_input_without_slippage: 505 })).toMatchObject({ aggregator: 'dexhunter', aggregatorFee: 0, batcherFee: 0, cbor: '', deposits: 0, frontendFee: 0, netPrice: 0.04252918925670425, priceImpact: 1.258404559451805, splits: [{ amountIn: 1, batcherFee: 2, deposits: 2, expectedOutput: 1130, expectedOutputWithoutSlippage: 1130, fee: 0.3, finalPrice: 0.041994, initialPrice: 1130, poolFee: 0.3, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', priceDistortion: 1.258404559451805, priceImpact: 1.258404559451805, protocol: 'minswap-v1' }], totalFee: 0, totalInput: 1, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); test('should correctly transform the build response to defaults (special case)', async () => { expect(transformers.build.response({ average_price: 1.234, communications: ['Success', 'Transaction confirmed'], net_price_reverse: 0, partner_code: 'PartnerX', possible_routes: { route1: 0.5, route2: 0.3, route3: 0.2 }, splits: [{ batcher_fee: 2, deposits: 2, expected_output: 1130, expected_output_without_slippage: 1130, fee: 0.3, final_price: 0.041994, initial_price: undefined, pool_fee: 0.3, pool_id: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', price_distortion: 1.258404559451805, price_impact: 1.258404559451805, dex: 'MINSWAP' }], total_input_without_slippage: 505 }, true)).toMatchObject({ aggregator: 'dexhunter', aggregatorFee: 0, batcherFee: 0, cbor: '', deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [{ amountIn: 0, batcherFee: 2, deposits: 2, expectedOutput: 1130, expectedOutputWithoutSlippage: 1130, fee: 0.3, finalPrice: 0.041994, initialPrice: 0, poolFee: 0.3, poolId: '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1.3513ef4f9724b1bdbedd1f606ed93368f0442b236f3ff201bb28532cdf2a53a9', priceDistortion: 1.258404559451805, priceImpact: 1.258404559451805, protocol: 'minswap-v1' }], totalFee: 0, totalInput: 0, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); test('should correctly transform the build response to defaults (special case 2)', async () => { expect(transformers.build.response({ average_price: 1.234, communications: ['Success', 'Transaction confirmed'], net_price_reverse: 0.812, partner_code: 'PartnerX', possible_routes: { route1: 0.5, route2: 0.3, route3: 0.2 }, total_input_without_slippage: 505 })).toEqual({ aggregator: 'dexhunter', aggregatorFee: 0, batcherFee: 0, cbor: '', deposits: 0, frontendFee: 0, netPrice: 0, priceImpact: 0, splits: [], totalFee: 0, totalInput: 0, totalOutput: 0, totalOutputWithoutSlippage: 0 }); }); }); }); describe('toSwapSplit', () => { it('should convert input object to Swap.Split format with defaults', () => { const input = {}; const expectedOutput = { amountIn: 0, batcherFee: 0, deposits: 0, protocol: 'unsupported', expectedOutput: 0, expectedOutputWithoutSlippage: 0, fee: 0, finalPrice: 0, initialPrice: 0, poolFee: 0, poolId: '', priceDistortion: 0, priceImpact: 0 }; expect(toSwapSplit(input)).toEqual(expect.objectContaining(expectedOutput)); }); it('should correctly map input values to output structure', () => { const input = { amount_in: 100, batcher_fee: 2, deposits: 50, dex: 'MINSWAP', expected_output: 95, expected_output_without_slippage: 98, fee: 1, final_price: 1.1, initial_price: 1.0, pool_fee: 0.3, pool_id: 'pool-123', price_distortion: 0.05, price_impact: 0.02 }; const expectedOutput = { amountIn: 100, batcherFee: 2, deposits: 50, protocol: 'minswap-v1', expectedOutput: 95, expectedOutputWithoutSlippage: 98, fee: 1, finalPrice: 1.1, initialPrice: 0.98, poolFee: 0.3, poolId: 'pool-123', priceDistortion: 0.05, priceImpact: 0.02 }; expect(toSwapSplit(input)).toEqual(expect.objectContaining(expectedOutput)); }); }); describe('toPriceImpact', () => { it('should calculate the weighted average price impact correctly', () => { const splits = [{ amount_in: 100, price_impact: 0.02 }, { amount_in: 200, price_impact: 0.03 }, { amount_in: 300, price_impact: 0.01 }]; const result = toPriceImpact(splits); expect(result).toBeCloseTo(0.018333333, 5); // Weighted average is 0.02 }); it('should return 0 if total amount_in is 0', () => { const splits = [{ amount_in: 0, price_impact: 0.02 }, { amount_in: 0, price_impact: 0.03 }]; const result = toPriceImpact(splits); expect(result).toBe(0); }); it('should handle missing price_impact or amount_in gracefully', () => { const splits = [{ amount_in: 100, price_impact: undefined }, { amount_in: undefined, price_impact: 0.03 }, { amount_in: 300, price_impact: 0.01 }]; const result = toPriceImpact(splits); expect(result).toBeCloseTo(0.0075, 5); // Weighted average is (300 * 0.01) / 400 }); it('should return 0 for an empty array', () => { const splits = []; const result = toPriceImpact(splits); expect(result).toBe(0); }); }); describe('toSwapProtocol', () => { it.each` dex | protocol ${Dex.Minswap_v1} | ${Swap.Protocol.Minswap_v1} ${Dex.Minswap_v2} | ${Swap.Protocol.Minswap_v2} ${Dex.Wingriders_v1} | ${Swap.Protocol.Wingriders_v1} ${Dex.Wingriders_v2} | ${Swap.Protocol.Wingriders_v2} ${Dex.Vyfi_v1} | ${Swap.Protocol.Vyfi_v1} ${Dex.Sundaeswap_v1} | ${Swap.Protocol.Sundaeswap_v1} ${Dex.Sundaeswap_v3} | ${Swap.Protocol.Sundaeswap_v3} ${Dex.Splash_v1} | ${Swap.Protocol.Splash_v1} ${Dex.Muesliswap} | ${Swap.Protocol.Muesliswap} ${Dex.Snekfun} | ${Swap.Protocol.Snekfun} ${Dex.Spectrum_v1} | ${Swap.Protocol.Spectrum_v1} ${Dex.Chadswap} | ${Swap.Protocol.Chadswap} ${Dex.Cerra} | ${Swap.Protocol.Cerra} ${Dex.Genius} | ${Swap.Protocol.Genius} ${Dex.Unsupported} | ${Swap.Protocol.Unsupported} ${'new-protocol'} | ${Swap.Protocol.Unsupported} `('should map $dex to $protocol', ({ dex, protocol }) => { expect(toSwapProtocol(dex)).toBe(protocol); }); }); describe('fromSwapProtocol', () => { it.each` protocol | dex ${Swap.Protocol.Minswap_v1} | ${Dex.Minswap_v1} ${Swap.Protocol.Minswap_v2} | ${Dex.Minswap_v2} ${Swap.Protocol.Wingriders_v1} | ${Dex.Wingriders_v1} ${Swap.Protocol.Wingriders_v2} | ${Dex.Wingriders_v2} ${Swap.Protocol.Vyfi_v1} | ${Dex.Vyfi_v1} ${Swap.Protocol.Sundaeswap_v1} | ${Dex.Sundaeswap_v1} ${Swap.Protocol.Sundaeswap_v3} | ${Dex.Sundaeswap_v3} ${Swap.Protocol.Splash_v1} | ${Dex.Splash_v1} ${Swap.Protocol.Muesliswap} | ${Dex.Muesliswap} ${Swap.Protocol.Snekfun} | ${Dex.Snekfun} ${Swap.Protocol.Spectrum_v1} | ${Dex.Spectrum_v1} ${Swap.Protocol.Chadswap} | ${Dex.Chadswap} ${Swap.Protocol.Cerra} | ${Dex.Cerra} ${Swap.Protocol.Genius} | ${Dex.Genius} ${Swap.Protocol.Teddy_v1} | ${Dex.Unsupported} ${Swap.Protocol.Minswap_stable} | ${Dex.Unsupported} ${Swap.Protocol.Muesliswap_v1} | ${Dex.Unsupported} ${Swap.Protocol.Muesliswap_v2} | ${Dex.Unsupported} ${Swap.Protocol.Muesliswap_clp} | ${Dex.Unsupported} ${Swap.Protocol.Muesliswap_orderbook} | ${Dex.Unsupported} ${Swap.Protocol.Wingriders_stable} | ${Dex.Unsupported} ${Swap.Protocol.Splash_v4} | ${Dex.Splash_v1} ${Swap.Protocol.Splash_v5} | ${Dex.Splash_v1} ${Swap.Protocol.Splash_v6} | ${Dex.Splash_v1} ${Swap.Protocol.Snekfun} | ${Dex.Snekfun} ${Swap.Protocol.Unsupported} | ${Dex.Unsupported} ${'new-protocol'} | ${Dex.Unsupported} `('should map $protocol to $dex', ({ protocol, dex }) => { expect(fromSwapProtocol(protocol)).toBe(dex); }); }); describe('reverse', () => { it('should return the same price if reversed is false', () => { const result = reverse(false, 100); expect(result).toBe(100); }); it('should return the same price if price is 0', () => { const result = reverse(true, 0); expect(result).toBe(0); }); it('should return the same price if price is undefined', () => { const result = reverse(true, undefined); expect(result).toBe(undefined); }); it('should return the reciprocal of the price if reversed is true and price is valid', () => { const result = reverse(true, 100); expect(result).toBe(1 / 100); }); it('should handle edge cases for very small prices', () => { const result = reverse(true, 0.0001); expect(result).toBeCloseTo(10000, 5); }); it('should handle edge cases for very large prices', () => { const result = reverse(true, 1000000); expect(result).toBeCloseTo(0.000001, 6); }); }); //# sourceMappingURL=transformers.test.js.map