@solana/web3.js 1.41.11 → 1.42.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/web3.js",
3
- "version": "1.41.11",
3
+ "version": "1.42.1",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
package/src/connection.ts CHANGED
@@ -284,15 +284,18 @@ export type RpcResponseAndContext<T> = {
284
284
  value: T;
285
285
  };
286
286
 
287
+ export type BlockhashWithExpiryBlockHeight = Readonly<{
288
+ blockhash: Blockhash;
289
+ lastValidBlockHeight: number;
290
+ }>;
291
+
287
292
  /**
288
293
  * A strategy for confirming transactions that uses the last valid
289
294
  * block height for a given blockhash to check for transaction expiration.
290
295
  */
291
296
  export type BlockheightBasedTransactionConfimationStrategy = {
292
297
  signature: TransactionSignature;
293
- blockhash: Blockhash;
294
- lastValidBlockHeight: number;
295
- };
298
+ } & BlockhashWithExpiryBlockHeight;
296
299
 
297
300
  /**
298
301
  * @internal
@@ -2218,12 +2221,12 @@ export class Connection {
2218
2221
  /** @internal */ _disableBlockhashCaching: boolean = false;
2219
2222
  /** @internal */ _pollingBlockhash: boolean = false;
2220
2223
  /** @internal */ _blockhashInfo: {
2221
- recentBlockhash: Blockhash | null;
2224
+ latestBlockhash: BlockhashWithExpiryBlockHeight | null;
2222
2225
  lastFetch: number;
2223
2226
  simulatedSignatures: Array<string>;
2224
2227
  transactionSignatures: Array<string>;
2225
2228
  } = {
2226
- recentBlockhash: null,
2229
+ latestBlockhash: null,
2227
2230
  lastFetch: 0,
2228
2231
  transactionSignatures: [],
2229
2232
  simulatedSignatures: [],
@@ -3322,11 +3325,11 @@ export class Connection {
3322
3325
 
3323
3326
  /**
3324
3327
  * Fetch the latest blockhash from the cluster
3325
- * @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
3328
+ * @return {Promise<BlockhashWithExpiryBlockHeight>}
3326
3329
  */
3327
3330
  async getLatestBlockhash(
3328
3331
  commitment?: Commitment,
3329
- ): Promise<{blockhash: Blockhash; lastValidBlockHeight: number}> {
3332
+ ): Promise<BlockhashWithExpiryBlockHeight> {
3330
3333
  try {
3331
3334
  const res = await this.getLatestBlockhashAndContext(commitment);
3332
3335
  return res.value;
@@ -3337,13 +3340,11 @@ export class Connection {
3337
3340
 
3338
3341
  /**
3339
3342
  * Fetch the latest blockhash from the cluster
3340
- * @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
3343
+ * @return {Promise<BlockhashWithExpiryBlockHeight>}
3341
3344
  */
3342
3345
  async getLatestBlockhashAndContext(
3343
3346
  commitment?: Commitment,
3344
- ): Promise<
3345
- RpcResponseAndContext<{blockhash: Blockhash; lastValidBlockHeight: number}>
3346
- > {
3347
+ ): Promise<RpcResponseAndContext<BlockhashWithExpiryBlockHeight>> {
3347
3348
  const args = this._buildArgs([], commitment);
3348
3349
  const unsafeRes = await this._rpcRequest('getLatestBlockhash', args);
3349
3350
  const res = create(unsafeRes, GetLatestBlockhashRpcResult);
@@ -3989,7 +3990,9 @@ export class Connection {
3989
3990
  /**
3990
3991
  * @internal
3991
3992
  */
3992
- async _recentBlockhash(disableCache: boolean): Promise<Blockhash> {
3993
+ async _blockhashWithExpiryBlockHeight(
3994
+ disableCache: boolean,
3995
+ ): Promise<BlockhashWithExpiryBlockHeight> {
3993
3996
  if (!disableCache) {
3994
3997
  // Wait for polling to finish
3995
3998
  while (this._pollingBlockhash) {
@@ -3997,8 +4000,8 @@ export class Connection {
3997
4000
  }
3998
4001
  const timeSinceFetch = Date.now() - this._blockhashInfo.lastFetch;
3999
4002
  const expired = timeSinceFetch >= BLOCKHASH_CACHE_TIMEOUT_MS;
4000
- if (this._blockhashInfo.recentBlockhash !== null && !expired) {
4001
- return this._blockhashInfo.recentBlockhash;
4003
+ if (this._blockhashInfo.latestBlockhash !== null && !expired) {
4004
+ return this._blockhashInfo.latestBlockhash;
4002
4005
  }
4003
4006
  }
4004
4007
 
@@ -4008,21 +4011,25 @@ export class Connection {
4008
4011
  /**
4009
4012
  * @internal
4010
4013
  */
4011
- async _pollNewBlockhash(): Promise<Blockhash> {
4014
+ async _pollNewBlockhash(): Promise<BlockhashWithExpiryBlockHeight> {
4012
4015
  this._pollingBlockhash = true;
4013
4016
  try {
4014
4017
  const startTime = Date.now();
4018
+ const cachedLatestBlockhash = this._blockhashInfo.latestBlockhash;
4019
+ const cachedBlockhash = cachedLatestBlockhash
4020
+ ? cachedLatestBlockhash.blockhash
4021
+ : null;
4015
4022
  for (let i = 0; i < 50; i++) {
4016
- const {blockhash} = await this.getRecentBlockhash('finalized');
4023
+ const latestBlockhash = await this.getLatestBlockhash('finalized');
4017
4024
 
4018
- if (this._blockhashInfo.recentBlockhash != blockhash) {
4025
+ if (cachedBlockhash !== latestBlockhash.blockhash) {
4019
4026
  this._blockhashInfo = {
4020
- recentBlockhash: blockhash,
4027
+ latestBlockhash,
4021
4028
  lastFetch: Date.now(),
4022
4029
  transactionSignatures: [],
4023
4030
  simulatedSignatures: [],
4024
4031
  };
4025
- return blockhash;
4032
+ return latestBlockhash;
4026
4033
  }
4027
4034
 
4028
4035
  // Sleep for approximately half a slot
@@ -4048,13 +4055,11 @@ export class Connection {
4048
4055
  let transaction;
4049
4056
  if (transactionOrMessage instanceof Transaction) {
4050
4057
  let originalTx: Transaction = transactionOrMessage;
4051
- transaction = new Transaction({
4052
- recentBlockhash: originalTx.recentBlockhash,
4053
- nonceInfo: originalTx.nonceInfo,
4054
- feePayer: originalTx.feePayer,
4055
- signatures: [...originalTx.signatures],
4056
- });
4058
+ transaction = new Transaction();
4059
+ transaction.feePayer = originalTx.feePayer;
4057
4060
  transaction.instructions = transactionOrMessage.instructions;
4061
+ transaction.nonceInfo = originalTx.nonceInfo;
4062
+ transaction.signatures = originalTx.signatures;
4058
4063
  } else {
4059
4064
  transaction = Transaction.populate(transactionOrMessage);
4060
4065
  // HACK: this function relies on mutating the populated transaction
@@ -4066,7 +4071,11 @@ export class Connection {
4066
4071
  } else {
4067
4072
  let disableCache = this._disableBlockhashCaching;
4068
4073
  for (;;) {
4069
- transaction.recentBlockhash = await this._recentBlockhash(disableCache);
4074
+ const latestBlockhash = await this._blockhashWithExpiryBlockHeight(
4075
+ disableCache,
4076
+ );
4077
+ transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
4078
+ transaction.recentBlockhash = latestBlockhash.blockhash;
4070
4079
 
4071
4080
  if (!signers) break;
4072
4081
 
@@ -4154,7 +4163,11 @@ export class Connection {
4154
4163
  } else {
4155
4164
  let disableCache = this._disableBlockhashCaching;
4156
4165
  for (;;) {
4157
- transaction.recentBlockhash = await this._recentBlockhash(disableCache);
4166
+ const latestBlockhash = await this._blockhashWithExpiryBlockHeight(
4167
+ disableCache,
4168
+ );
4169
+ transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
4170
+ transaction.recentBlockhash = latestBlockhash.blockhash;
4158
4171
  transaction.sign(...signers);
4159
4172
  if (!transaction.signature) {
4160
4173
  throw new Error('!signature'); // should never happen
@@ -1,6 +1,9 @@
1
1
  import type {Buffer} from 'buffer';
2
2
 
3
- import {Connection} from '../connection';
3
+ import {
4
+ BlockheightBasedTransactionConfimationStrategy,
5
+ Connection,
6
+ } from '../connection';
4
7
  import type {TransactionSignature} from '../transaction';
5
8
  import type {ConfirmOptions} from '../connection';
6
9
 
@@ -11,14 +14,57 @@ import type {ConfirmOptions} from '../connection';
11
14
  *
12
15
  * @param {Connection} connection
13
16
  * @param {Buffer} rawTransaction
17
+ * @param {BlockheightBasedTransactionConfimationStrategy} confirmationStrategy
14
18
  * @param {ConfirmOptions} [options]
15
19
  * @returns {Promise<TransactionSignature>}
16
20
  */
17
21
  export async function sendAndConfirmRawTransaction(
18
22
  connection: Connection,
19
23
  rawTransaction: Buffer,
24
+ confirmationStrategy: BlockheightBasedTransactionConfimationStrategy,
20
25
  options?: ConfirmOptions,
26
+ ): Promise<TransactionSignature>;
27
+
28
+ /**
29
+ * @deprecated Calling `sendAndConfirmRawTransaction()` without a `confirmationStrategy`
30
+ * is no longer supported and will be removed in a future version.
31
+ */
32
+ // eslint-disable-next-line no-redeclare
33
+ export async function sendAndConfirmRawTransaction(
34
+ connection: Connection,
35
+ rawTransaction: Buffer,
36
+ options?: ConfirmOptions,
37
+ ): Promise<TransactionSignature>;
38
+
39
+ // eslint-disable-next-line no-redeclare
40
+ export async function sendAndConfirmRawTransaction(
41
+ connection: Connection,
42
+ rawTransaction: Buffer,
43
+ confirmationStrategyOrConfirmOptions:
44
+ | BlockheightBasedTransactionConfimationStrategy
45
+ | ConfirmOptions
46
+ | undefined,
47
+ maybeConfirmOptions?: ConfirmOptions,
21
48
  ): Promise<TransactionSignature> {
49
+ let confirmationStrategy:
50
+ | BlockheightBasedTransactionConfimationStrategy
51
+ | undefined;
52
+ let options: ConfirmOptions | undefined;
53
+ if (
54
+ confirmationStrategyOrConfirmOptions &&
55
+ Object.prototype.hasOwnProperty.call(
56
+ confirmationStrategyOrConfirmOptions,
57
+ 'lastValidBlockHeight',
58
+ )
59
+ ) {
60
+ confirmationStrategy =
61
+ confirmationStrategyOrConfirmOptions as BlockheightBasedTransactionConfimationStrategy;
62
+ options = maybeConfirmOptions;
63
+ } else {
64
+ options = confirmationStrategyOrConfirmOptions as
65
+ | ConfirmOptions
66
+ | undefined;
67
+ }
22
68
  const sendOptions = options && {
23
69
  skipPreflight: options.skipPreflight,
24
70
  preflightCommitment: options.preflightCommitment || options.commitment,
@@ -29,12 +75,11 @@ export async function sendAndConfirmRawTransaction(
29
75
  sendOptions,
30
76
  );
31
77
 
32
- const status = (
33
- await connection.confirmTransaction(
34
- signature,
35
- options && options.commitment,
36
- )
37
- ).value;
78
+ const commitment = options && options.commitment;
79
+ const confirmationPromise = confirmationStrategy
80
+ ? connection.confirmTransaction(confirmationStrategy, commitment)
81
+ : connection.confirmTransaction(signature, commitment);
82
+ const status = (await confirmationPromise).value;
38
83
 
39
84
  if (status.err) {
40
85
  throw new Error(