@solana/web3.js 1.41.1 → 1.41.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.browser.cjs.js +501 -371
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +501 -371
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +501 -371
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +37 -22
- package/lib/index.esm.js +501 -371
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +533 -612
- package/lib/index.iife.js.map +1 -1
- package/lib/index.iife.min.js +1 -23
- package/lib/index.iife.min.js.map +1 -1
- package/package.json +8 -5
- package/src/connection.ts +657 -486
package/lib/index.esm.js
CHANGED
|
@@ -4209,6 +4209,82 @@ class ComputeBudgetProgram {
|
|
|
4209
4209
|
}
|
|
4210
4210
|
ComputeBudgetProgram.programId = new PublicKey('ComputeBudget111111111111111111111111111111');
|
|
4211
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
|
+
|
|
4212
4288
|
const DESTROY_TIMEOUT_MS = 5000;
|
|
4213
4289
|
class AgentManager {
|
|
4214
4290
|
static _newAgent(useHttps) {
|
|
@@ -4424,6 +4500,12 @@ const BufferFromRawAccountData = coerce(instance(Buffer), RawAccountDataResult,
|
|
|
4424
4500
|
*/
|
|
4425
4501
|
|
|
4426
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
|
+
*/
|
|
4427
4509
|
|
|
4428
4510
|
/**
|
|
4429
4511
|
* @internal
|
|
@@ -5298,14 +5380,9 @@ const LogsNotificationResult = type({
|
|
|
5298
5380
|
* Filter for log subscriptions.
|
|
5299
5381
|
*/
|
|
5300
5382
|
|
|
5301
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5302
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5303
|
-
}
|
|
5304
5383
|
/**
|
|
5305
5384
|
* A connection to a fullnode JSON RPC endpoint
|
|
5306
5385
|
*/
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
5386
|
class Connection {
|
|
5310
5387
|
/** @internal */
|
|
5311
5388
|
|
|
@@ -5329,21 +5406,13 @@ class Connection {
|
|
|
5329
5406
|
|
|
5330
5407
|
/** @internal */
|
|
5331
5408
|
|
|
5332
|
-
/** @internal
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
/** @internal */
|
|
5341
|
-
|
|
5342
|
-
/** @internal */
|
|
5343
|
-
|
|
5344
|
-
/** @internal */
|
|
5345
|
-
|
|
5346
|
-
/** @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
|
+
*/
|
|
5347
5416
|
|
|
5348
5417
|
/** @internal */
|
|
5349
5418
|
|
|
@@ -5359,7 +5428,19 @@ class Connection {
|
|
|
5359
5428
|
|
|
5360
5429
|
/** @internal */
|
|
5361
5430
|
|
|
5362
|
-
/**
|
|
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
|
+
*/
|
|
5363
5444
|
|
|
5364
5445
|
/** @internal */
|
|
5365
5446
|
|
|
@@ -5381,6 +5462,7 @@ class Connection {
|
|
|
5381
5462
|
this._rpcWebSocketConnected = false;
|
|
5382
5463
|
this._rpcWebSocketHeartbeat = null;
|
|
5383
5464
|
this._rpcWebSocketIdleTimeout = null;
|
|
5465
|
+
this._rpcWebSocketGeneration = 0;
|
|
5384
5466
|
this._disableBlockhashCaching = false;
|
|
5385
5467
|
this._pollingBlockhash = false;
|
|
5386
5468
|
this._blockhashInfo = {
|
|
@@ -5389,20 +5471,11 @@ class Connection {
|
|
|
5389
5471
|
transactionSignatures: [],
|
|
5390
5472
|
simulatedSignatures: []
|
|
5391
5473
|
};
|
|
5392
|
-
this.
|
|
5393
|
-
this.
|
|
5394
|
-
this.
|
|
5395
|
-
this.
|
|
5396
|
-
this.
|
|
5397
|
-
this._rootSubscriptions = {};
|
|
5398
|
-
this._signatureSubscriptionCounter = 0;
|
|
5399
|
-
this._signatureSubscriptions = {};
|
|
5400
|
-
this._slotSubscriptionCounter = 0;
|
|
5401
|
-
this._slotSubscriptions = {};
|
|
5402
|
-
this._logsSubscriptionCounter = 0;
|
|
5403
|
-
this._logsSubscriptions = {};
|
|
5404
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5405
|
-
this._slotUpdateSubscriptions = {};
|
|
5474
|
+
this._nextClientSubscriptionId = 0;
|
|
5475
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
5476
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
5477
|
+
this._subscriptionsByHash = {};
|
|
5478
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5406
5479
|
let url = new URL(endpoint);
|
|
5407
5480
|
const useHttps = url.protocol === 'https:';
|
|
5408
5481
|
let wsEndpoint;
|
|
@@ -7170,6 +7243,8 @@ class Connection {
|
|
|
7170
7243
|
|
|
7171
7244
|
|
|
7172
7245
|
_wsOnClose(code) {
|
|
7246
|
+
this._rpcWebSocketGeneration++;
|
|
7247
|
+
|
|
7173
7248
|
if (this._rpcWebSocketHeartbeat) {
|
|
7174
7249
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7175
7250
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7183,85 +7258,20 @@ class Connection {
|
|
|
7183
7258
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7184
7259
|
|
|
7185
7260
|
|
|
7186
|
-
this.
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7194
|
-
if (sub.subscriptionId == null) {
|
|
7195
|
-
sub.subscriptionId = 'subscribing';
|
|
7196
|
-
|
|
7197
|
-
try {
|
|
7198
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7199
|
-
|
|
7200
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7201
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7202
|
-
sub.subscriptionId = id;
|
|
7203
|
-
}
|
|
7204
|
-
} catch (err) {
|
|
7205
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7206
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7207
|
-
sub.subscriptionId = null;
|
|
7208
|
-
}
|
|
7209
|
-
|
|
7210
|
-
if (err instanceof Error) {
|
|
7211
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7212
|
-
}
|
|
7213
|
-
}
|
|
7214
|
-
}
|
|
7215
|
-
}
|
|
7216
|
-
/**
|
|
7217
|
-
* @internal
|
|
7218
|
-
*/
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7222
|
-
const subscriptionId = sub.subscriptionId;
|
|
7223
|
-
|
|
7224
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7225
|
-
const unsubscribeId = subscriptionId;
|
|
7226
|
-
|
|
7227
|
-
try {
|
|
7228
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7229
|
-
} catch (err) {
|
|
7230
|
-
if (err instanceof Error) {
|
|
7231
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7232
|
-
}
|
|
7233
|
-
}
|
|
7234
|
-
}
|
|
7235
|
-
}
|
|
7236
|
-
/**
|
|
7237
|
-
* @internal
|
|
7238
|
-
*/
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
_resetSubscriptions() {
|
|
7242
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7243
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7244
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7245
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7246
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7247
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7248
|
-
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
|
+
});
|
|
7249
7267
|
}
|
|
7250
7268
|
/**
|
|
7251
7269
|
* @internal
|
|
7252
7270
|
*/
|
|
7253
7271
|
|
|
7254
7272
|
|
|
7255
|
-
_updateSubscriptions() {
|
|
7256
|
-
|
|
7257
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7258
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7259
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7260
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7261
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7262
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7263
|
-
|
|
7264
|
-
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) {
|
|
7265
7275
|
if (this._rpcWebSocketConnected) {
|
|
7266
7276
|
this._rpcWebSocketConnected = false;
|
|
7267
7277
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7293,60 +7303,167 @@ class Connection {
|
|
|
7293
7303
|
return;
|
|
7294
7304
|
}
|
|
7295
7305
|
|
|
7296
|
-
|
|
7297
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7298
|
-
|
|
7299
|
-
this._subscribe(sub, 'accountSubscribe', this._buildArgs([sub.publicKey], sub.commitment, 'base64'));
|
|
7300
|
-
}
|
|
7306
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7301
7307
|
|
|
7302
|
-
|
|
7303
|
-
|
|
7308
|
+
const isCurrentConnectionStillActive = () => {
|
|
7309
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7310
|
+
};
|
|
7304
7311
|
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
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];
|
|
7309
7318
|
|
|
7310
|
-
|
|
7311
|
-
|
|
7319
|
+
if (subscription === undefined) {
|
|
7320
|
+
// This entry has since been deleted. Skip.
|
|
7321
|
+
return;
|
|
7322
|
+
}
|
|
7312
7323
|
|
|
7313
|
-
|
|
7314
|
-
|
|
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
|
+
}
|
|
7315
7346
|
|
|
7316
|
-
|
|
7317
|
-
|
|
7347
|
+
await this._updateSubscriptions();
|
|
7348
|
+
return;
|
|
7349
|
+
}
|
|
7318
7350
|
|
|
7319
|
-
|
|
7320
|
-
|
|
7351
|
+
await (async () => {
|
|
7352
|
+
const {
|
|
7353
|
+
args,
|
|
7354
|
+
method
|
|
7355
|
+
} = subscription;
|
|
7321
7356
|
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
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?
|
|
7326
7376
|
|
|
7327
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7328
|
-
}
|
|
7329
7377
|
|
|
7330
|
-
|
|
7331
|
-
|
|
7378
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7379
|
+
state: 'pending'
|
|
7380
|
+
};
|
|
7381
|
+
await this._updateSubscriptions();
|
|
7382
|
+
}
|
|
7383
|
+
})();
|
|
7384
|
+
break;
|
|
7332
7385
|
|
|
7333
|
-
|
|
7334
|
-
|
|
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
|
+
}
|
|
7335
7432
|
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7433
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7434
|
+
state: 'unsubscribed'
|
|
7435
|
+
};
|
|
7436
|
+
await this._updateSubscriptions();
|
|
7437
|
+
})();
|
|
7438
|
+
}
|
|
7339
7439
|
|
|
7340
|
-
|
|
7341
|
-
filter = {
|
|
7342
|
-
mentions: [sub.filter.toString()]
|
|
7343
|
-
};
|
|
7344
|
-
} else {
|
|
7345
|
-
filter = sub.filter;
|
|
7440
|
+
break;
|
|
7346
7441
|
}
|
|
7442
|
+
}));
|
|
7443
|
+
}
|
|
7444
|
+
/**
|
|
7445
|
+
* @internal
|
|
7446
|
+
*/
|
|
7347
7447
|
|
|
7348
|
-
|
|
7448
|
+
|
|
7449
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7450
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7451
|
+
|
|
7452
|
+
if (callbacks === undefined) {
|
|
7453
|
+
return;
|
|
7349
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
|
+
});
|
|
7350
7467
|
}
|
|
7351
7468
|
/**
|
|
7352
7469
|
* @internal
|
|
@@ -7354,14 +7471,71 @@ class Connection {
|
|
|
7354
7471
|
|
|
7355
7472
|
|
|
7356
7473
|
_wsOnAccountNotification(notification) {
|
|
7357
|
-
const
|
|
7474
|
+
const {
|
|
7475
|
+
result,
|
|
7476
|
+
subscription
|
|
7477
|
+
} = create(notification, AccountNotificationResult);
|
|
7358
7478
|
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
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);
|
|
7364
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;
|
|
7365
7539
|
}
|
|
7366
7540
|
/**
|
|
7367
7541
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7374,35 +7548,24 @@ class Connection {
|
|
|
7374
7548
|
|
|
7375
7549
|
|
|
7376
7550
|
onAccountChange(publicKey, callback, commitment) {
|
|
7377
|
-
const
|
|
7378
|
-
|
|
7379
|
-
publicKey: publicKey.toBase58(),
|
|
7380
|
-
callback,
|
|
7381
|
-
commitment,
|
|
7382
|
-
subscriptionId: null
|
|
7383
|
-
};
|
|
7551
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7552
|
+
'base64');
|
|
7384
7553
|
|
|
7385
|
-
this.
|
|
7386
|
-
|
|
7387
|
-
|
|
7554
|
+
return this._makeSubscription({
|
|
7555
|
+
callback,
|
|
7556
|
+
method: 'accountSubscribe',
|
|
7557
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
7558
|
+
}, args);
|
|
7388
7559
|
}
|
|
7389
7560
|
/**
|
|
7390
7561
|
* Deregister an account notification callback
|
|
7391
7562
|
*
|
|
7392
|
-
* @param id subscription id to deregister
|
|
7563
|
+
* @param id client subscription id to deregister
|
|
7393
7564
|
*/
|
|
7394
7565
|
|
|
7395
7566
|
|
|
7396
|
-
async removeAccountChangeListener(
|
|
7397
|
-
|
|
7398
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7399
|
-
delete this._accountChangeSubscriptions[id];
|
|
7400
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7401
|
-
|
|
7402
|
-
this._updateSubscriptions();
|
|
7403
|
-
} else {
|
|
7404
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7405
|
-
}
|
|
7567
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
7568
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7406
7569
|
}
|
|
7407
7570
|
/**
|
|
7408
7571
|
* @internal
|
|
@@ -7410,21 +7573,15 @@ class Connection {
|
|
|
7410
7573
|
|
|
7411
7574
|
|
|
7412
7575
|
_wsOnProgramAccountNotification(notification) {
|
|
7413
|
-
const
|
|
7576
|
+
const {
|
|
7577
|
+
result,
|
|
7578
|
+
subscription
|
|
7579
|
+
} = create(notification, ProgramAccountNotificationResult);
|
|
7414
7580
|
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
context
|
|
7420
|
-
} = res.result;
|
|
7421
|
-
sub.callback({
|
|
7422
|
-
accountId: value.pubkey,
|
|
7423
|
-
accountInfo: value.account
|
|
7424
|
-
}, context);
|
|
7425
|
-
return;
|
|
7426
|
-
}
|
|
7427
|
-
}
|
|
7581
|
+
this._handleServerNotification(subscription, [{
|
|
7582
|
+
accountId: result.value.pubkey,
|
|
7583
|
+
accountInfo: result.value.account
|
|
7584
|
+
}, result.context]);
|
|
7428
7585
|
}
|
|
7429
7586
|
/**
|
|
7430
7587
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7439,36 +7596,30 @@ class Connection {
|
|
|
7439
7596
|
|
|
7440
7597
|
|
|
7441
7598
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7442
|
-
const
|
|
7443
|
-
|
|
7444
|
-
|
|
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({
|
|
7445
7609
|
callback,
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
};
|
|
7450
|
-
|
|
7451
|
-
this._updateSubscriptions();
|
|
7452
|
-
|
|
7453
|
-
return id;
|
|
7610
|
+
method: 'programSubscribe',
|
|
7611
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
7612
|
+
}, args);
|
|
7454
7613
|
}
|
|
7455
7614
|
/**
|
|
7456
7615
|
* Deregister an account notification callback
|
|
7457
7616
|
*
|
|
7458
|
-
* @param id subscription id to deregister
|
|
7617
|
+
* @param id client subscription id to deregister
|
|
7459
7618
|
*/
|
|
7460
7619
|
|
|
7461
7620
|
|
|
7462
|
-
async removeProgramAccountChangeListener(
|
|
7463
|
-
|
|
7464
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7465
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7466
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7467
|
-
|
|
7468
|
-
this._updateSubscriptions();
|
|
7469
|
-
} else {
|
|
7470
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
7471
|
-
}
|
|
7621
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
7622
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7472
7623
|
}
|
|
7473
7624
|
/**
|
|
7474
7625
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7476,35 +7627,26 @@ class Connection {
|
|
|
7476
7627
|
|
|
7477
7628
|
|
|
7478
7629
|
onLogs(filter, callback, commitment) {
|
|
7479
|
-
const
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
commitment,
|
|
7484
|
-
subscriptionId: null
|
|
7485
|
-
};
|
|
7486
|
-
|
|
7487
|
-
this._updateSubscriptions();
|
|
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
|
-
return
|
|
7635
|
+
return this._makeSubscription({
|
|
7636
|
+
callback,
|
|
7637
|
+
method: 'logsSubscribe',
|
|
7638
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
7639
|
+
}, args);
|
|
7490
7640
|
}
|
|
7491
7641
|
/**
|
|
7492
7642
|
* Deregister a logs callback.
|
|
7493
7643
|
*
|
|
7494
|
-
* @param id subscription id to deregister.
|
|
7644
|
+
* @param id client subscription id to deregister.
|
|
7495
7645
|
*/
|
|
7496
7646
|
|
|
7497
7647
|
|
|
7498
|
-
async removeOnLogsListener(
|
|
7499
|
-
|
|
7500
|
-
const subInfo = this._logsSubscriptions[id];
|
|
7501
|
-
delete this._logsSubscriptions[id];
|
|
7502
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
7503
|
-
|
|
7504
|
-
this._updateSubscriptions();
|
|
7505
|
-
} else {
|
|
7506
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
7507
|
-
}
|
|
7648
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
7649
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
7508
7650
|
}
|
|
7509
7651
|
/**
|
|
7510
7652
|
* @internal
|
|
@@ -7512,17 +7654,12 @@ class Connection {
|
|
|
7512
7654
|
|
|
7513
7655
|
|
|
7514
7656
|
_wsOnLogsNotification(notification) {
|
|
7515
|
-
const
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
const sub = this._logsSubscriptions[id];
|
|
7657
|
+
const {
|
|
7658
|
+
result,
|
|
7659
|
+
subscription
|
|
7660
|
+
} = create(notification, LogsNotificationResult);
|
|
7520
7661
|
|
|
7521
|
-
|
|
7522
|
-
sub.callback(res.result.value, res.result.context);
|
|
7523
|
-
return;
|
|
7524
|
-
}
|
|
7525
|
-
}
|
|
7662
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7526
7663
|
}
|
|
7527
7664
|
/**
|
|
7528
7665
|
* @internal
|
|
@@ -7530,14 +7667,12 @@ class Connection {
|
|
|
7530
7667
|
|
|
7531
7668
|
|
|
7532
7669
|
_wsOnSlotNotification(notification) {
|
|
7533
|
-
const
|
|
7670
|
+
const {
|
|
7671
|
+
result,
|
|
7672
|
+
subscription
|
|
7673
|
+
} = create(notification, SlotNotificationResult);
|
|
7534
7674
|
|
|
7535
|
-
|
|
7536
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7537
|
-
sub.callback(res.result);
|
|
7538
|
-
return;
|
|
7539
|
-
}
|
|
7540
|
-
}
|
|
7675
|
+
this._handleServerNotification(subscription, [result]);
|
|
7541
7676
|
}
|
|
7542
7677
|
/**
|
|
7543
7678
|
* Register a callback to be invoked upon slot changes
|
|
@@ -7548,33 +7683,23 @@ class Connection {
|
|
|
7548
7683
|
|
|
7549
7684
|
|
|
7550
7685
|
onSlotChange(callback) {
|
|
7551
|
-
|
|
7552
|
-
this._slotSubscriptions[id] = {
|
|
7686
|
+
return this._makeSubscription({
|
|
7553
7687
|
callback,
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
return id;
|
|
7688
|
+
method: 'slotSubscribe',
|
|
7689
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
7690
|
+
}, []
|
|
7691
|
+
/* args */
|
|
7692
|
+
);
|
|
7560
7693
|
}
|
|
7561
7694
|
/**
|
|
7562
7695
|
* Deregister a slot notification callback
|
|
7563
7696
|
*
|
|
7564
|
-
* @param id subscription id to deregister
|
|
7697
|
+
* @param id client subscription id to deregister
|
|
7565
7698
|
*/
|
|
7566
7699
|
|
|
7567
7700
|
|
|
7568
|
-
async removeSlotChangeListener(
|
|
7569
|
-
|
|
7570
|
-
const subInfo = this._slotSubscriptions[id];
|
|
7571
|
-
delete this._slotSubscriptions[id];
|
|
7572
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
7573
|
-
|
|
7574
|
-
this._updateSubscriptions();
|
|
7575
|
-
} else {
|
|
7576
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
7577
|
-
}
|
|
7701
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
7702
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
7578
7703
|
}
|
|
7579
7704
|
/**
|
|
7580
7705
|
* @internal
|
|
@@ -7582,14 +7707,12 @@ class Connection {
|
|
|
7582
7707
|
|
|
7583
7708
|
|
|
7584
7709
|
_wsOnSlotUpdatesNotification(notification) {
|
|
7585
|
-
const
|
|
7710
|
+
const {
|
|
7711
|
+
result,
|
|
7712
|
+
subscription
|
|
7713
|
+
} = create(notification, SlotUpdateNotificationResult);
|
|
7586
7714
|
|
|
7587
|
-
|
|
7588
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7589
|
-
sub.callback(res.result);
|
|
7590
|
-
return;
|
|
7591
|
-
}
|
|
7592
|
-
}
|
|
7715
|
+
this._handleServerNotification(subscription, [result]);
|
|
7593
7716
|
}
|
|
7594
7717
|
/**
|
|
7595
7718
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -7601,32 +7724,36 @@ class Connection {
|
|
|
7601
7724
|
|
|
7602
7725
|
|
|
7603
7726
|
onSlotUpdate(callback) {
|
|
7604
|
-
|
|
7605
|
-
this._slotUpdateSubscriptions[id] = {
|
|
7727
|
+
return this._makeSubscription({
|
|
7606
7728
|
callback,
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
return id;
|
|
7729
|
+
method: 'slotsUpdatesSubscribe',
|
|
7730
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
7731
|
+
}, []
|
|
7732
|
+
/* args */
|
|
7733
|
+
);
|
|
7613
7734
|
}
|
|
7614
7735
|
/**
|
|
7615
7736
|
* Deregister a slot update notification callback
|
|
7616
7737
|
*
|
|
7617
|
-
* @param id subscription id to deregister
|
|
7738
|
+
* @param id client subscription id to deregister
|
|
7618
7739
|
*/
|
|
7619
7740
|
|
|
7620
7741
|
|
|
7621
|
-
async removeSlotUpdateListener(
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7742
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
7743
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
7744
|
+
}
|
|
7745
|
+
/**
|
|
7746
|
+
* @internal
|
|
7747
|
+
*/
|
|
7626
7748
|
|
|
7627
|
-
|
|
7749
|
+
|
|
7750
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
7751
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7752
|
+
|
|
7753
|
+
if (dispose) {
|
|
7754
|
+
await dispose();
|
|
7628
7755
|
} else {
|
|
7629
|
-
console.warn(
|
|
7756
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
7630
7757
|
}
|
|
7631
7758
|
}
|
|
7632
7759
|
|
|
@@ -7673,30 +7800,34 @@ class Connection {
|
|
|
7673
7800
|
|
|
7674
7801
|
|
|
7675
7802
|
_wsOnSignatureNotification(notification) {
|
|
7676
|
-
const
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7680
|
-
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
|
|
7690
|
-
|
|
7691
|
-
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
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]);
|
|
7700
7831
|
}
|
|
7701
7832
|
/**
|
|
7702
7833
|
* Register a callback to be invoked upon signature updates
|
|
@@ -7709,23 +7840,26 @@ class Connection {
|
|
|
7709
7840
|
|
|
7710
7841
|
|
|
7711
7842
|
onSignature(signature, callback, commitment) {
|
|
7712
|
-
const
|
|
7713
|
-
|
|
7714
|
-
|
|
7843
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7844
|
+
);
|
|
7845
|
+
|
|
7846
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
7715
7847
|
callback: (notification, context) => {
|
|
7716
7848
|
if (notification.type === 'status') {
|
|
7717
|
-
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
|
+
}
|
|
7718
7856
|
}
|
|
7719
7857
|
},
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
subscriptionId: null
|
|
7724
|
-
};
|
|
7858
|
+
method: 'signatureSubscribe',
|
|
7859
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
7860
|
+
}, args);
|
|
7725
7861
|
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
return id;
|
|
7862
|
+
return clientSubscriptionId;
|
|
7729
7863
|
}
|
|
7730
7864
|
/**
|
|
7731
7865
|
* Register a callback to be invoked when a transaction is
|
|
@@ -7740,35 +7874,43 @@ class Connection {
|
|
|
7740
7874
|
|
|
7741
7875
|
|
|
7742
7876
|
onSignatureWithOptions(signature, callback, options) {
|
|
7743
|
-
const
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
options
|
|
7748
|
-
|
|
7877
|
+
const {
|
|
7878
|
+
commitment,
|
|
7879
|
+
...extra
|
|
7880
|
+
} = { ...options,
|
|
7881
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7882
|
+
|
|
7749
7883
|
};
|
|
7750
7884
|
|
|
7751
|
-
this.
|
|
7885
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
7886
|
+
/* encoding */
|
|
7887
|
+
, extra);
|
|
7752
7888
|
|
|
7753
|
-
|
|
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);
|
|
7902
|
+
|
|
7903
|
+
return clientSubscriptionId;
|
|
7754
7904
|
}
|
|
7755
7905
|
/**
|
|
7756
7906
|
* Deregister a signature notification callback
|
|
7757
7907
|
*
|
|
7758
|
-
* @param id subscription id to deregister
|
|
7908
|
+
* @param id client subscription id to deregister
|
|
7759
7909
|
*/
|
|
7760
7910
|
|
|
7761
7911
|
|
|
7762
|
-
async removeSignatureListener(
|
|
7763
|
-
|
|
7764
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
7765
|
-
delete this._signatureSubscriptions[id];
|
|
7766
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
7767
|
-
|
|
7768
|
-
this._updateSubscriptions();
|
|
7769
|
-
} else {
|
|
7770
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
7771
|
-
}
|
|
7912
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
7913
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
7772
7914
|
}
|
|
7773
7915
|
/**
|
|
7774
7916
|
* @internal
|
|
@@ -7776,14 +7918,12 @@ class Connection {
|
|
|
7776
7918
|
|
|
7777
7919
|
|
|
7778
7920
|
_wsOnRootNotification(notification) {
|
|
7779
|
-
const
|
|
7921
|
+
const {
|
|
7922
|
+
result,
|
|
7923
|
+
subscription
|
|
7924
|
+
} = create(notification, RootNotificationResult);
|
|
7780
7925
|
|
|
7781
|
-
|
|
7782
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7783
|
-
sub.callback(res.result);
|
|
7784
|
-
return;
|
|
7785
|
-
}
|
|
7786
|
-
}
|
|
7926
|
+
this._handleServerNotification(subscription, [result]);
|
|
7787
7927
|
}
|
|
7788
7928
|
/**
|
|
7789
7929
|
* Register a callback to be invoked upon root changes
|
|
@@ -7794,33 +7934,23 @@ class Connection {
|
|
|
7794
7934
|
|
|
7795
7935
|
|
|
7796
7936
|
onRootChange(callback) {
|
|
7797
|
-
|
|
7798
|
-
this._rootSubscriptions[id] = {
|
|
7937
|
+
return this._makeSubscription({
|
|
7799
7938
|
callback,
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
return id;
|
|
7939
|
+
method: 'rootSubscribe',
|
|
7940
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
7941
|
+
}, []
|
|
7942
|
+
/* args */
|
|
7943
|
+
);
|
|
7806
7944
|
}
|
|
7807
7945
|
/**
|
|
7808
7946
|
* Deregister a root notification callback
|
|
7809
7947
|
*
|
|
7810
|
-
* @param id subscription id to deregister
|
|
7948
|
+
* @param id client subscription id to deregister
|
|
7811
7949
|
*/
|
|
7812
7950
|
|
|
7813
7951
|
|
|
7814
|
-
async removeRootChangeListener(
|
|
7815
|
-
|
|
7816
|
-
const subInfo = this._rootSubscriptions[id];
|
|
7817
|
-
delete this._rootSubscriptions[id];
|
|
7818
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
7819
|
-
|
|
7820
|
-
this._updateSubscriptions();
|
|
7821
|
-
} else {
|
|
7822
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
7823
|
-
}
|
|
7952
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
7953
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
7824
7954
|
}
|
|
7825
7955
|
|
|
7826
7956
|
}
|