@solana/web3.js 1.41.0 → 1.41.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/lib/index.iife.js CHANGED
@@ -13761,6 +13761,16 @@ var solanaWeb3 = (function (exports) {
13761
13761
  /** Factory for {@link Constant} values. */
13762
13762
  Layout$1.constant = ((value, property) => new Constant(value, property));
13763
13763
 
13764
+ /**
13765
+ * Maximum over-the-wire size of a Transaction
13766
+ *
13767
+ * 1280 is IPv6 minimum MTU
13768
+ * 40 bytes is the size of the IPv6 header
13769
+ * 8 bytes is the size of the fragment header
13770
+ */
13771
+ const PACKET_DATA_SIZE = 1280 - 40 - 8;
13772
+ const SIGNATURE_LENGTH_IN_BYTES = 64;
13773
+
13764
13774
  /**
13765
13775
  * Layout for a public key
13766
13776
  */
@@ -14020,20 +14030,8 @@ var solanaWeb3 = (function (exports) {
14020
14030
 
14021
14031
  /**
14022
14032
  * Default (empty) signature
14023
- *
14024
- * Signatures are 64 bytes in length
14025
14033
  */
14026
- const DEFAULT_SIGNATURE = buffer.Buffer.alloc(64).fill(0);
14027
- /**
14028
- * Maximum over-the-wire size of a Transaction
14029
- *
14030
- * 1280 is IPv6 minimum MTU
14031
- * 40 bytes is the size of the IPv6 header
14032
- * 8 bytes is the size of the fragment header
14033
- */
14034
-
14035
- const PACKET_DATA_SIZE = 1280 - 40 - 8;
14036
- const SIGNATURE_LENGTH = 64;
14034
+ const DEFAULT_SIGNATURE = buffer.Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
14037
14035
  /**
14038
14036
  * Account metadata used to define instructions
14039
14037
  */
@@ -14663,8 +14661,8 @@ var solanaWeb3 = (function (exports) {
14663
14661
  let signatures = [];
14664
14662
 
14665
14663
  for (let i = 0; i < signatureCount; i++) {
14666
- const signature = byteArray.slice(0, SIGNATURE_LENGTH);
14667
- byteArray = byteArray.slice(SIGNATURE_LENGTH);
14664
+ const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
14665
+ byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
14668
14666
  signatures.push(bs58$1.encode(buffer.Buffer.from(signature)));
14669
14667
  }
14670
14668
 
@@ -15553,11 +15551,11 @@ var solanaWeb3 = (function (exports) {
15553
15551
  }
15554
15552
  SystemProgram.programId = new PublicKey('11111111111111111111111111111111');
15555
15553
 
15556
- // Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
15557
15554
  // rest of the Transaction fields
15558
15555
  //
15559
15556
  // TODO: replace 300 with a proper constant for the size of the other
15560
15557
  // Transaction fields
15558
+
15561
15559
  const CHUNK_SIZE = PACKET_DATA_SIZE - 300;
15562
15560
  /**
15563
15561
  * Program loader interface
@@ -16448,6 +16446,82 @@ var solanaWeb3 = (function (exports) {
16448
16446
 
16449
16447
  var crossFetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfill.exports);
16450
16448
 
16449
+ var objToString = Object.prototype.toString;
16450
+ var objKeys = Object.keys || function(obj) {
16451
+ var keys = [];
16452
+ for (var name in obj) {
16453
+ keys.push(name);
16454
+ }
16455
+ return keys;
16456
+ };
16457
+
16458
+ function stringify$1(val, isArrayProp) {
16459
+ var i, max, str, keys, key, propVal, toStr;
16460
+ if (val === true) {
16461
+ return "true";
16462
+ }
16463
+ if (val === false) {
16464
+ return "false";
16465
+ }
16466
+ switch (typeof val) {
16467
+ case "object":
16468
+ if (val === null) {
16469
+ return null;
16470
+ } else if (val.toJSON && typeof val.toJSON === "function") {
16471
+ return stringify$1(val.toJSON(), isArrayProp);
16472
+ } else {
16473
+ toStr = objToString.call(val);
16474
+ if (toStr === "[object Array]") {
16475
+ str = '[';
16476
+ max = val.length - 1;
16477
+ for(i = 0; i < max; i++) {
16478
+ str += stringify$1(val[i], true) + ',';
16479
+ }
16480
+ if (max > -1) {
16481
+ str += stringify$1(val[i], true);
16482
+ }
16483
+ return str + ']';
16484
+ } else if (toStr === "[object Object]") {
16485
+ // only object is left
16486
+ keys = objKeys(val).sort();
16487
+ max = keys.length;
16488
+ str = "";
16489
+ i = 0;
16490
+ while (i < max) {
16491
+ key = keys[i];
16492
+ propVal = stringify$1(val[key], false);
16493
+ if (propVal !== undefined) {
16494
+ if (str) {
16495
+ str += ',';
16496
+ }
16497
+ str += JSON.stringify(key) + ':' + propVal;
16498
+ }
16499
+ i++;
16500
+ }
16501
+ return '{' + str + '}';
16502
+ } else {
16503
+ return JSON.stringify(val);
16504
+ }
16505
+ }
16506
+ case "function":
16507
+ case "undefined":
16508
+ return isArrayProp ? null : undefined;
16509
+ case "string":
16510
+ return JSON.stringify(val);
16511
+ default:
16512
+ return isFinite(val) ? val : null;
16513
+ }
16514
+ }
16515
+
16516
+ var fastStableStringify = function(val) {
16517
+ var returnVal = stringify$1(val, false);
16518
+ if (returnVal !== undefined) {
16519
+ return ''+ returnVal;
16520
+ }
16521
+ };
16522
+
16523
+ var fastStableStringify$1 = fastStableStringify;
16524
+
16451
16525
  /**
16452
16526
  * A `StructFailure` represents a single specific failure in validation.
16453
16527
  */
@@ -17072,6 +17146,31 @@ var solanaWeb3 = (function (exports) {
17072
17146
  module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports;
17073
17147
  }(interopRequireDefault));
17074
17148
 
17149
+ var createClass = {exports: {}};
17150
+
17151
+ (function (module) {
17152
+ function _defineProperties(target, props) {
17153
+ for (var i = 0; i < props.length; i++) {
17154
+ var descriptor = props[i];
17155
+ descriptor.enumerable = descriptor.enumerable || false;
17156
+ descriptor.configurable = true;
17157
+ if ("value" in descriptor) descriptor.writable = true;
17158
+ Object.defineProperty(target, descriptor.key, descriptor);
17159
+ }
17160
+ }
17161
+
17162
+ function _createClass(Constructor, protoProps, staticProps) {
17163
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
17164
+ if (staticProps) _defineProperties(Constructor, staticProps);
17165
+ Object.defineProperty(Constructor, "prototype", {
17166
+ writable: false
17167
+ });
17168
+ return Constructor;
17169
+ }
17170
+
17171
+ module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
17172
+ }(createClass));
17173
+
17075
17174
  var classCallCheck = {exports: {}};
17076
17175
 
17077
17176
  (function (module) {
@@ -17189,31 +17288,6 @@ var solanaWeb3 = (function (exports) {
17189
17288
 
17190
17289
  var websocket_browser = {};
17191
17290
 
17192
- var createClass = {exports: {}};
17193
-
17194
- (function (module) {
17195
- function _defineProperties(target, props) {
17196
- for (var i = 0; i < props.length; i++) {
17197
- var descriptor = props[i];
17198
- descriptor.enumerable = descriptor.enumerable || false;
17199
- descriptor.configurable = true;
17200
- if ("value" in descriptor) descriptor.writable = true;
17201
- Object.defineProperty(target, descriptor.key, descriptor);
17202
- }
17203
- }
17204
-
17205
- function _createClass(Constructor, protoProps, staticProps) {
17206
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
17207
- if (staticProps) _defineProperties(Constructor, staticProps);
17208
- Object.defineProperty(Constructor, "prototype", {
17209
- writable: false
17210
- });
17211
- return Constructor;
17212
- }
17213
-
17214
- module.exports = _createClass, module.exports.__esModule = true, module.exports["default"] = module.exports;
17215
- }(createClass));
17216
-
17217
17291
  var eventemitter3 = {exports: {}};
17218
17292
 
17219
17293
  (function (module) {
@@ -17582,7 +17656,7 @@ var solanaWeb3 = (function (exports) {
17582
17656
 
17583
17657
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
17584
17658
 
17585
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
17659
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
17586
17660
 
17587
17661
  var WebSocketBrowserImpl = /*#__PURE__*/function (_EventEmitter) {
17588
17662
  (0, _inherits2["default"])(WebSocketBrowserImpl, _EventEmitter);
@@ -18483,215 +18557,6 @@ var solanaWeb3 = (function (exports) {
18483
18557
  module.exports = _asyncToGenerator, module.exports.__esModule = true, module.exports["default"] = module.exports;
18484
18558
  }(asyncToGenerator));
18485
18559
 
18486
- /*!
18487
- Copyright (C) 2013-2017 by Andrea Giammarchi - @WebReflection
18488
-
18489
- Permission is hereby granted, free of charge, to any person obtaining a copy
18490
- of this software and associated documentation files (the "Software"), to deal
18491
- in the Software without restriction, including without limitation the rights
18492
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18493
- copies of the Software, and to permit persons to whom the Software is
18494
- furnished to do so, subject to the following conditions:
18495
-
18496
- The above copyright notice and this permission notice shall be included in
18497
- all copies or substantial portions of the Software.
18498
-
18499
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18500
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18501
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18502
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18503
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18504
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18505
- THE SOFTWARE.
18506
-
18507
- */
18508
-
18509
- var
18510
- // should be a not so common char
18511
- // possibly one JSON does not encode
18512
- // possibly one encodeURIComponent does not encode
18513
- // right now this char is '~' but this might change in the future
18514
- specialChar = '~',
18515
- safeSpecialChar = '\\x' + (
18516
- '0' + specialChar.charCodeAt(0).toString(16)
18517
- ).slice(-2),
18518
- escapedSafeSpecialChar = '\\' + safeSpecialChar,
18519
- specialCharRG = new RegExp(safeSpecialChar, 'g'),
18520
- safeSpecialCharRG = new RegExp(escapedSafeSpecialChar, 'g'),
18521
-
18522
- safeStartWithSpecialCharRG = new RegExp('(?:^|([^\\\\]))' + escapedSafeSpecialChar),
18523
-
18524
- indexOf = [].indexOf || function(v){
18525
- for(var i=this.length;i--&&this[i]!==v;);
18526
- return i;
18527
- },
18528
- $String = String // there's no way to drop warnings in JSHint
18529
- // about new String ... well, I need that here!
18530
- // faked, and happy linter!
18531
- ;
18532
-
18533
- function generateReplacer(value, replacer, resolve) {
18534
- var
18535
- doNotIgnore = false,
18536
- inspect = !!replacer,
18537
- path = [],
18538
- all = [value],
18539
- seen = [value],
18540
- mapp = [resolve ? specialChar : '[Circular]'],
18541
- last = value,
18542
- lvl = 1,
18543
- i, fn
18544
- ;
18545
- if (inspect) {
18546
- fn = typeof replacer === 'object' ?
18547
- function (key, value) {
18548
- return key !== '' && replacer.indexOf(key) < 0 ? void 0 : value;
18549
- } :
18550
- replacer;
18551
- }
18552
- return function(key, value) {
18553
- // the replacer has rights to decide
18554
- // if a new object should be returned
18555
- // or if there's some key to drop
18556
- // let's call it here rather than "too late"
18557
- if (inspect) value = fn.call(this, key, value);
18558
-
18559
- // first pass should be ignored, since it's just the initial object
18560
- if (doNotIgnore) {
18561
- if (last !== this) {
18562
- i = lvl - indexOf.call(all, this) - 1;
18563
- lvl -= i;
18564
- all.splice(lvl, all.length);
18565
- path.splice(lvl - 1, path.length);
18566
- last = this;
18567
- }
18568
- // console.log(lvl, key, path);
18569
- if (typeof value === 'object' && value) {
18570
- // if object isn't referring to parent object, add to the
18571
- // object path stack. Otherwise it is already there.
18572
- if (indexOf.call(all, value) < 0) {
18573
- all.push(last = value);
18574
- }
18575
- lvl = all.length;
18576
- i = indexOf.call(seen, value);
18577
- if (i < 0) {
18578
- i = seen.push(value) - 1;
18579
- if (resolve) {
18580
- // key cannot contain specialChar but could be not a string
18581
- path.push(('' + key).replace(specialCharRG, safeSpecialChar));
18582
- mapp[i] = specialChar + path.join(specialChar);
18583
- } else {
18584
- mapp[i] = mapp[0];
18585
- }
18586
- } else {
18587
- value = mapp[i];
18588
- }
18589
- } else {
18590
- if (typeof value === 'string' && resolve) {
18591
- // ensure no special char involved on deserialization
18592
- // in this case only first char is important
18593
- // no need to replace all value (better performance)
18594
- value = value .replace(safeSpecialChar, escapedSafeSpecialChar)
18595
- .replace(specialChar, safeSpecialChar);
18596
- }
18597
- }
18598
- } else {
18599
- doNotIgnore = true;
18600
- }
18601
- return value;
18602
- };
18603
- }
18604
-
18605
- function retrieveFromPath(current, keys) {
18606
- for(var i = 0, length = keys.length; i < length; current = current[
18607
- // keys should be normalized back here
18608
- keys[i++].replace(safeSpecialCharRG, specialChar)
18609
- ]);
18610
- return current;
18611
- }
18612
-
18613
- function generateReviver(reviver) {
18614
- return function(key, value) {
18615
- var isString = typeof value === 'string';
18616
- if (isString && value.charAt(0) === specialChar) {
18617
- return new $String(value.slice(1));
18618
- }
18619
- if (key === '') value = regenerate(value, value, {});
18620
- // again, only one needed, do not use the RegExp for this replacement
18621
- // only keys need the RegExp
18622
- if (isString) value = value .replace(safeStartWithSpecialCharRG, '$1' + specialChar)
18623
- .replace(escapedSafeSpecialChar, safeSpecialChar);
18624
- return reviver ? reviver.call(this, key, value) : value;
18625
- };
18626
- }
18627
-
18628
- function regenerateArray(root, current, retrieve) {
18629
- for (var i = 0, length = current.length; i < length; i++) {
18630
- current[i] = regenerate(root, current[i], retrieve);
18631
- }
18632
- return current;
18633
- }
18634
-
18635
- function regenerateObject(root, current, retrieve) {
18636
- for (var key in current) {
18637
- if (current.hasOwnProperty(key)) {
18638
- current[key] = regenerate(root, current[key], retrieve);
18639
- }
18640
- }
18641
- return current;
18642
- }
18643
-
18644
- function regenerate(root, current, retrieve) {
18645
- return current instanceof Array ?
18646
- // fast Array reconstruction
18647
- regenerateArray(root, current, retrieve) :
18648
- (
18649
- current instanceof $String ?
18650
- (
18651
- // root is an empty string
18652
- current.length ?
18653
- (
18654
- retrieve.hasOwnProperty(current) ?
18655
- retrieve[current] :
18656
- retrieve[current] = retrieveFromPath(
18657
- root, current.split(specialChar)
18658
- )
18659
- ) :
18660
- root
18661
- ) :
18662
- (
18663
- current instanceof Object ?
18664
- // dedicated Object parser
18665
- regenerateObject(root, current, retrieve) :
18666
- // value as it is
18667
- current
18668
- )
18669
- )
18670
- ;
18671
- }
18672
-
18673
- var CircularJSON = {
18674
- stringify: function stringify(value, replacer, space, doNotResolve) {
18675
- return CircularJSON.parser.stringify(
18676
- value,
18677
- generateReplacer(value, replacer, !doNotResolve),
18678
- space
18679
- );
18680
- },
18681
- parse: function parse(text, reviver) {
18682
- return CircularJSON.parser.parse(
18683
- text,
18684
- generateReviver(reviver)
18685
- );
18686
- },
18687
- // A parser should be an API 1:1 compatible with JSON
18688
- // it should expose stringify and parse methods.
18689
- // The default parser is the native JSON.
18690
- parser: JSON
18691
- };
18692
-
18693
- var circularJson_node = CircularJSON;
18694
-
18695
18560
  /**
18696
18561
  * "Client" wraps "ws" or a browser-implemented "WebSocket" library
18697
18562
  * according to the environment providing JSON RPC 2.0 support on top.
@@ -18725,11 +18590,9 @@ var solanaWeb3 = (function (exports) {
18725
18590
 
18726
18591
  var _eventemitter = eventemitter3.exports;
18727
18592
 
18728
- var _circularJson = _interopRequireDefault(circularJson_node);
18729
-
18730
18593
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
18731
18594
 
18732
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
18595
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
18733
18596
 
18734
18597
  var __rest = function (s, e) {
18735
18598
  var t = {};
@@ -19113,7 +18976,7 @@ var solanaWeb3 = (function (exports) {
19113
18976
  if (message instanceof ArrayBuffer) message = Buffer.from(message).toString();
19114
18977
 
19115
18978
  try {
19116
- message = _circularJson["default"].parse(message);
18979
+ message = JSON.parse(message);
19117
18980
  } catch (error) {
19118
18981
  return;
19119
18982
  } // check if any listeners are attached and forward event
@@ -19184,6 +19047,8 @@ var solanaWeb3 = (function (exports) {
19184
19047
  });
19185
19048
  var Client_1 = index_browser.Client = void 0;
19186
19049
 
19050
+ var _createClass2 = _interopRequireDefault(createClass.exports);
19051
+
19187
19052
  var _classCallCheck2 = _interopRequireDefault(classCallCheck.exports);
19188
19053
 
19189
19054
  var _inherits2 = _interopRequireDefault(inherits$3.exports);
@@ -19198,7 +19063,7 @@ var solanaWeb3 = (function (exports) {
19198
19063
 
19199
19064
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; }
19200
19065
 
19201
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
19066
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
19202
19067
 
19203
19068
  var Client = /*#__PURE__*/function (_CommonClient) {
19204
19069
  (0, _inherits2["default"])(Client, _CommonClient);
@@ -19228,7 +19093,7 @@ var solanaWeb3 = (function (exports) {
19228
19093
  }, generate_request_id);
19229
19094
  }
19230
19095
 
19231
- return Client;
19096
+ return (0, _createClass2["default"])(Client);
19232
19097
  }(_client["default"]);
19233
19098
 
19234
19099
  Client_1 = index_browser.Client = Client;
@@ -20225,6 +20090,12 @@ var solanaWeb3 = (function (exports) {
20225
20090
  */
20226
20091
 
20227
20092
  const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
20093
+ /**
20094
+ * HACK.
20095
+ * Copied from rpc-websockets/dist/lib/client.
20096
+ * Otherwise, `yarn build` fails with:
20097
+ * https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
20098
+ */
20228
20099
 
20229
20100
  /**
20230
20101
  * @internal
@@ -21093,14 +20964,9 @@ var solanaWeb3 = (function (exports) {
21093
20964
  * Filter for log subscriptions.
21094
20965
  */
21095
20966
 
21096
- function createSubscriptionWarningMessage(id, label) {
21097
- return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
21098
- }
21099
20967
  /**
21100
20968
  * A connection to a fullnode JSON RPC endpoint
21101
20969
  */
21102
-
21103
-
21104
20970
  class Connection {
21105
20971
  /** @internal */
21106
20972
 
@@ -21124,21 +20990,13 @@ var solanaWeb3 = (function (exports) {
21124
20990
 
21125
20991
  /** @internal */
21126
20992
 
21127
- /** @internal */
21128
-
21129
- /** @internal */
21130
-
21131
- /** @internal */
21132
-
21133
- /** @internal */
21134
-
21135
- /** @internal */
21136
-
21137
- /** @internal */
21138
-
21139
- /** @internal */
21140
-
21141
- /** @internal */
20993
+ /** @internal
20994
+ * A number that we increment every time an active connection closes.
20995
+ * Used to determine whether the same socket connection that was open
20996
+ * when an async operation started is the same one that's active when
20997
+ * its continuation fires.
20998
+ *
20999
+ */
21142
21000
 
21143
21001
  /** @internal */
21144
21002
 
@@ -21154,7 +21012,19 @@ var solanaWeb3 = (function (exports) {
21154
21012
 
21155
21013
  /** @internal */
21156
21014
 
21157
- /** @internal */
21015
+ /**
21016
+ * Special case.
21017
+ * After a signature is processed, RPCs automatically dispose of the
21018
+ * subscription on the server side. We need to track which of these
21019
+ * subscriptions have been disposed in such a way, so that we know
21020
+ * whether the client is dealing with a not-yet-processed signature
21021
+ * (in which case we must tear down the server subscription) or an
21022
+ * already-processed signature (in which case the client can simply
21023
+ * clear out the subscription locally without telling the server).
21024
+ *
21025
+ * NOTE: There is a proposal to eliminate this special case, here:
21026
+ * https://github.com/solana-labs/solana/issues/18892
21027
+ */
21158
21028
 
21159
21029
  /** @internal */
21160
21030
 
@@ -21176,6 +21046,7 @@ var solanaWeb3 = (function (exports) {
21176
21046
  this._rpcWebSocketConnected = false;
21177
21047
  this._rpcWebSocketHeartbeat = null;
21178
21048
  this._rpcWebSocketIdleTimeout = null;
21049
+ this._rpcWebSocketGeneration = 0;
21179
21050
  this._disableBlockhashCaching = false;
21180
21051
  this._pollingBlockhash = false;
21181
21052
  this._blockhashInfo = {
@@ -21184,20 +21055,11 @@ var solanaWeb3 = (function (exports) {
21184
21055
  transactionSignatures: [],
21185
21056
  simulatedSignatures: []
21186
21057
  };
21187
- this._accountChangeSubscriptionCounter = 0;
21188
- this._accountChangeSubscriptions = {};
21189
- this._programAccountChangeSubscriptionCounter = 0;
21190
- this._programAccountChangeSubscriptions = {};
21191
- this._rootSubscriptionCounter = 0;
21192
- this._rootSubscriptions = {};
21193
- this._signatureSubscriptionCounter = 0;
21194
- this._signatureSubscriptions = {};
21195
- this._slotSubscriptionCounter = 0;
21196
- this._slotSubscriptions = {};
21197
- this._logsSubscriptionCounter = 0;
21198
- this._logsSubscriptions = {};
21199
- this._slotUpdateSubscriptionCounter = 0;
21200
- this._slotUpdateSubscriptions = {};
21058
+ this._nextClientSubscriptionId = 0;
21059
+ this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
21060
+ this._subscriptionCallbacksByServerSubscriptionId = {};
21061
+ this._subscriptionsByHash = {};
21062
+ this._subscriptionsAutoDisposedByRpc = new Set();
21201
21063
  let url = new URL(endpoint);
21202
21064
  const useHttps = url.protocol === 'https:';
21203
21065
  let wsEndpoint;
@@ -22965,6 +22827,8 @@ var solanaWeb3 = (function (exports) {
22965
22827
 
22966
22828
 
22967
22829
  _wsOnClose(code) {
22830
+ this._rpcWebSocketGeneration++;
22831
+
22968
22832
  if (this._rpcWebSocketHeartbeat) {
22969
22833
  clearInterval(this._rpcWebSocketHeartbeat);
22970
22834
  this._rpcWebSocketHeartbeat = null;
@@ -22978,85 +22842,20 @@ var solanaWeb3 = (function (exports) {
22978
22842
  } // implicit close, prepare subscriptions for auto-reconnect
22979
22843
 
22980
22844
 
22981
- this._resetSubscriptions();
22982
- }
22983
- /**
22984
- * @internal
22985
- */
22986
-
22987
-
22988
- async _subscribe(sub, rpcMethod, rpcArgs) {
22989
- if (sub.subscriptionId == null) {
22990
- sub.subscriptionId = 'subscribing';
22991
-
22992
- try {
22993
- const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
22994
-
22995
- if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
22996
- // eslint-disable-next-line require-atomic-updates
22997
- sub.subscriptionId = id;
22998
- }
22999
- } catch (err) {
23000
- if (sub.subscriptionId === 'subscribing') {
23001
- // eslint-disable-next-line require-atomic-updates
23002
- sub.subscriptionId = null;
23003
- }
23004
-
23005
- if (err instanceof Error) {
23006
- console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
23007
- }
23008
- }
23009
- }
23010
- }
23011
- /**
23012
- * @internal
23013
- */
23014
-
23015
-
23016
- async _unsubscribe(sub, rpcMethod) {
23017
- const subscriptionId = sub.subscriptionId;
23018
-
23019
- if (subscriptionId != null && typeof subscriptionId != 'string') {
23020
- const unsubscribeId = subscriptionId;
23021
-
23022
- try {
23023
- await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
23024
- } catch (err) {
23025
- if (err instanceof Error) {
23026
- console.error(`${rpcMethod} error:`, err.message);
23027
- }
23028
- }
23029
- }
23030
- }
23031
- /**
23032
- * @internal
23033
- */
23034
-
23035
-
23036
- _resetSubscriptions() {
23037
- Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
23038
- Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
23039
- Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
23040
- Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
23041
- Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
23042
- Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
23043
- Object.values(this._slotUpdateSubscriptions).forEach(s => s.subscriptionId = null);
22845
+ this._subscriptionCallbacksByServerSubscriptionId = {};
22846
+ Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
22847
+ this._subscriptionsByHash[hash] = { ...subscription,
22848
+ state: 'pending'
22849
+ };
22850
+ });
23044
22851
  }
23045
22852
  /**
23046
22853
  * @internal
23047
22854
  */
23048
22855
 
23049
22856
 
23050
- _updateSubscriptions() {
23051
- const accountKeys = Object.keys(this._accountChangeSubscriptions).map(Number);
23052
- const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
23053
- const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
23054
- const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
23055
- const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
23056
- const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
23057
- const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
23058
-
23059
- if (accountKeys.length === 0 && programKeys.length === 0 && slotKeys.length === 0 && slotUpdateKeys.length === 0 && signatureKeys.length === 0 && rootKeys.length === 0 && logsKeys.length === 0) {
22857
+ async _updateSubscriptions() {
22858
+ if (Object.keys(this._subscriptionsByHash).length === 0) {
23060
22859
  if (this._rpcWebSocketConnected) {
23061
22860
  this._rpcWebSocketConnected = false;
23062
22861
  this._rpcWebSocketIdleTimeout = setTimeout(() => {
@@ -23088,60 +22887,167 @@ var solanaWeb3 = (function (exports) {
23088
22887
  return;
23089
22888
  }
23090
22889
 
23091
- for (let id of accountKeys) {
23092
- const sub = this._accountChangeSubscriptions[id];
22890
+ const activeWebSocketGeneration = this._rpcWebSocketGeneration;
23093
22891
 
23094
- this._subscribe(sub, 'accountSubscribe', this._buildArgs([sub.publicKey], sub.commitment, 'base64'));
23095
- }
22892
+ const isCurrentConnectionStillActive = () => {
22893
+ return activeWebSocketGeneration === this._rpcWebSocketGeneration;
22894
+ };
23096
22895
 
23097
- for (let id of programKeys) {
23098
- const sub = this._programAccountChangeSubscriptions[id];
22896
+ await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
22897
+ // `_updateSubscriptions` recursively when processing the state,
22898
+ // so it's important that we look up the *current* version of
22899
+ // each subscription, every time we process a hash.
22900
+ Object.keys(this._subscriptionsByHash).map(async hash => {
22901
+ const subscription = this._subscriptionsByHash[hash];
23099
22902
 
23100
- this._subscribe(sub, 'programSubscribe', this._buildArgs([sub.programId], sub.commitment, 'base64', {
23101
- filters: sub.filters
23102
- }));
23103
- }
22903
+ if (subscription === undefined) {
22904
+ // This entry has since been deleted. Skip.
22905
+ return;
22906
+ }
23104
22907
 
23105
- for (let id of slotKeys) {
23106
- const sub = this._slotSubscriptions[id];
22908
+ switch (subscription.state) {
22909
+ case 'pending':
22910
+ case 'unsubscribed':
22911
+ if (subscription.callbacks.size === 0) {
22912
+ /**
22913
+ * You can end up here when:
22914
+ *
22915
+ * - a subscription has recently unsubscribed
22916
+ * without having new callbacks added to it
22917
+ * while the unsubscribe was in flight, or
22918
+ * - when a pending subscription has its
22919
+ * listeners removed before a request was
22920
+ * sent to the server.
22921
+ *
22922
+ * Being that nobody is interested in this
22923
+ * subscription any longer, delete it.
22924
+ */
22925
+ delete this._subscriptionsByHash[hash];
22926
+
22927
+ if (subscription.state === 'unsubscribed') {
22928
+ delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
22929
+ }
23107
22930
 
23108
- this._subscribe(sub, 'slotSubscribe', []);
23109
- }
22931
+ await this._updateSubscriptions();
22932
+ return;
22933
+ }
23110
22934
 
23111
- for (let id of slotUpdateKeys) {
23112
- const sub = this._slotUpdateSubscriptions[id];
22935
+ await (async () => {
22936
+ const {
22937
+ args,
22938
+ method
22939
+ } = subscription;
23113
22940
 
23114
- this._subscribe(sub, 'slotsUpdatesSubscribe', []);
23115
- }
23116
-
23117
- for (let id of signatureKeys) {
23118
- const sub = this._signatureSubscriptions[id];
23119
- const args = [sub.signature];
23120
- if (sub.options) args.push(sub.options);
22941
+ try {
22942
+ this._subscriptionsByHash[hash] = { ...subscription,
22943
+ state: 'subscribing'
22944
+ };
22945
+ const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
22946
+ this._subscriptionsByHash[hash] = { ...subscription,
22947
+ serverSubscriptionId,
22948
+ state: 'subscribed'
22949
+ };
22950
+ this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
22951
+ await this._updateSubscriptions();
22952
+ } catch (e) {
22953
+ if (e instanceof Error) {
22954
+ console.error(`${method} error for argument`, args, e.message);
22955
+ }
22956
+
22957
+ if (!isCurrentConnectionStillActive()) {
22958
+ return;
22959
+ } // TODO: Maybe add an 'errored' state or a retry limit?
23121
22960
 
23122
- this._subscribe(sub, 'signatureSubscribe', args);
23123
- }
23124
22961
 
23125
- for (let id of rootKeys) {
23126
- const sub = this._rootSubscriptions[id];
22962
+ this._subscriptionsByHash[hash] = { ...subscription,
22963
+ state: 'pending'
22964
+ };
22965
+ await this._updateSubscriptions();
22966
+ }
22967
+ })();
22968
+ break;
23127
22969
 
23128
- this._subscribe(sub, 'rootSubscribe', []);
23129
- }
22970
+ case 'subscribed':
22971
+ if (subscription.callbacks.size === 0) {
22972
+ // By the time we successfully set up a subscription
22973
+ // with the server, the client stopped caring about it.
22974
+ // Tear it down now.
22975
+ await (async () => {
22976
+ const {
22977
+ serverSubscriptionId,
22978
+ unsubscribeMethod
22979
+ } = subscription;
22980
+
22981
+ if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
22982
+ /**
22983
+ * Special case.
22984
+ * If we're dealing with a subscription that has been auto-
22985
+ * disposed by the RPC, then we can skip the RPC call to
22986
+ * tear down the subscription here.
22987
+ *
22988
+ * NOTE: There is a proposal to eliminate this special case, here:
22989
+ * https://github.com/solana-labs/solana/issues/18892
22990
+ */
22991
+ this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
22992
+ } else {
22993
+ this._subscriptionsByHash[hash] = { ...subscription,
22994
+ state: 'unsubscribing'
22995
+ };
22996
+
22997
+ try {
22998
+ await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
22999
+ } catch (e) {
23000
+ if (e instanceof Error) {
23001
+ console.error(`${unsubscribeMethod} error:`, e.message);
23002
+ }
23003
+
23004
+ if (!isCurrentConnectionStillActive()) {
23005
+ return;
23006
+ } // TODO: Maybe add an 'errored' state or a retry limit?
23007
+
23008
+
23009
+ this._subscriptionsByHash[hash] = { ...subscription,
23010
+ state: 'subscribed'
23011
+ };
23012
+ await this._updateSubscriptions();
23013
+ return;
23014
+ }
23015
+ }
23130
23016
 
23131
- for (let id of logsKeys) {
23132
- const sub = this._logsSubscriptions[id];
23133
- let filter;
23017
+ this._subscriptionsByHash[hash] = { ...subscription,
23018
+ state: 'unsubscribed'
23019
+ };
23020
+ await this._updateSubscriptions();
23021
+ })();
23022
+ }
23134
23023
 
23135
- if (typeof sub.filter === 'object') {
23136
- filter = {
23137
- mentions: [sub.filter.toString()]
23138
- };
23139
- } else {
23140
- filter = sub.filter;
23024
+ break;
23141
23025
  }
23026
+ }));
23027
+ }
23028
+ /**
23029
+ * @internal
23030
+ */
23142
23031
 
23143
- this._subscribe(sub, 'logsSubscribe', this._buildArgs([filter], sub.commitment));
23032
+
23033
+ _handleServerNotification(serverSubscriptionId, callbackArgs) {
23034
+ const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
23035
+
23036
+ if (callbacks === undefined) {
23037
+ return;
23144
23038
  }
23039
+
23040
+ callbacks.forEach(cb => {
23041
+ try {
23042
+ cb( // I failed to find a way to convince TypeScript that `cb` is of type
23043
+ // `TCallback` which is certainly compatible with `Parameters<TCallback>`.
23044
+ // See https://github.com/microsoft/TypeScript/issues/47615
23045
+ // @ts-ignore
23046
+ ...callbackArgs);
23047
+ } catch (e) {
23048
+ console.error(e);
23049
+ }
23050
+ });
23145
23051
  }
23146
23052
  /**
23147
23053
  * @internal
@@ -23149,14 +23055,71 @@ var solanaWeb3 = (function (exports) {
23149
23055
 
23150
23056
 
23151
23057
  _wsOnAccountNotification(notification) {
23152
- const res = create(notification, AccountNotificationResult);
23058
+ const {
23059
+ result,
23060
+ subscription
23061
+ } = create(notification, AccountNotificationResult);
23153
23062
 
23154
- for (const sub of Object.values(this._accountChangeSubscriptions)) {
23155
- if (sub.subscriptionId === res.subscription) {
23156
- sub.callback(res.result.value, res.result.context);
23157
- return;
23158
- }
23063
+ this._handleServerNotification(subscription, [result.value, result.context]);
23064
+ }
23065
+ /**
23066
+ * @internal
23067
+ */
23068
+
23069
+
23070
+ _makeSubscription(subscriptionConfig,
23071
+ /**
23072
+ * When preparing `args` for a call to `_makeSubscription`, be sure
23073
+ * to carefully apply a default `commitment` property, if necessary.
23074
+ *
23075
+ * - If the user supplied a `commitment` use that.
23076
+ * - Otherwise, if the `Connection::commitment` is set, use that.
23077
+ * - Otherwise, set it to the RPC server default: `finalized`.
23078
+ *
23079
+ * This is extremely important to ensure that these two fundamentally
23080
+ * identical subscriptions produce the same identifying hash:
23081
+ *
23082
+ * - A subscription made without specifying a commitment.
23083
+ * - A subscription made where the commitment specified is the same
23084
+ * as the default applied to the subscription above.
23085
+ *
23086
+ * Example; these two subscriptions must produce the same hash:
23087
+ *
23088
+ * - An `accountSubscribe` subscription for `'PUBKEY'`
23089
+ * - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
23090
+ * `'finalized'`.
23091
+ *
23092
+ * See the 'making a subscription with defaulted params omitted' test
23093
+ * in `connection-subscriptions.ts` for more.
23094
+ */
23095
+ args) {
23096
+ const clientSubscriptionId = this._nextClientSubscriptionId++;
23097
+ const hash = fastStableStringify$1([subscriptionConfig.method, args], true
23098
+ /* isArrayProp */
23099
+ );
23100
+ const existingSubscription = this._subscriptionsByHash[hash];
23101
+
23102
+ if (existingSubscription === undefined) {
23103
+ this._subscriptionsByHash[hash] = { ...subscriptionConfig,
23104
+ args,
23105
+ callbacks: new Set([subscriptionConfig.callback]),
23106
+ state: 'pending'
23107
+ };
23108
+ } else {
23109
+ existingSubscription.callbacks.add(subscriptionConfig.callback);
23159
23110
  }
23111
+
23112
+ this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
23113
+ delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
23114
+ const subscription = this._subscriptionsByHash[hash];
23115
+ assert$c(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
23116
+ subscription.callbacks.delete(subscriptionConfig.callback);
23117
+ await this._updateSubscriptions();
23118
+ };
23119
+
23120
+ this._updateSubscriptions();
23121
+
23122
+ return clientSubscriptionId;
23160
23123
  }
23161
23124
  /**
23162
23125
  * Register a callback to be invoked whenever the specified account changes
@@ -23169,35 +23132,24 @@ var solanaWeb3 = (function (exports) {
23169
23132
 
23170
23133
 
23171
23134
  onAccountChange(publicKey, callback, commitment) {
23172
- const id = ++this._accountChangeSubscriptionCounter;
23173
- this._accountChangeSubscriptions[id] = {
23174
- publicKey: publicKey.toBase58(),
23175
- callback,
23176
- commitment,
23177
- subscriptionId: null
23178
- };
23179
-
23180
- this._updateSubscriptions();
23135
+ const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
23136
+ 'base64');
23181
23137
 
23182
- return id;
23138
+ return this._makeSubscription({
23139
+ callback,
23140
+ method: 'accountSubscribe',
23141
+ unsubscribeMethod: 'accountUnsubscribe'
23142
+ }, args);
23183
23143
  }
23184
23144
  /**
23185
23145
  * Deregister an account notification callback
23186
23146
  *
23187
- * @param id subscription id to deregister
23147
+ * @param id client subscription id to deregister
23188
23148
  */
23189
23149
 
23190
23150
 
23191
- async removeAccountChangeListener(id) {
23192
- if (this._accountChangeSubscriptions[id]) {
23193
- const subInfo = this._accountChangeSubscriptions[id];
23194
- delete this._accountChangeSubscriptions[id];
23195
- await this._unsubscribe(subInfo, 'accountUnsubscribe');
23196
-
23197
- this._updateSubscriptions();
23198
- } else {
23199
- console.warn(createSubscriptionWarningMessage(id, 'account change'));
23200
- }
23151
+ async removeAccountChangeListener(clientSubscriptionId) {
23152
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
23201
23153
  }
23202
23154
  /**
23203
23155
  * @internal
@@ -23205,21 +23157,15 @@ var solanaWeb3 = (function (exports) {
23205
23157
 
23206
23158
 
23207
23159
  _wsOnProgramAccountNotification(notification) {
23208
- const res = create(notification, ProgramAccountNotificationResult);
23160
+ const {
23161
+ result,
23162
+ subscription
23163
+ } = create(notification, ProgramAccountNotificationResult);
23209
23164
 
23210
- for (const sub of Object.values(this._programAccountChangeSubscriptions)) {
23211
- if (sub.subscriptionId === res.subscription) {
23212
- const {
23213
- value,
23214
- context
23215
- } = res.result;
23216
- sub.callback({
23217
- accountId: value.pubkey,
23218
- accountInfo: value.account
23219
- }, context);
23220
- return;
23221
- }
23222
- }
23165
+ this._handleServerNotification(subscription, [{
23166
+ accountId: result.value.pubkey,
23167
+ accountInfo: result.value.account
23168
+ }, result.context]);
23223
23169
  }
23224
23170
  /**
23225
23171
  * Register a callback to be invoked whenever accounts owned by the
@@ -23234,36 +23180,30 @@ var solanaWeb3 = (function (exports) {
23234
23180
 
23235
23181
 
23236
23182
  onProgramAccountChange(programId, callback, commitment, filters) {
23237
- const id = ++this._programAccountChangeSubscriptionCounter;
23238
- this._programAccountChangeSubscriptions[id] = {
23239
- programId: programId.toBase58(),
23240
- callback,
23241
- commitment,
23242
- subscriptionId: null,
23243
- filters
23244
- };
23245
-
23246
- this._updateSubscriptions();
23183
+ const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
23184
+ 'base64'
23185
+ /* encoding */
23186
+ , filters ? {
23187
+ filters: filters
23188
+ } : undefined
23189
+ /* extra */
23190
+ );
23247
23191
 
23248
- return id;
23192
+ return this._makeSubscription({
23193
+ callback,
23194
+ method: 'programSubscribe',
23195
+ unsubscribeMethod: 'programUnsubscribe'
23196
+ }, args);
23249
23197
  }
23250
23198
  /**
23251
23199
  * Deregister an account notification callback
23252
23200
  *
23253
- * @param id subscription id to deregister
23201
+ * @param id client subscription id to deregister
23254
23202
  */
23255
23203
 
23256
23204
 
23257
- async removeProgramAccountChangeListener(id) {
23258
- if (this._programAccountChangeSubscriptions[id]) {
23259
- const subInfo = this._programAccountChangeSubscriptions[id];
23260
- delete this._programAccountChangeSubscriptions[id];
23261
- await this._unsubscribe(subInfo, 'programUnsubscribe');
23262
-
23263
- this._updateSubscriptions();
23264
- } else {
23265
- console.warn(createSubscriptionWarningMessage(id, 'program account change'));
23266
- }
23205
+ async removeProgramAccountChangeListener(clientSubscriptionId) {
23206
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
23267
23207
  }
23268
23208
  /**
23269
23209
  * Registers a callback to be invoked whenever logs are emitted.
@@ -23271,35 +23211,26 @@ var solanaWeb3 = (function (exports) {
23271
23211
 
23272
23212
 
23273
23213
  onLogs(filter, callback, commitment) {
23274
- const id = ++this._logsSubscriptionCounter;
23275
- this._logsSubscriptions[id] = {
23276
- filter,
23277
- callback,
23278
- commitment,
23279
- subscriptionId: null
23280
- };
23281
-
23282
- this._updateSubscriptions();
23214
+ const args = this._buildArgs([typeof filter === 'object' ? {
23215
+ mentions: [filter.toString()]
23216
+ } : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
23217
+ );
23283
23218
 
23284
- return id;
23219
+ return this._makeSubscription({
23220
+ callback,
23221
+ method: 'logsSubscribe',
23222
+ unsubscribeMethod: 'logsUnsubscribe'
23223
+ }, args);
23285
23224
  }
23286
23225
  /**
23287
23226
  * Deregister a logs callback.
23288
23227
  *
23289
- * @param id subscription id to deregister.
23228
+ * @param id client subscription id to deregister.
23290
23229
  */
23291
23230
 
23292
23231
 
23293
- async removeOnLogsListener(id) {
23294
- if (this._logsSubscriptions[id]) {
23295
- const subInfo = this._logsSubscriptions[id];
23296
- delete this._logsSubscriptions[id];
23297
- await this._unsubscribe(subInfo, 'logsUnsubscribe');
23298
-
23299
- this._updateSubscriptions();
23300
- } else {
23301
- console.warn(createSubscriptionWarningMessage(id, 'logs'));
23302
- }
23232
+ async removeOnLogsListener(clientSubscriptionId) {
23233
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
23303
23234
  }
23304
23235
  /**
23305
23236
  * @internal
@@ -23307,17 +23238,12 @@ var solanaWeb3 = (function (exports) {
23307
23238
 
23308
23239
 
23309
23240
  _wsOnLogsNotification(notification) {
23310
- const res = create(notification, LogsNotificationResult);
23311
- const keys = Object.keys(this._logsSubscriptions).map(Number);
23312
-
23313
- for (let id of keys) {
23314
- const sub = this._logsSubscriptions[id];
23241
+ const {
23242
+ result,
23243
+ subscription
23244
+ } = create(notification, LogsNotificationResult);
23315
23245
 
23316
- if (sub.subscriptionId === res.subscription) {
23317
- sub.callback(res.result.value, res.result.context);
23318
- return;
23319
- }
23320
- }
23246
+ this._handleServerNotification(subscription, [result.value, result.context]);
23321
23247
  }
23322
23248
  /**
23323
23249
  * @internal
@@ -23325,14 +23251,12 @@ var solanaWeb3 = (function (exports) {
23325
23251
 
23326
23252
 
23327
23253
  _wsOnSlotNotification(notification) {
23328
- const res = create(notification, SlotNotificationResult);
23254
+ const {
23255
+ result,
23256
+ subscription
23257
+ } = create(notification, SlotNotificationResult);
23329
23258
 
23330
- for (const sub of Object.values(this._slotSubscriptions)) {
23331
- if (sub.subscriptionId === res.subscription) {
23332
- sub.callback(res.result);
23333
- return;
23334
- }
23335
- }
23259
+ this._handleServerNotification(subscription, [result]);
23336
23260
  }
23337
23261
  /**
23338
23262
  * Register a callback to be invoked upon slot changes
@@ -23343,33 +23267,23 @@ var solanaWeb3 = (function (exports) {
23343
23267
 
23344
23268
 
23345
23269
  onSlotChange(callback) {
23346
- const id = ++this._slotSubscriptionCounter;
23347
- this._slotSubscriptions[id] = {
23270
+ return this._makeSubscription({
23348
23271
  callback,
23349
- subscriptionId: null
23350
- };
23351
-
23352
- this._updateSubscriptions();
23353
-
23354
- return id;
23272
+ method: 'slotSubscribe',
23273
+ unsubscribeMethod: 'slotUnsubscribe'
23274
+ }, []
23275
+ /* args */
23276
+ );
23355
23277
  }
23356
23278
  /**
23357
23279
  * Deregister a slot notification callback
23358
23280
  *
23359
- * @param id subscription id to deregister
23281
+ * @param id client subscription id to deregister
23360
23282
  */
23361
23283
 
23362
23284
 
23363
- async removeSlotChangeListener(id) {
23364
- if (this._slotSubscriptions[id]) {
23365
- const subInfo = this._slotSubscriptions[id];
23366
- delete this._slotSubscriptions[id];
23367
- await this._unsubscribe(subInfo, 'slotUnsubscribe');
23368
-
23369
- this._updateSubscriptions();
23370
- } else {
23371
- console.warn(createSubscriptionWarningMessage(id, 'slot change'));
23372
- }
23285
+ async removeSlotChangeListener(clientSubscriptionId) {
23286
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
23373
23287
  }
23374
23288
  /**
23375
23289
  * @internal
@@ -23377,14 +23291,12 @@ var solanaWeb3 = (function (exports) {
23377
23291
 
23378
23292
 
23379
23293
  _wsOnSlotUpdatesNotification(notification) {
23380
- const res = create(notification, SlotUpdateNotificationResult);
23294
+ const {
23295
+ result,
23296
+ subscription
23297
+ } = create(notification, SlotUpdateNotificationResult);
23381
23298
 
23382
- for (const sub of Object.values(this._slotUpdateSubscriptions)) {
23383
- if (sub.subscriptionId === res.subscription) {
23384
- sub.callback(res.result);
23385
- return;
23386
- }
23387
- }
23299
+ this._handleServerNotification(subscription, [result]);
23388
23300
  }
23389
23301
  /**
23390
23302
  * Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
@@ -23396,32 +23308,36 @@ var solanaWeb3 = (function (exports) {
23396
23308
 
23397
23309
 
23398
23310
  onSlotUpdate(callback) {
23399
- const id = ++this._slotUpdateSubscriptionCounter;
23400
- this._slotUpdateSubscriptions[id] = {
23311
+ return this._makeSubscription({
23401
23312
  callback,
23402
- subscriptionId: null
23403
- };
23404
-
23405
- this._updateSubscriptions();
23406
-
23407
- return id;
23313
+ method: 'slotsUpdatesSubscribe',
23314
+ unsubscribeMethod: 'slotsUpdatesUnsubscribe'
23315
+ }, []
23316
+ /* args */
23317
+ );
23408
23318
  }
23409
23319
  /**
23410
23320
  * Deregister a slot update notification callback
23411
23321
  *
23412
- * @param id subscription id to deregister
23322
+ * @param id client subscription id to deregister
23413
23323
  */
23414
23324
 
23415
23325
 
23416
- async removeSlotUpdateListener(id) {
23417
- if (this._slotUpdateSubscriptions[id]) {
23418
- const subInfo = this._slotUpdateSubscriptions[id];
23419
- delete this._slotUpdateSubscriptions[id];
23420
- await this._unsubscribe(subInfo, 'slotsUpdatesUnsubscribe');
23326
+ async removeSlotUpdateListener(clientSubscriptionId) {
23327
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
23328
+ }
23329
+ /**
23330
+ * @internal
23331
+ */
23421
23332
 
23422
- this._updateSubscriptions();
23333
+
23334
+ async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
23335
+ const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
23336
+
23337
+ if (dispose) {
23338
+ await dispose();
23423
23339
  } else {
23424
- console.warn(createSubscriptionWarningMessage(id, 'slot update'));
23340
+ console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
23425
23341
  }
23426
23342
  }
23427
23343
 
@@ -23468,30 +23384,34 @@ var solanaWeb3 = (function (exports) {
23468
23384
 
23469
23385
 
23470
23386
  _wsOnSignatureNotification(notification) {
23471
- const res = create(notification, SignatureNotificationResult);
23472
-
23473
- for (const [id, sub] of Object.entries(this._signatureSubscriptions)) {
23474
- if (sub.subscriptionId === res.subscription) {
23475
- if (res.result.value === 'receivedSignature') {
23476
- sub.callback({
23477
- type: 'received'
23478
- }, res.result.context);
23479
- } else {
23480
- // Signatures subscriptions are auto-removed by the RPC service so
23481
- // no need to explicitly send an unsubscribe message
23482
- delete this._signatureSubscriptions[Number(id)];
23483
-
23484
- this._updateSubscriptions();
23485
-
23486
- sub.callback({
23487
- type: 'status',
23488
- result: res.result.value
23489
- }, res.result.context);
23490
- }
23491
-
23492
- return;
23493
- }
23494
- }
23387
+ const {
23388
+ result,
23389
+ subscription
23390
+ } = create(notification, SignatureNotificationResult);
23391
+
23392
+ if (result.value !== 'receivedSignature') {
23393
+ /**
23394
+ * Special case.
23395
+ * After a signature is processed, RPCs automatically dispose of the
23396
+ * subscription on the server side. We need to track which of these
23397
+ * subscriptions have been disposed in such a way, so that we know
23398
+ * whether the client is dealing with a not-yet-processed signature
23399
+ * (in which case we must tear down the server subscription) or an
23400
+ * already-processed signature (in which case the client can simply
23401
+ * clear out the subscription locally without telling the server).
23402
+ *
23403
+ * NOTE: There is a proposal to eliminate this special case, here:
23404
+ * https://github.com/solana-labs/solana/issues/18892
23405
+ */
23406
+ this._subscriptionsAutoDisposedByRpc.add(subscription);
23407
+ }
23408
+
23409
+ this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
23410
+ type: 'received'
23411
+ }, result.context] : [{
23412
+ type: 'status',
23413
+ result: result.value
23414
+ }, result.context]);
23495
23415
  }
23496
23416
  /**
23497
23417
  * Register a callback to be invoked upon signature updates
@@ -23504,23 +23424,26 @@ var solanaWeb3 = (function (exports) {
23504
23424
 
23505
23425
 
23506
23426
  onSignature(signature, callback, commitment) {
23507
- const id = ++this._signatureSubscriptionCounter;
23508
- this._signatureSubscriptions[id] = {
23509
- signature,
23427
+ const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
23428
+ );
23429
+
23430
+ const clientSubscriptionId = this._makeSubscription({
23510
23431
  callback: (notification, context) => {
23511
23432
  if (notification.type === 'status') {
23512
- callback(notification.result, context);
23433
+ callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
23434
+ // so no need to explicitly send an unsubscribe message.
23435
+
23436
+ try {
23437
+ this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
23438
+ } catch {// Already removed.
23439
+ }
23513
23440
  }
23514
23441
  },
23515
- options: {
23516
- commitment
23517
- },
23518
- subscriptionId: null
23519
- };
23520
-
23521
- this._updateSubscriptions();
23442
+ method: 'signatureSubscribe',
23443
+ unsubscribeMethod: 'signatureUnsubscribe'
23444
+ }, args);
23522
23445
 
23523
- return id;
23446
+ return clientSubscriptionId;
23524
23447
  }
23525
23448
  /**
23526
23449
  * Register a callback to be invoked when a transaction is
@@ -23535,35 +23458,43 @@ var solanaWeb3 = (function (exports) {
23535
23458
 
23536
23459
 
23537
23460
  onSignatureWithOptions(signature, callback, options) {
23538
- const id = ++this._signatureSubscriptionCounter;
23539
- this._signatureSubscriptions[id] = {
23540
- signature,
23541
- callback,
23542
- options,
23543
- subscriptionId: null
23461
+ const {
23462
+ commitment,
23463
+ ...extra
23464
+ } = { ...options,
23465
+ commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
23466
+
23544
23467
  };
23545
23468
 
23546
- this._updateSubscriptions();
23469
+ const args = this._buildArgs([signature], commitment, undefined
23470
+ /* encoding */
23471
+ , extra);
23547
23472
 
23548
- return id;
23473
+ const clientSubscriptionId = this._makeSubscription({
23474
+ callback: (notification, context) => {
23475
+ callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
23476
+ // so no need to explicitly send an unsubscribe message.
23477
+
23478
+ try {
23479
+ this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
23480
+ } catch {// Already removed.
23481
+ }
23482
+ },
23483
+ method: 'signatureSubscribe',
23484
+ unsubscribeMethod: 'signatureUnsubscribe'
23485
+ }, args);
23486
+
23487
+ return clientSubscriptionId;
23549
23488
  }
23550
23489
  /**
23551
23490
  * Deregister a signature notification callback
23552
23491
  *
23553
- * @param id subscription id to deregister
23492
+ * @param id client subscription id to deregister
23554
23493
  */
23555
23494
 
23556
23495
 
23557
- async removeSignatureListener(id) {
23558
- if (this._signatureSubscriptions[id]) {
23559
- const subInfo = this._signatureSubscriptions[id];
23560
- delete this._signatureSubscriptions[id];
23561
- await this._unsubscribe(subInfo, 'signatureUnsubscribe');
23562
-
23563
- this._updateSubscriptions();
23564
- } else {
23565
- console.warn(createSubscriptionWarningMessage(id, 'signature result'));
23566
- }
23496
+ async removeSignatureListener(clientSubscriptionId) {
23497
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
23567
23498
  }
23568
23499
  /**
23569
23500
  * @internal
@@ -23571,14 +23502,12 @@ var solanaWeb3 = (function (exports) {
23571
23502
 
23572
23503
 
23573
23504
  _wsOnRootNotification(notification) {
23574
- const res = create(notification, RootNotificationResult);
23505
+ const {
23506
+ result,
23507
+ subscription
23508
+ } = create(notification, RootNotificationResult);
23575
23509
 
23576
- for (const sub of Object.values(this._rootSubscriptions)) {
23577
- if (sub.subscriptionId === res.subscription) {
23578
- sub.callback(res.result);
23579
- return;
23580
- }
23581
- }
23510
+ this._handleServerNotification(subscription, [result]);
23582
23511
  }
23583
23512
  /**
23584
23513
  * Register a callback to be invoked upon root changes
@@ -23589,33 +23518,23 @@ var solanaWeb3 = (function (exports) {
23589
23518
 
23590
23519
 
23591
23520
  onRootChange(callback) {
23592
- const id = ++this._rootSubscriptionCounter;
23593
- this._rootSubscriptions[id] = {
23521
+ return this._makeSubscription({
23594
23522
  callback,
23595
- subscriptionId: null
23596
- };
23597
-
23598
- this._updateSubscriptions();
23599
-
23600
- return id;
23523
+ method: 'rootSubscribe',
23524
+ unsubscribeMethod: 'rootUnsubscribe'
23525
+ }, []
23526
+ /* args */
23527
+ );
23601
23528
  }
23602
23529
  /**
23603
23530
  * Deregister a root notification callback
23604
23531
  *
23605
- * @param id subscription id to deregister
23532
+ * @param id client subscription id to deregister
23606
23533
  */
23607
23534
 
23608
23535
 
23609
- async removeRootChangeListener(id) {
23610
- if (this._rootSubscriptions[id]) {
23611
- const subInfo = this._rootSubscriptions[id];
23612
- delete this._rootSubscriptions[id];
23613
- await this._unsubscribe(subInfo, 'rootUnsubscribe');
23614
-
23615
- this._updateSubscriptions();
23616
- } else {
23617
- console.warn(createSubscriptionWarningMessage(id, 'root change'));
23618
- }
23536
+ async removeRootChangeListener(clientSubscriptionId) {
23537
+ await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
23619
23538
  }
23620
23539
 
23621
23540
  }
@@ -30123,6 +30042,7 @@ var solanaWeb3 = (function (exports) {
30123
30042
  exports.NonceAccount = NonceAccount;
30124
30043
  exports.PACKET_DATA_SIZE = PACKET_DATA_SIZE;
30125
30044
  exports.PublicKey = PublicKey;
30045
+ exports.SIGNATURE_LENGTH_IN_BYTES = SIGNATURE_LENGTH_IN_BYTES;
30126
30046
  exports.SOLANA_SCHEMA = SOLANA_SCHEMA;
30127
30047
  exports.STAKE_CONFIG_ID = STAKE_CONFIG_ID;
30128
30048
  exports.STAKE_INSTRUCTION_LAYOUTS = STAKE_INSTRUCTION_LAYOUTS;