"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getSamplesBetween = exports.calcApr = exports.calcPeriodicCompoundInterest = exports.calcContinuousCompoundInterest = exports.gasCost = exports.fixedPointAdjustment = exports.fromWei = exports.toBNWei = exports.bs58 = exports.keccak256 = exports.MAX_BIG_INT = exports.AddressZero = void 0;
exports.min = min;
exports.max = max;
exports.nativeToToken = nativeToToken;
exports.calculateGasFees = calculateGasFees;
exports.percent = percent;
exports.delay = delay;
exports.retry = retry;
exports.randomAddress = randomAddress;
const tslib_1 = require("tslib");
const decimal_js_1 = tslib_1.__importDefault(require("decimal.js"));
const bs58_1 = tslib_1.__importDefault(require("bs58"));
exports.bs58 = bs58_1.default;
const ethers_1 = require("ethers");
const BigNumberUtils_1 = require("./BigNumberUtils");
const FormattingUtils_1 = require("./FormattingUtils");
exports.AddressZero = ethers_1.ethers.constants.AddressZero;
exports.MAX_BIG_INT = BigNumberUtils_1.BigNumber.from(Number.MAX_SAFE_INTEGER.toString());
exports.keccak256 = ethers_1.ethers.utils.keccak256;
const toBNWei = (num, decimals) => {
    const numStr = num.toString();
    if (numStr.includes("e") || numStr.includes("E")) {
        const normalized = new decimal_js_1.default(numStr).toFixed();
        return (0, BigNumberUtils_1.parseUnits)(normalized, decimals);
    }
    return (0, BigNumberUtils_1.parseUnits)(num.toString(), decimals);
};
exports.toBNWei = toBNWei;
const fromWei = (num, decimals) => (0, BigNumberUtils_1.formatUnits)(num.toString(), decimals);
exports.fromWei = fromWei;
function min(a, b) {
    const bna = (0, BigNumberUtils_1.toBN)(a);
    const bnb = (0, BigNumberUtils_1.toBN)(b);
    return bna.lte(bnb) ? bna : bnb;
}
function max(a, b) {
    const bna = (0, BigNumberUtils_1.toBN)(a);
    const bnb = (0, BigNumberUtils_1.toBN)(b);
    return bna.gte(bnb) ? bna : bnb;
}
exports.fixedPointAdjustment = (0, exports.toBNWei)("1");
function nativeToToken(fromAmount, price = 1, toDecimals = 18, nativeDecimals = 18) {
    const priceWei = (0, exports.toBNWei)(price);
    const toAmount = (0, exports.toBNWei)(fromAmount).div(priceWei);
    return (0, FormattingUtils_1.ConvertDecimals)(nativeDecimals, toDecimals)(toAmount).toString();
}
const gasCost = (gas, gasPrice) => {
    return BigNumberUtils_1.BigNumber.from(gas).mul(gasPrice);
};
exports.gasCost = gasCost;
function calculateGasFees(gas, gasPrice, price = 1, decimals = 18) {
    const amountNative = (0, exports.gasCost)(gas, gasPrice);
    return nativeToToken(amountNative, price, decimals);
}
function percent(numerator, denominator) {
    return exports.fixedPointAdjustment.mul(numerator).div(denominator);
}
const calcContinuousCompoundInterest = (startAmount, endAmount, periodsElapsed, periodsPerYear) => {
    const years = new decimal_js_1.default(periodsPerYear).div(periodsElapsed);
    return new decimal_js_1.default(endAmount).div(startAmount).ln().div(years).toString();
};
exports.calcContinuousCompoundInterest = calcContinuousCompoundInterest;
const calcPeriodicCompoundInterest = (startAmount, endAmount, periodsElapsed, periodsPerYear) => {
    const n = new decimal_js_1.default(periodsPerYear);
    const A = new decimal_js_1.default(endAmount);
    const P = new decimal_js_1.default(startAmount);
    const t = new decimal_js_1.default(periodsPerYear).div(periodsElapsed);
    const one = new decimal_js_1.default(1);
    return n
        .mul(A.div(P)
        .pow(one.div(n.div(t)))
        .sub(one))
        .toFixed(18);
};
exports.calcPeriodicCompoundInterest = calcPeriodicCompoundInterest;
const calcApr = (startAmount, endAmount, periodsElapsed, periodsPerYear) => {
    return new decimal_js_1.default(endAmount).sub(startAmount).div(startAmount).mul(periodsPerYear).div(periodsElapsed).toFixed(18);
};
exports.calcApr = calcApr;
const getSamplesBetween = (min, max, size) => {
    let keepIterate = true;
    const intervals = [];
    while (keepIterate) {
        const to = Math.min(min + size - 1, max);
        intervals.push([min, to]);
        min = to + 1;
        if (min >= max)
            keepIterate = false;
    }
    return intervals;
};
exports.getSamplesBetween = getSamplesBetween;
function delay(seconds) {
    return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
function retry(call, times, _delayS) {
    let promiseChain = call();
    for (let i = 0; i < times; i++)
        promiseChain = promiseChain.catch(async () => {
            const delayS = _delayS ** i + Math.random();
            await delay(delayS);
            return await call();
        });
    return promiseChain;
}
function randomAddress() {
    return ethers_1.ethers.utils.getAddress(ethers_1.ethers.utils.hexlify(ethers_1.ethers.utils.randomBytes(20)));
}
//# sourceMappingURL=common.js.map