@kadena/kadena-cli
Version:
Kadena CLI tool to interact with the Kadena blockchain (manage keys, transactions, etc.)
184 lines • 7.98 kB
JavaScript
import { Option } from 'commander';
import { load as loadYaml } from 'js-yaml';
import { join } from 'node:path';
import { z } from 'zod';
import { tx } from '../../prompts/index.js';
import { templateDataPrompt, templateVariables, txRequestKeyPrompt, txTransactionNetworks, } from '../../prompts/tx.js';
import { services } from '../../services/index.js';
import { createOption } from '../../utils/createOption.js';
import { getVariablesByTemplate } from './utils/template.js';
import { parseInput, requestKeyValidation } from './utils/txHelpers.js';
export const txOptions = {
selectTemplate: createOption({
key: 'template',
option: new Option('-t, --template <template>', 'Filepath of ktpl template to create a transaction from'),
validation: z.union([
z.object({
template: z.string(),
path: z.string(),
cwd: z.string(),
}),
z.string(),
]),
prompt: tx.selectTemplate,
expand: getVariablesByTemplate,
}),
templateData: createOption({
key: 'templateData',
validation: z.string(),
option: new Option('-d, --template-data <templateData>', 'Filepath of JSON or YAML file to use as template data'),
prompt: templateDataPrompt,
async expand(filePath) {
if (filePath === undefined)
return null;
const absolutePath = join(process.cwd(), filePath);
const exists = await services.filesystem.fileExists(absolutePath);
const file = await services.filesystem.readFile(exists ? absolutePath : filePath);
if (file === null)
return null;
let parsed;
try {
parsed = JSON.parse(file);
// eslint-disable-next-line no-empty
}
catch (e) { }
try {
parsed = loadYaml(file);
// eslint-disable-next-line no-empty
}
catch (e) { }
const validated = z
.record(z.union([z.string(), z.number()]))
.safeParse(parsed);
if (validated.success)
return validated.data;
else
return null;
},
}),
templateVariables: createOption({
key: 'templateVariables',
validation: z.object({}).passthrough(),
option: new Option('--template-variables <templateVariables>', 'Dynamic placeholder flag for template data, do not use this flag directly'),
prompt: templateVariables,
allowUnknownOptions: true,
// TODO:
// Transform repeats the same logic as in the prompt
// This is because prompt can be skipped entirely if quiet=true
// But prompt still needs the logic to prevent prompting known variables
transform: async (value, args) => {
const variableValues = value !== null && value !== void 0 ? value : {};
const { values, variables, data } = args;
for (const variable of variables) {
// Prioritize variables from data file
if (Object.hasOwn(data, variable)) {
variableValues[variable] = String(data[variable]);
continue;
}
// Find variables in cli arguments
const match = values.find((value) => value.startsWith(`--${variable}=`));
if (match !== undefined)
variableValues[variable] = match.split('=')[1];
}
return variableValues;
},
}),
txUnsignedCommand: createOption({
key: 'txUnsignedCommand',
prompt: tx.txUnsignedCommandPrompt,
validation: tx.IUnsignedCommandSchema,
option: new Option('-m, --tx-unsigned-command <txUnsignedCommand>', 'enter your unsigned command to sign'),
}),
txUnsignedTransactionFile: createOption({
key: 'txUnsignedTransactionFile',
prompt: tx.transactionSelectPrompt,
validation: tx.IUnsignedCommandSchema,
option: new Option('-u, --tx-unsigned-transaction-file <txUnsignedTransactionFile>', 'provide your unsigned transaction file to sign'),
}),
txUnsignedTransactionFiles: createOption({
key: 'txUnsignedTransactionFiles',
prompt: tx.transactionsSelectPrompt,
validation: z.string().or(z.array(z.string())),
option: new Option('-u, --tx-unsigned-transaction-files <txUnsignedTransactionFiles>', 'provide your unsigned transaction file(s) to sign'),
transform: async (txUnsigedTransactionFiles) => {
if (typeof txUnsigedTransactionFiles === 'string') {
return parseInput(txUnsigedTransactionFiles);
}
return txUnsigedTransactionFiles;
},
}),
txSignedTransactionFile: createOption({
key: 'txSignedTransactionFile',
prompt: tx.transactionSelectPrompt,
validation: tx.ISignedCommandSchema,
option: new Option('-s, --tx-signed-transaction-file <txSignedTransactionFile>', 'provide your signed transaction file'),
}),
txSignedTransactionFiles: createOption({
key: 'txSignedTransactionFiles',
prompt: tx.transactionsSelectPrompt,
validation: z.union([z.array(z.string()), z.string()]),
option: new Option('-s, --tx-signed-transaction-files <txSignedTransactionFiles>', 'provide your signed transaction file'),
transform: async (txSignedTransactionFiles) => {
if (typeof txSignedTransactionFiles === 'string') {
return parseInput(txSignedTransactionFiles);
}
return txSignedTransactionFiles;
},
}),
txTransactionNetwork: createOption({
key: 'txTransactionNetwork',
validation: z.array(z.string()),
option: new Option('-n, --tx-transaction-network <txTransactionNetwork>', 'Kadena networks comma seperated list in order of transaction. (e.g. "mainnet, testnet, devnet, ...")'),
transform: async (value) => {
return parseInput(value);
},
prompt: txTransactionNetworks,
}),
txSignWith: createOption({
key: 'txSignWith',
prompt: tx.selectSignMethodPrompt,
validation: z.string(),
option: new Option('-s, --tx-sign-with <txSignWith>', 'Select a signing method'),
}),
poll: createOption({
key: 'poll',
prompt: ({ poll }) => {
return poll === true || poll === 'true' || false;
},
validation: z.boolean().optional(),
option: new Option('-p, --poll', 'Poll for transaction status'),
}),
requestKey: createOption({
key: 'requestKey',
prompt: txRequestKeyPrompt,
defaultIsOptional: false,
validation: requestKeyValidation,
transform: (value) => {
return value.trim();
},
option: new Option('-k, --request-key <requestKey>', 'Request key of the transaction'),
}),
holes: createOption({
key: 'holes',
prompt: ({ holes }) => {
return holes === true || holes === 'true' || false;
},
validation: z.boolean().optional(),
option: new Option('-l --holes', 'Get a list of all the values this template needs'),
}),
gasLimit: createOption({
key: 'gasLimit',
prompt: () => undefined,
validation: z.string().optional(),
option: new Option('-g --gas-limit <gasLimit>', 'Gas limit for the local transaction'),
}),
chainweaverSignatures: createOption({
key: 'legacy',
prompt: ({ legacy }) => {
return legacy === true || legacy === 'true' || false;
},
validation: z.boolean().optional(),
option: new Option('-l, --legacy', 'Make the signed output transactions ChainWeaver and kda-tool compatible'),
}),
};
//# sourceMappingURL=txOptions.js.map