@hsuite/helpers - Utility Library

🛠️ Comprehensive utility library for Hedera Hashgraph development and market data integration

Essential helper functions for offline transaction handling, cryptocurrency price fetching via CoinGecko API, and enhanced logging capabilities within the Smart Node ecosystem.


Table of Contents


Quick Start

Installation

npm install @hsuite/helpers

Basic Usage

import { CoingeckoHelper, LoggerHelper, HashgraphOfflineTransactionHelper } from '@hsuite/helpers';

// Enhanced logging
const logger = new LoggerHelper('MyService');
logger.log('Service started');

// CoinGecko integration
const coingecko = new CoingeckoHelper(httpService);
const btcData = await coingecko.fetchTokenMarkets('bitcoin');

// Offline transactions
const txHelper = new HashgraphOfflineTransactionHelper(config, client, network);
const nodes = await txHelper.getHederaNodes();

Architecture

Core Utilities

📊 Market Data Integration

  • CoingeckoHelper - CoinGecko API integration for cryptocurrency market data

  • Enhanced Error Handling - Robust data formatting and error management

  • Rate Limiting - Built-in API rate limiting and retry logic

📝 Enhanced Logging

  • LoggerHelper - Advanced logging with global and instance-level control

  • Flexible Control - Enable/disable logging at global or service level

  • NestJS Integration - Extends NestJS Logger with enhanced functionality

Offline Transactions

  • HashgraphOfflineTransactionHelper - Hedera transaction utilities for offline workflows

  • Node Discovery - Automatic network node discovery and selection

  • Multi-Service Integration - Works with ClientService and NetworkService

Module Structure

src/
├── commons/                     # Common utility functions
├── hashgraph/                   # Hedera Hashgraph specific utilities
│   └── offline-transaction.helper.ts # Offline transaction management
├── index.ts                    # Public API exports
└── interfaces/                 # TypeScript interfaces

API Reference

CoingeckoHelper

Constructor: new CoingeckoHelper(httpService: HttpService)

Methods

fetchTokenMarkets(coinId: string): Promise<TokenMarketData>

  • Retrieves comprehensive market data for a specific cryptocurrency

  • Parameters: coinId - CoinGecko coin identifier (e.g., 'bitcoin', 'hedera-hashgraph')

  • Returns: Formatted object with price, volume, supply, and metadata

  • Throws: Error if API request fails or invalid response

interface TokenMarketData {
  symbol: string;              // Token symbol (e.g., 'btc')
  name: string;                // Full token name (e.g., 'Bitcoin')
  icon: string;                // Icon URL
  price: number;               // Current USD price
  volume: number;              // 24h trading volume
  high_24h: number;            // 24h high price
  low_24h: number;             // 24h low price
  price_change_24h: number;    // 24h price change
  total_supply: number;        // Total token supply
  circulating_supply: number;  // Circulating supply
  last_updated: string;        // Last update timestamp
}

LoggerHelper

Constructor: new LoggerHelper(context: string)

Static Methods

setGlobalLoggingEnabled(enabled: boolean): void

  • Controls logging globally across all LoggerHelper instances

  • Parameters: enabled - Whether to enable global logging

Instance Methods

setLoggingEnabled(enabled: boolean): void

  • Controls logging for specific instance

  • Parameters: enabled - Whether to enable instance logging

Standard Logging Methods:

  • log(message: string, ...optionalParams: any[]): void

  • error(message: string, trace?: string, ...optionalParams: any[]): void

  • warn(message: string, ...optionalParams: any[]): void

  • debug(message: string, ...optionalParams: any[]): void

  • verbose(message: string, ...optionalParams: any[]): void

HashgraphOfflineTransactionHelper

Constructor: new HashgraphOfflineTransactionHelper(configService, clientService, networkService)

Methods

getHederaNodes(): Promise<AccountId[]>

  • Fetches all available Hedera network nodes

  • Returns: Array of AccountId objects representing network nodes

  • Throws: Error if network discovery fails

getRandomHederaNode(): Promise<AccountId>

  • Returns a randomly selected Hedera network node

  • Returns: Single AccountId for load balancing

  • Throws: Error if no nodes available


Guides

Market Data Integration Guide

Learn how to integrate CoinGecko API for real-time cryptocurrency market data. Set up token price monitoring, market cap tracking, and historical data analysis for your applications.

Enhanced Logging Guide

Set up advanced logging with global and instance-level control. Configure logging levels, structured logging patterns, and debug controls for production environments.

Offline Transaction Guide

Handle Hedera Hashgraph transactions for offline workflows and node management. Implement transaction queuing, node selection, and load balancing strategies.


Examples

CoinGecko Market Data Integration

import { Injectable } from '@nestjs/common';
import { CoingeckoHelper } from '@hsuite/helpers';
import { HttpService } from '@nestjs/axios';

@Injectable()
export class TokenService {
  private coingecko: CoingeckoHelper;

  constructor(private httpService: HttpService) {
    this.coingecko = new CoingeckoHelper(httpService);
  }

  async getBitcoinData() {
    try {
      const btcData = await this.coingecko.fetchTokenMarkets('bitcoin');
      
      return {
        symbol: btcData.symbol,        // 'btc'
        name: btcData.name,            // 'Bitcoin'
        price: btcData.price,          // Current USD price
        volume: btcData.volume,        // 24h trading volume
        high24h: btcData.high_24h,     // 24h high
        low24h: btcData.low_24h,       // 24h low
        priceChange: btcData.price_change_24h,
        totalSupply: btcData.total_supply,
        circulatingSupply: btcData.circulating_supply,
        lastUpdated: btcData.last_updated
      };
    } catch (error) {
      console.error('Failed to fetch Bitcoin data:', error);
      throw error;
    }
  }

