diff --git a/packages/cli/docsgen/markdown.ts b/packages/cli/docsgen/markdown.ts index e7fbcab7ad4b..4ca0d5b21e99 100644 --- a/packages/cli/docsgen/markdown.ts +++ b/packages/cli/docsgen/markdown.ts @@ -1,4 +1,4 @@ -import {CliOptionDefinition, CliCommand, CliExample, CliCommandOptions} from "../src/util/index.js"; +import {CliOptionDefinition, CliCommand, CliExample, CliCommandOptions} from "@lodestar/utils"; import {toKebab} from "./changeCase.js"; const DEFAULT_SEPARATOR = "\n\n"; diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index bfc5372cc3e8..e8f4aeba8ebc 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -1,9 +1,9 @@ // Must not use `* as yargs`, see https://github.com/yargs/yargs/issues/1131 import yargs from "yargs"; import {hideBin} from "yargs/helpers"; +import {registerCommandToYargs} from "@lodestar/utils"; import {cmds} from "./cmds/index.js"; import {globalOptions, rcConfigOption} from "./options/index.js"; -import {registerCommandToYargs} from "./util/index.js"; import {getVersionData} from "./util/version.js"; const {version} = getVersionData(); diff --git a/packages/cli/src/cmds/beacon/index.ts b/packages/cli/src/cmds/beacon/index.ts index 38d1d4cad221..b6d5c26f6fed 100644 --- a/packages/cli/src/cmds/beacon/index.ts +++ b/packages/cli/src/cmds/beacon/index.ts @@ -1,4 +1,4 @@ -import {CliCommand, CliCommandOptions} from "../../util/index.js"; +import {CliCommand, CliCommandOptions} from "@lodestar/utils"; import {GlobalArgs} from "../../options/index.js"; import {beaconOptions, BeaconArgs} from "./options.js"; import {beaconHandler} from "./handler.js"; diff --git a/packages/cli/src/cmds/beacon/options.ts b/packages/cli/src/cmds/beacon/options.ts index a1d5b35fe5de..1ec508696a13 100644 --- a/packages/cli/src/cmds/beacon/options.ts +++ b/packages/cli/src/cmds/beacon/options.ts @@ -1,6 +1,6 @@ +import {CliCommandOptions, CliOptionDefinition} from "@lodestar/utils"; import {beaconNodeOptions, paramsOptions, BeaconNodeArgs} from "../../options/index.js"; import {LogArgs, logOptions} from "../../options/logOptions.js"; -import {CliCommandOptions, CliOptionDefinition} from "../../util/index.js"; import {defaultBeaconPaths, BeaconPaths} from "./paths.js"; type BeaconExtraArgs = { diff --git a/packages/cli/src/cmds/bootnode/index.ts b/packages/cli/src/cmds/bootnode/index.ts index 4030c4a73b0f..c429f42b1fbe 100644 --- a/packages/cli/src/cmds/bootnode/index.ts +++ b/packages/cli/src/cmds/bootnode/index.ts @@ -1,4 +1,4 @@ -import {CliCommand, CliCommandOptions} from "../../util/index.js"; +import {CliCommand, CliCommandOptions} from "@lodestar/utils"; import {GlobalArgs} from "../../options/index.js"; import {bootnodeOptions, BootnodeArgs} from "./options.js"; import {bootnodeHandler} from "./handler.js"; diff --git a/packages/cli/src/cmds/bootnode/options.ts b/packages/cli/src/cmds/bootnode/options.ts index ab92ec00e155..dd597e6a22ef 100644 --- a/packages/cli/src/cmds/bootnode/options.ts +++ b/packages/cli/src/cmds/bootnode/options.ts @@ -1,5 +1,5 @@ +import {CliOptionDefinition, CliCommandOptions} from "@lodestar/utils"; import {LogArgs, logOptions} from "../../options/logOptions.js"; -import {CliOptionDefinition, CliCommandOptions} from "../../util/index.js"; import {MetricsArgs, options as metricsOptions} from "../../options/beaconNodeOptions/metrics.js"; import {defaultListenAddress, defaultP2pPort, defaultP2pPort6} from "../../options/beaconNodeOptions/network.js"; diff --git a/packages/cli/src/cmds/dev/index.ts b/packages/cli/src/cmds/dev/index.ts index d213c8b3218d..6c0f73327816 100644 --- a/packages/cli/src/cmds/dev/index.ts +++ b/packages/cli/src/cmds/dev/index.ts @@ -1,4 +1,4 @@ -import {CliCommand, CliCommandOptions} from "../../util/index.js"; +import {CliCommand, CliCommandOptions} from "@lodestar/utils"; import {GlobalArgs} from "../../options/index.js"; import {devOptions, IDevArgs} from "./options.js"; import {devHandler} from "./handler.js"; diff --git a/packages/cli/src/cmds/dev/options.ts b/packages/cli/src/cmds/dev/options.ts index 4665fe529776..c484150e58d7 100644 --- a/packages/cli/src/cmds/dev/options.ts +++ b/packages/cli/src/cmds/dev/options.ts @@ -1,4 +1,4 @@ -import {CliCommandOptions, CliOptionDefinition} from "../../util/index.js"; +import {CliCommandOptions, CliOptionDefinition} from "@lodestar/utils"; import {beaconOptions, BeaconArgs} from "../beacon/options.js"; import {NetworkName} from "../../networks/index.js"; import {beaconNodeOptions, globalOptions} from "../../options/index.js"; diff --git a/packages/cli/src/cmds/index.ts b/packages/cli/src/cmds/index.ts index 849cb23d9af7..7f701379b097 100644 --- a/packages/cli/src/cmds/index.ts +++ b/packages/cli/src/cmds/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../util/index.js"; +import {CliCommand} from "@lodestar/utils"; import {GlobalArgs} from "../options/index.js"; import {beacon} from "./beacon/index.js"; import {dev} from "./dev/index.js"; diff --git a/packages/cli/src/cmds/lightclient/handler.ts b/packages/cli/src/cmds/lightclient/handler.ts index 1aaaac5075a1..02bb98cb4d1d 100644 --- a/packages/cli/src/cmds/lightclient/handler.ts +++ b/packages/cli/src/cmds/lightclient/handler.ts @@ -7,7 +7,6 @@ import {getNodeLogger} from "@lodestar/logger/node"; import {getBeaconConfigFromArgs} from "../../config/beaconParams.js"; import {getGlobalPaths} from "../../paths/global.js"; import {parseLoggerArgs} from "../../util/logger.js"; -import {YargsError} from "../../util/errors.js"; import {GlobalArgs} from "../../options/index.js"; import {ILightClientArgs} from "./options.js"; @@ -19,11 +18,7 @@ export async function lightclientHandler(args: ILightClientArgs & GlobalArgs): P parseLoggerArgs(args, {defaultLogFilepath: path.join(globalPaths.dataDir, "lightclient.log")}, config) ); - const {beaconApiUrl, checkpointRoot} = args; - if (!beaconApiUrl) throw new YargsError("must provide beaconApiUrl arg"); - if (!checkpointRoot) throw new YargsError("must provide checkpointRoot arg"); - - const api = getClient({baseUrl: beaconApiUrl}, {config}); + const api = getClient({baseUrl: args.beaconApiUrl}, {config}); const res = await api.beacon.getGenesis(); ApiError.assert(res, "Can not fetch genesis data"); @@ -34,7 +29,7 @@ export async function lightclientHandler(args: ILightClientArgs & GlobalArgs): P genesisTime: Number(res.response.data.genesisTime), genesisValidatorsRoot: res.response.data.genesisValidatorsRoot, }, - checkpointRoot: fromHexString(checkpointRoot), + checkpointRoot: fromHexString(args.checkpointRoot), transport: new LightClientRestTransport(api), }); diff --git a/packages/cli/src/cmds/lightclient/index.ts b/packages/cli/src/cmds/lightclient/index.ts index 1fceb3823154..e896a49abc56 100644 --- a/packages/cli/src/cmds/lightclient/index.ts +++ b/packages/cli/src/cmds/lightclient/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; import {GlobalArgs} from "../../options/index.js"; import {ILightClientArgs, lightclientOptions} from "./options.js"; import {lightclientHandler} from "./handler.js"; diff --git a/packages/cli/src/cmds/lightclient/options.ts b/packages/cli/src/cmds/lightclient/options.ts index 1dd1ddab8f00..d8a3f2f99861 100644 --- a/packages/cli/src/cmds/lightclient/options.ts +++ b/packages/cli/src/cmds/lightclient/options.ts @@ -1,9 +1,9 @@ +import {CliCommandOptions} from "@lodestar/utils"; import {LogArgs, logOptions} from "../../options/logOptions.js"; -import {CliCommandOptions} from "../../util/index.js"; export type ILightClientArgs = LogArgs & { - beaconApiUrl?: string; - checkpointRoot?: string; + beaconApiUrl: string; + checkpointRoot: string; }; export const lightclientOptions: CliCommandOptions = { @@ -11,9 +11,11 @@ export const lightclientOptions: CliCommandOptions = { beaconApiUrl: { description: "Url to a beacon node that support lightclient API", type: "string", + demandOption: true, }, checkpointRoot: { description: "Checkpoint root hex string to sync the lightclient from, start with 0x", type: "string", + demandOption: true, }, }; diff --git a/packages/cli/src/cmds/validator/blsToExecutionChange.ts b/packages/cli/src/cmds/validator/blsToExecutionChange.ts index ec81a9370bd3..7452840e1c71 100644 --- a/packages/cli/src/cmds/validator/blsToExecutionChange.ts +++ b/packages/cli/src/cmds/validator/blsToExecutionChange.ts @@ -6,8 +6,8 @@ import {DOMAIN_BLS_TO_EXECUTION_CHANGE, ForkName} from "@lodestar/params"; import {createBeaconConfig} from "@lodestar/config"; import {ssz, capella} from "@lodestar/types"; import {ApiError, getClient} from "@lodestar/api"; +import {CliCommand} from "@lodestar/utils"; -import {CliCommand, YargsError} from "../../util/index.js"; import {GlobalArgs} from "../../options/index.js"; import {getBeaconConfigFromArgs} from "../../config/index.js"; import {IValidatorCliArgs} from "./options.js"; @@ -15,9 +15,9 @@ import {IValidatorCliArgs} from "./options.js"; /* eslint-disable no-console */ type BlsToExecutionChangeArgs = { - publicKey?: string; - fromBlsPrivkey?: string; - toExecutionAddress?: string; + publicKey: string; + fromBlsPrivkey: string; + toExecutionAddress: string; }; export const blsToExecutionChange: CliCommand = { @@ -39,26 +39,22 @@ like to choose for BLS To Execution Change.", publicKey: { description: "Validator public key for which to set withdrawal address hence enabling withdrawals", type: "string", - string: true, + demandOption: true, }, fromBlsPrivkey: { description: "Bls withdrawals private key to sign the message", type: "string", - string: true, + demandOption: true, }, toExecutionAddress: { description: "Address to which the validator's balances will be set to be withdrawn.", type: "string", - string: true, + demandOption: true, }, }, handler: async (args) => { - const {publicKey, fromBlsPrivkey, toExecutionAddress} = args; - if (!publicKey) throw new YargsError("must provide publicKey arg"); - if (!fromBlsPrivkey) throw new YargsError("must provide fromBlsPrivkey arg"); - if (!toExecutionAddress) throw new YargsError("must provide toExecutionAddress arg"); - + const {publicKey} = args; // Fetch genesisValidatorsRoot always from beacon node as anyway beacon node is needed for // submitting the signed message const {config: chainForkConfig} = getBeaconConfigFromArgs(args); @@ -76,13 +72,13 @@ like to choose for BLS To Execution Change.", throw new Error(`Validator pubkey ${publicKey} not found in state`); } - const blsPrivkey = bls.SecretKey.fromBytes(fromHexString(fromBlsPrivkey)); + const blsPrivkey = bls.SecretKey.fromBytes(fromHexString(args.fromBlsPrivkey)); const fromBlsPubkey = blsPrivkey.toPublicKey().toBytes(PointFormat.compressed); const blsToExecutionChange: capella.BLSToExecutionChange = { validatorIndex: stateValidator.index, fromBlsPubkey, - toExecutionAddress: fromHexString(toExecutionAddress), + toExecutionAddress: fromHexString(args.toExecutionAddress), }; const signatureFork = ForkName.phase0; diff --git a/packages/cli/src/cmds/validator/import.ts b/packages/cli/src/cmds/validator/import.ts index a39dfcc16f74..58ae8a033de6 100644 --- a/packages/cli/src/cmds/validator/import.ts +++ b/packages/cli/src/cmds/validator/import.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import {Keystore} from "@chainsafe/bls-keystore"; -import {YargsError, CliCommand, getPubkeyHexFromKeystore} from "../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; +import {YargsError, getPubkeyHexFromKeystore} from "../../util/index.js"; import {getBeaconConfigFromArgs} from "../../config/beaconParams.js"; import {GlobalArgs} from "../../options/index.js"; import {validatorOptions, IValidatorCliArgs} from "./options.js"; diff --git a/packages/cli/src/cmds/validator/index.ts b/packages/cli/src/cmds/validator/index.ts index 49c7211c740d..c8b55bf4600a 100644 --- a/packages/cli/src/cmds/validator/index.ts +++ b/packages/cli/src/cmds/validator/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; import {GlobalArgs} from "../../options/index.js"; import {getAccountPaths} from "./paths.js"; import {slashingProtection} from "./slashingProtection/index.js"; diff --git a/packages/cli/src/cmds/validator/list.ts b/packages/cli/src/cmds/validator/list.ts index ae713bcbdecb..4e867b042b37 100644 --- a/packages/cli/src/cmds/validator/list.ts +++ b/packages/cli/src/cmds/validator/list.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; import {getBeaconConfigFromArgs} from "../../config/beaconParams.js"; import {GlobalArgs} from "../../options/index.js"; import {IValidatorCliArgs} from "./options.js"; diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index a5b4044f6867..7fdcdec59e86 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -1,6 +1,7 @@ import {defaultOptions} from "@lodestar/validator"; +import {CliCommandOptions} from "@lodestar/utils"; import {LogArgs, logOptions} from "../../options/logOptions.js"; -import {ensure0xPrefix, CliCommandOptions} from "../../util/index.js"; +import {ensure0xPrefix} from "../../util/index.js"; import {keymanagerRestApiServerOptsDefault} from "./keymanager/server.js"; import {defaultAccountPaths, defaultValidatorPaths} from "./paths.js"; diff --git a/packages/cli/src/cmds/validator/slashingProtection/export.ts b/packages/cli/src/cmds/validator/slashingProtection/export.ts index 0e5b7a17833e..fb694feb058a 100644 --- a/packages/cli/src/cmds/validator/slashingProtection/export.ts +++ b/packages/cli/src/cmds/validator/slashingProtection/export.ts @@ -2,7 +2,8 @@ import path from "node:path"; import {toHexString} from "@chainsafe/ssz"; import {InterchangeFormatVersion} from "@lodestar/validator"; import {getNodeLogger} from "@lodestar/logger/node"; -import {CliCommand, YargsError, ensure0xPrefix, isValidatePubkeyHex, writeFile600Perm} from "../../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; +import {YargsError, ensure0xPrefix, isValidatePubkeyHex, writeFile600Perm} from "../../../util/index.js"; import {parseLoggerArgs} from "../../../util/logger.js"; import {GlobalArgs} from "../../../options/index.js"; import {LogArgs} from "../../../options/logOptions.js"; @@ -13,7 +14,7 @@ import {getGenesisValidatorsRoot, getSlashingProtection} from "./utils.js"; import {ISlashingProtectionArgs} from "./options.js"; type ExportArgs = { - file?: string; + file: string; pubkeys?: string[]; }; @@ -51,7 +52,6 @@ export const exportCmd: CliCommand { const {file} = args; - if (!file) throw new YargsError("must provide file arg"); const {config, network} = getBeaconConfigFromArgs(args); const validatorPaths = getValidatorPaths(args, network); diff --git a/packages/cli/src/cmds/validator/slashingProtection/import.ts b/packages/cli/src/cmds/validator/slashingProtection/import.ts index de7f1bd48bd7..20c37550526d 100644 --- a/packages/cli/src/cmds/validator/slashingProtection/import.ts +++ b/packages/cli/src/cmds/validator/slashingProtection/import.ts @@ -2,7 +2,7 @@ import fs from "node:fs"; import path from "node:path"; import {Interchange} from "@lodestar/validator"; import {getNodeLogger} from "@lodestar/logger/node"; -import {CliCommand, YargsError} from "../../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; import {parseLoggerArgs} from "../../../util/logger.js"; import {GlobalArgs} from "../../../options/index.js"; import {LogArgs} from "../../../options/logOptions.js"; @@ -13,7 +13,7 @@ import {getGenesisValidatorsRoot, getSlashingProtection} from "./utils.js"; import {ISlashingProtectionArgs} from "./options.js"; type ImportArgs = { - file?: string; + file: string; }; export const importCmd: CliCommand = @@ -39,7 +39,6 @@ export const importCmd: CliCommand { const {file} = args; - if (!file) throw new YargsError("must provide file arg"); const {config, network} = getBeaconConfigFromArgs(args); const validatorPaths = getValidatorPaths(args, network); diff --git a/packages/cli/src/cmds/validator/slashingProtection/index.ts b/packages/cli/src/cmds/validator/slashingProtection/index.ts index 5644b3e1126f..9c180c59c378 100644 --- a/packages/cli/src/cmds/validator/slashingProtection/index.ts +++ b/packages/cli/src/cmds/validator/slashingProtection/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../../../util/index.js"; +import {CliCommand} from "@lodestar/utils"; import {AccountValidatorArgs} from "../options.js"; import {ISlashingProtectionArgs, slashingProtectionOptions} from "./options.js"; import {importCmd} from "./import.js"; diff --git a/packages/cli/src/cmds/validator/slashingProtection/options.ts b/packages/cli/src/cmds/validator/slashingProtection/options.ts index ff2f109d7d4c..741d4c87742d 100644 --- a/packages/cli/src/cmds/validator/slashingProtection/options.ts +++ b/packages/cli/src/cmds/validator/slashingProtection/options.ts @@ -1,4 +1,4 @@ -import {CliCommandOptions} from "../../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; import {IValidatorCliArgs, validatorOptions} from "../options.js"; export type ISlashingProtectionArgs = Pick & { diff --git a/packages/cli/src/cmds/validator/voluntaryExit.ts b/packages/cli/src/cmds/validator/voluntaryExit.ts index c3c0360a8264..4676e94f7547 100644 --- a/packages/cli/src/cmds/validator/voluntaryExit.ts +++ b/packages/cli/src/cmds/validator/voluntaryExit.ts @@ -8,10 +8,10 @@ import { } from "@lodestar/state-transition"; import {createBeaconConfig, BeaconConfig} from "@lodestar/config"; import {phase0, ssz, ValidatorIndex, Epoch} from "@lodestar/types"; -import {toHex} from "@lodestar/utils"; +import {CliCommand, toHex} from "@lodestar/utils"; import {externalSignerPostSignature, SignableMessageType, Signer, SignerType} from "@lodestar/validator"; import {Api, ApiError, getClient} from "@lodestar/api"; -import {CliCommand, ensure0xPrefix, YargsError, wrapError} from "../../util/index.js"; +import {ensure0xPrefix, YargsError, wrapError} from "../../util/index.js"; import {GlobalArgs} from "../../options/index.js"; import {getBeaconConfigFromArgs} from "../../config/index.js"; import {IValidatorCliArgs} from "./options.js"; diff --git a/packages/cli/src/options/beaconNodeOptions/api.ts b/packages/cli/src/options/beaconNodeOptions/api.ts index ab3ceeff945d..996136f262ec 100644 --- a/packages/cli/src/options/beaconNodeOptions/api.ts +++ b/packages/cli/src/options/beaconNodeOptions/api.ts @@ -1,5 +1,5 @@ import {defaultOptions, IBeaconNodeOptions, allNamespaces} from "@lodestar/beacon-node"; -import {CliCommandOptions} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; const enabledAll = "*"; diff --git a/packages/cli/src/options/beaconNodeOptions/builder.ts b/packages/cli/src/options/beaconNodeOptions/builder.ts index 96388ddfe2dd..2c89cbad89d2 100644 --- a/packages/cli/src/options/beaconNodeOptions/builder.ts +++ b/packages/cli/src/options/beaconNodeOptions/builder.ts @@ -1,5 +1,6 @@ import {defaultExecutionBuilderHttpOpts, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions, YargsError} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; +import {YargsError} from "../../util/index.js"; export type ExecutionBuilderArgs = { builder: boolean; diff --git a/packages/cli/src/options/beaconNodeOptions/chain.ts b/packages/cli/src/options/beaconNodeOptions/chain.ts index a324e3060e1f..390ffb3ad2f6 100644 --- a/packages/cli/src/options/beaconNodeOptions/chain.ts +++ b/packages/cli/src/options/beaconNodeOptions/chain.ts @@ -1,6 +1,6 @@ import * as path from "node:path"; import {defaultOptions, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; export type ChainArgs = { suggestedFeeRecipient: string; diff --git a/packages/cli/src/options/beaconNodeOptions/eth1.ts b/packages/cli/src/options/beaconNodeOptions/eth1.ts index 196deb59161f..46654cca6b2e 100644 --- a/packages/cli/src/options/beaconNodeOptions/eth1.ts +++ b/packages/cli/src/options/beaconNodeOptions/eth1.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import {defaultOptions, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions, extractJwtHexSecret} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; +import {extractJwtHexSecret} from "../../util/index.js"; import {ExecutionEngineArgs} from "./execution.js"; export type Eth1Args = { diff --git a/packages/cli/src/options/beaconNodeOptions/execution.ts b/packages/cli/src/options/beaconNodeOptions/execution.ts index 58b372d26e52..f2f1b42fb2bf 100644 --- a/packages/cli/src/options/beaconNodeOptions/execution.ts +++ b/packages/cli/src/options/beaconNodeOptions/execution.ts @@ -1,6 +1,7 @@ import fs from "node:fs"; import {defaultExecutionEngineHttpOpts, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions, extractJwtHexSecret} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; +import {extractJwtHexSecret} from "../../util/index.js"; export type ExecutionEngineArgs = { "execution.urls": string[]; diff --git a/packages/cli/src/options/beaconNodeOptions/metrics.ts b/packages/cli/src/options/beaconNodeOptions/metrics.ts index dc328cfa5685..ba12a7546eae 100644 --- a/packages/cli/src/options/beaconNodeOptions/metrics.ts +++ b/packages/cli/src/options/beaconNodeOptions/metrics.ts @@ -1,5 +1,5 @@ import {defaultOptions, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; export type MetricsArgs = { metrics: boolean; diff --git a/packages/cli/src/options/beaconNodeOptions/monitoring.ts b/packages/cli/src/options/beaconNodeOptions/monitoring.ts index f9224dca684f..2143277df2ae 100644 --- a/packages/cli/src/options/beaconNodeOptions/monitoring.ts +++ b/packages/cli/src/options/beaconNodeOptions/monitoring.ts @@ -1,5 +1,5 @@ import {defaultOptions, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; export type MonitoringArgs = { "monitoring.endpoint"?: string; diff --git a/packages/cli/src/options/beaconNodeOptions/network.ts b/packages/cli/src/options/beaconNodeOptions/network.ts index 79ec3d710d44..59d74a5cfa48 100644 --- a/packages/cli/src/options/beaconNodeOptions/network.ts +++ b/packages/cli/src/options/beaconNodeOptions/network.ts @@ -1,7 +1,8 @@ import {multiaddr} from "@multiformats/multiaddr"; import {ENR} from "@chainsafe/enr"; import {defaultOptions, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions, YargsError} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; +import {YargsError} from "../../util/index.js"; export const defaultListenAddress = "0.0.0.0"; export const defaultP2pPort = 9000; diff --git a/packages/cli/src/options/beaconNodeOptions/sync.ts b/packages/cli/src/options/beaconNodeOptions/sync.ts index 7130b835b987..789307781ed0 100644 --- a/packages/cli/src/options/beaconNodeOptions/sync.ts +++ b/packages/cli/src/options/beaconNodeOptions/sync.ts @@ -1,5 +1,5 @@ import {defaultOptions, IBeaconNodeOptions} from "@lodestar/beacon-node"; -import {CliCommandOptions} from "../../util/index.js"; +import {CliCommandOptions} from "@lodestar/utils"; export type SyncArgs = { "sync.isSingleNode"?: boolean; diff --git a/packages/cli/src/options/globalOptions.ts b/packages/cli/src/options/globalOptions.ts index 30e515de49c0..52a5090c6794 100644 --- a/packages/cli/src/options/globalOptions.ts +++ b/packages/cli/src/options/globalOptions.ts @@ -1,6 +1,7 @@ import {ACTIVE_PRESET} from "@lodestar/params"; +import {CliCommandOptions} from "@lodestar/utils"; import {NetworkName, networkNames} from "../networks/index.js"; -import {CliCommandOptions, readFile} from "../util/index.js"; +import {readFile} from "../util/index.js"; import {paramsOptions, IParamsArgs} from "./paramsOptions.js"; type GlobalSingleArgs = { diff --git a/packages/cli/src/options/logOptions.ts b/packages/cli/src/options/logOptions.ts index 687057d6ec1e..b45057a4532f 100644 --- a/packages/cli/src/options/logOptions.ts +++ b/packages/cli/src/options/logOptions.ts @@ -1,6 +1,5 @@ -import {LogLevels} from "@lodestar/utils"; +import {LogLevels, CliCommandOptions} from "@lodestar/utils"; import {LogLevel, logFormats} from "@lodestar/logger"; -import {CliCommandOptions} from "../util/command.js"; import {LOG_FILE_DISABLE_KEYWORD} from "../util/logger.js"; export type LogArgs = { diff --git a/packages/cli/src/options/paramsOptions.ts b/packages/cli/src/options/paramsOptions.ts index 643fb991bc61..b35a15e3c9b6 100644 --- a/packages/cli/src/options/paramsOptions.ts +++ b/packages/cli/src/options/paramsOptions.ts @@ -1,6 +1,7 @@ import {ChainConfig, chainConfigTypes} from "@lodestar/config"; +import {CliCommandOptions, CliOptionDefinition} from "@lodestar/utils"; import {IBeaconParamsUnparsed} from "../config/types.js"; -import {ObjectKeys, CliCommandOptions, CliOptionDefinition} from "../util/index.js"; +import {ObjectKeys} from "../util/index.js"; // No options are statically declared // If an arbitrary key notation is used, it removes type safety on most of this CLI arg parsing code. diff --git a/packages/cli/src/util/index.ts b/packages/cli/src/util/index.ts index 4d2be3cc92f4..3d94977f5fb7 100644 --- a/packages/cli/src/util/index.ts +++ b/packages/cli/src/util/index.ts @@ -1,4 +1,3 @@ -export * from "./command.js"; export * from "./errors.js"; export * from "./ethers.js"; export * from "./file.js"; diff --git a/packages/flare/src/cli.ts b/packages/flare/src/cli.ts index 4da4eb4e158c..91c4ef83ca09 100644 --- a/packages/flare/src/cli.ts +++ b/packages/flare/src/cli.ts @@ -1,8 +1,8 @@ // Must not use `* as yargs`, see https://github.com/yargs/yargs/issues/1131 import yargs from "yargs"; import {hideBin} from "yargs/helpers"; +import {registerCommandToYargs} from "@lodestar/utils"; import {cmds} from "./cmds/index.js"; -import {registerCommandToYargs} from "./util/command.js"; const topBanner = `Beacon chain multi-purpose and debugging tool. diff --git a/packages/flare/src/cmds/index.ts b/packages/flare/src/cmds/index.ts index 12a989ae6b27..63e1f316b3b6 100644 --- a/packages/flare/src/cmds/index.ts +++ b/packages/flare/src/cmds/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../util/command.js"; +import {CliCommand} from "@lodestar/utils"; import {selfSlashProposer} from "./selfSlashProposer.js"; import {selfSlashAttester} from "./selfSlashAttester.js"; diff --git a/packages/flare/src/cmds/selfSlashAttester.ts b/packages/flare/src/cmds/selfSlashAttester.ts index 3fa3414f5012..beaa14ed9291 100644 --- a/packages/flare/src/cmds/selfSlashAttester.ts +++ b/packages/flare/src/cmds/selfSlashAttester.ts @@ -5,9 +5,8 @@ import {phase0, ssz} from "@lodestar/types"; import {config as chainConfig} from "@lodestar/config/default"; import {createBeaconConfig, BeaconConfig} from "@lodestar/config"; import {DOMAIN_BEACON_ATTESTER, MAX_VALIDATORS_PER_COMMITTEE} from "@lodestar/params"; -import {toHexString} from "@lodestar/utils"; +import {CliCommand, toHexString} from "@lodestar/utils"; import {computeSigningRoot} from "@lodestar/state-transition"; -import {CliCommand} from "../util/command.js"; import {deriveSecretKeys, SecretKeysArgs, secretKeysOptions} from "../util/deriveSecretKeys.js"; /* eslint-disable no-console */ diff --git a/packages/flare/src/cmds/selfSlashProposer.ts b/packages/flare/src/cmds/selfSlashProposer.ts index 49675bb802de..ba8a85bc8e71 100644 --- a/packages/flare/src/cmds/selfSlashProposer.ts +++ b/packages/flare/src/cmds/selfSlashProposer.ts @@ -4,9 +4,8 @@ import {phase0, ssz} from "@lodestar/types"; import {config as chainConfig} from "@lodestar/config/default"; import {createBeaconConfig, BeaconConfig} from "@lodestar/config"; import {DOMAIN_BEACON_PROPOSER} from "@lodestar/params"; -import {toHexString} from "@lodestar/utils"; +import {CliCommand, toHexString} from "@lodestar/utils"; import {computeSigningRoot} from "@lodestar/state-transition"; -import {CliCommand} from "../util/command.js"; import {deriveSecretKeys, SecretKeysArgs, secretKeysOptions} from "../util/deriveSecretKeys.js"; /* eslint-disable no-console */ diff --git a/packages/flare/src/util/command.ts b/packages/flare/src/util/command.ts deleted file mode 100644 index f01d9f7ab17b..000000000000 --- a/packages/flare/src/util/command.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {Options, Argv} from "yargs"; - -export interface CliExample { - command: string; - title?: string; - description?: string; -} - -export interface CliOptionDefinition extends Options { - example?: CliExample; -} - -export type CliCommandOptions = Required<{[key in keyof OwnArgs]: CliOptionDefinition}>; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export interface CliCommand, ParentArgs = Record, R = any> { - command: string; - describe: string; - examples?: {command: string; description: string}[]; - options?: CliCommandOptions; - // 1st arg: any = free own sub command options - // 2nd arg: subcommand parent options is = to this command options + parent options - // eslint-disable-next-line @typescript-eslint/no-explicit-any - subcommands?: CliCommand[]; - handler?: (args: OwnArgs & ParentArgs) => Promise; -} - -/** - * Register a CliCommand type to yargs. Recursively registers subcommands too. - * @param yargs - * @param cliCommand - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function registerCommandToYargs(yargs: Argv, cliCommand: CliCommand): void { - yargs.command({ - command: cliCommand.command, - describe: cliCommand.describe, - builder: (yargsBuilder) => { - yargsBuilder.options(cliCommand.options || {}); - for (const subcommand of cliCommand.subcommands || []) { - registerCommandToYargs(yargsBuilder, subcommand); - } - if (cliCommand.examples) { - for (const example of cliCommand.examples) { - yargsBuilder.example(`$0 ${example.command}`, example.description); - } - } - return yargs; - }, - handler: cliCommand.handler || function emptyHandler(): void {}, - }); -} diff --git a/packages/flare/src/util/deriveSecretKeys.ts b/packages/flare/src/util/deriveSecretKeys.ts index 9660f86624a2..272cf87c09c4 100644 --- a/packages/flare/src/util/deriveSecretKeys.ts +++ b/packages/flare/src/util/deriveSecretKeys.ts @@ -2,9 +2,9 @@ import bls from "@chainsafe/bls"; import type {SecretKey} from "@chainsafe/bls/types"; import {deriveEth2ValidatorKeys, deriveKeyFromMnemonic} from "@chainsafe/bls-keygen"; import {interopSecretKey} from "@lodestar/state-transition"; +import {CliCommandOptions} from "@lodestar/utils"; import {YargsError} from "./errors.js"; import {parseRange} from "./format.js"; -import {CliCommandOptions} from "./command.js"; export type SecretKeysArgs = { mnemonic?: string; diff --git a/packages/prover/src/cli/cli.ts b/packages/prover/src/cli/cli.ts index 2d1475f3d39d..5e084a551536 100644 --- a/packages/prover/src/cli/cli.ts +++ b/packages/prover/src/cli/cli.ts @@ -1,7 +1,7 @@ // Must not use `* as yargs`, see https://github.com/yargs/yargs/issues/1131 import yargs from "yargs"; import {hideBin} from "yargs/helpers"; -import {registerCommandToYargs} from "../utils/command.js"; +import {registerCommandToYargs} from "@lodestar/utils"; import {getVersionData} from "../utils/version.js"; import {cmds, proverProxyStartCommand} from "./cmds/index.js"; import {globalOptions} from "./options.js"; diff --git a/packages/prover/src/cli/cmds/index.ts b/packages/prover/src/cli/cmds/index.ts index ecd2dae1da99..310f541cf591 100644 --- a/packages/prover/src/cli/cmds/index.ts +++ b/packages/prover/src/cli/cmds/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../../utils/command.js"; +import {CliCommand} from "@lodestar/utils"; import {GlobalArgs} from "../options.js"; import {proverProxyStartCommand} from "./start/index.js"; export {proverProxyStartCommand} from "./start/index.js"; diff --git a/packages/prover/src/cli/cmds/start/index.ts b/packages/prover/src/cli/cmds/start/index.ts index 2b49a6466a61..f69c3acebe94 100644 --- a/packages/prover/src/cli/cmds/start/index.ts +++ b/packages/prover/src/cli/cmds/start/index.ts @@ -1,4 +1,4 @@ -import {CliCommand} from "../../../utils/command.js"; +import {CliCommand} from "@lodestar/utils"; import {GlobalArgs} from "../../options.js"; import {proverProxyStartHandler} from "./handler.js"; import {StartArgs, startOptions} from "./options.js"; diff --git a/packages/prover/src/cli/cmds/start/options.ts b/packages/prover/src/cli/cmds/start/options.ts index 53ff5957765b..f63ee974be44 100644 --- a/packages/prover/src/cli/cmds/start/options.ts +++ b/packages/prover/src/cli/cmds/start/options.ts @@ -1,12 +1,12 @@ +import {CliCommandOptions} from "@lodestar/utils"; import {DEFAULT_PROXY_REQUEST_TIMEOUT} from "../../../constants.js"; import {LCTransport} from "../../../interfaces.js"; -import {CliCommandOptions} from "../../../utils/command.js"; import {alwaysAllowedMethods} from "../../../utils/process.js"; export type StartArgs = { port: number; executionRpcUrl: string; - beaconUrls?: string[]; + beaconUrls: string[]; wsCheckpoint?: string; unverifiedWhitelist?: string[]; requestTimeout: number; @@ -53,9 +53,12 @@ export const startOptions: CliCommandOptions = { beaconUrls: { description: "Urls of the beacon nodes to connect to.", - type: "string", + type: "array", + string: true, + coerce: (urls: string[]): string[] => + // Parse ["url1,url2"] to ["url1", "url2"] + urls.map((item) => item.split(",")).flat(), demandOption: true, - array: true, group: "beacon", }, diff --git a/packages/prover/src/cli/options.ts b/packages/prover/src/cli/options.ts index cb6ba1aaeca2..c37250070056 100644 --- a/packages/prover/src/cli/options.ts +++ b/packages/prover/src/cli/options.ts @@ -1,14 +1,14 @@ import {NetworkName, networksChainConfig} from "@lodestar/config/networks"; -import {LogLevel, LogLevels} from "@lodestar/utils"; +import {CliCommandOptions, LogLevel, LogLevels} from "@lodestar/utils"; import {ACTIVE_PRESET} from "@lodestar/params"; -import {CliCommandOptions} from "../utils/command.js"; +import {YargsError} from "../utils/errors.js"; export type GlobalArgs = { - network: string; + network?: string; logLevel: string; presetFile?: string; preset: string; - paramsFile: string; + paramsFile?: string; }; export type GlobalOptions = { @@ -62,8 +62,12 @@ export function parseGlobalArgs(args: GlobalArgs): GlobalOptions { }; } - return { - logLevel: args.logLevel as LogLevel, - paramsFile: args.paramsFile, - }; + if (args.paramsFile) { + return { + logLevel: args.logLevel as LogLevel, + paramsFile: args.paramsFile, + }; + } + + throw new YargsError("Either --network or --paramsFile must be provided"); } diff --git a/packages/prover/src/utils/command.ts b/packages/prover/src/utils/command.ts deleted file mode 100644 index f01d9f7ab17b..000000000000 --- a/packages/prover/src/utils/command.ts +++ /dev/null @@ -1,52 +0,0 @@ -import {Options, Argv} from "yargs"; - -export interface CliExample { - command: string; - title?: string; - description?: string; -} - -export interface CliOptionDefinition extends Options { - example?: CliExample; -} - -export type CliCommandOptions = Required<{[key in keyof OwnArgs]: CliOptionDefinition}>; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export interface CliCommand, ParentArgs = Record, R = any> { - command: string; - describe: string; - examples?: {command: string; description: string}[]; - options?: CliCommandOptions; - // 1st arg: any = free own sub command options - // 2nd arg: subcommand parent options is = to this command options + parent options - // eslint-disable-next-line @typescript-eslint/no-explicit-any - subcommands?: CliCommand[]; - handler?: (args: OwnArgs & ParentArgs) => Promise; -} - -/** - * Register a CliCommand type to yargs. Recursively registers subcommands too. - * @param yargs - * @param cliCommand - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function registerCommandToYargs(yargs: Argv, cliCommand: CliCommand): void { - yargs.command({ - command: cliCommand.command, - describe: cliCommand.describe, - builder: (yargsBuilder) => { - yargsBuilder.options(cliCommand.options || {}); - for (const subcommand of cliCommand.subcommands || []) { - registerCommandToYargs(yargsBuilder, subcommand); - } - if (cliCommand.examples) { - for (const example of cliCommand.examples) { - yargsBuilder.example(`$0 ${example.command}`, example.description); - } - } - return yargs; - }, - handler: cliCommand.handler || function emptyHandler(): void {}, - }); -} diff --git a/packages/utils/package.json b/packages/utils/package.json index 06c89f6593ca..3d888bb4e38b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -49,6 +49,7 @@ "devDependencies": { "@types/js-yaml": "^4.0.5", "@types/triple-beam": "^1.3.2", + "@types/yargs": "^17.0.24", "prom-client": "^15.1.0", "triple-beam": "^1.3.0" }, diff --git a/packages/cli/src/util/command.ts b/packages/utils/src/command.ts similarity index 85% rename from packages/cli/src/util/command.ts rename to packages/utils/src/command.ts index ccc8f47e71a9..3bfb372bd78f 100644 --- a/packages/cli/src/util/command.ts +++ b/packages/utils/src/command.ts @@ -1,4 +1,4 @@ -import {Options, Argv} from "yargs"; +import type {Options, Argv} from "yargs"; export interface CliExample { command: string; @@ -24,8 +24,8 @@ export interface CliOptionDefinition extends Options { export type CliCommandOptions = Required<{ [K in keyof OwnArgs]: undefined extends OwnArgs[K] ? CliOptionDefinition - : // If arg cannot be undefined it must specify a default value - CliOptionDefinition & Required>; + : // If arg cannot be undefined it must specify a default value or be provided by the user + CliOptionDefinition & (Required> | {demandOption: true}); }>; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -57,8 +57,8 @@ export function registerCommandToYargs(yargs: Argv, cliCommand: CliCommand { - yargsBuilder.options(cliCommand.options || {}); - for (const subcommand of cliCommand.subcommands || []) { + yargsBuilder.options(cliCommand.options ?? {}); + for (const subcommand of cliCommand.subcommands ?? []) { registerCommandToYargs(yargsBuilder, subcommand); } if (cliCommand.examples) { @@ -68,6 +68,6 @@ export function registerCommandToYargs(yargs: Argv, cliCommand: CliCommand