@solana/transaction-confirmation 2.0.0-rc.1 → 2.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@ function createBlockHeightExceedencePromiseFactory({
16
16
  commitment,
17
17
  lastValidBlockHeight
18
18
  }) {
19
+ callerAbortSignal.throwIfAborted();
19
20
  const abortController = new AbortController();
20
21
  const handleAbort = () => {
21
22
  abortController.abort();
@@ -33,6 +34,7 @@ function createBlockHeightExceedencePromiseFactory({
33
34
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
34
35
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
35
36
  ]);
37
+ callerAbortSignal.throwIfAborted();
36
38
  let currentBlockHeight = initialBlockHeight;
37
39
  if (currentBlockHeight <= lastValidBlockHeight) {
38
40
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -52,6 +54,7 @@ function createBlockHeightExceedencePromiseFactory({
52
54
  }
53
55
  }
54
56
  }
57
+ callerAbortSignal.throwIfAborted();
55
58
  throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
56
59
  currentBlockHeight,
57
60
  lastValidBlockHeight
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED","getBase58Decoder","getBase64Encoder","SOLANA_ERROR__INVALID_NONCE","SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND","safeRace","getSolanaErrorFromTransactionError","commitmentComparator","getSignatureFromTransaction","getTimeoutPromise"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }) {\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED","getBase58Decoder","getBase64Encoder","SOLANA_ERROR__INVALID_NONCE","SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND","safeRace","getSolanaErrorFromTransactionError","commitmentComparator","getSignatureFromTransaction","getTimeoutPromise"],"mappings":"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","file":"index.browser.cjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }): Promise<never> {\n callerAbortSignal.throwIfAborted();\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n callerAbortSignal.throwIfAborted();\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n callerAbortSignal.throwIfAborted();\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
@@ -14,6 +14,7 @@ function createBlockHeightExceedencePromiseFactory({
14
14
  commitment,
15
15
  lastValidBlockHeight
16
16
  }) {
17
+ callerAbortSignal.throwIfAborted();
17
18
  const abortController = new AbortController();
18
19
  const handleAbort = () => {
19
20
  abortController.abort();
@@ -31,6 +32,7 @@ function createBlockHeightExceedencePromiseFactory({
31
32
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
32
33
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
33
34
  ]);
35
+ callerAbortSignal.throwIfAborted();
34
36
  let currentBlockHeight = initialBlockHeight;
35
37
  if (currentBlockHeight <= lastValidBlockHeight) {
36
38
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -50,6 +52,7 @@ function createBlockHeightExceedencePromiseFactory({
50
52
  }
51
53
  }
52
54
  }
55
+ callerAbortSignal.throwIfAborted();
53
56
  throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
54
57
  currentBlockHeight,
55
58
  lastValidBlockHeight
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","safeRace","getTimeoutPromise"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }) {\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","safeRace","getTimeoutPromise"],"mappings":"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","file":"index.browser.mjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }): Promise<never> {\n callerAbortSignal.throwIfAborted();\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n callerAbortSignal.throwIfAborted();\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n callerAbortSignal.throwIfAborted();\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
@@ -14,6 +14,7 @@ function createBlockHeightExceedencePromiseFactory({
14
14
  commitment,
15
15
  lastValidBlockHeight
16
16
  }) {
17
+ callerAbortSignal.throwIfAborted();
17
18
  const abortController = new AbortController();
18
19
  const handleAbort = () => {
19
20
  abortController.abort();
@@ -31,6 +32,7 @@ function createBlockHeightExceedencePromiseFactory({
31
32
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
32
33
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
33
34
  ]);
35
+ callerAbortSignal.throwIfAborted();
34
36
  let currentBlockHeight = initialBlockHeight;
35
37
  if (currentBlockHeight <= lastValidBlockHeight) {
36
38
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -50,6 +52,7 @@ function createBlockHeightExceedencePromiseFactory({
50
52
  }
51
53
  }
52
54
  }
55
+ callerAbortSignal.throwIfAborted();
53
56
  throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
54
57
  currentBlockHeight,
55
58
  lastValidBlockHeight
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","safeRace","getTimeoutPromise"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }) {\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","safeRace","getTimeoutPromise"],"mappings":"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","file":"index.native.mjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }): Promise<never> {\n callerAbortSignal.throwIfAborted();\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n callerAbortSignal.throwIfAborted();\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n callerAbortSignal.throwIfAborted();\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
@@ -16,6 +16,7 @@ function createBlockHeightExceedencePromiseFactory({
16
16
  commitment,
17
17
  lastValidBlockHeight
18
18
  }) {
19
+ callerAbortSignal.throwIfAborted();
19
20
  const abortController = new AbortController();
20
21
  const handleAbort = () => {
21
22
  abortController.abort();
@@ -33,6 +34,7 @@ function createBlockHeightExceedencePromiseFactory({
33
34
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
34
35
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
35
36
  ]);
37
+ callerAbortSignal.throwIfAborted();
36
38
  let currentBlockHeight = initialBlockHeight;
37
39
  if (currentBlockHeight <= lastValidBlockHeight) {
38
40
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -52,6 +54,7 @@ function createBlockHeightExceedencePromiseFactory({
52
54
  }
53
55
  }
54
56
  }
57
+ callerAbortSignal.throwIfAborted();
55
58
  throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
56
59
  currentBlockHeight,
57
60
  lastValidBlockHeight
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED","getBase58Decoder","getBase64Encoder","SOLANA_ERROR__INVALID_NONCE","SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND","safeRace","getSolanaErrorFromTransactionError","commitmentComparator","getSignatureFromTransaction","getTimeoutPromise"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }) {\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED","getBase58Decoder","getBase64Encoder","SOLANA_ERROR__INVALID_NONCE","SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND","safeRace","getSolanaErrorFromTransactionError","commitmentComparator","getSignatureFromTransaction","getTimeoutPromise"],"mappings":"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","file":"index.node.cjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }): Promise<never> {\n callerAbortSignal.throwIfAborted();\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n callerAbortSignal.throwIfAborted();\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n callerAbortSignal.throwIfAborted();\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
@@ -14,6 +14,7 @@ function createBlockHeightExceedencePromiseFactory({
14
14
  commitment,
15
15
  lastValidBlockHeight
16
16
  }) {
17
+ callerAbortSignal.throwIfAborted();
17
18
  const abortController = new AbortController();
18
19
  const handleAbort = () => {
19
20
  abortController.abort();
@@ -31,6 +32,7 @@ function createBlockHeightExceedencePromiseFactory({
31
32
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
32
33
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
33
34
  ]);
35
+ callerAbortSignal.throwIfAborted();
34
36
  let currentBlockHeight = initialBlockHeight;
35
37
  if (currentBlockHeight <= lastValidBlockHeight) {
36
38
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -50,6 +52,7 @@ function createBlockHeightExceedencePromiseFactory({
50
52
  }
51
53
  }
52
54
  }
55
+ callerAbortSignal.throwIfAborted();
53
56
  throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
54
57
  currentBlockHeight,
55
58
  lastValidBlockHeight
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","safeRace","getTimeoutPromise"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }) {\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/confirmation-strategy-blockheight.ts","../src/confirmation-strategy-nonce.ts","../src/confirmation-strategy-recent-signature.ts","../src/confirmation-strategy-timeout.ts","../src/confirmation-strategy-racer.ts","../src/waiters.ts"],"names":["SolanaError","safeRace","getTimeoutPromise"],"mappings":"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","file":"index.node.mjs","sourcesContent":["import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment?: Commitment;\n lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster> = {\n rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryyConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n return async function getBlockHeightExceedencePromise({\n abortSignal: callerAbortSignal,\n commitment,\n lastValidBlockHeight,\n }): Promise<never> {\n callerAbortSignal.throwIfAborted();\n const abortController = new AbortController();\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n const { absoluteSlot, blockHeight } = await rpc\n .getEpochInfo({ commitment })\n .send({ abortSignal: abortController.signal });\n return {\n blockHeight,\n differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n };\n }\n try {\n const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n await Promise.all([\n rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n ]);\n callerAbortSignal.throwIfAborted();\n let currentBlockHeight = initialBlockHeight;\n if (currentBlockHeight <= lastValidBlockHeight) {\n let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n for await (const slotNotification of slotNotifications) {\n const { slot } = slotNotification;\n if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n // Before making a final decision, recheck the actual block height.\n const {\n blockHeight: recheckedBlockHeight,\n differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n currentBlockHeight = recheckedBlockHeight;\n if (currentBlockHeight > lastValidBlockHeight) {\n // Verified; the block height has been exceeded.\n break;\n } else {\n // The block height has not been exceeded, which implies that the\n // difference between the slot height and the block height has grown\n // (ie. some blocks have been skipped since we started). Recalibrate the\n // difference and keep waiting.\n lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n currentDifferenceBetweenSlotHeightAndBlockHeight;\n }\n }\n }\n }\n callerAbortSignal.throwIfAborted();\n throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n currentBlockHeight,\n lastValidBlockHeight,\n });\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n currentNonceValue: Nonce;\n nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n 4 + // version(u32)\n 4 + // state(u32)\n 32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n rpc,\n rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n return async function getNonceInvalidationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n currentNonceValue: expectedNonceValue,\n nonceAccountAddress,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for nonce account changes.\n */\n const accountNotifications = await rpcSubscriptions\n .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n .subscribe({ abortSignal: abortController.signal });\n const base58Decoder = getBase58Decoder();\n const base64Encoder = getBase64Encoder();\n function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n const data = base64Encoder.encode(base64EncodedBytes);\n const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n return base58Decoder.decode(nonceValueBytes) as Nonce;\n }\n const nonceAccountDidAdvancePromise = (async () => {\n for await (const accountNotification of accountNotifications) {\n const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n * value to check if it has already been advanced.\n */\n const nonceIsAlreadyInvalidPromise = (async () => {\n const { value: nonceAccount } = await rpc\n .getAccountInfo(nonceAccountAddress, {\n commitment,\n dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n encoding: 'base58',\n })\n .send({ abortSignal: abortController.signal });\n if (!nonceAccount) {\n throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n nonceAccountAddress,\n });\n }\n const nonceValue =\n // This works because we asked for the exact slice of data representing the nonce\n // value, and furthermore asked for it in `base58` encoding.\n nonceAccount.data[0] as unknown as Nonce;\n if (nonceValue !== expectedNonceValue) {\n throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n actualNonceValue: nonceValue,\n expectedNonceValue,\n });\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n abortSignal: AbortSignal;\n commitment: Commitment;\n signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n rpc,\n rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n return async function getRecentSignatureConfirmationPromise({\n abortSignal: callerAbortSignal,\n commitment,\n signature,\n }) {\n const abortController = new AbortController();\n function handleAbort() {\n abortController.abort();\n }\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n /**\n * STEP 1: Set up a subscription for status changes to a signature.\n */\n const signatureStatusNotifications = await rpcSubscriptions\n .signatureNotifications(signature, { commitment })\n .subscribe({ abortSignal: abortController.signal });\n const signatureDidCommitPromise = (async () => {\n for await (const signatureStatusNotification of signatureStatusNotifications) {\n if (signatureStatusNotification.value.err) {\n throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n } else {\n return;\n }\n }\n })();\n /**\n * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n * This will only yield a result if the signature is still in the status cache.\n */\n const signatureStatusLookupPromise = (async () => {\n const { value: signatureStatusResults } = await rpc\n .getSignatureStatuses([signature])\n .send({ abortSignal: abortController.signal });\n const signatureStatus = signatureStatusResults[0];\n if (\n signatureStatus &&\n signatureStatus.confirmationStatus &&\n commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n ) {\n return;\n } else {\n await new Promise(() => {\n /* never resolve */\n });\n }\n })();\n try {\n return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n abortSignal: AbortSignal;\n commitment: Commitment;\n}>;\n\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n return await new Promise((_, reject) => {\n const handleAbort = (e: AbortSignalEventMap['abort']) => {\n clearTimeout(timeoutId);\n const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n reject(abortError);\n };\n callerAbortSignal.addEventListener('abort', handleAbort);\n const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n const startMs = performance.now();\n const timeoutId =\n // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n // elapsed time instead of active time.\n // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n setTimeout(() => {\n const elapsedMs = performance.now() - startMs;\n reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n }, timeoutMs);\n });\n}\n","import type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n abortSignal?: AbortSignal;\n commitment: Commitment;\n getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n signature: Signature,\n config: TConfig,\n getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n callerAbortSignal?.throwIfAborted();\n const abortController = new AbortController();\n if (callerAbortSignal) {\n const handleAbort = () => {\n abortController.abort();\n };\n callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n }\n try {\n const specificStrategies = getSpecificStrategiesForRace({\n ...config,\n abortSignal: abortController.signal,\n });\n return await safeRace([\n getRecentSignatureConfirmationPromise({\n abortSignal: abortController.signal,\n commitment,\n signature,\n }),\n ...specificStrategies,\n ]);\n } finally {\n abortController.abort();\n }\n}\n","import { Signature } from '@solana/keys';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\nimport {\n TransactionWithBlockhashLifetime,\n TransactionWithDurableNonceLifetime,\n} from '@solana/transactions/dist/types/lifetime';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n transaction: Readonly<Transaction & TransactionWithBlockhashLifetime>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig\n extends BaseTransactionConfirmationStrategyConfig {\n getTimeoutPromise: typeof getTimeoutPromise;\n signature: Signature;\n}\n\nexport async function waitForDurableNonceTransactionConfirmation(\n config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n return [\n getNonceInvalidationPromise({\n abortSignal,\n commitment,\n currentNonceValue: transaction.lifetimeConstraint.nonce,\n nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n }),\n ];\n },\n );\n}\n\nexport async function waitForRecentTransactionConfirmation(\n config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n getSignatureFromTransaction(config.transaction),\n config,\n function getSpecificStrategiesForRace({\n abortSignal,\n commitment,\n getBlockHeightExceedencePromise,\n transaction,\n }) {\n return [\n getBlockHeightExceedencePromise({\n abortSignal,\n commitment,\n lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n }),\n ];\n },\n );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n await raceStrategies(\n config.signature,\n config,\n function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n return [\n getTimeoutPromise({\n abortSignal,\n commitment,\n }),\n ];\n },\n );\n}\n"]}
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "@solana/transaction-confirmation",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.2",
4
4
  "description": "Helpers for confirming Solana transactions",
5
5
  "exports": {
6
+ "edge-light": {
7
+ "import": "./dist/index.node.mjs",
8
+ "require": "./dist/index.node.cjs"
9
+ },
10
+ "workerd": {
11
+ "import": "./dist/index.node.mjs",
12
+ "require": "./dist/index.node.cjs"
13
+ },
6
14
  "browser": {
7
15
  "import": "./dist/index.browser.mjs",
8
16
  "require": "./dist/index.browser.cjs"
@@ -49,16 +57,16 @@
49
57
  "node": ">=17.4"
50
58
  },
51
59
  "dependencies": {
52
- "@solana/codecs-strings": "2.0.0-rc.1",
53
- "@solana/addresses": "2.0.0-rc.1",
54
- "@solana/keys": "2.0.0-rc.1",
55
- "@solana/errors": "2.0.0-rc.1",
56
- "@solana/promises": "2.0.0-rc.1",
57
- "@solana/rpc": "2.0.0-rc.1",
58
- "@solana/rpc-subscriptions": "2.0.0-rc.1",
59
- "@solana/rpc-types": "2.0.0-rc.1",
60
- "@solana/transaction-messages": "2.0.0-rc.1",
61
- "@solana/transactions": "2.0.0-rc.1"
60
+ "@solana/addresses": "2.0.0-rc.2",
61
+ "@solana/keys": "2.0.0-rc.2",
62
+ "@solana/errors": "2.0.0-rc.2",
63
+ "@solana/codecs-strings": "2.0.0-rc.2",
64
+ "@solana/promises": "2.0.0-rc.2",
65
+ "@solana/rpc": "2.0.0-rc.2",
66
+ "@solana/rpc-subscriptions": "2.0.0-rc.2",
67
+ "@solana/rpc-types": "2.0.0-rc.2",
68
+ "@solana/transactions": "2.0.0-rc.2",
69
+ "@solana/transaction-messages": "2.0.0-rc.2"
62
70
  },
63
71
  "peerDependencies": {
64
72
  "typescript": ">=5"
@@ -71,12 +79,15 @@
71
79
  }
72
80
  ]
73
81
  },
82
+ "engines": {
83
+ "node": ">=20.18.0"
84
+ },
74
85
  "scripts": {
75
86
  "compile:js": "tsup --config build-scripts/tsup.config.package.ts",
76
87
  "compile:typedefs": "tsc -p ./tsconfig.declarations.json",
77
88
  "dev": "jest -c ../../node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
78
89
  "publish-packages": "npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks",
79
- "style:fix": "pnpm eslint --fix src/* && pnpm prettier --log-level warn --ignore-unknown --write ./*",
90
+ "style:fix": "pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*",
80
91
  "test:lint": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.ts --rootDir . --silent",
81
92
  "test:prettier": "TERM_OVERRIDE=\"${TURBO_HASH:+dumb}\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.ts --rootDir . --silent",
82
93
  "test:treeshakability:browser": "agadoo dist/index.browser.mjs",