@solana/web3.js 1.41.1 → 1.41.2
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.browser.cjs.js +501 -371
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +501 -371
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +501 -371
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +37 -22
- package/lib/index.esm.js +501 -371
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +533 -612
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +1 -23
- package/lib/index.iife.min.js.map +1 -1
- package/package.json +8 -5
- package/src/connection.ts +657 -486
package/lib/index.browser.esm.js
CHANGED
|
@@ -4761,6 +4761,82 @@ module.exports = exports;
|
|
|
4761
4761
|
|
|
4762
4762
|
var crossFetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfill.exports);
|
|
4763
4763
|
|
|
4764
|
+
var objToString = Object.prototype.toString;
|
|
4765
|
+
var objKeys = Object.keys || function(obj) {
|
|
4766
|
+
var keys = [];
|
|
4767
|
+
for (var name in obj) {
|
|
4768
|
+
keys.push(name);
|
|
4769
|
+
}
|
|
4770
|
+
return keys;
|
|
4771
|
+
};
|
|
4772
|
+
|
|
4773
|
+
function stringify(val, isArrayProp) {
|
|
4774
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
4775
|
+
if (val === true) {
|
|
4776
|
+
return "true";
|
|
4777
|
+
}
|
|
4778
|
+
if (val === false) {
|
|
4779
|
+
return "false";
|
|
4780
|
+
}
|
|
4781
|
+
switch (typeof val) {
|
|
4782
|
+
case "object":
|
|
4783
|
+
if (val === null) {
|
|
4784
|
+
return null;
|
|
4785
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
4786
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
4787
|
+
} else {
|
|
4788
|
+
toStr = objToString.call(val);
|
|
4789
|
+
if (toStr === "[object Array]") {
|
|
4790
|
+
str = '[';
|
|
4791
|
+
max = val.length - 1;
|
|
4792
|
+
for(i = 0; i < max; i++) {
|
|
4793
|
+
str += stringify(val[i], true) + ',';
|
|
4794
|
+
}
|
|
4795
|
+
if (max > -1) {
|
|
4796
|
+
str += stringify(val[i], true);
|
|
4797
|
+
}
|
|
4798
|
+
return str + ']';
|
|
4799
|
+
} else if (toStr === "[object Object]") {
|
|
4800
|
+
// only object is left
|
|
4801
|
+
keys = objKeys(val).sort();
|
|
4802
|
+
max = keys.length;
|
|
4803
|
+
str = "";
|
|
4804
|
+
i = 0;
|
|
4805
|
+
while (i < max) {
|
|
4806
|
+
key = keys[i];
|
|
4807
|
+
propVal = stringify(val[key], false);
|
|
4808
|
+
if (propVal !== undefined) {
|
|
4809
|
+
if (str) {
|
|
4810
|
+
str += ',';
|
|
4811
|
+
}
|
|
4812
|
+
str += JSON.stringify(key) + ':' + propVal;
|
|
4813
|
+
}
|
|
4814
|
+
i++;
|
|
4815
|
+
}
|
|
4816
|
+
return '{' + str + '}';
|
|
4817
|
+
} else {
|
|
4818
|
+
return JSON.stringify(val);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
case "function":
|
|
4822
|
+
case "undefined":
|
|
4823
|
+
return isArrayProp ? null : undefined;
|
|
4824
|
+
case "string":
|
|
4825
|
+
return JSON.stringify(val);
|
|
4826
|
+
default:
|
|
4827
|
+
return isFinite(val) ? val : null;
|
|
4828
|
+
}
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
var fastStableStringify = function(val) {
|
|
4832
|
+
var returnVal = stringify(val, false);
|
|
4833
|
+
if (returnVal !== undefined) {
|
|
4834
|
+
return ''+ returnVal;
|
|
4835
|
+
}
|
|
4836
|
+
};
|
|
4837
|
+
|
|
4838
|
+
var fastStableStringify$1 = fastStableStringify;
|
|
4839
|
+
|
|
4764
4840
|
const MINIMUM_SLOT_PER_EPOCH = 32; // Returns the number of trailing zeros in the binary representation of self.
|
|
4765
4841
|
|
|
4766
4842
|
function trailingZeros(n) {
|
|
@@ -4927,6 +5003,12 @@ const BufferFromRawAccountData = coerce(instance(Buffer), RawAccountDataResult,
|
|
|
4927
5003
|
*/
|
|
4928
5004
|
|
|
4929
5005
|
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|
5006
|
+
/**
|
|
5007
|
+
* HACK.
|
|
5008
|
+
* Copied from rpc-websockets/dist/lib/client.
|
|
5009
|
+
* Otherwise, `yarn build` fails with:
|
|
5010
|
+
* https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
|
|
5011
|
+
*/
|
|
4930
5012
|
|
|
4931
5013
|
/**
|
|
4932
5014
|
* @internal
|
|
@@ -5795,14 +5877,9 @@ const LogsNotificationResult = type({
|
|
|
5795
5877
|
* Filter for log subscriptions.
|
|
5796
5878
|
*/
|
|
5797
5879
|
|
|
5798
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5799
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5800
|
-
}
|
|
5801
5880
|
/**
|
|
5802
5881
|
* A connection to a fullnode JSON RPC endpoint
|
|
5803
5882
|
*/
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
5883
|
class Connection {
|
|
5807
5884
|
/** @internal */
|
|
5808
5885
|
|
|
@@ -5826,21 +5903,13 @@ class Connection {
|
|
|
5826
5903
|
|
|
5827
5904
|
/** @internal */
|
|
5828
5905
|
|
|
5829
|
-
/** @internal
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
|
|
5836
|
-
|
|
5837
|
-
/** @internal */
|
|
5838
|
-
|
|
5839
|
-
/** @internal */
|
|
5840
|
-
|
|
5841
|
-
/** @internal */
|
|
5842
|
-
|
|
5843
|
-
/** @internal */
|
|
5906
|
+
/** @internal
|
|
5907
|
+
* A number that we increment every time an active connection closes.
|
|
5908
|
+
* Used to determine whether the same socket connection that was open
|
|
5909
|
+
* when an async operation started is the same one that's active when
|
|
5910
|
+
* its continuation fires.
|
|
5911
|
+
*
|
|
5912
|
+
*/
|
|
5844
5913
|
|
|
5845
5914
|
/** @internal */
|
|
5846
5915
|
|
|
@@ -5856,7 +5925,19 @@ class Connection {
|
|
|
5856
5925
|
|
|
5857
5926
|
/** @internal */
|
|
5858
5927
|
|
|
5859
|
-
/**
|
|
5928
|
+
/**
|
|
5929
|
+
* Special case.
|
|
5930
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
5931
|
+
* subscription on the server side. We need to track which of these
|
|
5932
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
5933
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
5934
|
+
* (in which case we must tear down the server subscription) or an
|
|
5935
|
+
* already-processed signature (in which case the client can simply
|
|
5936
|
+
* clear out the subscription locally without telling the server).
|
|
5937
|
+
*
|
|
5938
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
5939
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
5940
|
+
*/
|
|
5860
5941
|
|
|
5861
5942
|
/** @internal */
|
|
5862
5943
|
|
|
@@ -5878,6 +5959,7 @@ class Connection {
|
|
|
5878
5959
|
this._rpcWebSocketConnected = false;
|
|
5879
5960
|
this._rpcWebSocketHeartbeat = null;
|
|
5880
5961
|
this._rpcWebSocketIdleTimeout = null;
|
|
5962
|
+
this._rpcWebSocketGeneration = 0;
|
|
5881
5963
|
this._disableBlockhashCaching = false;
|
|
5882
5964
|
this._pollingBlockhash = false;
|
|
5883
5965
|
this._blockhashInfo = {
|
|
@@ -5886,20 +5968,11 @@ class Connection {
|
|
|
5886
5968
|
transactionSignatures: [],
|
|
5887
5969
|
simulatedSignatures: []
|
|
5888
5970
|
};
|
|
5889
|
-
this.
|
|
5890
|
-
this.
|
|
5891
|
-
this.
|
|
5892
|
-
this.
|
|
5893
|
-
this.
|
|
5894
|
-
this._rootSubscriptions = {};
|
|
5895
|
-
this._signatureSubscriptionCounter = 0;
|
|
5896
|
-
this._signatureSubscriptions = {};
|
|
5897
|
-
this._slotSubscriptionCounter = 0;
|
|
5898
|
-
this._slotSubscriptions = {};
|
|
5899
|
-
this._logsSubscriptionCounter = 0;
|
|
5900
|
-
this._logsSubscriptions = {};
|
|
5901
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5902
|
-
this._slotUpdateSubscriptions = {};
|
|
5971
|
+
this._nextClientSubscriptionId = 0;
|
|
5972
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
5973
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
5974
|
+
this._subscriptionsByHash = {};
|
|
5975
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5903
5976
|
let url = new URL(endpoint);
|
|
5904
5977
|
const useHttps = url.protocol === 'https:';
|
|
5905
5978
|
let wsEndpoint;
|
|
@@ -7667,6 +7740,8 @@ class Connection {
|
|
|
7667
7740
|
|
|
7668
7741
|
|
|
7669
7742
|
_wsOnClose(code) {
|
|
7743
|
+
this._rpcWebSocketGeneration++;
|
|
7744
|
+
|
|
7670
7745
|
if (this._rpcWebSocketHeartbeat) {
|
|
7671
7746
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7672
7747
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7680,85 +7755,20 @@ class Connection {
|
|
|
7680
7755
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7681
7756
|
|
|
7682
7757
|
|
|
7683
|
-
this.
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7691
|
-
if (sub.subscriptionId == null) {
|
|
7692
|
-
sub.subscriptionId = 'subscribing';
|
|
7693
|
-
|
|
7694
|
-
try {
|
|
7695
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7696
|
-
|
|
7697
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7698
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7699
|
-
sub.subscriptionId = id;
|
|
7700
|
-
}
|
|
7701
|
-
} catch (err) {
|
|
7702
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7703
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7704
|
-
sub.subscriptionId = null;
|
|
7705
|
-
}
|
|
7706
|
-
|
|
7707
|
-
if (err instanceof Error) {
|
|
7708
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7709
|
-
}
|
|
7710
|
-
}
|
|
7711
|
-
}
|
|
7712
|
-
}
|
|
7713
|
-
/**
|
|
7714
|
-
* @internal
|
|
7715
|
-
*/
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7719
|
-
const subscriptionId = sub.subscriptionId;
|
|
7720
|
-
|
|
7721
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7722
|
-
const unsubscribeId = subscriptionId;
|
|
7723
|
-
|
|
7724
|
-
try {
|
|
7725
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7726
|
-
} catch (err) {
|
|
7727
|
-
if (err instanceof Error) {
|
|
7728
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7729
|
-
}
|
|
7730
|
-
}
|
|
7731
|
-
}
|
|
7732
|
-
}
|
|
7733
|
-
/**
|
|
7734
|
-
* @internal
|
|
7735
|
-
*/
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
_resetSubscriptions() {
|
|
7739
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7740
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7741
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7742
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7743
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7744
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7745
|
-
Object.values(this._slotUpdateSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7758
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
7759
|
+
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
7760
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7761
|
+
state: 'pending'
|
|
7762
|
+
};
|
|
7763
|
+
});
|
|
7746
7764
|
}
|
|
7747
7765
|
/**
|
|
7748
7766
|
* @internal
|
|
7749
7767
|
*/
|
|
7750
7768
|
|
|
7751
7769
|
|
|
7752
|
-
_updateSubscriptions() {
|
|
7753
|
-
|
|
7754
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7755
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7756
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7757
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7758
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7759
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7760
|
-
|
|
7761
|
-
if (accountKeys.length === 0 && programKeys.length === 0 && slotKeys.length === 0 && slotUpdateKeys.length === 0 && signatureKeys.length === 0 && rootKeys.length === 0 && logsKeys.length === 0) {
|
|
7770
|
+
async _updateSubscriptions() {
|
|
7771
|
+
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
7762
7772
|
if (this._rpcWebSocketConnected) {
|
|
7763
7773
|
this._rpcWebSocketConnected = false;
|
|
7764
7774
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7790,60 +7800,167 @@ class Connection {
|
|
|
7790
7800
|
return;
|
|
7791
7801
|
}
|
|
7792
7802
|
|
|
7793
|
-
|
|
7794
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7795
|
-
|
|
7796
|
-
this._subscribe(sub, 'accountSubscribe', this._buildArgs([sub.publicKey], sub.commitment, 'base64'));
|
|
7797
|
-
}
|
|
7803
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7798
7804
|
|
|
7799
|
-
|
|
7800
|
-
|
|
7805
|
+
const isCurrentConnectionStillActive = () => {
|
|
7806
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7807
|
+
};
|
|
7801
7808
|
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7809
|
+
await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
|
|
7810
|
+
// `_updateSubscriptions` recursively when processing the state,
|
|
7811
|
+
// so it's important that we look up the *current* version of
|
|
7812
|
+
// each subscription, every time we process a hash.
|
|
7813
|
+
Object.keys(this._subscriptionsByHash).map(async hash => {
|
|
7814
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7806
7815
|
|
|
7807
|
-
|
|
7808
|
-
|
|
7816
|
+
if (subscription === undefined) {
|
|
7817
|
+
// This entry has since been deleted. Skip.
|
|
7818
|
+
return;
|
|
7819
|
+
}
|
|
7809
7820
|
|
|
7810
|
-
|
|
7811
|
-
|
|
7821
|
+
switch (subscription.state) {
|
|
7822
|
+
case 'pending':
|
|
7823
|
+
case 'unsubscribed':
|
|
7824
|
+
if (subscription.callbacks.size === 0) {
|
|
7825
|
+
/**
|
|
7826
|
+
* You can end up here when:
|
|
7827
|
+
*
|
|
7828
|
+
* - a subscription has recently unsubscribed
|
|
7829
|
+
* without having new callbacks added to it
|
|
7830
|
+
* while the unsubscribe was in flight, or
|
|
7831
|
+
* - when a pending subscription has its
|
|
7832
|
+
* listeners removed before a request was
|
|
7833
|
+
* sent to the server.
|
|
7834
|
+
*
|
|
7835
|
+
* Being that nobody is interested in this
|
|
7836
|
+
* subscription any longer, delete it.
|
|
7837
|
+
*/
|
|
7838
|
+
delete this._subscriptionsByHash[hash];
|
|
7839
|
+
|
|
7840
|
+
if (subscription.state === 'unsubscribed') {
|
|
7841
|
+
delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
|
|
7842
|
+
}
|
|
7812
7843
|
|
|
7813
|
-
|
|
7814
|
-
|
|
7844
|
+
await this._updateSubscriptions();
|
|
7845
|
+
return;
|
|
7846
|
+
}
|
|
7815
7847
|
|
|
7816
|
-
|
|
7817
|
-
|
|
7848
|
+
await (async () => {
|
|
7849
|
+
const {
|
|
7850
|
+
args,
|
|
7851
|
+
method
|
|
7852
|
+
} = subscription;
|
|
7818
7853
|
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7854
|
+
try {
|
|
7855
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7856
|
+
state: 'subscribing'
|
|
7857
|
+
};
|
|
7858
|
+
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
7859
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7860
|
+
serverSubscriptionId,
|
|
7861
|
+
state: 'subscribed'
|
|
7862
|
+
};
|
|
7863
|
+
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
7864
|
+
await this._updateSubscriptions();
|
|
7865
|
+
} catch (e) {
|
|
7866
|
+
if (e instanceof Error) {
|
|
7867
|
+
console.error(`${method} error for argument`, args, e.message);
|
|
7868
|
+
}
|
|
7869
|
+
|
|
7870
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7871
|
+
return;
|
|
7872
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7823
7873
|
|
|
7824
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7825
|
-
}
|
|
7826
7874
|
|
|
7827
|
-
|
|
7828
|
-
|
|
7875
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7876
|
+
state: 'pending'
|
|
7877
|
+
};
|
|
7878
|
+
await this._updateSubscriptions();
|
|
7879
|
+
}
|
|
7880
|
+
})();
|
|
7881
|
+
break;
|
|
7829
7882
|
|
|
7830
|
-
|
|
7831
|
-
|
|
7883
|
+
case 'subscribed':
|
|
7884
|
+
if (subscription.callbacks.size === 0) {
|
|
7885
|
+
// By the time we successfully set up a subscription
|
|
7886
|
+
// with the server, the client stopped caring about it.
|
|
7887
|
+
// Tear it down now.
|
|
7888
|
+
await (async () => {
|
|
7889
|
+
const {
|
|
7890
|
+
serverSubscriptionId,
|
|
7891
|
+
unsubscribeMethod
|
|
7892
|
+
} = subscription;
|
|
7893
|
+
|
|
7894
|
+
if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
|
|
7895
|
+
/**
|
|
7896
|
+
* Special case.
|
|
7897
|
+
* If we're dealing with a subscription that has been auto-
|
|
7898
|
+
* disposed by the RPC, then we can skip the RPC call to
|
|
7899
|
+
* tear down the subscription here.
|
|
7900
|
+
*
|
|
7901
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7902
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7903
|
+
*/
|
|
7904
|
+
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
7905
|
+
} else {
|
|
7906
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7907
|
+
state: 'unsubscribing'
|
|
7908
|
+
};
|
|
7909
|
+
|
|
7910
|
+
try {
|
|
7911
|
+
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
7912
|
+
} catch (e) {
|
|
7913
|
+
if (e instanceof Error) {
|
|
7914
|
+
console.error(`${unsubscribeMethod} error:`, e.message);
|
|
7915
|
+
}
|
|
7916
|
+
|
|
7917
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7918
|
+
return;
|
|
7919
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7920
|
+
|
|
7921
|
+
|
|
7922
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7923
|
+
state: 'subscribed'
|
|
7924
|
+
};
|
|
7925
|
+
await this._updateSubscriptions();
|
|
7926
|
+
return;
|
|
7927
|
+
}
|
|
7928
|
+
}
|
|
7832
7929
|
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7930
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7931
|
+
state: 'unsubscribed'
|
|
7932
|
+
};
|
|
7933
|
+
await this._updateSubscriptions();
|
|
7934
|
+
})();
|
|
7935
|
+
}
|
|
7836
7936
|
|
|
7837
|
-
|
|
7838
|
-
filter = {
|
|
7839
|
-
mentions: [sub.filter.toString()]
|
|
7840
|
-
};
|
|
7841
|
-
} else {
|
|
7842
|
-
filter = sub.filter;
|
|
7937
|
+
break;
|
|
7843
7938
|
}
|
|
7939
|
+
}));
|
|
7940
|
+
}
|
|
7941
|
+
/**
|
|
7942
|
+
* @internal
|
|
7943
|
+
*/
|
|
7844
7944
|
|
|
7845
|
-
|
|
7945
|
+
|
|
7946
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7947
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7948
|
+
|
|
7949
|
+
if (callbacks === undefined) {
|
|
7950
|
+
return;
|
|
7846
7951
|
}
|
|
7952
|
+
|
|
7953
|
+
callbacks.forEach(cb => {
|
|
7954
|
+
try {
|
|
7955
|
+
cb( // I failed to find a way to convince TypeScript that `cb` is of type
|
|
7956
|
+
// `TCallback` which is certainly compatible with `Parameters<TCallback>`.
|
|
7957
|
+
// See https://github.com/microsoft/TypeScript/issues/47615
|
|
7958
|
+
// @ts-ignore
|
|
7959
|
+
...callbackArgs);
|
|
7960
|
+
} catch (e) {
|
|
7961
|
+
console.error(e);
|
|
7962
|
+
}
|
|
7963
|
+
});
|
|
7847
7964
|
}
|
|
7848
7965
|
/**
|
|
7849
7966
|
* @internal
|
|
@@ -7851,14 +7968,71 @@ class Connection {
|
|
|
7851
7968
|
|
|
7852
7969
|
|
|
7853
7970
|
_wsOnAccountNotification(notification) {
|
|
7854
|
-
const
|
|
7971
|
+
const {
|
|
7972
|
+
result,
|
|
7973
|
+
subscription
|
|
7974
|
+
} = create(notification, AccountNotificationResult);
|
|
7855
7975
|
|
|
7856
|
-
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7976
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7977
|
+
}
|
|
7978
|
+
/**
|
|
7979
|
+
* @internal
|
|
7980
|
+
*/
|
|
7981
|
+
|
|
7982
|
+
|
|
7983
|
+
_makeSubscription(subscriptionConfig,
|
|
7984
|
+
/**
|
|
7985
|
+
* When preparing `args` for a call to `_makeSubscription`, be sure
|
|
7986
|
+
* to carefully apply a default `commitment` property, if necessary.
|
|
7987
|
+
*
|
|
7988
|
+
* - If the user supplied a `commitment` use that.
|
|
7989
|
+
* - Otherwise, if the `Connection::commitment` is set, use that.
|
|
7990
|
+
* - Otherwise, set it to the RPC server default: `finalized`.
|
|
7991
|
+
*
|
|
7992
|
+
* This is extremely important to ensure that these two fundamentally
|
|
7993
|
+
* identical subscriptions produce the same identifying hash:
|
|
7994
|
+
*
|
|
7995
|
+
* - A subscription made without specifying a commitment.
|
|
7996
|
+
* - A subscription made where the commitment specified is the same
|
|
7997
|
+
* as the default applied to the subscription above.
|
|
7998
|
+
*
|
|
7999
|
+
* Example; these two subscriptions must produce the same hash:
|
|
8000
|
+
*
|
|
8001
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'`
|
|
8002
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
|
|
8003
|
+
* `'finalized'`.
|
|
8004
|
+
*
|
|
8005
|
+
* See the 'making a subscription with defaulted params omitted' test
|
|
8006
|
+
* in `connection-subscriptions.ts` for more.
|
|
8007
|
+
*/
|
|
8008
|
+
args) {
|
|
8009
|
+
const clientSubscriptionId = this._nextClientSubscriptionId++;
|
|
8010
|
+
const hash = fastStableStringify$1([subscriptionConfig.method, args], true
|
|
8011
|
+
/* isArrayProp */
|
|
8012
|
+
);
|
|
8013
|
+
const existingSubscription = this._subscriptionsByHash[hash];
|
|
8014
|
+
|
|
8015
|
+
if (existingSubscription === undefined) {
|
|
8016
|
+
this._subscriptionsByHash[hash] = { ...subscriptionConfig,
|
|
8017
|
+
args,
|
|
8018
|
+
callbacks: new Set([subscriptionConfig.callback]),
|
|
8019
|
+
state: 'pending'
|
|
8020
|
+
};
|
|
8021
|
+
} else {
|
|
8022
|
+
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
7861
8023
|
}
|
|
8024
|
+
|
|
8025
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
8026
|
+
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8027
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
8028
|
+
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
8029
|
+
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
8030
|
+
await this._updateSubscriptions();
|
|
8031
|
+
};
|
|
8032
|
+
|
|
8033
|
+
this._updateSubscriptions();
|
|
8034
|
+
|
|
8035
|
+
return clientSubscriptionId;
|
|
7862
8036
|
}
|
|
7863
8037
|
/**
|
|
7864
8038
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7871,35 +8045,24 @@ class Connection {
|
|
|
7871
8045
|
|
|
7872
8046
|
|
|
7873
8047
|
onAccountChange(publicKey, callback, commitment) {
|
|
7874
|
-
const
|
|
7875
|
-
|
|
7876
|
-
publicKey: publicKey.toBase58(),
|
|
7877
|
-
callback,
|
|
7878
|
-
commitment,
|
|
7879
|
-
subscriptionId: null
|
|
7880
|
-
};
|
|
8048
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8049
|
+
'base64');
|
|
7881
8050
|
|
|
7882
|
-
this.
|
|
7883
|
-
|
|
7884
|
-
|
|
8051
|
+
return this._makeSubscription({
|
|
8052
|
+
callback,
|
|
8053
|
+
method: 'accountSubscribe',
|
|
8054
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
8055
|
+
}, args);
|
|
7885
8056
|
}
|
|
7886
8057
|
/**
|
|
7887
8058
|
* Deregister an account notification callback
|
|
7888
8059
|
*
|
|
7889
|
-
* @param id subscription id to deregister
|
|
8060
|
+
* @param id client subscription id to deregister
|
|
7890
8061
|
*/
|
|
7891
8062
|
|
|
7892
8063
|
|
|
7893
|
-
async removeAccountChangeListener(
|
|
7894
|
-
|
|
7895
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7896
|
-
delete this._accountChangeSubscriptions[id];
|
|
7897
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7898
|
-
|
|
7899
|
-
this._updateSubscriptions();
|
|
7900
|
-
} else {
|
|
7901
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7902
|
-
}
|
|
8064
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
8065
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7903
8066
|
}
|
|
7904
8067
|
/**
|
|
7905
8068
|
* @internal
|
|
@@ -7907,21 +8070,15 @@ class Connection {
|
|
|
7907
8070
|
|
|
7908
8071
|
|
|
7909
8072
|
_wsOnProgramAccountNotification(notification) {
|
|
7910
|
-
const
|
|
8073
|
+
const {
|
|
8074
|
+
result,
|
|
8075
|
+
subscription
|
|
8076
|
+
} = create(notification, ProgramAccountNotificationResult);
|
|
7911
8077
|
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
context
|
|
7917
|
-
} = res.result;
|
|
7918
|
-
sub.callback({
|
|
7919
|
-
accountId: value.pubkey,
|
|
7920
|
-
accountInfo: value.account
|
|
7921
|
-
}, context);
|
|
7922
|
-
return;
|
|
7923
|
-
}
|
|
7924
|
-
}
|
|
8078
|
+
this._handleServerNotification(subscription, [{
|
|
8079
|
+
accountId: result.value.pubkey,
|
|
8080
|
+
accountInfo: result.value.account
|
|
8081
|
+
}, result.context]);
|
|
7925
8082
|
}
|
|
7926
8083
|
/**
|
|
7927
8084
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7936,36 +8093,30 @@ class Connection {
|
|
|
7936
8093
|
|
|
7937
8094
|
|
|
7938
8095
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7939
|
-
const
|
|
7940
|
-
|
|
7941
|
-
|
|
8096
|
+
const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8097
|
+
'base64'
|
|
8098
|
+
/* encoding */
|
|
8099
|
+
, filters ? {
|
|
8100
|
+
filters: filters
|
|
8101
|
+
} : undefined
|
|
8102
|
+
/* extra */
|
|
8103
|
+
);
|
|
8104
|
+
|
|
8105
|
+
return this._makeSubscription({
|
|
7942
8106
|
callback,
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
};
|
|
7947
|
-
|
|
7948
|
-
this._updateSubscriptions();
|
|
7949
|
-
|
|
7950
|
-
return id;
|
|
8107
|
+
method: 'programSubscribe',
|
|
8108
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
8109
|
+
}, args);
|
|
7951
8110
|
}
|
|
7952
8111
|
/**
|
|
7953
8112
|
* Deregister an account notification callback
|
|
7954
8113
|
*
|
|
7955
|
-
* @param id subscription id to deregister
|
|
8114
|
+
* @param id client subscription id to deregister
|
|
7956
8115
|
*/
|
|
7957
8116
|
|
|
7958
8117
|
|
|
7959
|
-
async removeProgramAccountChangeListener(
|
|
7960
|
-
|
|
7961
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7962
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7963
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7964
|
-
|
|
7965
|
-
this._updateSubscriptions();
|
|
7966
|
-
} else {
|
|
7967
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
7968
|
-
}
|
|
8118
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
8119
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7969
8120
|
}
|
|
7970
8121
|
/**
|
|
7971
8122
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7973,35 +8124,26 @@ class Connection {
|
|
|
7973
8124
|
|
|
7974
8125
|
|
|
7975
8126
|
onLogs(filter, callback, commitment) {
|
|
7976
|
-
const
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
commitment,
|
|
7981
|
-
subscriptionId: null
|
|
7982
|
-
};
|
|
7983
|
-
|
|
7984
|
-
this._updateSubscriptions();
|
|
8127
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
8128
|
+
mentions: [filter.toString()]
|
|
8129
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8130
|
+
);
|
|
7985
8131
|
|
|
7986
|
-
return
|
|
8132
|
+
return this._makeSubscription({
|
|
8133
|
+
callback,
|
|
8134
|
+
method: 'logsSubscribe',
|
|
8135
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
8136
|
+
}, args);
|
|
7987
8137
|
}
|
|
7988
8138
|
/**
|
|
7989
8139
|
* Deregister a logs callback.
|
|
7990
8140
|
*
|
|
7991
|
-
* @param id subscription id to deregister.
|
|
8141
|
+
* @param id client subscription id to deregister.
|
|
7992
8142
|
*/
|
|
7993
8143
|
|
|
7994
8144
|
|
|
7995
|
-
async removeOnLogsListener(
|
|
7996
|
-
|
|
7997
|
-
const subInfo = this._logsSubscriptions[id];
|
|
7998
|
-
delete this._logsSubscriptions[id];
|
|
7999
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
8000
|
-
|
|
8001
|
-
this._updateSubscriptions();
|
|
8002
|
-
} else {
|
|
8003
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
8004
|
-
}
|
|
8145
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
8146
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
8005
8147
|
}
|
|
8006
8148
|
/**
|
|
8007
8149
|
* @internal
|
|
@@ -8009,17 +8151,12 @@ class Connection {
|
|
|
8009
8151
|
|
|
8010
8152
|
|
|
8011
8153
|
_wsOnLogsNotification(notification) {
|
|
8012
|
-
const
|
|
8013
|
-
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
const sub = this._logsSubscriptions[id];
|
|
8154
|
+
const {
|
|
8155
|
+
result,
|
|
8156
|
+
subscription
|
|
8157
|
+
} = create(notification, LogsNotificationResult);
|
|
8017
8158
|
|
|
8018
|
-
|
|
8019
|
-
sub.callback(res.result.value, res.result.context);
|
|
8020
|
-
return;
|
|
8021
|
-
}
|
|
8022
|
-
}
|
|
8159
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
8023
8160
|
}
|
|
8024
8161
|
/**
|
|
8025
8162
|
* @internal
|
|
@@ -8027,14 +8164,12 @@ class Connection {
|
|
|
8027
8164
|
|
|
8028
8165
|
|
|
8029
8166
|
_wsOnSlotNotification(notification) {
|
|
8030
|
-
const
|
|
8167
|
+
const {
|
|
8168
|
+
result,
|
|
8169
|
+
subscription
|
|
8170
|
+
} = create(notification, SlotNotificationResult);
|
|
8031
8171
|
|
|
8032
|
-
|
|
8033
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8034
|
-
sub.callback(res.result);
|
|
8035
|
-
return;
|
|
8036
|
-
}
|
|
8037
|
-
}
|
|
8172
|
+
this._handleServerNotification(subscription, [result]);
|
|
8038
8173
|
}
|
|
8039
8174
|
/**
|
|
8040
8175
|
* Register a callback to be invoked upon slot changes
|
|
@@ -8045,33 +8180,23 @@ class Connection {
|
|
|
8045
8180
|
|
|
8046
8181
|
|
|
8047
8182
|
onSlotChange(callback) {
|
|
8048
|
-
|
|
8049
|
-
this._slotSubscriptions[id] = {
|
|
8183
|
+
return this._makeSubscription({
|
|
8050
8184
|
callback,
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
return id;
|
|
8185
|
+
method: 'slotSubscribe',
|
|
8186
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
8187
|
+
}, []
|
|
8188
|
+
/* args */
|
|
8189
|
+
);
|
|
8057
8190
|
}
|
|
8058
8191
|
/**
|
|
8059
8192
|
* Deregister a slot notification callback
|
|
8060
8193
|
*
|
|
8061
|
-
* @param id subscription id to deregister
|
|
8194
|
+
* @param id client subscription id to deregister
|
|
8062
8195
|
*/
|
|
8063
8196
|
|
|
8064
8197
|
|
|
8065
|
-
async removeSlotChangeListener(
|
|
8066
|
-
|
|
8067
|
-
const subInfo = this._slotSubscriptions[id];
|
|
8068
|
-
delete this._slotSubscriptions[id];
|
|
8069
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
8070
|
-
|
|
8071
|
-
this._updateSubscriptions();
|
|
8072
|
-
} else {
|
|
8073
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
8074
|
-
}
|
|
8198
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
8199
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
8075
8200
|
}
|
|
8076
8201
|
/**
|
|
8077
8202
|
* @internal
|
|
@@ -8079,14 +8204,12 @@ class Connection {
|
|
|
8079
8204
|
|
|
8080
8205
|
|
|
8081
8206
|
_wsOnSlotUpdatesNotification(notification) {
|
|
8082
|
-
const
|
|
8207
|
+
const {
|
|
8208
|
+
result,
|
|
8209
|
+
subscription
|
|
8210
|
+
} = create(notification, SlotUpdateNotificationResult);
|
|
8083
8211
|
|
|
8084
|
-
|
|
8085
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8086
|
-
sub.callback(res.result);
|
|
8087
|
-
return;
|
|
8088
|
-
}
|
|
8089
|
-
}
|
|
8212
|
+
this._handleServerNotification(subscription, [result]);
|
|
8090
8213
|
}
|
|
8091
8214
|
/**
|
|
8092
8215
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -8098,32 +8221,36 @@ class Connection {
|
|
|
8098
8221
|
|
|
8099
8222
|
|
|
8100
8223
|
onSlotUpdate(callback) {
|
|
8101
|
-
|
|
8102
|
-
this._slotUpdateSubscriptions[id] = {
|
|
8224
|
+
return this._makeSubscription({
|
|
8103
8225
|
callback,
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
return id;
|
|
8226
|
+
method: 'slotsUpdatesSubscribe',
|
|
8227
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
8228
|
+
}, []
|
|
8229
|
+
/* args */
|
|
8230
|
+
);
|
|
8110
8231
|
}
|
|
8111
8232
|
/**
|
|
8112
8233
|
* Deregister a slot update notification callback
|
|
8113
8234
|
*
|
|
8114
|
-
* @param id subscription id to deregister
|
|
8235
|
+
* @param id client subscription id to deregister
|
|
8115
8236
|
*/
|
|
8116
8237
|
|
|
8117
8238
|
|
|
8118
|
-
async removeSlotUpdateListener(
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8239
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
8240
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
8241
|
+
}
|
|
8242
|
+
/**
|
|
8243
|
+
* @internal
|
|
8244
|
+
*/
|
|
8123
8245
|
|
|
8124
|
-
|
|
8246
|
+
|
|
8247
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
8248
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8249
|
+
|
|
8250
|
+
if (dispose) {
|
|
8251
|
+
await dispose();
|
|
8125
8252
|
} else {
|
|
8126
|
-
console.warn(
|
|
8253
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
8127
8254
|
}
|
|
8128
8255
|
}
|
|
8129
8256
|
|
|
@@ -8170,30 +8297,34 @@ class Connection {
|
|
|
8170
8297
|
|
|
8171
8298
|
|
|
8172
8299
|
_wsOnSignatureNotification(notification) {
|
|
8173
|
-
const
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8300
|
+
const {
|
|
8301
|
+
result,
|
|
8302
|
+
subscription
|
|
8303
|
+
} = create(notification, SignatureNotificationResult);
|
|
8304
|
+
|
|
8305
|
+
if (result.value !== 'receivedSignature') {
|
|
8306
|
+
/**
|
|
8307
|
+
* Special case.
|
|
8308
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
8309
|
+
* subscription on the server side. We need to track which of these
|
|
8310
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
8311
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
8312
|
+
* (in which case we must tear down the server subscription) or an
|
|
8313
|
+
* already-processed signature (in which case the client can simply
|
|
8314
|
+
* clear out the subscription locally without telling the server).
|
|
8315
|
+
*
|
|
8316
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
8317
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
8318
|
+
*/
|
|
8319
|
+
this._subscriptionsAutoDisposedByRpc.add(subscription);
|
|
8320
|
+
}
|
|
8321
|
+
|
|
8322
|
+
this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
|
|
8323
|
+
type: 'received'
|
|
8324
|
+
}, result.context] : [{
|
|
8325
|
+
type: 'status',
|
|
8326
|
+
result: result.value
|
|
8327
|
+
}, result.context]);
|
|
8197
8328
|
}
|
|
8198
8329
|
/**
|
|
8199
8330
|
* Register a callback to be invoked upon signature updates
|
|
@@ -8206,23 +8337,26 @@ class Connection {
|
|
|
8206
8337
|
|
|
8207
8338
|
|
|
8208
8339
|
onSignature(signature, callback, commitment) {
|
|
8209
|
-
const
|
|
8210
|
-
|
|
8211
|
-
|
|
8340
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8341
|
+
);
|
|
8342
|
+
|
|
8343
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8212
8344
|
callback: (notification, context) => {
|
|
8213
8345
|
if (notification.type === 'status') {
|
|
8214
|
-
callback(notification.result, context);
|
|
8346
|
+
callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8347
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8348
|
+
|
|
8349
|
+
try {
|
|
8350
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8351
|
+
} catch {// Already removed.
|
|
8352
|
+
}
|
|
8215
8353
|
}
|
|
8216
8354
|
},
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
subscriptionId: null
|
|
8221
|
-
};
|
|
8355
|
+
method: 'signatureSubscribe',
|
|
8356
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8357
|
+
}, args);
|
|
8222
8358
|
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
return id;
|
|
8359
|
+
return clientSubscriptionId;
|
|
8226
8360
|
}
|
|
8227
8361
|
/**
|
|
8228
8362
|
* Register a callback to be invoked when a transaction is
|
|
@@ -8237,35 +8371,43 @@ class Connection {
|
|
|
8237
8371
|
|
|
8238
8372
|
|
|
8239
8373
|
onSignatureWithOptions(signature, callback, options) {
|
|
8240
|
-
const
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
options
|
|
8245
|
-
|
|
8374
|
+
const {
|
|
8375
|
+
commitment,
|
|
8376
|
+
...extra
|
|
8377
|
+
} = { ...options,
|
|
8378
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8379
|
+
|
|
8246
8380
|
};
|
|
8247
8381
|
|
|
8248
|
-
this.
|
|
8382
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
8383
|
+
/* encoding */
|
|
8384
|
+
, extra);
|
|
8249
8385
|
|
|
8250
|
-
|
|
8386
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8387
|
+
callback: (notification, context) => {
|
|
8388
|
+
callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8389
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8390
|
+
|
|
8391
|
+
try {
|
|
8392
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8393
|
+
} catch {// Already removed.
|
|
8394
|
+
}
|
|
8395
|
+
},
|
|
8396
|
+
method: 'signatureSubscribe',
|
|
8397
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8398
|
+
}, args);
|
|
8399
|
+
|
|
8400
|
+
return clientSubscriptionId;
|
|
8251
8401
|
}
|
|
8252
8402
|
/**
|
|
8253
8403
|
* Deregister a signature notification callback
|
|
8254
8404
|
*
|
|
8255
|
-
* @param id subscription id to deregister
|
|
8405
|
+
* @param id client subscription id to deregister
|
|
8256
8406
|
*/
|
|
8257
8407
|
|
|
8258
8408
|
|
|
8259
|
-
async removeSignatureListener(
|
|
8260
|
-
|
|
8261
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
8262
|
-
delete this._signatureSubscriptions[id];
|
|
8263
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
8264
|
-
|
|
8265
|
-
this._updateSubscriptions();
|
|
8266
|
-
} else {
|
|
8267
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
8268
|
-
}
|
|
8409
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
8410
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
8269
8411
|
}
|
|
8270
8412
|
/**
|
|
8271
8413
|
* @internal
|
|
@@ -8273,14 +8415,12 @@ class Connection {
|
|
|
8273
8415
|
|
|
8274
8416
|
|
|
8275
8417
|
_wsOnRootNotification(notification) {
|
|
8276
|
-
const
|
|
8418
|
+
const {
|
|
8419
|
+
result,
|
|
8420
|
+
subscription
|
|
8421
|
+
} = create(notification, RootNotificationResult);
|
|
8277
8422
|
|
|
8278
|
-
|
|
8279
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8280
|
-
sub.callback(res.result);
|
|
8281
|
-
return;
|
|
8282
|
-
}
|
|
8283
|
-
}
|
|
8423
|
+
this._handleServerNotification(subscription, [result]);
|
|
8284
8424
|
}
|
|
8285
8425
|
/**
|
|
8286
8426
|
* Register a callback to be invoked upon root changes
|
|
@@ -8291,33 +8431,23 @@ class Connection {
|
|
|
8291
8431
|
|
|
8292
8432
|
|
|
8293
8433
|
onRootChange(callback) {
|
|
8294
|
-
|
|
8295
|
-
this._rootSubscriptions[id] = {
|
|
8434
|
+
return this._makeSubscription({
|
|
8296
8435
|
callback,
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
return id;
|
|
8436
|
+
method: 'rootSubscribe',
|
|
8437
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
8438
|
+
}, []
|
|
8439
|
+
/* args */
|
|
8440
|
+
);
|
|
8303
8441
|
}
|
|
8304
8442
|
/**
|
|
8305
8443
|
* Deregister a root notification callback
|
|
8306
8444
|
*
|
|
8307
|
-
* @param id subscription id to deregister
|
|
8445
|
+
* @param id client subscription id to deregister
|
|
8308
8446
|
*/
|
|
8309
8447
|
|
|
8310
8448
|
|
|
8311
|
-
async removeRootChangeListener(
|
|
8312
|
-
|
|
8313
|
-
const subInfo = this._rootSubscriptions[id];
|
|
8314
|
-
delete this._rootSubscriptions[id];
|
|
8315
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
8316
|
-
|
|
8317
|
-
this._updateSubscriptions();
|
|
8318
|
-
} else {
|
|
8319
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
8320
|
-
}
|
|
8449
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
8450
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
8321
8451
|
}
|
|
8322
8452
|
|
|
8323
8453
|
}
|