@alcorexchange/alcor-swap-sdk 1.0.402 → 1.0.403
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.
- package/build/entities/pool.js +50 -33
- package/build/entities/tickListDataProvider.d.ts +5 -0
- package/build/entities/tickListDataProvider.js +17 -0
- package/build/entities/trade.d.ts +23 -0
- package/build/entities/trade.js +107 -6
- package/build/utils/fullMath.js +5 -15
- package/build/utils/getBestSwapRoute.js +13 -12
- package/build/utils/swapMath.js +23 -4
- package/build/utils/tickList.d.ts +6 -0
- package/build/utils/tickList.js +56 -0
- package/build/utils/tickMath.d.ts +4 -0
- package/build/utils/tickMath.js +37 -4
- package/build/utils/tradeCalculatorWASM.d.ts +45 -0
- package/build/utils/tradeCalculatorWASM.js +261 -0
- package/build/utils/wasm_route_finder.js +99 -0
- package/build/utils/wasm_route_finder_bg.wasm +0 -0
- package/package.json +1 -1
package/build/entities/pool.js
CHANGED
|
@@ -202,48 +202,65 @@ let Pool = exports.Pool = /*#__PURE__*/function () {
|
|
|
202
202
|
|
|
203
203
|
// Убираем проверки invariant в продакшене, если данные гарантированно валидны
|
|
204
204
|
const exactInput = amountSpecified >= _internalConstants.ZERO;
|
|
205
|
-
const state = {
|
|
206
|
-
amountSpecifiedRemaining: amountSpecified,
|
|
207
|
-
amountCalculated: _internalConstants.ZERO,
|
|
208
|
-
sqrtPriceX64: this.sqrtPriceX64,
|
|
209
|
-
tick: this.tickCurrent,
|
|
210
|
-
liquidity: this.liquidity
|
|
211
|
-
};
|
|
212
|
-
while (state.amountSpecifiedRemaining !== _internalConstants.ZERO && state.sqrtPriceX64 !== sqrtPriceLimit) {
|
|
213
|
-
const step = {
|
|
214
|
-
sqrtPriceStartX64: state.sqrtPriceX64
|
|
215
|
-
};
|
|
216
205
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
206
|
+
// Cache tickSpacing to avoid getter call each iteration
|
|
207
|
+
const tickSpacing = this.tickSpacing;
|
|
208
|
+
|
|
209
|
+
// Reset cursor for sequential tick access optimization
|
|
210
|
+
const provider = this.tickDataProvider;
|
|
211
|
+
const useCursor = typeof provider.nextInitializedTickWithinOneWordWithCursor === 'function';
|
|
212
|
+
if (useCursor) provider.resetCursor();
|
|
213
|
+
|
|
214
|
+
// State variables
|
|
215
|
+
let amountSpecifiedRemaining = amountSpecified;
|
|
216
|
+
let amountCalculated = _internalConstants.ZERO;
|
|
217
|
+
let sqrtPriceX64 = this.sqrtPriceX64;
|
|
218
|
+
let tick = this.tickCurrent;
|
|
219
|
+
let liquidity = this.liquidity;
|
|
220
|
+
|
|
221
|
+
// Step variables (reused each iteration - no object allocation)
|
|
222
|
+
let sqrtPriceStartX64;
|
|
223
|
+
let tickNext;
|
|
224
|
+
let initialized;
|
|
225
|
+
let sqrtPriceNextX64;
|
|
226
|
+
let amountIn;
|
|
227
|
+
let amountOut;
|
|
228
|
+
let feeAmount;
|
|
229
|
+
while (amountSpecifiedRemaining !== _internalConstants.ZERO && sqrtPriceX64 !== sqrtPriceLimit) {
|
|
230
|
+
sqrtPriceStartX64 = sqrtPriceX64;
|
|
231
|
+
|
|
232
|
+
// Use cursor-optimized version if available (O(1) vs O(log n))
|
|
233
|
+
[tickNext, initialized] = useCursor ? provider.nextInitializedTickWithinOneWordWithCursor(tick, zeroForOne, tickSpacing) : this.tickDataProvider.nextInitializedTickWithinOneWord(tick, zeroForOne, tickSpacing);
|
|
234
|
+
|
|
235
|
+
// Clamp tickNext to valid range
|
|
236
|
+
if (tickNext < _tickMath.TickMath.MIN_TICK) tickNext = _tickMath.TickMath.MIN_TICK;else if (tickNext > _tickMath.TickMath.MAX_TICK) tickNext = _tickMath.TickMath.MAX_TICK;
|
|
237
|
+
sqrtPriceNextX64 = _tickMath.TickMath.getSqrtRatioAtTick(tickNext);
|
|
238
|
+
const targetPrice = (zeroForOne ? sqrtPriceNextX64 < sqrtPriceLimit : sqrtPriceNextX64 > sqrtPriceLimit) ? sqrtPriceLimit : sqrtPriceNextX64;
|
|
239
|
+
[sqrtPriceX64, amountIn, amountOut, feeAmount] = _swapMath.SwapMath.computeSwapStep(sqrtPriceX64, targetPrice, liquidity, amountSpecifiedRemaining, this.fee);
|
|
223
240
|
if (exactInput) {
|
|
224
|
-
|
|
225
|
-
|
|
241
|
+
amountSpecifiedRemaining = amountSpecifiedRemaining - (amountIn + feeAmount);
|
|
242
|
+
amountCalculated = amountCalculated - amountOut;
|
|
226
243
|
} else {
|
|
227
|
-
|
|
228
|
-
|
|
244
|
+
amountSpecifiedRemaining = amountSpecifiedRemaining + amountOut;
|
|
245
|
+
amountCalculated = amountCalculated + (amountIn + feeAmount);
|
|
229
246
|
}
|
|
230
|
-
if (
|
|
231
|
-
if (
|
|
232
|
-
let liquidityNet =
|
|
247
|
+
if (sqrtPriceX64 === sqrtPriceNextX64) {
|
|
248
|
+
if (initialized) {
|
|
249
|
+
let liquidityNet = this.tickDataProvider.getTick(tickNext).liquidityNet;
|
|
233
250
|
if (zeroForOne) liquidityNet = liquidityNet * _internalConstants.NEGATIVE_ONE;
|
|
234
|
-
|
|
251
|
+
liquidity = _liquidityMath.LiquidityMath.addDelta(liquidity, liquidityNet);
|
|
235
252
|
}
|
|
236
|
-
|
|
237
|
-
} else if (
|
|
238
|
-
|
|
253
|
+
tick = zeroForOne ? tickNext - 1 : tickNext;
|
|
254
|
+
} else if (sqrtPriceX64 !== sqrtPriceStartX64) {
|
|
255
|
+
tick = _tickMath.TickMath.getTickAtSqrtRatio(sqrtPriceX64);
|
|
239
256
|
}
|
|
240
257
|
}
|
|
241
258
|
return {
|
|
242
|
-
amountA: zeroForOne === exactInput ? amountSpecified -
|
|
243
|
-
amountB: zeroForOne === exactInput ?
|
|
244
|
-
sqrtPriceX64
|
|
245
|
-
liquidity
|
|
246
|
-
tickCurrent:
|
|
259
|
+
amountA: zeroForOne === exactInput ? amountSpecified - amountSpecifiedRemaining : amountCalculated,
|
|
260
|
+
amountB: zeroForOne === exactInput ? amountCalculated : amountSpecified - amountSpecifiedRemaining,
|
|
261
|
+
sqrtPriceX64,
|
|
262
|
+
liquidity,
|
|
263
|
+
tickCurrent: tick
|
|
247
264
|
};
|
|
248
265
|
}
|
|
249
266
|
}, {
|
|
@@ -5,9 +5,14 @@ import { TickDataProvider } from "./tickDataProvider";
|
|
|
5
5
|
*/
|
|
6
6
|
export declare class TickListDataProvider implements TickDataProvider {
|
|
7
7
|
ticks: readonly Tick[];
|
|
8
|
+
private _cursorIndex;
|
|
8
9
|
constructor(ticks: (Tick | TickConstructorArgs)[], tickSpacing: number);
|
|
9
10
|
getTick(tick: number): Tick;
|
|
11
|
+
/** Reset cursor for new swap */
|
|
12
|
+
resetCursor(): void;
|
|
10
13
|
nextInitializedTickWithinOneWord(tick: number, lte: boolean, tickSpacing: number): [number, boolean];
|
|
14
|
+
/** Optimized version with cursor - O(1) for sequential access */
|
|
15
|
+
nextInitializedTickWithinOneWordWithCursor(tick: number, lte: boolean, tickSpacing: number): [number, boolean];
|
|
11
16
|
static toJSON(ticks: Tick[]): object;
|
|
12
17
|
static fromJSON(ticksArray: any): TickListDataProvider;
|
|
13
18
|
}
|
|
@@ -19,6 +19,7 @@ let TickListDataProvider = exports.TickListDataProvider = /*#__PURE__*/function
|
|
|
19
19
|
function TickListDataProvider(ticks, tickSpacing) {
|
|
20
20
|
_classCallCheck(this, TickListDataProvider);
|
|
21
21
|
_defineProperty(this, "ticks", void 0);
|
|
22
|
+
_defineProperty(this, "_cursorIndex", -1);
|
|
22
23
|
const ticksMapped = ticks.map(t => t instanceof _tick.Tick ? t : new _tick.Tick(t));
|
|
23
24
|
_tickList.TickList.validateList(ticksMapped, tickSpacing);
|
|
24
25
|
this.ticks = ticksMapped;
|
|
@@ -28,11 +29,27 @@ let TickListDataProvider = exports.TickListDataProvider = /*#__PURE__*/function
|
|
|
28
29
|
value: function getTick(tick) {
|
|
29
30
|
return _tickList.TickList.getTick(this.ticks, tick);
|
|
30
31
|
}
|
|
32
|
+
|
|
33
|
+
/** Reset cursor for new swap */
|
|
34
|
+
}, {
|
|
35
|
+
key: "resetCursor",
|
|
36
|
+
value: function resetCursor() {
|
|
37
|
+
this._cursorIndex = -1;
|
|
38
|
+
}
|
|
31
39
|
}, {
|
|
32
40
|
key: "nextInitializedTickWithinOneWord",
|
|
33
41
|
value: function nextInitializedTickWithinOneWord(tick, lte, tickSpacing) {
|
|
34
42
|
return _tickList.TickList.nextInitializedTickWithinOneWord(this.ticks, tick, lte, tickSpacing);
|
|
35
43
|
}
|
|
44
|
+
|
|
45
|
+
/** Optimized version with cursor - O(1) for sequential access */
|
|
46
|
+
}, {
|
|
47
|
+
key: "nextInitializedTickWithinOneWordWithCursor",
|
|
48
|
+
value: function nextInitializedTickWithinOneWordWithCursor(tick, lte, tickSpacing) {
|
|
49
|
+
const [tickNext, initialized, newCursor] = _tickList.TickList.nextInitializedTickWithinOneWordWithCursor(this.ticks, tick, lte, tickSpacing, this._cursorIndex);
|
|
50
|
+
this._cursorIndex = newCursor;
|
|
51
|
+
return [tickNext, initialized];
|
|
52
|
+
}
|
|
36
53
|
}], [{
|
|
37
54
|
key: "toJSON",
|
|
38
55
|
value: function toJSON(ticks) {
|
|
@@ -2,6 +2,7 @@ import { Currency } from './currency';
|
|
|
2
2
|
import { Percent, Price, CurrencyAmount } from './fractions';
|
|
3
3
|
import { TradeType } from '../internalConstants';
|
|
4
4
|
import { Route } from './route';
|
|
5
|
+
import { Pool } from './pool';
|
|
5
6
|
/**
|
|
6
7
|
* Trades comparator, an extension of the input output comparator that also considers other dimensions of the trade in ranking them
|
|
7
8
|
* @template TInput The input token, either Ether or an ERC-20
|
|
@@ -105,6 +106,14 @@ export declare class Trade<TInput extends Currency, TOutput extends Currency, TT
|
|
|
105
106
|
* @returns The exact out trade
|
|
106
107
|
*/
|
|
107
108
|
static exactOut<TInput extends Currency, TOutput extends Currency>(route: Route<TInput, TOutput>, amountOut: CurrencyAmount<TOutput>): Trade<TInput, TOutput, TradeType.EXACT_OUTPUT>;
|
|
109
|
+
/**
|
|
110
|
+
* WASM-accelerated version of fromRoute (for EXACT_INPUT only)
|
|
111
|
+
* @param route route to swap through
|
|
112
|
+
* @param amount the input amount
|
|
113
|
+
* @param pools All pools for calculation
|
|
114
|
+
* @returns Promise of the trade
|
|
115
|
+
*/
|
|
116
|
+
static fromRouteWASM<TInput extends Currency, TOutput extends Currency>(route: Route<TInput, TOutput>, amount: CurrencyAmount<TInput>, pools: Pool[]): Promise<Trade<TInput, TOutput, TradeType.EXACT_INPUT>>;
|
|
108
117
|
/**
|
|
109
118
|
* Constructs a trade by simulating swaps through the given route
|
|
110
119
|
* @template TInput The input token, either Ether or an ERC-20.
|
|
@@ -191,6 +200,20 @@ export declare class Trade<TInput extends Currency, TOutput extends Currency, TT
|
|
|
191
200
|
worstExecutionPrice(slippageTolerance: Percent): Price<TInput, TOutput>;
|
|
192
201
|
static bestTradeExactIn<TInput extends Currency, TOutput extends Currency>(routes: Route<TInput, TOutput>[], currencyAmountIn: CurrencyAmount<TInput>, maxNumResults?: number): Trade<TInput, TOutput, TradeType.EXACT_INPUT>[];
|
|
193
202
|
static bestTradeExactOut<TInput extends Currency, TOutput extends Currency>(routes: Route<TInput, TOutput>[], currencyAmountOut: CurrencyAmount<TOutput>, maxNumResults?: number): Trade<TInput, TOutput, TradeType.EXACT_OUTPUT>[];
|
|
203
|
+
/**
|
|
204
|
+
* WASM-accelerated version of bestTradeWithSplit
|
|
205
|
+
* @param _routes Routes to consider
|
|
206
|
+
* @param amount Amount to swap
|
|
207
|
+
* @param percents Percentages to split
|
|
208
|
+
* @param tradeType Type of trade
|
|
209
|
+
* @param pools All pools for trade calculation
|
|
210
|
+
* @param swapConfig Configuration for splits
|
|
211
|
+
* @returns Best trade or null
|
|
212
|
+
*/
|
|
213
|
+
static bestTradeWithSplitWASM<TInput extends Currency, TOutput extends Currency>(_routes: Route<TInput, TOutput>[], amount: CurrencyAmount<Currency>, percents: number[], tradeType: TradeType, pools: Pool[], swapConfig?: {
|
|
214
|
+
minSplits: number;
|
|
215
|
+
maxSplits: number;
|
|
216
|
+
}): Promise<Trade<Currency, Currency, TradeType> | null>;
|
|
194
217
|
static bestTradeWithSplit<TInput extends Currency, TOutput extends Currency>(_routes: Route<TInput, TOutput>[], amount: CurrencyAmount<Currency>, percents: number[], tradeType: TradeType, swapConfig?: {
|
|
195
218
|
minSplits: number;
|
|
196
219
|
maxSplits: number;
|
package/build/entities/trade.js
CHANGED
|
@@ -14,6 +14,8 @@ var _getBestSwapRoute = require("../utils/getBestSwapRoute");
|
|
|
14
14
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
15
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
16
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
18
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
17
19
|
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
18
20
|
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
19
21
|
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
@@ -302,6 +304,22 @@ let Trade = exports.Trade = /*#__PURE__*/function () {
|
|
|
302
304
|
return Trade.fromRoute(route, amountOut, _internalConstants.TradeType.EXACT_OUTPUT);
|
|
303
305
|
}
|
|
304
306
|
|
|
307
|
+
/**
|
|
308
|
+
* WASM-accelerated version of fromRoute (for EXACT_INPUT only)
|
|
309
|
+
* @param route route to swap through
|
|
310
|
+
* @param amount the input amount
|
|
311
|
+
* @param pools All pools for calculation
|
|
312
|
+
* @returns Promise of the trade
|
|
313
|
+
*/
|
|
314
|
+
}, {
|
|
315
|
+
key: "fromRouteWASM",
|
|
316
|
+
value: async function fromRouteWASM(route, amount, pools) {
|
|
317
|
+
const {
|
|
318
|
+
createTradeFromRouteWASM
|
|
319
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require('../utils/tradeCalculatorWASM')));
|
|
320
|
+
return createTradeFromRouteWASM(route, amount, _internalConstants.TradeType.EXACT_INPUT, pools);
|
|
321
|
+
}
|
|
322
|
+
|
|
305
323
|
/**
|
|
306
324
|
* Constructs a trade by simulating swaps through the given route
|
|
307
325
|
* @template TInput The input token, either Ether or an ERC-20.
|
|
@@ -442,8 +460,38 @@ let Trade = exports.Trade = /*#__PURE__*/function () {
|
|
|
442
460
|
value: function bestTradeExactIn(routes, currencyAmountIn) {
|
|
443
461
|
let maxNumResults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
444
462
|
(0, _tinyInvariant.default)(routes.length > 0, 'ROUTES');
|
|
463
|
+
|
|
464
|
+
// Pre-filter: remove routes with zero-liquidity pools
|
|
465
|
+
const validRoutes = routes.filter(route => route.pools.every(pool => pool.active && pool.liquidity > _internalConstants.ZERO));
|
|
466
|
+
|
|
467
|
+
// Helper: compute min liquidity using JSBI (no overflow)
|
|
468
|
+
const getMinLiquidity = route => {
|
|
469
|
+
let min = route.pools[0].liquidity;
|
|
470
|
+
for (let i = 1; i < route.pools.length; i++) {
|
|
471
|
+
if (route.pools[i].liquidity < min) {
|
|
472
|
+
min = route.pools[i].liquidity;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return min;
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// Precompute min liquidity for sorting
|
|
479
|
+
const routeMinLiq = new Map();
|
|
480
|
+
for (const route of validRoutes) {
|
|
481
|
+
routeMinLiq.set(route, getMinLiquidity(route));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Sort routes: fewer hops first, then by min liquidity desc
|
|
485
|
+
validRoutes.sort((a, b) => {
|
|
486
|
+
if (a.pools.length !== b.pools.length) return a.pools.length - b.pools.length;
|
|
487
|
+
const minLiqA = routeMinLiq.get(a);
|
|
488
|
+
const minLiqB = routeMinLiq.get(b);
|
|
489
|
+
if (minLiqA > minLiqB) return -1;
|
|
490
|
+
if (minLiqA < minLiqB) return 1;
|
|
491
|
+
return 0;
|
|
492
|
+
});
|
|
445
493
|
const bestTrades = [];
|
|
446
|
-
for (const route of
|
|
494
|
+
for (const route of validRoutes) {
|
|
447
495
|
let trade;
|
|
448
496
|
try {
|
|
449
497
|
trade = Trade.fromRoute(route, currencyAmountIn, _internalConstants.TradeType.EXACT_INPUT);
|
|
@@ -455,8 +503,8 @@ let Trade = exports.Trade = /*#__PURE__*/function () {
|
|
|
455
503
|
throw error;
|
|
456
504
|
}
|
|
457
505
|
|
|
458
|
-
//
|
|
459
|
-
if (!trade.
|
|
506
|
+
// Only check outputAmount > 0, skip expensive priceImpact calculation
|
|
507
|
+
if (!trade.outputAmount.greaterThan(0)) continue;
|
|
460
508
|
(0, _utils.sortedInsert)(bestTrades, trade, maxNumResults, tradeComparator);
|
|
461
509
|
}
|
|
462
510
|
return bestTrades;
|
|
@@ -483,6 +531,29 @@ let Trade = exports.Trade = /*#__PURE__*/function () {
|
|
|
483
531
|
}
|
|
484
532
|
return bestTrades;
|
|
485
533
|
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* WASM-accelerated version of bestTradeWithSplit
|
|
537
|
+
* @param _routes Routes to consider
|
|
538
|
+
* @param amount Amount to swap
|
|
539
|
+
* @param percents Percentages to split
|
|
540
|
+
* @param tradeType Type of trade
|
|
541
|
+
* @param pools All pools for trade calculation
|
|
542
|
+
* @param swapConfig Configuration for splits
|
|
543
|
+
* @returns Best trade or null
|
|
544
|
+
*/
|
|
545
|
+
}, {
|
|
546
|
+
key: "bestTradeWithSplitWASM",
|
|
547
|
+
value: async function bestTradeWithSplitWASM(_routes, amount, percents, tradeType, pools) {
|
|
548
|
+
let swapConfig = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
|
|
549
|
+
minSplits: 1,
|
|
550
|
+
maxSplits: 10
|
|
551
|
+
};
|
|
552
|
+
const {
|
|
553
|
+
bestTradeWithSplitWASM
|
|
554
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require('../utils/tradeCalculatorWASM')));
|
|
555
|
+
return bestTradeWithSplitWASM(_routes, amount, percents, tradeType, pools, swapConfig);
|
|
556
|
+
}
|
|
486
557
|
}, {
|
|
487
558
|
key: "bestTradeWithSplit",
|
|
488
559
|
value: function bestTradeWithSplit(_routes, amount, percents, tradeType) {
|
|
@@ -493,6 +564,35 @@ let Trade = exports.Trade = /*#__PURE__*/function () {
|
|
|
493
564
|
(0, _tinyInvariant.default)(_routes.length > 0, 'ROUTES');
|
|
494
565
|
(0, _tinyInvariant.default)(percents.length > 0, 'PERCENTS');
|
|
495
566
|
|
|
567
|
+
// Pre-filter: remove routes with zero-liquidity or inactive pools
|
|
568
|
+
const validRoutes = _routes.filter(route => route.pools.every(pool => pool.active && pool.liquidity > _internalConstants.ZERO));
|
|
569
|
+
|
|
570
|
+
// Helper: compute min liquidity for a route using JSBI (no overflow)
|
|
571
|
+
const getMinLiquidity = route => {
|
|
572
|
+
let min = route.pools[0].liquidity;
|
|
573
|
+
for (let i = 1; i < route.pools.length; i++) {
|
|
574
|
+
if (route.pools[i].liquidity < min) {
|
|
575
|
+
min = route.pools[i].liquidity;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return min;
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
// Precompute min liquidity for sorting (avoid recalculating)
|
|
582
|
+
const routeMinLiq = new Map();
|
|
583
|
+
for (const route of validRoutes) {
|
|
584
|
+
routeMinLiq.set(route, getMinLiquidity(route));
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// Sort routes by min liquidity (descending) - no hop preference
|
|
588
|
+
validRoutes.sort((a, b) => {
|
|
589
|
+
const minLiqA = routeMinLiq.get(a);
|
|
590
|
+
const minLiqB = routeMinLiq.get(b);
|
|
591
|
+
if (minLiqA > minLiqB) return -1;
|
|
592
|
+
if (minLiqA < minLiqB) return 1;
|
|
593
|
+
return 0;
|
|
594
|
+
});
|
|
595
|
+
|
|
496
596
|
// Предварительно вычисляем splitAmount для всех процентов
|
|
497
597
|
const percentToAmount = new Map();
|
|
498
598
|
for (const percent of percents) {
|
|
@@ -506,13 +606,14 @@ let Trade = exports.Trade = /*#__PURE__*/function () {
|
|
|
506
606
|
}
|
|
507
607
|
|
|
508
608
|
// Оптимизируем внутренний цикл - группируем вычисления по маршрутам
|
|
509
|
-
for (const route of
|
|
510
|
-
// Для каждого маршрута проходим по всем процентам
|
|
609
|
+
for (const route of validRoutes) {
|
|
511
610
|
for (const percent of percents) {
|
|
512
611
|
const splitAmount = percentToAmount.get(percent);
|
|
513
612
|
try {
|
|
514
613
|
const trade = Trade.fromRoute(route, splitAmount, tradeType, percent);
|
|
515
|
-
|
|
614
|
+
|
|
615
|
+
// Only check outputAmount > 0, skip expensive priceImpact calculation
|
|
616
|
+
if (trade.outputAmount.greaterThan(0)) {
|
|
516
617
|
percentToTrades.get(percent).push(trade);
|
|
517
618
|
}
|
|
518
619
|
} catch (error) {
|
package/build/utils/fullMath.js
CHANGED
|
@@ -18,28 +18,18 @@ let FullMath = exports.FullMath = /*#__PURE__*/function () {
|
|
|
18
18
|
return _createClass(FullMath, null, [{
|
|
19
19
|
key: "mulDivRoundingUp",
|
|
20
20
|
value: function mulDivRoundingUp(a, b, denominator) {
|
|
21
|
-
//
|
|
22
|
-
if (denominator === ZERO) {
|
|
23
|
-
throw new Error("Division by zero");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Early return for zero inputs
|
|
21
|
+
// Early return for zero inputs (most common fast path)
|
|
27
22
|
if (a === ZERO || b === ZERO) {
|
|
28
23
|
return ZERO;
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
//
|
|
32
|
-
if (denominator === ONE) {
|
|
33
|
-
return a * b;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Calculate product, quotient, and remainder
|
|
26
|
+
// Calculate product and quotient (1 division instead of 2)
|
|
37
27
|
const product = a * b;
|
|
38
28
|
const quotient = product / denominator;
|
|
39
|
-
const remainder = product % denominator;
|
|
40
29
|
|
|
41
|
-
// Round up if there
|
|
42
|
-
|
|
30
|
+
// Round up if there's remainder: check if product !== quotient * denominator
|
|
31
|
+
// This avoids expensive % operation (which is another division internally)
|
|
32
|
+
if (product !== quotient * denominator) {
|
|
43
33
|
return quotient + ONE;
|
|
44
34
|
}
|
|
45
35
|
return quotient;
|
|
@@ -16,18 +16,18 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
16
16
|
// Извлекаем уникальные пулы из всех маршрутов
|
|
17
17
|
const allPools = [...new Set(Object.values(percentToQuotes).flatMap(routes => routes.flatMap(r => r.route.pools)))];
|
|
18
18
|
|
|
19
|
-
// Создаем битовую карту для пулов
|
|
19
|
+
// Создаем битовую карту для пулов (bigint для поддержки >31 пулов)
|
|
20
20
|
const poolToBit = new Map();
|
|
21
|
-
let bitCounter = 0;
|
|
21
|
+
let bitCounter = BigInt(0);
|
|
22
22
|
for (const pool of allPools) {
|
|
23
|
-
poolToBit.set(pool.id, 1 << bitCounter++);
|
|
23
|
+
poolToBit.set(pool.id, BigInt(1) << bitCounter++);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// Предвычисляем маски для всех маршрутов
|
|
27
27
|
const routeToMask = new Map();
|
|
28
28
|
for (const routes of Object.values(percentToQuotes)) {
|
|
29
29
|
for (const route of routes) {
|
|
30
|
-
let mask = 0;
|
|
30
|
+
let mask = BigInt(0);
|
|
31
31
|
for (const pool of route.route.pools) {
|
|
32
32
|
mask |= poolToBit.get(pool.id);
|
|
33
33
|
}
|
|
@@ -76,7 +76,7 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
// Очередь для обработки комбинаций маршрутов
|
|
79
|
+
// Очередь для обработки комбинаций маршрутов (с usedMask для быстрой проверки overlap)
|
|
80
80
|
const queue = new _queue.default();
|
|
81
81
|
if (percents.length === 0) return null;
|
|
82
82
|
|
|
@@ -90,6 +90,7 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
90
90
|
curRoutes: [topRoutes[0]],
|
|
91
91
|
percentIndex: i,
|
|
92
92
|
remainingPercent: 100 - percent,
|
|
93
|
+
usedMask: routeToMask.get(topRoutes[0]),
|
|
93
94
|
special: false
|
|
94
95
|
});
|
|
95
96
|
}
|
|
@@ -98,6 +99,7 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
98
99
|
curRoutes: [topRoutes[1]],
|
|
99
100
|
percentIndex: i,
|
|
100
101
|
remainingPercent: 100 - percent,
|
|
102
|
+
usedMask: routeToMask.get(topRoutes[1]),
|
|
101
103
|
special: true
|
|
102
104
|
});
|
|
103
105
|
}
|
|
@@ -121,6 +123,7 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
121
123
|
remainingPercent,
|
|
122
124
|
curRoutes,
|
|
123
125
|
percentIndex,
|
|
126
|
+
usedMask,
|
|
124
127
|
special
|
|
125
128
|
} = queue.dequeue();
|
|
126
129
|
for (let i = percentIndex; i >= 0; i--) {
|
|
@@ -128,11 +131,12 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
128
131
|
if (percentA > remainingPercent) continue;
|
|
129
132
|
if (!percentToSortedQuotes[percentA] || percentToSortedQuotes[percentA].length === 0) continue;
|
|
130
133
|
const candidateRoutesA = percentToSortedQuotes[percentA];
|
|
131
|
-
const routeWithQuoteA = findFirstRouteNotUsingUsedPools(
|
|
134
|
+
const routeWithQuoteA = findFirstRouteNotUsingUsedPools(usedMask, candidateRoutesA, routeToMask);
|
|
132
135
|
if (!routeWithQuoteA) continue;
|
|
133
136
|
const remainingPercentNew = remainingPercent - percentA;
|
|
134
137
|
const curRoutesNew = curRoutes.slice();
|
|
135
138
|
curRoutesNew.push(routeWithQuoteA);
|
|
139
|
+
const usedMaskNew = usedMask | routeToMask.get(routeWithQuoteA);
|
|
136
140
|
if (remainingPercentNew === 0 && splits >= minSplits) {
|
|
137
141
|
const quotesNew = curRoutesNew.map(r => r.outputAmount);
|
|
138
142
|
const quoteNew = sumFn(quotesNew);
|
|
@@ -149,6 +153,7 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
149
153
|
curRoutes: curRoutesNew,
|
|
150
154
|
remainingPercent: remainingPercentNew,
|
|
151
155
|
percentIndex: i,
|
|
156
|
+
usedMask: usedMaskNew,
|
|
152
157
|
special
|
|
153
158
|
});
|
|
154
159
|
}
|
|
@@ -165,14 +170,10 @@ function getBestSwapRoute(routeType, percentToQuotes, percents) {
|
|
|
165
170
|
}
|
|
166
171
|
|
|
167
172
|
// Вспомогательная функция для поиска маршрута без пересекающихся пулов
|
|
168
|
-
const findFirstRouteNotUsingUsedPools = (
|
|
169
|
-
let usedMask = 0;
|
|
170
|
-
for (const route of usedRoutes) {
|
|
171
|
-
usedMask |= routeToMask.get(route);
|
|
172
|
-
}
|
|
173
|
+
const findFirstRouteNotUsingUsedPools = (usedMask, candidateRoutes, routeToMask) => {
|
|
173
174
|
for (const candidate of candidateRoutes) {
|
|
174
175
|
const candidateMask = routeToMask.get(candidate);
|
|
175
|
-
if ((candidateMask & usedMask) === 0) {
|
|
176
|
+
if ((candidateMask & usedMask) === BigInt(0)) {
|
|
176
177
|
return candidate;
|
|
177
178
|
}
|
|
178
179
|
}
|
package/build/utils/swapMath.js
CHANGED
|
@@ -13,7 +13,26 @@ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r),
|
|
|
13
13
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
14
14
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
15
15
|
const MAX_FEE = 10n ** 6n;
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
// Cache for fee factors - feePips values are limited (100, 500, 3000, 10000)
|
|
18
|
+
const feeFactorCache = new Map();
|
|
19
|
+
const feePipsCache = new Map();
|
|
20
|
+
function getFeeFactor(feePips) {
|
|
21
|
+
let cached = feeFactorCache.get(feePips);
|
|
22
|
+
if (cached === undefined) {
|
|
23
|
+
cached = MAX_FEE - getFeePipsBigInt(feePips);
|
|
24
|
+
feeFactorCache.set(feePips, cached);
|
|
25
|
+
}
|
|
26
|
+
return cached;
|
|
27
|
+
}
|
|
28
|
+
function getFeePipsBigInt(feePips) {
|
|
29
|
+
let cached = feePipsCache.get(feePips);
|
|
30
|
+
if (cached === undefined) {
|
|
31
|
+
cached = BigInt(feePips);
|
|
32
|
+
feePipsCache.set(feePips, cached);
|
|
33
|
+
}
|
|
34
|
+
return cached;
|
|
35
|
+
}
|
|
17
36
|
let SwapMath = exports.SwapMath = /*#__PURE__*/function () {
|
|
18
37
|
/**
|
|
19
38
|
* Cannot be constructed.
|
|
@@ -31,7 +50,7 @@ let SwapMath = exports.SwapMath = /*#__PURE__*/function () {
|
|
|
31
50
|
let amountOut;
|
|
32
51
|
let feeAmount;
|
|
33
52
|
if (exactIn) {
|
|
34
|
-
const feeFactor =
|
|
53
|
+
const feeFactor = getFeeFactor(feePips);
|
|
35
54
|
const amountRemainingLessFee = amountRemaining * feeFactor / MAX_FEE;
|
|
36
55
|
const deltaIn = zeroForOne ? _sqrtPriceMath.SqrtPriceMath.getAmountADelta(sqrtRatioTargetX64, sqrtRatioCurrentX64, liquidity, true) : _sqrtPriceMath.SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, true);
|
|
37
56
|
if (amountRemainingLessFee >= deltaIn) {
|
|
@@ -42,7 +61,7 @@ let SwapMath = exports.SwapMath = /*#__PURE__*/function () {
|
|
|
42
61
|
amountIn = zeroForOne ? _sqrtPriceMath.SqrtPriceMath.getAmountADelta(sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, true) : _sqrtPriceMath.SqrtPriceMath.getAmountBDelta(sqrtRatioCurrentX64, sqrtRatioNextX64, liquidity, true);
|
|
43
62
|
}
|
|
44
63
|
amountOut = zeroForOne ? _sqrtPriceMath.SqrtPriceMath.getAmountBDelta(sqrtRatioNextX64, sqrtRatioCurrentX64, liquidity, false) : _sqrtPriceMath.SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, sqrtRatioNextX64, liquidity, false);
|
|
45
|
-
feeAmount = sqrtRatioNextX64 !== sqrtRatioTargetX64 ? amountRemaining - amountIn : _fullMath.FullMath.mulDivRoundingUp(amountIn,
|
|
64
|
+
feeAmount = sqrtRatioNextX64 !== sqrtRatioTargetX64 ? amountRemaining - amountIn : _fullMath.FullMath.mulDivRoundingUp(amountIn, getFeePipsBigInt(feePips), feeFactor);
|
|
46
65
|
} else {
|
|
47
66
|
const deltaOut = zeroForOne ? _sqrtPriceMath.SqrtPriceMath.getAmountBDelta(sqrtRatioTargetX64, sqrtRatioCurrentX64, liquidity, false) : _sqrtPriceMath.SqrtPriceMath.getAmountADelta(sqrtRatioCurrentX64, sqrtRatioTargetX64, liquidity, false);
|
|
48
67
|
const amountRemainingNegative = amountRemaining * _internalConstants.NEGATIVE_ONE;
|
|
@@ -57,7 +76,7 @@ let SwapMath = exports.SwapMath = /*#__PURE__*/function () {
|
|
|
57
76
|
if (amountOut > amountRemainingNegative) {
|
|
58
77
|
amountOut = amountRemainingNegative;
|
|
59
78
|
}
|
|
60
|
-
feeAmount = _fullMath.FullMath.mulDivRoundingUp(amountIn,
|
|
79
|
+
feeAmount = _fullMath.FullMath.mulDivRoundingUp(amountIn, getFeePipsBigInt(feePips), getFeeFactor(feePips));
|
|
61
80
|
}
|
|
62
81
|
return [sqrtRatioNextX64, amountIn, amountOut, feeAmount];
|
|
63
82
|
}
|
|
@@ -20,4 +20,10 @@ export declare abstract class TickList {
|
|
|
20
20
|
private static binarySearch;
|
|
21
21
|
static nextInitializedTick(ticks: readonly Tick[], tick: number, lte: boolean): Tick;
|
|
22
22
|
static nextInitializedTickWithinOneWord(ticks: readonly Tick[], tick: number, lte: boolean, tickSpacing: number): [number, boolean];
|
|
23
|
+
/**
|
|
24
|
+
* Optimized version with cursor hint for sequential access (swap loops)
|
|
25
|
+
* @param cursorHint - last known index position, -1 if unknown
|
|
26
|
+
* @returns [tickId, initialized, newCursorIndex]
|
|
27
|
+
*/
|
|
28
|
+
static nextInitializedTickWithinOneWordWithCursor(ticks: readonly Tick[], tick: number, lte: boolean, tickSpacing: number, cursorHint: number): [number, boolean, number];
|
|
23
29
|
}
|
package/build/utils/tickList.js
CHANGED
|
@@ -144,5 +144,61 @@ let TickList = exports.TickList = /*#__PURE__*/function () {
|
|
|
144
144
|
return [nextInitializedTick, nextInitializedTick === ticks[id + 1].id];
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Optimized version with cursor hint for sequential access (swap loops)
|
|
150
|
+
* @param cursorHint - last known index position, -1 if unknown
|
|
151
|
+
* @returns [tickId, initialized, newCursorIndex]
|
|
152
|
+
*/
|
|
153
|
+
}, {
|
|
154
|
+
key: "nextInitializedTickWithinOneWordWithCursor",
|
|
155
|
+
value: function nextInitializedTickWithinOneWordWithCursor(ticks, tick, lte, tickSpacing, cursorHint) {
|
|
156
|
+
const compressed = Math.floor(tick / tickSpacing);
|
|
157
|
+
const tickCount = ticks.length;
|
|
158
|
+
if (lte) {
|
|
159
|
+
const wordPos = compressed >> 7;
|
|
160
|
+
const minimum = (wordPos << 7) * tickSpacing;
|
|
161
|
+
if (tick < ticks[0].id) return [minimum, false, -1];
|
|
162
|
+
if (tick >= ticks[tickCount - 1].id) return [ticks[tickCount - 1].id, true, tickCount - 1];
|
|
163
|
+
|
|
164
|
+
// Use cursor hint for O(1) lookup if valid
|
|
165
|
+
let id;
|
|
166
|
+
if (cursorHint >= 0 && cursorHint < tickCount) {
|
|
167
|
+
// Linear scan from hint (swap moves monotonically)
|
|
168
|
+
if (ticks[cursorHint].id <= tick && (cursorHint === tickCount - 1 || ticks[cursorHint + 1].id > tick)) {
|
|
169
|
+
id = cursorHint;
|
|
170
|
+
} else if (cursorHint > 0 && ticks[cursorHint - 1].id <= tick && ticks[cursorHint].id > tick) {
|
|
171
|
+
id = cursorHint - 1;
|
|
172
|
+
} else {
|
|
173
|
+
id = this.binarySearch(ticks, tick);
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
id = this.binarySearch(ticks, tick);
|
|
177
|
+
}
|
|
178
|
+
const nextInitializedTick = Math.max(minimum, ticks[id].id);
|
|
179
|
+
return [nextInitializedTick, nextInitializedTick === ticks[id].id, id];
|
|
180
|
+
} else {
|
|
181
|
+
const wordPos = compressed + 1 >> 7;
|
|
182
|
+
const maximum = ((wordPos + 1 << 7) - 1) * tickSpacing;
|
|
183
|
+
if (tick >= ticks[tickCount - 1].id) return [maximum, false, tickCount - 1];
|
|
184
|
+
if (tick < ticks[0].id) return [ticks[0].id, true, 0];
|
|
185
|
+
|
|
186
|
+
// Use cursor hint for O(1) lookup if valid
|
|
187
|
+
let id;
|
|
188
|
+
if (cursorHint >= 0 && cursorHint < tickCount - 1) {
|
|
189
|
+
if (ticks[cursorHint].id <= tick && ticks[cursorHint + 1].id > tick) {
|
|
190
|
+
id = cursorHint;
|
|
191
|
+
} else if (cursorHint < tickCount - 2 && ticks[cursorHint + 1].id <= tick && ticks[cursorHint + 2].id > tick) {
|
|
192
|
+
id = cursorHint + 1;
|
|
193
|
+
} else {
|
|
194
|
+
id = this.binarySearch(ticks, tick);
|
|
195
|
+
}
|
|
196
|
+
} else {
|
|
197
|
+
id = this.binarySearch(ticks, tick);
|
|
198
|
+
}
|
|
199
|
+
const nextInitializedTick = Math.min(maximum, ticks[id + 1].id);
|
|
200
|
+
return [nextInitializedTick, nextInitializedTick === ticks[id + 1].id, id];
|
|
201
|
+
}
|
|
202
|
+
}
|
|
147
203
|
}]);
|
|
148
204
|
}();
|
|
@@ -16,6 +16,10 @@ export declare abstract class TickMath {
|
|
|
16
16
|
* The sqrt ratio corresponding to the maximum tick that could be used on any pool.
|
|
17
17
|
*/
|
|
18
18
|
static MAX_SQRT_RATIO: JSBI;
|
|
19
|
+
/**
|
|
20
|
+
* Clears all caches. Call this if memory usage is a concern.
|
|
21
|
+
*/
|
|
22
|
+
static clearCache(): void;
|
|
19
23
|
/**
|
|
20
24
|
* Returns the sqrt ratio as a Q64.96 for the given tick. The sqrt ratio is computed as sqrt(1.0001)^tick
|
|
21
25
|
* @param tick the tick for which to compute the sqrt ratio
|
package/build/utils/tickMath.js
CHANGED
|
@@ -18,18 +18,37 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
18
18
|
function mulShift(val, mulBy) {
|
|
19
19
|
return val * BigInt(mulBy) >> 128n;
|
|
20
20
|
}
|
|
21
|
+
|
|
22
|
+
// Memoization caches
|
|
23
|
+
const sqrtRatioCache = new Map();
|
|
24
|
+
const tickAtSqrtRatioCache = new Map();
|
|
21
25
|
let TickMath = exports.TickMath = /*#__PURE__*/function () {
|
|
22
26
|
function TickMath() {
|
|
23
27
|
_classCallCheck(this, TickMath);
|
|
24
28
|
}
|
|
25
29
|
return _createClass(TickMath, null, [{
|
|
26
|
-
key: "
|
|
30
|
+
key: "clearCache",
|
|
27
31
|
value:
|
|
32
|
+
/**
|
|
33
|
+
* Clears all caches. Call this if memory usage is a concern.
|
|
34
|
+
*/
|
|
35
|
+
function clearCache() {
|
|
36
|
+
sqrtRatioCache.clear();
|
|
37
|
+
tickAtSqrtRatioCache.clear();
|
|
38
|
+
}
|
|
39
|
+
|
|
28
40
|
/**
|
|
29
41
|
* Returns the sqrt ratio as a Q64.96 for the given tick. The sqrt ratio is computed as sqrt(1.0001)^tick
|
|
30
42
|
* @param tick the tick for which to compute the sqrt ratio
|
|
31
43
|
*/
|
|
32
|
-
|
|
44
|
+
}, {
|
|
45
|
+
key: "getSqrtRatioAtTick",
|
|
46
|
+
value: function getSqrtRatioAtTick(tick) {
|
|
47
|
+
// Check cache first
|
|
48
|
+
const cached = sqrtRatioCache.get(tick);
|
|
49
|
+
if (cached !== undefined) {
|
|
50
|
+
return cached;
|
|
51
|
+
}
|
|
33
52
|
(0, _tinyInvariant.default)(tick >= TickMath.MIN_TICK && tick <= TickMath.MAX_TICK && Number.isInteger(tick), "TICK");
|
|
34
53
|
const absTick = tick < 0 ? tick * -1 : tick;
|
|
35
54
|
let ratio = (absTick & 0x1) != 0 ? BigInt("0xfffcb933bd6fad37aa2d162d1a594001") : BigInt("0x100000000000000000000000000000000");
|
|
@@ -55,7 +74,11 @@ let TickMath = exports.TickMath = /*#__PURE__*/function () {
|
|
|
55
74
|
if (tick > 0) ratio = _internalConstants.MaxUint256 / ratio;
|
|
56
75
|
|
|
57
76
|
// back to Q64
|
|
58
|
-
|
|
77
|
+
const result = ratio % _internalConstants.Q64 > _internalConstants.ZERO ? ratio / _internalConstants.Q64 + _internalConstants.ONE : ratio / _internalConstants.Q64;
|
|
78
|
+
|
|
79
|
+
// Store in cache
|
|
80
|
+
sqrtRatioCache.set(tick, result);
|
|
81
|
+
return result;
|
|
59
82
|
}
|
|
60
83
|
|
|
61
84
|
/**
|
|
@@ -66,6 +89,12 @@ let TickMath = exports.TickMath = /*#__PURE__*/function () {
|
|
|
66
89
|
}, {
|
|
67
90
|
key: "getTickAtSqrtRatio",
|
|
68
91
|
value: function getTickAtSqrtRatio(sqrtRatioX64) {
|
|
92
|
+
// Check cache first
|
|
93
|
+
const cacheKey = sqrtRatioX64.toString();
|
|
94
|
+
const cached = tickAtSqrtRatioCache.get(cacheKey);
|
|
95
|
+
if (cached !== undefined) {
|
|
96
|
+
return cached;
|
|
97
|
+
}
|
|
69
98
|
(0, _tinyInvariant.default)(sqrtRatioX64 >= TickMath.MIN_SQRT_RATIO && sqrtRatioX64 < TickMath.MAX_SQRT_RATIO, "SQRT_RATIO");
|
|
70
99
|
const sqrtRatioX128 = sqrtRatioX64 << 64n;
|
|
71
100
|
const msb = (0, _mostSignificantBit.mostSignificantBit)(sqrtRatioX128);
|
|
@@ -85,7 +114,11 @@ let TickMath = exports.TickMath = /*#__PURE__*/function () {
|
|
|
85
114
|
const log_sqrt10001 = log_2 * 255738958999603826347141n;
|
|
86
115
|
const tickLow = Number(log_sqrt10001 - 3402992956809132418596140100660247210n >> 128n);
|
|
87
116
|
const tickHigh = Number(log_sqrt10001 + 291339464771989622907027621153398088495n >> 128n);
|
|
88
|
-
|
|
117
|
+
const result = tickLow === tickHigh ? tickLow : TickMath.getSqrtRatioAtTick(tickHigh) <= sqrtRatioX64 ? tickHigh : tickLow;
|
|
118
|
+
|
|
119
|
+
// Store in cache
|
|
120
|
+
tickAtSqrtRatioCache.set(cacheKey, result);
|
|
121
|
+
return result;
|
|
89
122
|
}
|
|
90
123
|
}]);
|
|
91
124
|
}();
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Token, Pool, Route, Trade } from '../entities';
|
|
2
|
+
import { CurrencyAmount } from '../entities/fractions';
|
|
3
|
+
import { TradeType } from '../internalConstants';
|
|
4
|
+
/**
|
|
5
|
+
* WASM-accelerated trade calculator
|
|
6
|
+
*/
|
|
7
|
+
export declare class WASMTradeCalculator {
|
|
8
|
+
private initialized;
|
|
9
|
+
private poolsMap;
|
|
10
|
+
/**
|
|
11
|
+
* Initialize with pools including full swap data
|
|
12
|
+
*/
|
|
13
|
+
initializeWithPools(pools: Pool[]): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Calculate trade output for a single route (WASM-accelerated)
|
|
16
|
+
*/
|
|
17
|
+
calculateTradeOutput(route: Route<Token, Token>, amountIn: CurrencyAmount<Token>): {
|
|
18
|
+
amountOut: CurrencyAmount<Token>;
|
|
19
|
+
priceImpact: number;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Batch calculate trades for multiple routes and amounts
|
|
23
|
+
*/
|
|
24
|
+
calculateTradesBatch(routes: Route<Token, Token>[], amounts: CurrencyAmount<Token>[]): Array<{
|
|
25
|
+
route: Route<Token, Token>;
|
|
26
|
+
amountIn: CurrencyAmount<Token>;
|
|
27
|
+
amountOut: CurrencyAmount<Token>;
|
|
28
|
+
priceImpact: number;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Clear all pools from memory
|
|
32
|
+
*/
|
|
33
|
+
clear(): void;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a WASM-accelerated Trade from a route
|
|
37
|
+
*/
|
|
38
|
+
export declare function createTradeFromRouteWASM(route: Route<Token, Token>, amount: CurrencyAmount<Token>, tradeType: TradeType, pools: Pool[]): Promise<Trade<Token, Token, TradeType>>;
|
|
39
|
+
/**
|
|
40
|
+
* Find best trade with split using WASM acceleration
|
|
41
|
+
*/
|
|
42
|
+
export declare function bestTradeWithSplitWASM(routes: Route<Token, Token>[], amount: CurrencyAmount<Token>, percents: number[], tradeType: TradeType, pools: Pool[], swapConfig?: {
|
|
43
|
+
minSplits: number;
|
|
44
|
+
maxSplits: number;
|
|
45
|
+
}): Promise<Trade<Token, Token, TradeType> | null>;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.WASMTradeCalculator = void 0;
|
|
7
|
+
exports.bestTradeWithSplitWASM = bestTradeWithSplitWASM;
|
|
8
|
+
exports.createTradeFromRouteWASM = createTradeFromRouteWASM;
|
|
9
|
+
var _entities = require("../entities");
|
|
10
|
+
var _fractions = require("../entities/fractions");
|
|
11
|
+
var _internalConstants = require("../internalConstants");
|
|
12
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
13
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
14
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
15
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
16
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
17
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
18
|
+
// WASM module - lazy loaded
|
|
19
|
+
let wasmModule = null;
|
|
20
|
+
function loadWasmModule() {
|
|
21
|
+
if (!wasmModule) {
|
|
22
|
+
try {
|
|
23
|
+
wasmModule = require('./wasm_route_finder.js');
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error('Failed to load WASM module:', error);
|
|
26
|
+
throw new Error('WASM module not available');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return wasmModule;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* WASM-accelerated trade calculator
|
|
34
|
+
*/
|
|
35
|
+
let WASMTradeCalculator = exports.WASMTradeCalculator = /*#__PURE__*/function () {
|
|
36
|
+
function WASMTradeCalculator() {
|
|
37
|
+
_classCallCheck(this, WASMTradeCalculator);
|
|
38
|
+
_defineProperty(this, "initialized", false);
|
|
39
|
+
_defineProperty(this, "poolsMap", new Map());
|
|
40
|
+
}
|
|
41
|
+
return _createClass(WASMTradeCalculator, [{
|
|
42
|
+
key: "initializeWithPools",
|
|
43
|
+
value:
|
|
44
|
+
/**
|
|
45
|
+
* Initialize with pools including full swap data
|
|
46
|
+
*/
|
|
47
|
+
async function initializeWithPools(pools) {
|
|
48
|
+
loadWasmModule();
|
|
49
|
+
|
|
50
|
+
// Build pool map for fast lookup
|
|
51
|
+
this.poolsMap.clear();
|
|
52
|
+
for (const pool of pools) {
|
|
53
|
+
this.poolsMap.set(pool.id, pool);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Convert pools to format needed by WASM (including swap data)
|
|
57
|
+
const wasmPools = pools.map(pool => {
|
|
58
|
+
// Extract ticks from tickDataProvider if available
|
|
59
|
+
let ticks = [];
|
|
60
|
+
const tickProvider = pool.tickDataProvider;
|
|
61
|
+
if (tickProvider && tickProvider.ticks) {
|
|
62
|
+
ticks = tickProvider.ticks.map(tick => ({
|
|
63
|
+
id: tick.id || tick.index,
|
|
64
|
+
index: tick.id || tick.index,
|
|
65
|
+
liquidityNet: (tick.liquidityNet || '0').toString(),
|
|
66
|
+
liquidityGross: (tick.liquidityGross || '0').toString()
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
id: String(pool.id),
|
|
71
|
+
token_a: {
|
|
72
|
+
id: pool.tokenA.id
|
|
73
|
+
},
|
|
74
|
+
token_b: {
|
|
75
|
+
id: pool.tokenB.id
|
|
76
|
+
},
|
|
77
|
+
fee: pool.fee,
|
|
78
|
+
sqrtPriceX64: pool.sqrtPriceX64.toString(),
|
|
79
|
+
liquidity: pool.liquidity.toString(),
|
|
80
|
+
tickCurrent: pool.tickCurrent,
|
|
81
|
+
ticks
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Initialize pools with full data in WASM
|
|
86
|
+
wasmModule.init_pools_with_data(wasmPools);
|
|
87
|
+
this.initialized = true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Calculate trade output for a single route (WASM-accelerated)
|
|
92
|
+
*/
|
|
93
|
+
}, {
|
|
94
|
+
key: "calculateTradeOutput",
|
|
95
|
+
value: function calculateTradeOutput(route, amountIn) {
|
|
96
|
+
if (!this.initialized) {
|
|
97
|
+
throw new Error('WASMTradeCalculator not initialized');
|
|
98
|
+
}
|
|
99
|
+
const poolIds = new Uint32Array(route.pools.map(p => p.id));
|
|
100
|
+
const result = wasmModule.calculate_trade_output(poolIds, amountIn.quotient.toString(), route.input.id);
|
|
101
|
+
|
|
102
|
+
// Check if result is valid
|
|
103
|
+
// The result might be a Map or an object depending on wasm-bindgen
|
|
104
|
+
let amountOutValue;
|
|
105
|
+
let priceImpactValue = 0;
|
|
106
|
+
if (result instanceof Map) {
|
|
107
|
+
amountOutValue = result.get('amountOut');
|
|
108
|
+
priceImpactValue = result.get('priceImpact') || 0;
|
|
109
|
+
} else if (result && typeof result === 'object') {
|
|
110
|
+
amountOutValue = result.amountOut;
|
|
111
|
+
priceImpactValue = result.priceImpact || 0;
|
|
112
|
+
}
|
|
113
|
+
if (!amountOutValue) {
|
|
114
|
+
console.error('WASM returned invalid result:', result);
|
|
115
|
+
throw new Error('WASM trade calculation failed - no amountOut');
|
|
116
|
+
}
|
|
117
|
+
const amountOut = _fractions.CurrencyAmount.fromRawAmount(route.output, BigInt(amountOutValue));
|
|
118
|
+
return {
|
|
119
|
+
amountOut,
|
|
120
|
+
priceImpact: priceImpactValue
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Batch calculate trades for multiple routes and amounts
|
|
126
|
+
*/
|
|
127
|
+
}, {
|
|
128
|
+
key: "calculateTradesBatch",
|
|
129
|
+
value: function calculateTradesBatch(routes, amounts) {
|
|
130
|
+
var _routes$;
|
|
131
|
+
if (!this.initialized) {
|
|
132
|
+
throw new Error('WASMTradeCalculator not initialized');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Convert routes to pool ID arrays
|
|
136
|
+
const routePoolIds = routes.map(route => route.pools.map(p => p.id));
|
|
137
|
+
|
|
138
|
+
// Convert amounts to strings
|
|
139
|
+
const amountStrings = amounts.map(a => a.quotient.toString());
|
|
140
|
+
|
|
141
|
+
// Assume all routes have same input token
|
|
142
|
+
const tokenInId = ((_routes$ = routes[0]) === null || _routes$ === void 0 ? void 0 : _routes$.input.id) || '';
|
|
143
|
+
const results = wasmModule.calculate_trades_for_routes(routePoolIds, amountStrings, tokenInId);
|
|
144
|
+
const trades = [];
|
|
145
|
+
let resultIdx = 0;
|
|
146
|
+
for (const route of routes) {
|
|
147
|
+
for (const amount of amounts) {
|
|
148
|
+
const result = results[resultIdx++];
|
|
149
|
+
if (result.success) {
|
|
150
|
+
trades.push({
|
|
151
|
+
route,
|
|
152
|
+
amountIn: amount,
|
|
153
|
+
amountOut: _fractions.CurrencyAmount.fromRawAmount(route.output, BigInt(result.amountOut)),
|
|
154
|
+
priceImpact: result.priceImpact
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return trades;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Clear all pools from memory
|
|
164
|
+
*/
|
|
165
|
+
}, {
|
|
166
|
+
key: "clear",
|
|
167
|
+
value: function clear() {
|
|
168
|
+
if (this.initialized) {
|
|
169
|
+
wasmModule.clear_pools();
|
|
170
|
+
this.poolsMap.clear();
|
|
171
|
+
this.initialized = false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}]);
|
|
175
|
+
}();
|
|
176
|
+
/**
|
|
177
|
+
* Create a WASM-accelerated Trade from a route
|
|
178
|
+
*/
|
|
179
|
+
async function createTradeFromRouteWASM(route, amount, tradeType, pools) {
|
|
180
|
+
const calculator = new WASMTradeCalculator();
|
|
181
|
+
await calculator.initializeWithPools(pools);
|
|
182
|
+
try {
|
|
183
|
+
if (tradeType === _internalConstants.TradeType.EXACT_INPUT) {
|
|
184
|
+
const {
|
|
185
|
+
amountOut
|
|
186
|
+
} = calculator.calculateTradeOutput(route, amount);
|
|
187
|
+
return _entities.Trade.createUncheckedTrade({
|
|
188
|
+
route,
|
|
189
|
+
inputAmount: amount,
|
|
190
|
+
outputAmount: amountOut,
|
|
191
|
+
tradeType: _internalConstants.TradeType.EXACT_INPUT,
|
|
192
|
+
percent: 100
|
|
193
|
+
});
|
|
194
|
+
} else {
|
|
195
|
+
// For EXACT_OUTPUT, we'd need to implement reverse calculation
|
|
196
|
+
// For now, fall back to JS implementation
|
|
197
|
+
return _entities.Trade.fromRoute(route, amount, tradeType);
|
|
198
|
+
}
|
|
199
|
+
} finally {
|
|
200
|
+
calculator.clear();
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Find best trade with split using WASM acceleration
|
|
206
|
+
*/
|
|
207
|
+
async function bestTradeWithSplitWASM(routes, amount, percents, tradeType, pools) {
|
|
208
|
+
let swapConfig = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {
|
|
209
|
+
minSplits: 1,
|
|
210
|
+
maxSplits: 10
|
|
211
|
+
};
|
|
212
|
+
const calculator = new WASMTradeCalculator();
|
|
213
|
+
await calculator.initializeWithPools(pools);
|
|
214
|
+
try {
|
|
215
|
+
// Calculate all split amounts
|
|
216
|
+
const splitAmounts = percents.map(percent => _fractions.CurrencyAmount.fromRawAmount(amount.currency, amount.quotient * BigInt(percent) / 100n));
|
|
217
|
+
|
|
218
|
+
// Batch calculate all trades
|
|
219
|
+
const allTrades = calculator.calculateTradesBatch(routes, splitAmounts);
|
|
220
|
+
|
|
221
|
+
// Group trades by percent
|
|
222
|
+
const tradesByPercent = {};
|
|
223
|
+
let tradeIdx = 0;
|
|
224
|
+
for (let i = 0; i < percents.length; i++) {
|
|
225
|
+
const percent = percents[i];
|
|
226
|
+
tradesByPercent[percent] = [];
|
|
227
|
+
for (const route of routes) {
|
|
228
|
+
const tradeDat = allTrades[tradeIdx++];
|
|
229
|
+
if (tradeDat) {
|
|
230
|
+
const trade = _entities.Trade.createUncheckedTrade({
|
|
231
|
+
route: tradeDat.route,
|
|
232
|
+
inputAmount: tradeDat.amountIn,
|
|
233
|
+
outputAmount: tradeDat.amountOut,
|
|
234
|
+
tradeType,
|
|
235
|
+
percent
|
|
236
|
+
});
|
|
237
|
+
tradesByPercent[percent].push(trade);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Use existing getBestSwapRoute logic
|
|
243
|
+
const {
|
|
244
|
+
getBestSwapRoute
|
|
245
|
+
} = require('./getBestSwapRoute');
|
|
246
|
+
const bestTrades = getBestSwapRoute(tradeType, tradesByPercent, percents, swapConfig);
|
|
247
|
+
if (!bestTrades) return null;
|
|
248
|
+
const routeData = bestTrades.map(trade => ({
|
|
249
|
+
inputAmount: trade.inputAmount,
|
|
250
|
+
outputAmount: trade.outputAmount,
|
|
251
|
+
route: trade.route,
|
|
252
|
+
percent: trade.swaps[0].percent
|
|
253
|
+
}));
|
|
254
|
+
return _entities.Trade.createUncheckedTradeWithMultipleRoutes({
|
|
255
|
+
routes: routeData,
|
|
256
|
+
tradeType
|
|
257
|
+
});
|
|
258
|
+
} finally {
|
|
259
|
+
calculator.clear();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
@@ -226,6 +226,67 @@ module.exports.get_pool_count = function() {
|
|
|
226
226
|
return ret >>> 0;
|
|
227
227
|
};
|
|
228
228
|
|
|
229
|
+
/**
|
|
230
|
+
* @param {any} pools_js
|
|
231
|
+
*/
|
|
232
|
+
module.exports.init_pools_with_data = function(pools_js) {
|
|
233
|
+
const ret = wasm.init_pools_with_data(pools_js);
|
|
234
|
+
if (ret[1]) {
|
|
235
|
+
throw takeFromExternrefTable0(ret[0]);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
let cachedUint32ArrayMemory0 = null;
|
|
240
|
+
|
|
241
|
+
function getUint32ArrayMemory0() {
|
|
242
|
+
if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
|
|
243
|
+
cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
|
|
244
|
+
}
|
|
245
|
+
return cachedUint32ArrayMemory0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function passArray32ToWasm0(arg, malloc) {
|
|
249
|
+
const ptr = malloc(arg.length * 4, 4) >>> 0;
|
|
250
|
+
getUint32ArrayMemory0().set(arg, ptr / 4);
|
|
251
|
+
WASM_VECTOR_LEN = arg.length;
|
|
252
|
+
return ptr;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* @param {Uint32Array} route_pool_ids
|
|
256
|
+
* @param {string} amount_in
|
|
257
|
+
* @param {string} token_in_id
|
|
258
|
+
* @returns {any}
|
|
259
|
+
*/
|
|
260
|
+
module.exports.calculate_trade_output = function(route_pool_ids, amount_in, token_in_id) {
|
|
261
|
+
const ptr0 = passArray32ToWasm0(route_pool_ids, wasm.__wbindgen_malloc);
|
|
262
|
+
const len0 = WASM_VECTOR_LEN;
|
|
263
|
+
const ptr1 = passStringToWasm0(amount_in, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
264
|
+
const len1 = WASM_VECTOR_LEN;
|
|
265
|
+
const ptr2 = passStringToWasm0(token_in_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
266
|
+
const len2 = WASM_VECTOR_LEN;
|
|
267
|
+
const ret = wasm.calculate_trade_output(ptr0, len0, ptr1, len1, ptr2, len2);
|
|
268
|
+
if (ret[2]) {
|
|
269
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
270
|
+
}
|
|
271
|
+
return takeFromExternrefTable0(ret[0]);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* @param {any} routes_js
|
|
276
|
+
* @param {any} amounts_js
|
|
277
|
+
* @param {string} token_in_id
|
|
278
|
+
* @returns {any}
|
|
279
|
+
*/
|
|
280
|
+
module.exports.calculate_trades_for_routes = function(routes_js, amounts_js, token_in_id) {
|
|
281
|
+
const ptr0 = passStringToWasm0(token_in_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
282
|
+
const len0 = WASM_VECTOR_LEN;
|
|
283
|
+
const ret = wasm.calculate_trades_for_routes(routes_js, amounts_js, ptr0, len0);
|
|
284
|
+
if (ret[2]) {
|
|
285
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
286
|
+
}
|
|
287
|
+
return takeFromExternrefTable0(ret[0]);
|
|
288
|
+
};
|
|
289
|
+
|
|
229
290
|
module.exports.__wbg_buffer_609cc3eee51ed158 = function(arg0) {
|
|
230
291
|
const ret = arg0.buffer;
|
|
231
292
|
return ret;
|
|
@@ -314,6 +375,20 @@ module.exports.__wbg_length_e2d2a49132c1b256 = function(arg0) {
|
|
|
314
375
|
return ret;
|
|
315
376
|
};
|
|
316
377
|
|
|
378
|
+
module.exports.__wbg_log_c222819a41e063d3 = function(arg0) {
|
|
379
|
+
console.log(arg0);
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
module.exports.__wbg_new_405e22f390576ce2 = function() {
|
|
383
|
+
const ret = new Object();
|
|
384
|
+
return ret;
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
module.exports.__wbg_new_5e0be73521bc8c17 = function() {
|
|
388
|
+
const ret = new Map();
|
|
389
|
+
return ret;
|
|
390
|
+
};
|
|
391
|
+
|
|
317
392
|
module.exports.__wbg_new_78feb108b6472713 = function() {
|
|
318
393
|
const ret = new Array();
|
|
319
394
|
return ret;
|
|
@@ -338,15 +413,29 @@ module.exports.__wbg_set_37837023f3d740e8 = function(arg0, arg1, arg2) {
|
|
|
338
413
|
arg0[arg1 >>> 0] = arg2;
|
|
339
414
|
};
|
|
340
415
|
|
|
416
|
+
module.exports.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {
|
|
417
|
+
arg0[arg1] = arg2;
|
|
418
|
+
};
|
|
419
|
+
|
|
341
420
|
module.exports.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) {
|
|
342
421
|
arg0.set(arg1, arg2 >>> 0);
|
|
343
422
|
};
|
|
344
423
|
|
|
424
|
+
module.exports.__wbg_set_8fc6bf8a5b1071d1 = function(arg0, arg1, arg2) {
|
|
425
|
+
const ret = arg0.set(arg1, arg2);
|
|
426
|
+
return ret;
|
|
427
|
+
};
|
|
428
|
+
|
|
345
429
|
module.exports.__wbg_value_cd1ffa7b1ab794f1 = function(arg0) {
|
|
346
430
|
const ret = arg0.value;
|
|
347
431
|
return ret;
|
|
348
432
|
};
|
|
349
433
|
|
|
434
|
+
module.exports.__wbindgen_as_number = function(arg0) {
|
|
435
|
+
const ret = +arg0;
|
|
436
|
+
return ret;
|
|
437
|
+
};
|
|
438
|
+
|
|
350
439
|
module.exports.__wbindgen_bigint_from_i64 = function(arg0) {
|
|
351
440
|
const ret = arg0;
|
|
352
441
|
return ret;
|
|
@@ -415,6 +504,11 @@ module.exports.__wbindgen_is_object = function(arg0) {
|
|
|
415
504
|
return ret;
|
|
416
505
|
};
|
|
417
506
|
|
|
507
|
+
module.exports.__wbindgen_is_string = function(arg0) {
|
|
508
|
+
const ret = typeof(arg0) === 'string';
|
|
509
|
+
return ret;
|
|
510
|
+
};
|
|
511
|
+
|
|
418
512
|
module.exports.__wbindgen_jsval_eq = function(arg0, arg1) {
|
|
419
513
|
const ret = arg0 === arg1;
|
|
420
514
|
return ret;
|
|
@@ -437,6 +531,11 @@ module.exports.__wbindgen_number_get = function(arg0, arg1) {
|
|
|
437
531
|
getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
|
|
438
532
|
};
|
|
439
533
|
|
|
534
|
+
module.exports.__wbindgen_number_new = function(arg0) {
|
|
535
|
+
const ret = arg0;
|
|
536
|
+
return ret;
|
|
537
|
+
};
|
|
538
|
+
|
|
440
539
|
module.exports.__wbindgen_string_get = function(arg0, arg1) {
|
|
441
540
|
const obj = arg1;
|
|
442
541
|
const ret = typeof(obj) === 'string' ? obj : undefined;
|
|
Binary file
|