@holographxyz/cli
Version:
Holograph operator CLI
169 lines (168 loc) ⢠6.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.readConfig = exports.checkFileExists = exports.validateBeta3Schema = exports.ensureConfigFileIsValid = exports.generateSupportedNetworksOptions = exports.CONFIG_FILE_NAME = void 0;
const tslib_1 = require("tslib");
const path = tslib_1.__importStar(require("node:path"));
const fs = tslib_1.__importStar(require("fs-extra"));
const inquirer = tslib_1.__importStar(require("inquirer"));
const Joi = tslib_1.__importStar(require("joi"));
const wallet_1 = require("@ethersproject/wallet");
const environment_1 = require("@holographxyz/environment");
const networks_1 = require("@holographxyz/networks");
const aes_encryption_1 = tslib_1.__importDefault(require("./aes-encryption"));
exports.CONFIG_FILE_NAME = 'config.json';
const localhostConfig = {
version: 'beta3',
networks: { localhost: { providerUrl: 'http://localhost:8545' }, localhost2: { providerUrl: 'http://localhost:9545' } },
user: {
credentials: {
iv: 'n6QP9:_vn=})',
privateKey: 'QDiDSbP9O0C58wm9rj41D1jqGgYT4+XBMuO6e8R1gc53IzbxKrHAjVeALxkSCkcFIx7MerWm4+ZVbJ0n51FbIPYz6OpnKRXXFGtDLq64mgU=',
address: '0xdf5295149F367b1FBFD595bdA578BAd22e59f504',
},
},
};
async function tryToUnlockWallet(configFile, unlockWallet, unsafePassword) {
let userWallet;
if (unlockWallet) {
// eslint-disable-next-line no-negated-condition
if (unsafePassword !== undefined) {
try {
userWallet = new wallet_1.Wallet(new aes_encryption_1.default(unsafePassword, configFile.user.credentials.iv).decrypt(configFile.user.credentials.privateKey));
}
catch {
throw new Error('password provided for wallet in holograph config is not correct');
}
}
else {
try {
userWallet = new wallet_1.Wallet(new aes_encryption_1.default('', configFile.user.credentials.iv).decrypt(configFile.user.credentials.privateKey));
}
catch {
await inquirer.prompt([
{
name: 'encryptionPassword',
message: 'Please enter the password to decrypt the private key for ' + configFile.user.credentials.address,
type: 'password',
validate: async (input) => {
try {
// we need to check that key decoded
userWallet = new wallet_1.Wallet(new aes_encryption_1.default(input, configFile.user.credentials.iv).decrypt(configFile.user.credentials.privateKey));
return true;
}
catch {
return 'Password is incorrect';
}
},
},
]);
}
}
if (userWallet === undefined) {
throw new Error('Wallet could not be unlocked');
}
}
return userWallet;
}
function generateSupportedNetworksOptions(configNetworks) {
const options = [];
for (const key of networks_1.supportedNetworks) {
if (configNetworks === undefined) {
options.push({ name: networks_1.networks[key].shortKey, value: networks_1.networks[key].key });
}
else if (key in configNetworks) {
options.push({ name: networks_1.networks[key].shortKey, value: networks_1.networks[key].key });
}
}
return options;
}
exports.generateSupportedNetworksOptions = generateSupportedNetworksOptions;
async function ensureConfigFileIsValid(configDir, unsafePassword, unlockWallet = false) {
const environment = (0, environment_1.getEnvironment)();
if (environment === environment_1.Environment.localhost) {
process.stdout.write(`\nš Environment: ${environment}\n\n`);
return {
environment,
userWallet: await tryToUnlockWallet(localhostConfig, unlockWallet),
configFile: localhostConfig,
supportedNetworksOptions: generateSupportedNetworksOptions(),
};
}
let configPath = configDir;
try {
await fs.pathExists(configDir);
const stats = await fs.stat(configDir);
if (!stats.isFile()) {
throw new Error('The configDir is a directory and not a file');
}
}
catch {
configPath = path.join(configDir, exports.CONFIG_FILE_NAME);
// console.debug('configPath', configPath)
}
const exists = await fs.pathExists(configPath);
if (!exists) {
throw new Error('Please run `holograph config` before running any other holograph command');
}
try {
const configFile = await fs.readJson(configPath);
await validateBeta3Schema(configFile);
const userWallet = await tryToUnlockWallet(configFile, unlockWallet, unsafePassword);
process.stdout.write(`\nš Environment: ${environment}\n\n`);
return {
environment,
userWallet,
configFile,
supportedNetworksOptions: generateSupportedNetworksOptions(configFile.networks),
};
}
catch (error) {
throw error.message
? error
: new Error(`Config file is no longer valid, please delete it before continuing ${error.message}`);
}
}
exports.ensureConfigFileIsValid = ensureConfigFileIsValid;
async function validateBeta3Schema(config) {
const networkObjects = {};
for (const network of networks_1.supportedNetworks) {
networkObjects[network] = Joi.object({
providerUrl: Joi.string().required(),
});
}
const beta3Schema = Joi.object({
version: Joi.string().valid('beta3').required(),
networks: Joi.object(networkObjects).required().unknown(false),
user: Joi.object({
credentials: Joi.object({
iv: Joi.string(),
privateKey: Joi.string().required(),
address: Joi.string().required(),
}).required(),
}).required(),
})
.required()
.unknown(false);
await beta3Schema.validateAsync(config);
}
exports.validateBeta3Schema = validateBeta3Schema;
async function checkFileExists(configPath) {
try {
return await fs.pathExists(configPath);
}
catch (error) {
console.debug(error);
return false;
}
}
exports.checkFileExists = checkFileExists;
async function readConfig(configPath) {
try {
return await fs.readJSON(configPath);
}
catch (error) {
console.debug(error);
return undefined;
}
}
exports.readConfig = readConfig;