@solana/web3.js 1.66.2 → 1.66.3

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.66.2",
3
+ "version": "1.66.3",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
@@ -81,7 +81,6 @@
81
81
  "@babel/preset-typescript": "^7.12.16",
82
82
  "@babel/register": "^7.12.13",
83
83
  "@commitlint/config-conventional": "^17.0.2",
84
- "@commitlint/travis-cli": "^17.0.0",
85
84
  "@rollup/plugin-alias": "^3.1.9",
86
85
  "@rollup/plugin-babel": "^5.2.3",
87
86
  "@rollup/plugin-commonjs": "^22.0.0",
package/src/bpf-loader.ts CHANGED
@@ -24,12 +24,12 @@ export class BpfLoader {
24
24
  }
25
25
 
26
26
  /**
27
- * Load a BPF program
27
+ * Load a SBF program
28
28
  *
29
29
  * @param connection The connection to use
30
30
  * @param payer Account that will pay program loading fees
31
31
  * @param program Account to load the program into
32
- * @param elf The entire ELF containing the BPF program
32
+ * @param elf The entire ELF containing the SBF program
33
33
  * @param loaderProgramId The program id of the BPF loader to use
34
34
  * @return true if program was loaded successfully, false if program was already loaded
35
35
  */
package/src/connection.ts CHANGED
@@ -88,6 +88,10 @@ type ClientSubscriptionId = number;
88
88
  /** @internal */ type ServerSubscriptionId = number;
89
89
  /** @internal */ type SubscriptionConfigHash = string;
90
90
  /** @internal */ type SubscriptionDisposeFn = () => Promise<void>;
91
+ /** @internal */ type SubscriptionStateChangeCallback = (
92
+ nextState: StatefulSubscription['state'],
93
+ ) => void;
94
+ /** @internal */ type SubscriptionStateChangeDisposeFn = () => void;
91
95
  /**
92
96
  * @internal
93
97
  * Every subscription contains the args used to open the subscription with
@@ -2617,6 +2621,8 @@ export type ConfirmedSignatureInfo = {
2617
2621
  memo: string | null;
2618
2622
  /** The unix timestamp of when the transaction was processed */
2619
2623
  blockTime?: number | null;
2624
+ /** Cluster confirmation status, if available. Possible values: `processed`, `confirmed`, `finalized` */
2625
+ confirmationStatus?: TransactionConfirmationStatus;
2620
2626
  };
2621
2627
 
