@hikaru-fi/swap-router
Version:
Package for calculating optimal path for executing swaps
78 lines (71 loc) • 2.28 kB
JavaScript
const BN = require("bn.js");
const { WeightedPool } = require("../poolMath/weightedPool/weightedPool");
const { SwapTypes } = require("../utils/types");
const { filterPathsForSwapType, filterPools } = require("./filtering");
const { producePaths } = require("./pathCalculation");
const { checkCacheForPath } = require("./pathesCache");
const { createSwapData, getBestSwap } = require("./swapCalculations");
const { toBN } = require("web3-utils");
/**
* @typedef PathCalculationOptions
* @property {Boolean} refresh
*/
/**
* @param {String} tokenIn
* @param {String} tokenOut
* @param {BN} swapAmount
* @param {String} swapType
* @param {import("./poolCache").PoolDictionary} pools
* @param {PathCalculationOptions} options
* @returns {FailReason|import("./swapCalculations").RouteInfo}
*/
function getSwap(
tokenIn,
tokenOut,
swapAmount,
swapType,
pools,
options
) {
options = options ? options : {};
/**
* @type {Record<String, WeightedPool>}
*/
const filteredPools = filterPools(pools, options.poolType);
if (Object.keys(filteredPools) == 0) return statusFailed('No pools of specified type exist');
let suitableSwaps = checkCacheForPath(tokenIn, tokenOut, swapType);
if (
options.refresh ||
suitableSwaps.length == 0
) {
const [directSwaps, hopSwaps] = producePaths(filteredPools, tokenIn, tokenOut);
if (directSwaps.length == 0 && hopSwaps.length == 0) return statusFailed('No suitable swap paths found for requested swap');
suitableSwaps = filterPathsForSwapType(filteredPools, directSwaps, hopSwaps, swapAmount, swapType);
}
if (suitableSwaps.length == 0) return statusFailed('Not enough liquidity in pools')
const {
path,
expectedResult
} = getBestSwap(filteredPools, suitableSwaps, swapAmount, swapType);
const swapData = createSwapData(filteredPools, path, swapAmount, swapType, expectedResult);
return swapData;
}
/**
* @typedef FailReason
* @property {String} swapType
* @property {String} reason
*/
/**
*
* @param {String} status
* @returns {FailReason}
*/
function statusFailed(status) {
return {
swapType: SwapTypes.None,
reason: status
}
}
module.exports = {
getSwap
}