@hsuite/smart-transaction-types - Smart Transaction Type Definitions
⚡ Comprehensive TypeScript type system for Smart Node transaction operations with multi-ledger support
Enterprise-grade type definitions and model library providing robust interfaces, concrete implementations, and runtime validation for smart transactions within the Smart Node ecosystem, supporting Hashgraph with planned Ripple/XRPL integration.
📚 Table of Contents
✨ Quick Start
Installation
npm install @hsuite/smart-transaction-types
Basic Setup
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
import { Status, TransactionId } from '@hashgraph/sdk';
// Interface-based type definitions
const detailsInterface: ISmartTransaction.IDetails = {
status: Status.SUCCESS,
transactionId: "[email protected]"
};
// Model-based runtime validation
const request = new SmartTransaction.Request(
new Uint8Array([1, 2, 3, 4]),
"Transfer 10 HBAR to account 0.0.789012"
);
NestJS Integration
import { SmartTransaction } from '@hsuite/smart-transaction-types';
@Controller('transactions')
export class TransactionController {
@Post('request')
@ApiResponse({ type: SmartTransaction.Request })
async createTransactionRequest(@Body() data: any): Promise<SmartTransaction.Request> {
return new SmartTransaction.Request(
data.bytes,
data.message
);
}
}
🏗️ Architecture
Dual Namespace System
The library provides a comprehensive dual-namespace architecture:
🔧 ISmartTransaction Namespace (Interfaces)
Type Definitions - Pure TypeScript interfaces for type safety
Transaction Details - Status and identifier interface definitions
Execution Interfaces - Transaction execution structure definitions
Request Interfaces - Transaction request and tracking interfaces
🏛️ SmartTransaction Namespace (Models)
Runtime Validation - Concrete classes with built-in validation
Swagger Integration - Complete API documentation decorators
Multi-Ledger Support - Hashgraph with planned Ripple integration
Error Handling - Comprehensive validation and error management
Core Components
📋 Transaction Details
Status Tracking - Comprehensive transaction status management
ID Management - Unique transaction identifier handling
Multi-Format Support - SDK types and string representations
Validation - Runtime validation of status and ID formats
⚡ Transaction Execution
Byte Processing - Binary transaction data handling
Chain Support - Multi-ledger transaction reconstruction
Execution Context - Transaction submission and processing
Format Flexibility - Uint8Array and base64 string support
📝 Transaction Requests
Request Management - Structured transaction request handling
Message Context - Descriptive transaction information
Job Tracking - Optional identifier for transaction correlation
Input Validation - Comprehensive request data validation
🏗️ Abstract Foundation
Base Functionality - Core transaction processing capabilities
Chain Reconstruction - Multi-ledger transaction reconstruction
Extensibility - Foundation for future ledger integrations
Type Safety - Strict TypeScript type enforcement
Module Structure
src/
├── index.ts # Main exports and documentation
├── interfaces/ # ISmartTransaction namespace
│ ├── smart-transaction.namespace.ts # Central interface hub
│ └── interfaces/ # Specific interface definitions
│ ├── smart-transaction.details.interface.ts
│ ├── smart-transaction.execute.interface.ts
│ └── smart-transaction.request.interface.ts
└── models/ # SmartTransaction namespace
├── smart-transaction.namespace.ts # Central model hub
└── models/ # Concrete implementations
├── smart-transaction.abstract.model.ts
├── smart-transaction.details.model.ts
├── smart-transaction.execute.model.ts
└── smart-transaction.request.model.ts
🔧 API Reference
ISmartTransaction Namespace
Core Interface Structure
namespace ISmartTransaction {
IDetails: _IDetails; // Transaction details interface
IExecute: _IExecute; // Transaction execution interface
IRequest: _IRequest; // Transaction request interface
}
Transaction Details Interface
ISmartTransaction.IDetails
Purpose: Represents transaction details for status tracking
Properties:
status: Status | string
- Transaction status (SUCCESS, FAILURE, etc.)transactionId: TransactionId | string
- Unique identifier format "[email protected]"
Usage: Status monitoring and transaction identification
Transaction Execution Interface
ISmartTransaction.IExecute
Purpose: Defines transaction execution structure
Properties:
bytes: Uint8Array | string
- Transaction data in binary or base64 format
Usage: Transaction execution and submission workflows
Transaction Request Interface
ISmartTransaction.IRequest
Purpose: Represents transaction requests with context
Properties:
bytes: Uint8Array | string
- Transaction datamessage: string
- Descriptive transaction messagejobId?: string
- Optional job identifier for tracking
Usage: Transaction request creation and management
SmartTransaction Namespace
Core Model Structure
namespace SmartTransaction {
Abstract: _Abstract; // Base transaction class
Details: _Details; // Transaction details implementation
Execute: _Execute; // Transaction execution implementation
Request: _Request; // Transaction request implementation
}
Abstract Base Class
SmartTransaction.Abstract
Purpose: Base class for transaction operations
Static Methods:
fromBytes(bytes: Uint8Array | string, chain: ChainType): Transaction
Features: Transaction reconstruction from raw data
Supported Chains: Hashgraph (Ripple planned)
Transaction Details Model
SmartTransaction.Details
Constructor:
new Details(status: Status | string, transactionId: TransactionId | string)
Validation: Ensures valid status and transaction ID formats
Features: Full Swagger/OpenAPI support
Decorators: Complete API documentation
Transaction Execution Model
SmartTransaction.Execute
Constructor:
new Execute(bytes: Uint8Array | string)
Extends: Abstract class for reconstruction capabilities
Features: Transaction submission and execution workflows
Validation: Ensures valid byte data format
Transaction Request Model
SmartTransaction.Request
Constructor:
new Request(bytes: Uint8Array | string, message: string)
Validation:
Non-empty bytes (binary or string)
Non-empty, non-whitespace message
Optional job ID tracking
Features: Full Swagger/OpenAPI support
Error Handling
The library provides comprehensive error handling:
Validation Errors: Descriptive messages for invalid inputs
Type Errors: Clear type mismatch notifications
Format Errors: Specific formatting requirement messages
Empty Data Errors: Non-empty data requirement validation
📖 Guides
Transaction Lifecycle Guide
Understand the complete lifecycle of smart transactions from request to completion. Comprehensive guide covering transaction creation, validation, execution, status tracking, and error handling across multiple blockchain networks with enterprise-grade monitoring and management capabilities.
Multi-Ledger Integration Guide
Learn how to integrate transactions across different blockchain networks. Advanced integration guide covering cross-chain transaction management, ledger-specific configurations, chain abstraction layers, unified transaction interfaces, and seamless multi-blockchain operations.
Validation and Error Handling Guide
Implement robust validation and error handling for transaction operations. Detailed implementation guide covering input validation, transaction integrity checks, error classification, recovery strategies, and comprehensive error reporting for enterprise transaction systems.
Status Tracking Guide
Track and monitor transaction status throughout the execution process. Advanced monitoring guide covering status lifecycle management, real-time tracking, progress indicators, completion detection, and enterprise-grade transaction monitoring with alerts and notifications.
🎯 Examples
Basic Transaction Operations
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
import { Status, TransactionId } from '@hashgraph/sdk';
@Injectable()
export class TransactionService {
async createTransactionDetails(status: string, txId: string) {
try {
// Using SDK types
const detailsSDK = new SmartTransaction.Details(
Status.SUCCESS,
new TransactionId("[email protected]")
);
// Using string representations
const detailsString = new SmartTransaction.Details(
"SUCCESS",
"[email protected]"
);
return {
sdk: detailsSDK,
string: detailsString,
status: detailsSDK.status,
transactionId: detailsSDK.transactionId
};
} catch (error) {
throw new Error(`Transaction details creation failed: ${error.message}`);
}
}
async processTransactionExecution(transactionData: Uint8Array) {
try {
// Create execution instance
const execute = new SmartTransaction.Execute(transactionData);
// Reconstruct transaction for specific chain
const transaction = SmartTransaction.Abstract.fromBytes(
execute.bytes,
ChainType.HASHGRAPH
);
return {
success: true,
executionData: execute.bytes,
reconstructedTransaction: transaction,
chainType: 'HASHGRAPH'
};
} catch (error) {
throw new Error(`Transaction execution failed: ${error.message}`);
}
}
async validateTransactionRequest(requestData: any) {
try {
const request = new SmartTransaction.Request(
requestData.bytes,
requestData.message
);
// Add optional job tracking
if (requestData.jobId) {
request.jobId = requestData.jobId;
}
return {
isValid: true,
request: request,
messageLength: request.message.length,
hasJobId: !!request.jobId
};
} catch (error) {
return {
isValid: false,
error: error.message,
validationFailed: true
};
}
}
}
Advanced Transaction Management
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
import { ChainType } from '@hsuite/smart-ledgers';
@Injectable()
export class AdvancedTransactionService {
async batchTransactionProcessing(transactions: any[]) {
const results = [];
for (const txData of transactions) {
try {
// Create transaction request
const request = new SmartTransaction.Request(
txData.bytes,
txData.description
);
// Set unique job ID for tracking
request.jobId = `batch-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
// Create execution context
const execute = new SmartTransaction.Execute(request.bytes);
// Process for different chains
let reconstructedTx;
switch (txData.targetChain) {
case 'HASHGRAPH':
reconstructedTx = SmartTransaction.Abstract.fromBytes(
execute.bytes,
ChainType.HASHGRAPH
);
break;
default:
throw new Error(`Unsupported chain: ${txData.targetChain}`);
}
results.push({
jobId: request.jobId,
success: true,
request: request,
execution: execute,
reconstructedTransaction: reconstructedTx,
processedAt: new Date().toISOString()
});
} catch (error) {
results.push({
success: false,
error: error.message,
originalData: txData,
failedAt: new Date().toISOString()
});
}
}
return {
totalProcessed: transactions.length,
successful: results.filter(r => r.success).length,
failed: results.filter(r => !r.success).length,
results: results
};
}
async monitorTransactionStatus(transactionId: string) {
try {
// Create initial details
const details = new SmartTransaction.Details(
"PENDING",
transactionId
);
// Simulate status progression
const statusProgression = [
"PENDING",
"PROCESSING",
"SUBMITTED",
"SUCCESS"
];
const monitoring = {
transactionId: transactionId,
currentStatus: details.status,
history: [],
startTime: Date.now()
};
for (const status of statusProgression) {
// Update status
const updatedDetails = new SmartTransaction.Details(
status,
transactionId
);
monitoring.history.push({
status: status,
timestamp: Date.now(),
details: updatedDetails
});
// Simulate processing time
await new Promise(resolve => setTimeout(resolve, 1000));
}
monitoring.currentStatus = "SUCCESS";
monitoring.completedAt = Date.now();
monitoring.totalDuration = monitoring.completedAt - monitoring.startTime;
return monitoring;
} catch (error) {
throw new Error(`Transaction monitoring failed: ${error.message}`);
}
}
async handleTransactionErrors(invalidData: any[]) {
const errorAnalysis = [];
for (const data of invalidData) {
try {
// Attempt to create request
const request = new SmartTransaction.Request(
data.bytes,
data.message
);
errorAnalysis.push({
data: data,
valid: true,
request: request
});
} catch (error) {
// Analyze specific error types
let errorType = 'UNKNOWN';
let suggestion = 'Check input data format';
if (error.message.includes('bytes cannot be empty')) {
errorType = 'EMPTY_BYTES';
suggestion = 'Provide non-empty transaction bytes';
} else if (error.message.includes('message cannot be empty')) {
errorType = 'EMPTY_MESSAGE';
suggestion = 'Provide descriptive transaction message';
} else if (error.message.includes('must be either Uint8Array or string')) {
errorType = 'INVALID_BYTES_TYPE';
suggestion = 'Use Uint8Array or base64 string for bytes';
} else if (error.message.includes('message must be a string')) {
errorType = 'INVALID_MESSAGE_TYPE';
suggestion = 'Ensure message is a string type';
}
errorAnalysis.push({
data: data,
valid: false,
error: error.message,
errorType: errorType,
suggestion: suggestion
});
}
}
return {
totalAnalyzed: invalidData.length,
validCount: errorAnalysis.filter(a => a.valid).length,
invalidCount: errorAnalysis.filter(a => !a.valid).length,
errorTypes: [...new Set(errorAnalysis.filter(a => !a.valid).map(a => a.errorType))],
analysis: errorAnalysis
};
}
}
Multi-Ledger Transaction Handling
import { SmartTransaction } from '@hsuite/smart-transaction-types';
import { ChainType } from '@hsuite/smart-ledgers';
@Injectable()
export class MultiLedgerTransactionService {
async processMultiChainTransaction(transactionData: any) {
try {
const request = new SmartTransaction.Request(
transactionData.bytes,
transactionData.message
);
const results = {};
// Process for each target chain
for (const chainType of transactionData.targetChains) {
try {
const execute = new SmartTransaction.Execute(request.bytes);
let chainResult;
switch (chainType) {
case 'HASHGRAPH':
chainResult = await this.processHashgraphTransaction(execute);
break;
case 'RIPPLE':
chainResult = await this.processRippleTransaction(execute);
break;
default:
throw new Error(`Unsupported chain: ${chainType}`);
}
results[chainType] = {
success: true,
result: chainResult,
processedAt: new Date().toISOString()
};
} catch (error) {
results[chainType] = {
success: false,
error: error.message,
failedAt: new Date().toISOString()
};
}
}
return {
originalRequest: request,
chainResults: results,
successfulChains: Object.keys(results).filter(chain => results[chain].success),
failedChains: Object.keys(results).filter(chain => !results[chain].success)
};
} catch (error) {
throw new Error(`Multi-chain transaction processing failed: ${error.message}`);
}
}
private async processHashgraphTransaction(execute: SmartTransaction.Execute) {
try {
// Reconstruct Hashgraph transaction
const transaction = SmartTransaction.Abstract.fromBytes(
execute.bytes,
ChainType.HASHGRAPH
);
return {
chainType: 'HASHGRAPH',
transaction: transaction,
reconstructed: true,
capabilities: ['HCS', 'HTS', 'Smart Contracts', 'Consensus']
};
} catch (error) {
throw new Error(`Hashgraph processing failed: ${error.message}`);
}
}
private async processRippleTransaction(execute: SmartTransaction.Execute) {
try {
// Placeholder for future Ripple implementation
return {
chainType: 'RIPPLE',
status: 'PLANNED',
message: 'Ripple/XRPL support coming soon',
capabilities: ['DEX', 'Payments', 'Escrow', 'Multi-signing']
};
} catch (error) {
throw new Error(`Ripple processing failed: ${error.message}`);
}
}
async getChainCapabilities(chainType: string) {
const capabilities = {
'HASHGRAPH': {
supported: true,
features: [
'Hedera Consensus Service (HCS)',
'Hedera Token Service (HTS)',
'Smart Contracts',
'Account Management',
'File Service',
'Network Services'
],
sdkIntegration: '@hashgraph/sdk',
status: 'ACTIVE'
},
'RIPPLE': {
supported: false,
features: [
'Decentralized Exchange (DEX)',
'Cross-border Payments',
'Escrow Services',
'Multi-signing',
'Payment Channels',
'Hooks (Smart Contracts)'
],
sdkIntegration: 'PLANNED',
status: 'PLANNED'
}
};
return capabilities[chainType] || {
supported: false,
error: 'Unknown chain type',
availableChains: Object.keys(capabilities)
};
}
}
Transaction Validation and Error Handling
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
@Injectable()
export class TransactionValidationService {
async validateTransactionInput(inputData: any) {
const validationResult = {
isValid: true,
errors: [],
warnings: [],
suggestions: []
};
try {
// Validate bytes
if (!inputData.bytes) {
validationResult.errors.push('Transaction bytes are required');
validationResult.isValid = false;
} else {
if (inputData.bytes instanceof Uint8Array && inputData.bytes.length === 0) {
validationResult.errors.push('Transaction bytes cannot be empty');
validationResult.isValid = false;
} else if (typeof inputData.bytes === 'string' && inputData.bytes.trim().length === 0) {
validationResult.errors.push('Transaction bytes string cannot be empty');
validationResult.isValid = false;
}
}
// Validate message
if (!inputData.message) {
validationResult.errors.push('Transaction message is required');
validationResult.isValid = false;
} else if (typeof inputData.message !== 'string') {
validationResult.errors.push('Transaction message must be a string');
validationResult.isValid = false;
} else if (inputData.message.trim().length === 0) {
validationResult.errors.push('Transaction message cannot be empty or whitespace only');
validationResult.isValid = false;
} else if (inputData.message.length < 10) {
validationResult.warnings.push('Transaction message is very short');
validationResult.suggestions.push('Consider providing more descriptive message');
}
// Validate optional jobId
if (inputData.jobId !== undefined && typeof inputData.jobId !== 'string') {
validationResult.errors.push('Job ID must be a string if provided');
validationResult.isValid = false;
}
// Additional validation checks
if (validationResult.isValid) {
try {
// Test creation to catch any other validation issues
const testRequest = new SmartTransaction.Request(
inputData.bytes,
inputData.message
);
if (inputData.jobId) {
testRequest.jobId = inputData.jobId;
}
validationResult.suggestions.push('Input data is valid and ready for processing');
} catch (error) {
validationResult.errors.push(`Validation failed: ${error.message}`);
validationResult.isValid = false;
}
}
return validationResult;
} catch (error) {
return {
isValid: false,
errors: [`Validation process failed: ${error.message}`],
warnings: [],
suggestions: ['Check input data structure and types']
};
}
}
async sanitizeTransactionData(rawData: any) {
try {
const sanitized = {
bytes: null,
message: '',
jobId: undefined
};
// Sanitize bytes
if (rawData.bytes instanceof Uint8Array) {
sanitized.bytes = rawData.bytes;
} else if (typeof rawData.bytes === 'string') {
// Trim and validate base64 if string
sanitized.bytes = rawData.bytes.trim();
} else if (Array.isArray(rawData.bytes)) {
// Convert array to Uint8Array
sanitized.bytes = new Uint8Array(rawData.bytes);
}
// Sanitize message
if (typeof rawData.message === 'string') {
sanitized.message = rawData.message.trim();
} else if (rawData.message !== undefined) {
sanitized.message = String(rawData.message).trim();
}
// Sanitize jobId
if (rawData.jobId && typeof rawData.jobId === 'string') {
sanitized.jobId = rawData.jobId.trim();
} else if (rawData.jobId) {
sanitized.jobId = String(rawData.jobId).trim();
}
return {
success: true,
sanitizedData: sanitized,
changes: {
bytesConverted: rawData.bytes !== sanitized.bytes,
messageTrimmed: rawData.message !== sanitized.message,
jobIdConverted: rawData.jobId !== sanitized.jobId
}
};
} catch (error) {
throw new Error(`Data sanitization failed: ${error.message}`);
}
}
generateValidationReport(validationResults: any[]) {
const report = {
totalValidated: validationResults.length,
valid: 0,
invalid: 0,
warnings: 0,
commonErrors: {},
summary: {}
};
validationResults.forEach(result => {
if (result.isValid) {
report.valid++;
} else {
report.invalid++;
}
if (result.warnings.length > 0) {
report.warnings++;
}
// Collect common errors
result.errors.forEach(error => {
if (report.commonErrors[error]) {
report.commonErrors[error]++;
} else {
report.commonErrors[error] = 1;
}
});
});
report.summary = {
successRate: ((report.valid / report.totalValidated) * 100).toFixed(2) + '%',
mostCommonError: Object.keys(report.commonErrors).reduce((a, b) =>
report.commonErrors[a] > report.commonErrors[b] ? a : b
) || 'None',
hasWarnings: report.warnings > 0
};
return report;
}
}
Status Tracking and Monitoring
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
import { Status, TransactionId } from '@hashgraph/sdk';
@Injectable()
export class TransactionStatusService {
private statusHistory = new Map<string, any[]>();
async trackTransactionLifecycle(transactionId: string) {
try {
const lifecycle = {
transactionId,
stages: [],
currentStatus: 'INITIATED',
startTime: Date.now(),
endTime: null,
duration: null
};
// Stage 1: Transaction Created
const createdDetails = new SmartTransaction.Details(
"CREATED",
transactionId
);
lifecycle.stages.push({
stage: 'CREATED',
status: createdDetails.status,
timestamp: Date.now(),
details: createdDetails
});
// Stage 2: Transaction Submitted
await this.simulateDelay(1000);
const submittedDetails = new SmartTransaction.Details(
"SUBMITTED",
transactionId
);
lifecycle.stages.push({
stage: 'SUBMITTED',
status: submittedDetails.status,
timestamp: Date.now(),
details: submittedDetails
});
// Stage 3: Transaction Processing
await this.simulateDelay(2000);
const processingDetails = new SmartTransaction.Details(
Status.PENDING,
new TransactionId(transactionId)
);
lifecycle.stages.push({
stage: 'PROCESSING',
status: processingDetails.status,
timestamp: Date.now(),
details: processingDetails
});
// Stage 4: Transaction Success
await this.simulateDelay(1500);
const successDetails = new SmartTransaction.Details(
Status.SUCCESS,
new TransactionId(transactionId)
);
lifecycle.stages.push({
stage: 'COMPLETED',
status: successDetails.status,
timestamp: Date.now(),
details: successDetails
});
lifecycle.currentStatus = 'COMPLETED';
lifecycle.endTime = Date.now();
lifecycle.duration = lifecycle.endTime - lifecycle.startTime;
// Store in history
this.statusHistory.set(transactionId, lifecycle.stages);
return lifecycle;
} catch (error) {
throw new Error(`Transaction lifecycle tracking failed: ${error.message}`);
}
}
async getStatusHistory(transactionId: string) {
const history = this.statusHistory.get(transactionId);
if (!history) {
return {
found: false,
message: 'No status history found for transaction'
};
}
return {
found: true,
transactionId,
totalStages: history.length,
history: history,
analysis: {
totalDuration: history[history.length - 1].timestamp - history[0].timestamp,
averageStageTime: (history[history.length - 1].timestamp - history[0].timestamp) / history.length,
longestStage: this.findLongestStage(history),
shortestStage: this.findShortestStage(history)
}
};
}
private findLongestStage(history: any[]) {
let longest = { stage: '', duration: 0 };
for (let i = 1; i < history.length; i++) {
const duration = history[i].timestamp - history[i-1].timestamp;
if (duration > longest.duration) {
longest = { stage: history[i].stage, duration };
}
}
return longest;
}
private findShortestStage(history: any[]) {
let shortest = { stage: '', duration: Infinity };
for (let i = 1; i < history.length; i++) {
const duration = history[i].timestamp - history[i-1].timestamp;
if (duration < shortest.duration) {
shortest = { stage: history[i].stage, duration };
}
}
return shortest;
}
private async simulateDelay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
async generateStatusReport(transactionIds: string[]) {
const report = {
totalTransactions: transactionIds.length,
tracked: 0,
untracked: 0,
statusBreakdown: {},
performanceMetrics: {
averageDuration: 0,
fastestTransaction: null,
slowestTransaction: null
}
};
const durations = [];
for (const txId of transactionIds) {
const history = await this.getStatusHistory(txId);
if (history.found) {
report.tracked++;
// Status breakdown
const finalStatus = history.history[history.history.length - 1].status;
if (report.statusBreakdown[finalStatus]) {
report.statusBreakdown[finalStatus]++;
} else {
report.statusBreakdown[finalStatus] = 1;
}
// Performance tracking
durations.push(history.analysis.totalDuration);
} else {
report.untracked++;
}
}
if (durations.length > 0) {
report.performanceMetrics.averageDuration = durations.reduce((a, b) => a + b, 0) / durations.length;
report.performanceMetrics.fastestTransaction = Math.min(...durations);
report.performanceMetrics.slowestTransaction = Math.max(...durations);
}
return report;
}
}
🔗 Integration
Required Dependencies
{
"@nestjs/common": "^10.4.2",
"@nestjs/core": "^10.4.2",
"@hsuite/nestjs-swagger": "^1.0.3",
"@hashgraph/sdk": "^2.62.0",
"@hsuite/smart-ledgers": "^2.0.0",
"lodash": "^4.17.21",
"@compodoc/compodoc": "^1.1.23"
}
TypeScript Configuration
{
"compilerOptions": {
"declaration": true,
"outDir": "../../dist/libs/smart-transaction-types",
"types": ["node"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
Module Integration
import { Module } from '@nestjs/common';
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
@Module({
providers: [
TransactionService,
AdvancedTransactionService,
MultiLedgerTransactionService,
TransactionValidationService,
TransactionStatusService
],
exports: [
TransactionService,
AdvancedTransactionService,
MultiLedgerTransactionService,
TransactionValidationService,
TransactionStatusService
]
})
export class SmartTransactionModule {}
Documentation Generation
# Generate comprehensive documentation
npm run compodoc
# Generate documentation with coverage report
npm run compodoc:coverage
Error Handling Patterns
// Comprehensive error handling
try {
const request = new SmartTransaction.Request(
new Uint8Array([]), // This will fail
"" // This will also fail
);
} catch (error) {
console.error('Validation failed:', error.message);
// Handle specific error types
if (error.message.includes('bytes cannot be empty')) {
// Handle empty bytes error
} else if (error.message.includes('message cannot be empty')) {
// Handle empty message error
}
}
Integration with HSuite Ecosystem
// Complete integration with other HSuite modules
import { SmartTransaction, ISmartTransaction } from '@hsuite/smart-transaction-types';
import { AuthModule } from '@hsuite/auth';
import { HashgraphModule } from '@hsuite/hashgraph';
import { ValidatorsModule } from '@hsuite/validators';
@Module({
imports: [
AuthModule,
HashgraphModule,
ValidatorsModule
]
})
export class SmartTransactionEcosystemModule {}
@Injectable()
export class IntegratedTransactionService {
constructor(
private authService: AuthService,
private hashgraphService: HashgraphService,
private validatorsService: ValidatorsService
) {}
async executeSecureTransaction(
transactionData: any,
session: IAuth.ICredentials.IWeb3.IEntity
): Promise<SmartTransaction.Details> {
// 1. Validate permissions
const hasPermission = await this.authService.validatePermission(
session,
'transaction:execute'
);
if (!hasPermission) {
throw new Error('Insufficient permissions for transaction execution');
}
// 2. Create and validate transaction request
const request = new SmartTransaction.Request(
transactionData.bytes,
transactionData.message
);
// 3. Validate with transaction validators
const validationResult = await this.validatorsService.validateTransaction(request);
if (!validationResult.isValid) {
throw new Error(`Transaction validation failed: ${validationResult.errors.join(', ')}`);
}
// 4. Execute transaction
const execute = new SmartTransaction.Execute(request.bytes);
const transaction = SmartTransaction.Abstract.fromBytes(
execute.bytes,
ChainType.HASHGRAPH
);
// 5. Submit to Hashgraph
const txResponse = await this.hashgraphService.submitTransaction(transaction);
// 6. Create transaction details
const details = new SmartTransaction.Details(
txResponse.status,
txResponse.transactionId
);
return details;
}
}
⚡ Enterprise Transaction System: Comprehensive TypeScript definitions with runtime validation and multi-ledger support for Smart Node operations.
🔄 Multi-Chain Ready: Current Hashgraph integration with planned Ripple/XRPL support for cross-ledger transaction processing.
🛡️ Type-Safe Operations: Full TypeScript support with strict validation, comprehensive error handling, and seamless NestJS integration.
Built with ❤️ by the HbarSuite Team Copyright © 2024 HbarSuite. All rights reserved.
Last updated