solana_kit_transaction_confirmation 0.2.1
solana_kit_transaction_confirmation: ^0.2.1 copied to clipboard
Confirmation tracking for the Solana Kit Dart SDK.
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 #
Add solana_kit_transaction_confirmation to your pubspec.yaml:
dependencies:
solana_kit_transaction_confirmation:
Or, if you are using the umbrella package:
dependencies:
solana_kit:
Documentation #
- Package page: https://pub.dev/packages/solana_kit_transaction_confirmation
- API reference: https://pub.dev/documentation/solana_kit_transaction_confirmation/latest/
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.
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 |
|---|---|
waitForRecentTransactionConfirmation({...}) |
Races signature confirmation against block height exceedence. |
waitForDurableNonceTransactionConfirmation({...}) |
Races signature confirmation against nonce invalidation. |
waitForRecentTransactionConfirmationUntilTimeout({...}) |
(Deprecated) Races signature confirmation against a timeout. |
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 |
|---|---|
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. |
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.