solana_kit_transaction_confirmation
Transaction confirmation tracking for the Solana Kit Dart SDK -- provides multiple strategies to confirm or detect expiry of Solana transactions.
This is the Dart port of @solana/transaction-confirmation from the Solana TypeScript SDK.
Installation
Install the package directly:
dart pub add solana_kit_transaction_confirmation
If your app uses several Solana Kit packages together, you can also depend on the umbrella package instead:
dart pub add solana_kit
Inside this monorepo, Dart workspace resolution uses the local package automatically.
Documentation
- Package page: https://pub.dev/packages/solana_kit_transaction_confirmation
- API reference: https://pub.dev/documentation/solana_kit_transaction_confirmation/latest/
- Workspace docs: https://openbudgetfun.github.io/solana_kit/
- Package catalog entry: https://openbudgetfun.github.io/solana_kit/reference/package-catalog#solana_kit_transaction_confirmation
- Source code: https://github.com/openbudgetfun/solana_kit/tree/main/packages/solana_kit_transaction_confirmation
For architecture notes, getting-started guides, and cross-package examples, start with the workspace docs site and then drill down into the package README and API reference.
Usage
Strategy overview
This package provides five confirmation strategies that can be composed together:
- Recent Signature Confirmation -- Watches for a signature to reach a target commitment level.
- Block Height Exceedence -- Detects when the network has progressed past the last valid block height for a transaction.
- Nonce Invalidation -- Detects when a durable nonce has been advanced, meaning the transaction has expired.
- Timeout -- A simple timeout-based fallback.
- Strategy Racing -- Races multiple strategies against each other, resolving with the first to complete.
In addition to the low-level strategy primitives, the package now includes additive polling helpers for the common app flow of sending a signed transaction and waiting for confirmation without manually wiring each strategy yourself.
Sending and confirming a signed transaction
import 'package:solana_kit_rpc/solana_kit_rpc.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
import 'package:solana_kit_transactions/solana_kit_transactions.dart';
Future<void> submitSignedTransaction(Transaction signedTransaction) async {
final rpc = createSolanaRpc(url: 'https://api.devnet.solana.com');
final signature = await sendAndConfirmTransaction(
rpc: rpc,
transaction: signedTransaction,
);
print('Confirmed signature: ${signature.value}');
}
Confirming an already-sent transaction
import 'package:solana_kit_keys/solana_kit_keys.dart';
import 'package:solana_kit_rpc/solana_kit_rpc.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
import 'package:solana_kit_transactions/solana_kit_transactions.dart';
Future<void> confirmExistingSubmission({
required Signature signature,
required Transaction transaction,
}) async {
final rpc = createSolanaRpc(url: 'https://api.devnet.solana.com');
await waitForTransactionConfirmation(
rpc: rpc,
signature: signature,
transaction: transaction,
);
}
Confirming a recent transaction (block height strategy)
The recommended approach for confirming blockhash-based transactions is to race the signature confirmation against block height exceedence.
import 'package:solana_kit_rpc_subscriptions_channel_websocket/solana_kit_rpc_subscriptions_channel_websocket.dart';
import 'package:solana_kit_rpc_types/solana_kit_rpc_types.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
Future<void> confirmTransaction(String signature) async {
final controller = AbortController();
// Create the signature confirmation factory.
// This watches the RPC for signature status updates.
final getRecentSignatureConfirmation =
createRecentSignatureConfirmationPromiseFactory(
RecentSignatureConfirmationConfig(
getSignatureStatuses: (sigs, {required abortSignal}) async {
// Call your RPC's getSignatureStatuses method.
// Return a list of SignatureStatus? (null if not found).
return [];
},
onSignatureNotification: (sig, {
required abortSignal,
required commitment,
required onNotification,
}) async {
// Subscribe to signatureNotifications via WebSocket.
// Call onNotification(err: null) when the signature is confirmed.
},
),
);
// Create the block height exceedence factory.
// This monitors the network's block height and rejects when it exceeds
// the transaction's lastValidBlockHeight.
final getBlockHeightExceedence =
createBlockHeightExceedencePromiseFactory(
BlockHeightExceedenceConfig(
getEpochInfo: ({required abortSignal, commitment}) async {
// Call your RPC's getEpochInfo method.
return EpochInfo(
absoluteSlot: BigInt.from(100),
blockHeight: BigInt.from(90),
);
},
onSlotNotification: ({
required abortSignal,
required onNotification,
}) async {
// Subscribe to slotNotifications via WebSocket.
},
),
);
// Wait for confirmation, racing against block height expiry.
await waitForRecentTransactionConfirmation(
abortSignal: controller.signal,
commitment: Commitment.confirmed,
getBlockHeightExceedencePromise: getBlockHeightExceedence,
getRecentSignatureConfirmationPromise: getRecentSignatureConfirmation,
lastValidBlockHeight: BigInt.from(200),
signature: signature,
);
print('Transaction confirmed!');
}
Confirming a durable nonce transaction
For transactions using durable nonces, race signature confirmation against nonce invalidation.
import 'package:solana_kit_rpc_subscriptions_channel_websocket/solana_kit_rpc_subscriptions_channel_websocket.dart';
import 'package:solana_kit_rpc_types/solana_kit_rpc_types.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
Future<void> confirmNonceTransaction({
required String signature,
required String nonceAccountAddress,
required String nonceValue,
required GetRecentSignatureConfirmationPromise getRecentSignatureConfirmation,
}) async {
final controller = AbortController();
// Create the nonce invalidation factory.
// This monitors a nonce account and rejects when its value changes,
// indicating the transaction has expired.
final getNonceInvalidation =
createNonceInvalidationPromiseFactory(
NonceInvalidationConfig(
getNonceAccount: (address, {
required abortSignal,
required commitment,
}) async {
// Fetch and parse the nonce account data.
return NonceAccountInfo(nonceValue: 'current-nonce-value');
},
onAccountNotification: (address, {
required abortSignal,
required commitment,
required onNotification,
}) async {
// Subscribe to accountNotifications for the nonce account.
},
),
);
// Wait for confirmation, racing against nonce invalidation.
await waitForDurableNonceTransactionConfirmation(
abortSignal: controller.signal,
commitment: Commitment.confirmed,
getNonceInvalidationPromise: getNonceInvalidation,
getRecentSignatureConfirmationPromise: getRecentSignatureConfirmation,
nonceAccountAddress: nonceAccountAddress,
nonceValue: nonceValue,
signature: signature,
);
print('Durable nonce transaction confirmed!');
}
Comparing commitment levels
The commitmentComparator function (re-exported from solana_kit_rpc_types) enables comparing commitment levels.
import 'package:solana_kit_rpc_types/solana_kit_rpc_types.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
void main() {
// commitmentComparator returns:
// < 0 if c1 is lower than c2
// 0 if c1 equals c2
// > 0 if c1 is higher than c2
print(commitmentComparator(Commitment.finalized, Commitment.confirmed) > 0);
// true -- finalized is higher than confirmed
print(commitmentComparator(Commitment.processed, Commitment.confirmed) < 0);
// true -- processed is lower than confirmed
print(commitmentComparator(Commitment.confirmed, Commitment.confirmed) == 0);
// true -- same level
}
Racing custom strategies
The raceStrategies function races a signature confirmation promise against a list of other strategy futures. The first to resolve or reject determines the outcome.
import 'package:solana_kit_rpc_subscriptions_channel_websocket/solana_kit_rpc_subscriptions_channel_websocket.dart';
import 'package:solana_kit_rpc_types/solana_kit_rpc_types.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
Future<void> confirmWithCustomStrategy({
required String signature,
required GetRecentSignatureConfirmationPromise confirmationFactory,
}) async {
final controller = AbortController();
// Race signature confirmation against both a timeout and a custom strategy.
await raceStrategies(
signature,
BaseTransactionConfirmationStrategyConfig(
abortSignal: controller.signal,
commitment: Commitment.confirmed,
getRecentSignatureConfirmationPromise: confirmationFactory,
),
({required AbortSignal abortSignal}) => [
getTimeoutPromise(
abortSignal: abortSignal,
commitment: Commitment.confirmed,
),
],
);
print('Transaction confirmed before timeout!');
}
Timeout strategy
The getTimeoutPromise function provides a simple timeout-based fallback. It uses 30 seconds for processed commitment and 60 seconds otherwise.
import 'package:solana_kit_rpc_subscriptions_channel_websocket/solana_kit_rpc_subscriptions_channel_websocket.dart';
import 'package:solana_kit_rpc_types/solana_kit_rpc_types.dart';
import 'package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart';
Future<void> main() async {
final controller = AbortController();
try {
await getTimeoutPromise(
abortSignal: controller.signal,
commitment: Commitment.confirmed,
);
} on TimeoutException {
print('Transaction timed out after 60 seconds');
}
}
API Reference
Waiter functions
| Function | Description |
|---|---|
waitForTransactionConfirmation({...}) |
Polling-based helper that confirms a transaction using its lifetime metadata. |
waitForRecentTransactionConfirmation({...}) |
Races signature confirmation against block height exceedence. |
waitForDurableNonceTransactionConfirmation({...}) |
Races signature confirmation against nonce invalidation. |
waitForRecentTransactionConfirmationUntilTimeout({...}) |
(Deprecated) Races signature confirmation against a timeout. |
sendAndConfirmTransaction({...}) |
Sends a fully signed transaction over RPC, then waits for confirmation. |
Factory functions
| Function | Description |
|---|---|
createRecentSignatureConfirmationPromiseFactory(config) |
Creates a function that resolves when a signature reaches a target commitment. |
createBlockHeightExceedencePromiseFactory(config) |
Creates a function that rejects when block height exceeds the last valid height. |
createNonceInvalidationPromiseFactory(config) |
Creates a function that rejects when a durable nonce has been advanced. |
Strategy functions
| Function | Description |
|---|---|
raceStrategies(signature, config, getStrategies) |
Races a signature confirmation against specific strategies. |
getTimeoutPromise({abortSignal, commitment}) |
Returns a future that rejects after 30s (processed) or 60s (other). |
Comparators
| Function | Description |
|---|---|
commitmentComparator(c1, c2) |
Compares two Commitment levels. Returns negative, zero, or positive. |
Configuration classes
| Class | Description |
|---|---|
RpcTransactionConfirmationConfig |
Config for polling-based confirmation helpers: abortSignal, commitment, pollInterval, searchTransactionHistory. |
SendAndConfirmTransactionConfig |
Extends polling config with send options such as maxRetries, minContextSlot, preflightCommitment, and skipPreflight. |
RecentSignatureConfirmationConfig |
Config: getSignatureStatuses, onSignatureNotification. |
BlockHeightExceedenceConfig |
Config: getEpochInfo, onSlotNotification. |
NonceInvalidationConfig |
Config: getNonceAccount, onAccountNotification. |
BaseTransactionConfirmationStrategyConfig |
Base config for raceStrategies: commitment, getRecentSignatureConfirmationPromise, abortSignal?. |
Type aliases
| Type | Description |
|---|---|
GetRecentSignatureConfirmationPromise |
Function type for signature confirmation: Future<void> Function({required AbortSignal abortSignal, required Commitment commitment, required String signature}). |
Data classes
| Class | Description |
|---|---|
SignatureStatus |
Status of a transaction signature: confirmationStatus, err. |
EpochInfo |
Epoch info: absoluteSlot, blockHeight. |
SlotNotification |
A slot notification: slot. |
NonceAccountInfo |
Nonce account info: nonceValue. |
Constants
| Constant | Description |
|---|---|
defaultTransactionConfirmationPollInterval |
Default interval for polling confirmation helpers. |
Example
Use example/main.dart as a runnable starting point for solana_kit_transaction_confirmation.
- Import path:
package:solana_kit_transaction_confirmation/solana_kit_transaction_confirmation.dart - This section is centrally maintained with
mdtto keep package guidance aligned. - After updating shared docs templates, run
docs:updatefrom the repo root.
Maintenance
- Validate docs in CI and locally with
docs:check. - Keep examples focused on one workflow and reference package README sections for deeper API details.
Libraries
- solana_kit_transaction_confirmation
- Confirmation tracking for the Solana Kit Dart SDK.