Architecture Overview
Understanding the Hoosat SDK's architecture will help you build better applications and use the SDK more effectively.
Design Philosophy
The Hoosat SDK is built with these principles:
- Modularity - Each module has a single, well-defined purpose
- Type Safety - Full TypeScript support with comprehensive types
- Error Handling - Consistent error patterns across all methods
- Production Ready - Built for real-world production use
- Developer Experience - Intuitive APIs with excellent documentation
SDK Structure
hoosat-sdk/
├── Client Layer (HoosatClient)
├── Cryptography (HoosatCrypto, HoosatSigner)
├── Transactions (HoosatTxBuilder)
├── Fee Management (HoosatFeeEstimator)
├── Events (HoosatEventManager)
├── QR Codes (HoosatQR)
└── Utilities (HoosatUtils)
Core Modules
HoosatClient
The main entry point for all blockchain interactions.
Purpose: Connect to Hoosat nodes and query blockchain data
Key responsibilities:
- Node connection management
- gRPC communication
- Blockchain queries (blocks, transactions, balances)
- UTXO management
- Transaction submission
- Network information
Example:
const client = new HoosatClient({
host: '54.38.176.95',
port: 42420
});
const info = await client.getInfo();
const balance = await client.getBalance(address);
When to use:
- Connecting to nodes
- Querying blockchain data
- Submitting transactions
- Monitoring network status
HoosatCrypto
Cryptographic operations using ECDSA secp256k1.
Purpose: Key management and transaction signing
Key responsibilities:
- Key pair generation
- Private key import
- Address creation (ECDSA, Schnorr, P2SH)
- Transaction signing
- Hash generation (BLAKE3)
- Fee calculation
Example:
// Generate new wallet
const wallet = HoosatCrypto.generateKeyPair('mainnet');
// Import existing wallet
const imported = HoosatCrypto.importKeyPair(privateKeyHex);
// Sign transaction
const signedTx = HoosatCrypto.signTransaction(tx, privateKey);
When to use:
- Creating or importing wallets
- Generating addresses
- Signing transactions
- Cryptographic hashing
HoosatTxBuilder
Fluent API for building transactions.
Purpose: Construct and sign transactions easily
Key responsibilities:
- Input management
- Output management
- Automatic change calculation
- Fee setting
- Transaction signing
- Validation
Example:
const builder = new HoosatTxBuilder();
builder
.addInput(utxo, privateKey)
.addOutput(recipientAddress, amount)
.setFee(estimatedFee)
.addChangeOutput(myAddress);
const signedTx = builder.sign();
When to use:
- Building any transaction
- Managing inputs and outputs
- Calculating change
- Signing transactions
HoosatFeeEstimator
Dynamic fee estimation based on network conditions.
Purpose: Calculate optimal transaction fees
Key responsibilities:
- Mempool analysis
- Fee rate calculation
- Priority-based recommendations
- Caching for performance
- Outlier filtering
Example:
const estimator = new HoosatFeeEstimator(client);
// Get all recommendations
const recs = await estimator.getRecommendations();
console.log('Normal priority:', recs.normal.feeRate);
// Estimate for specific transaction
const fee = await estimator.estimateFee(
FeePriority.Normal,
inputsCount,
outputsCount
);
When to use:
- Before building transactions
- Checking current fee market
- Optimizing transaction costs
- Implementing fee selection UI
HoosatEventManager
Real-time blockchain event streaming.
Purpose: Monitor blockchain changes in real-time
Key responsibilities:
- UTXO change subscriptions
- WebSocket connection management
- Automatic reconnection
- Event emission
- Connection state tracking
Example:
// Subscribe to address
await client.events.subscribeToUtxoChanges([address]);
// Listen for changes
client.events.on(EventType.UtxoChange, (notification) => {
console.log('UTXOs changed!');
console.log('Added:', notification.changes.added);
console.log('Removed:', notification.changes.removed);
});
// Handle connection events
client.events.on(EventType.Reconnected, () => {
console.log('Reconnected successfully');
});
When to use:
- Real-time balance monitoring
- Payment detection
- Wallet synchronization
- Transaction confirmation tracking
HoosatSigner
Message signing for off-chain authentication.
Purpose: Sign and verify messages for DApp authentication
Key responsibilities:
- Message signing (ECDSA)
- Signature verification
- Public key recovery
- DApp authentication
- Proof of ownership
Example:
// Sign message
const signature = HoosatSigner.signMessage(privateKey, message);
// Verify signature
const isValid = HoosatSigner.verifyMessage(
signature,
message,
publicKey
);
// Create signed message for DApp
const signedMsg = HoosatSigner.createSignedMessage(
privateKey,
'Login to MyApp',
'mainnet',
{ appId: 'my-app' }
);
When to use:
- DApp authentication
- Proving address ownership
- Off-chain message signing
- Secure login systems
HoosatQR
QR code generation and parsing.
Purpose: Generate payment QR codes
Key responsibilities:
- Address QR generation
- Payment URI QR codes
- URI parsing
- Multiple output formats
Example:
// Simple address QR
const qr = await HoosatQR.generateAddressQR(address);
// Payment request with amount
const paymentQR = await HoosatQR.generatePaymentQR({
address,
amount: 100,
label: 'Coffee Shop',
message: 'Order #123'
});
// Parse scanned QR
const parsed = HoosatQR.parsePaymentURI(scannedUri);
When to use:
- Payment request generation
- Address sharing
- Mobile wallet integration
- Point-of-sale systems
HoosatUtils
Utility functions for validation and conversion.
Purpose: Helper functions for common operations
Key responsibilities:
- Address validation
- Amount conversion (HTN ↔ sompi)
- Hash validation
- Key validation
- Formatting helpers
- Network detection
Example:
// Validate address
const isValid = HoosatUtils.isValidAddress(address);
// Convert amounts
const sompi = HoosatUtils.amountToSompi('1.5'); // HTN to sompi
const htn = HoosatUtils.sompiToAmount(sompi); // sompi to HTN
// Format
const truncated = HoosatUtils.truncateAddress(address);
const formatted = HoosatUtils.formatAmount('1.23456', 2);
// Get address info
const network = HoosatUtils.getAddressNetwork(address);
const type = HoosatUtils.getAddressType(address);
When to use:
- Validating user input
- Converting between units
- Formatting for display
- Address type detection
Data Flow
Query Flow
Application
↓
HoosatClient
↓
gRPC Client
↓
Hoosat Node
↓
Response
↓
BaseResult<T>
↓
Application
Transaction Flow
Application
↓
HoosatTxBuilder
↓
HoosatCrypto (signing)
↓
HoosatClient.submitTransaction()
↓
gRPC Client
↓
Hoosat Node
↓
Transaction ID
↓
Application
Event Flow
Hoosat Node
↓
gRPC Stream
↓
HoosatEventManager
↓
Event Emitter
↓
Application Listeners
Error Handling Pattern
All SDK methods follow a consistent error handling pattern:
interface BaseResult<T> {
ok: boolean;
result: T | null;
error: string | null;
}
Usage:
const result = await client.getBalance(address);
if (result.ok) {
// Success - result.result contains data
const balance = result.result.balance;
} else {
// Error - result.error contains error message
console.error('Error:', result.error);
}
Benefits:
- No try-catch needed for expected errors
- Explicit success/error handling
- Type-safe error checking
- Consistent across all methods
Module Dependencies
HoosatClient
├── HoosatEventManager (embedded)
├── gRPC Client
└── Protocol Buffers
HoosatTxBuilder
├── HoosatCrypto (for signing)
└── HoosatUtils (for validation)
HoosatFeeEstimator
└── HoosatClient (for mempool data)
HoosatSigner
├── HoosatCrypto (for hashing)
└── secp256k1 library
HoosatQR
├── HoosatUtils (for validation)
└── qrcode library
HoosatUtils
└── No dependencies (pure functions)
Performance Considerations
Caching
Fee Estimator caches mempool data:
const estimator = new HoosatFeeEstimator(client, {
cacheDuration: 60000 // Cache for 1 minute
});
Connection Pooling
Multi-node setup maintains persistent connections:
const client = new HoosatClient({
nodes: [...], // Connections managed automatically
healthCheckInterval: 30000
});
Event Streaming
EventManager uses single WebSocket connection:
// Single connection for all addresses
await client.events.subscribeToUtxoChanges([
address1,
address2,
address3
]);
Type System
The SDK provides comprehensive TypeScript types:
import type {
// Client types
HoosatClientConfig,
NodeConfig,
NodeStatus,
// Transaction types
Transaction,
TransactionInput,
TransactionOutput,
UtxoForSigning,
// Result types
BaseResult,
GetInfo,
GetBalance,
// Event types
EventManagerConfig,
UtxoChangeNotification,
// Crypto types
KeyPair,
SignedMessage
} from 'hoosat-sdk';