Skip to content

Instantly share code, notes, and snippets.

@crypt0miester
Last active November 11, 2024 08:13
Show Gist options
  • Save crypt0miester/5e452cd82f2fc819887fc83fb923400b to your computer and use it in GitHub Desktop.
Save crypt0miester/5e452cd82f2fc819887fc83fb923400b to your computer and use it in GitHub Desktop.
confirms the transaction via websocket race vs getBlockheight.
import {
Commitment,
Connection,
Context,
RpcResponseAndContext,
SignatureResult,
SignatureStatus,
TransactionSignature,
} from "@solana/web3.js";
import { sleep } from "./index";
export const enum TransactionStatus {
BLOCKHEIGHT_EXCEEDED = 0,
PROCESSED = 1,
TIMED_OUT = 2,
}
export async function awaitTransactionSignatureConfirmationBlockhash(
txid: TransactionSignature,
connection: Connection,
commitment: Commitment = "confirmed",
lastValidBlockHeight: number,
timeout = 60000, // 60 second timeout
): Promise<{
status: SignatureStatus | null;
transactionStatus: TransactionStatus;
}> {
let done = false;
let status: SignatureStatus | null = null;
const checkBlockHeight = async () => {
try {
return await connection.getBlockHeight(commitment);
} catch (_e) {
return -1;
}
};
let subId: number | undefined;
const confirmationPromise = new Promise<TransactionStatus>((resolve) => {
try {
subId = connection.onSignature(
txid,
(_result: SignatureResult, _context: Context) => {
done = true;
resolve(TransactionStatus.PROCESSED);
},
commitment,
);
} catch (err) {
console.error("Error setting up onSignature listener:", err);
}
});
const expiryPromise = (async () => {
const startTime = Date.now();
while (Date.now() - startTime < timeout && !done) {
const currentBlockHeight = await checkBlockHeight();
if (currentBlockHeight > lastValidBlockHeight) {
return TransactionStatus.BLOCKHEIGHT_EXCEEDED;
}
await sleep(1000); // Check every second
}
return TransactionStatus.TIMED_OUT;
})();
const transactionStatus = await Promise.race([
confirmationPromise,
expiryPromise,
]);
if (subId !== undefined) {
connection.removeSignatureListener(subId);
}
// Fetch the latest status regardless of the outcome
const signatureStatuses = await connection.getSignatureStatuses([txid]);
status = signatureStatuses && signatureStatuses.value[0];
return { status, transactionStatus };
}
@crypt0miester
Copy link
Author

how to sleep

export function sleep(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment