"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWallet = createWallet;
const bitcore_client_1 = require("@bitpay-labs/bitcore-client");
const coin_1 = require("../../src/models/coin");
const storage_1 = require("../../src/services/storage");
const utils_1 = require("../../src/utils");
async function getAllAddressesFromBlocks(start, end) {
    if (!storage_1.Storage.connected)
        await storage_1.Storage.start({});
    const coins = await coin_1.CoinStorage.collection
        .find({ chain: 'BTC', network: 'mainnet', mintHeight: { $gte: start, $lte: end } })
        .project({ address: 1 })
        .toArray();
    const uniqueAddresses = (0, utils_1.uniq)(coins.map(c => c.address));
    return uniqueAddresses;
}
async function createWallet(addresses, iteration, networkName) {
    const walletName = 'Benchmark Wallet' + iteration;
    const password = 'iamsatoshi';
    const chain = 'BTC';
    const network = networkName || 'mainnet';
    const baseUrl = 'http://localhost:3000/api';
    let lockedWallet;
    try {
        lockedWallet = await bitcore_client_1.Wallet.loadWallet({ name: walletName });
    }
    catch (err) {
        lockedWallet = await bitcore_client_1.Wallet.create({
            name: walletName,
            chain,
            network,
            baseUrl,
            password
        });
    }
    await lockedWallet.register({ baseUrl });
    if (addresses.length > 0) {
        const unlockedWallet = await lockedWallet.unlock(password);
        const keysToImport = addresses.map(a => ({ address: a }));
        await unlockedWallet.importKeys({ keys: keysToImport });
    }
    return lockedWallet;
}
async function benchMarkUtxoList(unlockedWallet, addresses, includeSpent = false) {
    const utxoListStart = new Date();
    const utxoStream = unlockedWallet.getUtxos({ includeSpent });
    const utxoBenchmark = new Promise(resolve => {
        const utxos = new Array();
        utxoStream
            .on('data', data => {
            const stringData = data.toString().replace(',\n', '');
            if (stringData.includes('{') && stringData.includes('}')) {
                utxos.push(JSON.parse(stringData));
            }
        })
            .on('complete', () => {
            const includeUnspentMsg = includeSpent ? '(+spent)' : '';
            console.log(`Listed ${includeUnspentMsg} `, (utxos || []).length, ' utxos for a wallet with', addresses.length, 'addresses. Took ', new Date().getTime() - utxoListStart.getTime(), ' ms');
            resolve(utxos);
        });
    });
    await utxoBenchmark;
}
async function bench(iteration = 0, startBlock = 0, endBlock = 100) {
    console.log('Benchmark', iteration, 'START');
    const addresses = await getAllAddressesFromBlocks(startBlock, endBlock);
    console.log('Collected', addresses.length, 'addresses');
    const walletCreationStart = new Date();
    const unlockedWallet = await createWallet(addresses, iteration);
    console.log('Create a wallet with', addresses.length, 'addresses. Took ', new Date().getTime() - walletCreationStart.getTime(), ' ms');
    await benchMarkUtxoList(unlockedWallet, addresses);
    await benchMarkUtxoList(unlockedWallet, addresses, true);
    const walletTxListStart = new Date();
    const txStream = unlockedWallet.listTransactions({ startBlock, endBlock });
    const benchmarkComplete = new Promise(resolve => {
        const txs = new Array();
        txStream.on('data', data => {
            const stringData = data.toString().replace(',\n', '');
            if (stringData.includes('{') && stringData.includes('}')) {
                txs.push(JSON.parse(stringData));
            }
        });
        txStream.on('complete', () => {
            console.log('Listed ', txs.length, ' txs for a wallet with', addresses.length, 'addresses. Took ', new Date().getTime() - walletTxListStart.getTime(), ' ms');
            resolve(txs);
        });
    });
    await benchmarkComplete;
}
async function main() {
    for (let i = 1; i < 6; i++) {
        await bench(i, 0, Math.pow(10, i));
    }
    process.exit(0);
}
if (require.main === module) {
    main();
}
//# sourceMappingURL=wallet-benchmark.js.map