"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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const api_1 = require("@polkadot/api");
const index_1 = require("../../../../../src/index");
const bitcoin_core_client_1 = require("../../../../../src/utils/bitcoin-core-client");
const factory_1 = require("../../../../../src/factory");
const config_1 = require("../../../../config");
const chai_1 = require("../../../../chai");
const issueRedeem_1 = require("../../../../../src/utils/issueRedeem");
const src_1 = require("../../../../../src");
const helpers_1 = require("../../../../utils/helpers");
describe("replace", () => {
    let api;
    let bitcoinCoreClient;
    let keyring;
    let userAccount;
    let vault_3;
    let vault_3_ids;
    let vault_2;
    let vault_2_ids;
    let interBtcAPI;
    let assetRegistry;
    let loansAPI;
    let wrappedCurrency;
    before(function () {
        return __awaiter(this, void 0, void 0, function* () {
            api = yield factory_1.createSubstrateAPI(config_1.PARACHAIN_ENDPOINT);
            const transactionAPI = new index_1.DefaultTransactionAPI(api);
            keyring = new api_1.Keyring({ type: "sr25519" });
            bitcoinCoreClient = new bitcoin_core_client_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);
            userAccount = keyring.addFromUri(config_1.USER_1_URI);
            assetRegistry = new index_1.DefaultAssetRegistryAPI(api);
            loansAPI = new index_1.DefaultLoansAPI(api, assetRegistry, transactionAPI);
            interBtcAPI = new index_1.DefaultInterBtcApi(api, "regtest", userAccount, config_1.ESPLORA_BASE_PATH);
            wrappedCurrency = interBtcAPI.getWrappedCurrency();
            const collateralCurrencies = helpers_1.getCorrespondingCollateralCurrenciesForTests(interBtcAPI.getGovernanceCurrency());
            vault_3 = keyring.addFromUri(config_1.VAULT_3_URI);
            vault_3_ids = collateralCurrencies.map((collateralCurrency) => src_1.newVaultId(api, vault_3.address, collateralCurrency, wrappedCurrency));
            vault_2 = keyring.addFromUri(config_1.VAULT_2_URI);
            vault_2_ids = collateralCurrencies.map((collateralCurrency) => src_1.newVaultId(api, vault_2.address, collateralCurrency, wrappedCurrency));
        });
    });
    after(() => __awaiter(void 0, void 0, void 0, function* () {
        api.disconnect();
    }));
    describe("request", () => {
        let dustValue;
        let feesEstimate;
        before(() => __awaiter(void 0, void 0, void 0, function* () {
            dustValue = yield interBtcAPI.replace.getDustValue();
            feesEstimate = index_1.newMonetaryAmount(yield interBtcAPI.oracle.getBitcoinFees(), wrappedCurrency, false);
        }));
        it("should request vault replacement", () => __awaiter(void 0, void 0, void 0, function* () {
            const APPROX_TWENTY_BLOCKS_MS = 20 * 12 * 1000;
            for (const vault_3_id of vault_3_ids) {
                // try to set value above dust + estimated fees
                const issueAmount = dustValue.add(feesEstimate).mul(1.2);
                const replaceAmount = dustValue;
                yield issueRedeem_1.issueSingle(interBtcAPI, bitcoinCoreClient, userAccount, issueAmount, vault_3_id);
                const collateralCurrency = yield src_1.currencyIdToMonetaryCurrency(assetRegistry, loansAPI, vault_3_id.currencies.collateral);
                const foundEventPromise = helpers_1.waitForEvent(interBtcAPI, api.events.replace.AcceptReplace, true, APPROX_TWENTY_BLOCKS_MS);
                yield helpers_1.callWith(interBtcAPI, vault_3, () => __awaiter(void 0, void 0, void 0, function* () { return interBtcAPI.replace.request(replaceAmount, collateralCurrency); }));
                yield chai_1.expect(foundEventPromise).to.eventually.be.equal(true, `Unexpected timeout while waiting for AcceptReplace event (collateral currency: ${collateralCurrency.ticker})`);
            }
            const requestsList = yield interBtcAPI.replace.list();
            const requestsMap = yield interBtcAPI.replace.map();
            chai_1.assert.equal(requestsList.length, vault_3_ids.length, `Expected ${vault_3_ids.length} requests in list, got ${requestsList.length}`);
            chai_1.assert.equal(requestsMap.size, vault_3_ids.length, `Expected ${vault_3_ids.length} requests in map, got ${requestsMap.size}`);
            // Need to manually compare some fields
            const membersFromListToExpect = requestsList.map((req) => ({
                btcAddress: req.btcAddress,
                btcHeight: req.btcHeight,
                amount: req.amount.toString(),
            }));
            const membersFromMapToCheck = Array.from(requestsMap.values()).map((req) => ({
                btcAddress: req.btcAddress,
                btcHeight: req.btcHeight,
                amount: req.amount.toString(),
            }));
            chai_1.expect(membersFromMapToCheck).to.deep.include.members(membersFromListToExpect);
        })).timeout(2000000);
        it("should fail vault replace request if not having enough tokens", () => __awaiter(void 0, void 0, void 0, function* () {
            for (const vault_2_id of vault_2_ids) {
                const collateralCurrency = yield src_1.currencyIdToMonetaryCurrency(assetRegistry, loansAPI, vault_2_id.currencies.collateral);
                const currencyTicker = collateralCurrency.ticker;
                // fetch tokens held by vault
                const tokensInVault = yield interBtcAPI.vaults.getIssuedAmount(src_1.newAccountId(api, vault_2.address), collateralCurrency);
                // make sure vault does not hold enough issued tokens to request a replace
                const replaceAmount = dustValue.add(tokensInVault);
                const replacePromise = helpers_1.callWith(interBtcAPI, vault_2, () => interBtcAPI.replace.request(replaceAmount, collateralCurrency));
                chai_1.expect(replacePromise).to.be.rejectedWith(Error, `Expected replace request to fail with Error (${currencyTicker} vault)`);
            }
        })).timeout(600000);
    });
    it("should getDustValue", () => __awaiter(void 0, void 0, void 0, function* () {
        const dustValue = yield interBtcAPI.replace.getDustValue();
        chai_1.assert.equal(dustValue.toString(), "0.00001");
    })).timeout(500);
    it("should getReplacePeriod", () => __awaiter(void 0, void 0, void 0, function* () {
        const replacePeriod = yield interBtcAPI.replace.getReplacePeriod();
        chai_1.assert.isDefined(replacePeriod, "Expected replace period to be defined, but was not");
    })).timeout(500);
    it("should list replace request by a vault", () => __awaiter(void 0, void 0, void 0, function* () {
        const vault3Id = src_1.newAccountId(api, vault_3.address);
        const replaceRequests = yield interBtcAPI.replace.mapReplaceRequests(vault3Id);
        replaceRequests.forEach((request) => {
            chai_1.assert.deepEqual(request.oldVault.accountId, vault3Id);
        });
    }));
});
//# sourceMappingURL=replace.test.js.map