controller.ts
Overview
The [controller.ts](/projects/291/68853) file is a configuration and setup module for the Bitcoin Cash (BCH) blockchain integration within a larger application. Its main purpose is to initialize and export a configured UTXO (Unspent Transaction Output) service that interacts with blockchain data sources via both REST and WebSocket APIs. It also provides utility functions related to address formatting and public key identification tailored specifically for Bitcoin Cash's addressing schemes.
This file acts as a bridge between low-level blockchain data providers (like Blockbook and RPC nodes) and higher-level UTXO-related operations, ensuring that the rest of the system can work with BCH blockchain data seamlessly and correctly formatted.
Detailed Explanation
Constants and Environment Variables
INDEXER_URL: URL of the indexer API (Blockbook REST endpoint).INDEXER_WS_URL: URL of the WebSocket endpoint for real-time blockchain updates.INDEXER_API_KEY: API key for the indexer service.RPC_URL: URL for the RPC node endpoint.RPC_API_KEY: API key for the RPC node.
The file checks for the existence of critical environment variables and throws errors if they are missing, enforcing mandatory configuration.
Logger
export const logger = new Logger({
namespace: ['unchained', 'coinstacks', 'bitcoincash', 'api'],
level: process.env.LOG_LEVEL,
})
Purpose: Creates a logger instance scoped to Bitcoin Cash API operations, with its verbosity controlled by the
LOG_LEVELenvironment variable.Usage: Used internally by the Blockbook client and other services for consistent logging.
Blockbook Client Instance
const blockbook = new Blockbook({ httpURL: INDEXER_URL, wsURL: INDEXER_WS_URL, apiKey: INDEXER_API_KEY, logger })
Purpose: Instantiates the Blockbook client configured with HTTP and WebSocket URLs plus API keys for accessing BCH blockchain data.
Details: Blockbook is a blockchain API providing REST and WebSocket interfaces to query transactions, blocks, and addresses.
Function: isXpub(pubkey: string): boolean
const isXpub = (pubkey: string): boolean => {
return pubkey.startsWith('xpub') || pubkey.startsWith('ypub') || pubkey.startsWith('zpub')
}
Purpose: Checks if a given public key string corresponds to an extended public key (xpub, ypub, zpub), which are common formats used in hierarchical deterministic wallets.
Parameters:
pubkey: string — The public key string to test.
Returns:
trueif the string starts with one of the recognized extended public key prefixes; otherwise,false.Usage Example:
isXpub('xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKpR...'); // returns true
Function: formatAddress(address: string): string
export const formatAddress = (address: string): string => {
if (address.startsWith('bitcoincash') || bech32.decodeUnsafe(address.toLowerCase())?.prefix === 'bc')
return address.toLowerCase()
if (address.startsWith('q')) return `bitcoincash:${address.toLowerCase()}`
return address
}
Purpose: Normalizes Bitcoin Cash addresses to ensure they are in the expected CashAddr format with the
bitcoincash:prefix as required by the Blockbook API.Parameters:
address: string — A Bitcoin Cash address that may or may not be prefixed.
Returns: A lowercased Bitcoin Cash address string with the
bitcoincash:prefix added if missing.Implementation Details:
Checks if the address already has a recognized prefix (
bitcoincash, or a valid Bech32 prefixbc).If the address starts with
q(typical of CashAddr without prefix), it adds thebitcoincash:prefix.Otherwise, returns the address as-is.
Usage Example:
formatAddress('qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn'); // returns 'bitcoincash:qpzry9x8gf2tvdw0s3jn54khce6mua7lcw20ayyn'
Exported Service Instance: service
export const service = new Service({
blockbook,
rpcApiKey: RPC_API_KEY,
rpcUrl: RPC_URL,
isXpub,
addressFormatter: formatAddress,
})
Purpose: Creates an instance of the UTXO
Serviceconfigured specifically for Bitcoin Cash, supplying blockchain data interfaces and utility functions.Parameters supplied to Service constructor:
blockbook: The Blockbook client instance.rpcApiKeyandrpcUrl: Credentials and endpoint for RPC node access.isXpub: Function to detect extended public keys.addressFormatter: Function to normalize BCH addresses.
Usage: This service handles blockchain data fetching, transaction parsing, and other UTXO operations behind the scenes.
Assigning the Service to UTXO Controller
UTXO.service = service
Purpose: Sets the static
serviceproperty of theUTXOcontroller class to the instantiated BCH-specific service.Effect: All instances or static calls to
UTXOwill use this configured service for BCH blockchain interactions.
Implementation Details and Algorithms
Address Formatting: Uses
bech32decoding to detect if an address already has a prefix, avoiding double-prefixing.Public Key Type Detection: Simple prefix-based string matching for xpub/ypub/zpub formats.
Service Configuration: Combines multiple data sources (Blockbook REST, WebSocket, RPC node) with utility functions to provide a robust interface for UTXO management.
Error Handling: Immediate validation of critical environment variables to fail fast if configuration is incomplete.
Interactions with Other Parts of the System
ServiceClass (imported from../../../common/api/src/utxo/service): The core blockchain service interface that this file configures and exports for Bitcoin Cash.UTXOController (imported from../../../common/api/src/utxo/controller): The higher-level controller class that uses the configured service to perform UTXO-related operations.BlockbookClient (from@shapeshiftoss/blockbook): Provides REST and WebSocket blockchain data.Logger(from@shapeshiftoss/logger): Provides logging scoped to BCH API operations.Environment Variables: Supplies API URLs and keys that configure external blockchain data providers.
Together, these components enable the application to query, monitor, and manipulate Bitcoin Cash blockchain data efficiently.
Usage Example
import { UTXO } from './controller'
// Example: check if a string is an xpub
const testPubkey = 'xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKpR...'
console.log(UTXO.service.isXpub(testPubkey)) // true
// Example: format an address for Blockbook queries
const rawAddress = 'qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
const formatted = UTXO.service.addressFormatter(rawAddress)
console.log(formatted) // bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a
// Use UTXO service to fetch unspent outputs or transactions (pseudo-code)
// const utxos = await UTXO.service.getUTXOs(formatted)
Mermaid Class Diagram
classDiagram
class ControllerModule {
<<module>>
+logger: Logger
+blockbook: Blockbook
+isXpub(pubkey: string): boolean
+formatAddress(address: string): string
+service: Service
}
class Service {
+blockbook: Blockbook
+rpcApiKey: string | undefined
+rpcUrl: string | undefined
+isXpub(pubkey: string): boolean
+addressFormatter(address: string): string
+...other methods
}
class Blockbook {
+httpURL: string
+wsURL: string
+apiKey: string | undefined
+logger: Logger
+...other methods
}
class Logger {
+namespace: string[]
+level: string | undefined
+log()
+error()
+warn()
+info()
}
class UTXO {
<<controller>>
+service: Service
}
ControllerModule --> Service : "instantiates"
ControllerModule --> Blockbook : "instantiates"
ControllerModule --> Logger : "instantiates"
Service --> Blockbook : "uses"
Service --> Logger : "uses"
UTXO --> Service : "static property assignment"
Summary
This file is essential for the Bitcoin Cash integration in the system, establishing the blockchain data sources, formatting utilities, and service wrappers required for UTXO management. It ensures that the rest of the application interacts with BCH data in a standardized and reliable manner. The combination of environment-driven configuration, utility functions, and service instantiation encapsulates BCH-specific logic cleanly and extensibly.