@curvefi/api 2.47.5 → 2.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -150,6 +150,7 @@ export interface IRouteStep {
150
150
  baseToken: string;
151
151
  secondBasePool: string;
152
152
  secondBaseToken: string;
153
+ tvl: number;
153
154
  }
154
155
  export type IRoute = IRouteStep[];
155
156
  export interface IRouteTvl {
@@ -489,7 +489,7 @@ export var _getAmplificationCoefficientsFromApi = function () { return __awaiter
489
489
  extendedPoolData = allTypesExtendedPoolData_1[_i];
490
490
  for (_a = 0, _b = extendedPoolData.poolData; _a < _b.length; _a++) {
491
491
  pool = _b[_a];
492
- amplificationCoefficientDict[pool.address] = Number(pool.amplificationCoefficient);
492
+ amplificationCoefficientDict[pool.address.toLowerCase()] = Number(pool.amplificationCoefficient);
493
493
  }
494
494
  }
495
495
  return [2 /*return*/, amplificationCoefficientDict];
package/lib/router.js CHANGED
@@ -63,59 +63,16 @@ import { getPool } from "./pools/index.js";
63
63
  import { _getAmplificationCoefficientsFromApi } from "./pools/utils.js";
64
64
  var MAX_STEPS = 5;
65
65
  var ROUTE_LENGTH = (MAX_STEPS * 2) + 1;
66
- // 4 --> 6, 5 --> 7 not allowed
67
- // 4 --> 7, 5 --> 6 allowed
68
- var _handleSwapType = function (swapType) {
69
- if (swapType === 6)
70
- return "4";
71
- if (swapType === 7)
72
- return "5";
73
- return swapType.toString();
74
- };
75
- var _getNewRoute = function (routeTvl, poolId, swapAddress, inputCoinAddress, outputCoinAddress, swapParams, // i, j, swap_type, pool_type, n_coins
76
- poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl) {
77
- var routePoolIdsPlusSwapType = routeTvl.route.map(function (s) { return s.poolId + "+" + _handleSwapType(s.swapParams[2]); });
78
- // Steps <= MAX_STEPS
79
- if (routePoolIdsPlusSwapType.length >= MAX_STEPS)
80
- return { route: [], minTvl: Infinity, totalTvl: 0 };
81
- // Exclude such cases as cvxeth -> tricrypto2 -> tricrypto2 -> susd
82
- if (routePoolIdsPlusSwapType.includes(poolId + "+" + _handleSwapType(swapParams[2])))
83
- return { route: [], minTvl: Infinity, totalTvl: 0 };
84
- return {
85
- route: __spreadArray(__spreadArray([], routeTvl.route, true), [
86
- { poolId: poolId, swapAddress: swapAddress, inputCoinAddress: inputCoinAddress, outputCoinAddress: outputCoinAddress, swapParams: swapParams, poolAddress: poolAddress, basePool: basePool, baseToken: baseToken, secondBasePool: secondBasePool, secondBaseToken: secondBaseToken },
87
- ], false),
88
- minTvl: Math.min(tvl, routeTvl.minTvl),
89
- totalTvl: routeTvl.totalTvl + tvl,
90
- };
91
- };
92
- var MAX_ROUTES_FOR_ONE_COIN = 3;
93
- var _filterRoutes = function (routes, inputCoinAddress, sortFn) {
94
- return routes
95
- .filter(function (r) { return r.route.length > 0; })
96
- .filter(function (r) { return r.route[0].inputCoinAddress === inputCoinAddress; }) // Truncated routes
97
- .filter(function (r, i, _routes) {
66
+ var GRAPH_MAX_EDGES = 3;
67
+ var MAX_ROUTES_FOR_ONE_COIN = 5;
68
+ var _removeDuplications = function (routes) {
69
+ return routes.filter(function (r, i, _routes) {
98
70
  var routesByPoolIds = _routes.map(function (r) { return r.route.map(function (s) { return s.poolId; }).toString(); });
99
71
  return routesByPoolIds.indexOf(r.route.map(function (s) { return s.poolId; }).toString()) === i;
100
- }) // Route duplications
101
- .sort(sortFn).slice(0, MAX_ROUTES_FOR_ONE_COIN);
72
+ });
102
73
  };
103
74
  var _sortByTvl = function (a, b) { return b.minTvl - a.minTvl || b.totalTvl - a.totalTvl || a.route.length - b.route.length; };
104
75
  var _sortByLength = function (a, b) { return a.route.length - b.route.length || b.minTvl - a.minTvl || b.totalTvl - a.totalTvl; };
105
- var _updateRoutes = function (inputCoinAddress, routesByTvl, routesByLength, poolId, swapAddress, inCoin, outCoin, swapParams, // i, j, swap_type, pool_type, n_coins
106
- poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl) {
107
- var _a, _b;
108
- var newRoutesByTvl = routesByTvl[inCoin].map(function (route) {
109
- return _getNewRoute(route, poolId, swapAddress, inCoin, outCoin, swapParams, poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl);
110
- });
111
- var newRoutesByLength = routesByLength[inCoin].map(function (route) {
112
- return _getNewRoute(route, poolId, swapAddress, inCoin, outCoin, swapParams, poolAddress, basePool, baseToken, secondBasePool, secondBaseToken, tvl);
113
- });
114
- routesByTvl[outCoin] = __spreadArray(__spreadArray([], ((_a = routesByTvl[outCoin]) !== null && _a !== void 0 ? _a : []), true), newRoutesByTvl, true);
115
- routesByTvl[outCoin] = _filterRoutes(routesByTvl[outCoin], inputCoinAddress, _sortByTvl);
116
- routesByLength[outCoin] = __spreadArray(__spreadArray([], ((_b = routesByLength[outCoin]) !== null && _b !== void 0 ? _b : []), true), newRoutesByLength, true);
117
- routesByLength[outCoin] = _filterRoutes(routesByLength[outCoin], inputCoinAddress, _sortByLength);
118
- };
119
76
  var _getTVL = memoize(function (poolId) { return __awaiter(void 0, void 0, void 0, function () { var _a; return __generator(this, function (_b) {
120
77
  switch (_b.label) {
121
78
  case 0:
@@ -127,6 +84,15 @@ var _getTVL = memoize(function (poolId) { return __awaiter(void 0, void 0, void
127
84
  promise: true,
128
85
  maxAge: 5 * 60 * 1000, // 5m
129
86
  });
87
+ // 4 --> 6, 5 --> 7 not allowed
88
+ // 4 --> 7, 5 --> 6 allowed
89
+ var _handleSwapType = function (swapType) {
90
+ if (swapType === 6)
91
+ return "4";
92
+ if (swapType === 7)
93
+ return "5";
94
+ return swapType.toString();
95
+ };
130
96
  var SNX = {
131
97
  1: {
132
98
  swap: "0xC011a73ee8576Fb46F5E1c5751cA3B9Fe0af2a6F".toLowerCase(),
@@ -147,226 +113,384 @@ var SNX = {
147
113
  ].map(function (a) { return a.toLowerCase(); }),
148
114
  },
149
115
  };
150
- // Inspired by Dijkstra's algorithm
151
- var _findAllRoutes = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
152
- var ALL_POOLS, amplificationCoefficientDict, curCoins, nextCoins, routesByTvl, routesByLength, step, _i, curCoins_1, inCoin, outCoin, _a, _b, outCoin, outCoin, outCoin, _c, _d, outCoin, _e, ALL_POOLS_1, _f, poolId, poolData, wrapped_coin_addresses, underlying_coin_addresses, pool_address, token_address, is_aave_like_lending, pool_type, tvl_multiplier, base_pool, base_pool_address, base_token_address, second_base_pool, second_base_pool_address, second_base_token_address, meta_coin_addresses, swap_address, inCoinIndexes, tvl, j, outputCoinIdx, j, outputCoinIdx, swapType, swapType, j, outputCoinIdx, j, outputCoinIdx, hasEth, swapType, routes;
153
- var _h, _j;
154
- var _k, _l, _m, _o, _p, _q, _r;
155
- return __generator(this, function (_s) {
156
- switch (_s.label) {
116
+ var _buildRouteGraph = memoize(function () { return __awaiter(void 0, void 0, void 0, function () {
117
+ var routerGraph, _i, _a, outCoin, _b, _c, inCoin, _d, _e, outCoin, ALL_POOLS, amplificationCoefficientDict, _f, ALL_POOLS_1, _h, poolId, poolData, wrappedCoinAddresses, underlyingCoinAddresses, poolAddress, tokenAddress, isAaveLikeLending, poolType, tvlMultiplier, basePool, basePoolAddress, baseTokenAddress, secondBasePool, secondBasePoolAddress, secondBaseTokenAddress, metaCoinAddresses, swapAddress, tvl, coins, k, l, i, j, swapType, coins, k, l, i, j, swapType, i, j, i, j, hasEth, swapType;
118
+ var _j, _k, _l;
119
+ return __generator(this, function (_m) {
120
+ switch (_m.label) {
157
121
  case 0:
158
- inputCoinAddress = inputCoinAddress.toLowerCase();
159
- outputCoinAddress = outputCoinAddress.toLowerCase();
160
- ALL_POOLS = Object.entries(curve.getPoolsData()).filter(function (_a) {
161
- var id = _a[0], _ = _a[1];
162
- return id !== "crveth";
163
- });
164
- return [4 /*yield*/, _getAmplificationCoefficientsFromApi()];
165
- case 1:
166
- amplificationCoefficientDict = _s.sent();
167
- curCoins = [inputCoinAddress];
168
- nextCoins = new Set();
169
- routesByTvl = (_h = {},
170
- _h[inputCoinAddress] = [{ route: [], minTvl: Infinity, totalTvl: 0 }],
171
- _h);
172
- routesByLength = (_j = {},
173
- _j[inputCoinAddress] = [{ route: [], minTvl: Infinity, totalTvl: 0 }],
174
- _j);
175
- step = 0;
176
- _s.label = 2;
177
- case 2:
178
- if (!(step < MAX_STEPS)) return [3 /*break*/, 10];
179
- _i = 0, curCoins_1 = curCoins;
180
- _s.label = 3;
181
- case 3:
182
- if (!(_i < curCoins_1.length)) return [3 /*break*/, 8];
183
- inCoin = curCoins_1[_i];
122
+ routerGraph = {};
184
123
  // ETH <-> WETH (exclude Celo)
185
- if (curve.chainId !== 42220 && [curve.constants.NATIVE_TOKEN.address, curve.constants.NATIVE_TOKEN.wrappedAddress].includes(inCoin)) {
186
- outCoin = inCoin === curve.constants.NATIVE_TOKEN.address ? curve.constants.NATIVE_TOKEN.wrappedAddress : curve.constants.NATIVE_TOKEN.address;
187
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "WETH", curve.constants.NATIVE_TOKEN.wrappedAddress, inCoin, outCoin, [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
188
- nextCoins.add(outCoin);
124
+ if (curve.chainId !== 42220) {
125
+ routerGraph[curve.constants.NATIVE_TOKEN.address] = {};
126
+ routerGraph[curve.constants.NATIVE_TOKEN.address][curve.constants.NATIVE_TOKEN.wrappedAddress] = [{
127
+ poolId: "WETH wrapper",
128
+ swapAddress: curve.constants.NATIVE_TOKEN.wrappedAddress,
129
+ inputCoinAddress: curve.constants.NATIVE_TOKEN.address,
130
+ outputCoinAddress: curve.constants.NATIVE_TOKEN.wrappedAddress,
131
+ swapParams: [0, 0, 8, 0, 0],
132
+ poolAddress: curve.constants.ZERO_ADDRESS,
133
+ basePool: curve.constants.ZERO_ADDRESS,
134
+ baseToken: curve.constants.ZERO_ADDRESS,
135
+ secondBasePool: curve.constants.ZERO_ADDRESS,
136
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
137
+ tvl: Infinity,
138
+ }];
139
+ routerGraph[curve.constants.NATIVE_TOKEN.wrappedAddress] = {};
140
+ routerGraph[curve.constants.NATIVE_TOKEN.wrappedAddress][curve.constants.NATIVE_TOKEN.address] = [{
141
+ poolId: "WETH wrapper",
142
+ swapAddress: curve.constants.NATIVE_TOKEN.wrappedAddress,
143
+ inputCoinAddress: curve.constants.NATIVE_TOKEN.wrappedAddress,
144
+ outputCoinAddress: curve.constants.NATIVE_TOKEN.address,
145
+ swapParams: [0, 0, 8, 0, 0],
146
+ poolAddress: curve.constants.ZERO_ADDRESS,
147
+ basePool: curve.constants.ZERO_ADDRESS,
148
+ baseToken: curve.constants.ZERO_ADDRESS,
149
+ secondBasePool: curve.constants.ZERO_ADDRESS,
150
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
151
+ tvl: Infinity,
152
+ }];
189
153
  }
190
154
  // ETH -> stETH, ETH -> frxETH, ETH -> wBETH (Ethereum only)
191
- if (curve.chainId == 1 && inCoin === curve.constants.NATIVE_TOKEN.address) {
192
- for (_a = 0, _b = ["stETH", "frxETH", "wBETH"]; _a < _b.length; _a++) {
193
- outCoin = _b[_a];
194
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, outCoin === "frxETH" ? "frxETH minter" : outCoin, outCoin === "frxETH" ? "0xbAFA44EFE7901E04E39Dad13167D089C559c1138".toLowerCase() : curve.constants.COINS[outCoin.toLowerCase()], inCoin, curve.constants.COINS[outCoin.toLowerCase()], [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
195
- nextCoins.add(curve.constants.COINS[outCoin.toLowerCase()]);
155
+ if (curve.chainId == 1) {
156
+ for (_i = 0, _a = ["stETH", "frxETH", "wBETH"]; _i < _a.length; _i++) {
157
+ outCoin = _a[_i];
158
+ routerGraph[curve.constants.NATIVE_TOKEN.address][curve.constants.COINS[outCoin.toLowerCase()]] = [{
159
+ poolId: outCoin + " minter",
160
+ swapAddress: outCoin === "frxETH" ? "0xbAFA44EFE7901E04E39Dad13167D089C559c1138".toLowerCase() : curve.constants.COINS[outCoin.toLowerCase()],
161
+ inputCoinAddress: curve.constants.NATIVE_TOKEN.address,
162
+ outputCoinAddress: curve.constants.COINS[outCoin.toLowerCase()],
163
+ swapParams: [0, 0, 8, 0, 0],
164
+ poolAddress: curve.constants.ZERO_ADDRESS,
165
+ basePool: curve.constants.ZERO_ADDRESS,
166
+ baseToken: curve.constants.ZERO_ADDRESS,
167
+ secondBasePool: curve.constants.ZERO_ADDRESS,
168
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
169
+ tvl: Infinity,
170
+ }];
196
171
  }
197
172
  }
198
173
  // stETH <-> wstETH (Ethereum only)
199
- if (curve.chainId === 1 && [curve.constants.COINS.steth, curve.constants.COINS.wsteth].includes(inCoin)) {
200
- outCoin = inCoin === curve.constants.COINS.steth ? curve.constants.COINS.wsteth : curve.constants.COINS.steth;
201
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "wstETH", curve.constants.COINS["wsteth"], inCoin, outCoin, [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
202
- nextCoins.add(outCoin);
174
+ if (curve.chainId === 1) {
175
+ routerGraph[curve.constants.COINS.steth] = {};
176
+ routerGraph[curve.constants.COINS.steth][curve.constants.COINS.wsteth] = [{
177
+ poolId: "wstETH wrapper",
178
+ swapAddress: curve.constants.COINS.wsteth,
179
+ inputCoinAddress: curve.constants.COINS.steth,
180
+ outputCoinAddress: curve.constants.COINS.wsteth,
181
+ swapParams: [0, 0, 8, 0, 0],
182
+ poolAddress: curve.constants.ZERO_ADDRESS,
183
+ basePool: curve.constants.ZERO_ADDRESS,
184
+ baseToken: curve.constants.ZERO_ADDRESS,
185
+ secondBasePool: curve.constants.ZERO_ADDRESS,
186
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
187
+ tvl: Infinity,
188
+ }];
189
+ routerGraph[curve.constants.COINS.wsteth] = {};
190
+ routerGraph[curve.constants.COINS.wsteth][curve.constants.COINS.steth] = [{
191
+ poolId: "wstETH wrapper",
192
+ swapAddress: curve.constants.COINS.wsteth,
193
+ inputCoinAddress: curve.constants.COINS.wsteth,
194
+ outputCoinAddress: curve.constants.COINS.steth,
195
+ swapParams: [0, 0, 8, 0, 0],
196
+ poolAddress: curve.constants.ZERO_ADDRESS,
197
+ basePool: curve.constants.ZERO_ADDRESS,
198
+ baseToken: curve.constants.ZERO_ADDRESS,
199
+ secondBasePool: curve.constants.ZERO_ADDRESS,
200
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
201
+ tvl: Infinity,
202
+ }];
203
203
  }
204
204
  // frxETH <-> sfrxETH (Ethereum only)
205
- if (curve.chainId === 1 && [curve.constants.COINS.frxeth, curve.constants.COINS.sfrxeth].includes(inCoin)) {
206
- outCoin = inCoin === curve.constants.COINS.frxeth ? curve.constants.COINS.sfrxeth : curve.constants.COINS.frxeth;
207
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "sfrxETH", curve.constants.COINS["sfrxeth"], inCoin, outCoin, [0, 0, 8, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
208
- nextCoins.add(outCoin);
205
+ if (curve.chainId === 1) {
206
+ routerGraph[curve.constants.COINS.frxeth] = {};
207
+ routerGraph[curve.constants.COINS.frxeth][curve.constants.COINS.sfrxeth] = [{
208
+ poolId: "sfrxETH wrapper",
209
+ swapAddress: curve.constants.COINS.sfrxeth,
210
+ inputCoinAddress: curve.constants.COINS.frxeth,
211
+ outputCoinAddress: curve.constants.COINS.sfrxeth,
212
+ swapParams: [0, 0, 8, 0, 0],
213
+ poolAddress: curve.constants.ZERO_ADDRESS,
214
+ basePool: curve.constants.ZERO_ADDRESS,
215
+ baseToken: curve.constants.ZERO_ADDRESS,
216
+ secondBasePool: curve.constants.ZERO_ADDRESS,
217
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
218
+ tvl: Infinity,
219
+ }];
220
+ routerGraph[curve.constants.COINS.sfrxeth] = {};
221
+ routerGraph[curve.constants.COINS.sfrxeth][curve.constants.COINS.frxeth] = [{
222
+ poolId: "sfrxETH wrapper",
223
+ swapAddress: curve.constants.COINS.sfrxeth,
224
+ inputCoinAddress: curve.constants.COINS.sfrxeth,
225
+ outputCoinAddress: curve.constants.COINS.frxeth,
226
+ swapParams: [0, 0, 8, 0, 0],
227
+ poolAddress: curve.constants.ZERO_ADDRESS,
228
+ basePool: curve.constants.ZERO_ADDRESS,
229
+ baseToken: curve.constants.ZERO_ADDRESS,
230
+ secondBasePool: curve.constants.ZERO_ADDRESS,
231
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
232
+ tvl: Infinity,
233
+ }];
209
234
  }
210
235
  // SNX swaps
211
- // @ts-ignore
212
- if (((_l = (_k = SNX[curve.chainId]) === null || _k === void 0 ? void 0 : _k.coins) !== null && _l !== void 0 ? _l : []).includes(inCoin)) {
236
+ if (curve.chainId in SNX) {
213
237
  // @ts-ignore
214
- for (_c = 0, _d = SNX[curve.chainId].coins; _c < _d.length; _c++) {
215
- outCoin = _d[_c];
216
- if (inCoin === outCoin)
217
- continue;
218
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, "SNX exchange",
238
+ for (_b = 0, _c = SNX[curve.chainId].coins; _b < _c.length; _b++) {
239
+ inCoin = _c[_b];
219
240
  // @ts-ignore
220
- SNX[curve.chainId].swap, inCoin, outCoin, [0, 0, 9, 0, 0], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, Infinity);
221
- nextCoins.add(outCoin);
241
+ for (_d = 0, _e = SNX[curve.chainId].coins; _d < _e.length; _d++) {
242
+ outCoin = _e[_d];
243
+ if (inCoin === outCoin)
244
+ continue;
245
+ if (!routerGraph[inCoin])
246
+ routerGraph[inCoin] = {};
247
+ routerGraph[inCoin][outCoin] = [{
248
+ poolId: "SNX exchanger",
249
+ // @ts-ignore
250
+ swapAddress: SNX[curve.chainId].swap,
251
+ inputCoinAddress: inCoin,
252
+ outputCoinAddress: outCoin,
253
+ swapParams: [0, 0, 9, 0, 0],
254
+ poolAddress: curve.constants.ZERO_ADDRESS,
255
+ basePool: curve.constants.ZERO_ADDRESS,
256
+ baseToken: curve.constants.ZERO_ADDRESS,
257
+ secondBasePool: curve.constants.ZERO_ADDRESS,
258
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
259
+ tvl: Infinity,
260
+ }];
261
+ }
222
262
  }
223
263
  }
224
- _e = 0, ALL_POOLS_1 = ALL_POOLS;
225
- _s.label = 4;
226
- case 4:
227
- if (!(_e < ALL_POOLS_1.length)) return [3 /*break*/, 7];
228
- _f = ALL_POOLS_1[_e], poolId = _f[0], poolData = _f[1];
229
- wrapped_coin_addresses = poolData.wrapped_coin_addresses.map(function (a) { return a.toLowerCase(); });
230
- underlying_coin_addresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
231
- pool_address = poolData.swap_address.toLowerCase();
232
- token_address = poolData.token_address.toLowerCase();
233
- is_aave_like_lending = poolData.is_lending && wrapped_coin_addresses.length === 3 && !poolData.deposit_address;
234
- pool_type = poolData.is_llamma ? 4 : poolData.is_crypto ? Math.min(poolData.wrapped_coins.length, 3) : 1;
235
- tvl_multiplier = poolData.is_crypto ? 1 : ((_m = amplificationCoefficientDict[poolData.swap_address]) !== null && _m !== void 0 ? _m : 1);
236
- base_pool = poolData.is_meta ? __assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA)[poolData.base_pool] : null;
237
- base_pool_address = base_pool ? base_pool.swap_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
238
- base_token_address = base_pool ? base_pool.token_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
239
- second_base_pool = base_pool && base_pool.base_pool ? __assign(__assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA), curve.constants.CRVUSD_FACTORY_POOLS_DATA)[base_pool.base_pool] : null;
240
- second_base_pool_address = second_base_pool ? second_base_pool.swap_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
264
+ ALL_POOLS = Object.entries(curve.getPoolsData()).filter(function (_a) {
265
+ var id = _a[0], _ = _a[1];
266
+ return id !== "crveth";
267
+ });
268
+ return [4 /*yield*/, _getAmplificationCoefficientsFromApi()];
269
+ case 1:
270
+ amplificationCoefficientDict = _m.sent();
271
+ _f = 0, ALL_POOLS_1 = ALL_POOLS;
272
+ _m.label = 2;
273
+ case 2:
274
+ if (!(_f < ALL_POOLS_1.length)) return [3 /*break*/, 5];
275
+ _h = ALL_POOLS_1[_f], poolId = _h[0], poolData = _h[1];
276
+ wrappedCoinAddresses = poolData.wrapped_coin_addresses.map(function (a) { return a.toLowerCase(); });
277
+ underlyingCoinAddresses = poolData.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); });
278
+ poolAddress = poolData.swap_address.toLowerCase();
279
+ tokenAddress = poolData.token_address.toLowerCase();
280
+ isAaveLikeLending = poolData.is_lending && wrappedCoinAddresses.length === 3 && !poolData.deposit_address;
281
+ poolType = poolData.is_llamma ? 4 : poolData.is_crypto ? Math.min(poolData.wrapped_coins.length, 3) : 1;
282
+ tvlMultiplier = poolData.is_crypto ? 1 : ((_j = amplificationCoefficientDict[poolData.swap_address]) !== null && _j !== void 0 ? _j : 1);
283
+ basePool = poolData.is_meta ? __assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA)[poolData.base_pool] : null;
284
+ basePoolAddress = basePool ? basePool.swap_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
285
+ baseTokenAddress = basePool ? basePool.token_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
286
+ secondBasePool = basePool && basePool.base_pool ? __assign(__assign(__assign({}, curve.constants.POOLS_DATA), curve.constants.FACTORY_POOLS_DATA), curve.constants.CRVUSD_FACTORY_POOLS_DATA)[basePool.base_pool] : null;
287
+ secondBasePoolAddress = secondBasePool ? secondBasePool.swap_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
241
288
  // for double meta underlying (crv/tricrypto, wmatic/tricrypto)
242
- if (base_pool && second_base_pool_address !== curve.constants.ZERO_ADDRESS)
243
- base_token_address = (_o = base_pool.deposit_address) === null || _o === void 0 ? void 0 : _o.toLowerCase();
244
- second_base_token_address = second_base_pool ? second_base_pool.token_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
245
- meta_coin_addresses = base_pool ? base_pool.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); }) : [];
246
- swap_address = poolData.is_fake ? (_p = poolData.deposit_address) === null || _p === void 0 ? void 0 : _p.toLowerCase() : pool_address;
247
- inCoinIndexes = {
248
- wrapped_coin: wrapped_coin_addresses.indexOf(inCoin),
249
- underlying_coin: underlying_coin_addresses.indexOf(inCoin),
250
- meta_coin: meta_coin_addresses ? meta_coin_addresses.indexOf(inCoin) : -1,
251
- };
252
- // Skip pools which don't contain inCoin
253
- if (inCoinIndexes.wrapped_coin === -1 && inCoinIndexes.underlying_coin === -1 && inCoinIndexes.meta_coin === -1 && inCoin !== token_address)
254
- return [3 /*break*/, 6];
289
+ if (basePool && secondBasePoolAddress !== curve.constants.ZERO_ADDRESS)
290
+ baseTokenAddress = (_k = basePool.deposit_address) === null || _k === void 0 ? void 0 : _k.toLowerCase();
291
+ secondBaseTokenAddress = secondBasePool ? secondBasePool.token_address.toLowerCase() : curve.constants.ZERO_ADDRESS;
292
+ metaCoinAddresses = basePool ? basePool.underlying_coin_addresses.map(function (a) { return a.toLowerCase(); }) : [];
293
+ swapAddress = poolData.is_fake ? (_l = poolData.deposit_address) === null || _l === void 0 ? void 0 : _l.toLowerCase() : poolAddress;
255
294
  return [4 /*yield*/, _getTVL(poolId)];
256
- case 5:
257
- tvl = (_s.sent()) * tvl_multiplier;
295
+ case 3:
296
+ tvl = (_m.sent()) * tvlMultiplier;
258
297
  // Skip empty pools
259
298
  if (curve.chainId === 1 && tvl < 1000)
260
- return [3 /*break*/, 6];
299
+ return [3 /*break*/, 4];
261
300
  if (curve.chainId !== 1 && tvl < 100)
262
- return [3 /*break*/, 6];
263
- // LP -> wrapped coin "swaps" (actually remove_liquidity_one_coin)
264
- if (!poolData.is_fake && !poolData.is_llamma && wrapped_coin_addresses.length < 6 && inCoin === token_address) {
265
- for (j = 0; j < wrapped_coin_addresses.length; j++) {
266
- // Looking for outputCoinAddress only on the final step
267
- if (step === MAX_STEPS - 1 && wrapped_coin_addresses[j] !== outputCoinAddress)
268
- continue;
269
- outputCoinIdx = wrapped_coin_addresses.indexOf(outputCoinAddress);
270
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
271
- continue;
272
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, wrapped_coin_addresses[j], [0, j, 6, pool_type, wrapped_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
273
- nextCoins.add(wrapped_coin_addresses[j]);
301
+ return [3 /*break*/, 4];
302
+ // Wrapped coin <-> LP "swaps" (actually add_liquidity/remove_liquidity_one_coin)
303
+ if (!poolData.is_fake && !poolData.is_llamma && wrappedCoinAddresses.length < 6) {
304
+ coins = __spreadArray([tokenAddress], wrappedCoinAddresses, true);
305
+ for (k = 0; k < coins.length; k++) {
306
+ for (l = 0; l < coins.length; l++) {
307
+ if (k > 0 && l > 0)
308
+ continue;
309
+ i = Math.max(k - 1, 0);
310
+ j = Math.max(l - 1, 0);
311
+ swapType = k == 0 ? 6 : 4;
312
+ if (!routerGraph[coins[k]])
313
+ routerGraph[coins[k]] = {};
314
+ if (!routerGraph[coins[k]][coins[l]])
315
+ routerGraph[coins[k]][coins[l]] = [];
316
+ routerGraph[coins[k]][coins[l]].push({
317
+ poolId: poolId,
318
+ swapAddress: swapAddress,
319
+ inputCoinAddress: coins[k],
320
+ outputCoinAddress: coins[l],
321
+ swapParams: [i, j, swapType, poolType, wrappedCoinAddresses.length],
322
+ poolAddress: curve.constants.ZERO_ADDRESS,
323
+ basePool: curve.constants.ZERO_ADDRESS,
324
+ baseToken: curve.constants.ZERO_ADDRESS,
325
+ secondBasePool: curve.constants.ZERO_ADDRESS,
326
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
327
+ tvl: tvl,
328
+ });
329
+ }
274
330
  }
275
331
  }
276
- // LP -> underlying coin "swaps" (actually remove_liquidity_one_coin)
277
- if ((poolData.is_fake || is_aave_like_lending) && underlying_coin_addresses.length < 6 && inCoin === token_address) {
278
- for (j = 0; j < underlying_coin_addresses.length; j++) {
279
- // Looking for outputCoinAddress only on the final step
280
- if (step === MAX_STEPS - 1 && underlying_coin_addresses[j] !== outputCoinAddress)
281
- continue;
282
- outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
283
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
284
- continue;
285
- swapType = is_aave_like_lending ? 7 : 6;
286
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, underlying_coin_addresses[j], [0, j, swapType, pool_type, underlying_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
287
- nextCoins.add(underlying_coin_addresses[j]);
288
- }
289
- }
290
- // Wrapped coin -> LP "swaps" (actually add_liquidity)
291
- if (!poolData.is_fake && !poolData.is_llamma && wrapped_coin_addresses.length < 6 && inCoinIndexes.wrapped_coin >= 0) {
292
- // Looking for outputCoinAddress only on the final step
293
- if (!(step === MAX_STEPS - 1 && token_address !== outputCoinAddress)) {
294
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, token_address, [wrapped_coin_addresses.indexOf(inCoin), 0, 4, pool_type, wrapped_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
295
- nextCoins.add(token_address);
296
- }
297
- }
298
- // Underlying coin -> LP "swaps" (actually add_liquidity)
299
- if ((poolData.is_fake || is_aave_like_lending) && underlying_coin_addresses.length < 6 && inCoinIndexes.underlying_coin >= 0) {
300
- // Looking for outputCoinAddress only on the final step
301
- if (!(step === MAX_STEPS - 1 && token_address !== outputCoinAddress)) {
302
- swapType = is_aave_like_lending ? 5 : 4;
303
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, token_address, [underlying_coin_addresses.indexOf(inCoin), 0, swapType, pool_type, underlying_coin_addresses.length], curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, curve.constants.ZERO_ADDRESS, tvl);
304
- nextCoins.add(token_address);
332
+ // Underlying coin <-> LP "swaps" (actually add_liquidity/remove_liquidity_one_coin)
333
+ if ((poolData.is_fake || isAaveLikeLending) && underlyingCoinAddresses.length < 6) {
334
+ coins = __spreadArray([tokenAddress], underlyingCoinAddresses, true);
335
+ for (k = 0; k < coins.length; k++) {
336
+ for (l = 0; l < coins.length; l++) {
337
+ if (k > 0 && l > 0)
338
+ continue;
339
+ i = Math.max(k - 1, 0);
340
+ j = Math.max(l - 1, 0);
341
+ swapType = isAaveLikeLending ? 7 : 6;
342
+ if (k > 0)
343
+ swapType = isAaveLikeLending ? 5 : 4;
344
+ if (!routerGraph[coins[k]])
345
+ routerGraph[coins[k]] = {};
346
+ if (!routerGraph[coins[k]][coins[l]])
347
+ routerGraph[coins[k]][coins[l]] = [];
348
+ routerGraph[coins[k]][coins[l]].push({
349
+ poolId: poolId,
350
+ swapAddress: swapAddress,
351
+ inputCoinAddress: coins[k],
352
+ outputCoinAddress: coins[l],
353
+ swapParams: [i, j, swapType, poolType, underlyingCoinAddresses.length],
354
+ poolAddress: curve.constants.ZERO_ADDRESS,
355
+ basePool: curve.constants.ZERO_ADDRESS,
356
+ baseToken: curve.constants.ZERO_ADDRESS,
357
+ secondBasePool: curve.constants.ZERO_ADDRESS,
358
+ secondBaseToken: curve.constants.ZERO_ADDRESS,
359
+ tvl: tvl,
360
+ });
361
+ }
305
362
  }
306
363
  }
307
364
  // Wrapped swaps
308
- if (inCoinIndexes.wrapped_coin >= 0 && !poolData.is_fake) {
309
- for (j = 0; j < wrapped_coin_addresses.length; j++) {
310
- if (j === inCoinIndexes.wrapped_coin)
311
- continue;
312
- // Native swaps spend less gas
313
- if (wrapped_coin_addresses[j] !== outputCoinAddress && wrapped_coin_addresses[j] === curve.constants.NATIVE_TOKEN.wrappedAddress)
314
- continue;
315
- // Looking for outputCoinAddress only on the final step
316
- if (step === MAX_STEPS - 1 && wrapped_coin_addresses[j] !== outputCoinAddress)
317
- continue;
318
- outputCoinIdx = wrapped_coin_addresses.indexOf(outputCoinAddress);
319
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
320
- continue;
321
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, pool_address, inCoin, wrapped_coin_addresses[j], [inCoinIndexes.wrapped_coin, j, 1, pool_type, wrapped_coin_addresses.length], pool_address, base_pool_address, base_token_address, second_base_pool_address, second_base_token_address, tvl);
322
- nextCoins.add(wrapped_coin_addresses[j]);
365
+ if (!poolData.is_fake) {
366
+ for (i = 0; i < wrappedCoinAddresses.length; i++) {
367
+ for (j = 0; j < wrappedCoinAddresses.length; j++) {
368
+ if (i == j)
369
+ continue;
370
+ if (!routerGraph[wrappedCoinAddresses[i]])
371
+ routerGraph[wrappedCoinAddresses[i]] = {};
372
+ if (!routerGraph[wrappedCoinAddresses[i]][wrappedCoinAddresses[j]])
373
+ routerGraph[wrappedCoinAddresses[i]][wrappedCoinAddresses[j]] = [];
374
+ routerGraph[wrappedCoinAddresses[i]][wrappedCoinAddresses[j]] = routerGraph[wrappedCoinAddresses[i]][wrappedCoinAddresses[j]].concat({
375
+ poolId: poolId,
376
+ swapAddress: swapAddress,
377
+ inputCoinAddress: wrappedCoinAddresses[i],
378
+ outputCoinAddress: wrappedCoinAddresses[j],
379
+ swapParams: [i, j, 1, poolType, wrappedCoinAddresses.length],
380
+ poolAddress: poolAddress,
381
+ basePool: basePoolAddress,
382
+ baseToken: baseTokenAddress,
383
+ secondBasePool: secondBasePoolAddress,
384
+ secondBaseToken: secondBaseTokenAddress,
385
+ tvl: tvl,
386
+ }).sort(function (a, b) { return b.tvl - a.tvl; }).slice(0, GRAPH_MAX_EDGES);
387
+ }
323
388
  }
324
389
  }
325
390
  // Only for underlying swaps
326
- swap_address = (poolData.is_crypto && poolData.is_meta) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ?
391
+ swapAddress = (poolData.is_crypto && poolData.is_meta) || ((basePool === null || basePool === void 0 ? void 0 : basePool.is_lending) && poolData.is_factory) ?
327
392
  poolData.deposit_address : poolData.swap_address;
328
393
  // Underlying swaps
329
- if (!poolData.is_plain && inCoinIndexes.underlying_coin >= 0) {
330
- for (j = 0; j < underlying_coin_addresses.length; j++) {
331
- if (j === inCoinIndexes.underlying_coin)
332
- continue;
333
- // Don't swap metacoins since they can be swapped directly in base pool
334
- if (inCoinIndexes.meta_coin >= 0 && meta_coin_addresses.includes(underlying_coin_addresses[j]))
335
- continue;
336
- // Looking for outputCoinAddress only on the final step
337
- if (step === MAX_STEPS - 1 && underlying_coin_addresses[j] !== outputCoinAddress)
338
- continue;
339
- outputCoinIdx = underlying_coin_addresses.indexOf(outputCoinAddress);
340
- if (outputCoinIdx >= 0 && j !== outputCoinIdx)
341
- continue;
342
- // Skip empty pools
343
- if (tvl === 0)
344
- continue;
345
- hasEth = (inCoin === curve.constants.NATIVE_TOKEN.address || underlying_coin_addresses[j] === curve.constants.NATIVE_TOKEN.address);
346
- swapType = (poolData.is_crypto && poolData.is_meta && poolData.is_factory) || ((base_pool === null || base_pool === void 0 ? void 0 : base_pool.is_lending) && poolData.is_factory) ? 3
347
- : hasEth && poolId !== 'avaxcrypto' ? 1
348
- : 2;
349
- _updateRoutes(inputCoinAddress, routesByTvl, routesByLength, poolId, swap_address, inCoin, underlying_coin_addresses[j], [inCoinIndexes.underlying_coin, j, swapType, pool_type, underlying_coin_addresses.length], pool_address, base_pool_address, base_token_address, second_base_pool_address, second_base_token_address, tvl);
350
- nextCoins.add(underlying_coin_addresses[j]);
394
+ if (!poolData.is_plain) {
395
+ for (i = 0; i < underlyingCoinAddresses.length; i++) {
396
+ for (j = 0; j < underlyingCoinAddresses.length; j++) {
397
+ if (i === j)
398
+ continue;
399
+ // Don't swap metacoins since they can be swapped directly in base pool
400
+ if (metaCoinAddresses.includes(underlyingCoinAddresses[i]) && metaCoinAddresses.includes(underlyingCoinAddresses[j]))
401
+ continue;
402
+ hasEth = [underlyingCoinAddresses[i], underlyingCoinAddresses[j]].includes(curve.constants.NATIVE_TOKEN.address);
403
+ swapType = (poolData.is_crypto && poolData.is_meta && poolData.is_factory) || ((basePool === null || basePool === void 0 ? void 0 : basePool.is_lending) && poolData.is_factory) ? 3
404
+ : hasEth && poolId !== 'avaxcrypto' ? 1 : 2;
405
+ if (!routerGraph[underlyingCoinAddresses[i]])
406
+ routerGraph[underlyingCoinAddresses[i]] = {};
407
+ if (!routerGraph[underlyingCoinAddresses[i]][underlyingCoinAddresses[j]])
408
+ routerGraph[underlyingCoinAddresses[i]][underlyingCoinAddresses[j]] = [];
409
+ routerGraph[underlyingCoinAddresses[i]][underlyingCoinAddresses[j]] = routerGraph[underlyingCoinAddresses[i]][underlyingCoinAddresses[j]].concat({
410
+ poolId: poolId,
411
+ swapAddress: swapAddress,
412
+ inputCoinAddress: underlyingCoinAddresses[i],
413
+ outputCoinAddress: underlyingCoinAddresses[j],
414
+ swapParams: [i, j, swapType, poolType, underlyingCoinAddresses.length],
415
+ poolAddress: poolAddress,
416
+ basePool: basePoolAddress,
417
+ baseToken: baseTokenAddress,
418
+ secondBasePool: secondBasePoolAddress,
419
+ secondBaseToken: secondBaseTokenAddress,
420
+ tvl: tvl,
421
+ }).sort(function (a, b) { return b.tvl - a.tvl; }).slice(0, GRAPH_MAX_EDGES);
422
+ }
351
423
  }
352
424
  }
353
- _s.label = 6;
354
- case 6:
355
- _e++;
356
- return [3 /*break*/, 4];
357
- case 7:
358
- _i++;
359
- return [3 /*break*/, 3];
360
- case 8:
361
- curCoins = Array.from(nextCoins);
362
- nextCoins = new Set();
363
- _s.label = 9;
364
- case 9:
365
- step++;
425
+ _m.label = 4;
426
+ case 4:
427
+ _f++;
366
428
  return [3 /*break*/, 2];
367
- case 10:
368
- routes = __spreadArray(__spreadArray([], ((_q = routesByTvl[outputCoinAddress]) !== null && _q !== void 0 ? _q : []), true), ((_r = routesByLength[outputCoinAddress]) !== null && _r !== void 0 ? _r : []), true);
369
- return [2 /*return*/, routes.map(function (r) { return r.route; })];
429
+ case 5: return [2 /*return*/, routerGraph];
430
+ }
431
+ });
432
+ }); }, {
433
+ promise: true,
434
+ maxAge: 5 * 1000, // 5m
435
+ });
436
+ var _isVisitedCoin = function (coinAddress, route) {
437
+ return route.route.map(function (r) { return r.inputCoinAddress; }).includes(coinAddress);
438
+ };
439
+ var _isVisitedPool = function (poolId, route) {
440
+ return route.route.map(function (r) { return r.poolId; }).includes(poolId);
441
+ };
442
+ // Breadth-first search
443
+ var _findRoutes = function (inputCoinAddress, outputCoinAddress) { return __awaiter(void 0, void 0, void 0, function () {
444
+ var routes, targetRoutes, routerGraph, ALL_POOLS, route, inCoin, outCoin, _i, _a, step, poolData, routePoolIdsPlusSwapType, poolCoins;
445
+ return __generator(this, function (_b) {
446
+ switch (_b.label) {
447
+ case 0:
448
+ inputCoinAddress = inputCoinAddress.toLowerCase();
449
+ outputCoinAddress = outputCoinAddress.toLowerCase();
450
+ routes = [{ route: [], minTvl: Infinity, totalTvl: 0 }];
451
+ targetRoutes = [];
452
+ return [4 /*yield*/, _buildRouteGraph()];
453
+ case 1:
454
+ routerGraph = _b.sent();
455
+ ALL_POOLS = curve.getPoolsData();
456
+ while (routes.length > 0) {
457
+ route = routes.pop();
458
+ inCoin = route.route.length > 0 ? route.route[route.route.length - 1].outputCoinAddress : inputCoinAddress;
459
+ if (inCoin === outputCoinAddress) {
460
+ targetRoutes.push(route);
461
+ }
462
+ else if (route.route.length < 5) {
463
+ for (outCoin in routerGraph[inCoin]) {
464
+ if (_isVisitedCoin(outCoin, route))
465
+ continue;
466
+ for (_i = 0, _a = routerGraph[inCoin][outCoin]; _i < _a.length; _i++) {
467
+ step = _a[_i];
468
+ poolData = ALL_POOLS[step.poolId];
469
+ if (!(poolData === null || poolData === void 0 ? void 0 : poolData.is_lending) && _isVisitedPool(step.poolId, route))
470
+ continue;
471
+ routePoolIdsPlusSwapType = route.route.map(function (s) { return s.poolId + "+" + _handleSwapType(s.swapParams[2]); });
472
+ if (routePoolIdsPlusSwapType.includes(step.poolId + "+" + _handleSwapType(step.swapParams[2])))
473
+ continue;
474
+ poolCoins = poolData ? poolData.wrapped_coin_addresses.concat(poolData.underlying_coin_addresses) : [];
475
+ // Exclude such cases as:
476
+ // cvxeth -> tricrypto2 -> tusd -> susd (cvxeth -> tricrypto2 -> tusd instead)
477
+ if (!(poolData === null || poolData === void 0 ? void 0 : poolData.is_lending) && poolCoins.includes(outputCoinAddress) && outCoin !== outputCoinAddress)
478
+ continue;
479
+ // Exclude such cases as:
480
+ // aave -> aave -> 3pool (aave -> aave instead)
481
+ if ((poolData === null || poolData === void 0 ? void 0 : poolData.is_lending) && poolCoins.includes(outputCoinAddress) && outCoin !== outputCoinAddress && outCoin !== poolData.token_address)
482
+ continue;
483
+ routes.push({
484
+ route: __spreadArray(__spreadArray([], route.route, true), [step], false),
485
+ minTvl: Math.min(step.tvl, route.minTvl),
486
+ totalTvl: route.totalTvl + step.tvl,
487
+ });
488
+ }
489
+ }
490
+ }
491
+ }
492
+ targetRoutes = _removeDuplications(__spreadArray(__spreadArray([], targetRoutes.sort(_sortByTvl).slice(0, MAX_ROUTES_FOR_ONE_COIN), true), targetRoutes.sort(_sortByLength).slice(0, MAX_ROUTES_FOR_ONE_COIN), true));
493
+ return [2 /*return*/, targetRoutes.map(function (r) { return r.route; })];
370
494
  }
371
495
  });
372
496
  }); };
@@ -461,7 +585,7 @@ var _getBestRoute = memoize(function (inputCoinAddress, outputCoinAddress, amoun
461
585
  _amount = parseUnits(amount, inputCoinDecimals);
462
586
  if (_amount === curve.parseUnits("0"))
463
587
  return [2 /*return*/, []];
464
- return [4 /*yield*/, _findAllRoutes(inputCoinAddress, outputCoinAddress)];
588
+ return [4 /*yield*/, _findRoutes(inputCoinAddress, outputCoinAddress)];
465
589
  case 1:
466
590
  routesRaw = (_j.sent()).map(function (route) { return ({ route: route, _output: curve.parseUnits("0"), outputUsd: 0, txCostUsd: 0 }); });
467
591
  routes = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curvefi/api",
3
- "version": "2.47.5",
3
+ "version": "2.48.0",
4
4
  "description": "JavaScript library for curve.fi",
5
5
  "main": "lib/index.js",
6
6
  "author": "Macket",