@fairdatasociety/fdp-cli
Version:
CLI tool for FDP-Storage
173 lines (151 loc) • 5.26 kB
text/typescript
import { Option, Utils } from 'furious-commander'
import { RootCommand } from '../root-command'
import { CommandLineError } from '../../utils/error'
import { Message } from '../../utils/message'
import { ASK_FOR_PORTABLE_PASSWORD_OPTIONS } from '../root-command/command-log'
import { createKeyValue } from '../../utils/text'
import { createAndRunSpinner } from '../../utils/spinner'
import { isSeed, Seed } from '../../utils/type'
import { Account, MAX_PASSWORD_LENGTH, MIN_PASSWORD_LENGTH } from '../../utils/account'
import { encryptSeed, getPrintDataFromSeed, mainHDNodeFromSeed } from '../../utils/wallet'
import { setMainAccount } from '../../utils/config'
export class AccountCommand extends RootCommand {
public account!: string
public password!: string
protected async init(): Promise<void> {
await super.init()
}
/**
* Checks the account name and ability to create such an account
*/
protected accountNameCreationCheck(accountName: string, errorTemplate = Message.accountNameConflictArgument): void {
if (Utils.getSourcemap().name === 'default') {
this.console.info(`No account name specified, defaulting to '${accountName}'`)
}
if (this.commandConfig.config.accounts[accountName]) {
throw new CommandLineError(errorTemplate(accountName))
}
}
/**
* Throws an error if there are no accounts
*/
protected throwIfNoAccounts(): void {
if (!this.commandConfig.config.accounts) {
throw new CommandLineError(Message.noAccount())
}
}
/**
* Prints seed information to the console
*/
protected printSeed(seed: Seed): void {
const data = getPrintDataFromSeed(seed)
this.console.log(createKeyValue('Seed', data.seed))
this.console.log(createKeyValue('Public key', data.publicKey))
this.console.log(createKeyValue('Private key', data.privateKey))
this.console.log(createKeyValue('Address', data.address))
}
/**
* Prints a wallet information to the console in quiet mode
*/
protected printSeedQuietly(seed: Seed): void {
const data = getPrintDataFromSeed(seed)
this.console.quiet(data.seed)
this.console.quiet(data.publicKey)
this.console.quiet(data.privateKey)
this.console.quiet(data.address)
}
/**
* Gets an account by name from the config
*/
protected getAccountByName(name: string): Account {
const { accounts } = this.commandConfig.config
if (!accounts || !accounts[name]) {
throw new CommandLineError(Message.noSuchAccount(name))
}
return accounts[name]
}
/**
* Asks portable account password with confirmation if it is empty
*/
protected async askPortableAccountPassword(portablePassword: string, withConfirmation = true): Promise<string> {
if (portablePassword) {
return portablePassword
} else {
if (this.quiet) {
throw new CommandLineError(
`Password must be passed with the --${ASK_FOR_PORTABLE_PASSWORD_OPTIONS.optionName} option in quiet mode`,
)
}
this.console.log(
Message.optionNotDefinedWithTitle(
ASK_FOR_PORTABLE_PASSWORD_OPTIONS.optionLabel,
ASK_FOR_PORTABLE_PASSWORD_OPTIONS.optionName,
),
)
if (withConfirmation) {
return this.console.askForPasswordWithConfirmation(
Message.portableAccountPassword(),
Message.portableAccountPasswordConfirmation(),
MIN_PASSWORD_LENGTH,
MAX_PASSWORD_LENGTH,
)
} else {
return this.console.askForPassword(Message.portableAccountPassword(), ASK_FOR_PORTABLE_PASSWORD_OPTIONS)
}
}
}
/**
* Asks to enter a password for an account if the password is not provided
*/
protected async askPassword(): Promise<void> {
if (!this.password) {
this.console.log(Message.optionNotDefined('password'))
this.password = await this.console.askForPasswordWithConfirmation(
Message.newAccountPassword(),
Message.newAccountPasswordConfirmation(),
MIN_PASSWORD_LENGTH,
MAX_PASSWORD_LENGTH,
)
}
}
/**
* Creates an encrypted account from a seed
*/
protected async createAccount(seed: Seed): Promise<Account> {
if (!isSeed(seed)) {
throw new Error('Incorrect data type. Expected seed in form of bytes')
}
await this.askPassword()
const spinner = createAndRunSpinner('Creating account...', this.verbosity)
const encryptedSeed = encryptSeed(seed, this.password)
spinner.stop()
return {
address: mainHDNodeFromSeed(seed).address,
encryptedSeed,
mainPod: '',
}
}
/**
* Initialize first created account as main
*/
protected initializeDefaultAccount(name: string): void {
if (Object.entries(this.commandConfig.config.accounts).length !== 1) {
return
}
setMainAccount(name, this.commandConfig.configFilePath, this.commandConfig.config)
}
}