@xlink-network/xlink-sdk
Version:
481 lines (475 loc) • 14.3 kB
JavaScript
;
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