UNPKG

@xlink-network/xlink-sdk

Version:
186 lines (184 loc) 6.04 kB
import { checkNever } from "./chunk-E5Y3FGR6.mjs"; import { BigNumber } from "./chunk-KHTJNOQE.mjs"; import { concat, last, reduce } from "./chunk-PRLWYSC3.mjs"; // 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 ) ]); }; export { applyTransferProphets, applyTransferProphet, composeTransferProphets, composeTransferProphet2, composeRates2 }; //# sourceMappingURL=chunk-HJVY3USW.mjs.map