@solana/transaction-confirmation 2.0.0-rc.0 → 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.
package/README.md CHANGED
@@ -6,9 +6,9 @@
6
6
 
7
7
  [code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square
8
8
  [code-style-prettier-url]: https://github.com/prettier/prettier
9
- [npm-downloads-image]: https://img.shields.io/npm/dm/@solana/transaction-confirmation/experimental.svg?style=flat
10
- [npm-image]: https://img.shields.io/npm/v/@solana/transaction-confirmation/experimental.svg?style=flat
11
- [npm-url]: https://www.npmjs.com/package/@solana/transaction-confirmation/v/experimental
9
+ [npm-downloads-image]: https://img.shields.io/npm/dm/@solana/transaction-confirmation/rc.svg?style=flat
10
+ [npm-image]: https://img.shields.io/npm/v/@solana/transaction-confirmation/rc.svg?style=flat
11
+ [npm-url]: https://www.npmjs.com/package/@solana/transaction-confirmation/v/rc
12
12
  [semantic-release-image]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg
13
13
  [semantic-release-url]: https://github.com/semantic-release/semantic-release
14
14
 
@@ -102,10 +102,11 @@ try {
102
102
  When no other heuristic exists to infer that a transaction has expired, you can use this promise factory with a commitment level. It throws after 30 seconds when the commitment is `processed`, and 60 seconds otherwise. You would typically race this with another confirmation strategy.
103
103
 
104
104
  ```ts
105
+ import { safeRace } from '@solana/promises';
105
106
  import { getTimeoutPromise } from '@solana/transaction-confirmation';
106
107
 
107
108
  try {
108
- await Promise.race([getCustomTransactionConfirmationPromise(/* ... */), getTimeoutPromise({ commitment })]);
109
+ await safeRace([getCustomTransactionConfirmationPromise(/* ... */), getTimeoutPromise({ commitment })]);
109
110
  } catch (e) {
110
111
  if (e instanceof DOMException && e.name === 'TimeoutError') {
111
112
  console.log('Could not confirm transaction after a timeout');
@@ -2,6 +2,7 @@
2
2
 
3
3
  var errors = require('@solana/errors');
4
4
  var codecsStrings = require('@solana/codecs-strings');
5
+ var promises = require('@solana/promises');
5
6
  var rpcTypes = require('@solana/rpc-types');
6
7
  var transactions = require('@solana/transactions');
7
8
 
@@ -15,6 +16,7 @@ function createBlockHeightExceedencePromiseFactory({
15
16
  commitment,
16
17
  lastValidBlockHeight
17
18
  }) {
19
+ callerAbortSignal.throwIfAborted();
18
20
  const abortController = new AbortController();
19
21
  const handleAbort = () => {
20
22
  abortController.abort();
@@ -32,6 +34,7 @@ function createBlockHeightExceedencePromiseFactory({
32
34
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
33
35
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
34
36
  ]);
37
+ callerAbortSignal.throwIfAborted();
35
38
  let currentBlockHeight = initialBlockHeight;
36
39
  if (currentBlockHeight <= lastValidBlockHeight) {
37
40
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -51,6 +54,7 @@ function createBlockHeightExceedencePromiseFactory({
51
54
  }
52
55
  }
53
56
  }
57
+ callerAbortSignal.throwIfAborted();
54
58
  throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
55
59
  currentBlockHeight,
56
60
  lastValidBlockHeight
@@ -124,7 +128,7 @@ function createNonceInvalidationPromiseFactory({
124
128
  }
125
129
  })();
126
130
  try {
127
- return await Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
131
+ return await promises.safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
128
132
  } finally {
129
133
  abortController.abort();
130
134
  }
@@ -165,7 +169,7 @@ function createRecentSignatureConfirmationPromiseFactory({
165
169
  }
166
170
  })();
167
171
  try {
168
- return await Promise.race([signatureDidCommitPromise, signatureStatusLookupPromise]);
172
+ return await promises.safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);
169
173
  } finally {
170
174
  abortController.abort();
171
175
  }
@@ -194,8 +198,6 @@ async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment })
194
198
  );
195
199
  });
196
200
  }
197
-
198
- // src/confirmation-strategy-racer.ts
199
201
  async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
200
202
  const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;
201
203
  callerAbortSignal?.throwIfAborted();
@@ -211,7 +213,7 @@ async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
211
213
  ...config,
212
214
  abortSignal: abortController.signal
213
215
  });
214
- return await Promise.race([
216
+ return await promises.safeRace([
215
217
  getRecentSignatureConfirmationPromise({
216
218
  abortSignal: abortController.signal,
217
219
  commitment,
@@ -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","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 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 Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\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 Promise.race([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 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 Promise.race([\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"]}
@@ -1,5 +1,6 @@
1
1
  import { SolanaError, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, getSolanaErrorFromTransactionError } from '@solana/errors';
2
2
  import { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';
3
+ import { safeRace } from '@solana/promises';
3
4
  import { commitmentComparator } from '@solana/rpc-types';
4
5
  import { getSignatureFromTransaction } from '@solana/transactions';
5
6
 
@@ -13,6 +14,7 @@ function createBlockHeightExceedencePromiseFactory({
13
14
  commitment,
14
15
  lastValidBlockHeight
15
16
  }) {
17
+ callerAbortSignal.throwIfAborted();
16
18
  const abortController = new AbortController();
17
19
  const handleAbort = () => {
18
20
  abortController.abort();
@@ -30,6 +32,7 @@ function createBlockHeightExceedencePromiseFactory({
30
32
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
31
33
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
32
34
  ]);
35
+ callerAbortSignal.throwIfAborted();
33
36
  let currentBlockHeight = initialBlockHeight;
34
37
  if (currentBlockHeight <= lastValidBlockHeight) {
35
38
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -49,6 +52,7 @@ function createBlockHeightExceedencePromiseFactory({
49
52
  }
50
53
  }
51
54
  }
55
+ callerAbortSignal.throwIfAborted();
52
56
  throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
53
57
  currentBlockHeight,
54
58
  lastValidBlockHeight
@@ -122,7 +126,7 @@ function createNonceInvalidationPromiseFactory({
122
126
  }
123
127
  })();
124
128
  try {
125
- return await Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
129
+ return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
126
130
  } finally {
127
131
  abortController.abort();
128
132
  }
@@ -163,7 +167,7 @@ function createRecentSignatureConfirmationPromiseFactory({
163
167
  }
164
168
  })();
165
169
  try {
166
- return await Promise.race([signatureDidCommitPromise, signatureStatusLookupPromise]);
170
+ return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);
167
171
  } finally {
168
172
  abortController.abort();
169
173
  }
@@ -192,8 +196,6 @@ async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment })
192
196
  );
193
197
  });
194
198
  }
195
-
196
- // src/confirmation-strategy-racer.ts
197
199
  async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
198
200
  const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;
199
201
  callerAbortSignal?.throwIfAborted();
@@ -209,7 +211,7 @@ async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
209
211
  ...config,
210
212
  abortSignal: abortController.signal
211
213
  });
212
- return await Promise.race([
214
+ return await safeRace([
213
215
  getRecentSignatureConfirmationPromise({
214
216
  abortSignal: abortController.signal,
215
217
  commitment,
@@ -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","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 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 Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\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 Promise.race([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 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 Promise.race([\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"]}
@@ -1,5 +1,6 @@
1
1
  import { SolanaError, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, getSolanaErrorFromTransactionError } from '@solana/errors';
2
2
  import { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';
3
+ import { safeRace } from '@solana/promises';
3
4
  import { commitmentComparator } from '@solana/rpc-types';
4
5
  import { getSignatureFromTransaction } from '@solana/transactions';
5
6
 
@@ -13,6 +14,7 @@ function createBlockHeightExceedencePromiseFactory({
13
14
  commitment,
14
15
  lastValidBlockHeight
15
16
  }) {
17
+ callerAbortSignal.throwIfAborted();
16
18
  const abortController = new AbortController();
17
19
  const handleAbort = () => {
18
20
  abortController.abort();
@@ -30,6 +32,7 @@ function createBlockHeightExceedencePromiseFactory({
30
32
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
31
33
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
32
34
  ]);
35
+ callerAbortSignal.throwIfAborted();
33
36
  let currentBlockHeight = initialBlockHeight;
34
37
  if (currentBlockHeight <= lastValidBlockHeight) {
35
38
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -49,6 +52,7 @@ function createBlockHeightExceedencePromiseFactory({
49
52
  }
50
53
  }
51
54
  }
55
+ callerAbortSignal.throwIfAborted();
52
56
  throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
53
57
  currentBlockHeight,
54
58
  lastValidBlockHeight
@@ -122,7 +126,7 @@ function createNonceInvalidationPromiseFactory({
122
126
  }
123
127
  })();
124
128
  try {
125
- return await Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
129
+ return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
126
130
  } finally {
127
131
  abortController.abort();
128
132
  }
@@ -163,7 +167,7 @@ function createRecentSignatureConfirmationPromiseFactory({
163
167
  }
164
168
  })();
165
169
  try {
166
- return await Promise.race([signatureDidCommitPromise, signatureStatusLookupPromise]);
170
+ return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);
167
171
  } finally {
168
172
  abortController.abort();
169
173
  }
@@ -192,8 +196,6 @@ async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment })
192
196
  );
193
197
  });
194
198
  }
195
-
196
- // src/confirmation-strategy-racer.ts
197
199
  async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
198
200
  const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;
199
201
  callerAbortSignal?.throwIfAborted();
@@ -209,7 +211,7 @@ async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
209
211
  ...config,
210
212
  abortSignal: abortController.signal
211
213
  });
212
- return await Promise.race([
214
+ return await safeRace([
213
215
  getRecentSignatureConfirmationPromise({
214
216
  abortSignal: abortController.signal,
215
217
  commitment,
@@ -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","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 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 Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\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 Promise.race([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 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 Promise.race([\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"]}
@@ -2,6 +2,7 @@
2
2
 
3
3
  var errors = require('@solana/errors');
4
4
  var codecsStrings = require('@solana/codecs-strings');
5
+ var promises = require('@solana/promises');
5
6
  var rpcTypes = require('@solana/rpc-types');
6
7
  var transactions = require('@solana/transactions');
7
8
 
@@ -15,6 +16,7 @@ function createBlockHeightExceedencePromiseFactory({
15
16
  commitment,
16
17
  lastValidBlockHeight
17
18
  }) {
19
+ callerAbortSignal.throwIfAborted();
18
20
  const abortController = new AbortController();
19
21
  const handleAbort = () => {
20
22
  abortController.abort();
@@ -32,6 +34,7 @@ function createBlockHeightExceedencePromiseFactory({
32
34
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
33
35
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
34
36
  ]);
37
+ callerAbortSignal.throwIfAborted();
35
38
  let currentBlockHeight = initialBlockHeight;
36
39
  if (currentBlockHeight <= lastValidBlockHeight) {
37
40
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -51,6 +54,7 @@ function createBlockHeightExceedencePromiseFactory({
51
54
  }
52
55
  }
53
56
  }
57
+ callerAbortSignal.throwIfAborted();
54
58
  throw new errors.SolanaError(errors.SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
55
59
  currentBlockHeight,
56
60
  lastValidBlockHeight
@@ -124,7 +128,7 @@ function createNonceInvalidationPromiseFactory({
124
128
  }
125
129
  })();
126
130
  try {
127
- return await Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
131
+ return await promises.safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
128
132
  } finally {
129
133
  abortController.abort();
130
134
  }
@@ -165,7 +169,7 @@ function createRecentSignatureConfirmationPromiseFactory({
165
169
  }
166
170
  })();
167
171
  try {
168
- return await Promise.race([signatureDidCommitPromise, signatureStatusLookupPromise]);
172
+ return await promises.safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);
169
173
  } finally {
170
174
  abortController.abort();
171
175
  }
@@ -194,8 +198,6 @@ async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment })
194
198
  );
195
199
  });
196
200
  }
197
-
198
- // src/confirmation-strategy-racer.ts
199
201
  async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
200
202
  const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;
201
203
  callerAbortSignal?.throwIfAborted();
@@ -211,7 +213,7 @@ async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
211
213
  ...config,
212
214
  abortSignal: abortController.signal
213
215
  });
214
- return await Promise.race([
216
+ return await promises.safeRace([
215
217
  getRecentSignatureConfirmationPromise({
216
218
  abortSignal: abortController.signal,
217
219
  commitment,
@@ -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","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 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 Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\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 Promise.race([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 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 Promise.race([\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"]}
@@ -1,5 +1,6 @@
1
1
  import { SolanaError, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, getSolanaErrorFromTransactionError } from '@solana/errors';
2
2
  import { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';
3
+ import { safeRace } from '@solana/promises';
3
4
  import { commitmentComparator } from '@solana/rpc-types';
4
5
  import { getSignatureFromTransaction } from '@solana/transactions';
5
6
 
@@ -13,6 +14,7 @@ function createBlockHeightExceedencePromiseFactory({
13
14
  commitment,
14
15
  lastValidBlockHeight
15
16
  }) {
17
+ callerAbortSignal.throwIfAborted();
16
18
  const abortController = new AbortController();
17
19
  const handleAbort = () => {
18
20
  abortController.abort();
@@ -30,6 +32,7 @@ function createBlockHeightExceedencePromiseFactory({
30
32
  rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),
31
33
  getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight()
32
34
  ]);
35
+ callerAbortSignal.throwIfAborted();
33
36
  let currentBlockHeight = initialBlockHeight;
34
37
  if (currentBlockHeight <= lastValidBlockHeight) {
35
38
  let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;
@@ -49,6 +52,7 @@ function createBlockHeightExceedencePromiseFactory({
49
52
  }
50
53
  }
51
54
  }
55
+ callerAbortSignal.throwIfAborted();
52
56
  throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {
53
57
  currentBlockHeight,
54
58
  lastValidBlockHeight
@@ -122,7 +126,7 @@ function createNonceInvalidationPromiseFactory({
122
126
  }
123
127
  })();
124
128
  try {
125
- return await Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
129
+ return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);
126
130
  } finally {
127
131
  abortController.abort();
128
132
  }
@@ -163,7 +167,7 @@ function createRecentSignatureConfirmationPromiseFactory({
163
167
  }
164
168
  })();
165
169
  try {
166
- return await Promise.race([signatureDidCommitPromise, signatureStatusLookupPromise]);
170
+ return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);
167
171
  } finally {
168
172
  abortController.abort();
169
173
  }
@@ -192,8 +196,6 @@ async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment })
192
196
  );
193
197
  });
194
198
  }
195
-
196
- // src/confirmation-strategy-racer.ts
197
199
  async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
198
200
  const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;
199
201
  callerAbortSignal?.throwIfAborted();
@@ -209,7 +211,7 @@ async function raceStrategies(signature, config, getSpecificStrategiesForRace) {
209
211
  ...config,
210
212
  abortSignal: abortController.signal
211
213
  });
212
- return await Promise.race([
214
+ return await safeRace([
213
215
  getRecentSignatureConfirmationPromise({
214
216
  abortSignal: abortController.signal,
215
217
  commitment,
@@ -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","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 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 Promise.race([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n } finally {\n abortController.abort();\n }\n };\n}\n","import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\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 Promise.race([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 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 Promise.race([\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"confirmation-strategy-nonce.d.ts","sourceRoot":"","sources":["../../src/confirmation-strategy-nonce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAA6B,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAErD,KAAK,6BAA6B,GAAG,CAAC,MAAM,EAAE;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,iBAAiB,EAAE,KAAK,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;CAChC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,KAAK,2CAA2C,CAAC,QAAQ,IAAI;IACzD,GAAG,EAAE,GAAG,CAAC,iBAAiB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IACxD,gBAAgB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;CAC3F,CAAC;AAQF,wBAAgB,qCAAqC,CAAC,EAClD,GAAG,EACH,gBAAgB,GACnB,EAAE,2CAA2C,CAAC,QAAQ,CAAC,GAAG,6BAA6B,CAAC;AACzF,wBAAgB,qCAAqC,CAAC,EAClD,GAAG,EACH,gBAAgB,GACnB,EAAE,2CAA2C,CAAC,SAAS,CAAC,GAAG,6BAA6B,CAAC;AAC1F,wBAAgB,qCAAqC,CAAC,EAClD,GAAG,EACH,gBAAgB,GACnB,EAAE,2CAA2C,CAAC,SAAS,CAAC,GAAG,6BAA6B,CAAC"}
1
+ {"version":3,"file":"confirmation-strategy-nonce.d.ts","sourceRoot":"","sources":["../../src/confirmation-strategy-nonce.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAA6B,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAErD,KAAK,6BAA6B,GAAG,CAAC,MAAM,EAAE;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,iBAAiB,EAAE,KAAK,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;CAChC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,KAAK,2CAA2C,CAAC,QAAQ,IAAI;IACzD,GAAG,EAAE,GAAG,CAAC,iBAAiB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IACxD,gBAAgB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;CAC3F,CAAC;AAQF,wBAAgB,qCAAqC,CAAC,EAClD,GAAG,EACH,gBAAgB,GACnB,EAAE,2CAA2C,CAAC,QAAQ,CAAC,GAAG,6BAA6B,CAAC;AACzF,wBAAgB,qCAAqC,CAAC,EAClD,GAAG,EACH,gBAAgB,GACnB,EAAE,2CAA2C,CAAC,SAAS,CAAC,GAAG,6BAA6B,CAAC;AAC1F,wBAAgB,qCAAqC,CAAC,EAClD,GAAG,EACH,gBAAgB,GACnB,EAAE,2CAA2C,CAAC,SAAS,CAAC,GAAG,6BAA6B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"confirmation-strategy-racer.d.ts","sourceRoot":"","sources":["../../src/confirmation-strategy-racer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,+CAA+C,EAAE,MAAM,0CAA0C,CAAC;AAE3G,MAAM,WAAW,yCAAyC;IACtD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,qCAAqC,EAAE,UAAU,CAAC,OAAO,+CAA+C,CAAC,CAAC;CAC7G;AAED,KAAK,0BAA0B,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AAErG,wBAAsB,cAAc,CAAC,OAAO,SAAS,yCAAyC,EAC1F,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,OAAO,EACf,4BAA4B,EAAE,CAAC,MAAM,EAAE,0BAA0B,CAAC,OAAO,CAAC,KAAK,SAAS,OAAO,CAAC,OAAO,CAAC,EAAE,oBA2B7G"}
1
+ {"version":3,"file":"confirmation-strategy-racer.d.ts","sourceRoot":"","sources":["../../src/confirmation-strategy-racer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,+CAA+C,EAAE,MAAM,0CAA0C,CAAC;AAE3G,MAAM,WAAW,yCAAyC;IACtD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,UAAU,EAAE,UAAU,CAAC;IACvB,qCAAqC,EAAE,UAAU,CAAC,OAAO,+CAA+C,CAAC,CAAC;CAC7G;AAED,KAAK,0BAA0B,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AAErG,wBAAsB,cAAc,CAAC,OAAO,SAAS,yCAAyC,EAC1F,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,OAAO,EACf,4BAA4B,EAAE,CAAC,MAAM,EAAE,0BAA0B,CAAC,OAAO,CAAC,KAAK,SAAS,OAAO,CAAC,OAAO,CAAC,EAAE,oBA2B7G"}
@@ -1 +1 @@
1
- {"version":3,"file":"confirmation-strategy-recent-signature.d.ts","sourceRoot":"","sources":["../../src/confirmation-strategy-recent-signature.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,mBAAmB,CAAC;AAE1E,KAAK,uCAAuC,GAAG,CAAC,MAAM,EAAE;IACpD,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;CACxB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,KAAK,qDAAqD,CAAC,QAAQ,IAAI;IACnE,GAAG,EAAE,GAAG,CAAC,uBAAuB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC,yBAAyB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;CAC7F,CAAC;AAEF,wBAAgB,+CAA+C,CAAC,EAC5D,GAAG,EACH,gBAAgB,GACnB,EAAE,qDAAqD,CAAC,QAAQ,CAAC,GAAG,uCAAuC,CAAC;AAC7G,wBAAgB,+CAA+C,CAAC,EAC5D,GAAG,EACH,gBAAgB,GACnB,EAAE,qDAAqD,CAAC,SAAS,CAAC,GAAG,uCAAuC,CAAC;AAC9G,wBAAgB,+CAA+C,CAAC,EAC5D,GAAG,EACH,gBAAgB,GACnB,EAAE,qDAAqD,CAAC,SAAS,CAAC,GAAG,uCAAuC,CAAC"}
1
+ {"version":3,"file":"confirmation-strategy-recent-signature.d.ts","sourceRoot":"","sources":["../../src/confirmation-strategy-recent-signature.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC7F,OAAO,EAAE,KAAK,UAAU,EAAwB,MAAM,mBAAmB,CAAC;AAE1E,KAAK,uCAAuC,GAAG,CAAC,MAAM,EAAE;IACpD,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;CACxB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEpB,KAAK,qDAAqD,CAAC,QAAQ,IAAI;IACnE,GAAG,EAAE,GAAG,CAAC,uBAAuB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;IAC9D,gBAAgB,EAAE,gBAAgB,CAAC,yBAAyB,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;CAC7F,CAAC;AAEF,wBAAgB,+CAA+C,CAAC,EAC5D,GAAG,EACH,gBAAgB,GACnB,EAAE,qDAAqD,CAAC,QAAQ,CAAC,GAAG,uCAAuC,CAAC;AAC7G,wBAAgB,+CAA+C,CAAC,EAC5D,GAAG,EACH,gBAAgB,GACnB,EAAE,qDAAqD,CAAC,SAAS,CAAC,GAAG,uCAAuC,CAAC;AAC9G,wBAAgB,+CAA+C,CAAC,EAC5D,GAAG,EACH,gBAAgB,GACnB,EAAE,qDAAqD,CAAC,SAAS,CAAC,GAAG,uCAAuC,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "name": "@solana/transaction-confirmation",
3
- "version": "2.0.0-rc.0",
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,15 +57,16 @@
49
57
  "node": ">=17.4"
50
58
  },
51
59
  "dependencies": {
52
- "@solana/addresses": "2.0.0-rc.0",
53
- "@solana/codecs-strings": "2.0.0-rc.0",
54
- "@solana/errors": "2.0.0-rc.0",
55
- "@solana/keys": "2.0.0-rc.0",
56
- "@solana/rpc": "2.0.0-rc.0",
57
- "@solana/rpc-subscriptions": "2.0.0-rc.0",
58
- "@solana/rpc-types": "2.0.0-rc.0",
59
- "@solana/transaction-messages": "2.0.0-rc.0",
60
- "@solana/transactions": "2.0.0-rc.0"
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"
61
70
  },
62
71
  "peerDependencies": {
63
72
  "typescript": ">=5"
@@ -70,12 +79,15 @@
70
79
  }
71
80
  ]
72
81
  },
82
+ "engines": {
83
+ "node": ">=20.18.0"
84
+ },
73
85
  "scripts": {
74
86
  "compile:js": "tsup --config build-scripts/tsup.config.package.ts",
75
87
  "compile:typedefs": "tsc -p ./tsconfig.declarations.json",
76
88
  "dev": "jest -c ../../node_modules/@solana/test-config/jest-dev.config.ts --rootDir . --watch",
77
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",
78
- "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 ./*",
79
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",
80
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",
81
93
  "test:treeshakability:browser": "agadoo dist/index.browser.mjs",