UNPKG

@renproject/ren

Version:

Official Ren JavaScript SDK for bridging crypto assets cross-chain.

120 lines 5.93 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.estimateTransactionFee = exports.BIP_DENOMINATOR = void 0; const utils_1 = require("@renproject/utils"); const bignumber_js_1 = __importDefault(require("bignumber.js")); exports.BIP_DENOMINATOR = 10000; // Some assets may have their gas price defined in a different unit. const assetGasDivisors = { LUNA: 5, }; const estimateTransactionFee = async (renVM, asset, fromChain, toChain) => { // Determine if the transaction is a lock-and-mint, burn-and-release or // burn-and-mint. const [blockState, isLockAssetOnFromChain, isLockAssetOnToChain, isMintAssetOnFromChain, isMintAssetOnToChain, decimalsOnFromChain, decimalsOnToChain, isDepositAssetOnFromChain, isDepositAssetOnToChain,] = await Promise.all([ renVM.queryBlockState(asset, 5), fromChain.isLockAsset(asset), toChain.isLockAsset(asset), (0, utils_1.isContractChain)(fromChain) && fromChain.isMintAsset(asset), (0, utils_1.isContractChain)(toChain) && toChain.isMintAsset(asset), fromChain.assetDecimals(asset), toChain.assetDecimals(asset), (0, utils_1.isDepositChain)(fromChain) && fromChain.isDepositAsset(asset), (0, utils_1.isDepositChain)(toChain) && toChain.isDepositAsset(asset), ]); if (!isLockAssetOnFromChain && !isMintAssetOnFromChain) { throw utils_1.ErrorWithCode.updateError(new Error(`Asset not supported by chain ${fromChain.chain}.`), utils_1.RenJSError.PARAMETER_ERROR); } if (!isLockAssetOnToChain && !isMintAssetOnToChain) { throw utils_1.ErrorWithCode.updateError(new Error(`Asset not supported by chain ${toChain.chain}.`), utils_1.RenJSError.PARAMETER_ERROR); } const isLockAndMint = isLockAssetOnFromChain; const isBurnAndRelease = isLockAssetOnToChain; // const isBurnAndMint = isMintAssetOnFromChain && isMintAssetOnToChain; if (!blockState[asset]) { throw utils_1.ErrorWithCode.updateError(new Error(`No fee details found for ${asset}`), utils_1.RenJSError.UNKNOWN_ERROR); } const { gasLimit, gasCap, minimumAmount: minimumBeforeFees, dustAmount, } = blockState[asset]; // For burning, use the fees for the origin chain. For other txs, use // the fees for the target chain. const feesChain = isBurnAndRelease ? fromChain.chain : toChain.chain; const mintAndBurnFees = blockState[asset].fees.chains.filter((chainFees) => chainFees.chain === feesChain)[0]; // No other way of getting proper decimals for burn-and-mints. const nativeDecimals = Math.max(decimalsOnFromChain, decimalsOnToChain); const requiresTransfer = (isLockAndMint && isDepositAssetOnFromChain) || (isBurnAndRelease && isDepositAssetOnToChain); const fixedFee = requiresTransfer ? gasLimit .times(gasCap) .shiftedBy(-assetGasDivisors[asset] || 0) .plus(isBurnAndRelease ? dustAmount.plus(1) : 0) : new bignumber_js_1.default(0); const mintFee = mintAndBurnFees && mintAndBurnFees.mintFee ? mintAndBurnFees.mintFee.toNumber() : 15; const burnFee = mintAndBurnFees && mintAndBurnFees.burnFee ? mintAndBurnFees.burnFee.toNumber() : 15; const burnAndMintFee = mintAndBurnFees && mintAndBurnFees.burnAndMintFee ? mintAndBurnFees.burnAndMintFee.toNumber() : 15; const variableFee = isLockAndMint ? mintFee : isBurnAndRelease ? burnFee : burnAndMintFee; const minimumAmount = minimumBeforeFees .plus(fixedFee) .plus(minimumBeforeFees .plus(fixedFee) .times(variableFee) .dividedBy(exports.BIP_DENOMINATOR) .decimalPlaces(0, bignumber_js_1.default.ROUND_DOWN)); const estimateOutput = (input) => { const amount = bignumber_js_1.default.isBigNumber(input) || typeof input === "string" || typeof input === "number" ? input : input.amount; const convertUnit = typeof input === "object" && !bignumber_js_1.default.isBigNumber(input) ? input.convertUnit || false : false; const amountBN = new bignumber_js_1.default(amount).shiftedBy(convertUnit ? nativeDecimals : 0); if (amountBN.isLessThan(minimumAmount)) { return new bignumber_js_1.default(0); } if (isLockAndMint) { return bignumber_js_1.default.max(amountBN .minus(fixedFee) .times(exports.BIP_DENOMINATOR - variableFee) .dividedBy(exports.BIP_DENOMINATOR) .decimalPlaces(0, bignumber_js_1.default.ROUND_DOWN), 0).shiftedBy(convertUnit ? -nativeDecimals : 0); } else if (isBurnAndRelease) { return bignumber_js_1.default.max(amountBN .times(exports.BIP_DENOMINATOR - variableFee) .dividedBy(exports.BIP_DENOMINATOR) .minus(fixedFee) .decimalPlaces(0, bignumber_js_1.default.ROUND_DOWN), 0).shiftedBy(convertUnit ? -nativeDecimals : 0); } else { // Burn-and-mint transaction. If a fixed-fee is ever added for all // transactions, it will need to be added here. return bignumber_js_1.default.max(amountBN .times(exports.BIP_DENOMINATOR - variableFee) .dividedBy(exports.BIP_DENOMINATOR) .decimalPlaces(0, bignumber_js_1.default.ROUND_DOWN), 0).shiftedBy(convertUnit ? -nativeDecimals : 0); } }; return { fixedFee, variableFee, minimumAmount, estimateOutput, }; }; exports.estimateTransactionFee = estimateTransactionFee; //# sourceMappingURL=fees.js.map