@solana/web3.js 1.41.9 → 1.41.11

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.
@@ -2192,6 +2192,36 @@ function encodeLength(bytes, len) {
2192
2192
  }
2193
2193
  }
2194
2194
 
2195
+ const END_OF_BUFFER_ERROR_MESSAGE = 'Reached end of buffer unexpectedly';
2196
+ /**
2197
+ * Delegates to `Array#shift`, but throws if the array is zero-length.
2198
+ */
2199
+
2200
+ function guardedShift(byteArray) {
2201
+ if (byteArray.length === 0) {
2202
+ throw new Error(END_OF_BUFFER_ERROR_MESSAGE);
2203
+ }
2204
+
2205
+ return byteArray.shift();
2206
+ }
2207
+ /**
2208
+ * Delegates to `Array#splice`, but throws if the section being spliced out extends past the end of
2209
+ * the array.
2210
+ */
2211
+
2212
+ function guardedSplice(byteArray, ...args) {
2213
+ var _args$;
2214
+
2215
+ const [start] = args;
2216
+
2217
+ if (args.length === 2 // Implies that `deleteCount` was supplied
2218
+ ? start + ((_args$ = args[1]) !== null && _args$ !== void 0 ? _args$ : 0) > byteArray.length : start >= byteArray.length) {
2219
+ throw new Error(END_OF_BUFFER_ERROR_MESSAGE);
2220
+ }
2221
+
2222
+ return byteArray.splice(...args);
2223
+ }
2224
+
2195
2225
  /**
2196
2226
  * The message header, identifying signed and read-only account
2197
2227
  */
