UNPKG

@xlink-network/xlink-sdk

Version:
481 lines (475 loc) 14.3 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/utils/feeRateHelpers.ts var feeRateHelpers_exports = {}; __export(feeRateHelpers_exports, { applyTransferProphet: () => applyTransferProphet, applyTransferProphets: () => applyTransferProphets, composeRates2: () => composeRates2, composeTransferProphet2: () => composeTransferProphet2, composeTransferProphets: () => composeTransferProphets }); module.exports = __toCommonJS(feeRateHelpers_exports); // src/utils/BigNumber.ts var import_big = require("big.js"); // src/utils/arrayHelpers.ts function last(ary) { return ary[ary.length - 1]; } var _concat = [].concat; function concat(...inputArrays) { return _concat.apply([], inputArrays); } var _reduce = [].reduce; function reduce(fn, initialValue, inputArray) { return _reduce.call(inputArray, fn, initialValue); } // src/utils/BigNumber.ts import_big.Big.PE = 21; import_big.Big.NE = -21; var toBig = (num) => { if (num instanceof import_big.Big) { return num; } return new import_big.Big(num); }; var fromBig = (num) => { return num; }; var BigNumber; ((BigNumber2) => { ({ roundUp: BigNumber2.roundUp, roundDown: BigNumber2.roundDown, roundHalfUp: BigNumber2.roundHalfUp, roundHalfEven: BigNumber2.roundHalfEven } = import_big.Big); let defaultRoundingMode = BigNumber2.roundHalfUp; BigNumber2.setDefaultRoundingMode = (roundingMode) => { defaultRoundingMode = roundingMode; }; BigNumber2.isBigNumber = (num) => { return num instanceof import_big.Big; }; BigNumber2.safeFrom = (value) => { try { return (0, BigNumber2.from)(value); } catch (e) { return void 0; } }; BigNumber2.from = (value) => { return fromBig(toBig(value)); }; BigNumber2.toString = (value) => { return toBig(value).toString(); }; BigNumber2.toNumber = (value) => { return toBig(value).toNumber(); }; BigNumber2.toBigInt = curry2( (options, value) => { return BigInt( (0, BigNumber2.toFixed)( { precision: 0, roundingMode: options.roundingMode ?? defaultRoundingMode }, toBig(value) ) ); } ); BigNumber2.toFixed = curry2( (options, value) => { return toBig(value).toFixed( options.precision, options.roundingMode ?? defaultRoundingMode ); } ); BigNumber2.toExponential = curry2( (options, value) => { return toBig(value).toExponential( options.precision, options.roundingMode ?? defaultRoundingMode ); } ); BigNumber2.isNegative = (value) => { return toBig(value).lt(0); }; BigNumber2.isGtZero = (value) => { return toBig(value).gt(0); }; BigNumber2.isZero = (value) => { return toBig(value).eq(0); }; BigNumber2.isEq = curry2( (value, a) => { return toBig(value).eq(toBig(a)); } ); BigNumber2.isGt = curry2( (value, a) => { return toBig(value).gt(toBig(a)); } ); BigNumber2.isGte = curry2( (value, a) => { return toBig(value).gte(toBig(a)); } ); BigNumber2.isLt = curry2( (value, a) => { return toBig(value).lt(toBig(a)); } ); BigNumber2.isLte = curry2( (value, a) => { return toBig(value).lte(toBig(a)); } ); BigNumber2.setPrecision = curry2( (options, value) => { return fromBig( toBig( toBig(value).toPrecision( options.precision, options.roundingMode ?? defaultRoundingMode ) ) ); } ); BigNumber2.getPrecision = (value) => { return toBig(value).c.length - (toBig(value).e + 1); }; BigNumber2.getIntegerLength = (value) => { return toBig(value).e + 1; }; BigNumber2.leftMoveDecimals = curry2( (distance, value) => (0, BigNumber2.moveDecimals)({ distance }, value) ); BigNumber2.rightMoveDecimals = curry2( (distance, value) => (0, BigNumber2.moveDecimals)({ distance: -distance }, value) ); BigNumber2.moveDecimals = curry2( (options, value) => { if (options.distance > 0) { return fromBig(toBig(value).div(10 ** options.distance)); } if (options.distance < 0) { return fromBig(toBig(value).mul(10 ** -options.distance)); } return (0, BigNumber2.from)(value); } ); BigNumber2.getDecimalPart = curry2( (options, value) => { const formatted = (0, BigNumber2.toFixed)( { precision: Math.min((0, BigNumber2.getPrecision)(value), options.precision), roundingMode: BigNumber2.roundDown }, value ); const [, decimals] = formatted.split("."); if (decimals == null) return void 0; return decimals; } ); BigNumber2.abs = (value) => { return fromBig(toBig(value).abs()); }; BigNumber2.neg = (value) => { return fromBig(toBig(value).neg()); }; BigNumber2.sqrt = (value) => { return fromBig(toBig(value).sqrt()); }; BigNumber2.add = curry2( (value, a) => { return fromBig(toBig(value).add(toBig(a))); } ); BigNumber2.minus = curry2( (value, a) => { return fromBig(toBig(value).minus(toBig(a))); } ); BigNumber2.mul = curry2( (value, a) => { return fromBig(toBig(value).mul(toBig(a))); } ); BigNumber2.cumulativeMul = curry2( (value, as) => { return reduce( (acc, currentRate) => [ ...acc, BigNumber2.mul(last(acc), currentRate) ], [(0, BigNumber2.from)(value)], as ); } ); BigNumber2.div = curry2( (value, a) => { return fromBig(toBig(value).div(toBig(a))); } ); BigNumber2.pow = curry2((value, a) => { return fromBig(toBig(value).pow(a)); }); BigNumber2.round = curry2( (options, value) => { return fromBig( toBig(value).round( options.precision, options.roundingMode ?? defaultRoundingMode ) ); } ); BigNumber2.toPrecision = curry2( (options, value) => { return toBig(value).toPrecision( options.precision, options.roundingMode ?? defaultRoundingMode ); } ); BigNumber2.ascend = curry2( (a, b) => (0, BigNumber2.isLt)(a, b) ? -1 : (0, BigNumber2.isGt)(a, b) ? 1 : 0 ); BigNumber2.descend = curry2( (a, b) => (0, BigNumber2.isLt)(a, b) ? 1 : (0, BigNumber2.isGt)(a, b) ? -1 : 0 ); BigNumber2.sort = (comparator, numbers) => { const _numbers = numbers.map((a) => fromBig(toBig(a))); _numbers.sort(comparator); return _numbers; }; BigNumber2.max = (numbers) => { return (0, BigNumber2.from)((0, BigNumber2.sort)(BigNumber2.descend, numbers)[0]); }; BigNumber2.min = (numbers) => { return (0, BigNumber2.from)((0, BigNumber2.sort)(BigNumber2.ascend, numbers)[0]); }; BigNumber2.clamp = (range, n) => { const [min2, max2] = range; if ((0, BigNumber2.isGte)(n, max2)) return max2; if ((0, BigNumber2.isLte)(n, min2)) return min2; return n; }; BigNumber2.sum = (numbers) => { return numbers.map((n) => fromBig(toBig(n))).reduce((acc, n) => (0, BigNumber2.add)(acc, n), BigNumber2.ZERO); }; BigNumber2.ZERO = BigNumber2.from(0); BigNumber2.ONE = BigNumber2.from(1); })(BigNumber || (BigNumber = {})); function curry2(fn) { return function(a, b) { if (arguments.length > 1) { return fn(a, b); } return (b2) => fn(a, b2); }; } // src/utils/typeHelpers.ts function checkNever(_x) { return; } function assertExclude(asserting, excluding) { return; } ((assertExclude2) => { assertExclude2.i = () => null; })(assertExclude || (assertExclude = {})); // src/utils/feeRateHelpers.ts var applyTransferProphets = (transferProphets, amount) => { return reduce( (acc, transferProphet) => concat(acc, [applyTransferProphet(transferProphet, last(acc).netAmount)]), [{ fees: [], netAmount: amount }], transferProphets ); }; var applyTransferProphet = (transferProphet, amount) => { const fees = []; let totalFeeAmount = BigNumber.ZERO; for (const f of transferProphet.fees) { let feeAmount = BigNumber.ZERO; if (f.type === "rate") { if (f.token !== transferProphet.bridgeToken) { throw new Error( `[XLinkSDK#applyTransferProphet] transferProphet.bridgeToken (${transferProphet.bridgeToken}) does not match rateFee.token (${f.token}), which is not expected` ); } feeAmount = BigNumber.max([ f.minimumAmount, BigNumber.mul(f.rate, amount) ]); fees.push({ ...f, amount: feeAmount }); } else if (f.type === "fixed") { if (f.token === transferProphet.bridgeToken) { feeAmount = f.amount; } fees.push(f); } else { checkNever(f); } totalFeeAmount = BigNumber.add(totalFeeAmount, feeAmount); } const netAmount = BigNumber.max([ BigNumber.ZERO, BigNumber.minus(amount, totalFeeAmount) ]); return { fees, netAmount }; }; var composeTransferProphets = (transferProphets, exchangeRates) => { const cumulativeExchangeRates = calcCumulativeExchangeRates(exchangeRates); return reduce( (res, transferProphet, idx) => ({ ...composeTransferProphet2( res, transferProphet, cumulativeExchangeRates[idx] ), transferProphets: [...res.transferProphets, transferProphet] }), composeTransferProphet2( transferProphets[0], transferProphets[1], cumulativeExchangeRates[0] ), transferProphets.slice(2) ); }; var calcCumulativeExchangeRates = (exchangeRates) => { return BigNumber.cumulativeMul(BigNumber.ONE, exchangeRates).slice(1); }; var composeTransferProphet2 = (transferProphet1, transferProphet2, exchangeRate) => { if (exchangeRate == null) { throw new Error( "[XLinkSDK#composeTransferProphet2] exchangeRate is required" ); } const bridgeTokenMinFeeAmount = BigNumber.sum([ ...transferProphet1.fees.flatMap( (f) => f.type === "rate" && f.token === transferProphet1.bridgeToken ? [f.minimumAmount] : [] ), ...transferProphet2.fees.flatMap( (f) => f.type === "rate" && f.token === transferProphet2.bridgeToken ? [ /** * convert to the denomination of the first step token */ BigNumber.div(f.minimumAmount, exchangeRate) ] : [] ) ]); const step1FlatFeeRate = BigNumber.minus( BigNumber.ONE, last( BigNumber.cumulativeMul( BigNumber.ONE, transferProphet1.fees.flatMap( (f) => f.type === "rate" && f.token === transferProphet1.bridgeToken ? [BigNumber.minus(1, f.rate)] : [] ) ) ) ); const step1ToStep2Rate = BigNumber.mul( BigNumber.minus(1, step1FlatFeeRate), exchangeRate ); let minBridgeAmount = null; if (BigNumber.isZero(bridgeTokenMinFeeAmount) && transferProphet1.minBridgeAmount == null && transferProphet2.minBridgeAmount == null) { minBridgeAmount = null; } else { minBridgeAmount = BigNumber.max([ bridgeTokenMinFeeAmount, transferProphet1.minBridgeAmount ?? 0, transferProphet2.minBridgeAmount == null ? 0 : BigNumber.div(transferProphet2.minBridgeAmount, step1ToStep2Rate) ]); } let maxBridgeAmount = null; if (transferProphet1.maxBridgeAmount == null && transferProphet2.maxBridgeAmount == null) { maxBridgeAmount = null; } else if (transferProphet1.maxBridgeAmount != null && transferProphet2.maxBridgeAmount != null) { maxBridgeAmount = BigNumber.min([ transferProphet1.maxBridgeAmount, BigNumber.div(transferProphet2.maxBridgeAmount, step1ToStep2Rate) ]); } else { maxBridgeAmount = transferProphet1.maxBridgeAmount ?? transferProphet2.maxBridgeAmount; } return { isPaused: transferProphet1.isPaused || transferProphet2.isPaused, bridgeToken: transferProphet1.bridgeToken, minBridgeAmount, maxBridgeAmount, fees: [ ...transferProphet1.fees, ...transferProphet2.fees.map((fee) => { if (fee.type === "fixed") { if (fee.token !== transferProphet2.bridgeToken) return fee; return { type: "fixed", token: transferProphet1.bridgeToken, amount: BigNumber.div(fee.amount, step1ToStep2Rate) }; } if (fee.type === "rate") { if (fee.token !== transferProphet2.bridgeToken) return fee; return { type: "rate", token: transferProphet1.bridgeToken, /** * feeAmount = step2Amount * fee.rate * feeAmount = (step1Amount * (1 - step1FlatFeeRate) * exchangeRate) * fee.rate * step1Amount * newFeeRate = (step1Amount * (1 - step1FlatFeeRate) * exchangeRate) * fee.rate * newFeeRate = (1 - step1FlatFeeRate) * exchangeRate * fee.rate * newFeeRate = step1ToStep2Rate * fee.rate */ rate: BigNumber.mul(step1ToStep2Rate, fee.rate), minimumAmount: BigNumber.div(fee.minimumAmount, step1ToStep2Rate) }; } checkNever(fee); return fee; }) ], transferProphets: [transferProphet1, transferProphet2] }; }; var composeRates2 = (rate1, rate2) => { return BigNumber.sum([ rate1, BigNumber.mul( BigNumber.minus(1, rate1), rate2 ) ]); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { applyTransferProphet, applyTransferProphets, composeRates2, composeTransferProphet2, composeTransferProphets }); //# sourceMappingURL=feeRateHelpers.js.map