Skip to content

Instantly share code, notes, and snippets.

@tlrjs
Created February 7, 2022 20:54
Show Gist options
  • Select an option

  • Save tlrjs/91d7d0861c97bfda901b8cdc1e81e277 to your computer and use it in GitHub Desktop.

Select an option

Save tlrjs/91d7d0861c97bfda901b8cdc1e81e277 to your computer and use it in GitHub Desktop.

Revisions

  1. tlrjs created this gist Feb 7, 2022.
    101 changes: 101 additions & 0 deletions awaitTransactionSignatureConfirmation.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,101 @@
    async awaitTransactionSignatureConfirmation(
    txid: TransactionSignature,
    timeout: number,
    confirmLevel: TransactionConfirmationStatus,
    ) {
    let done = false;

    const confirmLevels: (TransactionConfirmationStatus | null | undefined)[] =
    ['finalized'];

    if (confirmLevel === 'confirmed') {
    confirmLevels.push('confirmed');
    } else if (confirmLevel === 'processed') {
    confirmLevels.push('confirmed');
    confirmLevels.push('processed');
    }
    let subscriptionId;

    const result = await new Promise((resolve, reject) => {
    (async () => {
    setTimeout(() => {
    if (done) {
    return;
    }
    done = true;
    console.log('Timed out for txid: ', txid);
    reject({ timeout: true });
    }, timeout);
    try {
    subscriptionId = this.connection.onSignature(
    txid,
    (result, context) => {
    subscriptionId = undefined;
    done = true;
    if (result.err) {
    reject(result.err);
    } else {
    this.lastSlot = context?.slot;
    resolve(result);
    }
    },
    'processed',
    );
    } catch (e) {
    done = true;
    console.log('WS error in setup', txid, e);
    }
    let retrySleep = 200;
    while (!done) {
    // eslint-disable-next-line no-loop-func
    await sleep(retrySleep);
    (async () => {
    try {
    const response = await this.connection.getSignatureStatuses([
    txid,
    ]);

    const result = response && response.value[0];
    if (!done) {
    if (!result) {
    // console.log('REST null result for', txid, result);
    } else if (result.err) {
    console.log('REST error for', txid, result);
    done = true;
    reject(result.err);
    } else if (
    !(
    result.confirmations ||
    confirmLevels.includes(result.confirmationStatus)
    )
    ) {
    console.log('REST not confirmed', txid, result);
    } else {
    this.lastSlot = response?.context?.slot;
    console.log('REST confirmed', txid, result);
    done = true;
    resolve(result);
    }
    }
    } catch (e) {
    if (!done) {
    console.log('REST connection error: txid', txid, e);
    }
    }
    })();
    if (retrySleep <= 1600) {
    retrySleep = retrySleep * 2;
    }
    }
    })();
    });

    if (subscriptionId) {
    this.connection.removeSignatureListener(subscriptionId).catch((e) => {
    console.log('WS error in cleanup', e);
    });
    }

    done = true;
    return result;
    }