2622
2628
  /**
@@ -2715,6 +2721,16 @@ export class Connection {
2715
2721
  | SubscriptionDisposeFn
2716
2722
  | undefined;
2717
2723
  } = {};
2724
+ /** @internal */ private _subscriptionHashByClientSubscriptionId: {
2725
+ [clientSubscriptionId: ClientSubscriptionId]:
2726
+ | SubscriptionConfigHash
2727
+ | undefined;
2728
+ } = {};
2729
+ /** @internal */ private _subscriptionStateChangeCallbacksByHash: {
2730
+ [hash: SubscriptionConfigHash]:
2731
+ | Set<SubscriptionStateChangeCallback>
2732
+ | undefined;
2733
+ } = {};
2718
2734
  /** @internal */ private _subscriptionCallbacksByServerSubscriptionId: {
2719
2735
  [serverSubscriptionId: ServerSubscriptionId]:
2720
2736
  | Set<SubscriptionConfig['callback']>
@@ -3372,7 +3388,10 @@ export class Connection {
3372
3388
 
3373
3389
  const subscriptionCommitment = commitment || this.commitment;
3374
3390
  let timeoutId;
3375
- let subscriptionId;
3391
+ let signatureSubscriptionId: number | undefined;
3392
+ let disposeSignatureSubscriptionStateChangeObserver:
3393
+ | SubscriptionStateChangeDisposeFn
3394
+ | undefined;
3376
3395
  let done = false;
3377
3396
 
3378
3397
  const confirmationPromise = new Promise<{
@@ -3380,10 +3399,10 @@ export class Connection {
3380
3399
  response: RpcResponseAndContext<SignatureResult>;
3381
3400
  }>((resolve, reject) => {
3382
3401
  try {
3383
- subscriptionId = this.onSignature(
3402
+ signatureSubscriptionId = this.onSignature(
3384
3403
  rawSignature,
3385
3404
  (result: SignatureResult, context: Context) => {
3386
- subscriptionId = undefined;
3405
+ signatureSubscriptionId = undefined;
3387
3406
  const response = {
3388
3407
  context,
3389
3408
  value: result,
@@ -3393,6 +3412,46 @@ export class Connection {
3393
3412
  },
3394
3413
  subscriptionCommitment,
3395
3414
  );
3415
+ const subscriptionSetupPromise = new Promise<void>(
3416
+ resolveSubscriptionSetup => {
3417
+ if (signatureSubscriptionId == null) {
3418
+ resolveSubscriptionSetup();
3419
+ } else {
3420
+ disposeSignatureSubscriptionStateChangeObserver =
3421
+ this._onSubscriptionStateChange(
3422
+ signatureSubscriptionId,
3423
+ nextState => {
3424
+ if (nextState === 'subscribed') {
3425
+ resolveSubscriptionSetup();
3426
+ }
3427
+ },
3428
+ );
3429
+ }
3430
+ },
3431
+ );
3432
+ (async () => {
3433
+ await subscriptionSetupPromise;
3434
+ if (done) return;
3435
+ const response = await this.getSignatureStatus(rawSignature);
3436
+ if (done) return;
3437
+ if (response == null) {
3438
+ return;
3439
+ }
3440
+ const {context, value} = response;
3441
+ if (value?.err) {
3442
+ reject(value.err);
3443
+ }
3444
+ if (value) {
3445
+ done = true;
3446
+ resolve({
3447
+ __type: TransactionStatus.PROCESSED,
3448
+ response: {
3449
+ context,
3450
+ value,
3451
+ },
3452
+ });
3453
+ }
3454
+ })();
3396
3455
  } catch (err) {
3397
3456
  reject(err);
3398
3457
  }
@@ -3465,8 +3524,11 @@ export class Connection {
3465
3524
  }
3466
3525
  } finally {
3467
3526
  clearTimeout(timeoutId);
3468
- if (subscriptionId) {
3469
- this.removeSignatureListener(subscriptionId);
3527
+ if (disposeSignatureSubscriptionStateChangeObserver) {
3528
+ disposeSignatureSubscriptionStateChangeObserver();
3529
+ }
3530
+ if (signatureSubscriptionId) {
3531
+ this.removeSignatureListener(signatureSubscriptionId);
3470
3532
  }
3471
3533
  }
3472
3534
  return result;
@@ -5106,13 +5168,60 @@ export class Connection {
5106
5168
  Object.entries(
5107
5169
  this._subscriptionsByHash as Record<SubscriptionConfigHash, Subscription>,
5108
5170
  ).forEach(([hash, subscription]) => {
5109
- this._subscriptionsByHash[hash] = {
5171
+ this._setSubscription(hash, {
5110
5172
  ...subscription,
5111
5173
  state: 'pending',
5112
- };
5174
+ });
5113
5175
  });
5114
5176
  }
5115
5177
 
5178
+ /**
5179
+ * @internal
5180
+ */
5181
+ private _setSubscription(
5182
+ hash: SubscriptionConfigHash,
5183
+ nextSubscription: Subscription,
5184
+ ) {
5185
+ const prevState = this._subscriptionsByHash[hash]?.state;
5186
+ this._subscriptionsByHash[hash] = nextSubscription;
5187
+ if (prevState !== nextSubscription.state) {
5188
+ const stateChangeCallbacks =
5189
+ this._subscriptionStateChangeCallbacksByHash[hash];
5190
+ if (stateChangeCallbacks) {
5191
+ stateChangeCallbacks.forEach(cb => {
5192
+ try {
5193
+ cb(nextSubscription.state);
5194
+ // eslint-disable-next-line no-empty
5195
+ } catch {}
5196
+ });
5197
+ }
5198
+ }
5199
+ }
5200
+
5201
+ /**
5202
+ * @internal
5203
+ */
5204
+ private _onSubscriptionStateChange(
5205
+ clientSubscriptionId: ClientSubscriptionId,
5206
+ callback: SubscriptionStateChangeCallback,
5207
+ ): SubscriptionStateChangeDisposeFn {
5208
+ const hash =
5209
+ this._subscriptionHashByClientSubscriptionId[clientSubscriptionId];
5210
+ if (hash == null) {
5211
+ return () => {};
5212
+ }
5213
+ const stateChangeCallbacks = (this._subscriptionStateChangeCallbacksByHash[
5214
+ hash
5215
+ ] ||= new Set());
5216
+ stateChangeCallbacks.add(callback);
5217
+ return () => {
5218
+ stateChangeCallbacks.delete(callback);
5219
+ if (stateChangeCallbacks.size === 0) {
5220
+ delete this._subscriptionStateChangeCallbacksByHash[hash];
5221
+ }
5222
+ };
5223
+ }
5224
+
5116
5225
  /**
5117
5226
  * @internal
5118
5227
  */
@@ -5193,17 +5302,17 @@ export class Connection {
5193
5302
  await (async () => {
5194
5303
  const {args, method} = subscription;
5195
5304
  try {
5196
- this._subscriptionsByHash[hash] = {
5305
+ this._setSubscription(hash, {
5197
5306
  ...subscription,
5198
5307
  state: 'subscribing',
5199
- };
5308
+ });
5200
5309
  const serverSubscriptionId: ServerSubscriptionId =
5201
5310
  (await this._rpcWebSocket.call(method, args)) as number;
5202
- this._subscriptionsByHash[hash] = {
5311
+ this._setSubscription(hash, {
5203
5312
  ...subscription,
5204
5313
  serverSubscriptionId,
5205
5314
  state: 'subscribed',
5206
- };
5315
+ });
5207
5316
  this._subscriptionCallbacksByServerSubscriptionId[
5208
5317
  serverSubscriptionId
5209
5318
  ] = subscription.callbacks;
@@ -5220,10 +5329,10 @@ export class Connection {
5220
5329
  return;
5221
5330
  }
5222
5331
  // TODO: Maybe add an 'errored' state or a retry limit?
5223
- this._subscriptionsByHash[hash] = {
5332
+ this._setSubscription(hash, {
5224
5333
  ...subscription,
5225
5334
  state: 'pending',
5226
- };
5335
+ });
5227
5336
  await this._updateSubscriptions();
5228
5337
  }
5229
5338
  })();
@@ -5251,10 +5360,14 @@ export class Connection {
5251
5360
  serverSubscriptionId,
5252
5361
  );
5253
5362
  } else {
5254
- this._subscriptionsByHash[hash] = {
5363
+ this._setSubscription(hash, {
5364
+ ...subscription,
5365
+ state: 'unsubscribing',
5366
+ });
5367
+ this._setSubscription(hash, {
5255
5368
  ...subscription,
5256
5369
  state: 'unsubscribing',
5257
- };
5370
+ });
5258
5371
  try {
5259
5372
  await this._rpcWebSocket.call(unsubscribeMethod, [
5260
5373
  serverSubscriptionId,
@@ -5267,18 +5380,18 @@ export class Connection {
5267
5380
  return;
5268
5381
  }
5269
5382
  // TODO: Maybe add an 'errored' state or a retry limit?
5270
- this._subscriptionsByHash[hash] = {
5383
+ this._setSubscription(hash, {
5271
5384
  ...subscription,
5272
5385
  state: 'subscribed',
5273
- };
5386
+ });
5274
5387
  await this._updateSubscriptions();
5275
5388
  return;
5276
5389
  }
5277
5390
  }
5278
- this._subscriptionsByHash[hash] = {
5391
+ this._setSubscription(hash, {
5279
5392
  ...subscription,
5280
5393
  state: 'unsubscribed',
5281
- };
5394
+ });
5282
5395
  await this._updateSubscriptions();
5283
5396
  })();
5284
5397
  }
@@ -5381,12 +5494,14 @@ export class Connection {
5381
5494
  } else {
5382
5495
  existingSubscription.callbacks.add(subscriptionConfig.callback);
5383
5496
  }
5497
+ this._subscriptionHashByClientSubscriptionId[clientSubscriptionId] = hash;
5384
5498
  this._subscriptionDisposeFunctionsByClientSubscriptionId[
5385
5499
  clientSubscriptionId
5386
5500
  ] = async () => {
5387
5501
  delete this._subscriptionDisposeFunctionsByClientSubscriptionId[
5388
5502
  clientSubscriptionId
5389
5503
  ];
5504
+ delete this._subscriptionHashByClientSubscriptionId[clientSubscriptionId];
5390
5505
  const subscription = this._subscriptionsByHash[hash];
5391
5506
  assert(
5392
5507
  subscription !== undefined,