"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.eip1559 = eip1559;
exports.eip1559Raw = eip1559Raw;
exports.feeHistory = feeHistory;
exports.legacy = legacy;
const tslib_1 = require("tslib");
const assert_1 = tslib_1.__importDefault(require("assert"));
const utils_1 = require("../../utils");
const util_1 = require("../util");
function eip1559(provider, opts) {
    return eip1559Raw(provider, opts.chainId, opts.baseFeeMultiplier, opts.priorityFeeMultiplier);
}
async function eip1559Raw(provider, chainId, baseFeeMultiplier, priorityFeeMultiplier) {
    const [{ baseFeePerGas }, _maxPriorityFeePerGas] = await Promise.all([
        provider.getBlock("latest"),
        provider.send("eth_maxPriorityFeePerGas", []),
    ]);
    const maxPriorityFeePerGas = utils_1.BigNumber.from(_maxPriorityFeePerGas);
    (0, assert_1.default)(utils_1.BigNumber.isBigNumber(baseFeePerGas), `No baseFeePerGas received on ${(0, utils_1.getNetworkName)(chainId)}`);
    const scaledPriorityFee = maxPriorityFeePerGas.mul(priorityFeeMultiplier).div(utils_1.fixedPointAdjustment);
    const scaledBaseFee = baseFeePerGas.mul(baseFeeMultiplier).div(utils_1.fixedPointAdjustment);
    return {
        maxFeePerGas: scaledPriorityFee.add(scaledBaseFee),
        maxPriorityFeePerGas: scaledPriorityFee,
    };
}
async function feeHistory(provider, opts) {
    const { baseFeeMultiplier, feeHistoryOptions } = opts;
    (0, assert_1.default)((0, utils_1.isDefined)(feeHistoryOptions));
    const { percentile = 20, blockLookback = 10, minimumPriority = utils_1.bnOne } = feeHistoryOptions;
    const [{ baseFeePerGas }, feeHistory] = await Promise.all([
        provider.getBlock("latest"),
        provider.send("eth_feeHistory", [
            Number(blockLookback),
            "latest",
            [Number(percentile)],
        ]),
    ]);
    (0, assert_1.default)(utils_1.BigNumber.isBigNumber(baseFeePerGas), "No baseFeePerGas received on latest block query.");
    const defaultEstimator = (rewards) => {
        const sortedRewards = rewards
            .map((reward) => (0, utils_1.toBN)(reward))
            .filter((reward) => reward.gt(utils_1.bnZero))
            .sort((r1, r2) => {
            if (r1.gt(r2)) {
                return 1;
            }
            return r1.eq(r2) ? 0 : -1;
        });
        const n = sortedRewards.length;
        if (n === 0) {
            return minimumPriority;
        }
        const median = n % 2 === 0 ? sortedRewards[n / 2 - 1].add(sortedRewards[n / 2]).div(2) : sortedRewards[Math.floor(n / 2)];
        return median.gt(minimumPriority) ? median : minimumPriority;
    };
    const { estimator = defaultEstimator } = feeHistoryOptions;
    const maxPriorityFeePerGas = estimator(feeHistory.reward);
    const scaledBaseFee = baseFeePerGas.mul(baseFeeMultiplier).div(utils_1.fixedPointAdjustment);
    return {
        maxFeePerGas: scaledBaseFee.add(maxPriorityFeePerGas),
        maxPriorityFeePerGas,
    };
}
async function legacy(provider, opts) {
    const { chainId, baseFeeMultiplier } = opts;
    const gasPrice = await provider.getGasPrice();
    if (!utils_1.BigNumber.isBigNumber(gasPrice) || gasPrice.lt(utils_1.bnZero))
        (0, util_1.gasPriceError)("getGasPrice()", chainId, gasPrice);
    return {
        maxFeePerGas: gasPrice.mul(baseFeeMultiplier).div(utils_1.fixedPointAdjustment),
        maxPriorityFeePerGas: utils_1.bnZero,
    };
}
//# sourceMappingURL=ethereum.js.map