@solana/web3.js 1.41.1 → 1.41.4
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 +593 -375
- package/lib/index.browser.cjs.js.map +1 -1
- package/lib/index.browser.esm.js +639 -422
- package/lib/index.browser.esm.js.map +1 -1
- package/lib/index.cjs.js +610 -378
- package/lib/index.cjs.js.map +1 -1
- package/lib/index.d.ts +77 -26
- package/lib/index.esm.js +657 -426
- package/lib/index.esm.js.map +1 -1
- package/lib/index.iife.js +12157 -12148
- 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 +9 -5
- package/src/connection.ts +657 -486
- package/src/index.ts +1 -0
- package/src/system-program.ts +39 -10
package/lib/index.cjs.js
CHANGED
|
@@ -8,7 +8,7 @@ var BN = require('bn.js');
|
|
|
8
8
|
var bs58 = require('bs58');
|
|
9
9
|
var borsh = require('borsh');
|
|
10
10
|
var BufferLayout = require('@solana/buffer-layout');
|
|
11
|
-
var
|
|
11
|
+
var fetch = require('cross-fetch');
|
|
12
12
|
var superstruct = require('superstruct');
|
|
13
13
|
var rpcWebsockets = require('rpc-websockets');
|
|
14
14
|
var RpcClient = require('jayson/lib/client/browser');
|
|
@@ -41,7 +41,7 @@ var nacl__default = /*#__PURE__*/_interopDefaultLegacy(nacl);
|
|
|
41
41
|
var BN__default = /*#__PURE__*/_interopDefaultLegacy(BN);
|
|
42
42
|
var bs58__default = /*#__PURE__*/_interopDefaultLegacy(bs58);
|
|
43
43
|
var BufferLayout__namespace = /*#__PURE__*/_interopNamespace(BufferLayout);
|
|
44
|
-
var
|
|
44
|
+
var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
|
|
45
45
|
var RpcClient__default = /*#__PURE__*/_interopDefaultLegacy(RpcClient);
|
|
46
46
|
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
47
47
|
var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
@@ -3111,6 +3111,106 @@ function sleep(ms) {
|
|
|
3111
3111
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
3112
3112
|
}
|
|
3113
3113
|
|
|
3114
|
+
const encodeDecode = (layout) => {
|
|
3115
|
+
const decode = layout.decode.bind(layout);
|
|
3116
|
+
const encode = layout.encode.bind(layout);
|
|
3117
|
+
return { decode, encode };
|
|
3118
|
+
};
|
|
3119
|
+
|
|
3120
|
+
var node = {};
|
|
3121
|
+
|
|
3122
|
+
Object.defineProperty(node, "__esModule", { value: true });
|
|
3123
|
+
let converter;
|
|
3124
|
+
{
|
|
3125
|
+
try {
|
|
3126
|
+
converter = require('bindings')('bigint_buffer');
|
|
3127
|
+
}
|
|
3128
|
+
catch (e) {
|
|
3129
|
+
console.warn('bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)');
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
/**
|
|
3133
|
+
* Convert a little-endian buffer into a BigInt.
|
|
3134
|
+
* @param buf The little-endian buffer to convert
|
|
3135
|
+
* @returns A BigInt with the little-endian representation of buf.
|
|
3136
|
+
*/
|
|
3137
|
+
function toBigIntLE(buf) {
|
|
3138
|
+
if (converter === undefined) {
|
|
3139
|
+
const reversed = Buffer.from(buf);
|
|
3140
|
+
reversed.reverse();
|
|
3141
|
+
const hex = reversed.toString('hex');
|
|
3142
|
+
if (hex.length === 0) {
|
|
3143
|
+
return BigInt(0);
|
|
3144
|
+
}
|
|
3145
|
+
return BigInt(`0x${hex}`);
|
|
3146
|
+
}
|
|
3147
|
+
return converter.toBigInt(buf, false);
|
|
3148
|
+
}
|
|
3149
|
+
var toBigIntLE_1 = node.toBigIntLE = toBigIntLE;
|
|
3150
|
+
/**
|
|
3151
|
+
* Convert a big-endian buffer into a BigInt
|
|
3152
|
+
* @param buf The big-endian buffer to convert.
|
|
3153
|
+
* @returns A BigInt with the big-endian representation of buf.
|
|
3154
|
+
*/
|
|
3155
|
+
function toBigIntBE(buf) {
|
|
3156
|
+
if (converter === undefined) {
|
|
3157
|
+
const hex = buf.toString('hex');
|
|
3158
|
+
if (hex.length === 0) {
|
|
3159
|
+
return BigInt(0);
|
|
3160
|
+
}
|
|
3161
|
+
return BigInt(`0x${hex}`);
|
|
3162
|
+
}
|
|
3163
|
+
return converter.toBigInt(buf, true);
|
|
3164
|
+
}
|
|
3165
|
+
node.toBigIntBE = toBigIntBE;
|
|
3166
|
+
/**
|
|
3167
|
+
* Convert a BigInt to a little-endian buffer.
|
|
3168
|
+
* @param num The BigInt to convert.
|
|
3169
|
+
* @param width The number of bytes that the resulting buffer should be.
|
|
3170
|
+
* @returns A little-endian buffer representation of num.
|
|
3171
|
+
*/
|
|
3172
|
+
function toBufferLE(num, width) {
|
|
3173
|
+
if (converter === undefined) {
|
|
3174
|
+
const hex = num.toString(16);
|
|
3175
|
+
const buffer = Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
3176
|
+
buffer.reverse();
|
|
3177
|
+
return buffer;
|
|
3178
|
+
}
|
|
3179
|
+
// Allocation is done here, since it is slower using napi in C
|
|
3180
|
+
return converter.fromBigInt(num, Buffer.allocUnsafe(width), false);
|
|
3181
|
+
}
|
|
3182
|
+
var toBufferLE_1 = node.toBufferLE = toBufferLE;
|
|
3183
|
+
/**
|
|
3184
|
+
* Convert a BigInt to a big-endian buffer.
|
|
3185
|
+
* @param num The BigInt to convert.
|
|
3186
|
+
* @param width The number of bytes that the resulting buffer should be.
|
|
3187
|
+
* @returns A big-endian buffer representation of num.
|
|
3188
|
+
*/
|
|
3189
|
+
function toBufferBE(num, width) {
|
|
3190
|
+
if (converter === undefined) {
|
|
3191
|
+
const hex = num.toString(16);
|
|
3192
|
+
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
3193
|
+
}
|
|
3194
|
+
return converter.fromBigInt(num, Buffer.allocUnsafe(width), true);
|
|
3195
|
+
}
|
|
3196
|
+
node.toBufferBE = toBufferBE;
|
|
3197
|
+
|
|
3198
|
+
const bigInt = (length) => (property) => {
|
|
3199
|
+
const layout = BufferLayout.blob(length, property);
|
|
3200
|
+
const { encode, decode } = encodeDecode(layout);
|
|
3201
|
+
const bigIntLayout = layout;
|
|
3202
|
+
bigIntLayout.decode = (buffer, offset) => {
|
|
3203
|
+
const src = decode(buffer, offset);
|
|
3204
|
+
return toBigIntLE_1(Buffer.from(src));
|
|
3205
|
+
};
|
|
3206
|
+
bigIntLayout.encode = (bigInt, buffer, offset) => {
|
|
3207
|
+
const src = toBufferLE_1(bigInt, length);
|
|
3208
|
+
return encode(src, buffer, offset);
|
|
3209
|
+
};
|
|
3210
|
+
return bigIntLayout;
|
|
3211
|
+
};
|
|
3212
|
+
const u64 = bigInt(8);
|
|
3213
|
+
|
|
3114
3214
|
/**
|
|
3115
3215
|
* Populate a buffer of instruction data using an InstructionType
|
|
3116
3216
|
* @internal
|
|
@@ -3500,7 +3600,7 @@ const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
3500
3600
|
},
|
|
3501
3601
|
Transfer: {
|
|
3502
3602
|
index: 2,
|
|
3503
|
-
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'),
|
|
3603
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), u64('lamports')])
|
|
3504
3604
|
},
|
|
3505
3605
|
CreateWithSeed: {
|
|
3506
3606
|
index: 3,
|
|
@@ -3536,7 +3636,7 @@ const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
3536
3636
|
},
|
|
3537
3637
|
TransferWithSeed: {
|
|
3538
3638
|
index: 11,
|
|
3539
|
-
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'),
|
|
3639
|
+
layout: BufferLayout__namespace.struct([BufferLayout__namespace.u32('instruction'), u64('lamports'), rustString('seed'), publicKey('programId')])
|
|
3540
3640
|
}
|
|
3541
3641
|
});
|
|
3542
3642
|
/**
|
|
@@ -3589,7 +3689,7 @@ class SystemProgram {
|
|
|
3589
3689
|
if ('basePubkey' in params) {
|
|
3590
3690
|
const type = SYSTEM_INSTRUCTION_LAYOUTS.TransferWithSeed;
|
|
3591
3691
|
data = encodeData(type, {
|
|
3592
|
-
lamports: params.lamports,
|
|
3692
|
+
lamports: BigInt(params.lamports),
|
|
3593
3693
|
seed: params.seed,
|
|
3594
3694
|
programId: toBuffer(params.programId.toBuffer())
|
|
3595
3695
|
});
|
|
@@ -3609,7 +3709,7 @@ class SystemProgram {
|
|
|
3609
3709
|
} else {
|
|
3610
3710
|
const type = SYSTEM_INSTRUCTION_LAYOUTS.Transfer;
|
|
3611
3711
|
data = encodeData(type, {
|
|
3612
|
-
lamports: params.lamports
|
|
3712
|
+
lamports: BigInt(params.lamports)
|
|
3613
3713
|
});
|
|
3614
3714
|
keys = [{
|
|
3615
3715
|
pubkey: params.fromPubkey,
|
|
@@ -4244,6 +4344,82 @@ class ComputeBudgetProgram {
|
|
|
4244
4344
|
}
|
|
4245
4345
|
ComputeBudgetProgram.programId = new PublicKey('ComputeBudget111111111111111111111111111111');
|
|
4246
4346
|
|
|
4347
|
+
var objToString = Object.prototype.toString;
|
|
4348
|
+
var objKeys = Object.keys || function(obj) {
|
|
4349
|
+
var keys = [];
|
|
4350
|
+
for (var name in obj) {
|
|
4351
|
+
keys.push(name);
|
|
4352
|
+
}
|
|
4353
|
+
return keys;
|
|
4354
|
+
};
|
|
4355
|
+
|
|
4356
|
+
function stringify(val, isArrayProp) {
|
|
4357
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
4358
|
+
if (val === true) {
|
|
4359
|
+
return "true";
|
|
4360
|
+
}
|
|
4361
|
+
if (val === false) {
|
|
4362
|
+
return "false";
|
|
4363
|
+
}
|
|
4364
|
+
switch (typeof val) {
|
|
4365
|
+
case "object":
|
|
4366
|
+
if (val === null) {
|
|
4367
|
+
return null;
|
|
4368
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
4369
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
4370
|
+
} else {
|
|
4371
|
+
toStr = objToString.call(val);
|
|
4372
|
+
if (toStr === "[object Array]") {
|
|
4373
|
+
str = '[';
|
|
4374
|
+
max = val.length - 1;
|
|
4375
|
+
for(i = 0; i < max; i++) {
|
|
4376
|
+
str += stringify(val[i], true) + ',';
|
|
4377
|
+
}
|
|
4378
|
+
if (max > -1) {
|
|
4379
|
+
str += stringify(val[i], true);
|
|
4380
|
+
}
|
|
4381
|
+
return str + ']';
|
|
4382
|
+
} else if (toStr === "[object Object]") {
|
|
4383
|
+
// only object is left
|
|
4384
|
+
keys = objKeys(val).sort();
|
|
4385
|
+
max = keys.length;
|
|
4386
|
+
str = "";
|
|
4387
|
+
i = 0;
|
|
4388
|
+
while (i < max) {
|
|
4389
|
+
key = keys[i];
|
|
4390
|
+
propVal = stringify(val[key], false);
|
|
4391
|
+
if (propVal !== undefined) {
|
|
4392
|
+
if (str) {
|
|
4393
|
+
str += ',';
|
|
4394
|
+
}
|
|
4395
|
+
str += JSON.stringify(key) + ':' + propVal;
|
|
4396
|
+
}
|
|
4397
|
+
i++;
|
|
4398
|
+
}
|
|
4399
|
+
return '{' + str + '}';
|
|
4400
|
+
} else {
|
|
4401
|
+
return JSON.stringify(val);
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
case "function":
|
|
4405
|
+
case "undefined":
|
|
4406
|
+
return isArrayProp ? null : undefined;
|
|
4407
|
+
case "string":
|
|
4408
|
+
return JSON.stringify(val);
|
|
4409
|
+
default:
|
|
4410
|
+
return isFinite(val) ? val : null;
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4414
|
+
var fastStableStringify = function(val) {
|
|
4415
|
+
var returnVal = stringify(val, false);
|
|
4416
|
+
if (returnVal !== undefined) {
|
|
4417
|
+
return ''+ returnVal;
|
|
4418
|
+
}
|
|
4419
|
+
};
|
|
4420
|
+
|
|
4421
|
+
var fastStableStringify$1 = fastStableStringify;
|
|
4422
|
+
|
|
4247
4423
|
const DESTROY_TIMEOUT_MS = 5000;
|
|
4248
4424
|
class AgentManager {
|
|
4249
4425
|
static _newAgent(useHttps) {
|
|
@@ -4459,6 +4635,12 @@ const BufferFromRawAccountData = superstruct.coerce(superstruct.instance(buffer.
|
|
|
4459
4635
|
*/
|
|
4460
4636
|
|
|
4461
4637
|
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|
4638
|
+
/**
|
|
4639
|
+
* HACK.
|
|
4640
|
+
* Copied from rpc-websockets/dist/lib/client.
|
|
4641
|
+
* Otherwise, `yarn build` fails with:
|
|
4642
|
+
* https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
|
|
4643
|
+
*/
|
|
4462
4644
|
|
|
4463
4645
|
/**
|
|
4464
4646
|
* @internal
|
|
@@ -4629,7 +4811,7 @@ const BlockProductionResponseStruct = jsonRpcResultAndContext(superstruct.type({
|
|
|
4629
4811
|
*/
|
|
4630
4812
|
|
|
4631
4813
|
function createRpcClient(url, useHttps, httpHeaders, customFetch, fetchMiddleware, disableRetryOnRateLimit) {
|
|
4632
|
-
const fetch = customFetch ? customFetch :
|
|
4814
|
+
const fetch = customFetch ? customFetch : fetch__default["default"];
|
|
4633
4815
|
let agentManager;
|
|
4634
4816
|
|
|
4635
4817
|
{
|
|
@@ -5333,14 +5515,9 @@ const LogsNotificationResult = superstruct.type({
|
|
|
5333
5515
|
* Filter for log subscriptions.
|
|
5334
5516
|
*/
|
|
5335
5517
|
|
|
5336
|
-
function createSubscriptionWarningMessage(id, label) {
|
|
5337
|
-
return 'Ignored unsubscribe request because an active subscription ' + `with id \`${id}\` for '${label}' events could not be found.`;
|
|
5338
|
-
}
|
|
5339
5518
|
/**
|
|
5340
5519
|
* A connection to a fullnode JSON RPC endpoint
|
|
5341
5520
|
*/
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
5521
|
class Connection {
|
|
5345
5522
|
/** @internal */
|
|
5346
5523
|
|
|
@@ -5364,21 +5541,13 @@ class Connection {
|
|
|
5364
5541
|
|
|
5365
5542
|
/** @internal */
|
|
5366
5543
|
|
|
5367
|
-
/** @internal
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
/** @internal */
|
|
5376
|
-
|
|
5377
|
-
/** @internal */
|
|
5378
|
-
|
|
5379
|
-
/** @internal */
|
|
5380
|
-
|
|
5381
|
-
/** @internal */
|
|
5544
|
+
/** @internal
|
|
5545
|
+
* A number that we increment every time an active connection closes.
|
|
5546
|
+
* Used to determine whether the same socket connection that was open
|
|
5547
|
+
* when an async operation started is the same one that's active when
|
|
5548
|
+
* its continuation fires.
|
|
5549
|
+
*
|
|
5550
|
+
*/
|
|
5382
5551
|
|
|
5383
5552
|
/** @internal */
|
|
5384
5553
|
|
|
@@ -5394,7 +5563,19 @@ class Connection {
|
|
|
5394
5563
|
|
|
5395
5564
|
/** @internal */
|
|
5396
5565
|
|
|
5397
|
-
/**
|
|
5566
|
+
/**
|
|
5567
|
+
* Special case.
|
|
5568
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
5569
|
+
* subscription on the server side. We need to track which of these
|
|
5570
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
5571
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
5572
|
+
* (in which case we must tear down the server subscription) or an
|
|
5573
|
+
* already-processed signature (in which case the client can simply
|
|
5574
|
+
* clear out the subscription locally without telling the server).
|
|
5575
|
+
*
|
|
5576
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
5577
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
5578
|
+
*/
|
|
5398
5579
|
|
|
5399
5580
|
/** @internal */
|
|
5400
5581
|
|
|
@@ -5416,6 +5597,7 @@ class Connection {
|
|
|
5416
5597
|
this._rpcWebSocketConnected = false;
|
|
5417
5598
|
this._rpcWebSocketHeartbeat = null;
|
|
5418
5599
|
this._rpcWebSocketIdleTimeout = null;
|
|
5600
|
+
this._rpcWebSocketGeneration = 0;
|
|
5419
5601
|
this._disableBlockhashCaching = false;
|
|
5420
5602
|
this._pollingBlockhash = false;
|
|
5421
5603
|
this._blockhashInfo = {
|
|
@@ -5424,20 +5606,11 @@ class Connection {
|
|
|
5424
5606
|
transactionSignatures: [],
|
|
5425
5607
|
simulatedSignatures: []
|
|
5426
5608
|
};
|
|
5427
|
-
this.
|
|
5428
|
-
this.
|
|
5429
|
-
this.
|
|
5430
|
-
this.
|
|
5431
|
-
this.
|
|
5432
|
-
this._rootSubscriptions = {};
|
|
5433
|
-
this._signatureSubscriptionCounter = 0;
|
|
5434
|
-
this._signatureSubscriptions = {};
|
|
5435
|
-
this._slotSubscriptionCounter = 0;
|
|
5436
|
-
this._slotSubscriptions = {};
|
|
5437
|
-
this._logsSubscriptionCounter = 0;
|
|
5438
|
-
this._logsSubscriptions = {};
|
|
5439
|
-
this._slotUpdateSubscriptionCounter = 0;
|
|
5440
|
-
this._slotUpdateSubscriptions = {};
|
|
5609
|
+
this._nextClientSubscriptionId = 0;
|
|
5610
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
5611
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
5612
|
+
this._subscriptionsByHash = {};
|
|
5613
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5441
5614
|
let url = new URL(endpoint);
|
|
5442
5615
|
const useHttps = url.protocol === 'https:';
|
|
5443
5616
|
let wsEndpoint;
|
|
@@ -7205,6 +7378,8 @@ class Connection {
|
|
|
7205
7378
|
|
|
7206
7379
|
|
|
7207
7380
|
_wsOnClose(code) {
|
|
7381
|
+
this._rpcWebSocketGeneration++;
|
|
7382
|
+
|
|
7208
7383
|
if (this._rpcWebSocketHeartbeat) {
|
|
7209
7384
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7210
7385
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7218,85 +7393,20 @@ class Connection {
|
|
|
7218
7393
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7219
7394
|
|
|
7220
7395
|
|
|
7221
|
-
this.
|
|
7222
|
-
|
|
7223
|
-
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
|
|
7228
|
-
async _subscribe(sub, rpcMethod, rpcArgs) {
|
|
7229
|
-
if (sub.subscriptionId == null) {
|
|
7230
|
-
sub.subscriptionId = 'subscribing';
|
|
7231
|
-
|
|
7232
|
-
try {
|
|
7233
|
-
const id = await this._rpcWebSocket.call(rpcMethod, rpcArgs);
|
|
7234
|
-
|
|
7235
|
-
if (typeof id === 'number' && sub.subscriptionId === 'subscribing') {
|
|
7236
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7237
|
-
sub.subscriptionId = id;
|
|
7238
|
-
}
|
|
7239
|
-
} catch (err) {
|
|
7240
|
-
if (sub.subscriptionId === 'subscribing') {
|
|
7241
|
-
// eslint-disable-next-line require-atomic-updates
|
|
7242
|
-
sub.subscriptionId = null;
|
|
7243
|
-
}
|
|
7244
|
-
|
|
7245
|
-
if (err instanceof Error) {
|
|
7246
|
-
console.error(`${rpcMethod} error for argument`, rpcArgs, err.message);
|
|
7247
|
-
}
|
|
7248
|
-
}
|
|
7249
|
-
}
|
|
7250
|
-
}
|
|
7251
|
-
/**
|
|
7252
|
-
* @internal
|
|
7253
|
-
*/
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
async _unsubscribe(sub, rpcMethod) {
|
|
7257
|
-
const subscriptionId = sub.subscriptionId;
|
|
7258
|
-
|
|
7259
|
-
if (subscriptionId != null && typeof subscriptionId != 'string') {
|
|
7260
|
-
const unsubscribeId = subscriptionId;
|
|
7261
|
-
|
|
7262
|
-
try {
|
|
7263
|
-
await this._rpcWebSocket.call(rpcMethod, [unsubscribeId]);
|
|
7264
|
-
} catch (err) {
|
|
7265
|
-
if (err instanceof Error) {
|
|
7266
|
-
console.error(`${rpcMethod} error:`, err.message);
|
|
7267
|
-
}
|
|
7268
|
-
}
|
|
7269
|
-
}
|
|
7270
|
-
}
|
|
7271
|
-
/**
|
|
7272
|
-
* @internal
|
|
7273
|
-
*/
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
_resetSubscriptions() {
|
|
7277
|
-
Object.values(this._accountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7278
|
-
Object.values(this._logsSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7279
|
-
Object.values(this._programAccountChangeSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7280
|
-
Object.values(this._rootSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7281
|
-
Object.values(this._signatureSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7282
|
-
Object.values(this._slotSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7283
|
-
Object.values(this._slotUpdateSubscriptions).forEach(s => s.subscriptionId = null);
|
|
7396
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
7397
|
+
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
7398
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7399
|
+
state: 'pending'
|
|
7400
|
+
};
|
|
7401
|
+
});
|
|
7284
7402
|
}
|
|
7285
7403
|
/**
|
|
7286
7404
|
* @internal
|
|
7287
7405
|
*/
|
|
7288
7406
|
|
|
7289
7407
|
|
|
7290
|
-
_updateSubscriptions() {
|
|
7291
|
-
|
|
7292
|
-
const programKeys = Object.keys(this._programAccountChangeSubscriptions).map(Number);
|
|
7293
|
-
const slotKeys = Object.keys(this._slotSubscriptions).map(Number);
|
|
7294
|
-
const slotUpdateKeys = Object.keys(this._slotUpdateSubscriptions).map(Number);
|
|
7295
|
-
const signatureKeys = Object.keys(this._signatureSubscriptions).map(Number);
|
|
7296
|
-
const rootKeys = Object.keys(this._rootSubscriptions).map(Number);
|
|
7297
|
-
const logsKeys = Object.keys(this._logsSubscriptions).map(Number);
|
|
7298
|
-
|
|
7299
|
-
if (accountKeys.length === 0 && programKeys.length === 0 && slotKeys.length === 0 && slotUpdateKeys.length === 0 && signatureKeys.length === 0 && rootKeys.length === 0 && logsKeys.length === 0) {
|
|
7408
|
+
async _updateSubscriptions() {
|
|
7409
|
+
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
7300
7410
|
if (this._rpcWebSocketConnected) {
|
|
7301
7411
|
this._rpcWebSocketConnected = false;
|
|
7302
7412
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7328,60 +7438,167 @@ class Connection {
|
|
|
7328
7438
|
return;
|
|
7329
7439
|
}
|
|
7330
7440
|
|
|
7331
|
-
|
|
7332
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7441
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7333
7442
|
|
|
7334
|
-
|
|
7335
|
-
|
|
7443
|
+
const isCurrentConnectionStillActive = () => {
|
|
7444
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7445
|
+
};
|
|
7336
7446
|
|
|
7337
|
-
|
|
7338
|
-
|
|
7447
|
+
await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
|
|
7448
|
+
// `_updateSubscriptions` recursively when processing the state,
|
|
7449
|
+
// so it's important that we look up the *current* version of
|
|
7450
|
+
// each subscription, every time we process a hash.
|
|
7451
|
+
Object.keys(this._subscriptionsByHash).map(async hash => {
|
|
7452
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7339
7453
|
|
|
7340
|
-
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
for (let id of slotKeys) {
|
|
7346
|
-
const sub = this._slotSubscriptions[id];
|
|
7454
|
+
if (subscription === undefined) {
|
|
7455
|
+
// This entry has since been deleted. Skip.
|
|
7456
|
+
return;
|
|
7457
|
+
}
|
|
7347
7458
|
|
|
7348
|
-
|
|
7349
|
-
|
|
7459
|
+
switch (subscription.state) {
|
|
7460
|
+
case 'pending':
|
|
7461
|
+
case 'unsubscribed':
|
|
7462
|
+
if (subscription.callbacks.size === 0) {
|
|
7463
|
+
/**
|
|
7464
|
+
* You can end up here when:
|
|
7465
|
+
*
|
|
7466
|
+
* - a subscription has recently unsubscribed
|
|
7467
|
+
* without having new callbacks added to it
|
|
7468
|
+
* while the unsubscribe was in flight, or
|
|
7469
|
+
* - when a pending subscription has its
|
|
7470
|
+
* listeners removed before a request was
|
|
7471
|
+
* sent to the server.
|
|
7472
|
+
*
|
|
7473
|
+
* Being that nobody is interested in this
|
|
7474
|
+
* subscription any longer, delete it.
|
|
7475
|
+
*/
|
|
7476
|
+
delete this._subscriptionsByHash[hash];
|
|
7477
|
+
|
|
7478
|
+
if (subscription.state === 'unsubscribed') {
|
|
7479
|
+
delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
|
|
7480
|
+
}
|
|
7350
7481
|
|
|
7351
|
-
|
|
7352
|
-
|
|
7482
|
+
await this._updateSubscriptions();
|
|
7483
|
+
return;
|
|
7484
|
+
}
|
|
7353
7485
|
|
|
7354
|
-
|
|
7355
|
-
|
|
7486
|
+
await (async () => {
|
|
7487
|
+
const {
|
|
7488
|
+
args,
|
|
7489
|
+
method
|
|
7490
|
+
} = subscription;
|
|
7356
7491
|
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7492
|
+
try {
|
|
7493
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7494
|
+
state: 'subscribing'
|
|
7495
|
+
};
|
|
7496
|
+
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
7497
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7498
|
+
serverSubscriptionId,
|
|
7499
|
+
state: 'subscribed'
|
|
7500
|
+
};
|
|
7501
|
+
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
7502
|
+
await this._updateSubscriptions();
|
|
7503
|
+
} catch (e) {
|
|
7504
|
+
if (e instanceof Error) {
|
|
7505
|
+
console.error(`${method} error for argument`, args, e.message);
|
|
7506
|
+
}
|
|
7507
|
+
|
|
7508
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7509
|
+
return;
|
|
7510
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7361
7511
|
|
|
7362
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7363
|
-
}
|
|
7364
7512
|
|
|
7365
|
-
|
|
7366
|
-
|
|
7513
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7514
|
+
state: 'pending'
|
|
7515
|
+
};
|
|
7516
|
+
await this._updateSubscriptions();
|
|
7517
|
+
}
|
|
7518
|
+
})();
|
|
7519
|
+
break;
|
|
7367
7520
|
|
|
7368
|
-
|
|
7369
|
-
|
|
7521
|
+
case 'subscribed':
|
|
7522
|
+
if (subscription.callbacks.size === 0) {
|
|
7523
|
+
// By the time we successfully set up a subscription
|
|
7524
|
+
// with the server, the client stopped caring about it.
|
|
7525
|
+
// Tear it down now.
|
|
7526
|
+
await (async () => {
|
|
7527
|
+
const {
|
|
7528
|
+
serverSubscriptionId,
|
|
7529
|
+
unsubscribeMethod
|
|
7530
|
+
} = subscription;
|
|
7531
|
+
|
|
7532
|
+
if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
|
|
7533
|
+
/**
|
|
7534
|
+
* Special case.
|
|
7535
|
+
* If we're dealing with a subscription that has been auto-
|
|
7536
|
+
* disposed by the RPC, then we can skip the RPC call to
|
|
7537
|
+
* tear down the subscription here.
|
|
7538
|
+
*
|
|
7539
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7540
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7541
|
+
*/
|
|
7542
|
+
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
7543
|
+
} else {
|
|
7544
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7545
|
+
state: 'unsubscribing'
|
|
7546
|
+
};
|
|
7547
|
+
|
|
7548
|
+
try {
|
|
7549
|
+
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
7550
|
+
} catch (e) {
|
|
7551
|
+
if (e instanceof Error) {
|
|
7552
|
+
console.error(`${unsubscribeMethod} error:`, e.message);
|
|
7553
|
+
}
|
|
7554
|
+
|
|
7555
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7556
|
+
return;
|
|
7557
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7558
|
+
|
|
7559
|
+
|
|
7560
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7561
|
+
state: 'subscribed'
|
|
7562
|
+
};
|
|
7563
|
+
await this._updateSubscriptions();
|
|
7564
|
+
return;
|
|
7565
|
+
}
|
|
7566
|
+
}
|
|
7370
7567
|
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
|
|
7568
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7569
|
+
state: 'unsubscribed'
|
|
7570
|
+
};
|
|
7571
|
+
await this._updateSubscriptions();
|
|
7572
|
+
})();
|
|
7573
|
+
}
|
|
7374
7574
|
|
|
7375
|
-
|
|
7376
|
-
filter = {
|
|
7377
|
-
mentions: [sub.filter.toString()]
|
|
7378
|
-
};
|
|
7379
|
-
} else {
|
|
7380
|
-
filter = sub.filter;
|
|
7575
|
+
break;
|
|
7381
7576
|
}
|
|
7577
|
+
}));
|
|
7578
|
+
}
|
|
7579
|
+
/**
|
|
7580
|
+
* @internal
|
|
7581
|
+
*/
|
|
7582
|
+
|
|
7382
7583
|
|
|
7383
|
-
|
|
7584
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7585
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7586
|
+
|
|
7587
|
+
if (callbacks === undefined) {
|
|
7588
|
+
return;
|
|
7384
7589
|
}
|
|
7590
|
+
|
|
7591
|
+
callbacks.forEach(cb => {
|
|
7592
|
+
try {
|
|
7593
|
+
cb( // I failed to find a way to convince TypeScript that `cb` is of type
|
|
7594
|
+
// `TCallback` which is certainly compatible with `Parameters<TCallback>`.
|
|
7595
|
+
// See https://github.com/microsoft/TypeScript/issues/47615
|
|
7596
|
+
// @ts-ignore
|
|
7597
|
+
...callbackArgs);
|
|
7598
|
+
} catch (e) {
|
|
7599
|
+
console.error(e);
|
|
7600
|
+
}
|
|
7601
|
+
});
|
|
7385
7602
|
}
|
|
7386
7603
|
/**
|
|
7387
7604
|
* @internal
|
|
@@ -7389,14 +7606,71 @@ class Connection {
|
|
|
7389
7606
|
|
|
7390
7607
|
|
|
7391
7608
|
_wsOnAccountNotification(notification) {
|
|
7392
|
-
const
|
|
7609
|
+
const {
|
|
7610
|
+
result,
|
|
7611
|
+
subscription
|
|
7612
|
+
} = superstruct.create(notification, AccountNotificationResult);
|
|
7393
7613
|
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7614
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7615
|
+
}
|
|
7616
|
+
/**
|
|
7617
|
+
* @internal
|
|
7618
|
+
*/
|
|
7619
|
+
|
|
7620
|
+
|
|
7621
|
+
_makeSubscription(subscriptionConfig,
|
|
7622
|
+
/**
|
|
7623
|
+
* When preparing `args` for a call to `_makeSubscription`, be sure
|
|
7624
|
+
* to carefully apply a default `commitment` property, if necessary.
|
|
7625
|
+
*
|
|
7626
|
+
* - If the user supplied a `commitment` use that.
|
|
7627
|
+
* - Otherwise, if the `Connection::commitment` is set, use that.
|
|
7628
|
+
* - Otherwise, set it to the RPC server default: `finalized`.
|
|
7629
|
+
*
|
|
7630
|
+
* This is extremely important to ensure that these two fundamentally
|
|
7631
|
+
* identical subscriptions produce the same identifying hash:
|
|
7632
|
+
*
|
|
7633
|
+
* - A subscription made without specifying a commitment.
|
|
7634
|
+
* - A subscription made where the commitment specified is the same
|
|
7635
|
+
* as the default applied to the subscription above.
|
|
7636
|
+
*
|
|
7637
|
+
* Example; these two subscriptions must produce the same hash:
|
|
7638
|
+
*
|
|
7639
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'`
|
|
7640
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
|
|
7641
|
+
* `'finalized'`.
|
|
7642
|
+
*
|
|
7643
|
+
* See the 'making a subscription with defaulted params omitted' test
|
|
7644
|
+
* in `connection-subscriptions.ts` for more.
|
|
7645
|
+
*/
|
|
7646
|
+
args) {
|
|
7647
|
+
const clientSubscriptionId = this._nextClientSubscriptionId++;
|
|
7648
|
+
const hash = fastStableStringify$1([subscriptionConfig.method, args], true
|
|
7649
|
+
/* isArrayProp */
|
|
7650
|
+
);
|
|
7651
|
+
const existingSubscription = this._subscriptionsByHash[hash];
|
|
7652
|
+
|
|
7653
|
+
if (existingSubscription === undefined) {
|
|
7654
|
+
this._subscriptionsByHash[hash] = { ...subscriptionConfig,
|
|
7655
|
+
args,
|
|
7656
|
+
callbacks: new Set([subscriptionConfig.callback]),
|
|
7657
|
+
state: 'pending'
|
|
7658
|
+
};
|
|
7659
|
+
} else {
|
|
7660
|
+
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
7399
7661
|
}
|
|
7662
|
+
|
|
7663
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
7664
|
+
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7665
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7666
|
+
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
7667
|
+
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
7668
|
+
await this._updateSubscriptions();
|
|
7669
|
+
};
|
|
7670
|
+
|
|
7671
|
+
this._updateSubscriptions();
|
|
7672
|
+
|
|
7673
|
+
return clientSubscriptionId;
|
|
7400
7674
|
}
|
|
7401
7675
|
/**
|
|
7402
7676
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7409,35 +7683,24 @@ class Connection {
|
|
|
7409
7683
|
|
|
7410
7684
|
|
|
7411
7685
|
onAccountChange(publicKey, callback, commitment) {
|
|
7412
|
-
const
|
|
7413
|
-
|
|
7414
|
-
publicKey: publicKey.toBase58(),
|
|
7415
|
-
callback,
|
|
7416
|
-
commitment,
|
|
7417
|
-
subscriptionId: null
|
|
7418
|
-
};
|
|
7419
|
-
|
|
7420
|
-
this._updateSubscriptions();
|
|
7686
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7687
|
+
'base64');
|
|
7421
7688
|
|
|
7422
|
-
return
|
|
7689
|
+
return this._makeSubscription({
|
|
7690
|
+
callback,
|
|
7691
|
+
method: 'accountSubscribe',
|
|
7692
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
7693
|
+
}, args);
|
|
7423
7694
|
}
|
|
7424
7695
|
/**
|
|
7425
7696
|
* Deregister an account notification callback
|
|
7426
7697
|
*
|
|
7427
|
-
* @param id subscription id to deregister
|
|
7698
|
+
* @param id client subscription id to deregister
|
|
7428
7699
|
*/
|
|
7429
7700
|
|
|
7430
7701
|
|
|
7431
|
-
async removeAccountChangeListener(
|
|
7432
|
-
|
|
7433
|
-
const subInfo = this._accountChangeSubscriptions[id];
|
|
7434
|
-
delete this._accountChangeSubscriptions[id];
|
|
7435
|
-
await this._unsubscribe(subInfo, 'accountUnsubscribe');
|
|
7436
|
-
|
|
7437
|
-
this._updateSubscriptions();
|
|
7438
|
-
} else {
|
|
7439
|
-
console.warn(createSubscriptionWarningMessage(id, 'account change'));
|
|
7440
|
-
}
|
|
7702
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
7703
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7441
7704
|
}
|
|
7442
7705
|
/**
|
|
7443
7706
|
* @internal
|
|
@@ -7445,21 +7708,15 @@ class Connection {
|
|
|
7445
7708
|
|
|
7446
7709
|
|
|
7447
7710
|
_wsOnProgramAccountNotification(notification) {
|
|
7448
|
-
const
|
|
7711
|
+
const {
|
|
7712
|
+
result,
|
|
7713
|
+
subscription
|
|
7714
|
+
} = superstruct.create(notification, ProgramAccountNotificationResult);
|
|
7449
7715
|
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
context
|
|
7455
|
-
} = res.result;
|
|
7456
|
-
sub.callback({
|
|
7457
|
-
accountId: value.pubkey,
|
|
7458
|
-
accountInfo: value.account
|
|
7459
|
-
}, context);
|
|
7460
|
-
return;
|
|
7461
|
-
}
|
|
7462
|
-
}
|
|
7716
|
+
this._handleServerNotification(subscription, [{
|
|
7717
|
+
accountId: result.value.pubkey,
|
|
7718
|
+
accountInfo: result.value.account
|
|
7719
|
+
}, result.context]);
|
|
7463
7720
|
}
|
|
7464
7721
|
/**
|
|
7465
7722
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7474,36 +7731,30 @@ class Connection {
|
|
|
7474
7731
|
|
|
7475
7732
|
|
|
7476
7733
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7477
|
-
const
|
|
7478
|
-
|
|
7479
|
-
|
|
7734
|
+
const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7735
|
+
'base64'
|
|
7736
|
+
/* encoding */
|
|
7737
|
+
, filters ? {
|
|
7738
|
+
filters: filters
|
|
7739
|
+
} : undefined
|
|
7740
|
+
/* extra */
|
|
7741
|
+
);
|
|
7742
|
+
|
|
7743
|
+
return this._makeSubscription({
|
|
7480
7744
|
callback,
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
};
|
|
7485
|
-
|
|
7486
|
-
this._updateSubscriptions();
|
|
7487
|
-
|
|
7488
|
-
return id;
|
|
7745
|
+
method: 'programSubscribe',
|
|
7746
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
7747
|
+
}, args);
|
|
7489
7748
|
}
|
|
7490
7749
|
/**
|
|
7491
7750
|
* Deregister an account notification callback
|
|
7492
7751
|
*
|
|
7493
|
-
* @param id subscription id to deregister
|
|
7752
|
+
* @param id client subscription id to deregister
|
|
7494
7753
|
*/
|
|
7495
7754
|
|
|
7496
7755
|
|
|
7497
|
-
async removeProgramAccountChangeListener(
|
|
7498
|
-
|
|
7499
|
-
const subInfo = this._programAccountChangeSubscriptions[id];
|
|
7500
|
-
delete this._programAccountChangeSubscriptions[id];
|
|
7501
|
-
await this._unsubscribe(subInfo, 'programUnsubscribe');
|
|
7502
|
-
|
|
7503
|
-
this._updateSubscriptions();
|
|
7504
|
-
} else {
|
|
7505
|
-
console.warn(createSubscriptionWarningMessage(id, 'program account change'));
|
|
7506
|
-
}
|
|
7756
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
7757
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7507
7758
|
}
|
|
7508
7759
|
/**
|
|
7509
7760
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7511,35 +7762,26 @@ class Connection {
|
|
|
7511
7762
|
|
|
7512
7763
|
|
|
7513
7764
|
onLogs(filter, callback, commitment) {
|
|
7514
|
-
const
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
commitment,
|
|
7519
|
-
subscriptionId: null
|
|
7520
|
-
};
|
|
7521
|
-
|
|
7522
|
-
this._updateSubscriptions();
|
|
7765
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
7766
|
+
mentions: [filter.toString()]
|
|
7767
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7768
|
+
);
|
|
7523
7769
|
|
|
7524
|
-
return
|
|
7770
|
+
return this._makeSubscription({
|
|
7771
|
+
callback,
|
|
7772
|
+
method: 'logsSubscribe',
|
|
7773
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
7774
|
+
}, args);
|
|
7525
7775
|
}
|
|
7526
7776
|
/**
|
|
7527
7777
|
* Deregister a logs callback.
|
|
7528
7778
|
*
|
|
7529
|
-
* @param id subscription id to deregister.
|
|
7779
|
+
* @param id client subscription id to deregister.
|
|
7530
7780
|
*/
|
|
7531
7781
|
|
|
7532
7782
|
|
|
7533
|
-
async removeOnLogsListener(
|
|
7534
|
-
|
|
7535
|
-
const subInfo = this._logsSubscriptions[id];
|
|
7536
|
-
delete this._logsSubscriptions[id];
|
|
7537
|
-
await this._unsubscribe(subInfo, 'logsUnsubscribe');
|
|
7538
|
-
|
|
7539
|
-
this._updateSubscriptions();
|
|
7540
|
-
} else {
|
|
7541
|
-
console.warn(createSubscriptionWarningMessage(id, 'logs'));
|
|
7542
|
-
}
|
|
7783
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
7784
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
7543
7785
|
}
|
|
7544
7786
|
/**
|
|
7545
7787
|
* @internal
|
|
@@ -7547,17 +7789,12 @@ class Connection {
|
|
|
7547
7789
|
|
|
7548
7790
|
|
|
7549
7791
|
_wsOnLogsNotification(notification) {
|
|
7550
|
-
const
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
const sub = this._logsSubscriptions[id];
|
|
7792
|
+
const {
|
|
7793
|
+
result,
|
|
7794
|
+
subscription
|
|
7795
|
+
} = superstruct.create(notification, LogsNotificationResult);
|
|
7555
7796
|
|
|
7556
|
-
|
|
7557
|
-
sub.callback(res.result.value, res.result.context);
|
|
7558
|
-
return;
|
|
7559
|
-
}
|
|
7560
|
-
}
|
|
7797
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7561
7798
|
}
|
|
7562
7799
|
/**
|
|
7563
7800
|
* @internal
|
|
@@ -7565,14 +7802,12 @@ class Connection {
|
|
|
7565
7802
|
|
|
7566
7803
|
|
|
7567
7804
|
_wsOnSlotNotification(notification) {
|
|
7568
|
-
const
|
|
7805
|
+
const {
|
|
7806
|
+
result,
|
|
7807
|
+
subscription
|
|
7808
|
+
} = superstruct.create(notification, SlotNotificationResult);
|
|
7569
7809
|
|
|
7570
|
-
|
|
7571
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7572
|
-
sub.callback(res.result);
|
|
7573
|
-
return;
|
|
7574
|
-
}
|
|
7575
|
-
}
|
|
7810
|
+
this._handleServerNotification(subscription, [result]);
|
|
7576
7811
|
}
|
|
7577
7812
|
/**
|
|
7578
7813
|
* Register a callback to be invoked upon slot changes
|
|
@@ -7583,33 +7818,23 @@ class Connection {
|
|
|
7583
7818
|
|
|
7584
7819
|
|
|
7585
7820
|
onSlotChange(callback) {
|
|
7586
|
-
|
|
7587
|
-
this._slotSubscriptions[id] = {
|
|
7821
|
+
return this._makeSubscription({
|
|
7588
7822
|
callback,
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
return id;
|
|
7823
|
+
method: 'slotSubscribe',
|
|
7824
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
7825
|
+
}, []
|
|
7826
|
+
/* args */
|
|
7827
|
+
);
|
|
7595
7828
|
}
|
|
7596
7829
|
/**
|
|
7597
7830
|
* Deregister a slot notification callback
|
|
7598
7831
|
*
|
|
7599
|
-
* @param id subscription id to deregister
|
|
7832
|
+
* @param id client subscription id to deregister
|
|
7600
7833
|
*/
|
|
7601
7834
|
|
|
7602
7835
|
|
|
7603
|
-
async removeSlotChangeListener(
|
|
7604
|
-
|
|
7605
|
-
const subInfo = this._slotSubscriptions[id];
|
|
7606
|
-
delete this._slotSubscriptions[id];
|
|
7607
|
-
await this._unsubscribe(subInfo, 'slotUnsubscribe');
|
|
7608
|
-
|
|
7609
|
-
this._updateSubscriptions();
|
|
7610
|
-
} else {
|
|
7611
|
-
console.warn(createSubscriptionWarningMessage(id, 'slot change'));
|
|
7612
|
-
}
|
|
7836
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
7837
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
7613
7838
|
}
|
|
7614
7839
|
/**
|
|
7615
7840
|
* @internal
|
|
@@ -7617,14 +7842,12 @@ class Connection {
|
|
|
7617
7842
|
|
|
7618
7843
|
|
|
7619
7844
|
_wsOnSlotUpdatesNotification(notification) {
|
|
7620
|
-
const
|
|
7845
|
+
const {
|
|
7846
|
+
result,
|
|
7847
|
+
subscription
|
|
7848
|
+
} = superstruct.create(notification, SlotUpdateNotificationResult);
|
|
7621
7849
|
|
|
7622
|
-
|
|
7623
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7624
|
-
sub.callback(res.result);
|
|
7625
|
-
return;
|
|
7626
|
-
}
|
|
7627
|
-
}
|
|
7850
|
+
this._handleServerNotification(subscription, [result]);
|
|
7628
7851
|
}
|
|
7629
7852
|
/**
|
|
7630
7853
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -7636,32 +7859,36 @@ class Connection {
|
|
|
7636
7859
|
|
|
7637
7860
|
|
|
7638
7861
|
onSlotUpdate(callback) {
|
|
7639
|
-
|
|
7640
|
-
this._slotUpdateSubscriptions[id] = {
|
|
7862
|
+
return this._makeSubscription({
|
|
7641
7863
|
callback,
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7647
|
-
return id;
|
|
7864
|
+
method: 'slotsUpdatesSubscribe',
|
|
7865
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
7866
|
+
}, []
|
|
7867
|
+
/* args */
|
|
7868
|
+
);
|
|
7648
7869
|
}
|
|
7649
7870
|
/**
|
|
7650
7871
|
* Deregister a slot update notification callback
|
|
7651
7872
|
*
|
|
7652
|
-
* @param id subscription id to deregister
|
|
7873
|
+
* @param id client subscription id to deregister
|
|
7653
7874
|
*/
|
|
7654
7875
|
|
|
7655
7876
|
|
|
7656
|
-
async removeSlotUpdateListener(
|
|
7657
|
-
|
|
7658
|
-
|
|
7659
|
-
|
|
7660
|
-
|
|
7877
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
7878
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
7879
|
+
}
|
|
7880
|
+
/**
|
|
7881
|
+
* @internal
|
|
7882
|
+
*/
|
|
7661
7883
|
|
|
7662
|
-
|
|
7884
|
+
|
|
7885
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
7886
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7887
|
+
|
|
7888
|
+
if (dispose) {
|
|
7889
|
+
await dispose();
|
|
7663
7890
|
} else {
|
|
7664
|
-
console.warn(
|
|
7891
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
7665
7892
|
}
|
|
7666
7893
|
}
|
|
7667
7894
|
|
|
@@ -7708,30 +7935,34 @@ class Connection {
|
|
|
7708
7935
|
|
|
7709
7936
|
|
|
7710
7937
|
_wsOnSignatureNotification(notification) {
|
|
7711
|
-
const
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7938
|
+
const {
|
|
7939
|
+
result,
|
|
7940
|
+
subscription
|
|
7941
|
+
} = superstruct.create(notification, SignatureNotificationResult);
|
|
7942
|
+
|
|
7943
|
+
if (result.value !== 'receivedSignature') {
|
|
7944
|
+
/**
|
|
7945
|
+
* Special case.
|
|
7946
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
7947
|
+
* subscription on the server side. We need to track which of these
|
|
7948
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
7949
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
7950
|
+
* (in which case we must tear down the server subscription) or an
|
|
7951
|
+
* already-processed signature (in which case the client can simply
|
|
7952
|
+
* clear out the subscription locally without telling the server).
|
|
7953
|
+
*
|
|
7954
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7955
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7956
|
+
*/
|
|
7957
|
+
this._subscriptionsAutoDisposedByRpc.add(subscription);
|
|
7958
|
+
}
|
|
7959
|
+
|
|
7960
|
+
this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
|
|
7961
|
+
type: 'received'
|
|
7962
|
+
}, result.context] : [{
|
|
7963
|
+
type: 'status',
|
|
7964
|
+
result: result.value
|
|
7965
|
+
}, result.context]);
|
|
7735
7966
|
}
|
|
7736
7967
|
/**
|
|
7737
7968
|
* Register a callback to be invoked upon signature updates
|
|
@@ -7744,23 +7975,26 @@ class Connection {
|
|
|
7744
7975
|
|
|
7745
7976
|
|
|
7746
7977
|
onSignature(signature, callback, commitment) {
|
|
7747
|
-
const
|
|
7748
|
-
|
|
7749
|
-
|
|
7978
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7979
|
+
);
|
|
7980
|
+
|
|
7981
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
7750
7982
|
callback: (notification, context) => {
|
|
7751
7983
|
if (notification.type === 'status') {
|
|
7752
|
-
callback(notification.result, context);
|
|
7984
|
+
callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
7985
|
+
// so no need to explicitly send an unsubscribe message.
|
|
7986
|
+
|
|
7987
|
+
try {
|
|
7988
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
7989
|
+
} catch {// Already removed.
|
|
7990
|
+
}
|
|
7753
7991
|
}
|
|
7754
7992
|
},
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
subscriptionId: null
|
|
7759
|
-
};
|
|
7760
|
-
|
|
7761
|
-
this._updateSubscriptions();
|
|
7993
|
+
method: 'signatureSubscribe',
|
|
7994
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
7995
|
+
}, args);
|
|
7762
7996
|
|
|
7763
|
-
return
|
|
7997
|
+
return clientSubscriptionId;
|
|
7764
7998
|
}
|
|
7765
7999
|
/**
|
|
7766
8000
|
* Register a callback to be invoked when a transaction is
|
|
@@ -7775,35 +8009,43 @@ class Connection {
|
|
|
7775
8009
|
|
|
7776
8010
|
|
|
7777
8011
|
onSignatureWithOptions(signature, callback, options) {
|
|
7778
|
-
const
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
options
|
|
7783
|
-
|
|
8012
|
+
const {
|
|
8013
|
+
commitment,
|
|
8014
|
+
...extra
|
|
8015
|
+
} = { ...options,
|
|
8016
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
8017
|
+
|
|
7784
8018
|
};
|
|
7785
8019
|
|
|
7786
|
-
this.
|
|
8020
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
8021
|
+
/* encoding */
|
|
8022
|
+
, extra);
|
|
8023
|
+
|
|
8024
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
8025
|
+
callback: (notification, context) => {
|
|
8026
|
+
callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
8027
|
+
// so no need to explicitly send an unsubscribe message.
|
|
8028
|
+
|
|
8029
|
+
try {
|
|
8030
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
8031
|
+
} catch {// Already removed.
|
|
8032
|
+
}
|
|
8033
|
+
},
|
|
8034
|
+
method: 'signatureSubscribe',
|
|
8035
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8036
|
+
}, args);
|
|
7787
8037
|
|
|
7788
|
-
return
|
|
8038
|
+
return clientSubscriptionId;
|
|
7789
8039
|
}
|
|
7790
8040
|
/**
|
|
7791
8041
|
* Deregister a signature notification callback
|
|
7792
8042
|
*
|
|
7793
|
-
* @param id subscription id to deregister
|
|
8043
|
+
* @param id client subscription id to deregister
|
|
7794
8044
|
*/
|
|
7795
8045
|
|
|
7796
8046
|
|
|
7797
|
-
async removeSignatureListener(
|
|
7798
|
-
|
|
7799
|
-
const subInfo = this._signatureSubscriptions[id];
|
|
7800
|
-
delete this._signatureSubscriptions[id];
|
|
7801
|
-
await this._unsubscribe(subInfo, 'signatureUnsubscribe');
|
|
7802
|
-
|
|
7803
|
-
this._updateSubscriptions();
|
|
7804
|
-
} else {
|
|
7805
|
-
console.warn(createSubscriptionWarningMessage(id, 'signature result'));
|
|
7806
|
-
}
|
|
8047
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
8048
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
7807
8049
|
}
|
|
7808
8050
|
/**
|
|
7809
8051
|
* @internal
|
|
@@ -7811,14 +8053,12 @@ class Connection {
|
|
|
7811
8053
|
|
|
7812
8054
|
|
|
7813
8055
|
_wsOnRootNotification(notification) {
|
|
7814
|
-
const
|
|
8056
|
+
const {
|
|
8057
|
+
result,
|
|
8058
|
+
subscription
|
|
8059
|
+
} = superstruct.create(notification, RootNotificationResult);
|
|
7815
8060
|
|
|
7816
|
-
|
|
7817
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7818
|
-
sub.callback(res.result);
|
|
7819
|
-
return;
|
|
7820
|
-
}
|
|
7821
|
-
}
|
|
8061
|
+
this._handleServerNotification(subscription, [result]);
|
|
7822
8062
|
}
|
|
7823
8063
|
/**
|
|
7824
8064
|
* Register a callback to be invoked upon root changes
|
|
@@ -7829,33 +8069,23 @@ class Connection {
|
|
|
7829
8069
|
|
|
7830
8070
|
|
|
7831
8071
|
onRootChange(callback) {
|
|
7832
|
-
|
|
7833
|
-
this._rootSubscriptions[id] = {
|
|
8072
|
+
return this._makeSubscription({
|
|
7834
8073
|
callback,
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
return id;
|
|
8074
|
+
method: 'rootSubscribe',
|
|
8075
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
8076
|
+
}, []
|
|
8077
|
+
/* args */
|
|
8078
|
+
);
|
|
7841
8079
|
}
|
|
7842
8080
|
/**
|
|
7843
8081
|
* Deregister a root notification callback
|
|
7844
8082
|
*
|
|
7845
|
-
* @param id subscription id to deregister
|
|
8083
|
+
* @param id client subscription id to deregister
|
|
7846
8084
|
*/
|
|
7847
8085
|
|
|
7848
8086
|
|
|
7849
|
-
async removeRootChangeListener(
|
|
7850
|
-
|
|
7851
|
-
const subInfo = this._rootSubscriptions[id];
|
|
7852
|
-
delete this._rootSubscriptions[id];
|
|
7853
|
-
await this._unsubscribe(subInfo, 'rootUnsubscribe');
|
|
7854
|
-
|
|
7855
|
-
this._updateSubscriptions();
|
|
7856
|
-
} else {
|
|
7857
|
-
console.warn(createSubscriptionWarningMessage(id, 'root change'));
|
|
7858
|
-
}
|
|
8087
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
8088
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
7859
8089
|
}
|
|
7860
8090
|
|
|
7861
8091
|
}
|
|
@@ -9557,7 +9787,9 @@ exports.MAX_SEED_LENGTH = MAX_SEED_LENGTH;
|
|
|
9557
9787
|
exports.Message = Message;
|
|
9558
9788
|
exports.NONCE_ACCOUNT_LENGTH = NONCE_ACCOUNT_LENGTH;
|
|
9559
9789
|
exports.NonceAccount = NonceAccount;
|
|
9790
|
+
exports.PACKET_DATA_SIZE = PACKET_DATA_SIZE;
|
|
9560
9791
|
exports.PublicKey = PublicKey;
|
|
9792
|
+
exports.SIGNATURE_LENGTH_IN_BYTES = SIGNATURE_LENGTH_IN_BYTES;
|
|
9561
9793
|
exports.SOLANA_SCHEMA = SOLANA_SCHEMA;
|
|
9562
9794
|
exports.STAKE_CONFIG_ID = STAKE_CONFIG_ID;
|
|
9563
9795
|
exports.STAKE_INSTRUCTION_LAYOUTS = STAKE_INSTRUCTION_LAYOUTS;
|