Make waitForTransaction part of BaseBlockchain

This commit is contained in:
Jim Hamill
2025-04-22 00:12:00 +00:00
parent 87b57bd535
commit e7ac86c0a4
5 changed files with 73 additions and 56 deletions
@@ -6,7 +6,7 @@ import {
type BlockchainTransactions,
} from './types.js';
import { type Transaction } from '@xocash/primitives';
import { Transaction } from '@xocash/primitives';
export type BlockchainEvents = {
isConnectedUpdated: boolean;
@@ -177,4 +177,55 @@ export abstract class BaseBlockchain<
transactionHash: string,
callback: BlockchainCallback<TransactionNotificationPayload>,
): Promise<boolean>;
/**
* Waits for a transaction to be seen by the node.
*
* @param tx - The transaction to wait for. Can be a Uint8Array, Transaction instance, or a string.
* @param timeoutMs - The maximum time to wait in milliseconds before timing out. Defaults to 10,000ms (10 seconds).
* @returns A Promise that resolves when the transaction is seen by the node or rejects if the timeout is reached.
* @throws Error if the transaction is not seen by the node within the specified timeout.
*/
async waitForTransaction(
tx: Uint8Array | Transaction | string,
timeoutMs = 10_000,
) {
// Cast the transaction.
if (!(tx instanceof Transaction)) {
tx = Transaction.from(tx);
}
const txHash = tx.toHashHex();
// First, subscribe to the transaction
let unsubscribeCallback: () => void;
const subscriptionPromise = this.subscribeTransaction(txHash, () => {
if (unsubscribeCallback) {
unsubscribeCallback();
}
});
// Then create the wait promise without an async executor
const waitForTxPromise = new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => {
if (unsubscribeCallback) {
unsubscribeCallback();
}
reject(new Error(`Failed to broadcast ${txHash}`));
}, timeoutMs);
// Create a subscribe function so that we get notified when transaction is seen by network
unsubscribeCallback = () => {
clearTimeout(timeout);
this.unsubscribeTransaction(txHash, unsubscribeCallback);
resolve();
};
});
// Wait for subscription to be set up first
await subscriptionPromise;
// Then wait for either resolution or timeout
return waitForTxPromise;
}
}