@solana/web3.js 1.41.8 → 1.42.0

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/lib/index.iife.js CHANGED
@@ -14028,9 +14028,17 @@ var solanaWeb3 = (function (exports) {
14028
14028
  }
14029
14029
  }
14030
14030
 
14031
+ exports.TransactionStatus = void 0;
14031
14032
  /**
14032
14033
  * Default (empty) signature
14033
14034
  */
14035
+
14036
+ (function (TransactionStatus) {
14037
+ TransactionStatus[TransactionStatus["BLOCKHEIGHT_EXCEEDED"] = 0] = "BLOCKHEIGHT_EXCEEDED";
14038
+ TransactionStatus[TransactionStatus["PROCESSED"] = 1] = "PROCESSED";
14039
+ TransactionStatus[TransactionStatus["TIMED_OUT"] = 2] = "TIMED_OUT";
14040
+ })(exports.TransactionStatus || (exports.TransactionStatus = {}));
14041
+
14034
14042
  const DEFAULT_SIGNATURE = buffer.Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
14035
14043
  /**
14036
14044
  * Account metadata used to define instructions
@@ -14121,10 +14129,23 @@ var solanaWeb3 = (function (exports) {
14121
14129
  this.feePayer = void 0;
14122
14130
  this.instructions = [];
14123
14131
  this.recentBlockhash = void 0;
14132
+ this.lastValidBlockHeight = void 0;
14124
14133
  this.nonceInfo = void 0;
14125
14134
  this._message = void 0;
14126
14135
  this._json = void 0;
14127
- opts && Object.assign(this, opts);
14136
+
14137
+ if (!opts) {
14138
+ return;
14139
+ } else if (Object.prototype.hasOwnProperty.call(opts, 'lastValidBlockHeight')) {
14140
+ const newOpts = opts;
14141
+ Object.assign(this, newOpts);
14142
+ this.recentBlockhash = newOpts.blockhash;
14143
+ this.lastValidBlockHeight = newOpts.lastValidBlockHeight;
14144
+ } else {
14145
+ const oldOpts = opts;
14146
+ Object.assign(this, oldOpts);
14147
+ this.recentBlockhash = oldOpts.recentBlockhash;
14148
+ }
14128
14149
  }
14129
14150
  /**
14130
14151
  * @internal
@@ -14734,7 +14755,11 @@ var solanaWeb3 = (function (exports) {
14734
14755
  maxRetries: options.maxRetries
14735
14756
  };
14736
14757
  const signature = await connection.sendTransaction(transaction, signers, sendOptions);
14737
- const status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
14758
+ const status = transaction.recentBlockhash != null && transaction.lastValidBlockHeight != null ? (await connection.confirmTransaction({
14759
+ signature: signature,
14760
+ blockhash: transaction.recentBlockhash,
14761
+ lastValidBlockHeight: transaction.lastValidBlockHeight
14762
+ }, options && options.commitment)).value : (await connection.confirmTransaction(signature, options && options.commitment)).value;
14738
14763
 
14739
14764
  if (status.err) {
14740
14765
  throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
@@ -24938,16 +24963,28 @@ var solanaWeb3 = (function (exports) {
24938
24963
 
24939
24964
  const MS_PER_SLOT = 1000 / NUM_SLOTS_PER_SECOND;
24940
24965
 
24941
- function promiseTimeout(promise, timeoutMs) {
24942
- let timeoutId;
24943
- const timeoutPromise = new Promise(resolve => {
24944
- timeoutId = setTimeout(() => resolve(null), timeoutMs);
24945
- });
24946
- return Promise.race([promise, timeoutPromise]).then(result => {
24947
- clearTimeout(timeoutId);
24948
- return result;
24949
- });
24966
+ class TransactionExpiredBlockheightExceededError extends Error {
24967
+ constructor(signature) {
24968
+ super(`Signature ${signature} has expired: block height exceeded.`);
24969
+ this.signature = void 0;
24970
+ this.signature = signature;
24971
+ }
24972
+
24950
24973
  }
24974
+ Object.defineProperty(TransactionExpiredBlockheightExceededError.prototype, 'name', {
24975
+ value: 'TransactionExpiredBlockheightExceededError'
24976
+ });
24977
+ class TransactionExpiredTimeoutError extends Error {
24978
+ constructor(signature, timeoutSeconds) {
24979
+ super(`Transaction was not confirmed in ${timeoutSeconds.toFixed(2)} seconds. It is ` + 'unknown if it succeeded or failed. Check signature ' + `${signature} using the Solana Explorer or CLI tools.`);
24980
+ this.signature = void 0;
24981
+ this.signature = signature;
24982
+ }
24983
+
24984
+ }
24985
+ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
24986
+ value: 'TransactionExpiredTimeoutError'
24987
+ });
24951
24988
 
24952
24989
  function makeWebsocketUrl(endpoint) {
24953
24990
  let url = new URL(endpoint);
@@ -25936,7 +25973,7 @@ var solanaWeb3 = (function (exports) {
25936
25973
  this._disableBlockhashCaching = false;
25937
25974
  this._pollingBlockhash = false;
25938
25975
  this._blockhashInfo = {
25939
- recentBlockhash: null,
25976
+ latestBlockhash: null,
25940
25977
  lastFetch: 0,
25941
25978
  transactionSignatures: [],
25942
25979
  simulatedSignatures: []
@@ -26417,67 +26454,124 @@ var solanaWeb3 = (function (exports) {
26417
26454
 
26418
26455
  return res.result;
26419
26456
  }
26420
- /**
26421
- * Confirm the transaction identified by the specified signature.
26422
- */
26423
26457
 
