Blockchain Traits

This commit is contained in:
Jim Hamill
2025-04-20 02:22:30 +00:00
parent b097abbd1c
commit 22bff76a55
13 changed files with 302 additions and 189 deletions
@@ -1,10 +1,9 @@
import { EventEmitter } from '../utils';
import {
type AddressCallback,
type BlockchainCallback,
type BlockchainUTXOs,
type BlockchainTransactions,
type TransactionCallback,
} from './types.js';
import { type Transaction } from '@xocash/primitives';
@@ -25,7 +24,10 @@ export type BlockchainEvents = {
* @abstract
* @extends {EventEmitter<BlockchainEvents>}
*/
export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
export abstract class BaseBlockchain<
AddressNotificationPayload = undefined,
TransactionNotificationPayload = undefined,
> extends EventEmitter<BlockchainEvents> {
// TODO: Lockscript might be better as the Subscribe Handler.
// From this, we can convert it to address.
// Fulcrum has Scripthash too - but I'm hesitant about this.
@@ -40,7 +42,6 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
* Initializes the blockchain connection and required resources.
* Should be called before performing any blockchain operations.
*
* @abstract
* @returns {Promise<void>} A promise that resolves when the blockchain connection is established
* @throws {Error} If the connection cannot be established
*/
@@ -50,35 +51,26 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
* Gracefully terminates the blockchain connection and cleans up resources.
* Should be called when blockchain operations are no longer needed.
*
* @abstract
* @returns {Promise<void>} A promise that resolves when the shutdown is complete
*/
abstract stop(): Promise<void>;
//-----------------------------------------------------------------------
// Traits (refer to traits.ts for docs)
//-----------------------------------------------------------------------
/**
* Retrieves all unspent transaction outputs (UTXOs) for a given address.
*
* @abstract
* @param {string} address - The blockchain address to query
* @returns {Promise<BlockchainUTXOs>} A promise that resolves with the unspent outputs
* @throws {Error} If the address is invalid or the query fails
*/
abstract fetchUnspents(address: string): Promise<BlockchainUTXOs>;
/**
* Retrieves detailed information about a specific transaction.
*
* @abstract
* @param {string} txHash - The transaction hash/ID to look up
* @returns {Promise<Transaction>} A promise that resolves with the transaction details
* @throws {Error} If the transaction cannot be found or the query fails
*/
abstract fetchTransaction(txHash: string): Promise<Transaction>;
/**
* Retrieves all transactions associated with a specific address.
*
* @abstract
* @param {string} address - The blockchain address to query
* @returns {Promise<BlockchainTransactions>} A promise that resolves with the list of transactions
* @throws {Error} If the address is invalid or the query fails
@@ -87,27 +79,55 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
address: string,
): Promise<BlockchainTransactions>;
// TODO: We may have a fetchTokenHistory in future, but Fulcrum does not currently support indexing tokens.
// There are actually a few functional discrepancies with the adapters: different adapters grant different capabilities.
// For example, Chaingraph can fetch token and address history. But BCHN P2P network cannot even fetch address history.
// We might want to handle this by having multiple BlockchainInterfaces (e.g. IBlockchainAddressSubscriptions) that describe capabilities.
// But we should return to that later.
/**
* Retrieves detailed information about a specific transaction.
*
* @param {string} txHash - The transaction hash/ID to look up
* @returns {Promise<Transaction>} A promise that resolves with the transaction details
* @throws {Error} If the transaction cannot be found or the query fails
*/
abstract fetchTransaction(txHash: string): Promise<Transaction>;
/**
* Broadcasts a raw transaction to the blockchain network.
*
* @abstract
* @param {Uint8Array} transaction - The serialized transaction data to broadcast
* @returns {Promise<void>} A promise that resolves when the transaction is successfully broadcast
* @throws {Error} If the transaction is invalid or broadcasting fails
*/
abstract broadcastTransaction(transaction: Uint8Array): Promise<void>;
/**
* Subscribes to updates for a specific lockscript.
* The provided callback will be invoked when relevant events occur for the address.
*
* @param lockscript - The blockchain lockscript to monitor
* @param callback - The callback function to handle address-related events
* @returns {Promise<void>} A promise that resolves when the subscription is established
* @throws {Error} If the subscription cannot be created
*/
abstract subscribeLockscript(
lockscript: string | Uint8Array,
callback: BlockchainCallback<AddressNotificationPayload>,
): Promise<void>;
/**
* Removes a subscription for a specific blockchain address.
*
* @param lockscript - The blockchain lockscript to unsubscribe from
* @param callback - The callback function to remove
* @returns {Promise<void>} A promise that resolves when the subscription is removed
* @throws {Error} If the subscription cannot be removed
*/
abstract unsubscribeLockscript(
lockscript: string | Uint8Array,
callback: BlockchainCallback<AddressNotificationPayload>,
): Promise<boolean>;
/**
* Subscribes to updates for a specific blockchain address.
* The provided callback will be invoked when relevant events occur for the address.
*
* @abstract
* @param {string} address - The blockchain address to monitor
* @param {AddressCallback} callback - The callback function to handle address-related events
* @returns {Promise<void>} A promise that resolves when the subscription is established
@@ -115,13 +135,12 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
*/
abstract subscribeAddress(
address: string,
callback: AddressCallback,
callback: BlockchainCallback<AddressNotificationPayload>,
): Promise<void>;
/**
* Removes a subscription for a specific blockchain address.
*
* @abstract
* @param {string} address - The blockchain address to unsubscribe from
* @param {AddressCallback} callback - The callback function to remove
* @returns {Promise<void>} A promise that resolves when the subscription is removed
@@ -129,14 +148,13 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
*/
abstract unsubscribeAddress(
address: string,
callback: AddressCallback,
): Promise<void>;
callback: BlockchainCallback<AddressNotificationPayload>,
): Promise<boolean>;
/**
* Subscribes to updates for a specific transaction.
* The provided callback will be invoked when relevant events occur for the transaction.
*
* @abstract
* @param {string} transactionHash - The transaction hash to monitor
* @param {TransactionCallback} callback - The callback function to handle transaction-related events
* @returns {Promise<void>} A promise that resolves when the subscription is established
@@ -144,13 +162,12 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
*/
abstract subscribeTransaction(
transactionHash: string,
callback: TransactionCallback,
callback: BlockchainCallback<TransactionNotificationPayload>,
): Promise<void>;
/**
* Removes a subscription for a specific transaction.
*
* @abstract
* @param {string} transactionHash - The transaction hash to unsubscribe from
* @param {TransactionCallback} callback - The callback function to remove
* @returns {Promise<void>} A promise that resolves when the subscription is removed
@@ -158,6 +175,6 @@ export abstract class BaseBlockchain extends EventEmitter<BlockchainEvents> {
*/
abstract unsubscribeTransaction(
transactionHash: string,
callback: TransactionCallback,
): Promise<void>;
callback: BlockchainCallback<TransactionNotificationPayload>,
): Promise<boolean>;
}