"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockPolygonGasStationPriorityFee = exports.MockPolygonGasStationBaseFee = exports.PolygonGasStation = void 0;
exports.gasStation = gasStation;
const baseAdapter_1 = require("../../priceClient/adapters/baseAdapter");
const utils_1 = require("../../utils");
const constants_1 = require("../../constants");
const util_1 = require("../util");
const ethereum_1 = require("./ethereum");
const { POLYGON } = constants_1.CHAIN_IDs;
class PolygonGasStation extends baseAdapter_1.BaseHTTPAdapter {
    chainId;
    constructor({ chainId = POLYGON, host, timeout = 1500, retries = 1 } = {}) {
        host = host ?? chainId === POLYGON ? "gasstation.polygon.technology" : "gasstation-testnet.polygon.technology";
        super("Polygon Gas Station", host, { timeout, retries });
        this.chainId = chainId;
    }
    async getFeeData(strategy = "fast") {
        const gas = await this.query("v2", {});
        const gasPrice = gas?.[strategy];
        if (!this.isPolygon1559GasPrice(gasPrice)) {
            (0, util_1.gasPriceError)("getFeeData()", this.chainId, utils_1.bnZero);
        }
        [gasPrice.maxFee, gasPrice.maxPriorityFee].forEach((gasPrice) => {
            if (Number(gasPrice) < 0) {
                (0, util_1.gasPriceError)("getFeeData()", this.chainId, (0, utils_1.parseUnits)(gasPrice.toString(), 9));
            }
        });
        const maxPriorityFeePerGas = (0, utils_1.parseUnits)(gasPrice.maxPriorityFee.toString(), 9);
        const maxFeePerGas = (0, utils_1.parseUnits)(gasPrice.maxFee.toString(), 9);
        return { maxPriorityFeePerGas, maxFeePerGas };
    }
    isPolygon1559GasPrice(gasPrice) {
        if (!(0, utils_1.isDefined)(gasPrice)) {
            return false;
        }
        const _gasPrice = gasPrice;
        return [_gasPrice.maxPriorityFee, _gasPrice.maxFee].every((field) => ["number", "string"].includes(typeof field));
    }
}
exports.PolygonGasStation = PolygonGasStation;
class MockRevertingPolygonGasStation extends PolygonGasStation {
    getFeeData() {
        throw new Error();
    }
}
const MockPolygonGasStationBaseFee = () => (0, utils_1.parseUnits)("12", 9);
exports.MockPolygonGasStationBaseFee = MockPolygonGasStationBaseFee;
const MockPolygonGasStationPriorityFee = () => (0, utils_1.parseUnits)("1", 9);
exports.MockPolygonGasStationPriorityFee = MockPolygonGasStationPriorityFee;
class MockPolygonGasStation extends PolygonGasStation {
    getFeeData() {
        return Promise.resolve({
            maxPriorityFeePerGas: (0, exports.MockPolygonGasStationPriorityFee)(),
            maxFeePerGas: (0, exports.MockPolygonGasStationBaseFee)().add((0, exports.MockPolygonGasStationPriorityFee)()),
        });
    }
}
async function gasStation(provider, opts) {
    const { chainId, baseFeeMultiplier, priorityFeeMultiplier } = opts;
    let gasStation;
    if (process.env.TEST_POLYGON_GAS_STATION === "true") {
        gasStation = new MockPolygonGasStation();
    }
    else if (process.env.TEST_REVERTING_POLYGON_GAS_STATION === "true") {
        gasStation = new MockRevertingPolygonGasStation();
    }
    else {
        gasStation = new PolygonGasStation({ chainId: chainId, timeout: 2000, retries: 0 });
    }
    let maxPriorityFeePerGas;
    let maxFeePerGas;
    try {
        ({ maxPriorityFeePerGas, maxFeePerGas } = await gasStation.getFeeData());
        const baseFeeMinusPriorityFee = maxFeePerGas.sub(maxPriorityFeePerGas);
        const scaledBaseFee = baseFeeMinusPriorityFee.mul(baseFeeMultiplier).div(utils_1.fixedPointAdjustment);
        const scaledPriorityFee = maxPriorityFeePerGas.mul(priorityFeeMultiplier).div(utils_1.fixedPointAdjustment);
        maxFeePerGas = scaledBaseFee.add(scaledPriorityFee);
        maxPriorityFeePerGas = scaledPriorityFee;
    }
    catch {
        ({ maxPriorityFeePerGas, maxFeePerGas } = await (0, ethereum_1.eip1559)(provider, opts));
        const minPriorityFee = (0, utils_1.parseUnits)("30", 9).mul(priorityFeeMultiplier).div(utils_1.fixedPointAdjustment);
        if (maxPriorityFeePerGas.lt(minPriorityFee)) {
            const priorityDelta = minPriorityFee.sub(maxPriorityFeePerGas);
            maxPriorityFeePerGas = minPriorityFee;
            maxFeePerGas = maxFeePerGas.add(priorityDelta);
        }
    }
    return { maxPriorityFeePerGas, maxFeePerGas };
}
//# sourceMappingURL=polygon.js.map