@solana/web3.js 1.41.0 → 1.41.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.browser.cjs.js +516 -387
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +516 -388
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +516 -387
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +47 -30
- package/lib/index.esm.js +516 -388
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +548 -628
- 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/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.esm.js
CHANGED
|
@@ -2085,6 +2085,16 @@ class Account {
|
|
|
2085
2085
|
|
|
2086
2086
|
const BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey('BPFLoader1111111111111111111111111111111111');
|
|
2087
2087
|
|
|
2088
|
+
/**
|
|
2089
|
+
* Maximum over-the-wire size of a Transaction
|
|
2090
|
+
*
|
|
2091
|
+
* 1280 is IPv6 minimum MTU
|
|
2092
|
+
* 40 bytes is the size of the IPv6 header
|
|
2093
|
+
* 8 bytes is the size of the fragment header
|
|
2094
|
+
*/
|
|
2095
|
+
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
2096
|
+
const SIGNATURE_LENGTH_IN_BYTES = 64;
|
|
2097
|
+
|
|
2088
2098
|
/**
|
|
2089
2099
|
* Layout for a public key
|
|
2090
2100
|
*/
|
|
@@ -2344,20 +2354,8 @@ function assert (condition, message) {
|
|
|
2344
2354
|
|
|
2345
2355
|
/**
|
|
2346
2356
|
* Default (empty) signature
|
|
2347
|
-
*
|
|
2348
|
-
* Signatures are 64 bytes in length
|
|
2349
2357
|
*/
|
|
2350
|
-
const DEFAULT_SIGNATURE = Buffer.alloc(
|
|
2351
|
-
/**
|
|
2352
|
-
* Maximum over-the-wire size of a Transaction
|
|
2353
|
-
*
|
|
2354
|
-
* 1280 is IPv6 minimum MTU
|
|
2355
|
-
* 40 bytes is the size of the IPv6 header
|
|
2356
|
-
* 8 bytes is the size of the fragment header
|
|
2357
|
-
*/
|
|
2358
|
-
|
|
2359
|
-
const PACKET_DATA_SIZE = 1280 - 40 - 8;
|
|
2360
|
-
const SIGNATURE_LENGTH = 64;
|
|
2358
|
+
const DEFAULT_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
2361
2359
|
/**
|
|
2362
2360
|
* Account metadata used to define instructions
|
|
2363
2361
|
*/
|
|
@@ -2987,8 +2985,8 @@ class Transaction {
|
|
|
2987
2985
|
let signatures = [];
|
|
2988
2986
|
|
|
2989
2987
|
for (let i = 0; i < signatureCount; i++) {
|
|
2990
|
-
const signature = byteArray.slice(0,
|
|
2991
|
-
byteArray = byteArray.slice(
|
|
2988
|
+
const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
|
|
2989
|
+
byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
|
|
2992
2990
|
signatures.push(bs58.encode(Buffer.from(signature)));
|
|
2993
2991
|
}
|
|
2994
2992
|
|
|
@@ -3877,11 +3875,11 @@ class SystemProgram {
|
|
|
3877
3875
|
}
|
|
3878
3876
|
SystemProgram.programId = new PublicKey('11111111111111111111111111111111');
|
|
3879
3877
|
|
|
3880
|
-
// Keep program chunks under PACKET_DATA_SIZE, leaving enough room for the
|
|
3881
3878
|
// rest of the Transaction fields
|
|
3882
3879
|
//
|
|
3883
3880
|
// TODO: replace 300 with a proper constant for the size of the other
|
|
3884
3881
|
// Transaction fields
|
|
3882
|
+
|
|
3885
3883
|
const CHUNK_SIZE = PACKET_DATA_SIZE - 300;
|
|
3886
3884
|
/**
|
|
3887
3885
|
* Program loader interface
|
|
@@ -4211,6 +4209,82 @@ class ComputeBudgetProgram {
|
|
|
4211
4209
|
}
|
|
4212
4210
|
ComputeBudgetProgram.programId = new PublicKey('ComputeBudget111111111111111111111111111111');
|
|
4213
4211
|
|
|
4212
|
+
var objToString = Object.prototype.toString;
|
|
4213
|
+
var objKeys = Object.keys || function(obj) {
|
|
4214
|
+
var keys = [];
|
|
4215
|
+
for (var name in obj) {
|
|
4216
|
+
keys.push(name);
|
|
4217
|
+
}
|
|
4218
|
+
return keys;
|
|
4219
|
+
};
|
|
4220
|
+
|
|
4221
|
+
function stringify(val, isArrayProp) {
|
|
4222
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
4223
|
+
if (val === true) {
|
|
4224
|
+
return "true";
|
|
4225
|
+
}
|
|
4226
|
+
if (val === false) {
|
|
4227
|
+
return "false";
|
|
4228
|
+
}
|
|
4229
|
+
switch (typeof val) {
|
|
4230
|
+
case "object":
|
|
4231
|
+
if (val === null) {
|
|
4232
|
+
return null;
|
|
4233
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
4234
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
4235
|
+
} else {
|
|
4236
|
+
toStr = objToString.call(val);
|
|
4237
|
+
if (toStr === "[object Array]") {
|
|
4238
|
+
str = '[';
|
|
4239
|
+
max = val.length - 1;
|
|
4240
|
+
for(i = 0; i < max; i++) {
|
|
4241
|
+
str += stringify(val[i], true) + ',';
|
|
4242
|
+
}
|
|
4243
|
+
if (max > -1) {
|
|
4244
|
+
str += stringify(val[i], true);
|
|
4245
|
+
}
|
|
4246
|
+
return str + ']';
|
|
4247
|
+
} else if (toStr === "[object Object]") {
|
|
4248
|
+
// only object is left
|
|
4249
|
+
keys = objKeys(val).sort();
|
|
4250
|
+
max = keys.length;
|
|
4251
|
+
str = "";
|
|
4252
|
+
i = 0;
|
|
4253
|
+
while (i < max) {
|
|
4254
|
+
key = keys[i];
|
|
4255
|
+
propVal = stringify(val[key], false);
|
|
4256
|
+
if (propVal !== undefined) {
|
|
4257
|
+
if (str) {
|
|
4258
|
+
str += ',';
|
|
4259
|
+
}
|
|
4260
|
+
str += JSON.stringify(key) + ':' + propVal;
|
|
4261
|
+
}
|
|
4262
|
+
i++;
|
|
4263
|
+
}
|
|
4264
|
+
return '{' + str + '}';
|
|
4265
|
+
} else {
|
|
4266
|
+
return JSON.stringify(val);
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
case "function":
|
|
4270
|
+
case "undefined":
|
|
4271
|
+
return isArrayProp ? null : undefined;
|
|
4272
|
+
case "string":
|
|
4273
|
+
return JSON.stringify(val);
|
|
4274
|
+
default:
|
|
4275
|
+
return isFinite(val) ? val : null;
|
|
4276
|
+
}
|
|
4277
|
+
}
|
|
4278
|
+
|
|
4279
|
+
var fastStableStringify = function(val) {
|
|
4280
|
+
var returnVal = stringify(val, false);
|
|
4281
|
+
if (returnVal !== undefined) {
|
|
4282
|
+
return ''+ returnVal;
|
|
4283
|
+
}
|
|
4284
|
+
};
|
|
4285
|
+
|
|
4286
|
+
var fastStableStringify$1 = fastStableStringify;
|
|
4287
|
+
|
|
4214
4288
|
const DESTROY_TIMEOUT_MS = 5000;
|
|
4215
4289
|
class AgentManager {
|
|
4216
4290
|
static _newAgent(useHttps) {
|
|
@@ -4426,6 +4500,12 @@ const BufferFromRawAccountData = coerce(instance(Buffer), RawAccountDataResult,
|
|
|
4426
4500
|
*/
|
|
4427
4501
|
|
|
4428
4502
|
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|
4503
|
+
/**
|
|
4504
|
+
* HACK.
|
|
4505
|
+
* Copied from rpc-websockets/dist/lib/client.
|
|
4506
|
+
* Otherwise, `yarn build` fails with:
|
|
4507
|
+
* https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
|
|
4508
|
+
*/
|
|
4429
4509
|
|
|
4430
4510
|
/**
|
|
4431
4511
|
* @internal
|
|
@@ -5300,14 +5380,9 @@ const LogsNotificationResult = type({
|
|
|
5300
5380
|
* Filter for log subscriptions.
|
|
5301
5381
|
*/
|
|
5302
5382
|
|
|
5303
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5304
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5305
|
-
}
|
|
5306
5383
|
/**
|
|
5307
5384
|
* A connection to a fullnode JSON RPC endpoint
|
|
5308
5385
|
*/
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
5386
|
class Connection {
|
|
5312
5387
|
/** @internal */
|
|
5313
5388
|
|
|
@@ -5331,21 +5406,13 @@ class Connection {
|
|
|
5331
5406
|
|
|
5332
5407
|
/** @internal */
|
|
5333
5408
|
|
|
5334
|
-
/** @internal
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
/** @internal */
|
|
5343
|
-
|
|
5344
|
-
/** @internal */
|
|
5345
|
-
|
|
5346
|
-
/** @internal */
|
|
5347
|
-
|
|
5348
|
-
/** @internal */
|
|
5409
|
+
/** @internal
|
|
5410
|
+
* A number that we increment every time an active connection closes.
|
|
5411
|
+
* Used to determine whether the same socket connection that was open
|
|
5412
|
+
* when an async operation started is the same one that's active when
|
|
5413
|
+
* its continuation fires.
|
|
5414
|
+
*
|
|
5415
|
+
*/
|
|
5349
5416
|
|
|
5350
5417
|
/** @internal */
|
|
5351
5418
|
|
|
@@ -5361,7 +5428,19 @@ class Connection {
|
|
|
5361
5428
|
|
|
5362
5429
|
/** @internal */
|
|
5363
5430
|
|
|
5364
|
-
/**
|
|
5431
|
+
/**
|
|
5432
|
+
* Special case.
|
|
5433
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
5434
|
+
* subscription on the server side. We need to track which of these
|
|
5435
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
5436
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
5437
|
+
* (in which case we must tear down the server subscription) or an
|
|
5438
|
+
* already-processed signature (in which case the client can simply
|
|
5439
|
+
* clear out the subscription locally without telling the server).
|
|
5440
|
+
*
|
|
5441
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
5442
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
5443
|
+
*/
|
|
5365
5444
|
|
|
5366
5445
|
/** @internal */
|
|
5367
5446
|
|
|
@@ -5383,6 +5462,7 @@ class Connection {
|
|
|
5383
5462
|
this._rpcWebSocketConnected = false;
|
|
5384
5463
|
this._rpcWebSocketHeartbeat = null;
|
|
5385
5464
|
this._rpcWebSocketIdleTimeout = null;
|
|
5465
|
+
this._rpcWebSocketGeneration = 0;
|
|
5386
5466
|
this._disableBlockhashCaching = false;
|
|
5387
5467
|
this._pollingBlockhash = false;
|
|
5388
5468
|
this._blockhashInfo = {
|
|
@@ -5391,20 +5471,11 @@ class Connection {
|
|
|
5391
5471
|
transactionSignatures: [],
|
|
5392
5472
|
simulatedSignatures: []
|
|
5393
5473
|
};
|
|
5394
|
-
this.
|
|
5395
|
-
this.
|
|
5396
|
-
this.
|
|
5397
|
-
this.
|
|
5398
|
-
this.
|
|
5399
|
-
this._rootSubscriptions = {};
|
|
5400
|
-
this._signatureSubscriptionCounter = 0;
|
|
5401
|
-
this._signatureSubscriptions = {};
|
|
5402
|
-
this._slotSubscriptionCounter = 0;
|
|
5403
|
-
this._slotSubscriptions = {};
|
|
5404
|
-
this._logsSubscriptionCounter = 0;
|
|
5405
|
-
this._logsSubscriptions = {};
|
|
5406
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5407
|
-
this._slotUpdateSubscriptions = {};
|
|
5474
|
+
this._nextClientSubscriptionId = 0;
|
|
5475
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
5476
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
5477
|
+
this._subscriptionsByHash = {};
|
|
5478
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5408
5479
|
let url = new URL(endpoint);
|
|
5409
5480
|
const useHttps = url.protocol === 'https:';
|
|
5410
5481
|
let wsEndpoint;
|
|
@@ -7172,6 +7243,8 @@ class Connection {
|
|
|
7172
7243
|
|
|
7173
7244
|
|
|
7174
7245
|
_wsOnClose(code) {
|
|
7246
|
+
this._rpcWebSocketGeneration++;
|
|
7247
|
+
|
|
7175
7248
|
if (this._rpcWebSocketHeartbeat) {
|
|
7176
7249
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7177
7250
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7185,85 +7258,20 @@ class Connection {
|
|
|
7185
7258
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7186
7259
|
|
|
7187
7260
|
|
|
7188
|
-
this.
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7196
|
-
if (sub.subscriptionId == null) {
|
|
7197
|
-
sub.subscriptionId = 'subscribing';
|
|
7198
|
-
|
|
7199
|
-
try {
|
|
7200
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7201
|
-
|
|
7202
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7203
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7204
|
-
sub.subscriptionId = id;
|
|
7205
|
-
}
|
|
7206
|
-
} catch (err) {
|
|
7207
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7208
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7209
|
-
sub.subscriptionId = null;
|
|
7210
|
-
}
|
|
7211
|
-
|
|
7212
|
-
if (err instanceof Error) {
|
|
7213
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7214
|
-
}
|
|
7215
|
-
}
|
|
7216
|
-
}
|
|
7217
|
-
}
|
|
7218
|
-
/**
|
|
7219
|
-
* @internal
|
|
7220
|
-
*/
|
|
7221
|
-
|
|
7222
|
-
|
|
7223
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7224
|
-
const subscriptionId = sub.subscriptionId;
|
|
7225
|
-
|
|
7226
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7227
|
-
const unsubscribeId = subscriptionId;
|
|
7228
|
-
|
|
7229
|
-
try {
|
|
7230
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7231
|
-
} catch (err) {
|
|
7232
|
-
if (err instanceof Error) {
|
|
7233
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7234
|
-
}
|
|
7235
|
-
}
|
|
7236
|
-
}
|
|
7237
|
-
}
|
|
7238
|
-
/**
|
|
7239
|
-
* @internal
|
|
7240
|
-
*/
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
_resetSubscriptions() {
|
|
7244
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7245
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7246
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7247
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7248
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7249
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7250
|
-
Object.values(this._slotUpdateSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7261
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
7262
|
+
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
7263
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7264
|
+
state: 'pending'
|
|
7265
|
+
};
|
|
7266
|
+
});
|
|
7251
7267
|
}
|
|
7252
7268
|
/**
|
|
7253
7269
|
* @internal
|
|
7254
7270
|
*/
|
|
7255
7271
|
|
|
7256
7272
|
|
|
7257
|
-
_updateSubscriptions() {
|
|
7258
|
-
|
|
7259
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7260
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7261
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7262
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7263
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7264
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7265
|
-
|
|
7266
|
-
if (accountKeys.length === 0 && programKeys.length === 0 && slotKeys.length === 0 && slotUpdateKeys.length === 0 && signatureKeys.length === 0 && rootKeys.length === 0 && logsKeys.length === 0) {
|
|
7273
|
+
async _updateSubscriptions() {
|
|
7274
|
+
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
7267
7275
|
if (this._rpcWebSocketConnected) {
|
|
7268
7276
|
this._rpcWebSocketConnected = false;
|
|
7269
7277
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7295,60 +7303,167 @@ class Connection {
|
|
|
7295
7303
|
return;
|
|
7296
7304
|
}
|
|
7297
7305
|
|
|
7298
|
-
|
|
7299
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7306
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7300
7307
|
|
|
7301
|
-
|
|
7302
|
-
|
|
7303
|
-
|
|
7304
|
-
for (let id of programKeys) {
|
|
7305
|
-
const sub = this._programAccountChangeSubscriptions[id];
|
|
7308
|
+
const isCurrentConnectionStillActive = () => {
|
|
7309
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7310
|
+
};
|
|
7306
7311
|
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7312
|
+
await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
|
|
7313
|
+
// `_updateSubscriptions` recursively when processing the state,
|
|
7314
|
+
// so it's important that we look up the *current* version of
|
|
7315
|
+
// each subscription, every time we process a hash.
|
|
7316
|
+
Object.keys(this._subscriptionsByHash).map(async hash => {
|
|
7317
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7311
7318
|
|
|
7312
|
-
|
|
7313
|
-
|
|
7319
|
+
if (subscription === undefined) {
|
|
7320
|
+
// This entry has since been deleted. Skip.
|
|
7321
|
+
return;
|
|
7322
|
+
}
|
|
7314
7323
|
|
|
7315
|
-
|
|
7316
|
-
|
|
7324
|
+
switch (subscription.state) {
|
|
7325
|
+
case 'pending':
|
|
7326
|
+
case 'unsubscribed':
|
|
7327
|
+
if (subscription.callbacks.size === 0) {
|
|
7328
|
+
/**
|
|
7329
|
+
* You can end up here when:
|
|
7330
|
+
*
|
|
7331
|
+
* - a subscription has recently unsubscribed
|
|
7332
|
+
* without having new callbacks added to it
|
|
7333
|
+
* while the unsubscribe was in flight, or
|
|
7334
|
+
* - when a pending subscription has its
|
|
7335
|
+
* listeners removed before a request was
|
|
7336
|
+
* sent to the server.
|
|
7337
|
+
*
|
|
7338
|
+
* Being that nobody is interested in this
|
|
7339
|
+
* subscription any longer, delete it.
|
|
7340
|
+
*/
|
|
7341
|
+
delete this._subscriptionsByHash[hash];
|
|
7342
|
+
|
|
7343
|
+
if (subscription.state === 'unsubscribed') {
|
|
7344
|
+
delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
|
|
7345
|
+
}
|
|
7317
7346
|
|
|
7318
|
-
|
|
7319
|
-
|
|
7347
|
+
await this._updateSubscriptions();
|
|
7348
|
+
return;
|
|
7349
|
+
}
|
|
7320
7350
|
|
|
7321
|
-
|
|
7322
|
-
|
|
7351
|
+
await (async () => {
|
|
7352
|
+
const {
|
|
7353
|
+
args,
|
|
7354
|
+
method
|
|
7355
|
+
} = subscription;
|
|
7323
7356
|
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7357
|
+
try {
|
|
7358
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7359
|
+
state: 'subscribing'
|
|
7360
|
+
};
|
|
7361
|
+
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
7362
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7363
|
+
serverSubscriptionId,
|
|
7364
|
+
state: 'subscribed'
|
|
7365
|
+
};
|
|
7366
|
+
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
7367
|
+
await this._updateSubscriptions();
|
|
7368
|
+
} catch (e) {
|
|
7369
|
+
if (e instanceof Error) {
|
|
7370
|
+
console.error(`${method} error for argument`, args, e.message);
|
|
7371
|
+
}
|
|
7372
|
+
|
|
7373
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7374
|
+
return;
|
|
7375
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7328
7376
|
|
|
7329
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7330
|
-
}
|
|
7331
7377
|
|
|
7332
|
-
|
|
7333
|
-
|
|
7378
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7379
|
+
state: 'pending'
|
|
7380
|
+
};
|
|
7381
|
+
await this._updateSubscriptions();
|
|
7382
|
+
}
|
|
7383
|
+
})();
|
|
7384
|
+
break;
|
|
7334
7385
|
|
|
7335
|
-
|
|
7336
|
-
|
|
7386
|
+
case 'subscribed':
|
|
7387
|
+
if (subscription.callbacks.size === 0) {
|
|
7388
|
+
// By the time we successfully set up a subscription
|
|
7389
|
+
// with the server, the client stopped caring about it.
|
|
7390
|
+
// Tear it down now.
|
|
7391
|
+
await (async () => {
|
|
7392
|
+
const {
|
|
7393
|
+
serverSubscriptionId,
|
|
7394
|
+
unsubscribeMethod
|
|
7395
|
+
} = subscription;
|
|
7396
|
+
|
|
7397
|
+
if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
|
|
7398
|
+
/**
|
|
7399
|
+
* Special case.
|
|
7400
|
+
* If we're dealing with a subscription that has been auto-
|
|
7401
|
+
* disposed by the RPC, then we can skip the RPC call to
|
|
7402
|
+
* tear down the subscription here.
|
|
7403
|
+
*
|
|
7404
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7405
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7406
|
+
*/
|
|
7407
|
+
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
7408
|
+
} else {
|
|
7409
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7410
|
+
state: 'unsubscribing'
|
|
7411
|
+
};
|
|
7412
|
+
|
|
7413
|
+
try {
|
|
7414
|
+
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
7415
|
+
} catch (e) {
|
|
7416
|
+
if (e instanceof Error) {
|
|
7417
|
+
console.error(`${unsubscribeMethod} error:`, e.message);
|
|
7418
|
+
}
|
|
7419
|
+
|
|
7420
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7421
|
+
return;
|
|
7422
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7423
|
+
|
|
7424
|
+
|
|
7425
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7426
|
+
state: 'subscribed'
|
|
7427
|
+
};
|
|
7428
|
+
await this._updateSubscriptions();
|
|
7429
|
+
return;
|
|
7430
|
+
}
|
|
7431
|
+
}
|
|
7337
7432
|
|
|
7338
|
-
|
|
7339
|
-
|
|
7340
|
-
|
|
7433
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7434
|
+
state: 'unsubscribed'
|
|
7435
|
+
};
|
|
7436
|
+
await this._updateSubscriptions();
|
|
7437
|
+
})();
|
|
7438
|
+
}
|
|
7341
7439
|
|
|
7342
|
-
|
|
7343
|
-
filter = {
|
|
7344
|
-
mentions: [sub.filter.toString()]
|
|
7345
|
-
};
|
|
7346
|
-
} else {
|
|
7347
|
-
filter = sub.filter;
|
|
7440
|
+
break;
|
|
7348
7441
|
}
|
|
7442
|
+
}));
|
|
7443
|
+
}
|
|
7444
|
+
/**
|
|
7445
|
+
* @internal
|
|
7446
|
+
*/
|
|
7349
7447
|
|
|
7350
|
-
|
|
7448
|
+
|
|
7449
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7450
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7451
|
+
|
|
7452
|
+
if (callbacks === undefined) {
|
|
7453
|
+
return;
|
|
7351
7454
|
}
|
|
7455
|
+
|
|
7456
|
+
callbacks.forEach(cb => {
|
|
7457
|
+
try {
|
|
7458
|
+
cb( // I failed to find a way to convince TypeScript that `cb` is of type
|
|
7459
|
+
// `TCallback` which is certainly compatible with `Parameters<TCallback>`.
|
|
7460
|
+
// See https://github.com/microsoft/TypeScript/issues/47615
|
|
7461
|
+
// @ts-ignore
|
|
7462
|
+
...callbackArgs);
|
|
7463
|
+
} catch (e) {
|
|
7464
|
+
console.error(e);
|
|
7465
|
+
}
|
|
7466
|
+
});
|
|
7352
7467
|
}
|
|
7353
7468
|
/**
|
|
7354
7469
|
* @internal
|
|
@@ -7356,14 +7471,71 @@ class Connection {
|
|
|
7356
7471
|
|
|
7357
7472
|
|
|
7358
7473
|
_wsOnAccountNotification(notification) {
|
|
7359
|
-
const
|
|
7474
|
+
const {
|
|
7475
|
+
result,
|
|
7476
|
+
subscription
|
|
7477
|
+
} = create(notification, AccountNotificationResult);
|
|
7360
7478
|
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7365
|
-
|
|
7479
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7480
|
+
}
|
|
7481
|
+
/**
|
|
7482
|
+
* @internal
|
|
7483
|
+
*/
|
|
7484
|
+
|
|
7485
|
+
|
|
7486
|
+
_makeSubscription(subscriptionConfig,
|
|
7487
|
+
/**
|
|
7488
|
+
* When preparing `args` for a call to `_makeSubscription`, be sure
|
|
7489
|
+
* to carefully apply a default `commitment` property, if necessary.
|
|
7490
|
+
*
|
|
7491
|
+
* - If the user supplied a `commitment` use that.
|
|
7492
|
+
* - Otherwise, if the `Connection::commitment` is set, use that.
|
|
7493
|
+
* - Otherwise, set it to the RPC server default: `finalized`.
|
|
7494
|
+
*
|
|
7495
|
+
* This is extremely important to ensure that these two fundamentally
|
|
7496
|
+
* identical subscriptions produce the same identifying hash:
|
|
7497
|
+
*
|
|
7498
|
+
* - A subscription made without specifying a commitment.
|
|
7499
|
+
* - A subscription made where the commitment specified is the same
|
|
7500
|
+
* as the default applied to the subscription above.
|
|
7501
|
+
*
|
|
7502
|
+
* Example; these two subscriptions must produce the same hash:
|
|
7503
|
+
*
|
|
7504
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'`
|
|
7505
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
|
|
7506
|
+
* `'finalized'`.
|
|
7507
|
+
*
|
|
7508
|
+
* See the 'making a subscription with defaulted params omitted' test
|
|
7509
|
+
* in `connection-subscriptions.ts` for more.
|
|
7510
|
+
*/
|
|
7511
|
+
args) {
|
|
7512
|
+
const clientSubscriptionId = this._nextClientSubscriptionId++;
|
|
7513
|
+
const hash = fastStableStringify$1([subscriptionConfig.method, args], true
|
|
7514
|
+
/* isArrayProp */
|
|
7515
|
+
);
|
|
7516
|
+
const existingSubscription = this._subscriptionsByHash[hash];
|
|
7517
|
+
|
|
7518
|
+
if (existingSubscription === undefined) {
|
|
7519
|
+
this._subscriptionsByHash[hash] = { ...subscriptionConfig,
|
|
7520
|
+
args,
|
|
7521
|
+
callbacks: new Set([subscriptionConfig.callback]),
|
|
7522
|
+
state: 'pending'
|
|
7523
|
+
};
|
|
7524
|
+
} else {
|
|
7525
|
+
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
7366
7526
|
}
|
|
7527
|
+
|
|
7528
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
7529
|
+
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7530
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7531
|
+
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
7532
|
+
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
7533
|
+
await this._updateSubscriptions();
|
|
7534
|
+
};
|
|
7535
|
+
|
|
7536
|
+
this._updateSubscriptions();
|
|
7537
|
+
|
|
7538
|
+
return clientSubscriptionId;
|
|
7367
7539
|
}
|
|
7368
7540
|
/**
|
|
7369
7541
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7376,35 +7548,24 @@ class Connection {
|
|
|
7376
7548
|
|
|
7377
7549
|
|
|
7378
7550
|
onAccountChange(publicKey, callback, commitment) {
|
|
7379
|
-
const
|
|
7380
|
-
|
|
7381
|
-
publicKey: publicKey.toBase58(),
|
|
7382
|
-
callback,
|
|
7383
|
-
commitment,
|
|
7384
|
-
subscriptionId: null
|
|
7385
|
-
};
|
|
7551
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7552
|
+
'base64');
|
|
7386
7553
|
|
|
7387
|
-
this.
|
|
7388
|
-
|
|
7389
|
-
|
|
7554
|
+
return this._makeSubscription({
|
|
7555
|
+
callback,
|
|
7556
|
+
method: 'accountSubscribe',
|
|
7557
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
7558
|
+
}, args);
|
|
7390
7559
|
}
|
|
7391
7560
|
/**
|
|
7392
7561
|
* Deregister an account notification callback
|
|
7393
7562
|
*
|
|
7394
|
-
* @param id subscription id to deregister
|
|
7563
|
+
* @param id client subscription id to deregister
|
|
7395
7564
|
*/
|
|
7396
7565
|
|
|
7397
7566
|
|
|
7398
|
-
async removeAccountChangeListener(
|
|
7399
|
-
|
|
7400
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7401
|
-
delete this._accountChangeSubscriptions[id];
|
|
7402
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7403
|
-
|
|
7404
|
-
this._updateSubscriptions();
|
|
7405
|
-
} else {
|
|
7406
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7407
|
-
}
|
|
7567
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
7568
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7408
7569
|
}
|
|
7409
7570
|
/**
|
|
7410
7571
|
* @internal
|
|
@@ -7412,21 +7573,15 @@ class Connection {
|
|
|
7412
7573
|
|
|
7413
7574
|
|
|
7414
7575
|
_wsOnProgramAccountNotification(notification) {
|
|
7415
|
-
const
|
|
7576
|
+
const {
|
|
7577
|
+
result,
|
|
7578
|
+
subscription
|
|
7579
|
+
} = create(notification, ProgramAccountNotificationResult);
|
|
7416
7580
|
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
context
|
|
7422
|
-
} = res.result;
|
|
7423
|
-
sub.callback({
|
|
7424
|
-
accountId: value.pubkey,
|
|
7425
|
-
accountInfo: value.account
|
|
7426
|
-
}, context);
|
|
7427
|
-
return;
|
|
7428
|
-
}
|
|
7429
|
-
}
|
|
7581
|
+
this._handleServerNotification(subscription, [{
|
|
7582
|
+
accountId: result.value.pubkey,
|
|
7583
|
+
accountInfo: result.value.account
|
|
7584
|
+
}, result.context]);
|
|
7430
7585
|
}
|
|
7431
7586
|
/**
|
|
7432
7587
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7441,36 +7596,30 @@ class Connection {
|
|
|
7441
7596
|
|
|
7442
7597
|
|
|
7443
7598
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7444
|
-
const
|
|
7445
|
-
|
|
7446
|
-
|
|
7599
|
+
const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7600
|
+
'base64'
|
|
7601
|
+
/* encoding */
|
|
7602
|
+
, filters ? {
|
|
7603
|
+
filters: filters
|
|
7604
|
+
} : undefined
|
|
7605
|
+
/* extra */
|
|
7606
|
+
);
|
|
7607
|
+
|
|
7608
|
+
return this._makeSubscription({
|
|
7447
7609
|
callback,
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
};
|
|
7452
|
-
|
|
7453
|
-
this._updateSubscriptions();
|
|
7454
|
-
|
|
7455
|
-
return id;
|
|
7610
|
+
method: 'programSubscribe',
|
|
7611
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
7612
|
+
}, args);
|
|
7456
7613
|
}
|
|
7457
7614
|
/**
|
|
7458
7615
|
* Deregister an account notification callback
|
|
7459
7616
|
*
|
|
7460
|
-
* @param id subscription id to deregister
|
|
7617
|
+
* @param id client subscription id to deregister
|
|
7461
7618
|
*/
|
|
7462
7619
|
|
|
7463
7620
|
|
|
7464
|
-
async removeProgramAccountChangeListener(
|
|
7465
|
-
|
|
7466
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7467
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7468
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7469
|
-
|
|
7470
|
-
this._updateSubscriptions();
|
|
7471
|
-
} else {
|
|
7472
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
7473
|
-
}
|
|
7621
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
7622
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7474
7623
|
}
|
|
7475
7624
|
/**
|
|
7476
7625
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7478,35 +7627,26 @@ class Connection {
|
|
|
7478
7627
|
|
|
7479
7628
|
|
|
7480
7629
|
onLogs(filter, callback, commitment) {
|
|
7481
|
-
const
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
commitment,
|
|
7486
|
-
subscriptionId: null
|
|
7487
|
-
};
|
|
7630
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
7631
|
+
mentions: [filter.toString()]
|
|
7632
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7633
|
+
);
|
|
7488
7634
|
|
|
7489
|
-
this.
|
|
7490
|
-
|
|
7491
|
-
|
|
7635
|
+
return this._makeSubscription({
|
|
7636
|
+
callback,
|
|
7637
|
+
method: 'logsSubscribe',
|
|
7638
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
7639
|
+
}, args);
|
|
7492
7640
|
}
|
|
7493
7641
|
/**
|
|
7494
7642
|
* Deregister a logs callback.
|
|
7495
7643
|
*
|
|
7496
|
-
* @param id subscription id to deregister.
|
|
7644
|
+
* @param id client subscription id to deregister.
|
|
7497
7645
|
*/
|
|
7498
7646
|
|
|
7499
7647
|
|
|
7500
|
-
async removeOnLogsListener(
|
|
7501
|
-
|
|
7502
|
-
const subInfo = this._logsSubscriptions[id];
|
|
7503
|
-
delete this._logsSubscriptions[id];
|
|
7504
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
7505
|
-
|
|
7506
|
-
this._updateSubscriptions();
|
|
7507
|
-
} else {
|
|
7508
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
7509
|
-
}
|
|
7648
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
7649
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
7510
7650
|
}
|
|
7511
7651
|
/**
|
|
7512
7652
|
* @internal
|
|
@@ -7514,17 +7654,12 @@ class Connection {
|
|
|
7514
7654
|
|
|
7515
7655
|
|
|
7516
7656
|
_wsOnLogsNotification(notification) {
|
|
7517
|
-
const
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
const sub = this._logsSubscriptions[id];
|
|
7657
|
+
const {
|
|
7658
|
+
result,
|
|
7659
|
+
subscription
|
|
7660
|
+
} = create(notification, LogsNotificationResult);
|
|
7522
7661
|
|
|
7523
|
-
|
|
7524
|
-
sub.callback(res.result.value, res.result.context);
|
|
7525
|
-
return;
|
|
7526
|
-
}
|
|
7527
|
-
}
|
|
7662
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7528
7663
|
}
|
|
7529
7664
|
/**
|
|
7530
7665
|
* @internal
|
|
@@ -7532,14 +7667,12 @@ class Connection {
|
|
|
7532
7667
|
|
|
7533
7668
|
|
|
7534
7669
|
_wsOnSlotNotification(notification) {
|
|
7535
|
-
const
|
|
7670
|
+
const {
|
|
7671
|
+
result,
|
|
7672
|
+
subscription
|
|
7673
|
+
} = create(notification, SlotNotificationResult);
|
|
7536
7674
|
|
|
7537
|
-
|
|
7538
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7539
|
-
sub.callback(res.result);
|
|
7540
|
-
return;
|
|
7541
|
-
}
|
|
7542
|
-
}
|
|
7675
|
+
this._handleServerNotification(subscription, [result]);
|
|
7543
7676
|
}
|
|
7544
7677
|
/**
|
|
7545
7678
|
* Register a callback to be invoked upon slot changes
|
|
@@ -7550,33 +7683,23 @@ class Connection {
|
|
|
7550
7683
|
|
|
7551
7684
|
|
|
7552
7685
|
onSlotChange(callback) {
|
|
7553
|
-
|
|
7554
|
-
this._slotSubscriptions[id] = {
|
|
7686
|
+
return this._makeSubscription({
|
|
7555
7687
|
callback,
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
return id;
|
|
7688
|
+
method: 'slotSubscribe',
|
|
7689
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
7690
|
+
}, []
|
|
7691
|
+
/* args */
|
|
7692
|
+
);
|
|
7562
7693
|
}
|
|
7563
7694
|
/**
|
|
7564
7695
|
* Deregister a slot notification callback
|
|
7565
7696
|
*
|
|
7566
|
-
* @param id subscription id to deregister
|
|
7697
|
+
* @param id client subscription id to deregister
|
|
7567
7698
|
*/
|
|
7568
7699
|
|
|
7569
7700
|
|
|
7570
|
-
async removeSlotChangeListener(
|
|
7571
|
-
|
|
7572
|
-
const subInfo = this._slotSubscriptions[id];
|
|
7573
|
-
delete this._slotSubscriptions[id];
|
|
7574
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
7575
|
-
|
|
7576
|
-
this._updateSubscriptions();
|
|
7577
|
-
} else {
|
|
7578
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
7579
|
-
}
|
|
7701
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
7702
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
7580
7703
|
}
|
|
7581
7704
|
/**
|
|
7582
7705
|
* @internal
|
|
@@ -7584,14 +7707,12 @@ class Connection {
|
|
|
7584
7707
|
|
|
7585
7708
|
|
|
7586
7709
|
_wsOnSlotUpdatesNotification(notification) {
|
|
7587
|
-
const
|
|
7710
|
+
const {
|
|
7711
|
+
result,
|
|
7712
|
+
subscription
|
|
7713
|
+
} = create(notification, SlotUpdateNotificationResult);
|
|
7588
7714
|
|
|
7589
|
-
|
|
7590
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7591
|
-
sub.callback(res.result);
|
|
7592
|
-
return;
|
|
7593
|
-
}
|
|
7594
|
-
}
|
|
7715
|
+
this._handleServerNotification(subscription, [result]);
|
|
7595
7716
|
}
|
|
7596
7717
|
/**
|
|
7597
7718
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -7603,32 +7724,36 @@ class Connection {
|
|
|
7603
7724
|
|
|
7604
7725
|
|
|
7605
7726
|
onSlotUpdate(callback) {
|
|
7606
|
-
|
|
7607
|
-
this._slotUpdateSubscriptions[id] = {
|
|
7727
|
+
return this._makeSubscription({
|
|
7608
7728
|
callback,
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
return id;
|
|
7729
|
+
method: 'slotsUpdatesSubscribe',
|
|
7730
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
7731
|
+
}, []
|
|
7732
|
+
/* args */
|
|
7733
|
+
);
|
|
7615
7734
|
}
|
|
7616
7735
|
/**
|
|
7617
7736
|
* Deregister a slot update notification callback
|
|
7618
7737
|
*
|
|
7619
|
-
* @param id subscription id to deregister
|
|
7738
|
+
* @param id client subscription id to deregister
|
|
7620
7739
|
*/
|
|
7621
7740
|
|
|
7622
7741
|
|
|
7623
|
-
async removeSlotUpdateListener(
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7742
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
7743
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
7744
|
+
}
|
|
7745
|
+
/**
|
|
7746
|
+
* @internal
|
|
7747
|
+
*/
|
|
7628
7748
|
|
|
7629
|
-
|
|
7749
|
+
|
|
7750
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
7751
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7752
|
+
|
|
7753
|
+
if (dispose) {
|
|
7754
|
+
await dispose();
|
|
7630
7755
|
} else {
|
|
7631
|
-
console.warn(
|
|
7756
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
7632
7757
|
}
|
|
7633
7758
|
}
|
|
7634
7759
|
|
|
@@ -7675,30 +7800,34 @@ class Connection {
|
|
|
7675
7800
|
|
|
7676
7801
|
|
|
7677
7802
|
_wsOnSignatureNotification(notification) {
|
|
7678
|
-
const
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7803
|
+
const {
|
|
7804
|
+
result,
|
|
7805
|
+
subscription
|
|
7806
|
+
} = create(notification, SignatureNotificationResult);
|
|
7807
|
+
|
|
7808
|
+
if (result.value !== 'receivedSignature') {
|
|
7809
|
+
/**
|
|
7810
|
+
* Special case.
|
|
7811
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
7812
|
+
* subscription on the server side. We need to track which of these
|
|
7813
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
7814
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
7815
|
+
* (in which case we must tear down the server subscription) or an
|
|
7816
|
+
* already-processed signature (in which case the client can simply
|
|
7817
|
+
* clear out the subscription locally without telling the server).
|
|
7818
|
+
*
|
|
7819
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7820
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7821
|
+
*/
|
|
7822
|
+
this._subscriptionsAutoDisposedByRpc.add(subscription);
|
|
7823
|
+
}
|
|
7824
|
+
|
|
7825
|
+
this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
|
|
7826
|
+
type: 'received'
|
|
7827
|
+
}, result.context] : [{
|
|
7828
|
+
type: 'status',
|
|
7829
|
+
result: result.value
|
|
7830
|
+
}, result.context]);
|
|
7702
7831
|
}
|
|
7703
7832
|
/**
|
|
7704
7833
|
* Register a callback to be invoked upon signature updates
|
|
@@ -7711,23 +7840,26 @@ class Connection {
|
|
|
7711
7840
|
|
|
7712
7841
|
|
|
7713
7842
|
onSignature(signature, callback, commitment) {
|
|
7714
|
-
const
|
|
7715
|
-
|
|
7716
|
-
|
|
7843
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7844
|
+
);
|
|
7845
|
+
|
|
7846
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
7717
7847
|
callback: (notification, context) => {
|
|
7718
7848
|
if (notification.type === 'status') {
|
|
7719
|
-
callback(notification.result, context);
|
|
7849
|
+
callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
7850
|
+
// so no need to explicitly send an unsubscribe message.
|
|
7851
|
+
|
|
7852
|
+
try {
|
|
7853
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
7854
|
+
} catch {// Already removed.
|
|
7855
|
+
}
|
|
7720
7856
|
}
|
|
7721
7857
|
},
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
subscriptionId: null
|
|
7726
|
-
};
|
|
7727
|
-
|
|
7728
|
-
this._updateSubscriptions();
|
|
7858
|
+
method: 'signatureSubscribe',
|
|
7859
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
7860
|
+
}, args);
|
|
7729
7861
|
|
|
7730
|
-
return
|
|
7862
|
+
return clientSubscriptionId;
|
|
7731
7863
|
}
|
|
7732
7864
|
/**
|
|
7733
7865
|
* Register a callback to be invoked when a transaction is
|
|
@@ -7742,35 +7874,43 @@ class Connection {
|
|
|
7742
7874
|
|
|
7743
7875
|
|
|
7744
7876
|
onSignatureWithOptions(signature, callback, options) {
|
|
7745
|
-
const
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
options
|
|
7750
|
-
|
|
7877
|
+
const {
|
|
7878
|
+
commitment,
|
|
7879
|
+
...extra
|
|
7880
|
+
} = { ...options,
|
|
7881
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7882
|
+
|
|
7751
7883
|
};
|
|
7752
7884
|
|
|
7753
|
-
this.
|
|
7885
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
7886
|
+
/* encoding */
|
|
7887
|
+
, extra);
|
|
7888
|
+
|
|
7889
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
7890
|
+
callback: (notification, context) => {
|
|
7891
|
+
callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
7892
|
+
// so no need to explicitly send an unsubscribe message.
|
|
7893
|
+
|
|
7894
|
+
try {
|
|
7895
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
7896
|
+
} catch {// Already removed.
|
|
7897
|
+
}
|
|
7898
|
+
},
|
|
7899
|
+
method: 'signatureSubscribe',
|
|
7900
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
7901
|
+
}, args);
|
|
7754
7902
|
|
|
7755
|
-
return
|
|
7903
|
+
return clientSubscriptionId;
|
|
7756
7904
|
}
|
|
7757
7905
|
/**
|
|
7758
7906
|
* Deregister a signature notification callback
|
|
7759
7907
|
*
|
|
7760
|
-
* @param id subscription id to deregister
|
|
7908
|
+
* @param id client subscription id to deregister
|
|
7761
7909
|
*/
|
|
7762
7910
|
|
|
7763
7911
|
|
|
7764
|
-
async removeSignatureListener(
|
|
7765
|
-
|
|
7766
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
7767
|
-
delete this._signatureSubscriptions[id];
|
|
7768
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
7769
|
-
|
|
7770
|
-
this._updateSubscriptions();
|
|
7771
|
-
} else {
|
|
7772
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
7773
|
-
}
|
|
7912
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
7913
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
7774
7914
|
}
|
|
7775
7915
|
/**
|
|
7776
7916
|
* @internal
|
|
@@ -7778,14 +7918,12 @@ class Connection {
|
|
|
7778
7918
|
|
|
7779
7919
|
|
|
7780
7920
|
_wsOnRootNotification(notification) {
|
|
7781
|
-
const
|
|
7921
|
+
const {
|
|
7922
|
+
result,
|
|
7923
|
+
subscription
|
|
7924
|
+
} = create(notification, RootNotificationResult);
|
|
7782
7925
|
|
|
7783
|
-
|
|
7784
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7785
|
-
sub.callback(res.result);
|
|
7786
|
-
return;
|
|
7787
|
-
}
|
|
7788
|
-
}
|
|
7926
|
+
this._handleServerNotification(subscription, [result]);
|
|
7789
7927
|
}
|
|
7790
7928
|
/**
|
|
7791
7929
|
* Register a callback to be invoked upon root changes
|
|
@@ -7796,33 +7934,23 @@ class Connection {
|
|
|
7796
7934
|
|
|
7797
7935
|
|
|
7798
7936
|
onRootChange(callback) {
|
|
7799
|
-
|
|
7800
|
-
this._rootSubscriptions[id] = {
|
|
7937
|
+
return this._makeSubscription({
|
|
7801
7938
|
callback,
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
return id;
|
|
7939
|
+
method: 'rootSubscribe',
|
|
7940
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
7941
|
+
}, []
|
|
7942
|
+
/* args */
|
|
7943
|
+
);
|
|
7808
7944
|
}
|
|
7809
7945
|
/**
|
|
7810
7946
|
* Deregister a root notification callback
|
|
7811
7947
|
*
|
|
7812
|
-
* @param id subscription id to deregister
|
|
7948
|
+
* @param id client subscription id to deregister
|
|
7813
7949
|
*/
|
|
7814
7950
|
|
|
7815
7951
|
|
|
7816
|
-
async removeRootChangeListener(
|
|
7817
|
-
|
|
7818
|
-
const subInfo = this._rootSubscriptions[id];
|
|
7819
|
-
delete this._rootSubscriptions[id];
|
|
7820
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
7821
|
-
|
|
7822
|
-
this._updateSubscriptions();
|
|
7823
|
-
} else {
|
|
7824
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
7825
|
-
}
|
|
7952
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
7953
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
7826
7954
|
}
|
|
7827
7955
|
|
|
7828
7956
|
}
|
|
@@ -9502,5 +9630,5 @@ function clusterApiUrl(cluster, tls) {
|
|
|
9502
9630
|
|
|
9503
9631
|
const LAMPORTS_PER_SOL = 1000000000;
|
|
9504
9632
|
|
|
9505
|
-
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, PACKET_DATA_SIZE, 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 };
|
|
9633
|
+
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, PACKET_DATA_SIZE, PublicKey, SIGNATURE_LENGTH_IN_BYTES, 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 };
|
|
9506
9634
|
//# sourceMappingURL=index.esm.js.map
|