  async getHederaData() {
    const hbarData = await this.coingecko.fetchTokenMarkets('hedera-hashgraph');
    return {
      price: hbarData.price,
      marketCap: hbarData.price * hbarData.circulating_supply,
      volume24h: hbarData.volume
    };
  }

  async getMultipleTokens() {
    const tokens = ['bitcoin', 'ethereum', 'hedera-hashgraph'];
    const results = await Promise.all(
      tokens.map(token => this.coingecko.fetchTokenMarkets(token))
    );
    
    return results.map(data => ({
      symbol: data.symbol,
      price: data.price,
      change24h: data.price_change_24h
    }));
  }
}

Enhanced Logging Patterns

import { Injectable } from '@nestjs/common';
import { LoggerHelper } from '@hsuite/helpers';

@Injectable()
export class MyService {
  private logger = new LoggerHelper(MyService.name);

  async performOperation() {
    // Standard logging
    this.logger.log('Starting operation');
    
    try {
      this.logger.debug('Operation in progress');
      
      const result = await this.processData();
      
      this.logger.log('Operation completed successfully', { 
        result,
        duration: '123ms'
      });
      
      return result;
    } catch (error) {
      this.logger.error('Operation failed', error.stack);
      throw error;
    }
  }

  // Global logging control
  disableAllLogging() {
    LoggerHelper.setGlobalLoggingEnabled(false);
    this.logger.log('This will not appear');
  }

  // Instance-level logging control
  muteThisService() {
    this.logger.setLoggingEnabled(false);
    this.logger.log('This will not appear');
  }

  // Conditional logging
  conditionalLogging(isDebugMode: boolean) {
    this.logger.setLoggingEnabled(isDebugMode);
    this.logger.debug('Debug information'); // Only shows if enabled
  }

  private async processData() {
    this.logger.verbose('Processing data in detail');
    // Simulate processing
    await new Promise(resolve => setTimeout(resolve, 100));
    return { processed: true };
  }
}

Offline Transaction Management

import { Injectable } from '@nestjs/common';
import { HashgraphOfflineTransactionHelper } from '@hsuite/helpers';
import { SmartConfigService } from '@hsuite/smart-config';
import { ClientService } from '@hsuite/client';
import { NetworkService } from '@hsuite/mirrors';

@Injectable()
export class TransactionService {
  private helper: HashgraphOfflineTransactionHelper;

  constructor(
    private configService: SmartConfigService,
    private clientService: ClientService,
    private networkService: NetworkService
  ) {
    this.helper = new HashgraphOfflineTransactionHelper(
      configService,
      clientService,
      networkService
    );
  }

  async prepareOfflineTransaction() {
    try {
      // Get all available Hedera nodes
      const allNodes = await this.helper.getHederaNodes();
      console.log(`Found ${allNodes.length} nodes`);

      // Get a random node for transaction submission
      const randomNode = await this.helper.getRandomHederaNode();
      console.log(`Selected node: ${randomNode.toString()}`);

      return { 
        allNodes, 
        selectedNode: randomNode,
        nodeCount: allNodes.length
      };
    } catch (error) {
      console.error('Failed to prepare offline transaction:', error);
      throw error;
    }
  }

  async loadBalanceTransactions() {
    // Use multiple nodes for load balancing
    const tasks = [];
    for (let i = 0; i < 5; i++) {
      tasks.push(this.helper.getRandomHederaNode());
    }
    
    const selectedNodes = await Promise.all(tasks);
    
    return selectedNodes.map((node, index) => ({
      taskId: index + 1,
      assignedNode: node.toString()
    }));
  }

  async monitorNetworkHealth() {
    try {
      const nodes = await this.helper.getHederaNodes();
      
      return {
        totalNodes: nodes.length,
        status: nodes.length > 0 ? 'healthy' : 'unhealthy',
        nodes: nodes.slice(0, 5).map(node => node.toString()) // Show first 5
      };
    } catch (error) {
      return {
        totalNodes: 0,
        status: 'error',
        error: error.message
      };
    }
  }
}

Integration

Required Dependencies

{
  "@hashgraph/sdk": "^2.62.0",
  "@hsuite/hashgraph-types": "^2.0.3",
  "@hsuite/smart-config": "^2.1.1",
  "@nestjs/axios": "^3.0.2"
}

Environment Variables

# CoinGecko Configuration
COINGECKO_API_KEY=your-coingecko-pro-api-key

# Hedera Configuration (for offline transactions)
HEDERA_NETWORK=testnet
HEDERA_ACCOUNT_ID=0.0.123456
HEDERA_PRIVATE_KEY=302e020100300506032b657004220420...

# Logging Configuration (optional)
LOG_LEVEL=debug
GLOBAL_LOGGING_ENABLED=true

Module Integration

import { HttpModule } from '@nestjs/axios';
import { CoingeckoHelper, LoggerHelper } from '@hsuite/helpers';

@Module({
  imports: [HttpModule],
  providers: [
    CoingeckoHelper,
    {
      provide: 'APP_LOGGER',
      useFactory: () => new LoggerHelper('AppModule')
    }
  ],
  exports: [CoingeckoHelper, 'APP_LOGGER']
})
export class UtilitiesModule {}

💡 Best Practices:

  • Use LoggerHelper for consistent logging across your application

  • Cache CoinGecko API responses to avoid rate limiting

  • Handle offline transaction errors gracefully with proper retry logic

⚠️ Rate Limits: CoinGecko API has rate limits. Consider implementing caching for production use.

Built with ❤️ by the HbarSuite Team Copyright © 2024 HbarSuite. All rights reserved.

Last updated