@@ -2290,32 +2320,28 @@ class Message {
2290
2320
  static from(buffer) {
2291
2321
  // Slice up wire data
2292
2322
  let byteArray = [...buffer];
2293
- const numRequiredSignatures = byteArray.shift();
2294
- const numReadonlySignedAccounts = byteArray.shift();
2295
- const numReadonlyUnsignedAccounts = byteArray.shift();
2323
+ const numRequiredSignatures = guardedShift(byteArray);
2324
+ const numReadonlySignedAccounts = guardedShift(byteArray);
2325
+ const numReadonlyUnsignedAccounts = guardedShift(byteArray);
2296
2326
  const accountCount = decodeLength(byteArray);
2297
2327
  let accountKeys = [];
2298
2328
 
2299
2329
  for (let i = 0; i < accountCount; i++) {
2300
- const account = byteArray.slice(0, PUBKEY_LENGTH);
2301
- byteArray = byteArray.slice(PUBKEY_LENGTH);
2330
+ const account = guardedSplice(byteArray, 0, PUBKEY_LENGTH);
2302
2331
  accountKeys.push(bs58.encode(Buffer.from(account)));
2303
2332
  }
2304
2333
 
2305
- const recentBlockhash = byteArray.slice(0, PUBKEY_LENGTH);
2306
- byteArray = byteArray.slice(PUBKEY_LENGTH);
2334
+ const recentBlockhash = guardedSplice(byteArray, 0, PUBKEY_LENGTH);
2307
2335
  const instructionCount = decodeLength(byteArray);
2308
2336
  let instructions = [];
2309
2337
 
2310
2338
  for (let i = 0; i < instructionCount; i++) {
2311
- const programIdIndex = byteArray.shift();
2339
+ const programIdIndex = guardedShift(byteArray);
2312
2340
  const accountCount = decodeLength(byteArray);
2313
- const accounts = byteArray.slice(0, accountCount);
2314
- byteArray = byteArray.slice(accountCount);
2341
+ const accounts = guardedSplice(byteArray, 0, accountCount);
2315
2342
  const dataLength = decodeLength(byteArray);
2316
- const dataSlice = byteArray.slice(0, dataLength);
2343
+ const dataSlice = guardedSplice(byteArray, 0, dataLength);
2317
2344
  const data = bs58.encode(Buffer.from(dataSlice));
2318
- byteArray = byteArray.slice(dataLength);
2319
2345
  instructions.push({
2320
2346
  programIdIndex,
2321
2347
  accounts,
@@ -2344,9 +2370,21 @@ function assert (condition, message) {
2344
2370
  }
2345
2371
  }
2346
2372
 
2373
+ /**
2374
+ * Transaction signature as base-58 encoded string
2375
+ */
2376
+
2377
+ let TransactionStatus;
2347
2378
  /**
2348
2379
  * Default (empty) signature
2349
2380
  */
2381
+
2382
+ (function (TransactionStatus) {
2383
+ TransactionStatus[TransactionStatus["BLOCKHEIGHT_EXCEEDED"] = 0] = "BLOCKHEIGHT_EXCEEDED";
2384
+ TransactionStatus[TransactionStatus["PROCESSED"] = 1] = "PROCESSED";
2385
+ TransactionStatus[TransactionStatus["TIMED_OUT"] = 2] = "TIMED_OUT";
2386
+ })(TransactionStatus || (TransactionStatus = {}));
2387
+
2350
2388
  const DEFAULT_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
2351
2389
  /**
2352
2390
  * Account metadata used to define instructions
@@ -2437,10 +2475,23 @@ class Transaction {
2437
2475
  this.feePayer = void 0;
2438
2476
  this.instructions = [];
2439
2477
  this.recentBlockhash = void 0;
2478
+ this.lastValidBlockHeight = void 0;
2440
2479
  this.nonceInfo = void 0;
2441
2480
  this._message = void 0;
2442
2481
  this._json = void 0;
2443
- opts && Object.assign(this, opts);
2482
+
2483
+ if (!opts) {
2484
+ return;
2485
+ } else if (Object.prototype.hasOwnProperty.call(opts, 'lastValidBlockHeight')) {
2486
+ const newOpts = opts;
2487
+ Object.assign(this, newOpts);
2488
+ this.recentBlockhash = newOpts.blockhash;
2489
+ this.lastValidBlockHeight = newOpts.lastValidBlockHeight;
2490
+ } else {
2491
+ const oldOpts = opts;
2492
+ Object.assign(this, oldOpts);
2493
+ this.recentBlockhash = oldOpts.recentBlockhash;
2494
+ }
2444
2495
  }
2445
2496
  /**
2446
2497
  * @internal
@@ -2973,8 +3024,7 @@ class Transaction {
2973
3024
  let signatures = [];
2974
3025
 
2975
3026
  for (let i = 0; i < signatureCount; i++) {
2976
- const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
2977
- byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
3027
+ const signature = guardedSplice(byteArray, 0, SIGNATURE_LENGTH_IN_BYTES);
2978
3028
  signatures.push(bs58.encode(Buffer.from(signature)));
2979
3029
  }
2980
3030
 
@@ -3050,7 +3100,11 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
3050
3100
  maxRetries: options.maxRetries
3051
3101
  };
3052
3102
  const signature = await connection.sendTransaction(transaction, signers, sendOptions);
3053
- const status = (await connection.confirmTransaction(signature, options && options.commitment)).value;
3103
+ const status = transaction.recentBlockhash != null && transaction.lastValidBlockHeight != null ? (await connection.confirmTransaction({
3104
+ signature: signature,
3105
+ blockhash: transaction.recentBlockhash,
3106
+ lastValidBlockHeight: transaction.lastValidBlockHeight
3107
+ }, options && options.commitment)).value : (await connection.confirmTransaction(signature, options && options.commitment)).value;
3054
3108
 
3055
3109
  if (status.err) {
3056
3110
  throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
@@ -4962,16 +5016,28 @@ const NUM_SLOTS_PER_SECOND = NUM_TICKS_PER_SECOND / DEFAULT_TICKS_PER_SLOT;
4962
5016
 
4963
5017
  const MS_PER_SLOT = 1000 / NUM_SLOTS_PER_SECOND;
4964
5018
 
4965
- function promiseTimeout(promise, timeoutMs) {
4966
- let timeoutId;
4967
- const timeoutPromise = new Promise(resolve => {
4968
- timeoutId = setTimeout(() => resolve(null), timeoutMs);
4969
- });
4970
- return Promise.race([promise, timeoutPromise]).then(result => {
4971
- clearTimeout(timeoutId);
4972
- return result;
4973
- });
5019
+ class TransactionExpiredBlockheightExceededError extends Error {
5020
+ constructor(signature) {
5021
+ super(`Signature ${signature} has expired: block height exceeded.`);
5022
+ this.signature = void 0;
5023
+ this.signature = signature;
5024
+ }
5025
+
4974
5026
  }
5027
+ Object.defineProperty(TransactionExpiredBlockheightExceededError.prototype, 'name', {
5028
+ value: 'TransactionExpiredBlockheightExceededError'
5029
+ });
5030
+ class TransactionExpiredTimeoutError extends Error {
5031
+ constructor(signature, timeoutSeconds) {
5032
+ 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.`);
5033
+ this.signature = void 0;
5034
+ this.signature = signature;
5035
+ }
5036
+
5037
+ }
5038
+ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
5039
+ value: 'TransactionExpiredTimeoutError'
5040
+ });
4975
5041
 
4976
5042
  function makeWebsocketUrl(endpoint) {
4977
5043
  let url = new URL(endpoint);
@@ -6441,67 +6507,124 @@ class Connection {
6441
6507
 
6442
6508
  return res.result;
6443
6509
  }
6444
- /**
6445
- * Confirm the transaction identified by the specified signature.
6446
- */
6447
6510
 
6511
+ // eslint-disable-next-line no-dupe-class-members
6512
+ async confirmTransaction(strategy, commitment) {
6513
+ let rawSignature;
6514
+
6515
+ if (typeof strategy == 'string') {
6516
+ rawSignature = strategy;
6517
+ } else {
6518
+ const config = strategy;
6519
+ rawSignature = config.signature;
6520
+ }
6448
6521
 
6449
- async confirmTransaction(signature, commitment) {
6450
6522
  let decodedSignature;
6451
6523
 
6452
6524
  try {
6453
- decodedSignature = bs58.decode(signature);
6525
+ decodedSignature = bs58.decode(rawSignature);
6454
6526
  } catch (err) {
6455
- throw new Error('signature must be base58 encoded: ' + signature);
6527
+ throw new Error('signature must be base58 encoded: ' + rawSignature);
6456
6528
  }
6457
6529
 
6458
6530
  assert(decodedSignature.length === 64, 'signature has invalid length');
6459
- const start = Date.now();
6460
6531
  const subscriptionCommitment = commitment || this.commitment;
6532
+ let timeoutId;
6461
6533
  let subscriptionId;
6462
- let response = null;
6463
- const confirmPromise = new Promise((resolve, reject) => {
6534
+ let done = false;
6535
+ const confirmationPromise = new Promise((resolve, reject) => {
6464
6536
  try {
6465
- subscriptionId = this.onSignature(signature, (result, context) => {
6537
+ subscriptionId = this.onSignature(rawSignature, (result, context) => {
6466
6538
  subscriptionId = undefined;
6467
- response = {
6539
+ const response = {
6468
6540
  context,
6469
6541
  value: result
6470
6542
  };
6471
- resolve(null);
6543
+ done = true;
6544
+ resolve({
6545
+ __type: TransactionStatus.PROCESSED,
6546
+ response
6547
+ });
6472
6548
  }, subscriptionCommitment);
6473
6549
  } catch (err) {
6474
6550
  reject(err);
6475
6551
  }
6476
6552
  });
6477
- let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
6478
-
6479
- switch (subscriptionCommitment) {
6480
- case 'processed':
6481
- case 'recent':
6482
- case 'single':
6483
- case 'confirmed':
6484
- case 'singleGossip':
6485
- {
6486
- timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
6487
- break;
6553
+
6554
+ const checkBlockHeight = async () => {
6555
+ try {
6556
+ const blockHeight = await this.getBlockHeight(commitment);
6557
+ return blockHeight;
6558
+ } catch (_e) {
6559
+ return -1;
6560
+ }
6561
+ };
6562
+
6563
+ const expiryPromise = new Promise(resolve => {
6564
+ if (typeof strategy === 'string') {
6565
+ let timeoutMs = this._confirmTransactionInitialTimeout || 60 * 1000;
6566
+
6567
+ switch (subscriptionCommitment) {
6568
+ case 'processed':
6569
+ case 'recent':
6570
+ case 'single':
6571
+ case 'confirmed':
6572
+ case 'singleGossip':
6573
+ {
6574
+ timeoutMs = this._confirmTransactionInitialTimeout || 30 * 1000;
6575
+ break;
6576
+ }
6488
6577
  }
6489
- }
6578
+
6579
+ timeoutId = setTimeout(() => resolve({
6580
+ __type: TransactionStatus.TIMED_OUT,
6581
+ timeoutMs
6582
+ }), timeoutMs);
6583
+ } else {
6584
+ let config = strategy;
6585
+
6586
+ (async () => {
6587
+ let currentBlockHeight = await checkBlockHeight();
6588
+ if (done) return;
6589
+
6590
+ while (currentBlockHeight <= config.lastValidBlockHeight) {
6591
+ await sleep(1000);
6592
+ if (done) return;
6593
+ currentBlockHeight = await checkBlockHeight();
6594
+ if (done) return;
6595
+ }
6596
+
6597
+ resolve({
6598
+ __type: TransactionStatus.BLOCKHEIGHT_EXCEEDED
6599
+ });
6600
+ })();
6601
+ }
6602
+ });
6603
+ let result;
6490
6604
 
6491
6605
  try {
6492
- await promiseTimeout(confirmPromise, timeoutMs);
6606
+ const outcome = await Promise.race([confirmationPromise, expiryPromise]);
6607
+
6608
+ switch (outcome.__type) {
6609
+ case TransactionStatus.BLOCKHEIGHT_EXCEEDED:
6610
+ throw new TransactionExpiredBlockheightExceededError(rawSignature);
6611
+
6612
+ case TransactionStatus.PROCESSED:
6613
+ result = outcome.response;
6614
+ break;
6615
+
6616
+ case TransactionStatus.TIMED_OUT:
6617
+ throw new TransactionExpiredTimeoutError(rawSignature, outcome.timeoutMs / 1000);
6618
+ }
6493
6619
  } finally {
6620
+ clearTimeout(timeoutId);
6621
+
6494
6622
  if (subscriptionId) {
6495
6623
  this.removeSignatureListener(subscriptionId);
6496
6624
  }
6497
6625
  }
6498
6626
 
6499
- if (response === null) {
6500
- const duration = (Date.now() - start) / 1000;
6501
- 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.`);
6502
- }
6503
-
6504
- return response;
6627
+ return result;
6505
6628
  }
6506
6629
  /**
6507
6630
  * Return the list of nodes that are currently participating in the cluster
@@ -9618,10 +9741,8 @@ class ValidatorInfo {
9618
9741
  const configKeys = [];
9619
9742
 
9620
9743
  for (let i = 0; i < 2; i++) {
9621
- const publicKey = new PublicKey(byteArray.slice(0, PUBKEY_LENGTH));
9622
- byteArray = byteArray.slice(PUBKEY_LENGTH);
9623
- const isSigner = byteArray.slice(0, 1)[0] === 1;
9624
- byteArray = byteArray.slice(1);
9744
+ const publicKey = new PublicKey(guardedSplice(byteArray, 0, PUBKEY_LENGTH));
9745
+ const isSigner = guardedShift(byteArray) === 1;
9625
9746
  configKeys.push({
9626
9747
  publicKey,
9627
9748
  isSigner
@@ -10126,5 +10247,5 @@ function clusterApiUrl(cluster, tls) {
10126
10247
 
10127
10248
  const LAMPORTS_PER_SOL = 1000000000;
10128
10249
 
10129
- 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 };
10250
+ 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 };
10130
10251
  //# sourceMappingURL=index.browser.esm.js.map