confirmTransaction method

Confirms a transaction by subscribing to receive a signature notification when the transaction has been confirmed.

Implementation

Future<SignatureNotification> confirmTransaction(
  final TransactionSignature signature, {
  final ConfirmTransactionConfig? config,
  final BlockhashWithExpiryBlockHeight? blockhash,
  final NonceWithMinContextSlot? nonce,
}) async {
  assert(
    blockhash == null || nonce == null,
    'Confirm transaction by [blockhash] or [nonce], but not both.',
  );

  try {
    final Uint8List decodedSignature = base58.decode(signature);
    check(decodedSignature.length == nacl.signatureLength,
        'Invalid signature length.');
  } catch (error) {
    throw TransactionException(
        'Failed to decode base58 signature $signature.');
  }

  final SafeCompleter<SignatureNotification> completer = SafeCompleter();
  await signatureSubscribe(
    signature,
    onData: completer.complete,
    onError: completer.completeError,
    onDone: () => completer.completeError('Subscription closed.'),
    cancelOnError: true,
    config: SignatureSubscribeConfig(
      commitment: config?.commitment,
    ),
  );

  // Wait for a signature notification or one of the timeout strategies to expire.
  final SignatureNotification notification = await Future.any([
    completer.future,
    if (nonce != null)
      _confirmTransactionNonceInvalid(nonce, commitment)
    else if (blockhash != null)
      _confirmTransactionBlockHeightExceeded(blockhash, commitment)
    else
      _confirmTransactionTimeout(commitment),
  ]);

  // Use the signature status for [TransactionNonceInvalidException]s.
  final notificationErr = notification.err;
  if (notificationErr is TransactionNonceInvalidException) {
    return confirmSignatureStatus(
      signature,
      commitment: commitment,
      minContext: notificationErr.slot,
    );
  }

  // Return the result.
  return notificationErr != null
      ? Future.error(notificationErr)
      : Future.value(notification);
}