From 6c538588e93941a7501dc5a69dd9bdd2f0fd77de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Andrade?= Date: Sat, 27 Apr 2024 00:17:34 +0200 Subject: [PATCH] Replace ux with alternative libraries --- README.md | 49 ++++--- package.json | 4 +- src/commands/assets/mint.ts | 50 ++++--- src/commands/config/get.ts | 4 +- src/commands/config/init.ts | 18 +-- src/commands/config/set.ts | 11 +- src/commands/generate/mint-file.ts | 26 ++-- src/commands/generate/pfp-file.ts | 9 +- src/commands/generate/template-file.ts | 18 ++- src/commands/generate/token-transfer-file.ts | 9 +- src/commands/pfps/build.ts | 4 +- src/commands/pfps/generate.ts | 8 +- src/commands/templates/create.ts | 66 +++++---- src/commands/templates/export.ts | 26 ++-- src/commands/tokens/transfer.ts | 24 ++- src/services/mint-service.ts | 9 +- src/services/pfp-service.ts | 6 +- src/services/schema-service.ts | 2 - src/services/template-service.ts | 2 - src/utils/tty-utils.ts | 76 ++++++++++ src/wallet/ConsoleRenderer.ts | 45 ++---- src/wallet/WalletPluginSecurePrivateKey.ts | 4 +- yarn.lock | 145 ++----------------- 23 files changed, 285 insertions(+), 330 deletions(-) create mode 100644 src/utils/tty-utils.ts diff --git a/README.md b/README.md index badb685..b4e3971 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ $ npm install -g @nefty/cli $ nefty COMMAND running command... $ nefty (--version) -@nefty/cli/0.2.5 darwin-arm64 node-v18.19.1 +@nefty/cli/0.2.6 darwin-arm64 node-v18.19.1 $ nefty --help [COMMAND] USAGE $ nefty COMMAND @@ -271,7 +271,7 @@ DESCRIPTION Manages a collection's assets. ``` -_See code: [src/commands/assets/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/assets/index.ts)_ +_See code: [src/commands/assets/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/assets/index.ts)_ ## `nefty assets mint INPUT` @@ -298,7 +298,7 @@ EXAMPLES $ nefty assets mint test.xls -c alpacaworlds ``` -_See code: [src/commands/assets/mint.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/assets/mint.ts)_ +_See code: [src/commands/assets/mint.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/assets/mint.ts)_ ## `nefty config` @@ -312,7 +312,7 @@ DESCRIPTION Manages the configuration. ``` -_See code: [src/commands/config/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/config/index.ts)_ +_See code: [src/commands/config/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/config/index.ts)_ ## `nefty config auth` @@ -331,7 +331,7 @@ EXAMPLES $ nefty config auth auth ``` -_See code: [src/commands/config/auth.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/config/auth.ts)_ +_See code: [src/commands/config/auth.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/config/auth.ts)_ ## `nefty config get` @@ -348,7 +348,7 @@ EXAMPLES $ nefty config get ``` -_See code: [src/commands/config/get.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/config/get.ts)_ +_See code: [src/commands/config/get.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/config/get.ts)_ ## `nefty config init` @@ -368,7 +368,7 @@ EXAMPLES $ nefty config init ``` -_See code: [src/commands/config/init.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/config/init.ts)_ +_See code: [src/commands/config/init.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/config/init.ts)_ ## `nefty config set [PROPERTY] [VALUE]` @@ -391,7 +391,7 @@ EXAMPLES $ nefty config set explorerUrl https://waxblock.io ``` -_See code: [src/commands/config/set.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/config/set.ts)_ +_See code: [src/commands/config/set.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/config/set.ts)_ ## `nefty generate` @@ -405,7 +405,7 @@ DESCRIPTION Generates excel files to use in other batch commands. ``` -_See code: [src/commands/generate/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/generate/index.ts)_ +_See code: [src/commands/generate/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/generate/index.ts)_ ## `nefty generate mint-file OUTPUT` @@ -437,7 +437,7 @@ EXAMPLES $ nefty generate mint-file mints.xlsx -c alpacaworlds ``` -_See code: [src/commands/generate/mint-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/generate/mint-file.ts)_ +_See code: [src/commands/generate/mint-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/generate/mint-file.ts)_ ## `nefty generate pfp-file OUTPUT` @@ -469,7 +469,7 @@ EXAMPLES $ nefty generate pfp-file pfp-layers.xlsx -l Body -l Face -l Hair -a ``` -_See code: [src/commands/generate/pfp-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/generate/pfp-file.ts)_ +_See code: [src/commands/generate/pfp-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/generate/pfp-file.ts)_ ## `nefty generate template-file OUTPUT` @@ -501,7 +501,7 @@ EXAMPLES $ nefty generate template-file templates.xlsx -c alpacaworlds ``` -_See code: [src/commands/generate/template-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/generate/template-file.ts)_ +_See code: [src/commands/generate/template-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/generate/template-file.ts)_ ## `nefty generate token-transfer-file OUTPUT` @@ -523,7 +523,7 @@ EXAMPLES $ nefty generate token-transfer-file transfers.xlsx ``` -_See code: [src/commands/generate/token-transfer-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/generate/token-transfer-file.ts)_ +_See code: [src/commands/generate/token-transfer-file.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/generate/token-transfer-file.ts)_ ## `nefty help [COMMAND]` @@ -557,7 +557,7 @@ DESCRIPTION Commands to manage a PFP collection. ``` -_See code: [src/commands/pfps/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/pfps/index.ts)_ +_See code: [src/commands/pfps/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/pfps/index.ts)_ ## `nefty pfps build INPUT` @@ -588,7 +588,7 @@ EXAMPLES $ nefty pfps build ./pfps-folder -c alpacaworls -t 11324 -a alpacaworlds -n "My NFT" -r ``` -_See code: [src/commands/pfps/build.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/pfps/build.ts)_ +_See code: [src/commands/pfps/build.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/pfps/build.ts)_ ## `nefty pfps generate INPUT OUTPUT` @@ -617,7 +617,7 @@ EXAMPLES $ nefty pfps generate pfps-specs.xlsx pfps ``` -_See code: [src/commands/pfps/generate.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/pfps/generate.ts)_ +_See code: [src/commands/pfps/generate.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/pfps/generate.ts)_ ## `nefty pfps mint INPUT` @@ -625,13 +625,14 @@ Mints the NFTS in the mint-pfps.xlsx file. ``` USAGE - $ nefty pfps mint INPUT [--skip ] + $ nefty pfps mint INPUT [--skip ] [--batchSize ] ARGUMENTS INPUT Directory where the pfps are saved. FLAGS - --skip= Number of mints to skip + --batchSize= [default: 50] Batch size for minting + --skip= Number of mints to skip DESCRIPTION Mints the NFTS in the mint-pfps.xlsx file. @@ -642,7 +643,7 @@ EXAMPLES $ nefty pfps mint ./pfps-folder ``` -_See code: [src/commands/pfps/mint.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/pfps/mint.ts)_ +_See code: [src/commands/pfps/mint.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/pfps/mint.ts)_ ## `nefty templates` @@ -656,7 +657,7 @@ DESCRIPTION Manages a collection's templates. ``` -_See code: [src/commands/templates/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/templates/index.ts)_ +_See code: [src/commands/templates/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/templates/index.ts)_ ## `nefty templates create INPUT` @@ -680,7 +681,7 @@ EXAMPLES $ nefty templates create template.xls -c alpacaworlds ``` -_See code: [src/commands/templates/create.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/templates/create.ts)_ +_See code: [src/commands/templates/create.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/templates/create.ts)_ ## `nefty templates export OUTPUT` @@ -712,7 +713,7 @@ EXAMPLES $ nefty templates export templates.xlsx -c alpacaworlds ``` -_See code: [src/commands/templates/export.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/templates/export.ts)_ +_See code: [src/commands/templates/export.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/templates/export.ts)_ ## `nefty tokens` @@ -726,7 +727,7 @@ DESCRIPTION Manages an account's tokens ``` -_See code: [src/commands/tokens/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/tokens/index.ts)_ +_See code: [src/commands/tokens/index.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/tokens/index.ts)_ ## `nefty tokens transfer INPUT` @@ -749,5 +750,5 @@ EXAMPLES $ nefty tokens transfer test.xls ``` -_See code: [src/commands/tokens/transfer.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.5/src/commands/tokens/transfer.ts)_ +_See code: [src/commands/tokens/transfer.ts](https://github.com/neftyblocks/neftyblocks-cli/blob/v0.2.6/src/commands/tokens/transfer.ts)_ diff --git a/package.json b/package.json index ff33fc0..ac9abcb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nefty/cli", - "version": "0.2.5", + "version": "0.2.6", "description": "The NeftyBlocks cli will help you manage your collection with commands to create templates, mint assets, and more.", "keywords": [ "oclif" @@ -69,13 +69,13 @@ "@wharfkit/wallet-plugin-anchor": "^1.3.0", "atomicassets": "^1.5.1", "cli-progress": "^3.12.0", - "inquirer": "^9.2.19", "kubo-rpc-client": "^4.1.1", "node-fetch": "2.6.7", "ora": "^8.0.1", "qrcode-terminal": "^0.12.0", "read-excel-file": "^5.6.1", "sharp": "^0.32.5", + "terminal-link": "^3.0.0", "undici": "^6.14.1", "write-excel-file": "^1.4.27" }, diff --git a/src/commands/assets/mint.ts b/src/commands/assets/mint.ts index fe5c576..d3485d3 100644 --- a/src/commands/assets/mint.ts +++ b/src/commands/assets/mint.ts @@ -1,4 +1,4 @@ -import { ux, Flags, Args } from '@oclif/core'; +import { Flags, Args } from '@oclif/core'; import { mintAssets } from '../../services/asset-service.js'; import { getBatchesFromArray } from '../../utils/array-utils.js'; import { getCollectionSchemas } from '../../services/schema-service.js'; @@ -8,6 +8,7 @@ import { BaseCommand } from '../../base/BaseCommand.js'; import { readExcelContents } from '../../utils/excel-utils.js'; import { readExcelMintRows } from '../../services/mint-service.js'; import { confirmTransaction } from '../../services/antelope-service.js'; +import { confirmPrompt, makeSpinner, printTable } from '../../utils/tty-utils.js'; export default class MintAssetsCommand extends BaseCommand { static description = 'Mints assets in batches using a spreadsheet.'; @@ -53,16 +54,17 @@ export default class MintAssetsCommand extends BaseCommand { const mintsFile = args.input; const { batchSize, skip, confirm, ignoreSupply, collectionName } = flags; const config = await this.getCliConfig(); + const spinner = makeSpinner(); - ux.action.start('Getting collection schemas'); + spinner.start('Getting collection schemas'); const schema = await getCollectionSchemas(collectionName, config); const schemasMap = Object.fromEntries(schema.map((row) => [row.name, row])); - ux.action.stop(); + spinner.stop(); // Read XLS file const mintRows: MintRow[] = []; try { - ux.action.start('Reading mints in file'); + spinner.start('Reading mints in file'); const sheets = await readExcelContents(mintsFile); for (let i = 0; i < sheets.length; i++) { const { name, rows } = sheets[i]; @@ -70,10 +72,20 @@ export default class MintAssetsCommand extends BaseCommand { const schema = schemasMap[schemaName]; mintRows.push(...(await readExcelMintRows(rows, schema, config, ignoreSupply, skip))); } + spinner.succeed(); } catch (error: any) { + spinner.fail(); throw new Error(`Error reading file: ${error.message}`); - } finally { - ux.action.stop(); + } + + if (mintRows.length === 0) { + this.log('Nothing to mint'); + return; + } + + const sample = [mintRows[0]]; + if (mintRows.length > 1) { + sample.push(mintRows[mintRows.length - 1]); } // Create table columns and print table @@ -89,12 +101,14 @@ export default class MintAssetsCommand extends BaseCommand { .join('\n'), }, }; - ux.table(mintRows, columns); - const proceed = await ux.confirm('Continue? y/n'); + printTable(columns, sample); + + const proceed = await confirmPrompt( + `About to mint ${mintRows.length} NFTs. (Only first and last NFTs are displayed above) Continue?`, + ); if (!proceed) return; - ux.action.start('Minting assets...'); const mintActions = []; for (const mint of mintRows) { for (let i = 0; i < mint.amount; i++) { @@ -107,11 +121,11 @@ export default class MintAssetsCommand extends BaseCommand { let totalMintCount = 0; try { for (const mintActions of actionBatches) { + spinner.start(`Minting ${mintActions.length} assets`); const result = (await mintAssets(mintActions, config)) as TransactResult; const txId = result.resolved!.transaction.id; - this.log( - `${mintActions.length} Assets minted successfully. Transaction: ${config.explorerUrl}/transaction/${txId}`, - ); + const message = `${mintActions.length} Assets minted successfully. Transaction: ${config.explorerUrl}/transaction/${txId}`; + spinner.text = message + (confirm ? ' Confirming...' : ''); const templateAmountMap: any = {}; for (const mintAction of mintActions) { @@ -122,10 +136,6 @@ export default class MintAssetsCommand extends BaseCommand { } } - for (const templateId in templateAmountMap) { - this.log(`Minted ${templateAmountMap[templateId]} of template ${templateId}`); - } - totalMintCount += mintActions.length; if (confirm) { @@ -138,13 +148,15 @@ export default class MintAssetsCommand extends BaseCommand { } if (!confirmed) { throw new Error('Transaction not confirmed'); + } else { + spinner.succeed( + `${mintActions.length} Assets minted successfully. Transaction: ${config.explorerUrl}/transaction/${txId} Confirmed`, + ); } } } } catch (error: any) { - throw new Error(`Error after minting: ${totalMintCount} successfully:` + error.message); + spinner.fail(`Error after minting: ${totalMintCount} successfully: ` + error.message); } - - ux.action.stop(); } } diff --git a/src/commands/config/get.ts b/src/commands/config/get.ts index d69b54b..14dc578 100644 --- a/src/commands/config/get.ts +++ b/src/commands/config/get.ts @@ -1,6 +1,6 @@ -import { ux } from '@oclif/core'; import { Session } from '@wharfkit/session'; import { BaseCommand } from '../../base/BaseCommand.js'; +import { printTable } from '../../utils/tty-utils.js'; export default class GetCommand extends BaseCommand { static examples = ['<%= config.bin %> <%= command.id %>']; @@ -49,6 +49,6 @@ export default class GetCommand extends BaseCommand { params.push(param); } }); - ux.table(params, columns); + printTable(columns, params); } } diff --git a/src/commands/config/init.ts b/src/commands/config/init.ts index 159d4db..61247e7 100644 --- a/src/commands/config/init.ts +++ b/src/commands/config/init.ts @@ -5,8 +5,7 @@ import { getChainId, validateExplorerUrl, validateAtomicAssetsUrl } from '../../ import { getSession } from '../../services/antelope-service.js'; import { SettingsConfig } from '../../types/index.js'; import { input, select } from '@inquirer/prompts'; -import inquirer from 'inquirer'; -import ora from 'ora'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; interface Preset { name: string; @@ -49,18 +48,13 @@ export default class InitCommand extends Command { const { flags } = await this.parse(InitCommand); const deleteConfig = flags.deleteConfig; - const spinner = ora(); + const spinner = makeSpinner(); if (configFileExists(this.config.configDir)) { - const prompt = inquirer.createPromptModule(); - const proceed = deleteConfig - ? true - : await prompt({ - type: 'confirm', - name: 'proceed', - message: 'Configuration file already exists, do you want to overwrite it? y/n', - default: false, - }).then((answer) => answer.proceed); + const proceed = await confirmPrompt( + 'Configuration file already exists, do you want to overwrite it?', + deleteConfig, + ); if (proceed) { spinner.start('Deleting configuration file...'); removeConfigFile(this.config.configDir); diff --git a/src/commands/config/set.ts b/src/commands/config/set.ts index 4bd6f8a..45f4172 100644 --- a/src/commands/config/set.ts +++ b/src/commands/config/set.ts @@ -1,6 +1,7 @@ -import { Args, Command, ux } from '@oclif/core'; +import { Args, Command } from '@oclif/core'; import { SettingsConfig } from '../../types/index.js'; import { readConfiguration, validate, writeConfiguration } from '../../utils/config-utils.js'; +import { makeSpinner } from '../../utils/tty-utils.js'; export default class SetCommand extends Command { static examples = [ @@ -40,17 +41,17 @@ export default class SetCommand extends Command { return { ...accumulator, [key]: config[key as keyof SettingsConfig] }; }, {}) as SettingsConfig; - ux.action.start('Validating configurations...'); + const spinner = makeSpinner('Validating configurations...'); const validConfi = await validate(updatedConf); - ux.action.stop(); + spinner.succeed(); if (!validConfi) { return; } - ux.action.start('Updating configurations...'); + spinner.start('Updating configurations...'); writeConfiguration(validConfi, this.config.configDir); - ux.action.stop(); + spinner.succeed(); this.log('Update completed!!'); } } diff --git a/src/commands/generate/mint-file.ts b/src/commands/generate/mint-file.ts index e4c0b05..27988e0 100644 --- a/src/commands/generate/mint-file.ts +++ b/src/commands/generate/mint-file.ts @@ -1,4 +1,4 @@ -import { Args, Flags, ux } from '@oclif/core'; +import { Args, Flags } from '@oclif/core'; import { getTemplatesForCollection, getTemplatesFromSchema } from '../../services/template-service.js'; import { BaseCommand } from '../../base/BaseCommand.js'; import { getCollectionSchemas, getSchema } from '../../services/schema-service.js'; @@ -6,6 +6,7 @@ import { ITemplate } from 'atomicassets/build/API/Explorer/Objects.js'; import { fileExists } from '../../utils/file-utils.js'; import { AssetSchema } from '../../types/index.js'; import { generateMintExcelFile } from '../../services/mint-service.js'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; export default class GenerateMintFileCommand extends BaseCommand { static examples = [ @@ -53,33 +54,34 @@ export default class GenerateMintFileCommand extends BaseCommand { const templates: ITemplate[] = []; if (fileExists(output)) { - const proceed = await ux.confirm('File already exists. Do you want to overwrite it? y/n'); + const proceed = await confirmPrompt('File already exists. Do you want to overwrite it?'); if (!proceed) { return; } } + const spinner = makeSpinner(); if (schema) { - ux.action.start('Getting schema...'); + spinner.start('Getting schema...'); schemas.push(await getSchema(collection, schema, config)); - ux.action.stop(); + spinner.succeed(); - ux.action.start('Getting templates...'); + spinner.start('Getting templates...'); templates.push(...(await getTemplatesFromSchema(collection, schema, config))); - ux.action.stop(); + spinner.succeed(); } else { - ux.action.start('Getting schemas...'); + spinner.start('Getting schemas...'); schemas.push(...(await getCollectionSchemas(collection, config))); - ux.action.stop(); + spinner.succeed(); - ux.action.start('Getting templates...'); + spinner.start('Getting templates...'); templates.push(...(await getTemplatesForCollection(collection, config))); - ux.action.stop(); + spinner.succeed(); } - ux.action.start('Generating file...'); + spinner.start('Generating file...'); await generateMintExcelFile(schemas, templates, output); - ux.action.stop(); + spinner.succeed(); this.log(`File generated at ${output}`); } diff --git a/src/commands/generate/pfp-file.ts b/src/commands/generate/pfp-file.ts index 4f86af1..ad65191 100644 --- a/src/commands/generate/pfp-file.ts +++ b/src/commands/generate/pfp-file.ts @@ -1,4 +1,4 @@ -import { Args, Flags, ux } from '@oclif/core'; +import { Args, Flags } from '@oclif/core'; import { BaseCommand } from '../../base/BaseCommand.js'; import writeXlsxFile from 'write-excel-file/node'; import { fileExists } from '../../utils/file-utils.js'; @@ -13,6 +13,7 @@ import { skipHeader, valueHeader, } from '../../services/pfp-service.js'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; export default class GeneratePfpFileCommand extends BaseCommand { static examples = [ @@ -56,7 +57,7 @@ export default class GeneratePfpFileCommand extends BaseCommand { const advanced = flags.advanced; if (fileExists(output)) { - const proceed = await ux.confirm('File already exists. Do you want to overwrite it?'); + const proceed = await confirmPrompt('File already exists. Do you want to overwrite it?'); if (!proceed) { return; } @@ -193,12 +194,12 @@ export default class GeneratePfpFileCommand extends BaseCommand { })), ]); - ux.action.start('Generating file...'); + const spinner = makeSpinner('Generating file...'); await writeXlsxFile(data, { sheets: [...layers.map((layer) => layer), '_force_'], filePath: output, }); - ux.action.stop(); + spinner.succeed(); this.log(`File generated at ${output}`); } diff --git a/src/commands/generate/template-file.ts b/src/commands/generate/template-file.ts index 0195b94..1760fde 100644 --- a/src/commands/generate/template-file.ts +++ b/src/commands/generate/template-file.ts @@ -1,10 +1,11 @@ -import { Args, Flags, ux } from '@oclif/core'; +import { Args, Flags } from '@oclif/core'; import { BaseCommand } from '../../base/BaseCommand.js'; import writeXlsxFile from 'write-excel-file/node'; import { getCollectionSchemas, getSchema } from '../../services/schema-service.js'; import { getXlsType } from '../../utils/attributes-utils.js'; import { fileExists } from '../../utils/file-utils.js'; import { AssetSchema } from '../../types/index.js'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; const headers = [ { @@ -63,25 +64,26 @@ export default class GenerateTemplateFileCommand extends BaseCommand { const schemas: AssetSchema[] = []; if (fileExists(output)) { - const proceed = await ux.confirm('File already exists. Do you want to overwrite it?'); + const proceed = await confirmPrompt('File already exists. Do you want to overwrite it?'); if (!proceed) { return; } } + const spinner = makeSpinner(); if (schema) { - ux.action.start('Getting schema...'); + spinner.start('Getting schema...'); schemas.push(await getSchema(collection, schema, config)); - ux.action.stop(); + spinner.succeed(); } else { - ux.action.start('Getting schemas...'); + spinner.start('Getting schemas...'); schemas.push(...(await getCollectionSchemas(collection, config))); - ux.action.stop(); + spinner.succeed(); } - ux.action.start('Generating file...'); + spinner.start('Generating file...'); await this.generateExcelFile(schemas, output); - ux.action.stop(); + spinner.succeed(); this.log(`File generated at ${output}`); } diff --git a/src/commands/generate/token-transfer-file.ts b/src/commands/generate/token-transfer-file.ts index a33d8c2..38c264a 100644 --- a/src/commands/generate/token-transfer-file.ts +++ b/src/commands/generate/token-transfer-file.ts @@ -1,8 +1,9 @@ -import { Args, ux } from '@oclif/core'; +import { Args } from '@oclif/core'; import { BaseCommand } from '../../base/BaseCommand.js'; import writeXlsxFile from 'write-excel-file/node'; import { fileExists } from '../../utils/file-utils.js'; import { amountField, contractField, memoField, recipientField, symbolField } from '../../services/token-service.js'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; export default class GenerateTokenTransferFileCommand extends BaseCommand { static examples = [ @@ -26,7 +27,7 @@ export default class GenerateTokenTransferFileCommand extends BaseCommand { const output = args.output; if (fileExists(output)) { - const proceed = await ux.confirm('File already exists. Do you want to overwrite it?'); + const proceed = await confirmPrompt('File already exists. Do you want to overwrite it?'); if (!proceed) { return; } @@ -79,11 +80,11 @@ export default class GenerateTokenTransferFileCommand extends BaseCommand { ], ]; - ux.action.start('Generating file...'); + const spinner = makeSpinner('Generating file...'); await writeXlsxFile(data, { filePath: output, }); - ux.action.stop(); + spinner.succeed(); this.log(`File generated at ${output}`); } diff --git a/src/commands/pfps/build.ts b/src/commands/pfps/build.ts index a0f9549..37dc485 100644 --- a/src/commands/pfps/build.ts +++ b/src/commands/pfps/build.ts @@ -8,7 +8,7 @@ import { Pfp, PfpManifest } from '../../types/pfps.js'; import { getTemplate } from '../../services/template-service.js'; import { AssetSchema } from '../../types/index.js'; import { generateMintExcelFileWithContent } from '../../services/mint-service.js'; -import ora from 'ora'; +import { makeSpinner } from '../../utils/tty-utils.js'; export default class BuildPfpsCommand extends BaseCommand { static examples = [ @@ -127,7 +127,7 @@ export default class BuildPfpsCommand extends BaseCommand { pfpManifest.pfps.sort(() => Math.random() - 0.5); } - const spinner = ora('Getting template').start(); + const spinner = makeSpinner('Getting template').start(); const templateObject = await getTemplate(collection, template, config); const namedPfs = pfpManifest.pfps.map((pfp: Pfp, index: number) => { diff --git a/src/commands/pfps/generate.ts b/src/commands/pfps/generate.ts index de95054..c26059d 100644 --- a/src/commands/pfps/generate.ts +++ b/src/commands/pfps/generate.ts @@ -1,4 +1,4 @@ -import { Args, Flags, ux } from '@oclif/core'; +import { Args, Flags } from '@oclif/core'; import { BaseCommand } from '../../base/BaseCommand.js'; import { join } from 'node:path'; import { fileExists } from '../../utils/file-utils.js'; @@ -7,7 +7,7 @@ import writeXlsxFile from 'write-excel-file/node'; import { downloadIpfsImages, generateImage, generatePfps, readPfpLayerSpecs } from '../../services/pfp-service.js'; import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'; import { PfpManifest } from '../../types/pfps.js'; -import ora from 'ora'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; export default class GeneratePfpsCommand extends BaseCommand { static examples = [ @@ -61,10 +61,10 @@ export default class GeneratePfpsCommand extends BaseCommand { const manifestPath = join(output, 'manifest.json'); const imagesFolder = join(output, 'images'); const excelPath = join(output, 'pfps.xlsx'); - const spinner = ora(); + const spinner = makeSpinner(); if (existsSync(manifestPath)) { - const overwrite = await ux.confirm('Manifest file already exists, do you want to overwrite the pfp results? y/n'); + const overwrite = await confirmPrompt('Manifest file already exists, do you want to overwrite the pfp results?'); if (!overwrite) { return; } else { diff --git a/src/commands/templates/create.ts b/src/commands/templates/create.ts index c889486..3a2d204 100644 --- a/src/commands/templates/create.ts +++ b/src/commands/templates/create.ts @@ -1,4 +1,4 @@ -import { Args, Flags, ux } from '@oclif/core'; +import { Args, Flags } from '@oclif/core'; import { getCollectionSchemas } from '../../services/schema-service.js'; import { createTemplates } from '../../services/template-service.js'; import { Row } from 'read-excel-file'; @@ -8,6 +8,7 @@ import { TransactResult } from '@wharfkit/session'; import { BaseCommand } from '../../base/BaseCommand.js'; import { readExcelContents } from '../../utils/excel-utils.js'; import { AssetSchema, TemplateToCreate } from '../../types/index.js'; +import { confirmPrompt, makeSpinner, printTable } from '../../utils/tty-utils.js'; // Required headers const maxSupplyField = 'template_max_supply'; @@ -58,7 +59,7 @@ export default class CreateCommand extends BaseCommand { const config = await this.getCliConfig(); // Get Schemas - ux.action.start('Getting collection schemas'); + const spinner = makeSpinner('Getting collection schemas'); let schemasMap: Record = {}; try { const schemas = await getCollectionSchemas(collection, config); @@ -67,12 +68,12 @@ export default class CreateCommand extends BaseCommand { throw new Error(`Unable to obtain schemas for collection ${collection}`); } - ux.action.stop(); + spinner.succeed(); // Read XLS file const templates: TemplateToCreate[] = []; try { - ux.action.start('Reading templates in file'); + spinner.start('Reading templates in file'); const sheets = await readExcelContents(templatesFile); for (let i = 0; i < sheets.length; i++) { const { name, rows } = sheets[i]; @@ -83,43 +84,46 @@ export default class CreateCommand extends BaseCommand { } templates.push(...this.getTemplateToCreate(rows, schema)); } + spinner.succeed(); } catch (error: any) { + spinner.fail(); throw new Error(`Error reading file: ${error.message}`); - } finally { - ux.action.stop(); } const batches = getBatchesFromArray(templates, batchSize); batches.forEach((templatesBatch: any[]) => { - ux.table(templatesBatch, { - Schema: { - get: ({ schema }) => schema, + printTable( + { + Schema: { + get: ({ schema }) => schema, + }, + 'Max Supply': { + get: ({ maxSupply }) => (maxSupply > 0 ? maxSupply : '∞'), + }, + 'Burnable?': { + get: ({ isBurnable }) => isBurnable, + }, + 'Transferable?': { + get: ({ isTransferable }) => isTransferable, + }, + Attributes: { + get: ({ immutableAttributes }) => + <[Map]>( + immutableAttributes + .map((map: any) => `${>map.key}: ${>map.value[1]}`) + .join('\n') + ), + }, }, - 'Max Supply': { - get: ({ maxSupply }) => (maxSupply > 0 ? maxSupply : '∞'), - }, - 'Burnable?': { - get: ({ isBurnable }) => isBurnable, - }, - 'Transferable?': { - get: ({ isTransferable }) => isTransferable, - }, - Attributes: { - get: ({ immutableAttributes }) => - <[Map]>( - immutableAttributes - .map((map: any) => `${>map.key}: ${>map.value[1]}`) - .join('\n') - ), - }, - }); + templatesBatch, + ); }); let totalCreated = 0; - const proceed = await ux.confirm('Continue? y/n'); + const proceed = await confirmPrompt('Continue?'); // Create Templates - ux.action.start('Creating Templates...'); + spinner.start('Creating Templates...'); if (proceed) { try { for (const templatesBatch of batches) { @@ -130,12 +134,12 @@ export default class CreateCommand extends BaseCommand { ); totalCreated += templatesBatch.length; } + spinner.succeed(); } catch (error: any) { + spinner.fail(); this.warn(`Error after creating ~${totalCreated}`); throw new Error(error.message); } - - ux.action.stop(); } } diff --git a/src/commands/templates/export.ts b/src/commands/templates/export.ts index 05cc32f..e16c25b 100644 --- a/src/commands/templates/export.ts +++ b/src/commands/templates/export.ts @@ -1,4 +1,4 @@ -import { Args, Flags, ux } from '@oclif/core'; +import { Args, Flags } from '@oclif/core'; import { getTemplatesForCollection, getTemplatesFromSchema } from '../../services/template-service.js'; import { BaseCommand } from '../../base/BaseCommand.js'; import writeXlsxFile from 'write-excel-file/node'; @@ -7,6 +7,7 @@ import { ITemplate } from 'atomicassets/build/API/Explorer/Objects.js'; import { getXlsType, transformValueToType } from '../../utils/attributes-utils.js'; import { fileExists } from '../../utils/file-utils.js'; import { AssetSchema } from '../../types/index.js'; +import { confirmPrompt, makeSpinner } from '../../utils/tty-utils.js'; const headers = [ { @@ -68,33 +69,34 @@ export default class ExportTemplateCommand extends BaseCommand { const templates: ITemplate[] = []; if (fileExists(output)) { - const proceed = await ux.confirm('File already exists. Do you want to overwrite it? y/n'); + const proceed = await confirmPrompt('File already exists. Do you want to overwrite it?'); if (!proceed) { return; } } + const spinner = makeSpinner(); if (schema) { - ux.action.start('Getting schema...'); + spinner.start('Getting schema...'); schemas.push(await getSchema(collection, schema, config)); - ux.action.stop(); + spinner.succeed(); - ux.action.start('Getting templates...'); + spinner.start('Getting templates...'); templates.push(...(await getTemplatesFromSchema(collection, schema, config))); - ux.action.stop(); + spinner.succeed(); } else { - ux.action.start('Getting schemas...'); + spinner.start('Getting schemas...'); schemas.push(...(await getCollectionSchemas(collection, config))); - ux.action.stop(); + spinner.succeed(); - ux.action.start('Getting templates...'); + spinner.start('Getting templates...'); templates.push(...(await getTemplatesForCollection(collection, config))); - ux.action.stop(); + spinner.succeed(); } - ux.action.start('Generating file...'); + spinner.start('Generating file...'); await this.generateExcelFile(schemas, templates, output); - ux.action.stop(); + spinner.succeed(); this.log(`File generated at ${output}`); } diff --git a/src/commands/tokens/transfer.ts b/src/commands/tokens/transfer.ts index 270d6f4..e40e7ea 100644 --- a/src/commands/tokens/transfer.ts +++ b/src/commands/tokens/transfer.ts @@ -1,9 +1,10 @@ -import { ux, Flags, Args } from '@oclif/core'; +import { Flags, Args } from '@oclif/core'; import { getBatchesFromArray } from '../../utils/array-utils.js'; import { TransferAction } from '../../types/index.js'; import { TransactResult } from '@wharfkit/session'; import { BaseCommand } from '../../base/BaseCommand.js'; import { readTransferFile, transfer } from '../../services/token-service.js'; +import { confirmPrompt, makeSpinner, printTable } from '../../utils/tty-utils.js'; export default class TransferCommand extends BaseCommand { static description = 'Transfers tokens in batches using a spreadsheet.'; @@ -34,13 +35,14 @@ export default class TransferCommand extends BaseCommand { // Read XLS file let transfers: TransferAction[]; + const spinner = makeSpinner(); try { - ux.action.start('Reading transfers in file'); + spinner.start('Reading transfers in file'); transfers = await readTransferFile({ filePathOrSheetsId: transfersFile, config }); + spinner.succeed(); } catch (error: any) { + spinner.fail(); throw new Error(`Error reading file: ${error.message}`); - } finally { - ux.action.stop(); } // Create table columns and print table @@ -51,30 +53,26 @@ export default class TransferCommand extends BaseCommand { recipient: { get: (row: TransferAction) => row.data.to }, memo: { get: (row: TransferAction) => row.data.memo }, }; - ux.table(transfers, columns); + printTable(columns, transfers); - const proceed = await ux.confirm('Continue? y/n'); + const proceed = await confirmPrompt('Continue?'); if (!proceed) return; - ux.action.start('Transferring assets...'); - const actionBatches = getBatchesFromArray(transfers, batchSize); - let totalExecuted = 0; try { for (const transferActions of actionBatches) { + const spinner = makeSpinner('Transferring assets...'); const result = (await transfer(transferActions, config)) as TransactResult; const txId = result.resolved?.transaction.id; - this.log( + spinner.succeed( `${transferActions.length} transfers successful. Transaction: ${config.explorerUrl}/transaction/${txId}`, ); - totalExecuted += transferActions.length; } } catch (error) { + spinner.fail(); throw Error(`ERROR after executing ${totalExecuted} transfers successfully: ` + error); - } finally { - ux.action.stop(); } } } diff --git a/src/services/mint-service.ts b/src/services/mint-service.ts index 20e8541..628a67b 100644 --- a/src/services/mint-service.ts +++ b/src/services/mint-service.ts @@ -1,7 +1,6 @@ import { ITemplate } from 'atomicassets/build/API/Explorer/Objects.js'; import { AssetSchema, CliConfig, MintRow } from '../types/index.js'; import { Row } from 'read-excel-file'; -import { ux } from '@oclif/core'; import { getTemplatesMap } from './template-service.js'; import { getXlsType, isValidAttribute, transformValueToType, typeAliases } from '../utils/attributes-utils.js'; import writeXlsxFile from 'write-excel-file/node'; @@ -62,10 +61,8 @@ export async function readExcelMintRows( return templateId; }); - ux.action.start('Checking Templates...'); const templatesMap = await getTemplatesMap(templateIds, config); const mintedCounts: Record = {}; - ux.action.stop(); const mints: any[] = []; contentRows.forEach((row: any, index: number) => { @@ -90,7 +87,7 @@ export async function readExcelMintRows( schema.format.forEach((attr: { name: string; type: string }) => { let value = row[headersMap[attr.name]]; if (headersMap[attr.name] === undefined) { - ux.warn( + console.warn( `The attribute: '${attr.name}' of schema: '${ schema.name }' is not in any of the columns of the spreadsheet in row ${index + 2}`, @@ -98,7 +95,7 @@ export async function readExcelMintRows( } if (value !== null && value !== undefined) { if (attr.name in inmutableData) { - ux.warn( + console.warn( `Schema contains attribute "${ attr.name }" with value: "${value}", ignoring attribute from spreadsheet in row ${index + 2}`, @@ -107,7 +104,7 @@ export async function readExcelMintRows( } const type = typeAliases[attr.type] || attr.type; if (!isValidAttribute(attr.type, value)) { - ux.warn( + console.warn( `The attribute: '${attr.name}' with value: '${value}' is not of type ${attr.type} for schema: '${ schema.name }' in row ${index + 2}`, diff --git a/src/services/pfp-service.ts b/src/services/pfp-service.ts index f453ec1..0eaf759 100644 --- a/src/services/pfp-service.ts +++ b/src/services/pfp-service.ts @@ -15,7 +15,7 @@ import crypto from 'crypto'; import { readFile, downloadImage } from '../utils/file-utils.js'; import { SheetContents, getSheetHeader, readExcelContents } from '../utils/excel-utils.js'; import { Row } from 'read-excel-file'; -import { ux } from '@oclif/core'; +import { makeSpinner } from '../utils/tty-utils.js'; export const forceSheetName = '_force_'; export const idHeader = 'id'; @@ -47,7 +47,7 @@ export async function readPfpLayerSpecs({ let forcedPfps; if (filePathOrSheetsId.split('.').pop() === 'json') { const jsonString = readFile(filePathOrSheetsId); - ux.log('JSON file detected, reading...'); + const spinner = makeSpinner('Reading JSON file...'); try { const json = JSON.parse(jsonString); const pfpBlockRules = json.blockRules; @@ -61,7 +61,9 @@ export async function readPfpLayerSpecs({ layersFolder: layersRelativePath, }), ); + spinner.succeed(); } catch (e) { + spinner.fail(); throw new Error(`Error in JSON file ${filePathOrSheetsId}: ${e}`); } forcedPfps = undefined; diff --git a/src/services/schema-service.ts b/src/services/schema-service.ts index 02134ef..7cd8d05 100644 --- a/src/services/schema-service.ts +++ b/src/services/schema-service.ts @@ -1,7 +1,6 @@ import { getAtomicRpc, transact } from './antelope-service.js'; import { AssetSchema, CliConfig, SettingsConfig } from '../types/index.js'; import { TransactResult } from '@wharfkit/session'; -import { ux } from '@oclif/core'; export async function getCollectionSchemas(collection: string, config: SettingsConfig): Promise { const result = await getAtomicRpc(config.rpcUrl).getCollectionsSchemas(collection); @@ -55,7 +54,6 @@ export async function createSchema( config, ); } catch (error) { - ux.error('Error creating Schema'); throw error; } } diff --git a/src/services/template-service.ts b/src/services/template-service.ts index e28d167..bba1da8 100644 --- a/src/services/template-service.ts +++ b/src/services/template-service.ts @@ -6,7 +6,6 @@ import { getAtomicApi, transact } from './antelope-service.js'; import { getBatchesFromArray } from '../utils/array-utils.js'; import { CliConfig, SettingsConfig, TemplateIdentifier, TemplateToCreate } from '../types/index.js'; import { TransactResult } from '@wharfkit/session'; -import { ux } from '@oclif/core'; export async function getTemplate(collection: string, templateId: string, config: SettingsConfig): Promise { return getAtomicApi(config.aaUrl).getTemplate(collection, templateId); @@ -165,7 +164,6 @@ export async function createTemplates( try { return await transact(actions, config); } catch (error) { - ux.error('Error while creating templates...'); throw error; } } diff --git a/src/utils/tty-utils.ts b/src/utils/tty-utils.ts new file mode 100644 index 0000000..937c3f3 --- /dev/null +++ b/src/utils/tty-utils.ts @@ -0,0 +1,76 @@ +import { confirm, input, password } from '@inquirer/prompts'; +import { ux } from '@oclif/core'; +import ora, { Ora, Options } from 'ora'; +import terminalLink from 'terminal-link'; + +let currentSpinner: Ora | undefined = undefined; + +export type Columns> = { + [key: string]: Partial>; +}; + +export interface Column> { + extended: boolean; + get(row: T): any; + header: string; + minWidth: number; +} + +export function printTable(columns: Columns, rows: Record[]): void { + ux.table(rows, columns); +} + +export async function confirmPrompt(message: string, skip = false): Promise { + if (skip) { + return true; + } + + const value = await confirm({ + message: message, + default: false, + }); + + return value; +} + +export async function passwordPrompt(message: string): Promise { + if (currentSpinner) { + currentSpinner.stopAndPersist(); + } + + const value = await password({ + message: message, + mask: true, + }); + + if (currentSpinner) { + currentSpinner.start(); + } + + return value; +} + +export async function inputPrompt(message: string): Promise { + if (currentSpinner) { + currentSpinner.stopAndPersist(); + } + const value = await input({ + message: message, + }); + if (currentSpinner) { + currentSpinner.start(); + } + return value; +} + +export function makeSpinner(options?: string | Options): Ora { + currentSpinner = ora(options); + return currentSpinner; +} + +export function printLink(text: string, uri: string): void { + const link = terminalLink(text, uri, { + fallback: (_, url) => url, + }); + console.log(link); +} diff --git a/src/wallet/ConsoleRenderer.ts b/src/wallet/ConsoleRenderer.ts index f7d1b5a..da1922a 100644 --- a/src/wallet/ConsoleRenderer.ts +++ b/src/wallet/ConsoleRenderer.ts @@ -49,32 +49,8 @@ import { } from '@wharfkit/session'; import qrcode from 'qrcode-terminal'; import { select, input } from '@inquirer/prompts'; -import { ux } from '@oclif/core'; import { validateAccountName, validatePermissionName } from '../utils/validation-utils.js'; - -export function countdown(expirationTimeString?: string, interval = 10000) { - const expirationTime = expirationTimeString ? Date.parse(expirationTimeString) : Date.now() + 120000; - const startTime = Date.now(); - const remainingTime = expirationTime - startTime; - - const intervalId = setInterval(() => { - const elapsedTime = Date.now() - startTime; - const remainingSeconds = Math.ceil((remainingTime - elapsedTime) / 1000); - - if (remainingSeconds <= 0) { - clearInterval(intervalId); - ux.info('Time is up!'); - - return process.exit(1); - } - - const minutes = Math.floor(remainingSeconds / 60); - const seconds = remainingSeconds % 60; - ux.info(`Time remaining: ${minutes}:${seconds.toString().padStart(2, '0')}`); - }, interval); - - return () => clearInterval(intervalId); -} +import { printLink } from '../utils/tty-utils.js'; export class ConsoleUserInterface implements UserInterface { async login(context: LoginContext): Promise { @@ -214,7 +190,9 @@ export class ConsoleUserInterface implements UserInterface { * The UserInterface can decide how to surface this information to the user. */ - ux.info(`${message}`); + if (message) { + console.log(message); + } } prompt(args: PromptArgs): Cancelable { @@ -226,22 +204,27 @@ export class ConsoleUserInterface implements UserInterface { * The return value should be a boolean indicating whether the user selected yes or no. */ - ux.info(`${args.title}`); - ux.info(`${args.body}`); + if (args.title) { + console.log(`${args.title}`); + } + + if (args.body) { + console.log(`${args.body}`); + } const onEndCallbacks: (() => void)[] = []; args.elements.forEach((element: PromptElement) => { if (element.label) { - ux.info(`${element.label}`); + console.log(`${element.label}`); } if (element.type === 'qr') { qrcode.generate(element.data as string, { small: true }); } else if (element.type === 'link') { const url = (element.data as any)?.href; - ux.info('If unable to click the link, please copy and paste the link into your browser:'); - ux.url(url, url); + console.log('If unable to click the link, please copy and paste the link into your browser:'); + printLink(url, url); } }); diff --git a/src/wallet/WalletPluginSecurePrivateKey.ts b/src/wallet/WalletPluginSecurePrivateKey.ts index a5b818c..bb1993f 100644 --- a/src/wallet/WalletPluginSecurePrivateKey.ts +++ b/src/wallet/WalletPluginSecurePrivateKey.ts @@ -51,8 +51,8 @@ import { } from '@wharfkit/session'; import { password } from '@inquirer/prompts'; import { decrypt, encrypt } from '../utils/crypto-utils.js'; -import { ux } from '@oclif/core'; import { validatePrivateKey } from '../utils/validation-utils.js'; +import { passwordPrompt } from '../utils/tty-utils.js'; let cachedPassword: string | undefined; @@ -146,7 +146,7 @@ export class WalletPluginSecurePrivateKey extends AbstractWalletPlugin implement async handleSign(resolved: ResolvedSigningRequest, context: TransactContext): Promise { if (!cachedPassword) { - cachedPassword = await ux.prompt('Enter your password to decrypt the private key', { type: 'hide' }); + cachedPassword = await passwordPrompt('Enter your password to decrypt the private key'); } const privateKeyString = decrypt(this.data.encryptedPrivateKey, cachedPassword); diff --git a/yarn.lock b/yarn.lock index 9e6eaf2..b4e0c08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1334,13 +1334,6 @@ multiformats "^13.1.0" uint8arrays "^5.0.3" -"@ljharb/through@^2.3.13": - version "2.3.13" - resolved "https://registry.yarnpkg.com/@ljharb/through/-/through-2.3.13.tgz#b7e4766e0b65aa82e529be945ab078de79874edc" - integrity sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ== - dependencies: - call-bind "^1.0.7" - "@multiformats/dns@^1.0.3": version "1.0.6" resolved "https://registry.yarnpkg.com/@multiformats/dns/-/dns-1.0.6.tgz#b8c7de11459a02a5f4e609d35d3cdb95cb6ad152" @@ -3193,7 +3186,7 @@ binary@~0.3.0: buffers "~0.1.1" chainsaw "~0.1.0" -bl@^4.0.3, bl@^4.1.0: +bl@^4.0.3: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== @@ -3366,17 +3359,6 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" -call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" @@ -3558,13 +3540,6 @@ cli-columns@^4.0.0: string-width "^4.2.3" strip-ansi "^6.0.1" -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - cli-cursor@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" @@ -3579,7 +3554,7 @@ cli-progress@^3.12.0: dependencies: string-width "^4.2.3" -cli-spinners@^2.5.0, cli-spinners@^2.9.2: +cli-spinners@^2.9.2: version "2.9.2" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== @@ -3848,15 +3823,6 @@ define-data-property@^1.0.1: gopd "^1.0.1" has-property-descriptors "^1.0.0" -define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - define-properties@^1.1.3, define-properties@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" @@ -4122,18 +4088,6 @@ es-abstract@^1.22.1: unbox-primitive "^1.0.2" which-typed-array "^1.1.11" -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - es-set-tostringtag@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" @@ -4848,17 +4802,6 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: has-proto "^1.0.1" has-symbols "^1.0.3" -get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - get-iterator@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-iterator/-/get-iterator-1.0.2.tgz#cd747c02b4c084461fac14f48f6b45a80ed25c82" @@ -5067,13 +5010,6 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" -has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - has-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" @@ -5315,27 +5251,6 @@ init-package-json@^6.0.0: validate-npm-package-license "^3.0.4" validate-npm-package-name "^5.0.0" -inquirer@^9.2.19: - version "9.2.19" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.2.19.tgz#e142ebc111b6328a21eb84d8e7dd226ff824239e" - integrity sha512-WpxOT71HGsFya6/mj5PUue0sWwbpbiPfAR+332zLj/siB0QA1PZM8v3GepegFV1Op189UxHUCF6y8AySdtOMVA== - dependencies: - "@inquirer/figures" "^1.0.1" - "@ljharb/through" "^2.3.13" - ansi-escapes "^4.3.2" - chalk "^5.3.0" - cli-cursor "^3.1.0" - cli-width "^4.1.0" - external-editor "^3.1.0" - lodash "^4.17.21" - mute-stream "1.0.0" - ora "^5.4.1" - run-async "^3.0.0" - rxjs "^7.8.1" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wrap-ansi "^6.2.0" - interface-datastore@^8.2.11: version "8.2.11" resolved "https://registry.yarnpkg.com/interface-datastore/-/interface-datastore-8.2.11.tgz#1d555ce6218ab6cba6291fc361debe9713590207" @@ -5523,11 +5438,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - is-interactive@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-2.0.0.tgz#40c57614593826da1100ade6059778d597f16e90" @@ -6194,7 +6104,7 @@ lodash@^4.17.13, lodash@^4.17.21: resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@4.1.0, log-symbols@^4.1.0: +log-symbols@4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -6556,7 +6466,7 @@ multiformats@^13.0.0, multiformats@^13.1.0: resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.1.0.tgz#5aa9d2175108a448fc3bdb54ba8a3d0b6cab3ac3" integrity sha512-HzdtdBwxsIkzpeXzhQ5mAhhuxcHbjEHH+JQoxt7hG/2HGFjjwyolLo7hbaexcnhoEuV4e0TNJ8kkpMjiEYY4VQ== -mute-stream@1.0.0, mute-stream@^1.0.0, mute-stream@~1.0.0: +mute-stream@^1.0.0, mute-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== @@ -7043,21 +6953,6 @@ optionator@^0.9.3: prelude-ls "^1.2.1" type-check "^0.4.0" -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - ora@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ora/-/ora-8.0.1.tgz#6dcb9250a629642cbe0d2df3a6331ad6f7a2af3e" @@ -7739,14 +7634,6 @@ responselike@^3.0.0: dependencies: lowercase-keys "^3.0.0" -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - restore-cursor@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" @@ -7801,7 +7688,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.2.0, rxjs@^7.8.1: +rxjs@^7.2.0: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== @@ -7880,18 +7767,6 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-function-length@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - set-function-name@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -8429,6 +8304,14 @@ tar@^6.1.11, tar@^6.1.2, tar@^6.2.0: mkdirp "^1.0.3" yallist "^4.0.0" +terminal-link@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-3.0.0.tgz#91c82a66b52fc1684123297ce384429faf72ac5c" + integrity sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg== + dependencies: + ansi-escapes "^5.0.0" + supports-hyperlinks "^2.2.0" + text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -8756,7 +8639,7 @@ walk-up-path@^3.0.1: resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-3.0.1.tgz#c8d78d5375b4966c717eb17ada73dbd41490e886" integrity sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA== -wcwidth@^1.0.0, wcwidth@^1.0.1: +wcwidth@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==