"use strict";
// disabling linting as `bitcoin-core` has no types, causing the import to fail
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 });
exports.BitcoinCoreClient = void 0;
const monetary_js_1 = require("@interlay/monetary-js");
// eslint-disable-next-line
const Client = require("bitcoin-core");
class BitcoinCoreClient {
    /**
     * Initialize the Bitcoin-core client, which is a js equivalent to bitcoin-cli
     * @param network Bitcoin network (mainnet, testnet, regtest)
     * @param host URL of Bitcoin node (e.g. localhost)
     * @param username User for RPC authentication
     * @param password Password for RPC authentication
     * @param port Bitcoin node connection port (e.g. 18443)
     * @param wallet Wallet to use if several are available. See https://github.com/ruimarinho/bitcoin-core#multiwallet
     */
    constructor(network, host, username, password, port, wallet) {
        this.client = new Client({
            network,
            host,
            username,
            password,
            port,
            wallet,
        });
    }
    sendBtcTxAndMine(recipient, amount, blocksToMine, data) {
        return __awaiter(this, void 0, void 0, function* () {
            const tx = yield this.broadcastTx(recipient, amount, data);
            yield this.mineBlocks(blocksToMine);
            return tx;
        });
    }
    formatRawTxInput(recipient, amount, data) {
        const paidOutput = {};
        paidOutput[recipient] = amount.toString();
        if (data !== undefined) {
            return [{ data }, paidOutput];
        }
        return [paidOutput];
    }
    broadcastTx(recipient, amount, data) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.client) {
                throw new Error("Client needs to be initialized before usage");
            }
            console.log(`Broadcasting tx: ${amount.toString(monetary_js_1.Bitcoin.base)} BTC to ${recipient}`);
            const raw = yield this.client.command("createrawtransaction", [], this.formatRawTxInput(recipient, amount.toBig(monetary_js_1.Bitcoin.units.BTC), data));
            const funded = yield this.client.command("fundrawtransaction", raw);
            const signed = yield this.client.command("signrawtransactionwithwallet", funded.hex);
            const response = yield this.client.command("sendrawtransaction", signed.hex);
            const txid = response;
            return {
                txid: txid,
                rawTx: signed.hex,
            };
        });
    }
    mineBlocks(n) {
        return __awaiter(this, void 0, void 0, function* () {
            console.log(`Mining ${n} Bitcoin block(s)`);
            const newWalletAddress = yield this.client.command("getnewaddress");
            yield this.client.command("generatetoaddress", n, newWalletAddress);
        });
    }
    getBalance() {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.client.command("getbalance");
        });
    }
    sendToAddress(address, amount) {
        return __awaiter(this, void 0, void 0, function* () {
            return yield this.client.command("sendtoaddress", address, amount.toString(monetary_js_1.Bitcoin.units.BTC));
        });
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    getMempoolInfo() {
        return this.client.command("getmempoolinfo");
    }
    getBestBlockHash() {
        return this.client.command("getbestblockhash");
    }
    createWallet(name) {
        return this.client.command("createwallet", name);
    }
    loadWallet(name) {
        return this.client.command("loadwallet", name);
    }
}
exports.BitcoinCoreClient = BitcoinCoreClient;
//# sourceMappingURL=bitcoin-core-client.js.map