@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 data

    • message: string - Descriptive transaction message

    • jobId?: 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