"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PricerApi = void 0;
const tslib_1 = require("tslib");
const axios_1 = tslib_1.__importDefault(require("axios"));
const logger_1 = require("../utils/logger");
const ethers_1 = require("ethers");
const order_1 = require("../utils/order");
class PricerApi {
    config;
    lastAssetPrice = {};
    lastAssetPriceTime = {};
    constructor(config) {
        this.config = config;
    }
    async fetchAssetPrice(asset, network) {
        const response = await axios_1.default.get(`${this.config.pricer.url}/prices/asset/${network}/${asset}`);
        return response.data;
    }
    async fetchAssetPriceInUSD(asset, networkId, amount) {
        try {
            const formattedAmount = amount.toString();
            const response = await axios_1.default.get(`${this.config.pricer.url}/prices/usd/${networkId}/${asset}/${formattedAmount}`);
            return response.data;
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            logger_1.logger.error({ error: errMsg }, '🚨 Could not fetch asset price in USD');
            return 0;
        }
    }
    async getFees() {
        try {
            const response = await axios_1.default.get(`${this.config.pricer.url}/prices/fees`);
            return response.data;
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            logger_1.logger.error({ error: errMsg }, '🚨 Could not get fees');
            throw new Error(errMsg);
        }
    }
    async getInsurance() {
        try {
            const response = await axios_1.default.get(`${this.config.pricer.url}/orders/insurance`);
            const insurance = response.data;
            return ethers_1.BigNumber.from(insurance);
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            logger_1.logger.error({ error: errMsg }, '🚨 Could not get latest insurance. Return 0.');
            return ethers_1.BigNumber.from(0);
        }
    }
    async estimate(fromAsset, toAsset, fromChain, toChain, amountWei, executorTipUSD, slippagePercentage) {
        try {
            const response = await axios_1.default.post(`${this.config.pricer.url}/estimate`, {
                fromAsset,
                toAsset,
                fromChain,
                toChain,
                amountWei,
                executorTipUSD,
                slippagePercentage,
            });
            return response.data;
        }
        catch (error) {
            let errMsg;
            if (error.response?.data?.errors) {
                errMsg = error.response.data.errors.map((err) => `${err.msg}: ${err.value}`).join(', ');
            }
            else {
                errMsg = error.response?.data?.error || error.message;
            }
            throw new Error(errMsg);
        }
    }
    async fetchExecutorPendingExecutions(executor) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/executor/${executor}/pending-executions`);
            const orders = [];
            for (const orderApi of res.data) {
                orders.push((0, order_1.constructOrderFromOrderApi)(orderApi));
            }
            return orders;
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            if (error.response && error.response.status === 429) {
                logger_1.logger.warn({ error: errMsg, context: 'fetchExecutorPendingExecutions' }, '🐢 Rate limit exceeded');
            }
            else {
                logger_1.logger.error({ error: errMsg, context: 'fetchExecutorPendingExecutions' }, '🚨 Could not fetch pending Executions');
            }
            throw new Error(errMsg);
        }
    }
    // Returns either a string or an array of DynamoOrderStatusEntry depending on the config.pricer.returnClaimsExtendedAsIds
    async fetchExecutorPendingClaims(executor) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/executor/${executor}/pending-claims`);
            return res.data;
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            if (error.response && error.response.status === 429) {
                logger_1.logger.warn({ error: errMsg, context: 'fetchExecutorPendingClaims' }, '🐢 Rate limit exceeded');
            }
            else {
                logger_1.logger.error({ error: errMsg, context: 'fetchExecutorPendingClaims' }, '🚨 Could not fetch pending Claims');
            }
            throw new Error(errMsg);
        }
    }
    /**
     * Fetches pending orders per executor from the pricer
     * @returns Array of orderIds or orders depending on groupedByDestinationAndMaxRewardDesc
     * @param groupedByDestinationAndMaxRewardDesc
     * @param currentNetworkNativeBalancesMap
     */
    async fetchOrdersPendingPerExecutor(address, _groupedByDestinationAndMaxRewardDesc = false, _currentNetworkNativeBalancesMap = {}) {
        try {
            let res;
            if (this.config.executor.fetchPendingOrdersShared) {
                res = await axios_1.default.get(`${this.config.pricer.url}/orders/pending`);
            }
            else {
                res = await axios_1.default.get(`${this.config.pricer.url}/executor/${address}/orders/pending`);
            }
            const orders = [];
            for (const orderApi of res.data) {
                orders.push((0, order_1.constructOrderFromOrderApi)(orderApi));
            }
            return orders;
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            // Dont log error on rate limit exceeded
            if (error.response && error.response.status === 429) {
                logger_1.logger.warn({ error: errMsg, context: 'fetchOrdersPendingPerExecutor' }, '🐢 Rate limit exceeded');
            }
            else {
                logger_1.logger.error({ err: JSON.stringify(error), error: errMsg, context: 'fetchOrdersPendingPerExecutor' }, '🚨 Could not fetch orders Pending');
            }
            throw new Error(errMsg);
        }
    }
    /**
     * Fetches pending orders from the pricer
     * @returns Array of orderIds or orders depending on groupedByDestinationAndMaxRewardDesc
     * @param groupedByDestinationAndMaxRewardDesc
     * @param currentNetworkNativeBalancesMap
     */
    async fetchOrdersPending(_groupedByDestinationAndMaxRewardDesc = false, _currentNetworkNativeBalancesMap = {}) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/orders/pending`);
            const orders = [];
            for (const orderApi of res.data) {
                orders.push((0, order_1.constructOrderFromOrderApi)(orderApi));
            }
            return orders;
        }
        catch (error) {
            const errMsg = error.response?.data?.error || error.message;
            // Dont log error on rate limit exceeded
            if (error.response && error.response.status === 429) {
                logger_1.logger.warn({ error: errMsg, context: 'fetchExecutorPendingExecutions' }, '🐢 Rate limit exceeded');
            }
            else {
                logger_1.logger.error({ err: JSON.stringify(error), error: errMsg, context: 'fetchExecutorPendingExecutions' }, '🚨 Could not fetch pending Bids');
            }
            throw new Error(errMsg);
        }
    }
    async fetchOrder(id) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/order/${id}`);
            return res.data;
        }
        catch (error_) {
            const error = error_.response?.data?.error || error_.message;
            logger_1.logger.error({ error, id }, '🚨 Could not fetch order');
            throw new Error(error);
        }
    }
    async fetchExecutorProcessingIntervals() {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/executor/intervals`);
            return res.data;
        }
        catch (error_) {
            const error = error_.response?.data?.error || error_.message;
            logger_1.logger.error({ error }, '🚨 Could not fetch executor processing intervals');
            throw new Error(error);
        }
    }
    async fetchExecutorCount(executor) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/executor/${executor}/count`);
            return res.data;
        }
        catch (error_) {
            const error = error_.response?.data?.error || error_.message;
            logger_1.logger.error({ error, executor }, '🚨 Could not fetch executor count');
            throw new Error(error);
        }
    }
    async fetchAllPrices() {
        const res = await axios_1.default.get(`${this.config.pricer.url}/prices/all`);
        return res.data;
    }
    async fetchExecutorConditions(executor) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/executor/${executor}/conditions`);
            return res.data;
        }
        catch (error_) {
            const error = error_.response?.data?.error || error_.message;
            logger_1.logger.error({ error, executor }, '🚨 Could not fetch executor conditions');
            throw new Error(error);
        }
    }
    async getAccountBalances(address) {
        try {
            const res = await axios_1.default.get(`${this.config.pricer.url}/account/tokens/balance/${address}`);
            return res.data;
        }
        catch (error_) {
            const error = error_.response?.data?.error || error_.message;
            logger_1.logger.error({ error, address }, '🚨 Could not get account balances');
            // propagate original error
            throw error_;
        }
    }
    async insertAIxecutor(id) {
        const res = await axios_1.default.post(`${this.config.pricer.url}/aixecutor`, { id });
        return res.data;
    }
}
exports.PricerApi = PricerApi;
//# sourceMappingURL=pricer-api.js.map