diff --git a/README.md b/README.md index c8aca3a..428ce58 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ To run you will use the "shares" command **Input parameters:** - keystore (ks) = The path to either a validator keystore file or a folder that contains multiple validator keystore files. If a folder is provided, it will split in bulk all the keystore files within it according to the additional arguments provided -- password (ps) = The keystore file encryption password, if a folder was provided the password will be used for all keystore files in the folder +- password (ps) = The keystore file encryption password. For one keystore, enter the absolute path. For multiple keystores, enter only the password file name. - operator-ids (oids) = Comma-separated list of operator IDs. The amount must be 3f+1 compatible - operator-keys (oks) = Comma-separated list of operator keys (same sequence as operator ids). The amount must be 3f+1 compatible - output-folder (of) = Target folder path to output the key shares file @@ -103,7 +103,35 @@ To run you will use the "shares" command yarn cli shares --keystore=keystore.json --password=test --operator-ids=1,2,3,4 --operator-keys=LS..,LS..,LS..,LS.. --output-folder=./ --owner-address=... --owner-nonce=.. # folder with multiple keystore files -yarn cli shares --keystore=./keystore-files --password=test --operator-ids=1,2,3,4 --operator-keys=LS..,LS..,LS..,LS.. --output-folder=./ --owner-address=... --owner-nonce=.. +## folder structure for keystore files with the same password +keystore-files +├── keystore1.json +├── keystore2.json +├── keystore3.json +├── keystore4.json +└── keystore5.json + +yarn cli shares --keystore=./keystore_files --password=test --operator-ids=1,2,3,4 --operator-keys=LS..,LS..,LS..,LS.. --output-folder=./ --owner-address=... --owner-nonce=.. + +## folder structure for keystore files with diffent passwords +keystore_folders +├── validator1 +│   ├── keystore.json +│   └── password +├── validator2 +│   ├── keystore.json +│   └── password +├── validator3 +│   ├── keystore.json +│   └── password +├── validator4 +│   ├── keystore.json +│   └── password +└── validator5 + ├── keystore.json + └── password + +yarn cli shares --keystore=./keystore_folders --password=password --operator-ids=1,2,3,4 --operator-keys=LS..,LS..,LS..,LS.. --output-folder=./ --owner-address=... --owner-nonce=.. ``` **Output:** Name will start with keyshares-timestamp.json diff --git a/dist/tsc/src/commands/actions/KeySharesAction.js b/dist/tsc/src/commands/actions/KeySharesAction.js index 34260fd..fc58848 100644 --- a/dist/tsc/src/commands/actions/KeySharesAction.js +++ b/dist/tsc/src/commands/actions/KeySharesAction.js @@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.KeySharesAction = void 0; const tslib_1 = require("tslib"); const path_1 = tslib_1.__importDefault(require("path")); +const fs_1 = require("fs"); const BaseAction_1 = require("./BaseAction"); const SSVKeys_1 = require("../../lib/SSVKeys"); const KeySharesItem_1 = require("../../lib/KeyShares/KeySharesItem"); @@ -46,30 +47,52 @@ class KeySharesAction extends BaseAction_1.BaseAction { async processKeystorePath() { const keystorePath = (0, validators_1.sanitizePath)(String(this.args.keystore).trim()); const { files } = await (0, file_helper_1.getKeyStoreFiles)(keystorePath); - const validatedFiles = await this.validateKeystoreFiles(files); - const singleKeySharesList = await Promise.all(validatedFiles.map((file, index) => this.processFile(file, this.args.password, this.getOperators(), this.args.owner_address, this.args.owner_nonce + index))); + const keystoreSet = []; + for (const file of files) { + const isDir = (await fs_1.promises.stat(file)).isDirectory(); + let keystoreFile = file; + let keystorePassword = ''; + if (isDir) { + const dir = await fs_1.promises.opendir(file); + for await (const dirent of dir) { + if (dirent.name.includes('keystore')) { + keystoreFile = path_1.default.join(file, dirent.name); + } + if (dirent.name.includes(this.args.password)) { + keystorePassword = await fs_1.promises.readFile(path_1.default.join(file, dirent.name), 'utf-8'); + } + } + } + else { + keystorePassword = await fs_1.promises.readFile(this.args.password, 'utf-8'); + } + keystoreSet.push({ keystoreFile, keystorePassword }); + } + const validatedFiles = await this.validateKeystoreFiles(keystoreSet); + process.stdout.write(validatedFiles[0].keystoreFile); + const singleKeySharesList = await Promise.all(validatedFiles.map((keystore, index) => this.processFile(keystore.keystoreFile, keystore.keystorePassword, this.getOperators(), this.args.owner_address, this.args.owner_nonce + index))); return singleKeySharesList; } - async validateKeystoreFiles(files) { - const validatedFiles = []; + async validateKeystoreFiles(keystores) { + const validatedKeystoreSet = []; let failedValidation = 0; - for (const [index, file] of files.entries()) { - const isKeyStoreValid = await arguments_1.keystoreArgument.interactive.options.validate(file); - const isValidPassword = await validators_1.keystorePasswordValidator.validatePassword(this.args.password, file); + for (const [index, { keystoreFile, keystorePassword }] of keystores.entries()) { + const isKeyStoreValid = await arguments_1.keystoreArgument.interactive.options.validate(keystoreFile); + const isValidPassword = await validators_1.keystorePasswordValidator.validatePassword(keystorePassword, keystoreFile); let status = '✅'; if (isKeyStoreValid === true && isValidPassword === true) { - validatedFiles.push(file); + validatedKeystoreSet.push({ keystoreFile, keystorePassword }); } else { failedValidation++; status = '❌'; } - const fileName = path_1.default.basename(file); // Extract the file name - process.stdout.write(`\r\n${index + 1}/${files.length} ${status} ${fileName}`); + const fileName = path_1.default.basename(keystoreFile); // Extract the file name + process.stdout.write(`\r\n${index + 1}/${keystores.length} ${status} ${fileName}`); } - process.stdout.write(`\n\n${files.length - failedValidation} of ${files.length} keystore files successfully validated. ${failedValidation} failed validation`); + process.stdout.write(`\n\n${keystores.length - failedValidation} of ${keystores.length} keystore files successfully validated. ${failedValidation} failed validation`); process.stdout.write('\n'); - return validatedFiles; + return validatedKeystoreSet; } getOperators() { const operatorIds = this.args.operator_ids.split(','); diff --git a/dist/tsc/src/commands/actions/KeySharesAction.js.map b/dist/tsc/src/commands/actions/KeySharesAction.js.map index c844a2f..b1ebf77 100644 --- a/dist/tsc/src/commands/actions/KeySharesAction.js.map +++ b/dist/tsc/src/commands/actions/KeySharesAction.js.map @@ -1 +1 @@ -{"version":3,"file":"KeySharesAction.js","sourceRoot":"","sources":["../../../../../src/commands/actions/KeySharesAction.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"KeySharesAction.js","sourceRoot":"","sources":["../../../../../src/commands/actions/KeySharesAction.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/src/commands/actions/KeySharesAction.ts b/src/commands/actions/KeySharesAction.ts index 50b2dc7..c52159c 100644 --- a/src/commands/actions/KeySharesAction.ts +++ b/src/commands/actions/KeySharesAction.ts @@ -1,4 +1,5 @@ import path from 'path'; +import { promises as fsp } from 'fs'; import { BaseAction } from './BaseAction'; import { SSVKeys } from '../../lib/SSVKeys'; @@ -26,6 +27,11 @@ type Operator = { operatorKey: string; }; +type KeystoresArgs = { + keystoreFile: string; + keystorePassword: string; +}; + /** * Command to build keyshares from user input. */ @@ -48,7 +54,6 @@ export class KeySharesAction extends BaseAction { override async execute(): Promise { this.validateKeystoreArguments(); // Validate keystore arguments - const keySharesList = await this.processKeystorePath(); const keySharesFilePath = await this.saveKeyShares(keySharesList, this.args.output_folder); return keySharesFilePath; @@ -64,35 +69,60 @@ export class KeySharesAction extends BaseAction { private async processKeystorePath(): Promise { const keystorePath = sanitizePath(String(this.args.keystore).trim()); const { files } = await getKeyStoreFiles(keystorePath); - const validatedFiles = await this.validateKeystoreFiles(files); - const singleKeySharesList = await Promise.all(validatedFiles.map((file, index) => - this.processFile(file, this.args.password, this.getOperators(), this.args.owner_address, this.args.owner_nonce + index) + const keystoreSet : KeystoresArgs[] = []; + + for (const file of files) { + const isDir = (await fsp.stat(file)).isDirectory(); + keystoreFile = file; + keystorePassword = this.args.password; + + if (isDir) { + const dir = await fsp.opendir(file); + for await (const dirent of dir) { + if (dirent.name.includes(this.args.password)) { + keystorePassword = await fsp.readFile(path.join(file, dirent.name), 'utf-8'); + } else { + keystoreFile = path.join(file, dirent.name); + } + } + } + + keystoreSet.push({ keystoreFile, keystorePassword }); + } + + const validatedFiles = await this.validateKeystoreFiles(keystoreSet); + + const singleKeySharesList = await Promise.all(validatedFiles.map((keystore, index) => + this.processFile(keystore.keystoreFile, keystore.keystorePassword, this.getOperators(), this.args.owner_address, this.args.owner_nonce + index) )); return singleKeySharesList; } - private async validateKeystoreFiles(files: string[]): Promise { - const validatedFiles = []; + private async validateKeystoreFiles(keystores: KeystoresArgs[]): Promise { + const validatedKeystoreSet : KeystoresArgs[] = []; let failedValidation = 0; - for (const [index, file] of files.entries()) { - const isKeyStoreValid = await keystoreArgument.interactive.options.validate(file); - const isValidPassword = await keystorePasswordValidator.validatePassword(this.args.password, file); + + for (const [index, { keystoreFile, keystorePassword }] of keystores.entries()) { + const isKeyStoreValid = await keystoreArgument.interactive.options.validate(keystoreFile); + const isValidPassword = await keystorePasswordValidator.validatePassword(keystorePassword, keystoreFile); + let status = '✅'; if (isKeyStoreValid === true && isValidPassword === true) { - validatedFiles.push(file); + validatedKeystoreSet.push({ keystoreFile, keystorePassword }); } else { failedValidation++; status = '❌'; } - const fileName = path.basename(file); // Extract the file name - process.stdout.write(`\r\n${index+ 1}/${files.length} ${status} ${fileName}`); + const fileName = path.basename(keystoreFile); // Extract the file name + process.stdout.write(`\r\n${index+ 1}/${keystores.length} ${status} ${fileName}`); } - process.stdout.write(`\n\n${files.length - failedValidation} of ${files.length} keystore files successfully validated. ${failedValidation} failed validation`); + + process.stdout.write(`\n\n${keystores.length - failedValidation} of ${keystores.length} keystore files successfully validated. ${failedValidation} failed validation`); process.stdout.write('\n'); - return validatedFiles; + return validatedKeystoreSet; } private getOperators(): Operator[] {