Blockchain Traits
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { BaseBlockchain } from './base-blockchain.js';
|
||||
import {
|
||||
type AddressCallback,
|
||||
type TransactionCallback,
|
||||
type BlockchainCallback,
|
||||
type BlockchainTransaction,
|
||||
type BlockchainUTXO,
|
||||
} from './types.js';
|
||||
@@ -53,7 +52,20 @@ export type BlockchainElectrumParams = {
|
||||
opts?: Partial<BlockchainElectrumOpts>;
|
||||
};
|
||||
|
||||
export class BlockchainElectrum extends BaseBlockchain {
|
||||
export type AddressStatusPayload = {
|
||||
type: 'address-status';
|
||||
status: string | null;
|
||||
};
|
||||
|
||||
export type BlockHeightPayload = {
|
||||
type: 'block-height';
|
||||
height: number | null;
|
||||
};
|
||||
|
||||
export class BlockchainElectrum extends BaseBlockchain<
|
||||
AddressStatusPayload,
|
||||
BlockHeightPayload
|
||||
> {
|
||||
// Composables.
|
||||
electrumClient!: ElectrumClient<ElectrumProtocolEvents>;
|
||||
|
||||
@@ -61,9 +73,17 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
isConnected = false;
|
||||
blockHeight: number | undefined = undefined;
|
||||
|
||||
// Subscriptions State.
|
||||
addressSubscriptions: Map<string, Set<AddressCallback>> = new Map();
|
||||
transactionSubscriptions: Map<string, Set<TransactionCallback>> = new Map();
|
||||
// Address Subscriptions State.
|
||||
addressSubscriptions: Map<
|
||||
string,
|
||||
Set<BlockchainCallback<AddressStatusPayload>>
|
||||
> = new Map();
|
||||
|
||||
// Transaction Subscription State.
|
||||
transactionSubscriptions: Map<
|
||||
string,
|
||||
Set<BlockchainCallback<BlockHeightPayload>>
|
||||
> = new Map();
|
||||
|
||||
// Options
|
||||
store: BaseStore;
|
||||
@@ -314,7 +334,7 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
}, timeoutMs);
|
||||
|
||||
// Create a subscribe function so that we get notified when transaction is seen by network
|
||||
const subscribeCallback = (_height: number | null) => {
|
||||
const subscribeCallback = () => {
|
||||
clearTimeout(timeout);
|
||||
this.unsubscribeTransaction(tx.toHashHex(), subscribeCallback);
|
||||
resolve();
|
||||
@@ -356,13 +376,47 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
await waitForTxPromise;
|
||||
}
|
||||
|
||||
async subscribeAddress(address: string, callback: AddressCallback) {
|
||||
async subscribeLockscript(
|
||||
lockscript: string | Uint8Array,
|
||||
callback: BlockchainCallback<AddressStatusPayload>,
|
||||
) {
|
||||
// Fulcrum does not support subscribing to lockscripts, so we cast it to an address.
|
||||
const address = Address.fromLockscript(lockscript);
|
||||
|
||||
// TODO: Refactor to work around ScriptHash for Fulcrum.
|
||||
// Otherwise, we may get issues with CashAddr/Legacy Addresses.
|
||||
|
||||
// Use our subscribeAddress function.
|
||||
return await this.subscribeAddress(address.toCashAddr(), callback);
|
||||
}
|
||||
|
||||
async unsubscribeLockscript(
|
||||
lockscript: string | Uint8Array,
|
||||
callback: BlockchainCallback<AddressStatusPayload>,
|
||||
): Promise<boolean> {
|
||||
// Fulcrum does not support subscribing to lockscripts, so we cast it to an address.
|
||||
const address = Address.fromLockscript(lockscript);
|
||||
|
||||
// TODO: Refactor to work around ScriptHash for Fulcrum.
|
||||
// Otherwise, we may get issues with CashAddr/Legacy Addresses.
|
||||
|
||||
// Use our unsubscribeAddress function.
|
||||
return await this.unsubscribeAddress(address.toCashAddr(), callback);
|
||||
}
|
||||
|
||||
async subscribeAddress(
|
||||
address: string,
|
||||
callback: BlockchainCallback<AddressStatusPayload>,
|
||||
) {
|
||||
// Wait for connection to be established before attempting to subscribe.
|
||||
// TODO: Consider doing this at a higher level.
|
||||
if (!this.isConnected) {
|
||||
await this.waitFor('isConnectedUpdated', (isConnected) => isConnected);
|
||||
}
|
||||
|
||||
// TODO: Refactor to work around ScriptHash for Fulcrum.
|
||||
// Otherwise, we may get issues with CashAddr/Legacy Addresses.
|
||||
|
||||
// Get or create the set of callbacks for this transaction
|
||||
let callbacks = this.addressSubscriptions.get(address);
|
||||
if (!callbacks) {
|
||||
@@ -379,17 +433,28 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
callbacks.add(callback);
|
||||
}
|
||||
|
||||
async unsubscribeAddress(address: string, callback: AddressCallback) {
|
||||
async unsubscribeAddress(
|
||||
address: string,
|
||||
callback: BlockchainCallback<AddressStatusPayload>,
|
||||
) {
|
||||
// Wait for connection to be established before attempting to subscribe.
|
||||
// TODO: Consider doing this at a higher level.
|
||||
if (!this.isConnected) {
|
||||
await this.waitFor('isConnectedUpdated', (isConnected) => isConnected);
|
||||
}
|
||||
|
||||
// TODO: Refactor to work around ScriptHash for Fulcrum.
|
||||
// Otherwise, we may get issues with CashAddr/Legacy Addresses.
|
||||
|
||||
// Get the callbacks set for this address
|
||||
const callbacks = this.addressSubscriptions.get(address);
|
||||
if (!callbacks) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the index of the callback in the handlers array
|
||||
if (!callbacks.has(callback)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the specific callback
|
||||
@@ -405,11 +470,13 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
address,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async subscribeTransaction(
|
||||
transactionHash: string,
|
||||
callback: TransactionCallback,
|
||||
callback: BlockchainCallback<BlockHeightPayload>,
|
||||
) {
|
||||
// Wait for connection to be established before attempting to subscribe.
|
||||
// TODO: Consider doing this at a higher level.
|
||||
@@ -435,7 +502,7 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
|
||||
async unsubscribeTransaction(
|
||||
transactionHash: string,
|
||||
callback: TransactionCallback,
|
||||
callback: BlockchainCallback<BlockHeightPayload>,
|
||||
) {
|
||||
// Wait for connection to be established before attempting to subscribe.
|
||||
// TODO: Consider doing this at a higher level.
|
||||
@@ -446,7 +513,11 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
// Get the callbacks set for this transaction
|
||||
const callbacks = this.transactionSubscriptions.get(transactionHash);
|
||||
if (!callbacks) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!callbacks.has(callback)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the specific callback
|
||||
@@ -462,6 +533,8 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
transactionHash,
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async request(method: string, ...parameters: Array<RPCParameter>) {
|
||||
@@ -523,7 +596,7 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
// Execute all callbacks for this transaction.
|
||||
for (const callback of callbacks) {
|
||||
try {
|
||||
callback(status);
|
||||
callback(address, { type: 'address-status', status });
|
||||
} catch (error) {
|
||||
// Handle or log any callback execution errors
|
||||
console.error(
|
||||
@@ -549,7 +622,7 @@ export class BlockchainElectrum extends BaseBlockchain {
|
||||
// Execute all callbacks for this transaction.
|
||||
for (const callback of callbacks) {
|
||||
try {
|
||||
callback(height);
|
||||
callback(txHash, { type: 'block-height', height });
|
||||
} catch (error) {
|
||||
// Handle or log any callback execution errors
|
||||
console.error(
|
||||
|
||||
Reference in New Issue
Block a user