"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.messageFee = messageFee;
const utils_1 = require("../../utils");
const errors_1 = require("../errors");
const kit_1 = require("@solana/kit");
const MAX_BASE_FEE_ATTEMPTS = 2;
async function messageFee(provider, opts) {
    const { unsignedTx: _unsignedTx } = opts;
    const unsignedTx = _unsignedTx;
    const baseFee = await getBaseFee(provider, unsignedTx);
    const instructionAddresses = (0, utils_1.dedupArray)(unsignedTx.instructions.map((instruction) => instruction.programAddress));
    const recentPriorityFees = await provider.getRecentPrioritizationFees(instructionAddresses).send();
    const nonzeroPrioritizationFees = recentPriorityFees
        .slice(125)
        .map((value) => value.prioritizationFee)
        .filter((fee) => fee > 0);
    const totalPrioritizationFees = nonzeroPrioritizationFees.reduce((acc, fee) => acc + fee, BigInt(0));
    const microLamportsPerComputeUnit = (0, utils_1.toBN)(totalPrioritizationFees / BigInt(Math.max(nonzeroPrioritizationFees.length, 1)));
    return { baseFee, microLamportsPerComputeUnit };
}
async function getBaseFee(provider, tx) {
    for (let attempt = 0; attempt < MAX_BASE_FEE_ATTEMPTS; attempt++) {
        const { value: confirmedBlockhash } = await provider.getLatestBlockhash({ commitment: "confirmed" }).send();
        const refreshedTx = (0, kit_1.setTransactionMessageLifetimeUsingBlockhash)(confirmedBlockhash, tx);
        const compiled = (0, kit_1.compileTransaction)(refreshedTx);
        const encoded = Buffer.from(compiled.messageBytes).toString("base64");
        const { value } = await provider.getFeeForMessage(encoded).send();
        if (value !== null && value !== undefined) {
            return (0, utils_1.toBN)(value);
        }
    }
    throw new errors_1.SvmGasPriceUnavailableError("Solana getFeeForMessage returned null even after retrying with a confirmed blockhash");
}
//# sourceMappingURL=solana.js.map