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
225 lines (224 loc) • 7.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProfileManager = void 0;
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
/**
* Manages multiple configuration profiles for Caravan-X
*/
class ProfileManager {
constructor(baseDir) {
this.baseDir = baseDir;
this.profilesDir = path.join(baseDir, "profiles");
this.indexPath = path.join(this.profilesDir, "index.json");
}
/**
* Initialize profile directory structure
*/
async initialize() {
await fs.ensureDir(this.profilesDir);
if (!(await fs.pathExists(this.indexPath))) {
const emptyIndex = {
activeProfileId: null,
profiles: [],
};
await fs.writeJson(this.indexPath, emptyIndex, { spaces: 2 });
}
}
/**
* Get the profiles index
*/
async getIndex() {
await this.initialize();
return await fs.readJson(this.indexPath);
}
/**
* Save the profiles index
*/
async saveIndex(index) {
await fs.writeJson(this.indexPath, index, { spaces: 2 });
}
/**
* List all profiles
*/
async listProfiles() {
const index = await this.getIndex();
return index.profiles;
}
/**
* Get profiles by mode
*/
async getProfilesByMode(mode) {
const index = await this.getIndex();
return index.profiles.filter((p) => p.mode === mode);
}
/**
* Check if any profiles exist
*/
async hasProfiles() {
const index = await this.getIndex();
return index.profiles.length > 0;
}
/**
* Get a specific profile
*/
async getProfile(profileId) {
const index = await this.getIndex();
const profileEntry = index.profiles.find((p) => p.id === profileId);
if (!profileEntry)
return null;
try {
const config = await fs.readJson(profileEntry.configPath);
return {
id: profileEntry.id,
name: profileEntry.name,
mode: profileEntry.mode,
createdAt: profileEntry.createdAt,
lastUsedAt: profileEntry.lastUsedAt,
config,
};
}
catch (error) {
console.error(`Error loading profile ${profileId}:`, error);
return null;
}
}
/**
* Get the active profile
*/
async getActiveProfile() {
const index = await this.getIndex();
if (!index.activeProfileId)
return null;
return this.getProfile(index.activeProfileId);
}
/**
* Create a new profile
*/
async createProfile(name, mode, config) {
const index = await this.getIndex();
const id = this.generateProfileId();
const now = new Date().toISOString();
const configPath = path.join(this.profilesDir, `${id}.json`);
// Save the config file
await fs.writeJson(configPath, config, { spaces: 2 });
// Update index
index.profiles.push({
id,
name,
mode,
createdAt: now,
lastUsedAt: now,
configPath,
});
await this.saveIndex(index);
return {
id,
name,
mode,
createdAt: now,
lastUsedAt: now,
config,
};
}
/**
* Update an existing profile's config
*/
async updateProfile(profileId, config) {
const index = await this.getIndex();
const profileEntry = index.profiles.find((p) => p.id === profileId);
if (!profileEntry) {
throw new Error(`Profile ${profileId} not found`);
}
await fs.writeJson(profileEntry.configPath, config, { spaces: 2 });
profileEntry.lastUsedAt = new Date().toISOString();
await this.saveIndex(index);
}
/**
* Rename a profile
*/
async renameProfile(profileId, newName) {
const index = await this.getIndex();
const profileEntry = index.profiles.find((p) => p.id === profileId);
if (!profileEntry) {
throw new Error(`Profile ${profileId} not found`);
}
profileEntry.name = newName;
await this.saveIndex(index);
}
/**
* Set the active profile
*/
async setActiveProfile(profileId) {
const index = await this.getIndex();
const profileEntry = index.profiles.find((p) => p.id === profileId);
if (!profileEntry) {
throw new Error(`Profile ${profileId} not found`);
}
index.activeProfileId = profileId;
profileEntry.lastUsedAt = new Date().toISOString();
await this.saveIndex(index);
}
/**
* Delete a profile
*/
async deleteProfile(profileId) {
const index = await this.getIndex();
const profileIndex = index.profiles.findIndex((p) => p.id === profileId);
if (profileIndex === -1) {
throw new Error(`Profile ${profileId} not found`);
}
const profile = index.profiles[profileIndex];
// Delete config file
if (await fs.pathExists(profile.configPath)) {
await fs.remove(profile.configPath);
}
// Remove from index
index.profiles.splice(profileIndex, 1);
// Clear active if it was deleted
if (index.activeProfileId === profileId) {
index.activeProfileId = null;
}
await this.saveIndex(index);
}
/**
* Generate a unique profile ID
*/
generateProfileId() {
return `profile_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
}
exports.ProfileManager = ProfileManager;