@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.cjs.js
CHANGED
|
@@ -4793,6 +4793,82 @@ module.exports = exports;
|
|
|
4793
4793
|
|
|
4794
4794
|
var crossFetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfill.exports);
|
|
4795
4795
|
|
|
4796
|
+
var objToString = Object.prototype.toString;
|
|
4797
|
+
var objKeys = Object.keys || function(obj) {
|
|
4798
|
+
var keys = [];
|
|
4799
|
+
for (var name in obj) {
|
|
4800
|
+
keys.push(name);
|
|
4801
|
+
}
|
|
4802
|
+
return keys;
|
|
4803
|
+
};
|
|
4804
|
+
|
|
4805
|
+
function stringify(val, isArrayProp) {
|
|
4806
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
4807
|
+
if (val === true) {
|
|
4808
|
+
return "true";
|
|
4809
|
+
}
|
|
4810
|
+
if (val === false) {
|
|
4811
|
+
return "false";
|
|
4812
|
+
}
|
|
4813
|
+
switch (typeof val) {
|
|
4814
|
+
case "object":
|
|
4815
|
+
if (val === null) {
|
|
4816
|
+
return null;
|
|
4817
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
4818
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
4819
|
+
} else {
|
|
4820
|
+
toStr = objToString.call(val);
|
|
4821
|
+
if (toStr === "[object Array]") {
|
|
4822
|
+
str = '[';
|
|
4823
|
+
max = val.length - 1;
|
|
4824
|
+
for(i = 0; i < max; i++) {
|
|
4825
|
+
str += stringify(val[i], true) + ',';
|
|
4826
|
+
}
|
|
4827
|
+
if (max > -1) {
|
|
4828
|
+
str += stringify(val[i], true);
|
|
4829
|
+
}
|
|
4830
|
+
return str + ']';
|
|
4831
|
+
} else if (toStr === "[object Object]") {
|
|
4832
|
+
// only object is left
|
|
4833
|
+
keys = objKeys(val).sort();
|
|
4834
|
+
max = keys.length;
|
|
4835
|
+
str = "";
|
|
4836
|
+
i = 0;
|
|
4837
|
+
while (i < max) {
|
|
4838
|
+
key = keys[i];
|
|
4839
|
+
propVal = stringify(val[key], false);
|
|
4840
|
+
if (propVal !== undefined) {
|
|
4841
|
+
if (str) {
|
|
4842
|
+
str += ',';
|
|
4843
|
+
}
|
|
4844
|
+
str += JSON.stringify(key) + ':' + propVal;
|
|
4845
|
+
}
|
|
4846
|
+
i++;
|
|
4847
|
+
}
|
|
4848
|
+
return '{' + str + '}';
|
|
4849
|
+
} else {
|
|
4850
|
+
return JSON.stringify(val);
|
|
4851
|
+
}
|
|
4852
|
+
}
|
|
4853
|
+
case "function":
|
|
4854
|
+
case "undefined":
|
|
4855
|
+
return isArrayProp ? null : undefined;
|
|
4856
|
+
case "string":
|
|
4857
|
+
return JSON.stringify(val);
|
|
4858
|
+
default:
|
|
4859
|
+
return isFinite(val) ? val : null;
|
|
4860
|
+
}
|
|
4861
|
+
}
|
|
4862
|
+
|
|
4863
|
+
var fastStableStringify = function(val) {
|
|
4864
|
+
var returnVal = stringify(val, false);
|
|
4865
|
+
if (returnVal !== undefined) {
|
|
4866
|
+
return ''+ returnVal;
|
|
4867
|
+
}
|
|
4868
|
+
};
|
|
4869
|
+
|
|
4870
|
+
var fastStableStringify$1 = fastStableStringify;
|
|
4871
|
+
|
|
4796
4872
|
const MINIMUM_SLOT_PER_EPOCH = 32; // Returns the number of trailing zeros in the binary representation of self.
|
|
4797
4873
|
|
|
4798
4874
|
function trailingZeros(n) {
|
|
@@ -4959,6 +5035,12 @@ const BufferFromRawAccountData = superstruct.coerce(superstruct.instance(buffer.
|
|
|
4959
5035
|
*/
|
|
4960
5036
|
|
|
4961
5037
|
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|
5038
|
+
/**
|
|
5039
|
+
* HACK.
|
|
5040
|
+
* Copied from rpc-websockets/dist/lib/client.
|
|
5041
|
+
* Otherwise, `yarn build` fails with:
|
|
5042
|
+
* https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
|
|
5043
|
+
*/
|
|
4962
5044
|
|
|
4963
5045
|
/**
|
|
4964
5046
|
* @internal
|
|
@@ -5827,14 +5909,9 @@ const LogsNotificationResult = superstruct.type({
|
|
|
5827
5909
|
* Filter for log subscriptions.
|
|
5828
5910
|
*/
|
|
5829
5911
|
|
|
5830
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5831
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5832
|
-
}
|
|
5833
5912
|
/**
|
|
5834
5913
|
* A connection to a fullnode JSON RPC endpoint
|
|
5835
5914
|
*/
|
|
5836
|
-
|
|
5837
|
-
|
|
5838
5915
|
class Connection {
|
|
5839
5916
|
/** @internal */
|
|
5840
5917
|
|
|
@@ -5858,21 +5935,13 @@ class Connection {
|
|
|
5858
5935
|
|
|
5859
5936
|
/** @internal */
|
|
5860
5937
|
|
|
5861
|
-
/** @internal
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
/** @internal */
|
|
5870
|
-
|
|
5871
|
-
/** @internal */
|
|
5872
|
-
|
|
5873
|
-
/** @internal */
|
|
5874
|
-
|
|
5875
|
-
/** @internal */
|
|
5938
|
+
/** @internal
|
|
5939
|
+
* A number that we increment every time an active connection closes.
|
|
5940
|
+
* Used to determine whether the same socket connection that was open
|
|
5941
|
+
* when an async operation started is the same one that's active when
|
|
5942
|
+
* its continuation fires.
|
|
5943
|
+
*
|
|
5944
|
+
*/
|
|
5876
5945
|
|
|
5877
5946
|
/** @internal */
|
|
5878
5947
|
|
|
@@ -5888,7 +5957,19 @@ class Connection {
|
|
|
5888
5957
|
|
|
5889
5958
|
/** @internal */
|
|
5890
5959
|
|
|
5891
|
-
/**
|
|
5960
|
+
/**
|
|
5961
|
+
* Special case.
|
|
5962
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
5963
|
+
* subscription on the server side. We need to track which of these
|
|
5964
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
5965
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
5966
|
+
* (in which case we must tear down the server subscription) or an
|
|
5967
|
+
* already-processed signature (in which case the client can simply
|
|
5968
|
+
* clear out the subscription locally without telling the server).
|
|
5969
|
+
*
|
|
5970
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
5971
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
5972
|
+
*/
|
|
5892
5973
|
|
|
5893
5974
|
/** @internal */
|
|
5894
5975
|
|
|
@@ -5910,6 +5991,7 @@ class Connection {
|
|
|
5910
5991
|
this._rpcWebSocketConnected = false;
|
|
5911
5992
|
this._rpcWebSocketHeartbeat = null;
|
|
5912
5993
|
this._rpcWebSocketIdleTimeout = null;
|
|
5994
|
+
this._rpcWebSocketGeneration = 0;
|
|
5913
5995
|
this._disableBlockhashCaching = false;
|
|
5914
5996
|
this._pollingBlockhash = false;
|
|
5915
5997
|
this._blockhashInfo = {
|
|
@@ -5918,20 +6000,11 @@ class Connection {
|
|
|
5918
6000
|
transactionSignatures: [],
|
|
5919
6001
|
simulatedSignatures: []
|
|
5920
6002
|
};
|
|
5921
|
-
this.
|
|
5922
|
-
this.
|
|
5923
|
-
this.
|
|
5924
|
-
this.
|
|
5925
|
-
this.
|
|
5926
|
-
this._rootSubscriptions = {};
|
|
5927
|
-
this._signatureSubscriptionCounter = 0;
|
|
5928
|
-
this._signatureSubscriptions = {};
|
|
5929
|
-
this._slotSubscriptionCounter = 0;
|
|
5930
|
-
this._slotSubscriptions = {};
|
|
5931
|
-
this._logsSubscriptionCounter = 0;
|
|
5932
|
-
this._logsSubscriptions = {};
|
|
5933
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5934
|
-
this._slotUpdateSubscriptions = {};
|
|
6003
|
+
this._nextClientSubscriptionId = 0;
|
|
6004
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
6005
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
6006
|
+
this._subscriptionsByHash = {};
|
|
6007
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5935
6008
|
let url = new URL(endpoint);
|
|
5936
6009
|
const useHttps = url.protocol === 'https:';
|
|
5937
6010
|
let wsEndpoint;
|
|
@@ -7699,6 +7772,8 @@ class Connection {
|
|
|
7699
7772
|
|
|
7700
7773
|
|
|
7701
7774
|
_wsOnClose(code) {
|
|
7775
|
+
this._rpcWebSocketGeneration++;
|
|
7776
|
+
|
|
7702
7777
|
if (this._rpcWebSocketHeartbeat) {
|
|
7703
7778
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7704
7779
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7712,85 +7787,20 @@ class Connection {
|
|
|
7712
7787
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7713
7788
|
|
|
7714
7789
|
|
|
7715
|
-
this.
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7723
|
-
if (sub.subscriptionId == null) {
|
|
7724
|
-
sub.subscriptionId = 'subscribing';
|
|
7725
|
-
|
|
7726
|
-
try {
|
|
7727
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7728
|
-
|
|
7729
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7730
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7731
|
-
sub.subscriptionId = id;
|
|
7732
|
-
}
|
|
7733
|
-
} catch (err) {
|
|
7734
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7735
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7736
|
-
sub.subscriptionId = null;
|
|
7737
|
-
}
|
|
7738
|
-
|
|
7739
|
-
if (err instanceof Error) {
|
|
7740
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7741
|
-
}
|
|
7742
|
-
}
|
|
7743
|
-
}
|
|
7744
|
-
}
|
|
7745
|
-
/**
|
|
7746
|
-
* @internal
|
|
7747
|
-
*/
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7751
|
-
const subscriptionId = sub.subscriptionId;
|
|
7752
|
-
|
|
7753
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7754
|
-
const unsubscribeId = subscriptionId;
|
|
7755
|
-
|
|
7756
|
-
try {
|
|
7757
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7758
|
-
} catch (err) {
|
|
7759
|
-
if (err instanceof Error) {
|
|
7760
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7761
|
-
}
|
|
7762
|
-
}
|
|
7763
|
-
}
|
|
7764
|
-
}
|
|
7765
|
-
/**
|
|
7766
|
-
* @internal
|
|
7767
|
-
*/
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
_resetSubscriptions() {
|
|
7771
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7772
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7773
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7774
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7775
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7776
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7777
|
-
Object.values(this._slotUpdateSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7790
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
7791
|
+
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
7792
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7793
|
+
state: 'pending'
|
|
7794
|
+
};
|
|
7795
|
+
});
|
|
7778
7796
|
}
|
|
7779
7797
|
/**
|
|
7780
7798
|
* @internal
|
|
7781
7799
|
*/
|
|
7782
7800
|
|
|
7783
7801
|
|
|
7784
|
-
_updateSubscriptions() {
|
|
7785
|
-
|
|
7786
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7787
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7788
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7789
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7790
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7791
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7792
|
-
|
|
7793
|
-
if (accountKeys.length === 0 && programKeys.length === 0 && slotKeys.length === 0 && slotUpdateKeys.length === 0 && signatureKeys.length === 0 && rootKeys.length === 0 && logsKeys.length === 0) {
|
|
7802
|
+
async _updateSubscriptions() {
|
|
7803
|
+
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
7794
7804
|
if (this._rpcWebSocketConnected) {
|
|
7795
7805
|
this._rpcWebSocketConnected = false;
|
|
7796
7806
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7822,60 +7832,167 @@ class Connection {
|
|
|
7822
7832
|
return;
|
|
7823
7833
|
}
|
|
7824
7834
|
|
|
7825
|
-
|
|
7826
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7827
|
-
|
|
7828
|
-
this._subscribe(sub, 'accountSubscribe', this._buildArgs([sub.publicKey], sub.commitment, 'base64'));
|
|
7829
|
-
}
|
|
7835
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7830
7836
|
|
|
7831
|
-
|
|
7832
|
-
|
|
7837
|
+
const isCurrentConnectionStillActive = () => {
|
|
7838
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7839
|
+
};
|
|
7833
7840
|
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7841
|
+
await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
|
|
7842
|
+
// `_updateSubscriptions` recursively when processing the state,
|
|
7843
|
+
// so it's important that we look up the *current* version of
|
|
7844
|
+
// each subscription, every time we process a hash.
|
|
7845
|
+
Object.keys(this._subscriptionsByHash).map(async hash => {
|
|
7846
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7838
7847
|
|
|
7839
|
-
|
|
7840
|
-
|
|
7848
|
+
if (subscription === undefined) {
|
|
7849
|
+
// This entry has since been deleted. Skip.
|
|
7850
|
+
return;
|
|
7851
|
+
}
|
|
7841
7852
|
|
|
7842
|
-
|
|
7843
|
-
|
|
7853
|
+
switch (subscription.state) {
|
|
7854
|
+
case 'pending':
|
|
7855
|
+
case 'unsubscribed':
|
|
7856
|
+
if (subscription.callbacks.size === 0) {
|
|
7857
|
+
/**
|
|
7858
|
+
* You can end up here when:
|
|
7859
|
+
*
|
|
7860
|
+
* - a subscription has recently unsubscribed
|
|
7861
|
+
* without having new callbacks added to it
|
|
7862
|
+
* while the unsubscribe was in flight, or
|
|
7863
|
+
* - when a pending subscription has its
|
|
7864
|
+
* listeners removed before a request was
|
|
7865
|
+
* sent to the server.
|
|
7866
|
+
*
|
|
7867
|
+
* Being that nobody is interested in this
|
|
7868
|
+
* subscription any longer, delete it.
|
|
7869
|
+
*/
|
|
7870
|
+
delete this._subscriptionsByHash[hash];
|
|
7871
|
+
|
|
7872
|
+
if (subscription.state === 'unsubscribed') {
|
|
7873
|
+
delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
|
|
7874
|
+
}
|
|
7844
7875
|
|
|
7845
|
-
|
|
7846
|
-
|
|
7876
|
+
await this._updateSubscriptions();
|
|
7877
|
+
return;
|
|
7878
|
+
}
|
|
7847
7879
|
|
|
7848
|
-
|
|
7849
|
-
|
|
7880
|
+
await (async () => {
|
|
7881
|
+
const {
|
|
7882
|
+
args,
|
|
7883
|
+
method
|
|
7884
|
+
} = subscription;
|
|
7850
7885
|
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7886
|
+
try {
|
|
7887
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7888
|
+
state: 'subscribing'
|
|
7889
|
+
};
|
|
7890
|
+
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
7891
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7892
|
+
serverSubscriptionId,
|
|
7893
|
+
state: 'subscribed'
|
|
7894
|
+
};
|
|
7895
|
+
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
7896
|
+
await this._updateSubscriptions();
|
|
7897
|
+
} catch (e) {
|
|
7898
|
+
if (e instanceof Error) {
|
|
7899
|
+
console.error(`${method} error for argument`, args, e.message);
|
|
7900
|
+
}
|
|
7901
|
+
|
|
7902
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7903
|
+
return;
|
|
7904
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7855
7905
|
|
|
7856
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7857
|
-
}
|
|
7858
7906
|
|
|
7859
|
-
|
|
7860
|
-
|
|
7907
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7908
|
+
state: 'pending'
|
|
7909
|
+
};
|
|
7910
|
+
await this._updateSubscriptions();
|
|
7911
|
+
}
|
|
7912
|
+
})();
|
|
7913
|
+
break;
|
|
7861
7914
|
|
|
7862
|
-
|
|
7863
|
-
|
|
7915
|
+
case 'subscribed':
|
|
7916
|
+
if (subscription.callbacks.size === 0) {
|
|
7917
|
+
// By the time we successfully set up a subscription
|
|
7918
|
+
// with the server, the client stopped caring about it.
|
|
7919
|
+
// Tear it down now.
|
|
7920
|
+
await (async () => {
|
|
7921
|
+
const {
|
|
7922
|
+
serverSubscriptionId,
|
|
7923
|
+
unsubscribeMethod
|
|
7924
|
+
} = subscription;
|
|
7925
|
+
|
|
7926
|
+
if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
|
|
7927
|
+
/**
|
|
7928
|
+
* Special case.
|
|
7929
|
+
* If we're dealing with a subscription that has been auto-
|
|
7930
|
+
* disposed by the RPC, then we can skip the RPC call to
|
|
7931
|
+
* tear down the subscription here.
|
|
7932
|
+
*
|
|
7933
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7934
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7935
|
+
*/
|
|
7936
|
+
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
7937
|
+
} else {
|
|
7938
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7939
|
+
state: 'unsubscribing'
|
|
7940
|
+
};
|
|
7941
|
+
|
|
7942
|
+
try {
|
|
7943
|
+
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
7944
|
+
} catch (e) {
|
|
7945
|
+
if (e instanceof Error) {
|
|
7946
|
+
console.error(`${unsubscribeMethod} error:`, e.message);
|
|
7947
|
+
}
|
|
7948
|
+
|
|
7949
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7950
|
+
return;
|
|
7951
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7952
|
+
|
|
7953
|
+
|
|
7954
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7955
|
+
state: 'subscribed'
|
|
7956
|
+
};
|
|
7957
|
+
await this._updateSubscriptions();
|
|
7958
|
+
return;
|
|
7959
|
+
}
|
|
7960
|
+
}
|
|
7864
7961
|
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7962
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7963
|
+
state: 'unsubscribed'
|
|
7964
|
+
};
|
|
7965
|
+
await this._updateSubscriptions();
|
|
7966
|
+
})();
|
|
7967
|
+
}
|
|
7868
7968
|
|
|
7869
|
-
|
|
7870
|
-
filter = {
|
|
7871
|
-
mentions: [sub.filter.toString()]
|
|
7872
|
-
};
|
|
7873
|
-
} else {
|
|
7874
|
-
filter = sub.filter;
|
|
7969
|
+
break;
|
|
7875
7970
|
}
|
|
7971
|
+
}));
|
|
7972
|
+
}
|
|
7973
|
+
/**
|
|
7974
|
+
* @internal
|
|
7975
|
+
*/
|
|
7876
7976
|
|
|
7877
|
-
|
|
7977
|
+
|
|
7978
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7979
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7980
|
+
|
|
7981
|
+
if (callbacks === undefined) {
|
|
7982
|
+
return;
|
|
7878
7983
|
}
|
|
7984
|
+
|
|
7985
|
+
callbacks.forEach(cb => {
|
|
7986
|
+
try {
|
|
7987
|
+
cb( // I failed to find a way to convince TypeScript that `cb` is of type
|
|
7988
|
+
// `TCallback` which is certainly compatible with `Parameters<TCallback>`.
|
|
7989
|
+
// See https://github.com/microsoft/TypeScript/issues/47615
|
|
7990
|
+
// @ts-ignore
|
|
7991
|
+
...callbackArgs);
|
|
7992
|
+
} catch (e) {
|
|
7993
|
+
console.error(e);
|
|
7994
|
+
}
|
|
7995
|
+
});
|
|
7879
7996
|
}
|
|
7880
7997
|
/**
|
|
7881
7998
|
* @internal
|
|
@@ -7883,14 +8000,71 @@ class Connection {
|
|
|
7883
8000
|
|
|
7884
8001
|
|
|
7885
8002
|
_wsOnAccountNotification(notification) {
|
|
7886
|
-
const
|
|
8003
|
+
const {
|
|
8004
|
+
result,
|
|
8005
|
+
subscription
|
|
8006
|
+
} = superstruct.create(notification, AccountNotificationResult);
|
|
7887
8007
|
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
8008
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
8009
|
+
}
|
|
8010
|
+
/**
|
|
8011
|
+
* @internal
|
|
8012
|
+
*/
|
|
8013
|
+
|
|
8014
|
+
|
|
8015
|
+
_makeSubscription(subscriptionConfig,
|
|
8016
|
+
/**
|
|
8017
|
+
* When preparing `args` for a call to `_makeSubscription`, be sure
|
|
8018
|
+
* to carefully apply a default `commitment` property, if necessary.
|
|
8019
|
+
*
|
|
8020
|
+
* - If the user supplied a `commitment` use that.
|
|
8021
|
+
* - Otherwise, if the `Connection::commitment` is set, use that.
|
|
8022
|
+
* - Otherwise, set it to the RPC server default: `finalized`.
|
|
8023
|
+
*
|
|
8024
|
+
* This is extremely important to ensure that these two fundamentally
|
|
8025
|
+
* identical subscriptions produce the same identifying hash:
|
|
8026
|
+
*
|
|
8027
|
+
* - A subscription made without specifying a commitment.
|
|
8028
|
+
* - A subscription made where the commitment specified is the same
|
|
8029
|
+
* as the default applied to the subscription above.
|
|
8030
|
+
*
|
|
8031
|
+
* Example; these two subscriptions must produce the same hash:
|
|
8032
|
+
*
|
|
8033
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'`
|
|
8034
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
|
|
8035
|
+
* `'finalized'`.
|
|
8036
|
+
*
|
|
8037
|
+
* See the 'making a subscription with defaulted params omitted' test
|
|
8038
|
+
* in `connection-subscriptions.ts` for more.
|
|
8039
|
+
*/
|
|
8040
|
+
args) {
|
|
8041
|
+
const clientSubscriptionId = this._nextClientSubscriptionId++;
|
|
8042
|
+
const hash = fastStableStringify$1([subscriptionConfig.method, args], true
|
|
8043
|
+
/* isArrayProp */
|
|
8044
|
+
);
|
|
8045
|
+
const existingSubscription = this._subscriptionsByHash[hash];
|
|
8046
|
+
|
|
8047
|
+
if (existingSubscription === undefined) {
|
|
8048
|
+
this._subscriptionsByHash[hash] = { ...subscriptionConfig,
|
|
8049
|
+
args,
|
|
8050
|
+
callbacks: new Set([subscriptionConfig.callback]),
|
|
8051
|
+
state: 'pending'
|
|
8052
|
+
};
|
|
8053
|
+
} else {
|
|
8054
|
+
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
7893
8055
|
}
|
|
8056
|
+
|
|
8057
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
8058
|
+
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8059
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
8060
|
+
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
8061
|
+
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
8062
|
+
await this._updateSubscriptions();
|
|
8063
|
+
};
|
|
8064
|
+
|
|
8065
|
+
this._updateSubscriptions();
|
|
8066
|
+
|
|
8067
|
+
return clientSubscriptionId;
|
|
7894
8068
|
}
|
|
7895
8069
|
/**
|
|
7896
8070
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7903,35 +8077,24 @@ class Connection {
|
|
|
7903
8077
|
|
|
7904
8078
|
|
|
7905
8079
|
onAccountChange(publicKey, callback, commitment) {
|
|
7906
|
-
const
|
|
7907
|
-
|
|
7908
|
-
publicKey: publicKey.toBase58(),
|
|
7909
|
-
callback,
|
|
7910
|
-
commitment,
|
|
7911
|
-
subscriptionId: null
|
|
7912
|
-
};
|
|
8080
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8081
|
+
'base64');
|
|
7913
8082
|
|
|
7914
|
-
this.
|
|
7915
|
-
|
|
7916
|
-
|
|
8083
|
+
return this._makeSubscription({
|
|
8084
|
+
callback,
|
|
8085
|
+
method: 'accountSubscribe',
|
|
8086
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
8087
|
+
}, args);
|
|
7917
8088
|
}
|
|
7918
8089
|
/**
|
|
7919
8090
|
* Deregister an account notification callback
|
|
7920
8091
|
*
|
|
7921
|
-
* @param id subscription id to deregister
|
|
8092
|
+
* @param id client subscription id to deregister
|
|
7922
8093
|
*/
|
|
7923
8094
|
|
|
7924
8095
|
|
|
7925
|
-
async removeAccountChangeListener(
|
|
7926
|
-
|
|
7927
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7928
|
-
delete this._accountChangeSubscriptions[id];
|
|
7929
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7930
|
-
|
|
7931
|
-
this._updateSubscriptions();
|
|
7932
|
-
} else {
|
|
7933
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7934
|
-
}
|
|
8096
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
8097
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7935
8098
|
}
|
|
7936
8099
|
/**
|
|
7937
8100
|
* @internal
|
|
@@ -7939,21 +8102,15 @@ class Connection {
|
|
|
7939
8102
|
|
|
7940
8103
|
|
|
7941
8104
|
_wsOnProgramAccountNotification(notification) {
|
|
7942
|
-
const
|
|
8105
|
+
const {
|
|
8106
|
+
result,
|
|
8107
|
+
subscription
|
|
8108
|
+
} = superstruct.create(notification, ProgramAccountNotificationResult);
|
|
7943
8109
|
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
context
|
|
7949
|
-
} = res.result;
|
|
7950
|
-
sub.callback({
|
|
7951
|
-
accountId: value.pubkey,
|
|
7952
|
-
accountInfo: value.account
|
|
7953
|
-
}, context);
|
|
7954
|
-
return;
|
|
7955
|
-
}
|
|
7956
|
-
}
|
|
8110
|
+
this._handleServerNotification(subscription, [{
|
|
8111
|
+
accountId: result.value.pubkey,
|
|
8112
|
+
accountInfo: result.value.account
|
|
8113
|
+
}, result.context]);
|
|
7957
8114
|
}
|
|
7958
8115
|
/**
|
|
7959
8116
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7968,36 +8125,30 @@ class Connection {
|
|
|
7968
8125
|
|
|
7969
8126
|
|
|
7970
8127
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7971
|
-
const
|
|
7972
|
-
|
|
7973
|
-
|
|
8128
|
+
const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8129
|
+
'base64'
|
|
8130
|
+
/* encoding */
|
|
8131
|
+
, filters ? {
|
|
8132
|
+
filters: filters
|
|
8133
|
+
} : undefined
|
|
8134
|
+
/* extra */
|
|
8135
|
+
);
|
|
8136
|
+
|
|
8137
|
+
return this._makeSubscription({
|
|
7974
8138
|
callback,
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
};
|
|
7979
|
-
|
|
7980
|
-
this._updateSubscriptions();
|
|
7981
|
-
|
|
7982
|
-
return id;
|
|
8139
|
+
method: 'programSubscribe',
|
|
8140
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
8141
|
+
}, args);
|
|
7983
8142
|
}
|
|
7984
8143
|
/**
|
|
7985
8144
|
* Deregister an account notification callback
|
|
7986
8145
|
*
|
|
7987
|
-
* @param id subscription id to deregister
|
|
8146
|
+
* @param id client subscription id to deregister
|
|
7988
8147
|
*/
|
|
7989
8148
|
|
|
7990
8149
|
|
|
7991
|
-
async removeProgramAccountChangeListener(
|
|
7992
|
-
|
|
7993
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7994
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7995
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7996
|
-
|
|
7997
|
-
this._updateSubscriptions();
|
|
7998
|
-
} else {
|
|
7999
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
8000
|
-
}
|
|
8150
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
8151
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
8001
8152
|
}
|
|
8002
8153
|
/**
|
|
8003
8154
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -8005,35 +8156,26 @@ class Connection {
|
|
|
8005
8156
|
|
|
8006
8157
|
|
|
8007
8158
|
onLogs(filter, callback, commitment) {
|
|
8008
|
-
const
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
commitment,
|
|
8013
|
-
subscriptionId: null
|
|
8014
|
-
};
|
|
8015
|
-
|
|
8016
|
-
this._updateSubscriptions();
|
|
8159
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
8160
|
+
mentions: [filter.toString()]
|
|
8161
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8162
|
+
);
|
|
8017
8163
|
|
|
8018
|
-
return
|
|
8164
|
+
return this._makeSubscription({
|
|
8165
|
+
callback,
|
|
8166
|
+
method: 'logsSubscribe',
|
|
8167
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
8168
|
+
}, args);
|
|
8019
8169
|
}
|
|
8020
8170
|
/**
|
|
8021
8171
|
* Deregister a logs callback.
|
|
8022
8172
|
*
|
|
8023
|
-
* @param id subscription id to deregister.
|
|
8173
|
+
* @param id client subscription id to deregister.
|
|
8024
8174
|
*/
|
|
8025
8175
|
|
|
8026
8176
|
|
|
8027
|
-
async removeOnLogsListener(
|
|
8028
|
-
|
|
8029
|
-
const subInfo = this._logsSubscriptions[id];
|
|
8030
|
-
delete this._logsSubscriptions[id];
|
|
8031
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
8032
|
-
|
|
8033
|
-
this._updateSubscriptions();
|
|
8034
|
-
} else {
|
|
8035
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
8036
|
-
}
|
|
8177
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
8178
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
8037
8179
|
}
|
|
8038
8180
|
/**
|
|
8039
8181
|
* @internal
|
|
@@ -8041,17 +8183,12 @@ class Connection {
|
|
|
8041
8183
|
|
|
8042
8184
|
|
|
8043
8185
|
_wsOnLogsNotification(notification) {
|
|
8044
|
-
const
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
const sub = this._logsSubscriptions[id];
|
|
8186
|
+
const {
|
|
8187
|
+
result,
|
|
8188
|
+
subscription
|
|
8189
|
+
} = superstruct.create(notification, LogsNotificationResult);
|
|
8049
8190
|
|
|
8050
|
-
|
|
8051
|
-
sub.callback(res.result.value, res.result.context);
|
|
8052
|
-
return;
|
|
8053
|
-
}
|
|
8054
|
-
}
|
|
8191
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
8055
8192
|
}
|
|
8056
8193
|
/**
|
|
8057
8194
|
* @internal
|
|
@@ -8059,14 +8196,12 @@ class Connection {
|
|
|
8059
8196
|
|
|
8060
8197
|
|
|
8061
8198
|
_wsOnSlotNotification(notification) {
|
|
8062
|
-
const
|
|
8199
|
+
const {
|
|
8200
|
+
result,
|
|
8201
|
+
subscription
|
|
8202
|
+
} = superstruct.create(notification, SlotNotificationResult);
|
|
8063
8203
|
|
|
8064
|
-
|
|
8065
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8066
|
-
sub.callback(res.result);
|
|
8067
|
-
return;
|
|
8068
|
-
}
|
|
8069
|
-
}
|
|
8204
|
+
this._handleServerNotification(subscription, [result]);
|
|
8070
8205
|
}
|
|
8071
8206
|
/**
|
|
8072
8207
|
* Register a callback to be invoked upon slot changes
|
|
@@ -8077,33 +8212,23 @@ class Connection {
|
|
|
8077
8212
|
|
|
8078
8213
|
|
|
8079
8214
|
onSlotChange(callback) {
|
|
8080
|
-
|
|
8081
|
-
this._slotSubscriptions[id] = {
|
|
8215
|
+
return this._makeSubscription({
|
|
8082
8216
|
callback,
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
return id;
|
|
8217
|
+
method: 'slotSubscribe',
|
|
8218
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
8219
|
+
}, []
|
|
8220
|
+
/* args */
|
|
8221
|
+
);
|
|
8089
8222
|
}
|
|
8090
8223
|
/**
|
|
8091
8224
|
* Deregister a slot notification callback
|
|
8092
8225
|
*
|
|
8093
|
-
* @param id subscription id to deregister
|
|
8226
|
+
* @param id client subscription id to deregister
|
|
8094
8227
|
*/
|
|
8095
8228
|
|
|
8096
8229
|
|
|
8097
|
-
async removeSlotChangeListener(
|
|
8098
|
-
|
|
8099
|
-
const subInfo = this._slotSubscriptions[id];
|
|
8100
|
-
delete this._slotSubscriptions[id];
|
|
8101
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
8102
|
-
|
|
8103
|
-
this._updateSubscriptions();
|
|
8104
|
-
} else {
|
|
8105
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
8106
|
-
}
|
|
8230
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
8231
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
8107
8232
|
}
|
|
8108
8233
|
/**
|
|
8109
8234
|
* @internal
|
|
@@ -8111,14 +8236,12 @@ class Connection {
|
|
|
8111
8236
|
|
|
8112
8237
|
|
|
8113
8238
|
_wsOnSlotUpdatesNotification(notification) {
|
|
8114
|
-
const
|
|
8239
|
+
const {
|
|
8240
|
+
result,
|
|
8241
|
+
subscription
|
|
8242
|
+
} = superstruct.create(notification, SlotUpdateNotificationResult);
|
|
8115
8243
|
|
|
8116
|
-
|
|
8117
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8118
|
-
sub.callback(res.result);
|
|
8119
|
-
return;
|
|
8120
|
-
}
|
|
8121
|
-
}
|
|
8244
|
+
this._handleServerNotification(subscription, [result]);
|
|
8122
8245
|
}
|
|
8123
8246
|
/**
|
|
8124
8247
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -8130,32 +8253,36 @@ class Connection {
|
|
|
8130
8253
|
|
|
8131
8254
|
|
|
8132
8255
|
onSlotUpdate(callback) {
|
|
8133
|
-
|
|
8134
|
-
this._slotUpdateSubscriptions[id] = {
|
|
8256
|
+
return this._makeSubscription({
|
|
8135
8257
|
callback,
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
return id;
|
|
8258
|
+
method: 'slotsUpdatesSubscribe',
|
|
8259
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
8260
|
+
}, []
|
|
8261
|
+
/* args */
|
|
8262
|
+
);
|
|
8142
8263
|
}
|
|
8143
8264
|
/**
|
|
8144
8265
|
* Deregister a slot update notification callback
|
|
8145
8266
|
*
|
|
8146
|
-
* @param id subscription id to deregister
|
|
8267
|
+
* @param id client subscription id to deregister
|
|
8147
8268
|
*/
|
|
8148
8269
|
|
|
8149
8270
|
|
|
8150
|
-
async removeSlotUpdateListener(
|
|
8151
|
-
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8271
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
8272
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
8273
|
+
}
|
|
8274
|
+
/**
|
|
8275
|
+
* @internal
|
|
8276
|
+
*/
|
|
8155
8277
|
|
|
8156
|
-
|
|
8278
|
+
|
|
8279
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
8280
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8281
|
+
|
|
8282
|
+
if (dispose) {
|
|
8283
|
+
await dispose();
|
|
8157
8284
|
} else {
|
|
8158
|
-
console.warn(
|
|
8285
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
8159
8286
|
}
|
|
8160
8287
|
}
|
|
8161
8288
|
|
|
@@ -8202,30 +8329,34 @@ class Connection {
|
|
|
8202
8329
|
|
|
8203
8330
|
|
|
8204
8331
|
_wsOnSignatureNotification(notification) {
|
|
8205
|
-
const
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
|
|
8213
|
-
|
|
8214
|
-
|
|
8215
|
-
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
|
|
8219
|
-
|
|
8220
|
-
|
|
8221
|
-
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8225
|
-
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8332
|
+
const {
|
|
8333
|
+
result,
|
|
8334
|
+
subscription
|
|
8335
|
+
} = superstruct.create(notification, SignatureNotificationResult);
|
|
8336
|
+
|
|
8337
|
+
if (result.value !== 'receivedSignature') {
|
|
8338
|
+
/**
|
|
8339
|
+
* Special case.
|
|
8340
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
8341
|
+
* subscription on the server side. We need to track which of these
|
|
8342
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
8343
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
8344
|
+
* (in which case we must tear down the server subscription) or an
|
|
8345
|
+
* already-processed signature (in which case the client can simply
|
|
8346
|
+
* clear out the subscription locally without telling the server).
|
|
8347
|
+
*
|
|
8348
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
8349
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
8350
|
+
*/
|
|
8351
|
+
this._subscriptionsAutoDisposedByRpc.add(subscription);
|
|
8352
|
+
}
|
|
8353
|
+
|
|
8354
|
+
this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
|
|
8355
|
+
type: 'received'
|
|
8356
|
+
}, result.context] : [{
|
|
8357
|
+
type: 'status',
|
|
8358
|
+
result: result.value
|
|
8359
|
+
}, result.context]);
|
|
8229
8360
|
}
|
|
8230
8361
|
/**
|
|
8231
8362
|
* Register a callback to be invoked upon signature updates
|
|
@@ -8238,23 +8369,26 @@ class Connection {
|
|
|
8238
8369
|
|
|
8239
8370
|
|
|
8240
8371
|
onSignature(signature, callback, commitment) {
|
|
8241
|
-
const
|
|
8242
|
-
|
|
8243
|
-
|
|
8372
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8373
|
+
);
|
|
8374
|
+
|
|
8375
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8244
8376
|
callback: (notification, context) => {
|
|
8245
8377
|
if (notification.type === 'status') {
|
|
8246
|
-
callback(notification.result, context);
|
|
8378
|
+
callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8379
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8380
|
+
|
|
8381
|
+
try {
|
|
8382
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8383
|
+
} catch {// Already removed.
|
|
8384
|
+
}
|
|
8247
8385
|
}
|
|
8248
8386
|
},
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
subscriptionId: null
|
|
8253
|
-
};
|
|
8387
|
+
method: 'signatureSubscribe',
|
|
8388
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8389
|
+
}, args);
|
|
8254
8390
|
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
return id;
|
|
8391
|
+
return clientSubscriptionId;
|
|
8258
8392
|
}
|
|
8259
8393
|
/**
|
|
8260
8394
|
* Register a callback to be invoked when a transaction is
|
|
@@ -8269,35 +8403,43 @@ class Connection {
|
|
|
8269
8403
|
|
|
8270
8404
|
|
|
8271
8405
|
onSignatureWithOptions(signature, callback, options) {
|
|
8272
|
-
const
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
options
|
|
8277
|
-
|
|
8406
|
+
const {
|
|
8407
|
+
commitment,
|
|
8408
|
+
...extra
|
|
8409
|
+
} = { ...options,
|
|
8410
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8411
|
+
|
|
8278
8412
|
};
|
|
8279
8413
|
|
|
8280
|
-
this.
|
|
8414
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
8415
|
+
/* encoding */
|
|
8416
|
+
, extra);
|
|
8281
8417
|
|
|
8282
|
-
|
|
8418
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8419
|
+
callback: (notification, context) => {
|
|
8420
|
+
callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8421
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8422
|
+
|
|
8423
|
+
try {
|
|
8424
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8425
|
+
} catch {// Already removed.
|
|
8426
|
+
}
|
|
8427
|
+
},
|
|
8428
|
+
method: 'signatureSubscribe',
|
|
8429
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8430
|
+
}, args);
|
|
8431
|
+
|
|
8432
|
+
return clientSubscriptionId;
|
|
8283
8433
|
}
|
|
8284
8434
|
/**
|
|
8285
8435
|
* Deregister a signature notification callback
|
|
8286
8436
|
*
|
|
8287
|
-
* @param id subscription id to deregister
|
|
8437
|
+
* @param id client subscription id to deregister
|
|
8288
8438
|
*/
|
|
8289
8439
|
|
|
8290
8440
|
|
|
8291
|
-
async removeSignatureListener(
|
|
8292
|
-
|
|
8293
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
8294
|
-
delete this._signatureSubscriptions[id];
|
|
8295
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
8296
|
-
|
|
8297
|
-
this._updateSubscriptions();
|
|
8298
|
-
} else {
|
|
8299
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
8300
|
-
}
|
|
8441
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
8442
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
8301
8443
|
}
|
|
8302
8444
|
/**
|
|
8303
8445
|
* @internal
|
|
@@ -8305,14 +8447,12 @@ class Connection {
|
|
|
8305
8447
|
|
|
8306
8448
|
|
|
8307
8449
|
_wsOnRootNotification(notification) {
|
|
8308
|
-
const
|
|
8450
|
+
const {
|
|
8451
|
+
result,
|
|
8452
|
+
subscription
|
|
8453
|
+
} = superstruct.create(notification, RootNotificationResult);
|
|
8309
8454
|
|
|
8310
|
-
|
|
8311
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8312
|
-
sub.callback(res.result);
|
|
8313
|
-
return;
|
|
8314
|
-
}
|
|
8315
|
-
}
|
|
8455
|
+
this._handleServerNotification(subscription, [result]);
|
|
8316
8456
|
}
|
|
8317
8457
|
/**
|
|
8318
8458
|
* Register a callback to be invoked upon root changes
|
|
@@ -8323,33 +8463,23 @@ class Connection {
|
|
|
8323
8463
|
|
|
8324
8464
|
|
|
8325
8465
|
onRootChange(callback) {
|
|
8326
|
-
|
|
8327
|
-
this._rootSubscriptions[id] = {
|
|
8466
|
+
return this._makeSubscription({
|
|
8328
8467
|
callback,
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
return id;
|
|
8468
|
+
method: 'rootSubscribe',
|
|
8469
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
8470
|
+
}, []
|
|
8471
|
+
/* args */
|
|
8472
|
+
);
|
|
8335
8473
|
}
|
|
8336
8474
|
/**
|
|
8337
8475
|
* Deregister a root notification callback
|
|
8338
8476
|
*
|
|
8339
|
-
* @param id subscription id to deregister
|
|
8477
|
+
* @param id client subscription id to deregister
|
|
8340
8478
|
*/
|
|
8341
8479
|
|
|
8342
8480
|
|
|
8343
|
-
async removeRootChangeListener(
|
|
8344
|
-
|
|
8345
|
-
const subInfo = this._rootSubscriptions[id];
|
|
8346
|
-
delete this._rootSubscriptions[id];
|
|
8347
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
8348
|
-
|
|
8349
|
-
this._updateSubscriptions();
|
|
8350
|
-
} else {
|
|
8351
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
8352
|
-
}
|
|
8481
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
8482
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
8353
8483
|
}
|
|
8354
8484
|
|
|
8355
8485
|
}
|