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 ${bold("Sub-commands:")} - create ${dim("Create a new mnemonic file")} - list ${dim("List all mnemonic files")} - import ${dim("Import a mnemonic seed from a file")} - expose ${dim("Expose a mnemonic file")} ${bold("Options:")} -o --output ${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, ): 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}`, ); } };