"use strict";
/**
 * @file Comptroller
 * @desc These methods facilitate interactions with the Comptroller smart
 *     contract.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.redeemFaceValuePreview = exports.redeemFaceValueWithPermit = exports.redeemFaceValue = exports.exitMarket = exports.enterMarkets = void 0;
const eth = __importStar(require("./eth"));
const helpers_1 = require("./helpers");
const constants_1 = require("./constants");
const abi_1 = require("./abi");
const axios_1 = __importDefault(require("axios"));
const util_1 = require("./util");
const toSDRSymbol = (name) => {
    if (!name.startsWith('sdr')) {
        return 'sdr' + name;
    }
    return name;
};
const toUnderlySymbol = (name) => {
    if (name.startsWith('sdr')) {
        return name.slice(3);
    }
    return name;
};
/**
 * Enters the user's address into Sumer Protocol markets.
 *
 * @param {any[]} markets An array of strings of markets to enter, meaning use
 *     those supplied assets as collateral.
 * @param {CallOptions} [options] Call options and Ethers.js overrides for the
 *     transaction. A passed `gasLimit` will be used in both the `approve` (if
 *     not supressed) and `mint` transactions.
 *
 * @returns {object} Returns an Ethers.js transaction object of the enterMarkets
 *     transaction.
 *
 * @example
 *
 * ```
 * const sumer = new Sumer(window.ethereum);
 *
 * (async function () {
 *   const trx = await sumer.enterMarkets(Sumer.ETH); // Use [] for multiple
 *   console.log('Ethers.js transaction object', trx);
 * })().catch(console.error);
 * ```
 */
async function enterMarkets(markets = [], options = {}) {
    await (0, helpers_1.netId)(this);
    const errorPrefix = 'Sumer [enterMarkets] | ';
    if (typeof markets === 'string') {
        markets = [markets];
    }
    if (!Array.isArray(markets)) {
        throw Error(errorPrefix + 'Argument `markets` must be an array or string.');
    }
    const addresses = [];
    for (let i = 0; i < markets.length; i++) {
        markets[i] = toSDRSymbol(markets[i]);
        if (!(0, constants_1.isCTokenAllowed)(this._network.name, markets[i])) {
            throw Error(errorPrefix + 'Provided market `' + markets[i] + '` is not a recognized cToken.');
        }
        const cTokenAddress = (0, constants_1.getAddress)(this._network.name, markets[i]);
        addresses.push(cTokenAddress.toLowerCase());
    }
    const comptrollerAddress = (0, constants_1.getAddress)(this._network.name, 'Comptroller');
    const parameters = [addresses];
    // const comptroller = Comptroller__factory.connect(comptrollerAddress, this._provider)
    const trxOptions = Object.assign({ _sumerProvider: this._provider, abi: abi_1.abi.Comptroller }, options);
    // return (await comptroller.enterMarkets(addresses)).getTransaction
    return eth.trx(comptrollerAddress, 'enterMarkets', parameters, trxOptions);
}
exports.enterMarkets = enterMarkets;
/**
 * Exits the user's address from a Sumer Protocol market.
 *
 * @param {string} market A string of the symbol of the market to exit.
 * @param {CallOptions} [options] Call options and Ethers.js overrides for the
 *     transaction. A passed `gasLimit` will be used in both the `approve` (if
 *     not supressed) and `mint` transactions.
 *
 * @returns {object} Returns an Ethers.js transaction object of the exitMarket
 *     transaction.
 *
 * @example
 *
 * ```
 * const sumer = new Sumer(window.ethereum);
 *
 * (async function () {
 *   const trx = await sumer.exitMarket(Sumer.ETH);
 *   console.log('Ethers.js transaction object', trx);
 * })().catch(console.error);
 * ```
 */
