@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.esm.js
CHANGED
|
@@ -2076,6 +2076,16 @@ class Account {
|
|
|
2076
2076
|
|
|
2077
2077
|
const BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey('BPFLoader1111111111111111111111111111111111');
|
|
2078
2078
|
|
|
2079
|
+
/**
|
|
2080
|
+
* Maximum over-the-wire size of a Transaction
|
|
2081
|
+
*
|
|
2082
|
+
* 1280 is IPv6 minimum MTU
|
|
2083
|
+
* 40 bytes is the size of the IPv6 header
|
|
2084
|
+
* 8 bytes is the size of the fragment header
|
|
2085
|
+
*/
|
|
2086
|
+
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
2087
|
+
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
2088
|
+
|
|
2079
2089
|
/**
|
|
2080
2090
|
* Layout for a public key
|
|
2081
2091
|
*/
|
|
@@ -2335,20 +2345,8 @@ function assert (condition, message) {
|
|
|
2335
2345
|
|
|
2336
2346
|
/**
|
|
2337
2347
|
* Default (empty) signature
|
|
2338
|
-
*
|
|
2339
|
-
* Signatures are 64 bytes in length
|
|
2340
2348
|
*/
|
|
2341
|
-
const DEFAULT_SIGNATURE = Buffer.alloc(
|
|
2342
|
-
/**
|
|
2343
|
-
* Maximum over-the-wire size of a Transaction
|
|
2344
|
-
*
|
|
2345
|
-
* 1280 is IPv6 minimum MTU
|
|
2346
|
-
* 40 bytes is the size of the IPv6 header
|
|
2347
|
-
* 8 bytes is the size of the fragment header
|
|
2348
|
-
*/
|
|
2349
|
-
|
|
2350
|
-
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
2351
|
-
const SIGNATURE_LENGTH = 64;
|
|
2349
|
+
const DEFAULT_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
2352
2350
|
/**
|
|
2353
2351
|
* Account metadata used to define instructions
|
|
2354
2352
|
*/
|
|
@@ -2978,8 +2976,8 @@ class Transaction {
|
|
|
2978
2976
|
let signatures = [];
|
|
2979
2977
|
|
|
2980
2978
|
for (let i = 0; i < signatureCount; i++) {
|
|
2981
|
-
const signature = byteArray.slice(0,
|
|
2982
|
-
byteArray = byteArray.slice(
|
|
2979
|
+
const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
|
|
2980
|
+
byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
|
|
2983
2981
|
signatures.push(bs58.encode(Buffer.from(signature)));
|
|
2984
2982
|
}
|
|
2985
2983
|
|
|
@@ -3868,11 +3866,11 @@ class SystemProgram {
|
|
|
3868
3866
|
}
|
|
3869
3867
|
SystemProgram.programId = new PublicKey('11111111111111111111111111111111');
|
|
3870
3868
|
|
|
3871
|
-
// Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
|
|
3872
3869
|
// rest of the Transaction fields
|
|
3873
3870
|
//
|
|
3874
3871
|
// TODO: replace 300 with a proper constant for the size of the other
|
|
3875
3872
|
// Transaction fields
|
|
3873
|
+
|
|
3876
3874
|
const CHUNK_SIZE = PACKET_DATA_SIZE - 300;
|
|
3877
3875
|
/**
|
|
3878
3876
|
* Program loader interface
|
|
@@ -4072,6 +4070,136 @@ class BpfLoader {
|
|
|
4072
4070
|
|
|
4073
4071
|
}
|
|
4074
4072
|
|
|
4073
|
+
/**
|
|
4074
|
+
* Compute Budget Instruction class
|
|
4075
|
+
*/
|
|
4076
|
+
|
|
4077
|
+
class ComputeBudgetInstruction {
|
|
4078
|
+
/**
|
|
4079
|
+
* @internal
|
|
4080
|
+
*/
|
|
4081
|
+
constructor() {}
|
|
4082
|
+
/**
|
|
4083
|
+
* Decode a compute budget instruction and retrieve the instruction type.
|
|
4084
|
+
*/
|
|
4085
|
+
|
|
4086
|
+
|
|
4087
|
+
static decodeInstructionType(instruction) {
|
|
4088
|
+
this.checkProgramId(instruction.programId);
|
|
4089
|
+
const instructionTypeLayout = BufferLayout.u8('instruction');
|
|
4090
|
+
const typeIndex = instructionTypeLayout.decode(instruction.data);
|
|
4091
|
+
let type;
|
|
4092
|
+
|
|
4093
|
+
for (const [ixType, layout] of Object.entries(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS)) {
|
|
4094
|
+
if (layout.index == typeIndex) {
|
|
4095
|
+
type = ixType;
|
|
4096
|
+
break;
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
|
|
4100
|
+
if (!type) {
|
|
4101
|
+
throw new Error('Instruction type incorrect; not a ComputeBudgetInstruction');
|
|
4102
|
+
}
|
|
4103
|
+
|
|
4104
|
+
return type;
|
|
4105
|
+
}
|
|
4106
|
+
/**
|
|
4107
|
+
* Decode request units compute budget instruction and retrieve the instruction params.
|
|
4108
|
+
*/
|
|
4109
|
+
|
|
4110
|
+
|
|
4111
|
+
static decodeRequestUnits(instruction) {
|
|
4112
|
+
this.checkProgramId(instruction.programId);
|
|
4113
|
+
const {
|
|
4114
|
+
units,
|
|
4115
|
+
additionalFee
|
|
4116
|
+
} = decodeData(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits, instruction.data);
|
|
4117
|
+
return {
|
|
4118
|
+
units,
|
|
4119
|
+
additionalFee
|
|
4120
|
+
};
|
|
4121
|
+
}
|
|
4122
|
+
/**
|
|
4123
|
+
* Decode request heap frame compute budget instruction and retrieve the instruction params.
|
|
4124
|
+
*/
|
|
4125
|
+
|
|
4126
|
+
|
|
4127
|
+
static decodeRequestHeapFrame(instruction) {
|
|
4128
|
+
this.checkProgramId(instruction.programId);
|
|
4129
|
+
const {
|
|
4130
|
+
bytes
|
|
4131
|
+
} = decodeData(COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame, instruction.data);
|
|
4132
|
+
return {
|
|
4133
|
+
bytes
|
|
4134
|
+
};
|
|
4135
|
+
}
|
|
4136
|
+
/**
|
|
4137
|
+
* @internal
|
|
4138
|
+
*/
|
|
4139
|
+
|
|
4140
|
+
|
|
4141
|
+
static checkProgramId(programId) {
|
|
4142
|
+
if (!programId.equals(ComputeBudgetProgram.programId)) {
|
|
4143
|
+
throw new Error('invalid instruction; programId is not ComputeBudgetProgram');
|
|
4144
|
+
}
|
|
4145
|
+
}
|
|
4146
|
+
|
|
4147
|
+
}
|
|
4148
|
+
/**
|
|
4149
|
+
* An enumeration of valid ComputeBudgetInstructionType's
|
|
4150
|
+
*/
|
|
4151
|
+
|
|
4152
|
+
/**
|
|
4153
|
+
* An enumeration of valid ComputeBudget InstructionType's
|
|
4154
|
+
* @internal
|
|
4155
|
+
*/
|
|
4156
|
+
const COMPUTE_BUDGET_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
4157
|
+
RequestUnits: {
|
|
4158
|
+
index: 0,
|
|
4159
|
+
layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.u32('units'), BufferLayout.u32('additionalFee')])
|
|
4160
|
+
},
|
|
4161
|
+
RequestHeapFrame: {
|
|
4162
|
+
index: 1,
|
|
4163
|
+
layout: BufferLayout.struct([BufferLayout.u8('instruction'), BufferLayout.u32('bytes')])
|
|
4164
|
+
}
|
|
4165
|
+
});
|
|
4166
|
+
/**
|
|
4167
|
+
* Factory class for transaction instructions to interact with the Compute Budget program
|
|
4168
|
+
*/
|
|
4169
|
+
|
|
4170
|
+
class ComputeBudgetProgram {
|
|
4171
|
+
/**
|
|
4172
|
+
* @internal
|
|
4173
|
+
*/
|
|
4174
|
+
constructor() {}
|
|
4175
|
+
/**
|
|
4176
|
+
* Public key that identifies the Compute Budget program
|
|
4177
|
+
*/
|
|
4178
|
+
|
|
4179
|
+
|
|
4180
|
+
static requestUnits(params) {
|
|
4181
|
+
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestUnits;
|
|
4182
|
+
const data = encodeData(type, params);
|
|
4183
|
+
return new TransactionInstruction({
|
|
4184
|
+
keys: [],
|
|
4185
|
+
programId: this.programId,
|
|
4186
|
+
data
|
|
4187
|
+
});
|
|
4188
|
+
}
|
|
4189
|
+
|
|
4190
|
+
static requestHeapFrame(params) {
|
|
4191
|
+
const type = COMPUTE_BUDGET_INSTRUCTION_LAYOUTS.RequestHeapFrame;
|
|
4192
|
+
const data = encodeData(type, params);
|
|
4193
|
+
return new TransactionInstruction({
|
|
4194
|
+
keys: [],
|
|
4195
|
+
programId: this.programId,
|
|
4196
|
+
data
|
|
4197
|
+
});
|
|
4198
|
+
}
|
|
4199
|
+
|
|
4200
|
+
}
|
|
4201
|
+
ComputeBudgetProgram.programId = new PublicKey('ComputeBudget111111111111111111111111111111');
|
|
4202
|
+
|
|
4075
4203
|
var browserPonyfill = {exports: {}};
|
|
4076
4204
|
|
|
4077
4205
|
(function (module, exports) {
|
|
@@ -4633,6 +4761,82 @@ module.exports = exports;
|
|
|
4633
4761
|
|
|
4634
4762
|
var crossFetch = /*@__PURE__*/getDefaultExportFromCjs(browserPonyfill.exports);
|
|
4635
4763
|
|
|
4764
|
+
var objToString = Object.prototype.toString;
|
|
4765
|
+
var objKeys = Object.keys || function(obj) {
|
|
4766
|
+
var keys = [];
|
|
4767
|
+
for (var name in obj) {
|
|
4768
|
+
keys.push(name);
|
|
4769
|
+
}
|
|
4770
|
+
return keys;
|
|
4771
|
+
};
|
|
4772
|
+
|
|
4773
|
+
function stringify(val, isArrayProp) {
|
|
4774
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
4775
|
+
if (val === true) {
|
|
4776
|
+
return "true";
|
|
4777
|
+
}
|
|
4778
|
+
if (val === false) {
|
|
4779
|
+
return "false";
|
|
4780
|
+
}
|
|
4781
|
+
switch (typeof val) {
|
|
4782
|
+
case "object":
|
|
4783
|
+
if (val === null) {
|
|
4784
|
+
return null;
|
|
4785
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
4786
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
4787
|
+
} else {
|
|
4788
|
+
toStr = objToString.call(val);
|
|
4789
|
+
if (toStr === "[object Array]") {
|
|
4790
|
+
str = '[';
|
|
4791
|
+
max = val.length - 1;
|
|
4792
|
+
for(i = 0; i < max; i++) {
|
|
4793
|
+
str += stringify(val[i], true) + ',';
|
|
4794
|
+
}
|
|
4795
|
+
if (max > -1) {
|
|
4796
|
+
str += stringify(val[i], true);
|
|
4797
|
+
}
|
|
4798
|
+
return str + ']';
|
|
4799
|
+
} else if (toStr === "[object Object]") {
|
|
4800
|
+
// only object is left
|
|
4801
|
+
keys = objKeys(val).sort();
|
|
4802
|
+
max = keys.length;
|
|
4803
|
+
str = "";
|
|
4804
|
+
i = 0;
|
|
4805
|
+
while (i < max) {
|
|
4806
|
+
key = keys[i];
|
|
4807
|
+
propVal = stringify(val[key], false);
|
|
4808
|
+
if (propVal !== undefined) {
|
|
4809
|
+
if (str) {
|
|
4810
|
+
str += ',';
|
|
4811
|
+
}
|
|
4812
|
+
str += JSON.stringify(key) + ':' + propVal;
|
|
4813
|
+
}
|
|
4814
|
+
i++;
|
|
4815
|
+
}
|
|
4816
|
+
return '{' + str + '}';
|
|
4817
|
+
} else {
|
|
4818
|
+
return JSON.stringify(val);
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
4821
|
+
case "function":
|
|
4822
|
+
case "undefined":
|
|
4823
|
+
return isArrayProp ? null : undefined;
|
|
4824
|
+
case "string":
|
|
4825
|
+
return JSON.stringify(val);
|
|
4826
|
+
default:
|
|
4827
|
+
return isFinite(val) ? val : null;
|
|
4828
|
+
}
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
var fastStableStringify = function(val) {
|
|
4832
|
+
var returnVal = stringify(val, false);
|
|
4833
|
+
if (returnVal !== undefined) {
|
|
4834
|
+
return ''+ returnVal;
|
|
4835
|
+
}
|
|
4836
|
+
};
|
|
4837
|
+
|
|
4838
|
+
var fastStableStringify$1 = fastStableStringify;
|
|
4839
|
+
|
|
4636
4840
|
const MINIMUM_SLOT_PER_EPOCH = 32; // Returns the number of trailing zeros in the binary representation of self.
|
|
4637
4841
|
|
|
4638
4842
|
function trailingZeros(n) {
|
|
@@ -4799,6 +5003,12 @@ const BufferFromRawAccountData = coerce(instance(Buffer), RawAccountDataResult,
|
|
|
4799
5003
|
*/
|
|
4800
5004
|
|
|
4801
5005
|
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|
5006
|
+
/**
|
|
5007
|
+
* HACK.
|
|
5008
|
+
* Copied from rpc-websockets/dist/lib/client.
|
|
5009
|
+
* Otherwise, `yarn build` fails with:
|
|
5010
|
+
* https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
|
|
5011
|
+
*/
|
|
4802
5012
|
|
|
4803
5013
|
/**
|
|
4804
5014
|
* @internal
|
|
@@ -5667,14 +5877,9 @@ const LogsNotificationResult = type({
|
|
|
5667
5877
|
* Filter for log subscriptions.
|
|
5668
5878
|
*/
|
|
5669
5879
|
|
|
5670
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5671
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5672
|
-
}
|
|
5673
5880
|
/**
|
|
5674
5881
|
* A connection to a fullnode JSON RPC endpoint
|
|
5675
5882
|
*/
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
5883
|
class Connection {
|
|
5679
5884
|
/** @internal */
|
|
5680
5885
|
|
|
@@ -5698,21 +5903,13 @@ class Connection {
|
|
|
5698
5903
|
|
|
5699
5904
|
/** @internal */
|
|
5700
5905
|
|
|
5701
|
-
/** @internal
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
/** @internal */
|
|
5710
|
-
|
|
5711
|
-
/** @internal */
|
|
5712
|
-
|
|
5713
|
-
/** @internal */
|
|
5714
|
-
|
|
5715
|
-
/** @internal */
|
|
5906
|
+
/** @internal
|
|
5907
|
+
* A number that we increment every time an active connection closes.
|
|
5908
|
+
* Used to determine whether the same socket connection that was open
|
|
5909
|
+
* when an async operation started is the same one that's active when
|
|
5910
|
+
* its continuation fires.
|
|
5911
|
+
*
|
|
5912
|
+
*/
|
|
5716
5913
|
|
|
5717
5914
|
/** @internal */
|
|
5718
5915
|
|
|
@@ -5728,7 +5925,19 @@ class Connection {
|
|
|
5728
5925
|
|
|
5729
5926
|
/** @internal */
|
|
5730
5927
|
|
|
5731
|
-
/**
|
|
5928
|
+
/**
|
|
5929
|
+
* Special case.
|
|
5930
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
5931
|
+
* subscription on the server side. We need to track which of these
|
|
5932
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
5933
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
5934
|
+
* (in which case we must tear down the server subscription) or an
|
|
5935
|
+
* already-processed signature (in which case the client can simply
|
|
5936
|
+
* clear out the subscription locally without telling the server).
|
|
5937
|
+
*
|
|
5938
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
5939
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
5940
|
+
*/
|
|
5732
5941
|
|
|
5733
5942
|
/** @internal */
|
|
5734
5943
|
|
|
@@ -5750,6 +5959,7 @@ class Connection {
|
|
|
5750
5959
|
this._rpcWebSocketConnected = false;
|
|
5751
5960
|
this._rpcWebSocketHeartbeat = null;
|
|
5752
5961
|
this._rpcWebSocketIdleTimeout = null;
|
|
5962
|
+
this._rpcWebSocketGeneration = 0;
|
|
5753
5963
|
this._disableBlockhashCaching = false;
|
|
5754
5964
|
this._pollingBlockhash = false;
|
|
5755
5965
|
this._blockhashInfo = {
|
|
@@ -5758,20 +5968,11 @@ class Connection {
|
|
|
5758
5968
|
transactionSignatures: [],
|
|
5759
5969
|
simulatedSignatures: []
|
|
5760
5970
|
};
|
|
5761
|
-
this.
|
|
5762
|
-
this.
|
|
5763
|
-
this.
|
|
5764
|
-
this.
|
|
5765
|
-
this.
|
|
5766
|
-
this._rootSubscriptions = {};
|
|
5767
|
-
this._signatureSubscriptionCounter = 0;
|
|
5768
|
-
this._signatureSubscriptions = {};
|
|
5769
|
-
this._slotSubscriptionCounter = 0;
|
|
5770
|
-
this._slotSubscriptions = {};
|
|
5771
|
-
this._logsSubscriptionCounter = 0;
|
|
5772
|
-
this._logsSubscriptions = {};
|
|
5773
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5774
|
-
this._slotUpdateSubscriptions = {};
|
|
5971
|
+
this._nextClientSubscriptionId = 0;
|
|
5972
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
5973
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
5974
|
+
this._subscriptionsByHash = {};
|
|
5975
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5775
5976
|
let url = new URL(endpoint);
|
|
5776
5977
|
const useHttps = url.protocol === 'https:';
|
|
5777
5978
|
let wsEndpoint;
|
|
@@ -7539,6 +7740,8 @@ class Connection {
|
|
|
7539
7740
|
|
|
7540
7741
|
|
|
7541
7742
|
_wsOnClose(code) {
|
|
7743
|
+
this._rpcWebSocketGeneration++;
|
|
7744
|
+
|
|
7542
7745
|
if (this._rpcWebSocketHeartbeat) {
|
|
7543
7746
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7544
7747
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7552,85 +7755,20 @@ class Connection {
|
|
|
7552
7755
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7553
7756
|
|
|
7554
7757
|
|
|
7555
|
-
this.
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7563
|
-
if (sub.subscriptionId == null) {
|
|
7564
|
-
sub.subscriptionId = 'subscribing';
|
|
7565
|
-
|
|
7566
|
-
try {
|
|
7567
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7568
|
-
|
|
7569
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7570
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7571
|
-
sub.subscriptionId = id;
|
|
7572
|
-
}
|
|
7573
|
-
} catch (err) {
|
|
7574
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7575
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7576
|
-
sub.subscriptionId = null;
|
|
7577
|
-
}
|
|
7578
|
-
|
|
7579
|
-
if (err instanceof Error) {
|
|
7580
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7581
|
-
}
|
|
7582
|
-
}
|
|
7583
|
-
}
|
|
7584
|
-
}
|
|
7585
|
-
/**
|
|
7586
|
-
* @internal
|
|
7587
|
-
*/
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7591
|
-
const subscriptionId = sub.subscriptionId;
|
|
7592
|
-
|
|
7593
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7594
|
-
const unsubscribeId = subscriptionId;
|
|
7595
|
-
|
|
7596
|
-
try {
|
|
7597
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7598
|
-
} catch (err) {
|
|
7599
|
-
if (err instanceof Error) {
|
|
7600
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7601
|
-
}
|
|
7602
|
-
}
|
|
7603
|
-
}
|
|
7604
|
-
}
|
|
7605
|
-
/**
|
|
7606
|
-
* @internal
|
|
7607
|
-
*/
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
_resetSubscriptions() {
|
|
7611
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7612
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7613
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7614
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7615
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7616
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7617
|
-
Object.values(this._slotUpdateSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7758
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
7759
|
+
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
7760
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7761
|
+
state: 'pending'
|
|
7762
|
+
};
|
|
7763
|
+
});
|
|
7618
7764
|
}
|
|
7619
7765
|
/**
|
|
7620
7766
|
* @internal
|
|
7621
7767
|
*/
|
|
7622
7768
|
|
|
7623
7769
|
|
|
7624
|
-
_updateSubscriptions() {
|
|
7625
|
-
|
|
7626
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7627
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7628
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7629
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7630
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7631
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7632
|
-
|
|
7633
|
-
if (accountKeys.length === 0 && programKeys.length === 0 && slotKeys.length === 0 && slotUpdateKeys.length === 0 && signatureKeys.length === 0 && rootKeys.length === 0 && logsKeys.length === 0) {
|
|
7770
|
+
async _updateSubscriptions() {
|
|
7771
|
+
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
7634
7772
|
if (this._rpcWebSocketConnected) {
|
|
7635
7773
|
this._rpcWebSocketConnected = false;
|
|
7636
7774
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7662,60 +7800,167 @@ class Connection {
|
|
|
7662
7800
|
return;
|
|
7663
7801
|
}
|
|
7664
7802
|
|
|
7665
|
-
|
|
7666
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7803
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7667
7804
|
|
|
7668
|
-
|
|
7669
|
-
|
|
7670
|
-
|
|
7671
|
-
for (let id of programKeys) {
|
|
7672
|
-
const sub = this._programAccountChangeSubscriptions[id];
|
|
7805
|
+
const isCurrentConnectionStillActive = () => {
|
|
7806
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7807
|
+
};
|
|
7673
7808
|
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7809
|
+
await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
|
|
7810
|
+
// `_updateSubscriptions` recursively when processing the state,
|
|
7811
|
+
// so it's important that we look up the *current* version of
|
|
7812
|
+
// each subscription, every time we process a hash.
|
|
7813
|
+
Object.keys(this._subscriptionsByHash).map(async hash => {
|
|
7814
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7678
7815
|
|
|
7679
|
-
|
|
7680
|
-
|
|
7816
|
+
if (subscription === undefined) {
|
|
7817
|
+
// This entry has since been deleted. Skip.
|
|
7818
|
+
return;
|
|
7819
|
+
}
|
|
7681
7820
|
|
|
7682
|
-
|
|
7683
|
-
|
|
7821
|
+
switch (subscription.state) {
|
|
7822
|
+
case 'pending':
|
|
7823
|
+
case 'unsubscribed':
|
|
7824
|
+
if (subscription.callbacks.size === 0) {
|
|
7825
|
+
/**
|
|
7826
|
+
* You can end up here when:
|
|
7827
|
+
*
|
|
7828
|
+
* - a subscription has recently unsubscribed
|
|
7829
|
+
* without having new callbacks added to it
|
|
7830
|
+
* while the unsubscribe was in flight, or
|
|
7831
|
+
* - when a pending subscription has its
|
|
7832
|
+
* listeners removed before a request was
|
|
7833
|
+
* sent to the server.
|
|
7834
|
+
*
|
|
7835
|
+
* Being that nobody is interested in this
|
|
7836
|
+
* subscription any longer, delete it.
|
|
7837
|
+
*/
|
|
7838
|
+
delete this._subscriptionsByHash[hash];
|
|
7839
|
+
|
|
7840
|
+
if (subscription.state === 'unsubscribed') {
|
|
7841
|
+
delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
|
|
7842
|
+
}
|
|
7684
7843
|
|
|
7685
|
-
|
|
7686
|
-
|
|
7844
|
+
await this._updateSubscriptions();
|
|
7845
|
+
return;
|
|
7846
|
+
}
|
|
7687
7847
|
|
|
7688
|
-
|
|
7689
|
-
|
|
7848
|
+
await (async () => {
|
|
7849
|
+
const {
|
|
7850
|
+
args,
|
|
7851
|
+
method
|
|
7852
|
+
} = subscription;
|
|
7690
7853
|
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7854
|
+
try {
|
|
7855
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7856
|
+
state: 'subscribing'
|
|
7857
|
+
};
|
|
7858
|
+
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
7859
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7860
|
+
serverSubscriptionId,
|
|
7861
|
+
state: 'subscribed'
|
|
7862
|
+
};
|
|
7863
|
+
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
7864
|
+
await this._updateSubscriptions();
|
|
7865
|
+
} catch (e) {
|
|
7866
|
+
if (e instanceof Error) {
|
|
7867
|
+
console.error(`${method} error for argument`, args, e.message);
|
|
7868
|
+
}
|
|
7869
|
+
|
|
7870
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7871
|
+
return;
|
|
7872
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7695
7873
|
|
|
7696
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7697
|
-
}
|
|
7698
7874
|
|
|
7699
|
-
|
|
7700
|
-
|
|
7875
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7876
|
+
state: 'pending'
|
|
7877
|
+
};
|
|
7878
|
+
await this._updateSubscriptions();
|
|
7879
|
+
}
|
|
7880
|
+
})();
|
|
7881
|
+
break;
|
|
7701
7882
|
|
|
7702
|
-
|
|
7703
|
-
|
|
7883
|
+
case 'subscribed':
|
|
7884
|
+
if (subscription.callbacks.size === 0) {
|
|
7885
|
+
// By the time we successfully set up a subscription
|
|
7886
|
+
// with the server, the client stopped caring about it.
|
|
7887
|
+
// Tear it down now.
|
|
7888
|
+
await (async () => {
|
|
7889
|
+
const {
|
|
7890
|
+
serverSubscriptionId,
|
|
7891
|
+
unsubscribeMethod
|
|
7892
|
+
} = subscription;
|
|
7893
|
+
|
|
7894
|
+
if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
|
|
7895
|
+
/**
|
|
7896
|
+
* Special case.
|
|
7897
|
+
* If we're dealing with a subscription that has been auto-
|
|
7898
|
+
* disposed by the RPC, then we can skip the RPC call to
|
|
7899
|
+
* tear down the subscription here.
|
|
7900
|
+
*
|
|
7901
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7902
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7903
|
+
*/
|
|
7904
|
+
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
7905
|
+
} else {
|
|
7906
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7907
|
+
state: 'unsubscribing'
|
|
7908
|
+
};
|
|
7909
|
+
|
|
7910
|
+
try {
|
|
7911
|
+
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
7912
|
+
} catch (e) {
|
|
7913
|
+
if (e instanceof Error) {
|
|
7914
|
+
console.error(`${unsubscribeMethod} error:`, e.message);
|
|
7915
|
+
}
|
|
7916
|
+
|
|
7917
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7918
|
+
return;
|
|
7919
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7920
|
+
|
|
7921
|
+
|
|
7922
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7923
|
+
state: 'subscribed'
|
|
7924
|
+
};
|
|
7925
|
+
await this._updateSubscriptions();
|
|
7926
|
+
return;
|
|
7927
|
+
}
|
|
7928
|
+
}
|
|
7704
7929
|
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7930
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7931
|
+
state: 'unsubscribed'
|
|
7932
|
+
};
|
|
7933
|
+
await this._updateSubscriptions();
|
|
7934
|
+
})();
|
|
7935
|
+
}
|
|
7708
7936
|
|
|
7709
|
-
|
|
7710
|
-
filter = {
|
|
7711
|
-
mentions: [sub.filter.toString()]
|
|
7712
|
-
};
|
|
7713
|
-
} else {
|
|
7714
|
-
filter = sub.filter;
|
|
7937
|
+
break;
|
|
7715
7938
|
}
|
|
7939
|
+
}));
|
|
7940
|
+
}
|
|
7941
|
+
/**
|
|
7942
|
+
* @internal
|
|
7943
|
+
*/
|
|
7944
|
+
|
|
7945
|
+
|
|
7946
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7947
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7716
7948
|
|
|
7717
|
-
|
|
7949
|
+
if (callbacks === undefined) {
|
|
7950
|
+
return;
|
|
7718
7951
|
}
|
|
7952
|
+
|
|
7953
|
+
callbacks.forEach(cb => {
|
|
7954
|
+
try {
|
|
7955
|
+
cb( // I failed to find a way to convince TypeScript that `cb` is of type
|
|
7956
|
+
// `TCallback` which is certainly compatible with `Parameters<TCallback>`.
|
|
7957
|
+
// See https://github.com/microsoft/TypeScript/issues/47615
|
|
7958
|
+
// @ts-ignore
|
|
7959
|
+
...callbackArgs);
|
|
7960
|
+
} catch (e) {
|
|
7961
|
+
console.error(e);
|
|
7962
|
+
}
|
|
7963
|
+
});
|
|
7719
7964
|
}
|
|
7720
7965
|
/**
|
|
7721
7966
|
* @internal
|
|
@@ -7723,14 +7968,71 @@ class Connection {
|
|
|
7723
7968
|
|
|
7724
7969
|
|
|
7725
7970
|
_wsOnAccountNotification(notification) {
|
|
7726
|
-
const
|
|
7971
|
+
const {
|
|
7972
|
+
result,
|
|
7973
|
+
subscription
|
|
7974
|
+
} = create(notification, AccountNotificationResult);
|
|
7727
7975
|
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7976
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7977
|
+
}
|
|
7978
|
+
/**
|
|
7979
|
+
* @internal
|
|
7980
|
+
*/
|
|
7981
|
+
|
|
7982
|
+
|
|
7983
|
+
_makeSubscription(subscriptionConfig,
|
|
7984
|
+
/**
|
|
7985
|
+
* When preparing `args` for a call to `_makeSubscription`, be sure
|
|
7986
|
+
* to carefully apply a default `commitment` property, if necessary.
|
|
7987
|
+
*
|
|
7988
|
+
* - If the user supplied a `commitment` use that.
|
|
7989
|
+
* - Otherwise, if the `Connection::commitment` is set, use that.
|
|
7990
|
+
* - Otherwise, set it to the RPC server default: `finalized`.
|
|
7991
|
+
*
|
|
7992
|
+
* This is extremely important to ensure that these two fundamentally
|
|
7993
|
+
* identical subscriptions produce the same identifying hash:
|
|
7994
|
+
*
|
|
7995
|
+
* - A subscription made without specifying a commitment.
|
|
7996
|
+
* - A subscription made where the commitment specified is the same
|
|
7997
|
+
* as the default applied to the subscription above.
|
|
7998
|
+
*
|
|
7999
|
+
* Example; these two subscriptions must produce the same hash:
|
|
8000
|
+
*
|
|
8001
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'`
|
|
8002
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
|
|
8003
|
+
* `'finalized'`.
|
|
8004
|
+
*
|
|
8005
|
+
* See the 'making a subscription with defaulted params omitted' test
|
|
8006
|
+
* in `connection-subscriptions.ts` for more.
|
|
8007
|
+
*/
|
|
8008
|
+
args) {
|
|
8009
|
+
const clientSubscriptionId = this._nextClientSubscriptionId++;
|
|
8010
|
+
const hash = fastStableStringify$1([subscriptionConfig.method, args], true
|
|
8011
|
+
/* isArrayProp */
|
|
8012
|
+
);
|
|
8013
|
+
const existingSubscription = this._subscriptionsByHash[hash];
|
|
8014
|
+
|
|
8015
|
+
if (existingSubscription === undefined) {
|
|
8016
|
+
this._subscriptionsByHash[hash] = { ...subscriptionConfig,
|
|
8017
|
+
args,
|
|
8018
|
+
callbacks: new Set([subscriptionConfig.callback]),
|
|
8019
|
+
state: 'pending'
|
|
8020
|
+
};
|
|
8021
|
+
} else {
|
|
8022
|
+
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
7733
8023
|
}
|
|
8024
|
+
|
|
8025
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
8026
|
+
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8027
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
8028
|
+
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
8029
|
+
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
8030
|
+
await this._updateSubscriptions();
|
|
8031
|
+
};
|
|
8032
|
+
|
|
8033
|
+
this._updateSubscriptions();
|
|
8034
|
+
|
|
8035
|
+
return clientSubscriptionId;
|
|
7734
8036
|
}
|
|
7735
8037
|
/**
|
|
7736
8038
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7743,35 +8045,24 @@ class Connection {
|
|
|
7743
8045
|
|
|
7744
8046
|
|
|
7745
8047
|
onAccountChange(publicKey, callback, commitment) {
|
|
7746
|
-
const
|
|
7747
|
-
|
|
7748
|
-
publicKey: publicKey.toBase58(),
|
|
7749
|
-
callback,
|
|
7750
|
-
commitment,
|
|
7751
|
-
subscriptionId: null
|
|
7752
|
-
};
|
|
7753
|
-
|
|
7754
|
-
this._updateSubscriptions();
|
|
8048
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8049
|
+
'base64');
|
|
7755
8050
|
|
|
7756
|
-
return
|
|
8051
|
+
return this._makeSubscription({
|
|
8052
|
+
callback,
|
|
8053
|
+
method: 'accountSubscribe',
|
|
8054
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
8055
|
+
}, args);
|
|
7757
8056
|
}
|
|
7758
8057
|
/**
|
|
7759
8058
|
* Deregister an account notification callback
|
|
7760
8059
|
*
|
|
7761
|
-
* @param id subscription id to deregister
|
|
8060
|
+
* @param id client subscription id to deregister
|
|
7762
8061
|
*/
|
|
7763
8062
|
|
|
7764
8063
|
|
|
7765
|
-
async removeAccountChangeListener(
|
|
7766
|
-
|
|
7767
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7768
|
-
delete this._accountChangeSubscriptions[id];
|
|
7769
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7770
|
-
|
|
7771
|
-
this._updateSubscriptions();
|
|
7772
|
-
} else {
|
|
7773
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7774
|
-
}
|
|
8064
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
8065
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7775
8066
|
}
|
|
7776
8067
|
/**
|
|
7777
8068
|
* @internal
|
|
@@ -7779,21 +8070,15 @@ class Connection {
|
|
|
7779
8070
|
|
|
7780
8071
|
|
|
7781
8072
|
_wsOnProgramAccountNotification(notification) {
|
|
7782
|
-
const
|
|
8073
|
+
const {
|
|
8074
|
+
result,
|
|
8075
|
+
subscription
|
|
8076
|
+
} = create(notification, ProgramAccountNotificationResult);
|
|
7783
8077
|
|
|
7784
|
-
|
|
7785
|
-
|
|
7786
|
-
|
|
7787
|
-
|
|
7788
|
-
context
|
|
7789
|
-
} = res.result;
|
|
7790
|
-
sub.callback({
|
|
7791
|
-
accountId: value.pubkey,
|
|
7792
|
-
accountInfo: value.account
|
|
7793
|
-
}, context);
|
|
7794
|
-
return;
|
|
7795
|
-
}
|
|
7796
|
-
}
|
|
8078
|
+
this._handleServerNotification(subscription, [{
|
|
8079
|
+
accountId: result.value.pubkey,
|
|
8080
|
+
accountInfo: result.value.account
|
|
8081
|
+
}, result.context]);
|
|
7797
8082
|
}
|
|
7798
8083
|
/**
|
|
7799
8084
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7808,36 +8093,30 @@ class Connection {
|
|
|
7808
8093
|
|
|
7809
8094
|
|
|
7810
8095
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7811
|
-
const
|
|
7812
|
-
|
|
7813
|
-
|
|
8096
|
+
const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
8097
|
+
'base64'
|
|
8098
|
+
/* encoding */
|
|
8099
|
+
, filters ? {
|
|
8100
|
+
filters: filters
|
|
8101
|
+
} : undefined
|
|
8102
|
+
/* extra */
|
|
8103
|
+
);
|
|
8104
|
+
|
|
8105
|
+
return this._makeSubscription({
|
|
7814
8106
|
callback,
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7818
|
-
};
|
|
7819
|
-
|
|
7820
|
-
this._updateSubscriptions();
|
|
7821
|
-
|
|
7822
|
-
return id;
|
|
8107
|
+
method: 'programSubscribe',
|
|
8108
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
8109
|
+
}, args);
|
|
7823
8110
|
}
|
|
7824
8111
|
/**
|
|
7825
8112
|
* Deregister an account notification callback
|
|
7826
8113
|
*
|
|
7827
|
-
* @param id subscription id to deregister
|
|
8114
|
+
* @param id client subscription id to deregister
|
|
7828
8115
|
*/
|
|
7829
8116
|
|
|
7830
8117
|
|
|
7831
|
-
async removeProgramAccountChangeListener(
|
|
7832
|
-
|
|
7833
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7834
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7835
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7836
|
-
|
|
7837
|
-
this._updateSubscriptions();
|
|
7838
|
-
} else {
|
|
7839
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
7840
|
-
}
|
|
8118
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
8119
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7841
8120
|
}
|
|
7842
8121
|
/**
|
|
7843
8122
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7845,35 +8124,26 @@ class Connection {
|
|
|
7845
8124
|
|
|
7846
8125
|
|
|
7847
8126
|
onLogs(filter, callback, commitment) {
|
|
7848
|
-
const
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
commitment,
|
|
7853
|
-
subscriptionId: null
|
|
7854
|
-
};
|
|
8127
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
8128
|
+
mentions: [filter.toString()]
|
|
8129
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8130
|
+
);
|
|
7855
8131
|
|
|
7856
|
-
this.
|
|
7857
|
-
|
|
7858
|
-
|
|
8132
|
+
return this._makeSubscription({
|
|
8133
|
+
callback,
|
|
8134
|
+
method: 'logsSubscribe',
|
|
8135
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
8136
|
+
}, args);
|
|
7859
8137
|
}
|
|
7860
8138
|
/**
|
|
7861
8139
|
* Deregister a logs callback.
|
|
7862
8140
|
*
|
|
7863
|
-
* @param id subscription id to deregister.
|
|
8141
|
+
* @param id client subscription id to deregister.
|
|
7864
8142
|
*/
|
|
7865
8143
|
|
|
7866
8144
|
|
|
7867
|
-
async removeOnLogsListener(
|
|
7868
|
-
|
|
7869
|
-
const subInfo = this._logsSubscriptions[id];
|
|
7870
|
-
delete this._logsSubscriptions[id];
|
|
7871
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
7872
|
-
|
|
7873
|
-
this._updateSubscriptions();
|
|
7874
|
-
} else {
|
|
7875
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
7876
|
-
}
|
|
8145
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
8146
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
7877
8147
|
}
|
|
7878
8148
|
/**
|
|
7879
8149
|
* @internal
|
|
@@ -7881,17 +8151,12 @@ class Connection {
|
|
|
7881
8151
|
|
|
7882
8152
|
|
|
7883
8153
|
_wsOnLogsNotification(notification) {
|
|
7884
|
-
const
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
const sub = this._logsSubscriptions[id];
|
|
8154
|
+
const {
|
|
8155
|
+
result,
|
|
8156
|
+
subscription
|
|
8157
|
+
} = create(notification, LogsNotificationResult);
|
|
7889
8158
|
|
|
7890
|
-
|
|
7891
|
-
sub.callback(res.result.value, res.result.context);
|
|
7892
|
-
return;
|
|
7893
|
-
}
|
|
7894
|
-
}
|
|
8159
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7895
8160
|
}
|
|
7896
8161
|
/**
|
|
7897
8162
|
* @internal
|
|
@@ -7899,14 +8164,12 @@ class Connection {
|
|
|
7899
8164
|
|
|
7900
8165
|
|
|
7901
8166
|
_wsOnSlotNotification(notification) {
|
|
7902
|
-
const
|
|
8167
|
+
const {
|
|
8168
|
+
result,
|
|
8169
|
+
subscription
|
|
8170
|
+
} = create(notification, SlotNotificationResult);
|
|
7903
8171
|
|
|
7904
|
-
|
|
7905
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7906
|
-
sub.callback(res.result);
|
|
7907
|
-
return;
|
|
7908
|
-
}
|
|
7909
|
-
}
|
|
8172
|
+
this._handleServerNotification(subscription, [result]);
|
|
7910
8173
|
}
|
|
7911
8174
|
/**
|
|
7912
8175
|
* Register a callback to be invoked upon slot changes
|
|
@@ -7917,33 +8180,23 @@ class Connection {
|
|
|
7917
8180
|
|
|
7918
8181
|
|
|
7919
8182
|
onSlotChange(callback) {
|
|
7920
|
-
|
|
7921
|
-
this._slotSubscriptions[id] = {
|
|
8183
|
+
return this._makeSubscription({
|
|
7922
8184
|
callback,
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
return id;
|
|
8185
|
+
method: 'slotSubscribe',
|
|
8186
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
8187
|
+
}, []
|
|
8188
|
+
/* args */
|
|
8189
|
+
);
|
|
7929
8190
|
}
|
|
7930
8191
|
/**
|
|
7931
8192
|
* Deregister a slot notification callback
|
|
7932
8193
|
*
|
|
7933
|
-
* @param id subscription id to deregister
|
|
8194
|
+
* @param id client subscription id to deregister
|
|
7934
8195
|
*/
|
|
7935
8196
|
|
|
7936
8197
|
|
|
7937
|
-
async removeSlotChangeListener(
|
|
7938
|
-
|
|
7939
|
-
const subInfo = this._slotSubscriptions[id];
|
|
7940
|
-
delete this._slotSubscriptions[id];
|
|
7941
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
7942
|
-
|
|
7943
|
-
this._updateSubscriptions();
|
|
7944
|
-
} else {
|
|
7945
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
7946
|
-
}
|
|
8198
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
8199
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
7947
8200
|
}
|
|
7948
8201
|
/**
|
|
7949
8202
|
* @internal
|
|
@@ -7951,14 +8204,12 @@ class Connection {
|
|
|
7951
8204
|
|
|
7952
8205
|
|
|
7953
8206
|
_wsOnSlotUpdatesNotification(notification) {
|
|
7954
|
-
const
|
|
8207
|
+
const {
|
|
8208
|
+
result,
|
|
8209
|
+
subscription
|
|
8210
|
+
} = create(notification, SlotUpdateNotificationResult);
|
|
7955
8211
|
|
|
7956
|
-
|
|
7957
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7958
|
-
sub.callback(res.result);
|
|
7959
|
-
return;
|
|
7960
|
-
}
|
|
7961
|
-
}
|
|
8212
|
+
this._handleServerNotification(subscription, [result]);
|
|
7962
8213
|
}
|
|
7963
8214
|
/**
|
|
7964
8215
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -7970,32 +8221,36 @@ class Connection {
|
|
|
7970
8221
|
|
|
7971
8222
|
|
|
7972
8223
|
onSlotUpdate(callback) {
|
|
7973
|
-
|
|
7974
|
-
this._slotUpdateSubscriptions[id] = {
|
|
8224
|
+
return this._makeSubscription({
|
|
7975
8225
|
callback,
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
return id;
|
|
8226
|
+
method: 'slotsUpdatesSubscribe',
|
|
8227
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
8228
|
+
}, []
|
|
8229
|
+
/* args */
|
|
8230
|
+
);
|
|
7982
8231
|
}
|
|
7983
8232
|
/**
|
|
7984
8233
|
* Deregister a slot update notification callback
|
|
7985
8234
|
*
|
|
7986
|
-
* @param id subscription id to deregister
|
|
8235
|
+
* @param id client subscription id to deregister
|
|
7987
8236
|
*/
|
|
7988
8237
|
|
|
7989
8238
|
|
|
7990
|
-
async removeSlotUpdateListener(
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
8239
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
8240
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
8241
|
+
}
|
|
8242
|
+
/**
|
|
8243
|
+
* @internal
|
|
8244
|
+
*/
|
|
7995
8245
|
|
|
7996
|
-
|
|
8246
|
+
|
|
8247
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
8248
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
8249
|
+
|
|
8250
|
+
if (dispose) {
|
|
8251
|
+
await dispose();
|
|
7997
8252
|
} else {
|
|
7998
|
-
console.warn(
|
|
8253
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
7999
8254
|
}
|
|
8000
8255
|
}
|
|
8001
8256
|
|
|
@@ -8042,30 +8297,34 @@ class Connection {
|
|
|
8042
8297
|
|
|
8043
8298
|
|
|
8044
8299
|
_wsOnSignatureNotification(notification) {
|
|
8045
|
-
const
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8300
|
+
const {
|
|
8301
|
+
result,
|
|
8302
|
+
subscription
|
|
8303
|
+
} = create(notification, SignatureNotificationResult);
|
|
8304
|
+
|
|
8305
|
+
if (result.value !== 'receivedSignature') {
|
|
8306
|
+
/**
|
|
8307
|
+
* Special case.
|
|
8308
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
8309
|
+
* subscription on the server side. We need to track which of these
|
|
8310
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
8311
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
8312
|
+
* (in which case we must tear down the server subscription) or an
|
|
8313
|
+
* already-processed signature (in which case the client can simply
|
|
8314
|
+
* clear out the subscription locally without telling the server).
|
|
8315
|
+
*
|
|
8316
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
8317
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
8318
|
+
*/
|
|
8319
|
+
this._subscriptionsAutoDisposedByRpc.add(subscription);
|
|
8320
|
+
}
|
|
8321
|
+
|
|
8322
|
+
this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
|
|
8323
|
+
type: 'received'
|
|
8324
|
+
}, result.context] : [{
|
|
8325
|
+
type: 'status',
|
|
8326
|
+
result: result.value
|
|
8327
|
+
}, result.context]);
|
|
8069
8328
|
}
|
|
8070
8329
|
/**
|
|
8071
8330
|
* Register a callback to be invoked upon signature updates
|
|
@@ -8078,23 +8337,26 @@ class Connection {
|
|
|
8078
8337
|
|
|
8079
8338
|
|
|
8080
8339
|
onSignature(signature, callback, commitment) {
|
|
8081
|
-
const
|
|
8082
|
-
|
|
8083
|
-
|
|
8340
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8341
|
+
);
|
|
8342
|
+
|
|
8343
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8084
8344
|
callback: (notification, context) => {
|
|
8085
8345
|
if (notification.type === 'status') {
|
|
8086
|
-
callback(notification.result, context);
|
|
8346
|
+
callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8347
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8348
|
+
|
|
8349
|
+
try {
|
|
8350
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8351
|
+
} catch {// Already removed.
|
|
8352
|
+
}
|
|
8087
8353
|
}
|
|
8088
8354
|
},
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
subscriptionId: null
|
|
8093
|
-
};
|
|
8355
|
+
method: 'signatureSubscribe',
|
|
8356
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8357
|
+
}, args);
|
|
8094
8358
|
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
return id;
|
|
8359
|
+
return clientSubscriptionId;
|
|
8098
8360
|
}
|
|
8099
8361
|
/**
|
|
8100
8362
|
* Register a callback to be invoked when a transaction is
|
|
@@ -8109,35 +8371,43 @@ class Connection {
|
|
|
8109
8371
|
|
|
8110
8372
|
|
|
8111
8373
|
onSignatureWithOptions(signature, callback, options) {
|
|
8112
|
-
const
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
options
|
|
8117
|
-
|
|
8374
|
+
const {
|
|
8375
|
+
commitment,
|
|
8376
|
+
...extra
|
|
8377
|
+
} = { ...options,
|
|
8378
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8379
|
+
|
|
8118
8380
|
};
|
|
8119
8381
|
|
|
8120
|
-
this.
|
|
8382
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
8383
|
+
/* encoding */
|
|
8384
|
+
, extra);
|
|
8121
8385
|
|
|
8122
|
-
|
|
8386
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8387
|
+
callback: (notification, context) => {
|
|
8388
|
+
callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8389
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8390
|
+
|
|
8391
|
+
try {
|
|
8392
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8393
|
+
} catch {// Already removed.
|
|
8394
|
+
}
|
|
8395
|
+
},
|
|
8396
|
+
method: 'signatureSubscribe',
|
|
8397
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8398
|
+
}, args);
|
|
8399
|
+
|
|
8400
|
+
return clientSubscriptionId;
|
|
8123
8401
|
}
|
|
8124
8402
|
/**
|
|
8125
8403
|
* Deregister a signature notification callback
|
|
8126
8404
|
*
|
|
8127
|
-
* @param id subscription id to deregister
|
|
8405
|
+
* @param id client subscription id to deregister
|
|
8128
8406
|
*/
|
|
8129
8407
|
|
|
8130
8408
|
|
|
8131
|
-
async removeSignatureListener(
|
|
8132
|
-
|
|
8133
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
8134
|
-
delete this._signatureSubscriptions[id];
|
|
8135
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
8136
|
-
|
|
8137
|
-
this._updateSubscriptions();
|
|
8138
|
-
} else {
|
|
8139
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
8140
|
-
}
|
|
8409
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
8410
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
8141
8411
|
}
|
|
8142
8412
|
/**
|
|
8143
8413
|
* @internal
|
|
@@ -8145,14 +8415,12 @@ class Connection {
|
|
|
8145
8415
|
|
|
8146
8416
|
|
|
8147
8417
|
_wsOnRootNotification(notification) {
|
|
8148
|
-
const
|
|
8418
|
+
const {
|
|
8419
|
+
result,
|
|
8420
|
+
subscription
|
|
8421
|
+
} = create(notification, RootNotificationResult);
|
|
8149
8422
|
|
|
8150
|
-
|
|
8151
|
-
if (sub.subscriptionId === res.subscription) {
|
|
8152
|
-
sub.callback(res.result);
|
|
8153
|
-
return;
|
|
8154
|
-
}
|
|
8155
|
-
}
|
|
8423
|
+
this._handleServerNotification(subscription, [result]);
|
|
8156
8424
|
}
|
|
8157
8425
|
/**
|
|
8158
8426
|
* Register a callback to be invoked upon root changes
|
|
@@ -8163,33 +8431,23 @@ class Connection {
|
|
|
8163
8431
|
|
|
8164
8432
|
|
|
8165
8433
|
onRootChange(callback) {
|
|
8166
|
-
|
|
8167
|
-
this._rootSubscriptions[id] = {
|
|
8434
|
+
return this._makeSubscription({
|
|
8168
8435
|
callback,
|
|
8169
|
-
|
|
8170
|
-
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
return id;
|
|
8436
|
+
method: 'rootSubscribe',
|
|
8437
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
8438
|
+
}, []
|
|
8439
|
+
/* args */
|
|
8440
|
+
);
|
|
8175
8441
|
}
|
|
8176
8442
|
/**
|
|
8177
8443
|
* Deregister a root notification callback
|
|
8178
8444
|
*
|
|
8179
|
-
* @param id subscription id to deregister
|
|
8445
|
+
* @param id client subscription id to deregister
|
|
8180
8446
|
*/
|
|
8181
8447
|
|
|
8182
8448
|
|
|
8183
|
-
async removeRootChangeListener(
|
|
8184
|
-
|
|
8185
|
-
const subInfo = this._rootSubscriptions[id];
|
|
8186
|
-
delete this._rootSubscriptions[id];
|
|
8187
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
8188
|
-
|
|
8189
|
-
this._updateSubscriptions();
|
|
8190
|
-
} else {
|
|
8191
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
8192
|
-
}
|
|
8449
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
8450
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
8193
8451
|
}
|
|
8194
8452
|
|
|
8195
8453
|
}
|
|
@@ -9869,5 +10127,5 @@ function clusterApiUrl(cluster, tls) {
|
|
|
9869
10127
|
|
|
9870
10128
|
const LAMPORTS_PER_SOL = 1000000000;
|
|
9871
10129
|
|
|
9872
|
-
export { Account, Authorized, BLOCKHASH_CACHE_TIMEOUT_MS, BPF_LOADER_DEPRECATED_PROGRAM_ID, BPF_LOADER_PROGRAM_ID, BpfLoader, Connection, Ed25519Program, Enum, EpochSchedule, FeeCalculatorLayout, Keypair, LAMPORTS_PER_SOL, Loader, Lockup, MAX_SEED_LENGTH, Message, NONCE_ACCOUNT_LENGTH, NonceAccount,
|
|
10130
|
+
export { Account, Authorized, BLOCKHASH_CACHE_TIMEOUT_MS, BPF_LOADER_DEPRECATED_PROGRAM_ID, BPF_LOADER_PROGRAM_ID, BpfLoader, COMPUTE_BUDGET_INSTRUCTION_LAYOUTS, ComputeBudgetInstruction, ComputeBudgetProgram, Connection, Ed25519Program, Enum, EpochSchedule, FeeCalculatorLayout, Keypair, LAMPORTS_PER_SOL, Loader, Lockup, MAX_SEED_LENGTH, Message, NONCE_ACCOUNT_LENGTH, NonceAccount, PublicKey, SOLANA_SCHEMA, STAKE_CONFIG_ID, STAKE_INSTRUCTION_LAYOUTS, SYSTEM_INSTRUCTION_LAYOUTS, SYSVAR_CLOCK_PUBKEY, SYSVAR_EPOCH_SCHEDULE_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_REWARDS_PUBKEY, SYSVAR_SLOT_HASHES_PUBKEY, SYSVAR_SLOT_HISTORY_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, Secp256k1Program, SendTransactionError, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionInstruction, VALIDATOR_INFO_KEY, VOTE_PROGRAM_ID, ValidatorInfo, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
|
|
9873
10131
|
//# sourceMappingURL=index.browser.esm.js.map
|