@solana/transaction-confirmation
Version:
Helpers for confirming Solana transactions
140 lines (131 loc) • 5.35 kB
text/typescript
import { Signature } from '@solana/keys';
import {
getSignatureFromTransaction,
Transaction,
TransactionWithBlockhashLifetime,
TransactionWithDurableNonceLifetime,
} from '@solana/transactions';
import { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';
import { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';
import { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';
import { getTimeoutPromise } from './confirmation-strategy-timeout';
export type TransactionWithLastValidBlockHeight = Omit<TransactionWithBlockhashLifetime, 'lifetimeConstraint'> & {
lifetimeConstraint: Omit<TransactionWithBlockhashLifetime['lifetimeConstraint'], 'blockhash'>;
};
interface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {
getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;
transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;
}
interface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {
getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;
transaction: Readonly<Transaction & TransactionWithLastValidBlockHeight>;
}
interface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {
getTimeoutPromise: typeof getTimeoutPromise;
/**
* A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely identifies a
* transaction by virtue of being the first or only signature in its list of signatures.
*/
signature: Signature;
}
/**
* Supply your own confirmation implementations to this function to create a custom nonce
* transaction confirmation strategy.
*
* @example
* ```ts
* import { waitForDurableNonceTransactionConfirmation } from '@solana/transaction-confirmation';
*
* try {
* await waitForDurableNonceTransactionConfirmation({
* getNonceInvalidationPromise({ abortSignal, commitment, currentNonceValue, nonceAccountAddress }) {
* // Return a promise that rejects when a nonce becomes invalid.
* },
* getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {
* // Return a promise that resolves when a transaction achieves confirmation
* },
* });
* } catch (e) {
* // Handle errors.
* }
* ```
*/
export async function waitForDurableNonceTransactionConfirmation(
config: WaitForDurableNonceTransactionConfirmationConfig,
): Promise<void> {
await raceStrategies(
getSignatureFromTransaction(config.transaction),
config,
function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {
return [
getNonceInvalidationPromise({
abortSignal,
commitment,
currentNonceValue: transaction.lifetimeConstraint.nonce,
nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,
}),
];
},
);
}
/**
* Supply your own confirmation implementations to this function to create a custom confirmation
* strategy for recently-landed transactions.
*
* @example
* ```ts
* import { waitForRecentTransactionConfirmation } from '@solana/transaction-confirmation';
*
* try {
* await waitForRecentTransactionConfirmation({
* getBlockHeightExceedencePromise({ abortSignal, commitment, lastValidBlockHeight }) {
* // Return a promise that rejects when the blockhash's block height has been exceeded
* },
* getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {
* // Return a promise that resolves when a transaction achieves confirmation
* },
* });
* } catch (e) {
* // Handle errors.
* }
* ```
*/
export async function waitForRecentTransactionConfirmation(
config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,
): Promise<void> {
await raceStrategies(
getSignatureFromTransaction(config.transaction),
config,
function getSpecificStrategiesForRace({
abortSignal,
commitment,
getBlockHeightExceedencePromise,
transaction,
}) {
return [
getBlockHeightExceedencePromise({
abortSignal,
commitment,
lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,
}),
];
},
);
}
/** @deprecated */
export async function waitForRecentTransactionConfirmationUntilTimeout(
config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,
): Promise<void> {
await raceStrategies(
config.signature,
config,
function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {
return [
getTimeoutPromise({
abortSignal,
commitment,
}),
];
},
);
}