"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SvmQuery = void 0;
var tslib_1 = require("tslib");
var assert_1 = tslib_1.__importDefault(require("assert"));
var kit_1 = require("@solana/kit");
var svm_1 = require("../../arch/svm");
var coingecko_1 = require("../../coingecko");
var constants_1 = require("../../constants");
var gasPriceOracle_1 = require("../../gasPriceOracle");
var utils_1 = require("../../utils");
var relayFeeCalculator_1 = require("../relayFeeCalculator");
var SvmQuery = (function () {
    function SvmQuery(provider, symbolMapping, spokePool, simulatedRelayerAddress, logger, coingeckoProApiKey, fixedGasPrice, coingeckoBaseCurrency) {
        if (coingeckoBaseCurrency === void 0) { coingeckoBaseCurrency = "eth"; }
        this.provider = provider;
        this.symbolMapping = symbolMapping;
        this.spokePool = spokePool;
        this.simulatedRelayerAddress = simulatedRelayerAddress;
        this.logger = logger;
        this.coingeckoProApiKey = coingeckoProApiKey;
        this.fixedGasPrice = fixedGasPrice;
        this.coingeckoBaseCurrency = coingeckoBaseCurrency;
        this.computeUnitEstimator = (0, kit_1.getComputeUnitEstimateForTransactionMessageFactory)({
            rpc: provider,
        });
    }
    SvmQuery.prototype.getGasCosts = function (relayData, relayer, options) {
        if (relayer === void 0) { relayer = (0, relayFeeCalculator_1.getDefaultRelayer)(relayData.destinationChainId); }
        if (options === void 0) { options = {}; }
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var destinationChainId, recipient, outputToken, exclusiveRelayer, _a, repaymentChainId, repaymentAddress, fillRelayTx, _b, computeUnitsConsumed, gasPriceEstimate, _c, _d, _e, gasPrice;
            return tslib_1.__generator(this, function (_f) {
                switch (_f.label) {
                    case 0:
                        destinationChainId = relayData.destinationChainId, recipient = relayData.recipient, outputToken = relayData.outputToken, exclusiveRelayer = relayData.exclusiveRelayer;
                        (0, assert_1.default)(recipient.isSVM(), "getGasCosts: recipient not an SVM address (".concat(recipient, ")"));
                        (0, assert_1.default)(outputToken.isSVM(), "getGasCosts: outputToken not an SVM address (".concat(outputToken, ")"));
                        (0, assert_1.default)(exclusiveRelayer.isSVM(), "getGasCosts: exclusiveRelayer not an SVM address (".concat(exclusiveRelayer, ")"));
                        (0, assert_1.default)(relayer.isSVM());
                        _a = [destinationChainId, relayer], repaymentChainId = _a[0], repaymentAddress = _a[1];
                        return [4, this.getFillRelayTx(tslib_1.__assign(tslib_1.__assign({}, relayData), { recipient: recipient, outputToken: outputToken, exclusiveRelayer: exclusiveRelayer }), (0, svm_1.SolanaVoidSigner)(relayer.toBase58()), repaymentChainId, repaymentAddress)];
                    case 1:
                        fillRelayTx = _f.sent();
                        _d = (_c = Promise).all;
                        _e = utils_1.toBN;
                        return [4, this.computeUnitEstimator(fillRelayTx)];
                    case 2: return [4, _d.apply(_c, [[
                                _e.apply(void 0, [_f.sent()]),
                                (0, gasPriceOracle_1.getGasPriceEstimate)(this.provider, {
                                    unsignedTx: fillRelayTx,
                                    baseFeeMultiplier: options.baseFeeMultiplier,
                                    priorityFeeMultiplier: options.priorityFeeMultiplier,
                                })
                            ]])];
                    case 3:
                        _b = _f.sent(), computeUnitsConsumed = _b[0], gasPriceEstimate = _b[1];
                        gasPrice = gasPriceEstimate.baseFee.add(gasPriceEstimate.microLamportsPerComputeUnit.mul(computeUnitsConsumed).div((0, utils_1.toBN)(1000000)));
                        return [2, {
                                nativeGasCost: computeUnitsConsumed,
                                tokenGasCost: gasPrice,
                                gasPrice: gasPrice,
                            }];
                }
            });
        });
    };
    SvmQuery.prototype.getNativeGasCost = function (deposit, relayer) {
        if (relayer === void 0) { relayer = (0, relayFeeCalculator_1.getDefaultRelayer)(deposit.destinationChainId); }
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var destinationChainId, recipient, outputToken, exclusiveRelayer, _a, repaymentChainId, repaymentAddress, fillRelayTx, _b;
            return tslib_1.__generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        destinationChainId = deposit.destinationChainId, recipient = deposit.recipient, outputToken = deposit.outputToken, exclusiveRelayer = deposit.exclusiveRelayer;
                        (0, assert_1.default)(recipient.isSVM(), "getNativeGasCost: recipient not an SVM address (".concat(recipient, ")"));
                        (0, assert_1.default)(outputToken.isSVM(), "getNativeGasCost: outputToken not an SVM address (".concat(outputToken, ")"));
                        (0, assert_1.default)(exclusiveRelayer.isSVM(), "getNativeGasCost: exclusiveRelayer not an SVM address (".concat(exclusiveRelayer, ")"));
                        (0, assert_1.default)(relayer.isSVM());
                        _a = [destinationChainId, relayer], repaymentChainId = _a[0], repaymentAddress = _a[1];
                        return [4, this.getFillRelayTx(tslib_1.__assign(tslib_1.__assign({}, deposit), { recipient: recipient, outputToken: outputToken, exclusiveRelayer: exclusiveRelayer }), (0, svm_1.SolanaVoidSigner)(relayer.toBase58()), repaymentChainId, repaymentAddress)];
                    case 1:
                        fillRelayTx = _c.sent();
                        _b = utils_1.toBN;
                        return [4, this.computeUnitEstimator(fillRelayTx)];
                    case 2: return [2, _b.apply(void 0, [_c.sent()])];
                }
            });
        });
    };
    SvmQuery.prototype.getFillRelayTx = function (relayData, signer, repaymentChainId, repaymentAddress) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            return tslib_1.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4, (0, svm_1.getFillRelayTx)(this.spokePool, this.provider, relayData, signer, repaymentChainId, repaymentAddress)];
                    case 1: return [2, _a.sent()];
                }
            });
        });
    };
    SvmQuery.prototype.getTokenPrice = function (tokenSymbol) {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var coingeckoInstance, _a, price;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!this.symbolMapping[tokenSymbol])
                            throw new Error("".concat(tokenSymbol, " does not exist in mapping"));
                        coingeckoInstance = coingecko_1.Coingecko.get(this.logger, this.coingeckoProApiKey);
                        return [4, coingeckoInstance.getCurrentPriceByContract(this.symbolMapping[tokenSymbol].addresses[constants_1.CHAIN_IDs.MAINNET], this.coingeckoBaseCurrency)];
                    case 1:
                        _a = _b.sent(), price = _a[1];
                        return [2, price];
                }
            });
        });
    };
    SvmQuery.prototype.getTokenDecimals = function (tokenSymbol) {
        if (!this.symbolMapping[tokenSymbol])
            throw new Error("".concat(tokenSymbol, " does not exist in mapping"));
        return this.symbolMapping[tokenSymbol].decimals;
    };
    return SvmQuery;
}());
exports.SvmQuery = SvmQuery;
//# sourceMappingURL=svmQuery.js.map