async function exitMarket(market, options = {}) {
    await (0, helpers_1.netId)(this);
    const errorPrefix = 'Sumer [exitMarket] | ';
    if (typeof market !== 'string' || market === '') {
        throw Error(errorPrefix + 'Argument `market` must be a string of a cToken market name.');
    }
    market = toSDRSymbol(market);
    if (!(0, constants_1.isCTokenAllowed)(this._network.name, market)) {
        throw Error(errorPrefix + 'Provided market `' + market + '` is not a recognized cToken.');
    }
    const cTokenAddress = (0, constants_1.getAddress)(this._network.name, market);
    const comptrollerAddress = (0, constants_1.getAddress)(this._network.name, 'Comptroller');
    const parameters = [cTokenAddress.toLowerCase()];
    const trxOptions = Object.assign({ _sumerProvider: this._provider, abi: abi_1.abi.Comptroller }, options);
    return eth.trx(comptrollerAddress, 'exitMarket', parameters, trxOptions);
}
exports.exitMarket = exitMarket;
async function redeemFaceValue(market, amount, providers, deadline, signature, options = {}) {
    await (0, helpers_1.netId)(this);
    const errorPrefix = 'Sumer [redeemFaceValue] | ';
    if (typeof market !== 'string' || market === '') {
        throw Error(errorPrefix + 'Argument `market` must be a string of a cToken market name.');
    }
    market = toSDRSymbol(market);
    if (!(0, constants_1.isCTokenAllowed)(this._network.name, market)) {
        throw Error(errorPrefix + 'Provided market `' + market + '` is not a recognized cToken.');
    }
    const cTokenAddress = (0, constants_1.getAddress)(this._network.name, market);
    const redemptionManagerAddress = (0, constants_1.getAddress)(this._network.name, 'RedemptionManager');
    const parameters = [cTokenAddress.toLowerCase(), amount, providers, deadline, signature];
    const trxOptions = Object.assign({ _sumerProvider: this._provider, abi: abi_1.abi.RedemptionManager }, options);
    return eth.trx(redemptionManagerAddress, 'redeemFaceValue', parameters, trxOptions);
}
exports.redeemFaceValue = redeemFaceValue;
async function redeemFaceValueWithPermit(market, amount, providers, providersDeadline, providersSignature, options = {}) {
    await (0, helpers_1.netId)(this);
    const errorPrefix = 'Sumer [redeemFaceValueWithPermit] | ';
    if (typeof market !== 'string' || market === '') {
        throw Error(errorPrefix + 'Argument `market` must be a string of a cToken market name.');
    }
    const cTokenName = toSDRSymbol(market);
    if (!(0, constants_1.isCTokenAllowed)(this._network.name, cTokenName)) {
        throw Error(errorPrefix + 'Provided market `' + cTokenName + '` is not a recognized cToken.');
    }
    const tokenAddress = (0, constants_1.getAddress)(this._network.name, market);
    const cTokenAddress = (0, constants_1.getAddress)(this._network.name, cTokenName);
    const { signature, deadline } = await (0, util_1.getSignature)({
        signer: this._provider,
        tokenSymbol: market,
        chainId: this._network.id,
        verifyingContract: tokenAddress,
        spender: cTokenAddress,
        value: amount,
    });
    const parameters = [
        cTokenAddress.toLowerCase(),
        amount,
        providers,
        providersDeadline,
        providersSignature,
        deadline,
        signature,
    ];
    const trxOptions = Object.assign({ _sumerProvider: this._provider, abi: abi_1.abi.RedemptionManager }, options);
    const redemptionManagerAddress = (0, constants_1.getAddress)(this._network.name, 'RedemptionManager');
    return eth.trx(redemptionManagerAddress, 'redeemFaceValueWithPermit', parameters, trxOptions);
}
exports.redeemFaceValueWithPermit = redeemFaceValueWithPermit;
async function redeemFaceValuePreview(chainId, redeemer, market, amount) {
    const response = await axios_1.default.post(`https://api.meter.io:2000/api/${chainId}/${market}/redemptionPreview`, {
        redeemer,
        amount,
    });
    return response.data;
}
exports.redeemFaceValuePreview = redeemFaceValuePreview;
//# sourceMappingURL=comptroller.js.map