@prism-hq/prism-ag
Version:
Prism Aggregator
349 lines (348 loc) • 17.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.findRoutes = exports.transitiveRoute = exports.splitRoute = exports.directRoute = exports.findDirectRoute = void 0;
const aldrin_1 = require("./aldrin");
const balansol_1 = require("./balansol");
const crema_1 = require("./crema");
const cropper_1 = require("./cropper");
const cykura_1 = require("./cykura");
const gooseFx_1 = require("./gooseFx");
const marcopolo_1 = require("./marcopolo");
// import { lifinityRoute } from "./lifinity";
// import { lifinityV2Route } from "./lifinityV2";
const marinade_1 = require("./marinade");
const mercurial_1 = require("./mercurial");
const openbook_1 = require("./openbook");
const orca_1 = require("./orca");
const penguin_1 = require("./penguin");
// import { phoenixRoute } from "./phoenix";
const raydium_1 = require("./raydium");
const raydiumClmm_1 = require("./raydiumClmm");
const saber_1 = require("./saber");
const saros_1 = require("./saros");
const sencha_1 = require("./sencha");
const serum_1 = require("./serum");
const step_1 = require("./step");
const stepn_1 = require("./stepn");
const symmetry_1 = require("./symmetry");
const whirlpools_1 = require("./whirlpools");
function findDirectRoute(fromCoin, toCoin, amount, option, liquidityData, liquidityProviders, settings) {
let route;
try {
switch (option.provider) {
case "serum":
route = (0, serum_1.serumRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "raydium":
route = (0, raydium_1.raydiumRoute)(fromCoin, toCoin, amount, option, liquidityData, liquidityProviders, settings);
break;
case "aldrin":
route = (0, aldrin_1.aldrinRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "saber":
route = (0, saber_1.saberRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "orca":
route = (0, orca_1.orcaRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
// case "lifinity":
// route = lifinityRoute(
// fromCoin, toCoin, amount, option, liquidityData, settings,
// );
// break;
// case "lifinityV2":
// route = lifinityV2Route(
// fromCoin, toCoin, amount, option, liquidityData, settings,
// );
// break;
case "symmetry":
route = (0, symmetry_1.symmetryRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "cropper":
route = (0, cropper_1.cropperRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "sencha":
route = (0, sencha_1.senchaRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "saros":
route = (0, saros_1.sarosRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "step":
route = (0, step_1.stepRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "penguin":
route = (0, penguin_1.penguinRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "mercurial":
route = (0, mercurial_1.mercurialRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "stepn":
route = (0, stepn_1.stepnRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "marinade":
route = (0, marinade_1.marinadeRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "crema":
route = (0, crema_1.cremaRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "cykura":
route = (0, cykura_1.cykuraRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "gooseFX":
route = (0, gooseFx_1.gooseFxRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "openbook":
route = (0, openbook_1.openbookRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "balansol":
route = (0, balansol_1.balansolRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "whirlpools":
route = (0, whirlpools_1.whirlPoolsRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "raydiumClmm":
route = (0, raydiumClmm_1.raydiumClmmRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
case "marcopolo":
route = (0, marcopolo_1.marcopoloRoute)(fromCoin, toCoin, amount, option, liquidityData, settings);
break;
// case "phoenix":
// route = phoenixRoute(
// fromCoin, toCoin, amount, option, liquidityData, settings,
// );
// break;
default:
break;
}
}
catch (_a) { }
if (!route || !route.amountOut)
route = { amountOut: 0 };
return route;
}
exports.findDirectRoute = findDirectRoute;
function directRoute(route) {
return Object.assign(Object.assign({ type: "direct" }, route), { split: [1], providers: [route.provider], priceDisplay: route.amountOut / route.amountIn });
}
exports.directRoute = directRoute;
function splitRoute(route1, route2, split) {
return {
type: "split",
from: route1.from,
amountIn: route1.amountIn + route2.amountIn,
to: route1.to,
amountOut: route1.amountOut + route2.amountOut,
amountWithFees: route1.amountWithFees + route2.amountWithFees,
minimumReceived: route1.minimumReceived + route2.minimumReceived,
providers: [route1.provider, route2.provider],
fees: { [route1.to]: route1.fees[route1.to] + route2.fees[route1.to] },
priceImpact: Math.max(route1.priceImpact, route1.priceImpact),
priceDisplay: (route1.amountOut + route2.amountOut) / (route1.amountIn + route2.amountIn),
split: [split / 20, 1 - split / 20],
routeData: {
route1: route1,
route2: route2,
fromCoin: route1.routeData.fromCoin,
toCoin: route1.routeData.toCoin,
}
};
}
exports.splitRoute = splitRoute;
function transitiveRoute(routeFrom, routeTo) {
return {
type: "transitive",
from: routeFrom.from,
amountIn: routeFrom.amountIn,
mid: routeFrom.to,
amountMid: routeFrom.amountOut,
to: routeTo.to,
amountOut: routeTo.amountOut,
amountWithFees: routeTo.amountWithFees,
minimumReceived: routeTo.minimumReceived,
providers: [routeFrom.provider, routeTo.provider],
fees: Object.assign(Object.assign({}, routeFrom.fees), routeTo.fees),
priceImpact: Math.max(routeFrom.priceImpact, routeTo.priceImpact),
priceDisplay: routeTo.amountOut / routeFrom.amountIn,
split: [1, 1],
routeData: {
route1: routeFrom,
route2: routeTo,
fromCoin: routeFrom.routeData.fromCoin,
midCoin: routeFrom.routeData.toCoin,
toCoin: routeTo.routeData.toCoin,
}
};
}
exports.transitiveRoute = transitiveRoute;
function findRoutes(fromCoin, toCoin, amount, liquidityInfos, liquidityProviders, settings) {
if (!liquidityInfos)
return [];
amount = parseFloat(amount.toString());
let { routes, liquidityData } = liquidityInfos;
let allRoutes = [];
for (let [middleMint, data] of Object.entries(routes)) {
if (middleMint == "direct") {
let directRoutes = [];
//@ts-ignore
data.direct.forEach((option) => {
let directRoute = findDirectRoute(fromCoin, toCoin, amount, option, liquidityData, liquidityProviders, settings);
if (directRoute.amountOut > 0)
directRoutes.push(directRoute);
});
for (let i = 0; i < directRoutes.length; i++)
allRoutes.push(directRoute(directRoutes[i]));
let splits = {};
//@ts-ignore
data.direct.forEach((option) => {
for (let div = 1; div <= 19; div++) {
(splits[div] || (splits[div] = [])).push(findDirectRoute(fromCoin, toCoin, amount * div / 20, option, liquidityData, liquidityProviders, settings));
}
});
let splitRoutes = [];
for (let i = 19; i >= 10; i--) {
if (!splits[i] || !splits[20 - i])
continue;
for (let k = 1; k < splits[i].length; k++) {
if (splits[i][k].amountOut > splits[i][0].amountOut) {
let temp = splits[i][0];
splits[i][0] = splits[i][k];
splits[i][k] = temp;
}
}
let temp;
for (let k = 1; k < splits[20 - i].length; k++) {
if (splits[20 - i][k].amountOut > splits[20 - i][0].amountOut) {
temp = splits[i][0];
splits[20 - i][0] = splits[20 - i][k];
splits[20 - i][k] = temp;
continue;
}
if (splits[20 - i][k].amountOut > splits[20 - i][1].amountOut) {
temp = splits[20 - i][1];
splits[20 - i][1] = splits[20 - i][k];
splits[20 - i][k] = temp;
continue;
}
}
// splits[i].sort((a: any, b: any) => { return b.amountOut - a.amountOut });
// splits[20 - i].sort((a: any, b: any) => { return b.amountOut - a.amountOut });
for (let f = 0; f < Math.min(1, splits[i].length); f++)
for (let s = 0; s < Math.min(2, splits[20 - i].length); s++) {
if (splits[i][f].amountOut == 0 || splits[20 - i][s].amountOut == 0)
continue;
let pA = splits[i][f].provider;
let pB = splits[20 - i][s].provider;
if ((pA == pB) ||
(pA == "raydium" && pB == "serum") ||
(pB == "raydium" && pA == "serum") ||
(pA == "raydium" && pB == "gooseFX") ||
(pB == "raydium" && pA == "gooseFX") ||
(pA == "raydium" && pB == "balansol") ||
(pB == "raydium" && pA == "balansol") ||
(pA == "raydium" && pB == "openbook") ||
(pB == "raydium" && pA == "openbook") ||
(pA == "raydium" && pB == "cropper") ||
(pB == "raydium" && pA == "cropper") ||
(pA == "raydium" && pB == "marcopolo") ||
(pB == "raydium" && pA == "marcopolo"))
continue;
if (pA == "symmetry" || pB == "symmetry")
continue;
splitRoutes.push(splitRoute(splits[i][f], splits[20 - i][s], i));
}
}
splitRoutes.sort((a, b) => { return b.amountOut - a.amountOut; });
let pairs = {};
for (let i = 0; i < splitRoutes.length; i++) {
if (pairs[splitRoutes[i].providers[0] + splitRoutes[i].providers[1]])
continue;
if (pairs[splitRoutes[i].providers[1] + splitRoutes[i].providers[0]])
continue;
pairs[splitRoutes[i].providers[0] + splitRoutes[i].providers[1]] = true;
pairs[splitRoutes[i].providers[1] + splitRoutes[i].providers[0]] = true;
allRoutes.push(splitRoutes[i]);
}
continue;
}
//@ts-ignore
let { coin, from, to } = data;
let fromRoutes = [];
from.forEach((option) => fromRoutes.push(findDirectRoute(fromCoin, coin, amount, option, liquidityData, liquidityProviders, settings)));
fromRoutes.sort((a, b) => b.amountOut - a.amountOut);
// for(let k = 1; k<fromRoutes.length; k++){
// if(fromRoutes[k].amountOut > fromRoutes[0].amountOut){
// let temp = fromRoutes[0];
// fromRoutes[0] = fromRoutes[k];
// fromRoutes[k] = temp;
// }
// }
let found = 0;
let i = -1;
while (found < 4 && i + 1 < fromRoutes.length) {
i++;
if (!(fromRoutes[i].amountOut > 0)) {
continue;
}
let toRoutes = [];
to.forEach((option) => toRoutes.push(findDirectRoute(coin, toCoin, fromRoutes[i].amountOut, option, liquidityData, liquidityProviders, settings)));
toRoutes.sort((a, b) => { return b.amountOut - a.amountOut; });
// for(let k=1; k<toRoutes.length; k++){
// if(toRoutes[k].amountOut > toRoutes[0].amountOut){
// let temp = toRoutes[0];
// toRoutes[0] = toRoutes[k];
// toRoutes[k] = temp;
// }
// }
let j = -1;
while (j + 1 < toRoutes.length) {
j++;
if (toRoutes[j].amountOut > 0) {
if (fromRoutes[i].provider == "symmetry" || toRoutes[j].provider == "symmetry")
continue;
if (fromRoutes[i].provider == 'gooseFX' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "gooseFX")
continue;
if (fromRoutes[i].provider == 'openbook' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "openbook")
continue;
if (fromRoutes[i].provider == 'balansol' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "balansol")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "cropper")
continue;
if (fromRoutes[i].provider == 'cropper' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "saros")
continue;
if (fromRoutes[i].provider == 'saros' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "stepn")
continue;
if (fromRoutes[i].provider == 'stepn' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium CLMM' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "raydium CLMM")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "marcopolo")
continue;
if (fromRoutes[i].provider == 'marcopolo' && toRoutes[j].provider == "raydium")
continue;
if (fromRoutes[i].provider == 'raydium' && toRoutes[j].provider == "raydium") {
if (fromRoutes[i].routeData.poolInfo.ammId == toRoutes[j].routeData.poolInfo.ammId)
continue;
}
found++;
allRoutes.push(transitiveRoute(fromRoutes[i], toRoutes[j]));
break;
}
}
}
}
allRoutes.sort((a, b) => { return b.amountOut - a.amountOut; });
return allRoutes;
}
exports.findRoutes = findRoutes;