@solana/web3.js 1.41.7 → 1.41.10

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.d.ts CHANGED
@@ -338,6 +338,11 @@ declare module '@solana/web3.js' {
338
338
  * Transaction signature as base-58 encoded string
339
339
  */
340
340
  export type TransactionSignature = string;
341
+ export const enum TransactionStatus {
342
+ BLOCKHEIGHT_EXCEEDED = 0,
343
+ PROCESSED = 1,
344
+ TIMED_OUT = 2,
345
+ }
341
346
  /**
342
347
  * Account metadata used to define instructions
343
348
  */
@@ -394,17 +399,29 @@ declare module '@solana/web3.js' {
394
399
  };
395
400
  /**
396
401
  * List of Transaction object fields that may be initialized at construction
397
- *
398
402
  */
399
- export type TransactionCtorFields = {
400
- /** A recent blockhash */
401
- recentBlockhash?: Blockhash | null;
403
+ export type TransactionCtorFields_DEPRECATED = {
402
404
  /** Optional nonce information used for offline nonce'd transactions */
403
405
  nonceInfo?: NonceInformation | null;
404
406
  /** The transaction fee payer */
405
407
  feePayer?: PublicKey | null;
406
408
  /** One or more signatures */
407
409
  signatures?: Array<SignaturePubkeyPair>;
410
+ /** A recent blockhash */
411
+ recentBlockhash?: Blockhash;
412
+ };
413
+ /**
414
+ * List of Transaction object fields that may be initialized at construction
415
+ */
416
+ export type TransactionBlockhashCtor = {
417
+ /** The transaction fee payer */
418
+ feePayer?: PublicKey | null;
419
+ /** One or more signatures */
420
+ signatures?: Array<SignaturePubkeyPair>;
421
+ /** A recent blockhash */
422
+ blockhash: Blockhash;
423
+ /** the last block chain can advance to before tx is exportd expired */
424
+ lastValidBlockHeight: number;
408
425
  };
409
426
  /**
410
427
  * Nonce information to be used to build an offline Transaction.
@@ -440,15 +457,21 @@ declare module '@solana/web3.js' {
440
457
  * A recent transaction id. Must be populated by the caller
441
458
  */
442
459
  recentBlockhash?: Blockhash;
460
+ /**
461
+ * the last block chain can advance to before tx is exportd expired
462
+ * */
463
+ lastValidBlockHeight?: number;
443
464
  /**
444
465
  * Optional Nonce information. If populated, transaction will use a durable
445
466
  * Nonce hash instead of a recentBlockhash. Must be populated by the caller
446
467
  */
447
468
  nonceInfo?: NonceInformation;
469
+ constructor(opts?: TransactionBlockhashCtor);
448
470
  /**
449
- * Construct an empty Transaction
471
+ * @deprecated `TransactionCtorFields` has been deprecated and will be removed in a future version.
472
+ * Please supply a `TransactionBlockhashCtor` instead.
450
473
  */
451
- constructor(opts?: TransactionCtorFields);
474
+ constructor(opts?: TransactionCtorFields_DEPRECATED);
452
475
  /**
453
476
  * Add one or more instructions to this Transaction
454
477
  */
@@ -602,6 +625,15 @@ declare module '@solana/web3.js' {
602
625
  /** response value */
603
626
  value: T;
604
627
  };
628
+ /**
629
+ * A strategy for confirming transactions that uses the last valid
630
+ * block height for a given blockhash to check for transaction expiration.
631
+ */
632
+ export type BlockheightBasedTransactionConfimationStrategy = {
633
+ signature: TransactionSignature;
634
+ blockhash: Blockhash;
635
+ lastValidBlockHeight: number;
636
+ };
605
637
  /**
606
638
  * The level of commitment desired when querying state
607
639
  * <pre>
@@ -1624,11 +1656,13 @@ declare module '@solana/web3.js' {
1624
1656
  account: AccountInfo<Buffer | ParsedAccountData>;
1625
1657
  }>
1626
1658
  >;
1627
- /**
1628
- * Confirm the transaction identified by the specified signature.
1629
- */
1630
1659
  confirmTransaction(
1631
- signature: TransactionSignature,
1660
+ strategy: BlockheightBasedTransactionConfimationStrategy,
1661
+ commitment?: Commitment,
1662
+ ): Promise<RpcResponseAndContext<SignatureResult>>;
1663
+ /** @deprecated Instead, call `confirmTransaction` using a `TransactionConfirmationConfig` */
1664
+ confirmTransaction(
1665
+ strategy: TransactionSignature,
1632
1666
  commitment?: Commitment,
1633
1667
  ): Promise<RpcResponseAndContext<SignatureResult>>;
1634
1668
  /**
package/lib/index.esm.js CHANGED
@@ -2353,9 +2353,17 @@ function assert (condition, message) {
2353
2353
  }
2354
2354
  }
2355
2355
 
2356
+ let TransactionStatus;
2356
2357
  /**
2357
2358
  * Default (empty) signature
2358
2359
  */
2360
+
2361
+ (function (TransactionStatus) {
2362
+ TransactionStatus[TransactionStatus["BLOCKHEIGHT_EXCEEDED"] = 0] = "BLOCKHEIGHT_EXCEEDED";
2363
+ TransactionStatus[TransactionStatus["PROCESSED"] = 1] = "PROCESSED";
2364
+ TransactionStatus[TransactionStatus["TIMED_OUT"] = 2] = "TIMED_OUT";
2365
+ })(TransactionStatus || (TransactionStatus = {}));
2366
+
2359
2367
  const DEFAULT_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
2360
2368
  /**
2361
2369
  * Account metadata used to define instructions
@@ -2446,10 +2454,23 @@ class Transaction {
2446
2454
  this.feePayer = void 0;
2447
2455
  this.instructions = [];
2448
2456
  this.recentBlockhash = void 0;
2457
+ this.lastValidBlockHeight = void 0;
2449
2458
  this.nonceInfo = void 0;
2450
2459
  this._message = void 0;
2451
2460
  this._json = void 0;
2452
- opts && Object.assign(this, opts);
2461
+
2462
+ if (!opts) {
2463
+ return;
2464
+ } else if (Object.prototype.hasOwnProperty.call(opts, 'lastValidBlockHeight')) {
2465
+ const newOpts = opts;
2466
+ Object.assign(this, newOpts);
2467
+ this.recentBlockhash = newOpts.blockhash;
2468
+ this.lastValidBlockHeight = newOpts.lastValidBlockHeight;
2469
+ } else {
2470
+ const oldOpts = opts;
2471
+ Object.assign(this, oldOpts);
2472
+ this.recentBlockhash = oldOpts.recentBlockhash;
2473
+ }
2453
2474
  }
2454
2475
  /**
2455
2476
  * @internal
@@ -3059,7 +3080,11 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
3059
3080
  maxRetries: options.maxRetries
3060
3081
  };
3061
3082
  const signature = await connection.sendTransaction(transaction, signers, sendOptions);
3062
- const status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
3083
+ const status = transaction.recentBlockhash != null && transaction.lastValidBlockHeight != null ? (await connection.confirmTransaction({
3084
+ signature: signature,
3085
+ blockhash: transaction.recentBlockhash,
3086
+ lastValidBlockHeight: transaction.lastValidBlockHeight
3087
+ }, options && options.commitment)).value : (await connection.confirmTransaction(signature, options && options.commitment)).value;
3063
3088
 
3064
3089
  if (status.err) {
3065
3090
  throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
@@ -4459,16 +4484,28 @@ const NUM_SLOTS_PER_SECOND = NUM_TICKS_PER_SECOND / DEFAULT_TICKS_PER_SLOT;
4459
4484
 
4460
4485
  const MS_PER_SLOT = 1000 / NUM_SLOTS_PER_SECOND;
4461
4486
 
4462
- function promiseTimeout(promise, timeoutMs) {
4463
- let timeoutId;
4464
- const timeoutPromise = new Promise(resolve => {
4465
- timeoutId = setTimeout(() => resolve(null), timeoutMs);
4466
- });
4467
- return Promise.race([promise, timeoutPromise]).then(result => {
4468
- clearTimeout(timeoutId);
4469
- return result;
4470
- });
4487
+ class TransactionExpiredBlockheightExceededError extends Error {
4488
+ constructor(signature) {
4489
+ super(`Signature ${signature} has expired: block height exceeded.`);
4490
+ this.signature = void 0;
4491
+ this.signature = signature;
4492
+ }
4493
+
4471
4494
  }
4495
+ Object.defineProperty(TransactionExpiredBlockheightExceededError.prototype, 'name', {
4496
+ value: 'TransactionExpiredBlockheightExceededError'
4497
+ });
4498
+ class TransactionExpiredTimeoutError extends Error {
4499
+ constructor(signature, timeoutSeconds) {
4500
+ 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.`);
4501
+ this.signature = void 0;
4502
+ this.signature = signature;
4503
+ }
4504
+
4505
+ }
4506
+ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
4507
+ value: 'TransactionExpiredTimeoutError'
4508
+ });
4472
4509
 
4473
4510
  function makeWebsocketUrl(endpoint) {
4474
4511
  let url = new URL(endpoint);
@@ -5944,67 +5981,124 @@ class Connection {
5944
5981
 
5945
5982
  return res.result;
5946
5983
  }
5947
- /**
5948
- * Confirm the transaction identified by the specified signature.
5949
- */
5950
5984
 
5985
+ // eslint-disable-next-line no-dupe-class-members
5986
+ async confirmTransaction(strategy, commitment) {
5987
+ let rawSignature;
5988
+
5989
+ if (typeof strategy == 'string') {
5990
+ rawSignature = strategy;
5991
+ } else {
5992
+ const config = strategy;
5993
+ rawSignature = config.signature;
5994
+ }
5951
5995
 
5952
- async confirmTransaction(signature, commitment) {
5953
5996
  let decodedSignature;
5954
5997
 
5955
5998
  try {
5956
- decodedSignature = bs58.decode(signature);
5999
+ decodedSignature = bs58.decode(rawSignature);
5957
6000
  } catch (err) {
5958
- throw new Error('signature must be base58 encoded: ' + signature);
6001
+ throw new Error('signature must be base58 encoded: ' + rawSignature);
5959
6002
  }
5960
6003
 
5961
6004
  assert(decodedSignature.length === 64, 'signature has invalid length');
5962
- const start = Date.now();
5963
6005
  const subscriptionCommitment = commitment || this.commitment;
6006
+ let timeoutId;
5964
6007
  let subscriptionId;
5965
- let response = null;
5966
- const confirmPromise = new Promise((resolve, reject) => {
6008
+ let done = false;
6009
+ const confirmationPromise = new Promise((resolve, reject) => {
5967
6010
  try {
5968
- subscriptionId = this.onSignature(signature, (result, context) => {
6011
+ subscriptionId = this.onSignature(rawSignature, (result, context) => {
5969
6012
  subscriptionId = undefined;
5970
- response = {
6013
+ const response = {
5971
6014
  context,
5972
6015
  value: result
5973
6016
  };
5974
- resolve(null);
6017
+ done = true;
6018
+ resolve({
6019
+ __type: TransactionStatus.PROCESSED,
6020
+ response
6021
+ });
5975
6022
  }, subscriptionCommitment);
5976
6023
  } catch (err) {
5977
6024
  reject(err);
5978
6025
  }
5979
6026
  });
5980
- let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
5981
-
5982
- switch (subscriptionCommitment) {
5983
- case 'processed':
5984
- case 'recent':
5985
- case 'single':
5986
- case 'confirmed':
5987
- case 'singleGossip':
5988
- {
5989
- timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
5990
- break;
6027
+
6028
+ const checkBlockHeight = async () => {
6029
+ try {
6030
+ const blockHeight = await this.getBlockHeight(commitment);
6031
+ return blockHeight;
6032
+ } catch (_e) {
6033
+ return -1;
6034
+ }
6035
+ };
6036
+
6037
+ const expiryPromise = new Promise(resolve => {
6038
+ if (typeof strategy === 'string') {
6039
+ let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
6040
+
6041
+ switch (subscriptionCommitment) {
6042
+ case 'processed':
6043
+ case 'recent':
6044
+ case 'single':
6045
+ case 'confirmed':
6046
+ case 'singleGossip':
6047
+ {
6048
+ timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
6049
+ break;
6050
+ }
5991
6051
  }
5992
- }
6052
+
6053
+ timeoutId = setTimeout(() => resolve({
6054
+ __type: TransactionStatus.TIMED_OUT,
6055
+ timeoutMs
6056
+ }), timeoutMs);
6057
+ } else {
6058
+ let config = strategy;
6059
+
6060
+ (async () => {
6061
+ let currentBlockHeight = await checkBlockHeight();
6062
+ if (done) return;
6063
+
6064
+ while (currentBlockHeight <= config.lastValidBlockHeight) {
6065
+ await sleep(1000);
6066
+ if (done) return;
6067
+ currentBlockHeight = await checkBlockHeight();
6068
+ if (done) return;
6069
+ }
6070
+
6071
+ resolve({
6072
+ __type: TransactionStatus.BLOCKHEIGHT_EXCEEDED
6073
+ });
6074
+ })();
6075
+ }
6076
+ });
6077
+ let result;
5993
6078
 
5994
6079
  try {
5995
- await promiseTimeout(confirmPromise, timeoutMs);
6080
+ const outcome = await Promise.race([confirmationPromise, expiryPromise]);
6081
+
6082
+ switch (outcome.__type) {
6083
+ case TransactionStatus.BLOCKHEIGHT_EXCEEDED:
6084
+ throw new TransactionExpiredBlockheightExceededError(rawSignature);
6085
+
6086
+ case TransactionStatus.PROCESSED:
6087
+ result = outcome.response;
6088
+ break;
6089
+
6090
+ case TransactionStatus.TIMED_OUT:
6091
+ throw new TransactionExpiredTimeoutError(rawSignature, outcome.timeoutMs / 1000);
6092
+ }
5996
6093
  } finally {
6094
+ clearTimeout(timeoutId);
6095
+
5997
6096
  if (subscriptionId) {
5998
6097
  this.removeSignatureListener(subscriptionId);
5999
6098
  }
6000
6099
  }
6001
6100
 
6002
- if (response === null) {
6003
- const duration = (Date.now() - start) / 1000;
6004
- 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.`);
6005
- }
6006
-
6007
- return response;
6101
+ return result;
6008
6102
  }
6009
6103
  /**
6010
6104
  * Return the list of nodes that are currently participating in the cluster
@@ -7232,6 +7326,7 @@ class Connection {
7232
7326
 
7233
7327
 
7234
7328
  _wsOnError(err) {
7329
+ this._rpcWebSocketConnected = false;
7235
7330
  console.error('ws error:', err.message);
7236
7331
  }
7237
7332
  /**
@@ -7240,6 +7335,7 @@ class Connection {
7240
7335
 
7241
7336
 
7242
7337
  _wsOnClose(code) {
7338
+ this._rpcWebSocketConnected = false;
7243
7339
  this._rpcWebSocketGeneration++;
7244
7340
 
7245
7341
  if (this._rpcWebSocketHeartbeat) {
@@ -9627,5 +9723,5 @@ function clusterApiUrl(cluster, tls) {
9627
9723
 
9628
9724
  const LAMPORTS_PER_SOL = 1000000000;
9629
9725
 
9630
- export { Account, Authorized, BLOCKHASH_CACHE_TIMEOUT_MS, BPF_LOADER_DEPRECATED_PROGRAM_ID, BPF_LOADER_PROGRAM_ID, BpfLoader, COMPUTE_BUDGET_INSTRUCTION_LAYOUTS, ComputeBudgetInstruction, ComputeBudgetProgram, Connection, Ed25519Program, Enum, EpochSchedule, FeeCalculatorLayout, Keypair, LAMPORTS_PER_SOL, Loader, Lockup, MAX_SEED_LENGTH, Message, NONCE_ACCOUNT_LENGTH, NonceAccount, PACKET_DATA_SIZE, PublicKey, SIGNATURE_LENGTH_IN_BYTES, SOLANA_SCHEMA, STAKE_CONFIG_ID, STAKE_INSTRUCTION_LAYOUTS, SYSTEM_INSTRUCTION_LAYOUTS, SYSVAR_CLOCK_PUBKEY, SYSVAR_EPOCH_SCHEDULE_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_REWARDS_PUBKEY, SYSVAR_SLOT_HASHES_PUBKEY, SYSVAR_SLOT_HISTORY_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, Secp256k1Program, SendTransactionError, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionInstruction, VALIDATOR_INFO_KEY, VOTE_PROGRAM_ID, ValidatorInfo, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
9726
+ export { Account, Authorized, BLOCKHASH_CACHE_TIMEOUT_MS, BPF_LOADER_DEPRECATED_PROGRAM_ID, BPF_LOADER_PROGRAM_ID, BpfLoader, COMPUTE_BUDGET_INSTRUCTION_LAYOUTS, ComputeBudgetInstruction, ComputeBudgetProgram, Connection, Ed25519Program, Enum, EpochSchedule, FeeCalculatorLayout, Keypair, LAMPORTS_PER_SOL, Loader, Lockup, MAX_SEED_LENGTH, Message, NONCE_ACCOUNT_LENGTH, NonceAccount, PACKET_DATA_SIZE, PublicKey, SIGNATURE_LENGTH_IN_BYTES, SOLANA_SCHEMA, STAKE_CONFIG_ID, STAKE_INSTRUCTION_LAYOUTS, SYSTEM_INSTRUCTION_LAYOUTS, SYSVAR_CLOCK_PUBKEY, SYSVAR_EPOCH_SCHEDULE_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_REWARDS_PUBKEY, SYSVAR_SLOT_HASHES_PUBKEY, SYSVAR_SLOT_HISTORY_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, Secp256k1Program, SendTransactionError, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionInstruction, TransactionStatus, VALIDATOR_INFO_KEY, VOTE_PROGRAM_ID, ValidatorInfo, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
9631
9727
  //# sourceMappingURL=index.esm.js.map