Files
xo-cli/src/cli/commands/mnemonic.ts

152 lines
4.5 KiB
TypeScript

import { bold, dim } from "../utils.js";
import {
listMnemonicFiles,
createMnemonicFile,
createMnemonicSeed,
loadMnemonic,
} from "../mnemonic.js";
import type { BaseCommandDependencies, CommandIO } from "./types.js";
import { CommandError } from "./types.js";
/**
* Prints the help message for the mnemonic command
*/
export const printMnemonicHelp = (io: CommandIO): void => {
io.out(
`
${bold("Usage:")} xo-cli mnemonic <sub-command>
${bold("Sub-commands:")}
- create <mnemonic-seed> ${dim("Create a new mnemonic file")}
- list ${dim("List all mnemonic files")}
- import <mnemonic-seed> ${dim("Import a mnemonic seed from a file")}
- expose <mnemonic-file> ${dim("Expose a mnemonic file")}
${bold("Options:")}
-o --output <output-filename> ${dim("Output filename for the mnemonic file")}
-h --help ${dim("Show this help message")}
`,
);
};
/**
* Handles the mnemonic command.
* Throws CommandError on failure, returns result data on success.
* @param deps - The command dependencies.
* @param args - Positional args after the command name, e.g. ["create"] or ["import", "page", "pencil", ...].
* @param options - Parsed option flags, e.g. { output: "mnemonic.txt" }.
*/
export const handleMnemonicCommand = async (
deps: BaseCommandDependencies,
args: string[],
options: Record<string, string>,
): Promise<{ savedAs?: string; count?: number; mnemonic?: string }> => {
// Get the sub-command from the arguments
const subCommand = args[0];
const { mnemonicsDir } = deps.paths;
// If no sub-command is provided, print the help message and throw an error
if (!subCommand) {
deps.io.verbose("No sub-command provided");
printMnemonicHelp(deps.io);
throw new CommandError(
"mnemonic.subcommand.missing",
"No sub-command provided",
);
}
// Handle the sub-command
switch (subCommand) {
case "create": {
// Create a new mnemonic seed
const mnemonicSeed = createMnemonicSeed();
// Create a new mnemonic file
const savedAs = createMnemonicFile(
mnemonicsDir,
mnemonicSeed,
options["output"],
);
// Display the mnemonic file to the user
deps.io.out(`Mnemonic file created: ${savedAs} (${mnemonicSeed})`);
return { savedAs };
}
case "import": {
// Get the mnemonic seed from the arguments
const mnemonicSeed = args.slice(1).join(" ");
// If no mnemonic seed is provided, print the help message and throw an error
if (!mnemonicSeed) {
deps.io.verbose("No mnemonic seed provided");
printMnemonicHelp(deps.io);
throw new CommandError(
"mnemonic.import.seed_missing",
"No mnemonic seed provided",
);
}
// Create a new mnemonic file
deps.io.verbose(`Mnemonic seed: ${mnemonicSeed}`);
const savedAs = createMnemonicFile(
mnemonicsDir,
mnemonicSeed,
options["output"],
);
// Display the mnemonic file to the user
deps.io.out(`Mnemonic file created: ${savedAs}`);
return { savedAs };
}
case "list": {
// List all the mnemonic files
const mnemonicFiles = listMnemonicFiles(mnemonicsDir);
deps.io.out(mnemonicFiles.join("\n"));
// Return the number of mnemonic files
return { count: mnemonicFiles.length };
}
case "expose": {
// Get the mnemonic file from the arguments
const mnemonicFile = args[1];
// If no mnemonic file is provided, print the help message and throw an error
if (!mnemonicFile) {
deps.io.verbose("No mnemonic file provided");
printMnemonicHelp(deps.io);
throw new CommandError(
"mnemonic.expose.file_missing",
"No mnemonic file provided",
);
}
// Try to load the mnemonic file
try {
const mnemonic = loadMnemonic(mnemonicsDir, mnemonicFile);
deps.io.out(mnemonic);
// Return the mnemonic
return { mnemonic };
} catch (error) {
// If the mnemonic file is not found, print an error and throw an error
throw new CommandError(
"mnemonic.expose.file_not_found",
`Mnemonic file not found: ${mnemonicFile}`,
);
}
}
default:
// If the sub-command is not found, print an error and throw an error
deps.io.err(`Unknown sub-command: ${subCommand}`);
printMnemonicHelp(deps.io);
throw new CommandError(
"mnemonic.subcommand.unknown",
`Unknown sub-command: ${subCommand}`,
);
}
};