"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const api_1 = require("@polkadot/api");
const monetary_js_1 = require("@interlay/monetary-js");
const chai_1 = require("chai");
const big_js_1 = __importDefault(require("big.js"));
const src_1 = require("../../../../../src");
const setup_1 = require("../../../../../src/utils/setup");
const config_1 = require("../../../../config");
const helpers_1 = require("../../../../utils/helpers");
describe("Initialize parachain state", () => {
    let api;
    let userInterBtcAPI;
    let sudoInterBtcAPI;
    let bitcoinCoreClient;
    let keyring;
    let sudoAccount;
    let userAccount;
    let vault_1;
    let vault_2;
    let vault_3;
    let vault_to_ban;
    let vault_to_liquidate;
    let collateralCurrency;
    function accountIdFromKeyring(keyPair) {
        return src_1.newAccountId(api, keyPair.address);
    }
    function waitForRegister(api, accountId, collateralCurrency) {
        return __awaiter(this, void 0, void 0, function* () {
            for (;;) {
                try {
                    yield api.get(accountId, collateralCurrency);
                    return;
                }
                catch (e) {
                    console.log(e);
                }
                yield helpers_1.sleep(helpers_1.SLEEP_TIME_MS);
            }
        });
    }
    before(function () {
        return __awaiter(this, void 0, void 0, function* () {
            api = yield src_1.createSubstrateAPI(config_1.PARACHAIN_ENDPOINT);
            keyring = new api_1.Keyring({ type: "sr25519" });
            sudoAccount = keyring.addFromUri(config_1.SUDO_URI);
            userAccount = keyring.addFromUri(config_1.USER_1_URI);
            vault_1 = keyring.addFromUri(config_1.VAULT_1_URI);
            vault_2 = keyring.addFromUri(config_1.VAULT_2_URI);
            vault_3 = keyring.addFromUri(config_1.VAULT_3_URI);
            vault_to_ban = keyring.addFromUri(config_1.VAULT_TO_BAN_URI);
            vault_to_liquidate = keyring.addFromUri(config_1.VAULT_TO_LIQUIDATE_URI);
            bitcoinCoreClient = new src_1.BitcoinCoreClient(config_1.BITCOIN_CORE_NETWORK, config_1.BITCOIN_CORE_HOST, config_1.BITCOIN_CORE_USERNAME, config_1.BITCOIN_CORE_PASSWORD, config_1.BITCOIN_CORE_PORT, config_1.BITCOIN_CORE_WALLET);
            userInterBtcAPI = new src_1.DefaultInterBtcApi(api, "regtest", userAccount, config_1.ESPLORA_BASE_PATH);
            sudoInterBtcAPI = new src_1.DefaultInterBtcApi(api, "regtest", sudoAccount, config_1.ESPLORA_BASE_PATH);
            collateralCurrency = src_1.getCorrespondingCollateralCurrencies(userInterBtcAPI.getGovernanceCurrency())[0];
            const collateralCurrencyLiteral = src_1.tickerToCurrencyIdLiteral(collateralCurrency.ticker);
            const vaultCollateralPairs = [
                [vault_1, collateralCurrencyLiteral],
                [vault_2, collateralCurrencyLiteral],
                [vault_3, collateralCurrencyLiteral],
                [vault_to_ban, collateralCurrencyLiteral],
                [vault_to_liquidate, collateralCurrencyLiteral],
            ];
            // wait for all vaults to register
            yield Promise.all(vaultCollateralPairs
                .map(([keyring, collateral]) => [
                accountIdFromKeyring(keyring),
                collateral,
            ])
                .map(([accountId, collateral]) => waitForRegister(userInterBtcAPI.vaults, accountId, collateral)));
        });
    });
    after(() => __awaiter(void 0, void 0, void 0, function* () {
        api.disconnect();
    }));
    it("should set the stable confirmations and ready the BTC-Relay", () => __awaiter(void 0, void 0, void 0, function* () {
        // Speed up the process by only requiring 0 parachain and 0 bitcoin confirmations
        const stableBitcoinConfirmationsToSet = 0;
        const stableParachainConfirmationsToSet = 0;
        let [stableBitcoinConfirmations, stableParachainConfirmations] = yield Promise.all([
            userInterBtcAPI.btcRelay.getStableBitcoinConfirmations(),
            userInterBtcAPI.btcRelay.getStableParachainConfirmations(),
        ]);
        if (stableBitcoinConfirmations != 0 || stableParachainConfirmations != 0) {
            yield setup_1.initializeStableConfirmations(api, {
                bitcoinConfirmations: stableBitcoinConfirmationsToSet,
                parachainConfirmations: stableParachainConfirmationsToSet,
            }, sudoAccount, bitcoinCoreClient);
            [stableBitcoinConfirmations, stableParachainConfirmations] = yield Promise.all([
                userInterBtcAPI.btcRelay.getStableBitcoinConfirmations(),
                userInterBtcAPI.btcRelay.getStableParachainConfirmations(),
            ]);
        }
        chai_1.assert.equal(stableBitcoinConfirmationsToSet, stableBitcoinConfirmations, "Setting the Bitcoin confirmations failed");
        chai_1.assert.equal(stableParachainConfirmationsToSet, stableParachainConfirmations, "Setting the Parachain confirmations failed");
    }));
    it("should set the exchange rate", () => __awaiter(void 0, void 0, void 0, function* () {
        function setCollateralExchangeRate(value, currency) {
            return __awaiter(this, void 0, void 0, function* () {
                const exchangeRate = new monetary_js_1.ExchangeRate(monetary_js_1.Bitcoin, currency, value);
                // result will be medianized
                yield setup_1.initializeExchangeRate(exchangeRate, sudoInterBtcAPI.oracle);
            });
        }
        yield setCollateralExchangeRate(helpers_1.getExchangeRateValueToSetForTesting(monetary_js_1.Polkadot), monetary_js_1.Polkadot);
        yield setCollateralExchangeRate(helpers_1.getExchangeRateValueToSetForTesting(monetary_js_1.Kusama), monetary_js_1.Kusama);
        yield setCollateralExchangeRate(helpers_1.getExchangeRateValueToSetForTesting(monetary_js_1.Kintsugi), monetary_js_1.Kintsugi);
    }));
    it("should set BTC tx fees", () => __awaiter(void 0, void 0, void 0, function* () {
        const setFeeEstimate = new big_js_1.default(1);
        let getFeeEstimate = yield sudoInterBtcAPI.oracle.getBitcoinFees();
        if (!getFeeEstimate) {
            yield setup_1.initializeBtcTxFees(setFeeEstimate, sudoInterBtcAPI.oracle);
            // just check that this is set since we medianize results
            getFeeEstimate = yield sudoInterBtcAPI.oracle.getBitcoinFees();
        }
        chai_1.assert.isDefined(getFeeEstimate);
    }));
    it("should enable vault nomination", () => __awaiter(void 0, void 0, void 0, function* () {
        let isNominationEnabled = yield sudoInterBtcAPI.nomination.isNominationEnabled();
        if (!isNominationEnabled) {
            yield setup_1.initializeVaultNomination(true, sudoInterBtcAPI.nomination);
            isNominationEnabled = yield sudoInterBtcAPI.nomination.isNominationEnabled();
        }
        chai_1.assert.isTrue(isNominationEnabled);
    }));
});
//# sourceMappingURL=initialize.test.js.map