@solana/web3.js 1.40.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 +648 -388
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +646 -388
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +648 -388
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +96 -30
- package/lib/index.esm.js +646 -388
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +680 -629
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +2 -24
- package/lib/index.iife.min.js.map +1 -1
- package/package.json +11 -8
- package/src/compute-budget.ts +189 -0
- package/src/connection.ts +657 -486
- package/src/index.ts +1 -0
- package/src/loader.ts +2 -1
- package/src/message.ts +1 -1
- package/src/transaction-constants.ts +10 -0
- package/src/transaction.ts +7 -16
package/lib/index.browser.cjs.js
CHANGED
|
@@ -2108,6 +2108,16 @@ class Account {
|
|
|
2108
2108
|
|
|
2109
2109
|
const BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey('BPFLoader1111111111111111111111111111111111');
|
|
2110
2110
|
|
|
2111
|
+
/**
|
|
2112
|
+
* Maximum over-the-wire size of a Transaction
|
|
2113
|
+
*
|
|
2114
|
+
* 1280 is IPv6 minimum MTU
|
|
2115
|
+
* 40 bytes is the size of the IPv6 header
|
|
2116
|
+
* 8 bytes is the size of the fragment header
|
|
2117
|
+
*/
|
|
2118
|
+
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
2119
|
+
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
2120
|
+
|
|
2111
2121
|
/**
|
|
2112
2122
|
* Layout for a public key
|
|
2113
2123
|
*/
|
|
@@ -2367,20 +2377,8 @@ function assert (condition, message) {
|
|
|
2367
2377
|
|
|
2368
2378
|
/**
|
|
2369
2379
|
* Default (empty) signature
|
|
2370
|
-
*
|
|
2371
|
-
* Signatures are 64 bytes in length
|
|
2372
2380
|
*/
|
|
2373
|
-
const DEFAULT_SIGNATURE = buffer.Buffer.alloc(
|
|
2374
|
-
/**
|
|
2375
|
-
* Maximum over-the-wire size of a Transaction
|
|
2376
|
-
*
|
|
2377
|
-
* 1280 is IPv6 minimum MTU
|
|
2378
|
-
* 40 bytes is the size of the IPv6 header
|
|
2379
|
-
* 8 bytes is the size of the fragment header
|
|
2380
|
-
*/
|
|
2381
|
-
|
|
2382
|
-
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
2383
|
-
const SIGNATURE_LENGTH = 64;
|
|
2381
|
+
const DEFAULT_SIGNATURE = buffer.Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
2384
2382
|
/**
|
|
2385
2383
|
* Account metadata used to define instructions
|
|
2386
2384
|
*/
|
|
@@ -3010,8 +3008,8 @@ class Transaction {
|
|
|
3010
3008
|
let signatures = [];
|
|
3011
3009
|
|
|
3012
3010
|
for (let i = 0; i < signatureCount; i++) {
|
|
3013
|
-
const signature = byteArray.slice(0,
|
|
3014
|
-
byteArray = byteArray.slice(
|
|
3011
|
+
const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
|
|
3012
|
+
byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
|
|
3015
3013
|
signatures.push(bs58__default["default"].encode(buffer.Buffer.from(signature)));
|
|
3016
3014
|
}
|
|
3017
3015
|
|
|
@@ -3900,11 +3898,11 @@ class SystemProgram {
|
|
|
3900
3898
|
}
|
|
3901
3899
|
SystemProgram.programId = new PublicKey('11111111111111111111111111111111');
|
|
3902
3900
|
|
|
3903
|
-
// Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
|
|
3904
3901
|
// rest of the Transaction fields
|
|
3905
3902
|
//
|
|
3906
3903
|
// TODO: replace 300 with a proper constant for the size of the other
|
|
3907
3904
|
// Transaction fields
|
|
3905
|
+
|
|
3908
3906
|
const CHUNK_SIZE = PACKET_DATA_SIZE - 300;
|
|
3909
3907
|
/**
|
|
3910
3908
|
* Program loader interface
|
|
@@ -4104,6 +4102,136 @@ class BpfLoader {
|
|
|
4104
4102
|
|
|
4105
4103
|
}
|
|
4106
4104
|
|
|
4105
|
+
/**
|
|
4106
|
+
* Compute Budget Instruction class
|
|
4107
|
+
*/
|
|
4108
|
+
|
|
4109
|
+
class ComputeBudgetInstruction {
|
|
4110
|
+
/**
|
|
4111
|
+
* @internal
|
|
4112
|
+
*/
|
|
4113
|
+
constructor() {}
|
|
4114
|
+
/**
|
|
4115
|
+
* Decode a compute budget instruction and retrieve the instruction type.
|
|
4116
|
+
*/
|
|
4117
|
+
|
|
4118
|
+
|
|
4119
|
+
static decodeInstructionType(instruction) {
|
|
4120
|
+
this.checkProgramId(instruction.programId);
|
|
4121
|
+
const instructionTypeLayout = BufferLayout__namespace.u8('instruction');
|
|
4122
|
+
const typeIndex = instructionTypeLayout.decode(instruction.data);
|
|
4123
|
+
let type;
|
|
4124
|
+
|
|
4125
|
+
for (const [ixType, layout] of Object.entries(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS)) {
|
|
4126
|
+
if (layout.index == typeIndex) {
|
|
4127
|
+
type = ixType;
|
|
4128
|
+
break;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
|
|
4132
|
+
if (!type) {
|
|
4133
|
+
throw new Error('Instruction type incorrect; not a ComputeBudgetInstruction');
|
|
4134
|
+
}
|
|
4135
|
+
|
|
4136
|
+
return type;
|
|
4137
|
+
}
|
|
4138
|
+
/**
|
|
4139
|
+
* Decode request units compute budget instruction and retrieve the instruction params.
|
|
4140
|
+
*/
|
|
4141
|
+
|
|
4142
|
+
|
|
4143
|
+
static decodeRequestUnits(instruction) {
|
|
4144
|
+
this.checkProgramId(instruction.programId);
|
|
4145
|
+
const {
|
|
4146
|
+
units,
|
|
4147
|
+
additionalFee
|
|
4148
|
+
} = decodeData(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits, instruction.data);
|
|
4149
|
+
return {
|
|
4150
|
+
units,
|
|
4151
|
+
additionalFee
|
|
4152
|
+
};
|
|
4153
|
+
}
|
|
4154
|
+
/**
|
|
4155
|
+
* Decode request heap frame compute budget instruction and retrieve the instruction params.
|
|
4156
|
+
*/
|
|
4157
|
+
|
|
4158
|
+
|
|
4159
|
+
static decodeRequestHeapFrame(instruction) {
|
|
4160
|
+
this.checkProgramId(instruction.programId);
|
|
4161
|
+
const {
|
|
4162
|
+
bytes
|
|
4163
|
+
} = decodeData(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame, instruction.data);
|
|
4164
|
+
return {
|
|
4165
|
+
bytes
|
|
4166
|
+
};
|
|
4167
|
+
}
|
|
4168
|
+
/**
|
|
4169
|
+
* @internal
|
|
4170
|
+
*/
|
|
4171
|
+
|
|
4172
|
+
|
|
4173
|
+
static checkProgramId(programId) {
|
|
4174
|
+
if (!programId.equals(ComputeBudgetProgram.programId)) {
|
|
4175
|
+
throw new Error('invalid instruction; programId is not ComputeBudgetProgram');
|
|
4176
|
+
}
|
|
4177
|
+
}
|
|
4178
|
+
|
|
4179
|
+
}
|
|
4180
|
+
/**
|
|
4181
|
+
* An enumeration of valid ComputeBudgetInstructionType's
|
|
4182
|
+
*/
|
|
4183
|
+
|
|
4184
|
+
/**
|
|
4185
|
+
* An enumeration of valid ComputeBudget InstructionType's
|
|
4186
|
+
* @internal
|
|
4187
|
+
*/
|
|
4188
|
+
const COMPUTE_BUDGET_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
4189
|
+
RequestUnits: {
|
|
4190
|
+
index: 0,
|
|
4191
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u8('instruction'), BufferLayout__namespace.u32('units'), BufferLayout__namespace.u32('additionalFee')])
|
|
4192
|
+
},
|
|
4193
|
+
RequestHeapFrame: {
|
|
4194
|
+
index: 1,
|
|
4195
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u8('instruction'), BufferLayout__namespace.u32('bytes')])
|
|
4196
|
+
}
|
|
4197
|
+
});
|
|
4198
|
+
/**
|
|
4199
|
+
* Factory class for transaction instructions to interact with the Compute Budget program
|
|
4200
|
+
*/
|
|
4201
|
+
|
|
4202
|
+
class ComputeBudgetProgram {
|
|
4203
|
+
/**
|
|
4204
|
+
* @internal
|
|
4205
|
+
*/
|
|
4206
|
+
constructor() {}
|
|
4207
|
+
/**
|
|
4208
|
+
* Public key that identifies the Compute Budget program
|
|
4209
|
+
*/
|
|
4210
|
+
|
|
4211
|
+
|
|
4212
|
+
static requestUnits(params) {
|
|
4213
|
+
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits;
|
|
4214
|
+
const data = encodeData(type, params);
|
|
4215
|
+
return new TransactionInstruction({
|
|
4216
|
+
keys: [],
|
|
4217
|
+
programId: this.programId,
|
|
4218
|
+
data
|
|
4219
|
+
});
|
|
4220
|
+
}
|
|
4221
|
+
|
|
4222
|
+
static requestHeapFrame(params) {
|
|
4223
|
+
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame;
|
|
4224
|
+
const data = encodeData(type, params);
|
|
4225
|
+
return new TransactionInstruction({
|
|
4226
|
+
keys: [],
|
|
4227
|
+
programId: this.programId,
|
|
4228
|
+
data
|
|
4229
|
+
});
|
|
4230
|
+
}
|
|
4231
|
+
|
|
4232
|
+
}
|
|
4233
|
+
ComputeBudgetProgram.programId = new PublicKey('ComputeBudget111111111111111111111111111111');
|
|
4234
|
+
|
|
4107
4235
|
var browserPonyfill = {exports: {}};
|
|
4108
4236
|
|
|
4109
4237
|
(function (module, exports) {
|
|
@@ -4665,6 +4793,82 @@ module.exports = exports;
|
|
|
4665
4793
|
|
|
4666
4794
|
var crossFetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfill.exports);
|
|
4667
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
|
+
|
|
4668
4872
|
const MINIMUM_SLOT_PER_EPOCH = 32; // Returns the number of trailing zeros in the binary representation of self.
|
|
4669
4873
|
|
|
4670
4874
|
function trailingZeros(n) {
|
|
@@ -4831,6 +5035,12 @@ const BufferFromRawAccountData = superstruct.coerce(superstruct.instance(buffer.
|
|
|
4831
5035
|
*/
|
|
4832
5036
|
|
|
4833
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
|
+
*/
|
|
4834
5044
|
|
|
4835
5045
|
/**
|
|
4836
5046
|
* @internal
|
|
@@ -5699,14 +5909,9 @@ const LogsNotificationResult = superstruct.type({
|
|
|
5699
5909
|
* Filter for log subscriptions.
|
|
5700
5910
|
*/
|
|
5701
5911
|
|
|
5702
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5703
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5704
|
-
}
|
|
5705
5912
|
/**
|
|
5706
5913
|
* A connection to a fullnode JSON RPC endpoint
|
|
5707
5914
|
*/
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
5915
|
class Connection {
|
|
5711
5916
|
/** @internal */
|
|
5712
5917
|
|
|
@@ -5730,21 +5935,13 @@ class Connection {
|
|
|
5730
5935
|
|
|
5731
5936
|
/** @internal */
|
|
5732
5937
|
|
|
5733
|
-
/** @internal
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
/** @internal */
|
|
5742
|
-
|
|
5743
|
-
/** @internal */
|
|
5744
|
-
|
|
5745
|
-
/** @internal */
|
|
5746
|
-
|
|
5747
|
-
/** @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
|
+
*/
|
|
5748
5945
|
|
|
5749
5946
|
/** @internal */
|
|
5750
5947
|
|
|
@@ -5760,7 +5957,19 @@ class Connection {
|
|
|
5760
5957
|
|
|
5761
5958
|
/** @internal */
|
|
5762
5959
|
|
|
5763
|
-
/**
|
|
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
|
+
*/
|
|
5764
5973
|
|
|
5765
5974
|
/** @internal */
|
|
5766
5975
|
|
|
@@ -5782,6 +5991,7 @@ class Connection {
|
|
|
5782
5991
|
this._rpcWebSocketConnected = false;
|
|
5783
5992
|
this._rpcWebSocketHeartbeat = null;
|
|
5784
5993
|
this._rpcWebSocketIdleTimeout = null;
|
|
5994
|
+
this._rpcWebSocketGeneration = 0;
|
|
5785
5995
|
this._disableBlockhashCaching = false;
|
|
5786
5996
|
this._pollingBlockhash = false;
|
|
5787
5997
|
this._blockhashInfo = {
|
|
@@ -5790,20 +6000,11 @@ class Connection {
|
|
|
5790
6000
|
transactionSignatures: [],
|
|
5791
6001
|
simulatedSignatures: []
|
|
5792
6002
|
};
|
|
5793
|
-
this.
|
|
5794
|
-
this.
|
|
5795
|
-
this.
|
|
5796
|
-
this.
|
|
5797
|
-
this.
|
|
5798
|
-
this._rootSubscriptions = {};
|
|
5799
|
-
this._signatureSubscriptionCounter = 0;
|
|
5800
|
-
this._signatureSubscriptions = {};
|
|
5801
|
-
this._slotSubscriptionCounter = 0;
|
|
5802
|
-
this._slotSubscriptions = {};
|
|
5803
|
-
this._logsSubscriptionCounter = 0;
|
|
5804
|
-
this._logsSubscriptions = {};
|
|
5805
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5806
|
-
this._slotUpdateSubscriptions = {};
|
|
6003
|
+
this._nextClientSubscriptionId = 0;
|
|
6004
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
6005
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
6006
|
+
this._subscriptionsByHash = {};
|
|
6007
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5807
6008
|
let url = new URL(endpoint);
|
|
5808
6009
|
const useHttps = url.protocol === 'https:';
|
|
5809
6010
|
let wsEndpoint;
|
|
@@ -7571,6 +7772,8 @@ class Connection {
|
|
|
7571
7772
|
|
|
7572
7773
|
|
|
7573
7774
|
_wsOnClose(code) {
|
|
7775
|
+
this._rpcWebSocketGeneration++;
|
|
7776
|
+
|
|
7574
7777
|
if (this._rpcWebSocketHeartbeat) {
|
|
7575
7778
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7576
7779
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7584,85 +7787,20 @@ class Connection {
|
|
|
7584
7787
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7585
7788
|
|
|
7586
7789
|
|
|
7587
|
-
this.
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7595
|
-
if (sub.subscriptionId == null) {
|
|
7596
|
-
sub.subscriptionId = 'subscribing';
|
|
7597
|
-
|
|
7598
|
-
try {
|
|
7599
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7600
|
-
|
|
7601
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7602
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7603
|
-
sub.subscriptionId = id;
|
|
7604
|
-
}
|
|
7605
|
-
} catch (err) {
|
|
7606
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7607
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7608
|
-
sub.subscriptionId = null;
|
|
7609
|
-
}
|
|
7610
|
-
|
|
7611
|
-
if (err instanceof Error) {
|
|
7612
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7613
|
-
}
|
|
7614
|
-
}
|
|
7615
|
-
}
|
|
7616
|
-
}
|
|
7617
|
-
/**
|
|
7618
|
-
* @internal
|
|
7619
|
-
*/
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7623
|
-
const subscriptionId = sub.subscriptionId;
|
|
7624
|
-
|
|
7625
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7626
|
-
const unsubscribeId = subscriptionId;
|
|
7627
|
-
|
|
7628
|
-
try {
|
|
7629
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7630
|
-
} catch (err) {
|
|
7631
|
-
if (err instanceof Error) {
|
|
7632
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7633
|
-
}
|
|
7634
|
-
}
|
|
7635
|
-
}
|
|
7636
|
-
}
|
|
7637
|
-
/**
|
|
7638
|
-
* @internal
|
|
7639
|
-
*/
|
|
7640
|
-
|
|
7641
|
-
|
|
7642
|
-
_resetSubscriptions() {
|
|
7643
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7644
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7645
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7646
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7647
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7648
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7649
|
-
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
|
+
});
|
|
7650
7796
|
}
|
|
7651
7797
|
/**
|
|
7652
7798
|
* @internal
|
|
7653
7799
|
*/
|
|
7654
7800
|
|
|
7655
7801
|
|
|
7656
|
-
_updateSubscriptions() {
|
|
7657
|
-
|
|
7658
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7659
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7660
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7661
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7662
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7663
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7664
|
-
|
|
7665
|
-
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) {
|
|
7666
7804
|
if (this._rpcWebSocketConnected) {
|
|
7667
7805
|
this._rpcWebSocketConnected = false;
|
|
7668
7806
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7694,60 +7832,167 @@ class Connection {
|
|
|
7694
7832
|
return;
|
|
7695
7833
|
}
|
|
7696
7834
|
|
|
7697
|
-
|
|
7698
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7835
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7699
7836
|
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
for (let id of programKeys) {
|
|
7704
|
-
const sub = this._programAccountChangeSubscriptions[id];
|
|
7837
|
+
const isCurrentConnectionStillActive = () => {
|
|
7838
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7839
|
+
};
|
|
7705
7840
|
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
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];
|
|
7710
7847
|
|
|
7711
|
-
|
|
7712
|
-
|
|
7848
|
+
if (subscription === undefined) {
|
|
7849
|
+
// This entry has since been deleted. Skip.
|
|
7850
|
+
return;
|
|
7851
|
+
}
|
|
7713
7852
|
|
|
7714
|
-
|
|
7715
|
-
|
|
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
|
+
}
|
|
7716
7875
|
|
|
7717
|
-
|
|
7718
|
-
|
|
7876
|
+
await this._updateSubscriptions();
|
|
7877
|
+
return;
|
|
7878
|
+
}
|
|
7719
7879
|
|
|
7720
|
-
|
|
7721
|
-
|
|
7880
|
+
await (async () => {
|
|
7881
|
+
const {
|
|
7882
|
+
args,
|
|
7883
|
+
method
|
|
7884
|
+
} = subscription;
|
|
7722
7885
|
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
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?
|
|
7727
7905
|
|
|
7728
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7729
|
-
}
|
|
7730
7906
|
|
|
7731
|
-
|
|
7732
|
-
|
|
7907
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7908
|
+
state: 'pending'
|
|
7909
|
+
};
|
|
7910
|
+
await this._updateSubscriptions();
|
|
7911
|
+
}
|
|
7912
|
+
})();
|
|
7913
|
+
break;
|
|
7733
7914
|
|
|
7734
|
-
|
|
7735
|
-
|
|
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
|
+
}
|
|
7736
7961
|
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7962
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7963
|
+
state: 'unsubscribed'
|
|
7964
|
+
};
|
|
7965
|
+
await this._updateSubscriptions();
|
|
7966
|
+
})();
|
|
7967
|
+
}
|
|
7740
7968
|
|
|
7741
|
-
|
|
7742
|
-
filter = {
|
|
7743
|
-
mentions: [sub.filter.toString()]
|
|
7744
|
-
};
|
|
7745
|
-
} else {
|
|
7746
|
-
filter = sub.filter;
|
|
7969
|
+
break;
|
|
7747
7970
|
}
|
|
7971
|
+
}));
|
|
7972
|
+
}
|
|
7973
|
+
/**
|
|
7974
|
+
* @internal
|
|
7975
|
+
*/
|
|
7976
|
+
|
|
7977
|
+
|
|
7978
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7979
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7748
7980
|
|
|
7749
|
-
|
|
7981
|
+
if (callbacks === undefined) {
|
|
7982
|
+
return;
|
|
7750
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
|
+
});
|
|
7751
7996
|
}
|
|
7752
7997
|
/**
|
|
7753
7998
|
* @internal
|
|
@@ -7755,14 +8000,71 @@ class Connection {
|
|
|
7755
8000
|
|
|
7756
8001
|
|
|
7757
8002
|
_wsOnAccountNotification(notification) {
|
|
7758
|
-
const
|
|
8003
|
+
const {
|
|
8004
|
+
result,
|
|
8005
|
+
subscription
|
|
8006
|
+
} = superstruct.create(notification, AccountNotificationResult);
|
|
7759
8007
|
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
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);
|
|
7765
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;
|
|
7766
8068
|
}
|
|
7767
8069
|
/**
|
|
7768
8070
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7775,35 +8077,24 @@ class Connection {
|
|
|
7775
8077
|
|
|
7776
8078
|
|
|
7777
8079
|
onAccountChange(publicKey, callback, commitment) {
|
|
7778
|
-
const
|
|
7779
|
-
|
|
7780
|
-
publicKey: publicKey.toBase58(),
|
|
7781
|
-
callback,
|
|
7782
|
-
commitment,
|
|
7783
|
-
subscriptionId: null
|
|
7784
|
-
};
|
|
7785
|
-
|
|
7786
|
-
this._updateSubscriptions();
|
|
8080
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8081
|
+
'base64');
|
|
7787
8082
|
|
|
7788
|
-
return
|
|
8083
|
+
return this._makeSubscription({
|
|
8084
|
+
callback,
|
|
8085
|
+
method: 'accountSubscribe',
|
|
8086
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
8087
|
+
}, args);
|
|
7789
8088
|
}
|
|
7790
8089
|
/**
|
|
7791
8090
|
* Deregister an account notification callback
|
|
7792
8091
|
*
|
|
7793
|
-
* @param id subscription id to deregister
|
|
8092
|
+
* @param id client subscription id to deregister
|
|
7794
8093
|
*/
|
|
7795
8094
|
|
|
7796
8095
|
|
|
7797
|
-
async removeAccountChangeListener(
|
|
7798
|
-
|
|
7799
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7800
|
-
delete this._accountChangeSubscriptions[id];
|
|
7801
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7802
|
-
|
|
7803
|
-
this._updateSubscriptions();
|
|
7804
|
-
} else {
|
|
7805
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7806
|
-
}
|
|
8096
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
8097
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7807
8098
|
}
|
|
7808
8099
|
/**
|
|
7809
8100
|
* @internal
|
|
@@ -7811,21 +8102,15 @@ class Connection {
|
|
|
7811
8102
|
|
|
7812
8103
|
|
|
7813
8104
|
_wsOnProgramAccountNotification(notification) {
|
|
7814
|
-
const
|
|
8105
|
+
const {
|
|
8106
|
+
result,
|
|
8107
|
+
subscription
|
|
8108
|
+
} = superstruct.create(notification, ProgramAccountNotificationResult);
|
|
7815
8109
|
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
|
|
7819
|
-
|
|
7820
|
-
context
|
|
7821
|
-
} = res.result;
|
|
7822
|
-
sub.callback({
|
|
7823
|
-
accountId: value.pubkey,
|
|
7824
|
-
accountInfo: value.account
|
|
7825
|
-
}, context);
|
|
7826
|
-
return;
|
|
7827
|
-
}
|
|
7828
|
-
}
|
|
8110
|
+
this._handleServerNotification(subscription, [{
|
|
8111
|
+
accountId: result.value.pubkey,
|
|
8112
|
+
accountInfo: result.value.account
|
|
8113
|
+
}, result.context]);
|
|
7829
8114
|
}
|
|
7830
8115
|
/**
|
|
7831
8116
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7840,36 +8125,30 @@ class Connection {
|
|
|
7840
8125
|
|
|
7841
8126
|
|
|
7842
8127
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7843
|
-
const
|
|
7844
|
-
|
|
7845
|
-
|
|
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({
|
|
7846
8138
|
callback,
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
};
|
|
7851
|
-
|
|
7852
|
-
this._updateSubscriptions();
|
|
7853
|
-
|
|
7854
|
-
return id;
|
|
8139
|
+
method: 'programSubscribe',
|
|
8140
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
8141
|
+
}, args);
|
|
7855
8142
|
}
|
|
7856
8143
|
/**
|
|
7857
8144
|
* Deregister an account notification callback
|
|
7858
8145
|
*
|
|
7859
|
-
* @param id subscription id to deregister
|
|
8146
|
+
* @param id client subscription id to deregister
|
|
7860
8147
|
*/
|
|
7861
8148
|
|
|
7862
8149
|
|
|
7863
|
-
async removeProgramAccountChangeListener(
|
|
7864
|
-
|
|
7865
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7866
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7867
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7868
|
-
|
|
7869
|
-
this._updateSubscriptions();
|
|
7870
|
-
} else {
|
|
7871
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
7872
|
-
}
|
|
8150
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
8151
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7873
8152
|
}
|
|
7874
8153
|
/**
|
|
7875
8154
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7877,35 +8156,26 @@ class Connection {
|
|
|
7877
8156
|
|
|
7878
8157
|
|
|
7879
8158
|
onLogs(filter, callback, commitment) {
|
|
7880
|
-
const
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7884
|
-
commitment,
|
|
7885
|
-
subscriptionId: null
|
|
7886
|
-
};
|
|
8159
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
8160
|
+
mentions: [filter.toString()]
|
|
8161
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8162
|
+
);
|
|
7887
8163
|
|
|
7888
|
-
this.
|
|
7889
|
-
|
|
7890
|
-
|
|
8164
|
+
return this._makeSubscription({
|
|
8165
|
+
callback,
|
|
8166
|
+
method: 'logsSubscribe',
|
|
8167
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
8168
|
+
}, args);
|
|
7891
8169
|
}
|
|
7892
8170
|
/**
|
|
7893
8171
|
* Deregister a logs callback.
|
|
7894
8172
|
*
|
|
7895
|
-
* @param id subscription id to deregister.
|
|
8173
|
+
* @param id client subscription id to deregister.
|
|
7896
8174
|
*/
|
|
7897
8175
|
|
|
7898
8176
|
|
|
7899
|
-
async removeOnLogsListener(
|
|
7900
|
-
|
|
7901
|
-
const subInfo = this._logsSubscriptions[id];
|
|
7902
|
-
delete this._logsSubscriptions[id];
|
|
7903
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
7904
|
-
|
|
7905
|
-
this._updateSubscriptions();
|
|
7906
|
-
} else {
|
|
7907
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
7908
|
-
}
|
|
8177
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
8178
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
7909
8179
|
}
|
|
7910
8180
|
/**
|
|
7911
8181
|
* @internal
|
|
@@ -7913,17 +8183,12 @@ class Connection {
|
|
|
7913
8183
|
|
|
7914
8184
|
|
|
7915
8185
|
_wsOnLogsNotification(notification) {
|
|
7916
|
-
const
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
const sub = this._logsSubscriptions[id];
|
|
8186
|
+
const {
|
|
8187
|
+
result,
|
|
8188
|
+
subscription
|
|
8189
|
+
} = superstruct.create(notification, LogsNotificationResult);
|
|
7921
8190
|
|
|
7922
|
-
|
|
7923
|
-
sub.callback(res.result.value, res.result.context);
|
|
7924
|
-
return;
|
|
7925
|
-
}
|
|
7926
|
-
}
|
|
8191
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7927
8192
|
}
|
|
7928
8193
|
/**
|
|
7929
8194
|
* @internal
|
|
@@ -7931,14 +8196,12 @@ class Connection {
|
|
|
7931
8196
|
|
|
7932
8197
|
|
|
7933
8198
|
_wsOnSlotNotification(notification) {
|
|
7934
|
-
const
|
|
8199
|
+
const {
|
|
8200
|
+
result,
|
|
8201
|
+
subscription
|
|
8202
|
+
} = superstruct.create(notification, SlotNotificationResult);
|
|
7935
8203
|
|
|
7936
|
-
|
|
7937
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7938
|
-
sub.callback(res.result);
|
|
7939
|
-
return;
|
|
7940
|
-
}
|
|
7941
|
-
}
|
|
8204
|
+
this._handleServerNotification(subscription, [result]);
|
|
7942
8205
|
}
|
|
7943
8206
|
/**
|
|
7944
8207
|
* Register a callback to be invoked upon slot changes
|
|
@@ -7949,33 +8212,23 @@ class Connection {
|
|
|
7949
8212
|
|
|
7950
8213
|
|
|
7951
8214
|
onSlotChange(callback) {
|
|
7952
|
-
|
|
7953
|
-
this._slotSubscriptions[id] = {
|
|
8215
|
+
return this._makeSubscription({
|
|
7954
8216
|
callback,
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
return id;
|
|
8217
|
+
method: 'slotSubscribe',
|
|
8218
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
8219
|
+
}, []
|
|
8220
|
+
/* args */
|
|
8221
|
+
);
|
|
7961
8222
|
}
|
|
7962
8223
|
/**
|
|
7963
8224
|
* Deregister a slot notification callback
|
|
7964
8225
|
*
|
|
7965
|
-
* @param id subscription id to deregister
|
|
8226
|
+
* @param id client subscription id to deregister
|
|
7966
8227
|
*/
|
|
7967
8228
|
|
|
7968
8229
|
|
|
7969
|
-
async removeSlotChangeListener(
|
|
7970
|
-
|
|
7971
|
-
const subInfo = this._slotSubscriptions[id];
|
|
7972
|
-
delete this._slotSubscriptions[id];
|
|
7973
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
7974
|
-
|
|
7975
|
-
this._updateSubscriptions();
|
|
7976
|
-
} else {
|
|
7977
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
7978
|
-
}
|
|
8230
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
8231
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
7979
8232
|
}
|
|
7980
8233
|
/**
|
|
7981
8234
|
* @internal
|
|
@@ -7983,14 +8236,12 @@ class Connection {
|
|
|
7983
8236
|
|
|
7984
8237
|
|
|
7985
8238
|
_wsOnSlotUpdatesNotification(notification) {
|
|
7986
|
-
const
|
|
8239
|
+
const {
|
|
8240
|
+
result,
|
|
8241
|
+
subscription
|
|
8242
|
+
} = superstruct.create(notification, SlotUpdateNotificationResult);
|
|
7987
8243
|
|
|
7988
|
-
|
|
7989
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7990
|
-
sub.callback(res.result);
|
|
7991
|
-
return;
|
|
7992
|
-
}
|
|
7993
|
-
}
|
|
8244
|
+
this._handleServerNotification(subscription, [result]);
|
|
7994
8245
|
}
|
|
7995
8246
|
/**
|
|
7996
8247
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -8002,32 +8253,36 @@ class Connection {
|
|
|
8002
8253
|
|
|
8003
8254
|
|
|
8004
8255
|
onSlotUpdate(callback) {
|
|
8005
|
-
|
|
8006
|
-
this._slotUpdateSubscriptions[id] = {
|
|
8256
|
+
return this._makeSubscription({
|
|
8007
8257
|
callback,
|
|
8008
|
-
|
|
8009
|
-
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
return id;
|
|
8258
|
+
method: 'slotsUpdatesSubscribe',
|
|
8259
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
8260
|
+
}, []
|
|
8261
|
+
/* args */
|
|
8262
|
+
);
|
|
8014
8263
|
}
|
|
8015
8264
|
/**
|
|
8016
8265
|
* Deregister a slot update notification callback
|
|
8017
8266
|
*
|
|
8018
|
-
* @param id subscription id to deregister
|
|
8267
|
+
* @param id client subscription id to deregister
|
|
8019
8268
|
*/
|
|
8020
8269
|
|
|
8021
8270
|
|
|
8022
|
-
async removeSlotUpdateListener(
|
|
8023
|
-
|
|
8024
|
-
|
|
8025
|
-
|
|
8026
|
-
|
|
8271
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
8272
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
8273
|
+
}
|
|
8274
|
+
/**
|
|
8275
|
+
* @internal
|
|
8276
|
+
*/
|
|
8027
8277
|
|
|
8028
|
-
|
|
8278
|
+
|
|
8279
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
8280
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8281
|
+
|
|
8282
|
+
if (dispose) {
|
|
8283
|
+
await dispose();
|
|
8029
8284
|
} else {
|
|
8030
|
-
console.warn(
|
|
8285
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
8031
8286
|
}
|
|
8032
8287
|
}
|
|
8033
8288
|
|
|
@@ -8074,30 +8329,34 @@ class Connection {
|
|
|
8074
8329
|
|
|
8075
8330
|
|
|
8076
8331
|
_wsOnSignatureNotification(notification) {
|
|
8077
|
-
const
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
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]);
|
|
8101
8360
|
}
|
|
8102
8361
|
/**
|
|
8103
8362
|
* Register a callback to be invoked upon signature updates
|
|
@@ -8110,23 +8369,26 @@ class Connection {
|
|
|
8110
8369
|
|
|
8111
8370
|
|
|
8112
8371
|
onSignature(signature, callback, commitment) {
|
|
8113
|
-
const
|
|
8114
|
-
|
|
8115
|
-
|
|
8372
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8373
|
+
);
|
|
8374
|
+
|
|
8375
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8116
8376
|
callback: (notification, context) => {
|
|
8117
8377
|
if (notification.type === 'status') {
|
|
8118
|
-
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
|
+
}
|
|
8119
8385
|
}
|
|
8120
8386
|
},
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
subscriptionId: null
|
|
8125
|
-
};
|
|
8387
|
+
method: 'signatureSubscribe',
|
|
8388
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8389
|
+
}, args);
|
|
8126
8390
|
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
return id;
|
|
8391
|
+
return clientSubscriptionId;
|
|
8130
8392
|
}
|
|
8131
8393
|
/**
|
|
8132
8394
|
* Register a callback to be invoked when a transaction is
|
|
@@ -8141,35 +8403,43 @@ class Connection {
|
|
|
8141
8403
|
|
|
8142
8404
|
|
|
8143
8405
|
onSignatureWithOptions(signature, callback, options) {
|
|
8144
|
-
const
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
options
|
|
8149
|
-
|
|
8406
|
+
const {
|
|
8407
|
+
commitment,
|
|
8408
|
+
...extra
|
|
8409
|
+
} = { ...options,
|
|
8410
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8411
|
+
|
|
8150
8412
|
};
|
|
8151
8413
|
|
|
8152
|
-
this.
|
|
8414
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
8415
|
+
/* encoding */
|
|
8416
|
+
, extra);
|
|
8153
8417
|
|
|
8154
|
-
|
|
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;
|
|
8155
8433
|
}
|
|
8156
8434
|
/**
|
|
8157
8435
|
* Deregister a signature notification callback
|
|
8158
8436
|
*
|
|
8159
|
-
* @param id subscription id to deregister
|
|
8437
|
+
* @param id client subscription id to deregister
|
|
8160
8438
|
*/
|
|
8161
8439
|
|
|
8162
8440
|
|
|
8163
|
-
async removeSignatureListener(
|
|
8164
|
-
|
|
8165
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
8166
|
-
delete this._signatureSubscriptions[id];
|
|
8167
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
8168
|
-
|
|
8169
|
-
this._updateSubscriptions();
|
|
8170
|
-
} else {
|
|
8171
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
8172
|
-
}
|
|
8441
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
8442
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
8173
8443
|
}
|
|
8174
8444
|
/**
|
|
8175
8445
|
* @internal
|
|
@@ -8177,14 +8447,12 @@ class Connection {
|
|
|
8177
8447
|
|
|
8178
8448
|
|
|
8179
8449
|
_wsOnRootNotification(notification) {
|
|
8180
|
-
const
|
|
8450
|
+
const {
|
|
8451
|
+
result,
|
|
8452
|
+
subscription
|
|
8453
|
+
} = superstruct.create(notification, RootNotificationResult);
|
|
8181
8454
|
|
|
8182
|
-
|
|
8183
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8184
|
-
sub.callback(res.result);
|
|
8185
|
-
return;
|
|
8186
|
-
}
|
|
8187
|
-
}
|
|
8455
|
+
this._handleServerNotification(subscription, [result]);
|
|
8188
8456
|
}
|
|
8189
8457
|
/**
|
|
8190
8458
|
* Register a callback to be invoked upon root changes
|
|
@@ -8195,33 +8463,23 @@ class Connection {
|
|
|
8195
8463
|
|
|
8196
8464
|
|
|
8197
8465
|
onRootChange(callback) {
|
|
8198
|
-
|
|
8199
|
-
this._rootSubscriptions[id] = {
|
|
8466
|
+
return this._makeSubscription({
|
|
8200
8467
|
callback,
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
return id;
|
|
8468
|
+
method: 'rootSubscribe',
|
|
8469
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
8470
|
+
}, []
|
|
8471
|
+
/* args */
|
|
8472
|
+
);
|
|
8207
8473
|
}
|
|
8208
8474
|
/**
|
|
8209
8475
|
* Deregister a root notification callback
|
|
8210
8476
|
*
|
|
8211
|
-
* @param id subscription id to deregister
|
|
8477
|
+
* @param id client subscription id to deregister
|
|
8212
8478
|
*/
|
|
8213
8479
|
|
|
8214
8480
|
|
|
8215
|
-
async removeRootChangeListener(
|
|
8216
|
-
|
|
8217
|
-
const subInfo = this._rootSubscriptions[id];
|
|
8218
|
-
delete this._rootSubscriptions[id];
|
|
8219
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
8220
|
-
|
|
8221
|
-
this._updateSubscriptions();
|
|
8222
|
-
} else {
|
|
8223
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
8224
|
-
}
|
|
8481
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
8482
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
8225
8483
|
}
|
|
8226
8484
|
|
|
8227
8485
|
}
|
|
@@ -9907,6 +10165,9 @@ exports.BLOCKHASH_CACHE_TIMEOUT_MS = BLOCKHASH_CACHE_TIMEOUT_MS;
|
|
|
9907
10165
|
exports.BPF_LOADER_DEPRECATED_PROGRAM_ID = BPF_LOADER_DEPRECATED_PROGRAM_ID;
|
|
9908
10166
|
exports.BPF_LOADER_PROGRAM_ID = BPF_LOADER_PROGRAM_ID;
|
|
9909
10167
|
exports.BpfLoader = BpfLoader;
|
|
10168
|
+
exports.COMPUTE_BUDGET_INSTRUCTION_LAYOUTS = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS;
|
|
10169
|
+
exports.ComputeBudgetInstruction = ComputeBudgetInstruction;
|
|
10170
|
+
exports.ComputeBudgetProgram = ComputeBudgetProgram;
|
|
9910
10171
|
exports.Connection = Connection;
|
|
9911
10172
|
exports.Ed25519Program = Ed25519Program;
|
|
9912
10173
|
exports.Enum = Enum;
|
|
@@ -9920,7 +10181,6 @@ exports.MAX_SEED_LENGTH = MAX_SEED_LENGTH;
|
|
|
9920
10181
|
exports.Message = Message;
|
|
9921
10182
|
exports.NONCE_ACCOUNT_LENGTH = NONCE_ACCOUNT_LENGTH;
|
|
9922
10183
|
exports.NonceAccount = NonceAccount;
|
|
9923
|
-
exports.PACKET_DATA_SIZE = PACKET_DATA_SIZE;
|
|
9924
10184
|
exports.PublicKey = PublicKey;
|
|
9925
10185
|
exports.SOLANA_SCHEMA = SOLANA_SCHEMA;
|
|
9926
10186
|
exports.STAKE_CONFIG_ID = STAKE_CONFIG_ID;
|