"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MempoolSpace = exports.MempoolSpaceClass = void 0;
const util_1 = __importDefault(require("util"));
const request_1 = __importDefault(require("request"));
const logger_1 = __importDefault(require("../../logger"));
class MempoolSpaceClass {
    constructor() {
        // TODO run our own mempool.space server
        this.feeUrls = {
            mainnet: 'https://mempool.space/api/v1/fees/recommended',
            testnet3: 'https://mempool.space/testnet/api/v1/fees/recommended',
            testnet4: 'https://mempool.space/testnet4/api/v1/fees/recommended'
        };
        this.cache = {
            mainnet: {
                timestamp: 0,
                response: null
            },
            testnet3: {
                timestamp: 0,
                response: null
            },
            testnet4: {
                timestamp: 0,
                response: null
            }
        };
        this.cacheTime = 1000 * 90; // 90 seconds
    }
    async getFee(network, nblocks) {
        network = network === 'regtest' ? 'testnet4' : network;
        if (this.cache[network] && this.cache[network].timestamp > Date.now() - this.cacheTime) {
            return this._getFeeLevel(this.cache[network].response, nblocks);
        }
        try {
            const res = await util_1.default.promisify(request_1.default.get).call(request_1.default, {
                uri: this.feeUrls[network],
                json: true
            });
            if (res.statusCode !== 200) {
                if (res.statusCode === 429) {
                    this.cacheTime += 1000 * 30; // add 30 seconds
                }
                throw new Error(`Status code: ${res.statusCode}`);
            }
            const fee = res.body;
            this.cache[network] = {
                timestamp: Date.now(),
                response: fee
            };
            return this._getFeeLevel(fee, nblocks);
        }
        catch (err) {
            logger_1.default.warn('Error getting fee from mempool.space: %o', err.message || err);
            throw err;
        }
    }
    _getFeeLevel(response, nblocks) {
        const avgBlockTime = nblocks * 10; // 10 minutes per block on avg
        if (avgBlockTime <= 10) { // 0 or 1 block
            return response.fastestFee;
        }
        else if (avgBlockTime <= 30) {
            return response.halfHourFee;
        }
        else if (avgBlockTime <= 60) {
            return response.hourFee;
        }
        else if (avgBlockTime <= 60 * 24) { // one day
            return response.economyFee;
        }
        else {
            return response.minimumFee;
        }
    }
}
exports.MempoolSpaceClass = MempoolSpaceClass;
;
exports.MempoolSpace = new MempoolSpaceClass();
//# sourceMappingURL=mempoolspace.js.map