26458
+ // eslint-disable-next-line no-dupe-class-members
26459
+ async confirmTransaction(strategy, commitment) {
26460
+ let rawSignature;
26461
+
26462
+ if (typeof strategy == 'string') {
26463
+ rawSignature = strategy;
26464
+ } else {
26465
+ const config = strategy;
26466
+ rawSignature = config.signature;
26467
+ }
26424
26468
 
26425
- async confirmTransaction(signature, commitment) {
26426
26469
  let decodedSignature;
26427
26470
 
26428
26471
  try {
26429
- decodedSignature = bs58$1.decode(signature);
26472
+ decodedSignature = bs58$1.decode(rawSignature);
26430
26473
  } catch (err) {
26431
- throw new Error('signature must be base58 encoded: ' + signature);
26474
+ throw new Error('signature must be base58 encoded: ' + rawSignature);
26432
26475
  }
26433
26476
 
26434
26477
  assert$c(decodedSignature.length === 64, 'signature has invalid length');
26435
- const start = Date.now();
26436
26478
  const subscriptionCommitment = commitment || this.commitment;
26479
+ let timeoutId;
26437
26480
  let subscriptionId;
26438
- let response = null;
26439
- const confirmPromise = new Promise((resolve, reject) => {
26481
+ let done = false;
26482
+ const confirmationPromise = new Promise((resolve, reject) => {
26440
26483
  try {
26441
- subscriptionId = this.onSignature(signature, (result, context) => {
26484
+ subscriptionId = this.onSignature(rawSignature, (result, context) => {
26442
26485
  subscriptionId = undefined;
26443
- response = {
26486
+ const response = {
26444
26487
  context,
26445
26488
  value: result
26446
26489
  };
26447
- resolve(null);
26490
+ done = true;
26491
+ resolve({
26492
+ __type: exports.TransactionStatus.PROCESSED,
26493
+ response
26494
+ });
26448
26495
  }, subscriptionCommitment);
26449
26496
  } catch (err) {
26450
26497
  reject(err);
26451
26498
  }
26452
26499
  });
26453
- let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
26454
-
26455
- switch (subscriptionCommitment) {
26456
- case 'processed':
26457
- case 'recent':
26458
- case 'single':
26459
- case 'confirmed':
26460
- case 'singleGossip':
26461
- {
26462
- timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
26463
- break;
26500
+
26501
+ const checkBlockHeight = async () => {
26502
+ try {
26503
+ const blockHeight = await this.getBlockHeight(commitment);
26504
+ return blockHeight;
26505
+ } catch (_e) {
26506
+ return -1;
26507
+ }
26508
+ };
26509
+
26510
+ const expiryPromise = new Promise(resolve => {
26511
+ if (typeof strategy === 'string') {
26512
+ let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
26513
+
26514
+ switch (subscriptionCommitment) {
26515
+ case 'processed':
26516
+ case 'recent':
26517
+ case 'single':
26518
+ case 'confirmed':
26519
+ case 'singleGossip':
26520
+ {
26521
+ timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
26522
+ break;
26523
+ }
26464
26524
  }
26465
- }
26525
+
26526
+ timeoutId = setTimeout(() => resolve({
26527
+ __type: exports.TransactionStatus.TIMED_OUT,
26528
+ timeoutMs
26529
+ }), timeoutMs);
26530
+ } else {
26531
+ let config = strategy;
26532
+
26533
+ (async () => {
26534
+ let currentBlockHeight = await checkBlockHeight();
26535
+ if (done) return;
26536
+
26537
+ while (currentBlockHeight <= config.lastValidBlockHeight) {
26538
+ await sleep(1000);
26539
+ if (done) return;
26540
+ currentBlockHeight = await checkBlockHeight();
26541
+ if (done) return;
26542
+ }
26543
+
26544
+ resolve({
26545
+ __type: exports.TransactionStatus.BLOCKHEIGHT_EXCEEDED
26546
+ });
26547
+ })();
26548
+ }
26549
+ });
26550
+ let result;
26466
26551
 
26467
26552
  try {
26468
- await promiseTimeout(confirmPromise, timeoutMs);
26553
+ const outcome = await Promise.race([confirmationPromise, expiryPromise]);
26554
+
26555
+ switch (outcome.__type) {
26556
+ case exports.TransactionStatus.BLOCKHEIGHT_EXCEEDED:
26557
+ throw new TransactionExpiredBlockheightExceededError(rawSignature);
26558
+
26559
+ case exports.TransactionStatus.PROCESSED:
26560
+ result = outcome.response;
26561
+ break;
26562
+
26563
+ case exports.TransactionStatus.TIMED_OUT:
26564
+ throw new TransactionExpiredTimeoutError(rawSignature, outcome.timeoutMs / 1000);
26565
+ }
26469
26566
  } finally {
26567
+ clearTimeout(timeoutId);
26568
+
26470
26569
  if (subscriptionId) {
26471
26570
  this.removeSignatureListener(subscriptionId);
26472
26571
  }
26473
26572
  }
26474
26573
 
26475
- if (response === null) {
26476
- const duration = (Date.now() - start) / 1000;
26477
- throw new Error(`Transaction was not confirmed in ${duration.toFixed(2)} seconds. It is unknown if it succeeded or failed. Check signature ${signature} using the Solana Explorer or CLI tools.`);
26478
- }
26479
-
26480
- return response;
26574
+ return result;
26481
26575
  }
26482
26576
  /**
26483
26577
  * Return the list of nodes that are currently participating in the cluster
@@ -26842,7 +26936,7 @@ var solanaWeb3 = (function (exports) {
26842
26936
  }
26843
26937
  /**
26844
26938
  * Fetch the latest blockhash from the cluster
26845
- * @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
26939
+ * @return {Promise<BlockhashWithExpiryBlockHeight>}
26846
26940
  */
26847
26941
 
26848
26942
 
@@ -26856,7 +26950,7 @@ var solanaWeb3 = (function (exports) {
26856
26950
  }
26857
26951
  /**
26858
26952
  * Fetch the latest blockhash from the cluster
26859
- * @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
26953
+ * @return {Promise<BlockhashWithExpiryBlockHeight>}
26860
26954
  */
26861
26955
 
26862
26956
 
@@ -27439,7 +27533,7 @@ var solanaWeb3 = (function (exports) {
27439
27533
  */
27440
27534
 
27441
27535
 
27442
- async _recentBlockhash(disableCache) {
27536
+ async _blockhashWithExpiryBlockHeight(disableCache) {
27443
27537
  if (!disableCache) {
27444
27538
  // Wait for polling to finish
27445
27539
  while (this._pollingBlockhash) {
@@ -27450,8 +27544,8 @@ var solanaWeb3 = (function (exports) {
27450
27544
 
27451
27545
  const expired = timeSinceFetch >= BLOCKHASH_CACHE_TIMEOUT_MS;
27452
27546
 
27453
- if (this._blockhashInfo.recentBlockhash !== null && !expired) {
27454
- return this._blockhashInfo.recentBlockhash;
27547
+ if (this._blockhashInfo.latestBlockhash !== null && !expired) {
27548
+ return this._blockhashInfo.latestBlockhash;
27455
27549
  }
27456
27550
  }
27457
27551
 
@@ -27467,20 +27561,20 @@ var solanaWeb3 = (function (exports) {
27467
27561
 
27468
27562
  try {
27469
27563
  const startTime = Date.now();
27564
+ const cachedLatestBlockhash = this._blockhashInfo.latestBlockhash;
27565
+ const cachedBlockhash = cachedLatestBlockhash ? cachedLatestBlockhash.blockhash : null;
27470
27566
 
27471
27567
  for (let i = 0; i < 50; i++) {
27472
- const {
27473
- blockhash
27474
- } = await this.getRecentBlockhash('finalized');
27568
+ const latestBlockhash = await this.getLatestBlockhash('finalized');
27475
27569
 
27476
- if (this._blockhashInfo.recentBlockhash != blockhash) {
27570
+ if (cachedBlockhash !== latestBlockhash.blockhash) {
27477
27571
  this._blockhashInfo = {
27478
- recentBlockhash: blockhash,
27572
+ latestBlockhash,
27479
27573
  lastFetch: Date.now(),
27480
27574
  transactionSignatures: [],
27481
27575
  simulatedSignatures: []
27482
27576
  };
27483
- return blockhash;
27577
+ return latestBlockhash;
27484
27578
  } // Sleep for approximately half a slot
27485
27579
 
27486
27580
 
@@ -27502,13 +27596,11 @@ var solanaWeb3 = (function (exports) {
27502
27596
 
27503
27597
  if (transactionOrMessage instanceof Transaction) {
27504
27598
  let originalTx = transactionOrMessage;
27505
- transaction = new Transaction({
27506
- recentBlockhash: originalTx.recentBlockhash,
27507
- nonceInfo: originalTx.nonceInfo,
27508
- feePayer: originalTx.feePayer,
27509
- signatures: [...originalTx.signatures]
27510
- });
27599
+ transaction = new Transaction();
27600
+ transaction.feePayer = originalTx.feePayer;
27511
27601
  transaction.instructions = transactionOrMessage.instructions;
27602
+ transaction.nonceInfo = originalTx.nonceInfo;
27603
+ transaction.signatures = originalTx.signatures;
27512
27604
  } else {
27513
27605
  transaction = Transaction.populate(transactionOrMessage); // HACK: this function relies on mutating the populated transaction
27514
27606
 
@@ -27521,7 +27613,9 @@ var solanaWeb3 = (function (exports) {
27521
27613
  let disableCache = this._disableBlockhashCaching;
27522
27614
 
27523
27615
  for (;;) {
27524
- transaction.recentBlockhash = await this._recentBlockhash(disableCache);
27616
+ const latestBlockhash = await this._blockhashWithExpiryBlockHeight(disableCache);
27617
+ transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
27618
+ transaction.recentBlockhash = latestBlockhash.blockhash;
27525
27619
  if (!signers) break;
27526
27620
  transaction.sign(...signers);
27527
27621
 
@@ -27605,7 +27699,9 @@ var solanaWeb3 = (function (exports) {
27605
27699
  let disableCache = this._disableBlockhashCaching;
27606
27700
 
27607
27701
  for (;;) {
27608
- transaction.recentBlockhash = await this._recentBlockhash(disableCache);
27702
+ const latestBlockhash = await this._blockhashWithExpiryBlockHeight(disableCache);
27703
+ transaction.lastValidBlockHeight = latestBlockhash.lastValidBlockHeight;
27704
+ transaction.recentBlockhash = latestBlockhash.blockhash;
27609
27705
  transaction.sign(...signers);
27610
27706
 
27611
27707
  if (!transaction.signature) {
@@ -27705,6 +27801,7 @@ var solanaWeb3 = (function (exports) {
27705
27801
 
27706
27802
 
27707
27803
  _wsOnError(err) {
27804
+ this._rpcWebSocketConnected = false;
27708
27805
  console.error('ws error:', err.message);
27709
27806
  }
27710
27807
  /**
@@ -27713,6 +27810,7 @@ var solanaWeb3 = (function (exports) {
27713
27810
 
27714
27811
 
27715
27812
  _wsOnClose(code) {
27813
+ this._rpcWebSocketConnected = false;
27716
27814
  this._rpcWebSocketGeneration++;
27717
27815
 
27718
27816
  if (this._rpcWebSocketHeartbeat) {
@@ -30044,16 +30142,36 @@ var solanaWeb3 = (function (exports) {
30044
30142
  *
30045
30143
  * @param {Connection} connection
30046
30144
  * @param {Buffer} rawTransaction
30145
+ * @param {BlockheightBasedTransactionConfimationStrategy} confirmationStrategy
30047
30146
  * @param {ConfirmOptions} [options]
30048
30147
  * @returns {Promise<TransactionSignature>}
30049
30148
  */
30050
- async function sendAndConfirmRawTransaction(connection, rawTransaction, options) {
30149
+
30150
+ /**
30151
+ * @deprecated Calling `sendAndConfirmRawTransaction()` without a `confirmationStrategy`
30152
+ * is no longer supported and will be removed in a future version.
30153
+ */
30154
+ // eslint-disable-next-line no-redeclare
30155
+ // eslint-disable-next-line no-redeclare
30156
+ async function sendAndConfirmRawTransaction(connection, rawTransaction, confirmationStrategyOrConfirmOptions, maybeConfirmOptions) {
30157
+ let confirmationStrategy;
30158
+ let options;
30159
+
30160
+ if (confirmationStrategyOrConfirmOptions && Object.prototype.hasOwnProperty.call(confirmationStrategyOrConfirmOptions, 'lastValidBlockHeight')) {
30161
+ confirmationStrategy = confirmationStrategyOrConfirmOptions;
30162
+ options = maybeConfirmOptions;
30163
+ } else {
30164
+ options = confirmationStrategyOrConfirmOptions;
30165
+ }
30166
+
30051
30167
  const sendOptions = options && {
30052
30168
  skipPreflight: options.skipPreflight,
30053
30169
  preflightCommitment: options.preflightCommitment || options.commitment
30054
30170
  };
30055
30171
  const signature = await connection.sendRawTransaction(rawTransaction, sendOptions);
30056
- const status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
30172
+ const commitment = options && options.commitment;
30173
+ const confirmationPromise = confirmationStrategy ? connection.confirmTransaction(confirmationStrategy, commitment) : connection.confirmTransaction(signature, commitment);
30174
+ const status = (await confirmationPromise).value;
30057
30175
 
30058
30176
  if (status.err) {
30059
30177
  throw new Error(`Raw transaction ${signature} failed (${JSON.stringify(status)})`);