caravan-x
Version:
A terminal-based utility for managing Caravan multisig wallets in regtest mode. This tool simplifies development and testing with Caravan by providing an easy-to-use interface
159 lines (158 loc) • 7.46 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CaravanRegtestManager = void 0;
const config_1 = require("./core/config");
const rpc_1 = require("./core/rpc");
const bitcoin_1 = require("./core/bitcoin");
const caravan_1 = require("./core/caravan");
const transaction_1 = require("./core/transaction");
const wallet_1 = require("./commands/wallet");
const multisig_1 = require("./commands/multisig");
const transaction_2 = require("./commands/transaction");
const visualizations_1 = require("./commands/visualizations");
const scripts_1 = require("./commands/scripts");
const mainMenu_1 = require("./ui/mainMenu");
const prompts_1 = require("@inquirer/prompts");
const chalk_1 = __importDefault(require("chalk"));
/**
* Main application class
*/
class CaravanRegtestManager {
constructor() {
// Initialize configuration
this.configManager = new config_1.ConfigManager();
const config = this.configManager.getConfig();
// Initialize RPC client
this.bitcoinRpcClient = new rpc_1.BitcoinRpcClient(config.bitcoin);
// Initialize services
this.bitcoinService = new bitcoin_1.BitcoinService(this.bitcoinRpcClient, true); // true for regtest mode
this.caravanService = new caravan_1.CaravanService(this.bitcoinRpcClient, config.caravanDir, config.keysDir);
this.transactionService = new transaction_1.TransactionService(this.bitcoinRpcClient, true); // true for regtest mode
// Initialize command modules
this.walletCommands = new wallet_1.WalletCommands(this.bitcoinService);
this.multisigCommands = new multisig_1.MultisigCommands(this.caravanService, this.bitcoinService, this.bitcoinRpcClient, this.transactionService);
this.transactionCommands = new transaction_2.TransactionCommands(this.transactionService, this.caravanService, this.bitcoinService);
this.visualizationCommands = new visualizations_1.VisualizationCommands(this.configManager, this.bitcoinRpcClient, this.bitcoinService);
this.scriptCommands = new scripts_1.ScriptCommands(this.configManager, this.bitcoinService, this.caravanService, this.transactionService, this.bitcoinRpcClient, this.multisigCommands);
}
/**
* Check if Bitcoin Core is running and accessible
*/
async checkBitcoinCore() {
try {
const blockchainInfo = (await this.bitcoinRpcClient.callRpc("getblockchaininfo"));
return blockchainInfo && blockchainInfo.chain === "regtest";
}
catch (error) {
// More detailed error information
if (error.message.includes("ECONNREFUSED")) {
console.log(chalk_1.default.red("Error: Bitcoin Core is not running or RPC server is not accessible."));
}
else if (error.message.includes("401")) {
console.log(chalk_1.default.red("Error: Authentication failed. Check your RPC username and password."));
}
else if (error.message.includes("data directory")) {
console.log(chalk_1.default.red(`Error: ${error.message}`));
}
else {
console.log(chalk_1.default.red("Error connecting to Bitcoin Core:"), error.message);
}
return false;
}
}
/**
* Start the application
*/
async start() {
console.log(chalk_1.default.bold.cyan("\n=== Caravan Regtest Manager ==="));
// Check if Bitcoin Core is running
let bitcoinCoreRunning = await this.checkBitcoinCore();
if (!bitcoinCoreRunning) {
console.log(chalk_1.default.red("\nERROR: Could not connect to Bitcoin Core."));
console.log(chalk_1.default.yellow("Please make sure Bitcoin Core is running in regtest mode."));
console.log(chalk_1.default.yellow("You may need to update your RPC settings in the config file."));
const config = this.configManager.getConfig();
console.log(chalk_1.default.cyan("\nCurrent RPC settings:"));
console.log(`URL: ${config.bitcoin.protocol}://${config.bitcoin.host}:${config.bitcoin.port}`);
console.log(`User: ${config.bitcoin.user}`);
console.log(`Data Directory: ${config.bitcoin.dataDir}`);
const setupConfig = await (0, prompts_1.confirm)({
message: "Would you like to update your Bitcoin Core connection settings?",
default: true,
});
if (setupConfig) {
await this.setupBitcoinConfig();
// Try connecting again
bitcoinCoreRunning = await this.checkBitcoinCore();
}
}
if (!bitcoinCoreRunning) {
console.log(chalk_1.default.yellow("\nContinuing without Bitcoin Core connection."));
console.log(chalk_1.default.yellow("Some features will not be available until connected."));
}
else {
console.log(chalk_1.default.green("\nSuccessfully connected to Bitcoin Core (regtest mode)."));
}
// Start the main menu
const mainMenu = new mainMenu_1.MainMenu(this);
await mainMenu.start();
}
/**
* Set up Bitcoin Core connection configuration interactively
*/
async setupBitcoinConfig() {
console.log(chalk_1.default.cyan("\n=== Bitcoin Core Configuration ==="));
const config = this.configManager.getConfig();
const protocol = await (0, prompts_1.input)({
message: "Enter RPC protocol (http/https):",
default: config.bitcoin.protocol,
});
const host = await (0, prompts_1.input)({
message: "Enter RPC host:",
default: config.bitcoin.host,
});
const port = await (0, prompts_1.number)({
message: "Enter RPC port:",
default: config.bitcoin.port,
});
const user = await (0, prompts_1.input)({
message: "Enter RPC username:",
default: config.bitcoin.user,
});
const pass = await (0, prompts_1.input)({
message: "Enter RPC password:",
default: config.bitcoin.pass,
});
const dataDir = await (0, prompts_1.input)({
message: "Enter Bitcoin data directory:",
default: config.bitcoin.dataDir,
});
// Update the configuration
this.configManager.updateBitcoinConfig({
protocol,
host,
port: port,
user,
pass,
dataDir,
});
// Reinitialize the RPC client with new settings
this.bitcoinRpcClient = new rpc_1.BitcoinRpcClient(this.configManager.getConfig().bitcoin);
this.bitcoinService = new bitcoin_1.BitcoinService(this.bitcoinRpcClient, true);
console.log(chalk_1.default.green("\nConfiguration updated successfully!"));
}
}
exports.CaravanRegtestManager = CaravanRegtestManager;
// When run directly
if (require.main === module) {
const app = new CaravanRegtestManager();
app.start().catch((error) => {
console.error(chalk_1.default.red("\nError starting application:"), error);
process.exit(1);
});
}
// Export for use in other files
exports.default = CaravanRegtestManager;