Plugin for creating and executing batches of Hedera transactions following the plugin architecture. Supports grouping multiple inner transactions (token creation, topic creation, account creation, etc.) into a single atomic batch transaction.
This plugin follows the plugin architecture principles:
- Stateless: Plugin is functionally stateless
- Dependency Injection: Services are injected into command handlers
- Manifest-Driven: Capabilities declared via manifest with output specifications
- Namespace Isolation: Own state namespace (
batch-batches) - Type Safety: Full TypeScript support
- Structured Output: All command handlers return
CommandResultwith standardized output
src/plugins/batch/
├── manifest.ts # Plugin manifest with command definitions and output specs
├── schema.ts # Batch data schema with Zod validation
├── services/
│ ├── batch-state.service.interface.ts # BatchStateService interface
│ └── batch-state.service.ts # BatchStateServiceImpl implementation
├── commands/
│ ├── create/
│ │ ├── handler.ts # Batch creation handler
│ │ ├── input.ts # Input schema
│ │ ├── output.ts # Output schema and template
│ │ └── index.ts # Command exports
│ ├── execute/
│ │ ├── handler.ts # Batch execution handler
│ │ ├── input.ts # Input schema
│ │ ├── output.ts # Output schema and template
│ │ ├── types.ts # Command types
│ │ └── index.ts # Command exports
│ ├── list/
│ │ ├── handler.ts # Batch list handler
│ │ ├── output.ts # Output schema and template
│ │ └── index.ts # Command exports
│ └── delete/
│ ├── handler.ts # Batch delete handler
│ ├── input.ts # Input schema
│ ├── output.ts # Output schema and template
│ └── index.ts # Command exports
├── hooks/
│ ├── batchify-set-batch-key/
│ │ ├── handler.ts # Sets batch key on transaction before signing
│ │ └── index.ts # Hook exports
│ ├── batchify-add-transaction/
│ │ ├── handler.ts # Intercepts and adds signed transaction to batch
│ │ ├── output.ts # Output schema and template
│ │ └── index.ts # Hook exports
│ └── shared/
│ ├── input.ts # Shared --batch option schema
│ └── types.ts # Shared hook types
├── __tests__/ # Test suite
│ ├── unit/
│ │ ├── create.test.ts
│ │ ├── execute.test.ts
│ │ ├── list.test.ts
│ │ ├── delete.test.ts
│ │ ├── batchify-add-transaction.test.ts
│ │ ├── batchify-set-batch-key.test.ts
│ │ └── helpers/
│ └── ...
└── index.ts # Plugin exports
All commands return CommandResult with structured output data in the result field. Errors are thrown as typed CliError instances and handled uniformly by the core framework.
Create a new batch with a name and signing key for transaction execution.
# Basic usage
hcli batch create --name my-batch --key alice
# With account-id:private-key pair
hcli batch create --name my-batch --key 0.0.123456:302e020100300506032b657004220420...
# With specific key manager
hcli batch create --name my-batch --key alice --key-manager local_encryptedParameters:
--name/-n: Name/alias for the batch - Required--key/-k: Key to sign transactions - Required- Account alias:
alice - Account with key:
0.0.123456:privateKey - Key reference or account alias
- Account alias:
--key-manager/-m: Key manager type (optional, defaults to config setting)localorlocal_encrypted
Execute a batch by name, signing and submitting its transactions atomically.
hcli batch execute --name my-batchParameters:
--name/-n: Name of the batch to execute - Required
Note: The batch must have been created first and must contain at least one transaction. After execution, domain-specific hooks (e.g. token, account, topic) persist their state based on the transaction results.
List all available batches.
hcli batch listOutput: Shows batch name, transaction count, execution status, and success status for each batch.
Delete a whole batch or remove a single transaction from a batch.
# Delete entire batch
hcli batch delete --name my-batch
# Delete single transaction by order
hcli batch delete --name my-batch --order 3Parameters:
--name/-n: Name of the batch - Required--order/-o: Order of transaction to remove (optional). If omitted, deletes the entire batch
The batchify hook intercepts commands that support it. When you pass --batch <batch-name> to any command that registers the hook, the transaction is not executed immediately—instead, it is added to the specified batch.
Commands that support --batch (via registeredHooks):
account createtopic createtopic deletetoken create-fttoken create-ft-from-filetoken create-nfttoken create-nft-from-filetoken associate
# 1. Create a batch
hcli batch create --name my-batch --key alice
# 2. Add transactions to the batch (instead of executing immediately)
hcli token create-ft --token-name "Token A" --symbol "TA" --treasury alice --decimals 8 --initial-supply 1000 --supply-type FINITE --max-supply 10000 --admin-key alice --supply-key alice --name token-a --batch my-batch
hcli token create-ft --token-name "Token B" --symbol "TB" --treasury alice --decimals 8 --initial-supply 500 --supply-type INFINITE --admin-key alice --supply-key alice --name token-b --batch my-batch
hcli token associate --token token-a --account bob --batch my-batch
# 3. Optional: list batches to verify
hcli batch list
# 4. Execute the batch (all transactions atomically)
hcli batch execute --name my-batchParameters:
--batch/-B: Name of the batch to add the transaction to (optional). When provided, the command does not execute—it adds the transaction to the batch and returns immediately.
- Maximum 50 transactions per batch (Hedera HIP-551 limit)
- Batch must be created before adding transactions
- Batch cannot be modified after execution
The plugin uses the Core API services:
api.state- Namespaced state management for batch dataapi.kms- Key resolution and signingapi.keyResolver- Resolve signing keysapi.network- Network information and operatorapi.txSign- Transaction signingapi.txExecute- Transaction executionapi.batch- Batch transaction creationapi.logger- Logging
Batch state is managed by BatchStateServiceImpl (services/batch-state.service.ts), which implements the BatchStateService interface. The service is constructed fresh on each command invocation and injected via constructor. Hooks instantiate it directly inside execute().
Batch data is stored in the batch-batches namespace with the following structure:
interface BatchData {
name: string;
keyRefId: string;
executed: boolean;
success: boolean;
transactions: BatchTransactionItem[];
}
interface BatchTransactionItem {
transactionBytes: string; // Hex-encoded signed transaction
order: number;
command: string;
normalizedParams: Record<string, unknown>;
transactionId?: string; // Set after execution
}The schema is validated using Zod (BatchDataSchema) and stored as JSON Schema in the plugin manifest for runtime validation.
The batchify hook is registered in the manifest and declares options (--batch / -B) that are automatically injected into commands that register it. The hook:
- preSignTransactionHook: When
--batchis present, sets the batch key on the transaction - preExecuteTransactionHook: When
--batchis present, serializes the signed transaction, adds it to the batch state, and returnsbreakFlow: trueto prevent execution
Domain plugins (token, account, topic) register hooks that run during outputPreparation of the batch execute command to persist their state (e.g. saving newly created token IDs) after successful batch execution.
All commands return structured output through the CommandResult interface. Each command defines a Zod schema in output.ts for type-safe output validation and a Handlebars template for human-readable formatting.
Batch Create:
✅ Batch created successfully
Name: my-batch
Batch Key Reference ID: key-ref-123
Batch Execute:
✅ Batch executed successfully
Batch: my-batch
Transaction ID: 0.0.123@1700000000.123456789
Success: true
Batchify (Add to Batch):
✅ Transaction added to batch successfully
Batch: my-batch
Transaction order in batch: 1
Output format is controlled by the CLI's --format option (default: human, or json for machine-readable output).
The plugin includes unit tests for:
- Create: Batch creation, validation, duplicate name handling
- Execute: Batch execution flow, transaction ordering, state updates
- List: Listing batches with correct metadata
- Delete: Whole batch deletion, single transaction removal
- Batchify: Hook interception, transaction collection, batch size limits