Tests. Autocomplete. Few Fixes. Mocks for Electrum Service. Template-to-Json parser. Fix global paths. Use IO Dependency injection for logging from cli. Additional commands in CLI.
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import { existsSync, readFileSync } from "fs";
|
||||
import path from "path";
|
||||
import { generateTemplateIdentifier } from "@xo-cash/engine";
|
||||
import { hexToBin, lockingBytecodeToCashAddress } from "@bitauth/libauth";
|
||||
|
||||
import { bold, dim } from "../cli-utils.js";
|
||||
import type { CommandDependencies } from "./types.js";
|
||||
import type { CommandDependencies, CommandIO } from "./types.js";
|
||||
import { CommandError } from "./types.js";
|
||||
|
||||
import { resolveTemplate } from "../utils.js";
|
||||
|
||||
/**
|
||||
* Prints the help message for the receive command
|
||||
*/
|
||||
export const printReceiveHelp = () => {
|
||||
console.log(
|
||||
export const printReceiveHelp = (io: CommandIO): void => {
|
||||
io.out(
|
||||
`
|
||||
${bold("Usage:")} xo-cli receive <template-file> <output-identifier> [role-identifier]
|
||||
|
||||
@@ -29,36 +30,35 @@ ${bold("Options:")}
|
||||
|
||||
/**
|
||||
* Command which creates a single-use address/lockingScript for a given template and role.
|
||||
* Throws CommandError on failure, returns address data on success.
|
||||
*
|
||||
* @param deps - The command dependencies.
|
||||
* @param args - Positional args after the command name, e.g. ["template.json", "receiveOutput", "receiver"].
|
||||
* @param options - Parsed option flags.
|
||||
* @returns The address data.
|
||||
* @throws CommandError if the command fails.
|
||||
*/
|
||||
export const handleReceiveCommand = async (deps: CommandDependencies, args: string[], options: Record<string, string>): Promise<void> => {
|
||||
const templateFile = args[0];
|
||||
export const handleReceiveCommand = async (
|
||||
deps: CommandDependencies,
|
||||
args: string[],
|
||||
_options: Record<string, string>,
|
||||
): Promise<{ address: string }> => {
|
||||
const templateQuery = args[0];
|
||||
const outputIdentifier = args[1];
|
||||
const roleIdentifier = args[2];
|
||||
|
||||
deps.verboseLogger(`Receive args - template: ${templateFile}, output: ${outputIdentifier}, role: ${roleIdentifier}`);
|
||||
deps.io.verbose(`Receive args - template: ${templateQuery}, output: ${outputIdentifier}, role: ${roleIdentifier}`);
|
||||
|
||||
if (!templateFile || !outputIdentifier) {
|
||||
deps.verboseLogger("Missing required arguments");
|
||||
printReceiveHelp();
|
||||
return;
|
||||
if (!templateQuery || !outputIdentifier) {
|
||||
deps.io.verbose("Missing required arguments");
|
||||
printReceiveHelp(deps.io);
|
||||
throw new CommandError("receive.arguments.missing", "Missing required arguments");
|
||||
}
|
||||
|
||||
// Resolve and read the template file
|
||||
const templatePath = path.resolve(`${process.cwd()}/${templateFile}`);
|
||||
deps.verboseLogger(`Template path: ${templatePath}`);
|
||||
|
||||
if (!existsSync(templatePath)) {
|
||||
console.error(`Template file does not exist: ${templatePath}`);
|
||||
printReceiveHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
const template = readFileSync(templatePath, "utf8");
|
||||
const templateIdentifier = generateTemplateIdentifier(JSON.parse(template));
|
||||
deps.verboseLogger(`Template identifier: ${templateIdentifier}`);
|
||||
const template = await resolveTemplate(deps, templateQuery);
|
||||
const templateIdentifier = generateTemplateIdentifier(template);
|
||||
deps.io.verbose(`Template identifier: ${templateIdentifier}`);
|
||||
|
||||
// Generate the locking bytecode (returned as a hex string)
|
||||
const lockingBytecodeHex = await deps.app.engine.generateLockingBytecode(
|
||||
@@ -66,15 +66,16 @@ export const handleReceiveCommand = async (deps: CommandDependencies, args: stri
|
||||
outputIdentifier,
|
||||
roleIdentifier,
|
||||
);
|
||||
deps.verboseLogger(`Locking bytecode hex: ${lockingBytecodeHex}`);
|
||||
deps.io.verbose(`Locking bytecode hex: ${lockingBytecodeHex}`);
|
||||
|
||||
// Convert the locking bytecode to a BCH cash address
|
||||
const result = lockingBytecodeToCashAddress({ bytecode: hexToBin(lockingBytecodeHex), prefix: 'bitcoincash' });
|
||||
|
||||
if (typeof result === 'string') {
|
||||
console.error(`Failed to encode address: ${result}`);
|
||||
return;
|
||||
deps.io.err(`Failed to encode address: ${result}`);
|
||||
throw new CommandError("receive.address.encode_failed", `Failed to encode address: ${result}`);
|
||||
}
|
||||
|
||||
console.log(result.address);
|
||||
deps.io.out(result.address);
|
||||
return { address: result.address };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user