@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.esm.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import nacl from 'tweetnacl';
|
|
2
|
-
import { Buffer } from 'buffer';
|
|
2
|
+
import { Buffer as Buffer$1 } from 'buffer';
|
|
3
3
|
import BN from 'bn.js';
|
|
4
4
|
import bs58 from 'bs58';
|
|
5
5
|
import { serialize, deserialize, deserializeUnchecked } from 'borsh';
|
|
6
6
|
import * as BufferLayout from '@solana/buffer-layout';
|
|
7
|
-
import
|
|
7
|
+
import { blob } from '@solana/buffer-layout';
|
|
8
|
+
import fetch from 'cross-fetch';
|
|
8
9
|
import { coerce, instance, string, tuple, literal, unknown, union, type, optional, any, number, array, nullable, create, boolean, record, assert as assert$7 } from 'superstruct';
|
|
9
10
|
import { Client } from 'rpc-websockets';
|
|
10
11
|
import RpcClient from 'jayson/lib/client/browser';
|
|
@@ -14,12 +15,12 @@ import secp256k1 from 'secp256k1';
|
|
|
14
15
|
import sha3 from 'js-sha3';
|
|
15
16
|
|
|
16
17
|
const toBuffer = arr => {
|
|
17
|
-
if (Buffer.isBuffer(arr)) {
|
|
18
|
+
if (Buffer$1.isBuffer(arr)) {
|
|
18
19
|
return arr;
|
|
19
20
|
} else if (arr instanceof Uint8Array) {
|
|
20
|
-
return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
21
|
+
return Buffer$1.from(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
21
22
|
} else {
|
|
22
|
-
return Buffer.from(arr);
|
|
23
|
+
return Buffer$1.from(arr);
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
26
|
|
|
@@ -1746,7 +1747,7 @@ class Struct {
|
|
|
1746
1747
|
}
|
|
1747
1748
|
|
|
1748
1749
|
encode() {
|
|
1749
|
-
return Buffer.from(serialize(SOLANA_SCHEMA, this));
|
|
1750
|
+
return Buffer$1.from(serialize(SOLANA_SCHEMA, this));
|
|
1750
1751
|
}
|
|
1751
1752
|
|
|
1752
1753
|
static decode(data) {
|
|
@@ -1863,13 +1864,13 @@ class PublicKey extends Struct {
|
|
|
1863
1864
|
|
|
1864
1865
|
|
|
1865
1866
|
toBuffer() {
|
|
1866
|
-
const b = this._bn.toArrayLike(Buffer);
|
|
1867
|
+
const b = this._bn.toArrayLike(Buffer$1);
|
|
1867
1868
|
|
|
1868
1869
|
if (b.length === 32) {
|
|
1869
1870
|
return b;
|
|
1870
1871
|
}
|
|
1871
1872
|
|
|
1872
|
-
const zeroPad = Buffer.alloc(32);
|
|
1873
|
+
const zeroPad = Buffer$1.alloc(32);
|
|
1873
1874
|
b.copy(zeroPad, 32 - b.length);
|
|
1874
1875
|
return zeroPad;
|
|
1875
1876
|
}
|
|
@@ -1891,9 +1892,9 @@ class PublicKey extends Struct {
|
|
|
1891
1892
|
|
|
1892
1893
|
|
|
1893
1894
|
static async createWithSeed(fromPublicKey, seed, programId) {
|
|
1894
|
-
const buffer = Buffer.concat([fromPublicKey.toBuffer(), Buffer.from(seed), programId.toBuffer()]);
|
|
1895
|
+
const buffer = Buffer$1.concat([fromPublicKey.toBuffer(), Buffer$1.from(seed), programId.toBuffer()]);
|
|
1895
1896
|
const hash = sha256(new Uint8Array(buffer)).slice(2);
|
|
1896
|
-
return new PublicKey(Buffer.from(hash, 'hex'));
|
|
1897
|
+
return new PublicKey(Buffer$1.from(hash, 'hex'));
|
|
1897
1898
|
}
|
|
1898
1899
|
/**
|
|
1899
1900
|
* Derive a program address from seeds and a program ID.
|
|
@@ -1903,15 +1904,15 @@ class PublicKey extends Struct {
|
|
|
1903
1904
|
|
|
1904
1905
|
|
|
1905
1906
|
static createProgramAddressSync(seeds, programId) {
|
|
1906
|
-
let buffer = Buffer.alloc(0);
|
|
1907
|
+
let buffer = Buffer$1.alloc(0);
|
|
1907
1908
|
seeds.forEach(function (seed) {
|
|
1908
1909
|
if (seed.length > MAX_SEED_LENGTH) {
|
|
1909
1910
|
throw new TypeError(`Max seed length exceeded`);
|
|
1910
1911
|
}
|
|
1911
1912
|
|
|
1912
|
-
buffer = Buffer.concat([buffer, toBuffer(seed)]);
|
|
1913
|
+
buffer = Buffer$1.concat([buffer, toBuffer(seed)]);
|
|
1913
1914
|
});
|
|
1914
|
-
buffer = Buffer.concat([buffer, programId.toBuffer(), Buffer.from('ProgramDerivedAddress')]);
|
|
1915
|
+
buffer = Buffer$1.concat([buffer, programId.toBuffer(), Buffer$1.from('ProgramDerivedAddress')]);
|
|
1915
1916
|
let hash = sha256(new Uint8Array(buffer)).slice(2);
|
|
1916
1917
|
let publicKeyBytes = new BN(hash, 16).toArray(undefined, 32);
|
|
1917
1918
|
|
|
@@ -1947,7 +1948,7 @@ class PublicKey extends Struct {
|
|
|
1947
1948
|
|
|
1948
1949
|
while (nonce != 0) {
|
|
1949
1950
|
try {
|
|
1950
|
-
const seedsWithNonce = seeds.concat(Buffer.from([nonce]));
|
|
1951
|
+
const seedsWithNonce = seeds.concat(Buffer$1.from([nonce]));
|
|
1951
1952
|
address = this.createProgramAddressSync(seedsWithNonce, programId);
|
|
1952
1953
|
} catch (err) {
|
|
1953
1954
|
if (err instanceof TypeError) {
|
|
@@ -2123,13 +2124,13 @@ const rustString = (property = 'string') => {
|
|
|
2123
2124
|
|
|
2124
2125
|
rslShim.encode = (str, b, offset) => {
|
|
2125
2126
|
const data = {
|
|
2126
|
-
chars: Buffer.from(str, 'utf8')
|
|
2127
|
+
chars: Buffer$1.from(str, 'utf8')
|
|
2127
2128
|
};
|
|
2128
2129
|
return _encode(data, b, offset);
|
|
2129
2130
|
};
|
|
2130
2131
|
|
|
2131
2132
|
rslShim.alloc = str => {
|
|
2132
|
-
return BufferLayout.u32().span + BufferLayout.u32().span + Buffer.from(str, 'utf8').length;
|
|
2133
|
+
return BufferLayout.u32().span + BufferLayout.u32().span + Buffer$1.from(str, 'utf8').length;
|
|
2133
2134
|
};
|
|
2134
2135
|
|
|
2135
2136
|
return rslShim;
|
|
@@ -2259,16 +2260,16 @@ class Message {
|
|
|
2259
2260
|
encodeLength(dataCount, data.length);
|
|
2260
2261
|
return {
|
|
2261
2262
|
programIdIndex,
|
|
2262
|
-
keyIndicesCount: Buffer.from(keyIndicesCount),
|
|
2263
|
+
keyIndicesCount: Buffer$1.from(keyIndicesCount),
|
|
2263
2264
|
keyIndices: accounts,
|
|
2264
|
-
dataLength: Buffer.from(dataCount),
|
|
2265
|
+
dataLength: Buffer$1.from(dataCount),
|
|
2265
2266
|
data
|
|
2266
2267
|
};
|
|
2267
2268
|
});
|
|
2268
2269
|
let instructionCount = [];
|
|
2269
2270
|
encodeLength(instructionCount, instructions.length);
|
|
2270
|
-
let instructionBuffer = Buffer.alloc(PACKET_DATA_SIZE);
|
|
2271
|
-
Buffer.from(instructionCount).copy(instructionBuffer);
|
|
2271
|
+
let instructionBuffer = Buffer$1.alloc(PACKET_DATA_SIZE);
|
|
2272
|
+
Buffer$1.from(instructionCount).copy(instructionBuffer);
|
|
2272
2273
|
let instructionBufferLength = instructionCount.length;
|
|
2273
2274
|
instructions.forEach(instruction => {
|
|
2274
2275
|
const instructionLayout = BufferLayout.struct([BufferLayout.u8('programIdIndex'), BufferLayout.blob(instruction.keyIndicesCount.length, 'keyIndicesCount'), BufferLayout.seq(BufferLayout.u8('keyIndex'), instruction.keyIndices.length, 'keyIndices'), BufferLayout.blob(instruction.dataLength.length, 'dataLength'), BufferLayout.seq(BufferLayout.u8('userdatum'), instruction.data.length, 'data')]);
|
|
@@ -2278,14 +2279,14 @@ class Message {
|
|
|
2278
2279
|
instructionBuffer = instructionBuffer.slice(0, instructionBufferLength);
|
|
2279
2280
|
const signDataLayout = BufferLayout.struct([BufferLayout.blob(1, 'numRequiredSignatures'), BufferLayout.blob(1, 'numReadonlySignedAccounts'), BufferLayout.blob(1, 'numReadonlyUnsignedAccounts'), BufferLayout.blob(keyCount.length, 'keyCount'), BufferLayout.seq(publicKey('key'), numKeys, 'keys'), publicKey('recentBlockhash')]);
|
|
2280
2281
|
const transaction = {
|
|
2281
|
-
numRequiredSignatures: Buffer.from([this.header.numRequiredSignatures]),
|
|
2282
|
-
numReadonlySignedAccounts: Buffer.from([this.header.numReadonlySignedAccounts]),
|
|
2283
|
-
numReadonlyUnsignedAccounts: Buffer.from([this.header.numReadonlyUnsignedAccounts]),
|
|
2284
|
-
keyCount: Buffer.from(keyCount),
|
|
2282
|
+
numRequiredSignatures: Buffer$1.from([this.header.numRequiredSignatures]),
|
|
2283
|
+
numReadonlySignedAccounts: Buffer$1.from([this.header.numReadonlySignedAccounts]),
|
|
2284
|
+
numReadonlyUnsignedAccounts: Buffer$1.from([this.header.numReadonlyUnsignedAccounts]),
|
|
2285
|
+
keyCount: Buffer$1.from(keyCount),
|
|
2285
2286
|
keys: this.accountKeys.map(key => toBuffer(key.toBytes())),
|
|
2286
2287
|
recentBlockhash: bs58.decode(this.recentBlockhash)
|
|
2287
2288
|
};
|
|
2288
|
-
let signData = Buffer.alloc(2048);
|
|
2289
|
+
let signData = Buffer$1.alloc(2048);
|
|
2289
2290
|
const length = signDataLayout.encode(transaction, signData);
|
|
2290
2291
|
instructionBuffer.copy(signData, length);
|
|
2291
2292
|
return signData.slice(0, length + instructionBuffer.length);
|
|
@@ -2307,7 +2308,7 @@ class Message {
|
|
|
2307
2308
|
for (let i = 0; i < accountCount; i++) {
|
|
2308
2309
|
const account = byteArray.slice(0, PUBKEY_LENGTH);
|
|
2309
2310
|
byteArray = byteArray.slice(PUBKEY_LENGTH);
|
|
2310
|
-
accountKeys.push(bs58.encode(Buffer.from(account)));
|
|
2311
|
+
accountKeys.push(bs58.encode(Buffer$1.from(account)));
|
|
2311
2312
|
}
|
|
2312
2313
|
|
|
2313
2314
|
const recentBlockhash = byteArray.slice(0, PUBKEY_LENGTH);
|
|
@@ -2322,7 +2323,7 @@ class Message {
|
|
|
2322
2323
|
byteArray = byteArray.slice(accountCount);
|
|
2323
2324
|
const dataLength = decodeLength(byteArray);
|
|
2324
2325
|
const dataSlice = byteArray.slice(0, dataLength);
|
|
2325
|
-
const data = bs58.encode(Buffer.from(dataSlice));
|
|
2326
|
+
const data = bs58.encode(Buffer$1.from(dataSlice));
|
|
2326
2327
|
byteArray = byteArray.slice(dataLength);
|
|
2327
2328
|
instructions.push({
|
|
2328
2329
|
programIdIndex,
|
|
@@ -2337,7 +2338,7 @@ class Message {
|
|
|
2337
2338
|
numReadonlySignedAccounts,
|
|
2338
2339
|
numReadonlyUnsignedAccounts
|
|
2339
2340
|
},
|
|
2340
|
-
recentBlockhash: bs58.encode(Buffer.from(recentBlockhash)),
|
|
2341
|
+
recentBlockhash: bs58.encode(Buffer$1.from(recentBlockhash)),
|
|
2341
2342
|
accountKeys,
|
|
2342
2343
|
instructions
|
|
2343
2344
|
};
|
|
@@ -2355,7 +2356,7 @@ function assert (condition, message) {
|
|
|
2355
2356
|
/**
|
|
2356
2357
|
* Default (empty) signature
|
|
2357
2358
|
*/
|
|
2358
|
-
const DEFAULT_SIGNATURE = Buffer.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
2359
|
+
const DEFAULT_SIGNATURE = Buffer$1.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
|
|
2359
2360
|
/**
|
|
2360
2361
|
* Account metadata used to define instructions
|
|
2361
2362
|
*/
|
|
@@ -2379,7 +2380,7 @@ class TransactionInstruction {
|
|
|
2379
2380
|
constructor(opts) {
|
|
2380
2381
|
this.keys = void 0;
|
|
2381
2382
|
this.programId = void 0;
|
|
2382
|
-
this.data = Buffer.alloc(0);
|
|
2383
|
+
this.data = Buffer$1.alloc(0);
|
|
2383
2384
|
this.programId = opts.programId;
|
|
2384
2385
|
this.keys = opts.keys;
|
|
2385
2386
|
|
|
@@ -2862,7 +2863,7 @@ class Transaction {
|
|
|
2862
2863
|
throw new Error(`unknown signer: ${pubkey.toString()}`);
|
|
2863
2864
|
}
|
|
2864
2865
|
|
|
2865
|
-
this.signatures[index].signature = Buffer.from(signature);
|
|
2866
|
+
this.signatures[index].signature = Buffer$1.from(signature);
|
|
2866
2867
|
}
|
|
2867
2868
|
/**
|
|
2868
2869
|
* Verify signatures of a complete, signed Transaction
|
|
@@ -2928,15 +2929,15 @@ class Transaction {
|
|
|
2928
2929
|
const signatureCount = [];
|
|
2929
2930
|
encodeLength(signatureCount, signatures.length);
|
|
2930
2931
|
const transactionLength = signatureCount.length + signatures.length * 64 + signData.length;
|
|
2931
|
-
const wireTransaction = Buffer.alloc(transactionLength);
|
|
2932
|
+
const wireTransaction = Buffer$1.alloc(transactionLength);
|
|
2932
2933
|
assert(signatures.length < 256);
|
|
2933
|
-
Buffer.from(signatureCount).copy(wireTransaction, 0);
|
|
2934
|
+
Buffer$1.from(signatureCount).copy(wireTransaction, 0);
|
|
2934
2935
|
signatures.forEach(({
|
|
2935
2936
|
signature
|
|
2936
2937
|
}, index) => {
|
|
2937
2938
|
if (signature !== null) {
|
|
2938
2939
|
assert(signature.length === 64, `signature has invalid length`);
|
|
2939
|
-
Buffer.from(signature).copy(wireTransaction, signatureCount.length + index * 64);
|
|
2940
|
+
Buffer$1.from(signature).copy(wireTransaction, signatureCount.length + index * 64);
|
|
2940
2941
|
}
|
|
2941
2942
|
});
|
|
2942
2943
|
signData.copy(wireTransaction, signatureCount.length + signatures.length * 64);
|
|
@@ -2987,7 +2988,7 @@ class Transaction {
|
|
|
2987
2988
|
for (let i = 0; i < signatureCount; i++) {
|
|
2988
2989
|
const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
|
|
2989
2990
|
byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
|
|
2990
|
-
signatures.push(bs58.encode(Buffer.from(signature)));
|
|
2991
|
+
signatures.push(bs58.encode(Buffer$1.from(signature)));
|
|
2991
2992
|
}
|
|
2992
2993
|
|
|
2993
2994
|
return Transaction.populate(Message.from(byteArray), signatures);
|
|
@@ -3076,13 +3077,113 @@ function sleep(ms) {
|
|
|
3076
3077
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
3077
3078
|
}
|
|
3078
3079
|
|
|
3080
|
+
const encodeDecode = (layout) => {
|
|
3081
|
+
const decode = layout.decode.bind(layout);
|
|
3082
|
+
const encode = layout.encode.bind(layout);
|
|
3083
|
+
return { decode, encode };
|
|
3084
|
+
};
|
|
3085
|
+
|
|
3086
|
+
var node = {};
|
|
3087
|
+
|
|
3088
|
+
Object.defineProperty(node, "__esModule", { value: true });
|
|
3089
|
+
let converter;
|
|
3090
|
+
{
|
|
3091
|
+
try {
|
|
3092
|
+
converter = require('bindings')('bigint_buffer');
|
|
3093
|
+
}
|
|
3094
|
+
catch (e) {
|
|
3095
|
+
console.warn('bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)');
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
/**
|
|
3099
|
+
* Convert a little-endian buffer into a BigInt.
|
|
3100
|
+
* @param buf The little-endian buffer to convert
|
|
3101
|
+
* @returns A BigInt with the little-endian representation of buf.
|
|
3102
|
+
*/
|
|
3103
|
+
function toBigIntLE(buf) {
|
|
3104
|
+
if (converter === undefined) {
|
|
3105
|
+
const reversed = Buffer.from(buf);
|
|
3106
|
+
reversed.reverse();
|
|
3107
|
+
const hex = reversed.toString('hex');
|
|
3108
|
+
if (hex.length === 0) {
|
|
3109
|
+
return BigInt(0);
|
|
3110
|
+
}
|
|
3111
|
+
return BigInt(`0x${hex}`);
|
|
3112
|
+
}
|
|
3113
|
+
return converter.toBigInt(buf, false);
|
|
3114
|
+
}
|
|
3115
|
+
var toBigIntLE_1 = node.toBigIntLE = toBigIntLE;
|
|
3116
|
+
/**
|
|
3117
|
+
* Convert a big-endian buffer into a BigInt
|
|
3118
|
+
* @param buf The big-endian buffer to convert.
|
|
3119
|
+
* @returns A BigInt with the big-endian representation of buf.
|
|
3120
|
+
*/
|
|
3121
|
+
function toBigIntBE(buf) {
|
|
3122
|
+
if (converter === undefined) {
|
|
3123
|
+
const hex = buf.toString('hex');
|
|
3124
|
+
if (hex.length === 0) {
|
|
3125
|
+
return BigInt(0);
|
|
3126
|
+
}
|
|
3127
|
+
return BigInt(`0x${hex}`);
|
|
3128
|
+
}
|
|
3129
|
+
return converter.toBigInt(buf, true);
|
|
3130
|
+
}
|
|
3131
|
+
node.toBigIntBE = toBigIntBE;
|
|
3132
|
+
/**
|
|
3133
|
+
* Convert a BigInt to a little-endian buffer.
|
|
3134
|
+
* @param num The BigInt to convert.
|
|
3135
|
+
* @param width The number of bytes that the resulting buffer should be.
|
|
3136
|
+
* @returns A little-endian buffer representation of num.
|
|
3137
|
+
*/
|
|
3138
|
+
function toBufferLE(num, width) {
|
|
3139
|
+
if (converter === undefined) {
|
|
3140
|
+
const hex = num.toString(16);
|
|
3141
|
+
const buffer = Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
3142
|
+
buffer.reverse();
|
|
3143
|
+
return buffer;
|
|
3144
|
+
}
|
|
3145
|
+
// Allocation is done here, since it is slower using napi in C
|
|
3146
|
+
return converter.fromBigInt(num, Buffer.allocUnsafe(width), false);
|
|
3147
|
+
}
|
|
3148
|
+
var toBufferLE_1 = node.toBufferLE = toBufferLE;
|
|
3149
|
+
/**
|
|
3150
|
+
* Convert a BigInt to a big-endian buffer.
|
|
3151
|
+
* @param num The BigInt to convert.
|
|
3152
|
+
* @param width The number of bytes that the resulting buffer should be.
|
|
3153
|
+
* @returns A big-endian buffer representation of num.
|
|
3154
|
+
*/
|
|
3155
|
+
function toBufferBE(num, width) {
|
|
3156
|
+
if (converter === undefined) {
|
|
3157
|
+
const hex = num.toString(16);
|
|
3158
|
+
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
3159
|
+
}
|
|
3160
|
+
return converter.fromBigInt(num, Buffer.allocUnsafe(width), true);
|
|
3161
|
+
}
|
|
3162
|
+
node.toBufferBE = toBufferBE;
|
|
3163
|
+
|
|
3164
|
+
const bigInt = (length) => (property) => {
|
|
3165
|
+
const layout = blob(length, property);
|
|
3166
|
+
const { encode, decode } = encodeDecode(layout);
|
|
3167
|
+
const bigIntLayout = layout;
|
|
3168
|
+
bigIntLayout.decode = (buffer, offset) => {
|
|
3169
|
+
const src = decode(buffer, offset);
|
|
3170
|
+
return toBigIntLE_1(Buffer.from(src));
|
|
3171
|
+
};
|
|
3172
|
+
bigIntLayout.encode = (bigInt, buffer, offset) => {
|
|
3173
|
+
const src = toBufferLE_1(bigInt, length);
|
|
3174
|
+
return encode(src, buffer, offset);
|
|
3175
|
+
};
|
|
3176
|
+
return bigIntLayout;
|
|
3177
|
+
};
|
|
3178
|
+
const u64 = bigInt(8);
|
|
3179
|
+
|
|
3079
3180
|
/**
|
|
3080
3181
|
* Populate a buffer of instruction data using an InstructionType
|
|
3081
3182
|
* @internal
|
|
3082
3183
|
*/
|
|
3083
3184
|
function encodeData(type, fields) {
|
|
3084
3185
|
const allocLength = type.layout.span >= 0 ? type.layout.span : getAlloc(type, fields);
|
|
3085
|
-
const data = Buffer.alloc(allocLength);
|
|
3186
|
+
const data = Buffer$1.alloc(allocLength);
|
|
3086
3187
|
const layoutFields = Object.assign({
|
|
3087
3188
|
instruction: type.index
|
|
3088
3189
|
}, fields);
|
|
@@ -3465,7 +3566,7 @@ const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
3465
3566
|
},
|
|
3466
3567
|
Transfer: {
|
|
3467
3568
|
index: 2,
|
|
3468
|
-
layout: BufferLayout.struct([BufferLayout.u32('instruction'),
|
|
3569
|
+
layout: BufferLayout.struct([BufferLayout.u32('instruction'), u64('lamports')])
|
|
3469
3570
|
},
|
|
3470
3571
|
CreateWithSeed: {
|
|
3471
3572
|
index: 3,
|
|
@@ -3501,7 +3602,7 @@ const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze({
|
|
|
3501
3602
|
},
|
|
3502
3603
|
TransferWithSeed: {
|
|
3503
3604
|
index: 11,
|
|
3504
|
-
layout: BufferLayout.struct([BufferLayout.u32('instruction'),
|
|
3605
|
+
layout: BufferLayout.struct([BufferLayout.u32('instruction'), u64('lamports'), rustString('seed'), publicKey('programId')])
|
|
3505
3606
|
}
|
|
3506
3607
|
});
|
|
3507
3608
|
/**
|
|
@@ -3554,7 +3655,7 @@ class SystemProgram {
|
|
|
3554
3655
|
if ('basePubkey' in params) {
|
|
3555
3656
|
const type = SYSTEM_INSTRUCTION_LAYOUTS.TransferWithSeed;
|
|
3556
3657
|
data = encodeData(type, {
|
|
3557
|
-
lamports: params.lamports,
|
|
3658
|
+
lamports: BigInt(params.lamports),
|
|
3558
3659
|
seed: params.seed,
|
|
3559
3660
|
programId: toBuffer(params.programId.toBuffer())
|
|
3560
3661
|
});
|
|
@@ -3574,7 +3675,7 @@ class SystemProgram {
|
|
|
3574
3675
|
} else {
|
|
3575
3676
|
const type = SYSTEM_INSTRUCTION_LAYOUTS.Transfer;
|
|
3576
3677
|
data = encodeData(type, {
|
|
3577
|
-
lamports: params.lamports
|
|
3678
|
+
lamports: BigInt(params.lamports)
|
|
3578
3679
|
});
|
|
3579
3680
|
keys = [{
|
|
3580
3681
|
pubkey: params.fromPubkey,
|
|
@@ -3982,7 +4083,7 @@ class Loader {
|
|
|
3982
4083
|
|
|
3983
4084
|
while (array.length > 0) {
|
|
3984
4085
|
const bytes = array.slice(0, chunkSize);
|
|
3985
|
-
const data = Buffer.alloc(chunkSize + 16);
|
|
4086
|
+
const data = Buffer$1.alloc(chunkSize + 16);
|
|
3986
4087
|
dataLayout.encode({
|
|
3987
4088
|
instruction: 0,
|
|
3988
4089
|
// Load instruction
|
|
@@ -4017,7 +4118,7 @@ class Loader {
|
|
|
4017
4118
|
|
|
4018
4119
|
{
|
|
4019
4120
|
const dataLayout = BufferLayout.struct([BufferLayout.u32('instruction')]);
|
|
4020
|
-
const data = Buffer.alloc(dataLayout.span);
|
|
4121
|
+
const data = Buffer$1.alloc(dataLayout.span);
|
|
4021
4122
|
dataLayout.encode({
|
|
4022
4123
|
instruction: 1 // Finalize instruction
|
|
4023
4124
|
|
|
@@ -4209,6 +4310,82 @@ class ComputeBudgetProgram {
|
|
|
4209
4310
|
}
|
|
4210
4311
|
ComputeBudgetProgram.programId = new PublicKey('ComputeBudget111111111111111111111111111111');
|
|
4211
4312
|
|
|
4313
|
+
var objToString = Object.prototype.toString;
|
|
4314
|
+
var objKeys = Object.keys || function(obj) {
|
|
4315
|
+
var keys = [];
|
|
4316
|
+
for (var name in obj) {
|
|
4317
|
+
keys.push(name);
|
|
4318
|
+
}
|
|
4319
|
+
return keys;
|
|
4320
|
+
};
|
|
4321
|
+
|
|
4322
|
+
function stringify(val, isArrayProp) {
|
|
4323
|
+
var i, max, str, keys, key, propVal, toStr;
|
|
4324
|
+
if (val === true) {
|
|
4325
|
+
return "true";
|
|
4326
|
+
}
|
|
4327
|
+
if (val === false) {
|
|
4328
|
+
return "false";
|
|
4329
|
+
}
|
|
4330
|
+
switch (typeof val) {
|
|
4331
|
+
case "object":
|
|
4332
|
+
if (val === null) {
|
|
4333
|
+
return null;
|
|
4334
|
+
} else if (val.toJSON && typeof val.toJSON === "function") {
|
|
4335
|
+
return stringify(val.toJSON(), isArrayProp);
|
|
4336
|
+
} else {
|
|
4337
|
+
toStr = objToString.call(val);
|
|
4338
|
+
if (toStr === "[object Array]") {
|
|
4339
|
+
str = '[';
|
|
4340
|
+
max = val.length - 1;
|
|
4341
|
+
for(i = 0; i < max; i++) {
|
|
4342
|
+
str += stringify(val[i], true) + ',';
|
|
4343
|
+
}
|
|
4344
|
+
if (max > -1) {
|
|
4345
|
+
str += stringify(val[i], true);
|
|
4346
|
+
}
|
|
4347
|
+
return str + ']';
|
|
4348
|
+
} else if (toStr === "[object Object]") {
|
|
4349
|
+
// only object is left
|
|
4350
|
+
keys = objKeys(val).sort();
|
|
4351
|
+
max = keys.length;
|
|
4352
|
+
str = "";
|
|
4353
|
+
i = 0;
|
|
4354
|
+
while (i < max) {
|
|
4355
|
+
key = keys[i];
|
|
4356
|
+
propVal = stringify(val[key], false);
|
|
4357
|
+
if (propVal !== undefined) {
|
|
4358
|
+
if (str) {
|
|
4359
|
+
str += ',';
|
|
4360
|
+
}
|
|
4361
|
+
str += JSON.stringify(key) + ':' + propVal;
|
|
4362
|
+
}
|
|
4363
|
+
i++;
|
|
4364
|
+
}
|
|
4365
|
+
return '{' + str + '}';
|
|
4366
|
+
} else {
|
|
4367
|
+
return JSON.stringify(val);
|
|
4368
|
+
}
|
|
4369
|
+
}
|
|
4370
|
+
case "function":
|
|
4371
|
+
case "undefined":
|
|
4372
|
+
return isArrayProp ? null : undefined;
|
|
4373
|
+
case "string":
|
|
4374
|
+
return JSON.stringify(val);
|
|
4375
|
+
default:
|
|
4376
|
+
return isFinite(val) ? val : null;
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4379
|
+
|
|
4380
|
+
var fastStableStringify = function(val) {
|
|
4381
|
+
var returnVal = stringify(val, false);
|
|
4382
|
+
if (returnVal !== undefined) {
|
|
4383
|
+
return ''+ returnVal;
|
|
4384
|
+
}
|
|
4385
|
+
};
|
|
4386
|
+
|
|
4387
|
+
var fastStableStringify$1 = fastStableStringify;
|
|
4388
|
+
|
|
4212
4389
|
const DESTROY_TIMEOUT_MS = 5000;
|
|
4213
4390
|
class AgentManager {
|
|
4214
4391
|
static _newAgent(useHttps) {
|
|
@@ -4417,13 +4594,19 @@ function makeWebsocketUrl(endpoint) {
|
|
|
4417
4594
|
|
|
4418
4595
|
const PublicKeyFromString = coerce(instance(PublicKey), string(), value => new PublicKey(value));
|
|
4419
4596
|
const RawAccountDataResult = tuple([string(), literal('base64')]);
|
|
4420
|
-
const BufferFromRawAccountData = coerce(instance(Buffer), RawAccountDataResult, value => Buffer.from(value[0], 'base64'));
|
|
4597
|
+
const BufferFromRawAccountData = coerce(instance(Buffer$1), RawAccountDataResult, value => Buffer$1.from(value[0], 'base64'));
|
|
4421
4598
|
/**
|
|
4422
4599
|
* Attempt to use a recent blockhash for up to 30 seconds
|
|
4423
4600
|
* @internal
|
|
4424
4601
|
*/
|
|
4425
4602
|
|
|
4426
4603
|
const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
|
|
4604
|
+
/**
|
|
4605
|
+
* HACK.
|
|
4606
|
+
* Copied from rpc-websockets/dist/lib/client.
|
|
4607
|
+
* Otherwise, `yarn build` fails with:
|
|
4608
|
+
* https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
|
|
4609
|
+
*/
|
|
4427
4610
|
|
|
4428
4611
|
/**
|
|
4429
4612
|
* @internal
|
|
@@ -4594,7 +4777,7 @@ const BlockProductionResponseStruct = jsonRpcResultAndContext(type({
|
|
|
4594
4777
|
*/
|
|
4595
4778
|
|
|
4596
4779
|
function createRpcClient(url, useHttps, httpHeaders, customFetch, fetchMiddleware, disableRetryOnRateLimit) {
|
|
4597
|
-
const fetch = customFetch ? customFetch :
|
|
4780
|
+
const fetch$1 = customFetch ? customFetch : fetch;
|
|
4598
4781
|
let agentManager;
|
|
4599
4782
|
|
|
4600
4783
|
{
|
|
@@ -4612,7 +4795,7 @@ function createRpcClient(url, useHttps, httpHeaders, customFetch, fetchMiddlewar
|
|
|
4612
4795
|
reject(error);
|
|
4613
4796
|
}
|
|
4614
4797
|
});
|
|
4615
|
-
return await fetch(...modifiedFetchArgs);
|
|
4798
|
+
return await fetch$1(...modifiedFetchArgs);
|
|
4616
4799
|
};
|
|
4617
4800
|
}
|
|
4618
4801
|
|
|
@@ -4636,7 +4819,7 @@ function createRpcClient(url, useHttps, httpHeaders, customFetch, fetchMiddlewar
|
|
|
4636
4819
|
if (fetchWithMiddleware) {
|
|
4637
4820
|
res = await fetchWithMiddleware(url, options);
|
|
4638
4821
|
} else {
|
|
4639
|
-
res = await fetch(url, options);
|
|
4822
|
+
res = await fetch$1(url, options);
|
|
4640
4823
|
}
|
|
4641
4824
|
|
|
4642
4825
|
if (res.status !== 429
|
|
@@ -4840,7 +5023,7 @@ const KeyedAccountInfoResult = type({
|
|
|
4840
5023
|
pubkey: PublicKeyFromString,
|
|
4841
5024
|
account: AccountInfoResult
|
|
4842
5025
|
});
|
|
4843
|
-
const ParsedOrRawAccountData = coerce(union([instance(Buffer), ParsedAccountDataResult]), union([RawAccountDataResult, ParsedAccountDataResult]), value => {
|
|
5026
|
+
const ParsedOrRawAccountData = coerce(union([instance(Buffer$1), ParsedAccountDataResult]), union([RawAccountDataResult, ParsedAccountDataResult]), value => {
|
|
4844
5027
|
if (Array.isArray(value)) {
|
|
4845
5028
|
return create(value, BufferFromRawAccountData);
|
|
4846
5029
|
} else {
|
|
@@ -5298,14 +5481,9 @@ const LogsNotificationResult = type({
|
|
|
5298
5481
|
* Filter for log subscriptions.
|
|
5299
5482
|
*/
|
|
5300
5483
|
|
|
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
5484
|
/**
|
|
5305
5485
|
* A connection to a fullnode JSON RPC endpoint
|
|
5306
5486
|
*/
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
5487
|
class Connection {
|
|
5310
5488
|
/** @internal */
|
|
5311
5489
|
|
|
@@ -5329,21 +5507,13 @@ class Connection {
|
|
|
5329
5507
|
|
|
5330
5508
|
/** @internal */
|
|
5331
5509
|
|
|
5332
|
-
/** @internal
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
/** @internal */
|
|
5341
|
-
|
|
5342
|
-
/** @internal */
|
|
5343
|
-
|
|
5344
|
-
/** @internal */
|
|
5345
|
-
|
|
5346
|
-
/** @internal */
|
|
5510
|
+
/** @internal
|
|
5511
|
+
* A number that we increment every time an active connection closes.
|
|
5512
|
+
* Used to determine whether the same socket connection that was open
|
|
5513
|
+
* when an async operation started is the same one that's active when
|
|
5514
|
+
* its continuation fires.
|
|
5515
|
+
*
|
|
5516
|
+
*/
|
|
5347
5517
|
|
|
5348
5518
|
/** @internal */
|
|
5349
5519
|
|
|
@@ -5359,7 +5529,19 @@ class Connection {
|
|
|
5359
5529
|
|
|
5360
5530
|
/** @internal */
|
|
5361
5531
|
|
|
5362
|
-
/**
|
|
5532
|
+
/**
|
|
5533
|
+
* Special case.
|
|
5534
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
5535
|
+
* subscription on the server side. We need to track which of these
|
|
5536
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
5537
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
5538
|
+
* (in which case we must tear down the server subscription) or an
|
|
5539
|
+
* already-processed signature (in which case the client can simply
|
|
5540
|
+
* clear out the subscription locally without telling the server).
|
|
5541
|
+
*
|
|
5542
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
5543
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
5544
|
+
*/
|
|
5363
5545
|
|
|
5364
5546
|
/** @internal */
|
|
5365
5547
|
|
|
@@ -5381,6 +5563,7 @@ class Connection {
|
|
|
5381
5563
|
this._rpcWebSocketConnected = false;
|
|
5382
5564
|
this._rpcWebSocketHeartbeat = null;
|
|
5383
5565
|
this._rpcWebSocketIdleTimeout = null;
|
|
5566
|
+
this._rpcWebSocketGeneration = 0;
|
|
5384
5567
|
this._disableBlockhashCaching = false;
|
|
5385
5568
|
this._pollingBlockhash = false;
|
|
5386
5569
|
this._blockhashInfo = {
|
|
@@ -5389,20 +5572,11 @@ class Connection {
|
|
|
5389
5572
|
transactionSignatures: [],
|
|
5390
5573
|
simulatedSignatures: []
|
|
5391
5574
|
};
|
|
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 = {};
|
|
5575
|
+
this._nextClientSubscriptionId = 0;
|
|
5576
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId = {};
|
|
5577
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
5578
|
+
this._subscriptionsByHash = {};
|
|
5579
|
+
this._subscriptionsAutoDisposedByRpc = new Set();
|
|
5406
5580
|
let url = new URL(endpoint);
|
|
5407
5581
|
const useHttps = url.protocol === 'https:';
|
|
5408
5582
|
let wsEndpoint;
|
|
@@ -7170,6 +7344,8 @@ class Connection {
|
|
|
7170
7344
|
|
|
7171
7345
|
|
|
7172
7346
|
_wsOnClose(code) {
|
|
7347
|
+
this._rpcWebSocketGeneration++;
|
|
7348
|
+
|
|
7173
7349
|
if (this._rpcWebSocketHeartbeat) {
|
|
7174
7350
|
clearInterval(this._rpcWebSocketHeartbeat);
|
|
7175
7351
|
this._rpcWebSocketHeartbeat = null;
|
|
@@ -7183,85 +7359,20 @@ class Connection {
|
|
|
7183
7359
|
} // implicit close, prepare subscriptions for auto-reconnect
|
|
7184
7360
|
|
|
7185
7361
|
|
|
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);
|
|
7362
|
+
this._subscriptionCallbacksByServerSubscriptionId = {};
|
|
7363
|
+
Object.entries(this._subscriptionsByHash).forEach(([hash, subscription]) => {
|
|
7364
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7365
|
+
state: 'pending'
|
|
7366
|
+
};
|
|
7367
|
+
});
|
|
7249
7368
|
}
|
|
7250
7369
|
/**
|
|
7251
7370
|
* @internal
|
|
7252
7371
|
*/
|
|
7253
7372
|
|
|
7254
7373
|
|
|
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) {
|
|
7374
|
+
async _updateSubscriptions() {
|
|
7375
|
+
if (Object.keys(this._subscriptionsByHash).length === 0) {
|
|
7265
7376
|
if (this._rpcWebSocketConnected) {
|
|
7266
7377
|
this._rpcWebSocketConnected = false;
|
|
7267
7378
|
this._rpcWebSocketIdleTimeout = setTimeout(() => {
|
|
@@ -7293,60 +7404,167 @@ class Connection {
|
|
|
7293
7404
|
return;
|
|
7294
7405
|
}
|
|
7295
7406
|
|
|
7296
|
-
|
|
7297
|
-
const sub = this._accountChangeSubscriptions[id];
|
|
7407
|
+
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
|
|
7298
7408
|
|
|
7299
|
-
|
|
7300
|
-
|
|
7409
|
+
const isCurrentConnectionStillActive = () => {
|
|
7410
|
+
return activeWebSocketGeneration === this._rpcWebSocketGeneration;
|
|
7411
|
+
};
|
|
7301
7412
|
|
|
7302
|
-
|
|
7303
|
-
|
|
7413
|
+
await Promise.all( // Don't be tempted to change this to `Object.entries`. We call
|
|
7414
|
+
// `_updateSubscriptions` recursively when processing the state,
|
|
7415
|
+
// so it's important that we look up the *current* version of
|
|
7416
|
+
// each subscription, every time we process a hash.
|
|
7417
|
+
Object.keys(this._subscriptionsByHash).map(async hash => {
|
|
7418
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7304
7419
|
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
for (let id of slotKeys) {
|
|
7311
|
-
const sub = this._slotSubscriptions[id];
|
|
7420
|
+
if (subscription === undefined) {
|
|
7421
|
+
// This entry has since been deleted. Skip.
|
|
7422
|
+
return;
|
|
7423
|
+
}
|
|
7312
7424
|
|
|
7313
|
-
|
|
7314
|
-
|
|
7425
|
+
switch (subscription.state) {
|
|
7426
|
+
case 'pending':
|
|
7427
|
+
case 'unsubscribed':
|
|
7428
|
+
if (subscription.callbacks.size === 0) {
|
|
7429
|
+
/**
|
|
7430
|
+
* You can end up here when:
|
|
7431
|
+
*
|
|
7432
|
+
* - a subscription has recently unsubscribed
|
|
7433
|
+
* without having new callbacks added to it
|
|
7434
|
+
* while the unsubscribe was in flight, or
|
|
7435
|
+
* - when a pending subscription has its
|
|
7436
|
+
* listeners removed before a request was
|
|
7437
|
+
* sent to the server.
|
|
7438
|
+
*
|
|
7439
|
+
* Being that nobody is interested in this
|
|
7440
|
+
* subscription any longer, delete it.
|
|
7441
|
+
*/
|
|
7442
|
+
delete this._subscriptionsByHash[hash];
|
|
7443
|
+
|
|
7444
|
+
if (subscription.state === 'unsubscribed') {
|
|
7445
|
+
delete this._subscriptionCallbacksByServerSubscriptionId[subscription.serverSubscriptionId];
|
|
7446
|
+
}
|
|
7315
7447
|
|
|
7316
|
-
|
|
7317
|
-
|
|
7448
|
+
await this._updateSubscriptions();
|
|
7449
|
+
return;
|
|
7450
|
+
}
|
|
7318
7451
|
|
|
7319
|
-
|
|
7320
|
-
|
|
7452
|
+
await (async () => {
|
|
7453
|
+
const {
|
|
7454
|
+
args,
|
|
7455
|
+
method
|
|
7456
|
+
} = subscription;
|
|
7321
7457
|
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7458
|
+
try {
|
|
7459
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7460
|
+
state: 'subscribing'
|
|
7461
|
+
};
|
|
7462
|
+
const serverSubscriptionId = await this._rpcWebSocket.call(method, args);
|
|
7463
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7464
|
+
serverSubscriptionId,
|
|
7465
|
+
state: 'subscribed'
|
|
7466
|
+
};
|
|
7467
|
+
this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId] = subscription.callbacks;
|
|
7468
|
+
await this._updateSubscriptions();
|
|
7469
|
+
} catch (e) {
|
|
7470
|
+
if (e instanceof Error) {
|
|
7471
|
+
console.error(`${method} error for argument`, args, e.message);
|
|
7472
|
+
}
|
|
7473
|
+
|
|
7474
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7475
|
+
return;
|
|
7476
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7326
7477
|
|
|
7327
|
-
this._subscribe(sub, 'signatureSubscribe', args);
|
|
7328
|
-
}
|
|
7329
7478
|
|
|
7330
|
-
|
|
7331
|
-
|
|
7479
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7480
|
+
state: 'pending'
|
|
7481
|
+
};
|
|
7482
|
+
await this._updateSubscriptions();
|
|
7483
|
+
}
|
|
7484
|
+
})();
|
|
7485
|
+
break;
|
|
7332
7486
|
|
|
7333
|
-
|
|
7334
|
-
|
|
7487
|
+
case 'subscribed':
|
|
7488
|
+
if (subscription.callbacks.size === 0) {
|
|
7489
|
+
// By the time we successfully set up a subscription
|
|
7490
|
+
// with the server, the client stopped caring about it.
|
|
7491
|
+
// Tear it down now.
|
|
7492
|
+
await (async () => {
|
|
7493
|
+
const {
|
|
7494
|
+
serverSubscriptionId,
|
|
7495
|
+
unsubscribeMethod
|
|
7496
|
+
} = subscription;
|
|
7497
|
+
|
|
7498
|
+
if (this._subscriptionsAutoDisposedByRpc.has(serverSubscriptionId)) {
|
|
7499
|
+
/**
|
|
7500
|
+
* Special case.
|
|
7501
|
+
* If we're dealing with a subscription that has been auto-
|
|
7502
|
+
* disposed by the RPC, then we can skip the RPC call to
|
|
7503
|
+
* tear down the subscription here.
|
|
7504
|
+
*
|
|
7505
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7506
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7507
|
+
*/
|
|
7508
|
+
this._subscriptionsAutoDisposedByRpc.delete(serverSubscriptionId);
|
|
7509
|
+
} else {
|
|
7510
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7511
|
+
state: 'unsubscribing'
|
|
7512
|
+
};
|
|
7513
|
+
|
|
7514
|
+
try {
|
|
7515
|
+
await this._rpcWebSocket.call(unsubscribeMethod, [serverSubscriptionId]);
|
|
7516
|
+
} catch (e) {
|
|
7517
|
+
if (e instanceof Error) {
|
|
7518
|
+
console.error(`${unsubscribeMethod} error:`, e.message);
|
|
7519
|
+
}
|
|
7520
|
+
|
|
7521
|
+
if (!isCurrentConnectionStillActive()) {
|
|
7522
|
+
return;
|
|
7523
|
+
} // TODO: Maybe add an 'errored' state or a retry limit?
|
|
7524
|
+
|
|
7525
|
+
|
|
7526
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7527
|
+
state: 'subscribed'
|
|
7528
|
+
};
|
|
7529
|
+
await this._updateSubscriptions();
|
|
7530
|
+
return;
|
|
7531
|
+
}
|
|
7532
|
+
}
|
|
7335
7533
|
|
|
7336
|
-
|
|
7337
|
-
|
|
7338
|
-
|
|
7534
|
+
this._subscriptionsByHash[hash] = { ...subscription,
|
|
7535
|
+
state: 'unsubscribed'
|
|
7536
|
+
};
|
|
7537
|
+
await this._updateSubscriptions();
|
|
7538
|
+
})();
|
|
7539
|
+
}
|
|
7339
7540
|
|
|
7340
|
-
|
|
7341
|
-
filter = {
|
|
7342
|
-
mentions: [sub.filter.toString()]
|
|
7343
|
-
};
|
|
7344
|
-
} else {
|
|
7345
|
-
filter = sub.filter;
|
|
7541
|
+
break;
|
|
7346
7542
|
}
|
|
7543
|
+
}));
|
|
7544
|
+
}
|
|
7545
|
+
/**
|
|
7546
|
+
* @internal
|
|
7547
|
+
*/
|
|
7548
|
+
|
|
7347
7549
|
|
|
7348
|
-
|
|
7550
|
+
_handleServerNotification(serverSubscriptionId, callbackArgs) {
|
|
7551
|
+
const callbacks = this._subscriptionCallbacksByServerSubscriptionId[serverSubscriptionId];
|
|
7552
|
+
|
|
7553
|
+
if (callbacks === undefined) {
|
|
7554
|
+
return;
|
|
7349
7555
|
}
|
|
7556
|
+
|
|
7557
|
+
callbacks.forEach(cb => {
|
|
7558
|
+
try {
|
|
7559
|
+
cb( // I failed to find a way to convince TypeScript that `cb` is of type
|
|
7560
|
+
// `TCallback` which is certainly compatible with `Parameters<TCallback>`.
|
|
7561
|
+
// See https://github.com/microsoft/TypeScript/issues/47615
|
|
7562
|
+
// @ts-ignore
|
|
7563
|
+
...callbackArgs);
|
|
7564
|
+
} catch (e) {
|
|
7565
|
+
console.error(e);
|
|
7566
|
+
}
|
|
7567
|
+
});
|
|
7350
7568
|
}
|
|
7351
7569
|
/**
|
|
7352
7570
|
* @internal
|
|
@@ -7354,14 +7572,71 @@ class Connection {
|
|
|
7354
7572
|
|
|
7355
7573
|
|
|
7356
7574
|
_wsOnAccountNotification(notification) {
|
|
7357
|
-
const
|
|
7575
|
+
const {
|
|
7576
|
+
result,
|
|
7577
|
+
subscription
|
|
7578
|
+
} = create(notification, AccountNotificationResult);
|
|
7358
7579
|
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7580
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7581
|
+
}
|
|
7582
|
+
/**
|
|
7583
|
+
* @internal
|
|
7584
|
+
*/
|
|
7585
|
+
|
|
7586
|
+
|
|
7587
|
+
_makeSubscription(subscriptionConfig,
|
|
7588
|
+
/**
|
|
7589
|
+
* When preparing `args` for a call to `_makeSubscription`, be sure
|
|
7590
|
+
* to carefully apply a default `commitment` property, if necessary.
|
|
7591
|
+
*
|
|
7592
|
+
* - If the user supplied a `commitment` use that.
|
|
7593
|
+
* - Otherwise, if the `Connection::commitment` is set, use that.
|
|
7594
|
+
* - Otherwise, set it to the RPC server default: `finalized`.
|
|
7595
|
+
*
|
|
7596
|
+
* This is extremely important to ensure that these two fundamentally
|
|
7597
|
+
* identical subscriptions produce the same identifying hash:
|
|
7598
|
+
*
|
|
7599
|
+
* - A subscription made without specifying a commitment.
|
|
7600
|
+
* - A subscription made where the commitment specified is the same
|
|
7601
|
+
* as the default applied to the subscription above.
|
|
7602
|
+
*
|
|
7603
|
+
* Example; these two subscriptions must produce the same hash:
|
|
7604
|
+
*
|
|
7605
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'`
|
|
7606
|
+
* - An `accountSubscribe` subscription for `'PUBKEY'` with commitment
|
|
7607
|
+
* `'finalized'`.
|
|
7608
|
+
*
|
|
7609
|
+
* See the 'making a subscription with defaulted params omitted' test
|
|
7610
|
+
* in `connection-subscriptions.ts` for more.
|
|
7611
|
+
*/
|
|
7612
|
+
args) {
|
|
7613
|
+
const clientSubscriptionId = this._nextClientSubscriptionId++;
|
|
7614
|
+
const hash = fastStableStringify$1([subscriptionConfig.method, args], true
|
|
7615
|
+
/* isArrayProp */
|
|
7616
|
+
);
|
|
7617
|
+
const existingSubscription = this._subscriptionsByHash[hash];
|
|
7618
|
+
|
|
7619
|
+
if (existingSubscription === undefined) {
|
|
7620
|
+
this._subscriptionsByHash[hash] = { ...subscriptionConfig,
|
|
7621
|
+
args,
|
|
7622
|
+
callbacks: new Set([subscriptionConfig.callback]),
|
|
7623
|
+
state: 'pending'
|
|
7624
|
+
};
|
|
7625
|
+
} else {
|
|
7626
|
+
existingSubscription.callbacks.add(subscriptionConfig.callback);
|
|
7364
7627
|
}
|
|
7628
|
+
|
|
7629
|
+
this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId] = async () => {
|
|
7630
|
+
delete this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7631
|
+
const subscription = this._subscriptionsByHash[hash];
|
|
7632
|
+
assert(subscription !== undefined, `Could not find a \`Subscription\` when tearing down client subscription #${clientSubscriptionId}`);
|
|
7633
|
+
subscription.callbacks.delete(subscriptionConfig.callback);
|
|
7634
|
+
await this._updateSubscriptions();
|
|
7635
|
+
};
|
|
7636
|
+
|
|
7637
|
+
this._updateSubscriptions();
|
|
7638
|
+
|
|
7639
|
+
return clientSubscriptionId;
|
|
7365
7640
|
}
|
|
7366
7641
|
/**
|
|
7367
7642
|
* Register a callback to be invoked whenever the specified account changes
|
|
@@ -7374,35 +7649,24 @@ class Connection {
|
|
|
7374
7649
|
|
|
7375
7650
|
|
|
7376
7651
|
onAccountChange(publicKey, callback, commitment) {
|
|
7377
|
-
const
|
|
7378
|
-
|
|
7379
|
-
publicKey: publicKey.toBase58(),
|
|
7380
|
-
callback,
|
|
7381
|
-
commitment,
|
|
7382
|
-
subscriptionId: null
|
|
7383
|
-
};
|
|
7384
|
-
|
|
7385
|
-
this._updateSubscriptions();
|
|
7652
|
+
const args = this._buildArgs([publicKey.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7653
|
+
'base64');
|
|
7386
7654
|
|
|
7387
|
-
return
|
|
7655
|
+
return this._makeSubscription({
|
|
7656
|
+
callback,
|
|
7657
|
+
method: 'accountSubscribe',
|
|
7658
|
+
unsubscribeMethod: 'accountUnsubscribe'
|
|
7659
|
+
}, args);
|
|
7388
7660
|
}
|
|
7389
7661
|
/**
|
|
7390
7662
|
* Deregister an account notification callback
|
|
7391
7663
|
*
|
|
7392
|
-
* @param id subscription id to deregister
|
|
7664
|
+
* @param id client subscription id to deregister
|
|
7393
7665
|
*/
|
|
7394
7666
|
|
|
7395
7667
|
|
|
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
|
-
}
|
|
7668
|
+
async removeAccountChangeListener(clientSubscriptionId) {
|
|
7669
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'account change');
|
|
7406
7670
|
}
|
|
7407
7671
|
/**
|
|
7408
7672
|
* @internal
|
|
@@ -7410,21 +7674,15 @@ class Connection {
|
|
|
7410
7674
|
|
|
7411
7675
|
|
|
7412
7676
|
_wsOnProgramAccountNotification(notification) {
|
|
7413
|
-
const
|
|
7677
|
+
const {
|
|
7678
|
+
result,
|
|
7679
|
+
subscription
|
|
7680
|
+
} = create(notification, ProgramAccountNotificationResult);
|
|
7414
7681
|
|
|
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
|
-
}
|
|
7682
|
+
this._handleServerNotification(subscription, [{
|
|
7683
|
+
accountId: result.value.pubkey,
|
|
7684
|
+
accountInfo: result.value.account
|
|
7685
|
+
}, result.context]);
|
|
7428
7686
|
}
|
|
7429
7687
|
/**
|
|
7430
7688
|
* Register a callback to be invoked whenever accounts owned by the
|
|
@@ -7439,36 +7697,30 @@ class Connection {
|
|
|
7439
7697
|
|
|
7440
7698
|
|
|
7441
7699
|
onProgramAccountChange(programId, callback, commitment, filters) {
|
|
7442
|
-
const
|
|
7443
|
-
|
|
7444
|
-
|
|
7700
|
+
const args = this._buildArgs([programId.toBase58()], commitment || this._commitment || 'finalized', // Apply connection/server default.
|
|
7701
|
+
'base64'
|
|
7702
|
+
/* encoding */
|
|
7703
|
+
, filters ? {
|
|
7704
|
+
filters: filters
|
|
7705
|
+
} : undefined
|
|
7706
|
+
/* extra */
|
|
7707
|
+
);
|
|
7708
|
+
|
|
7709
|
+
return this._makeSubscription({
|
|
7445
7710
|
callback,
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
};
|
|
7450
|
-
|
|
7451
|
-
this._updateSubscriptions();
|
|
7452
|
-
|
|
7453
|
-
return id;
|
|
7711
|
+
method: 'programSubscribe',
|
|
7712
|
+
unsubscribeMethod: 'programUnsubscribe'
|
|
7713
|
+
}, args);
|
|
7454
7714
|
}
|
|
7455
7715
|
/**
|
|
7456
7716
|
* Deregister an account notification callback
|
|
7457
7717
|
*
|
|
7458
|
-
* @param id subscription id to deregister
|
|
7718
|
+
* @param id client subscription id to deregister
|
|
7459
7719
|
*/
|
|
7460
7720
|
|
|
7461
7721
|
|
|
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
|
-
}
|
|
7722
|
+
async removeProgramAccountChangeListener(clientSubscriptionId) {
|
|
7723
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'program account change');
|
|
7472
7724
|
}
|
|
7473
7725
|
/**
|
|
7474
7726
|
* Registers a callback to be invoked whenever logs are emitted.
|
|
@@ -7476,35 +7728,26 @@ class Connection {
|
|
|
7476
7728
|
|
|
7477
7729
|
|
|
7478
7730
|
onLogs(filter, callback, commitment) {
|
|
7479
|
-
const
|
|
7480
|
-
|
|
7481
|
-
|
|
7482
|
-
|
|
7483
|
-
commitment,
|
|
7484
|
-
subscriptionId: null
|
|
7485
|
-
};
|
|
7486
|
-
|
|
7487
|
-
this._updateSubscriptions();
|
|
7731
|
+
const args = this._buildArgs([typeof filter === 'object' ? {
|
|
7732
|
+
mentions: [filter.toString()]
|
|
7733
|
+
} : filter], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7734
|
+
);
|
|
7488
7735
|
|
|
7489
|
-
return
|
|
7736
|
+
return this._makeSubscription({
|
|
7737
|
+
callback,
|
|
7738
|
+
method: 'logsSubscribe',
|
|
7739
|
+
unsubscribeMethod: 'logsUnsubscribe'
|
|
7740
|
+
}, args);
|
|
7490
7741
|
}
|
|
7491
7742
|
/**
|
|
7492
7743
|
* Deregister a logs callback.
|
|
7493
7744
|
*
|
|
7494
|
-
* @param id subscription id to deregister.
|
|
7745
|
+
* @param id client subscription id to deregister.
|
|
7495
7746
|
*/
|
|
7496
7747
|
|
|
7497
7748
|
|
|
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
|
-
}
|
|
7749
|
+
async removeOnLogsListener(clientSubscriptionId) {
|
|
7750
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'logs');
|
|
7508
7751
|
}
|
|
7509
7752
|
/**
|
|
7510
7753
|
* @internal
|
|
@@ -7512,17 +7755,12 @@ class Connection {
|
|
|
7512
7755
|
|
|
7513
7756
|
|
|
7514
7757
|
_wsOnLogsNotification(notification) {
|
|
7515
|
-
const
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
const sub = this._logsSubscriptions[id];
|
|
7758
|
+
const {
|
|
7759
|
+
result,
|
|
7760
|
+
subscription
|
|
7761
|
+
} = create(notification, LogsNotificationResult);
|
|
7520
7762
|
|
|
7521
|
-
|
|
7522
|
-
sub.callback(res.result.value, res.result.context);
|
|
7523
|
-
return;
|
|
7524
|
-
}
|
|
7525
|
-
}
|
|
7763
|
+
this._handleServerNotification(subscription, [result.value, result.context]);
|
|
7526
7764
|
}
|
|
7527
7765
|
/**
|
|
7528
7766
|
* @internal
|
|
@@ -7530,14 +7768,12 @@ class Connection {
|
|
|
7530
7768
|
|
|
7531
7769
|
|
|
7532
7770
|
_wsOnSlotNotification(notification) {
|
|
7533
|
-
const
|
|
7771
|
+
const {
|
|
7772
|
+
result,
|
|
7773
|
+
subscription
|
|
7774
|
+
} = create(notification, SlotNotificationResult);
|
|
7534
7775
|
|
|
7535
|
-
|
|
7536
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7537
|
-
sub.callback(res.result);
|
|
7538
|
-
return;
|
|
7539
|
-
}
|
|
7540
|
-
}
|
|
7776
|
+
this._handleServerNotification(subscription, [result]);
|
|
7541
7777
|
}
|
|
7542
7778
|
/**
|
|
7543
7779
|
* Register a callback to be invoked upon slot changes
|
|
@@ -7548,33 +7784,23 @@ class Connection {
|
|
|
7548
7784
|
|
|
7549
7785
|
|
|
7550
7786
|
onSlotChange(callback) {
|
|
7551
|
-
|
|
7552
|
-
this._slotSubscriptions[id] = {
|
|
7787
|
+
return this._makeSubscription({
|
|
7553
7788
|
callback,
|
|
7554
|
-
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
return id;
|
|
7789
|
+
method: 'slotSubscribe',
|
|
7790
|
+
unsubscribeMethod: 'slotUnsubscribe'
|
|
7791
|
+
}, []
|
|
7792
|
+
/* args */
|
|
7793
|
+
);
|
|
7560
7794
|
}
|
|
7561
7795
|
/**
|
|
7562
7796
|
* Deregister a slot notification callback
|
|
7563
7797
|
*
|
|
7564
|
-
* @param id subscription id to deregister
|
|
7798
|
+
* @param id client subscription id to deregister
|
|
7565
7799
|
*/
|
|
7566
7800
|
|
|
7567
7801
|
|
|
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
|
-
}
|
|
7802
|
+
async removeSlotChangeListener(clientSubscriptionId) {
|
|
7803
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot change');
|
|
7578
7804
|
}
|
|
7579
7805
|
/**
|
|
7580
7806
|
* @internal
|
|
@@ -7582,14 +7808,12 @@ class Connection {
|
|
|
7582
7808
|
|
|
7583
7809
|
|
|
7584
7810
|
_wsOnSlotUpdatesNotification(notification) {
|
|
7585
|
-
const
|
|
7811
|
+
const {
|
|
7812
|
+
result,
|
|
7813
|
+
subscription
|
|
7814
|
+
} = create(notification, SlotUpdateNotificationResult);
|
|
7586
7815
|
|
|
7587
|
-
|
|
7588
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7589
|
-
sub.callback(res.result);
|
|
7590
|
-
return;
|
|
7591
|
-
}
|
|
7592
|
-
}
|
|
7816
|
+
this._handleServerNotification(subscription, [result]);
|
|
7593
7817
|
}
|
|
7594
7818
|
/**
|
|
7595
7819
|
* Register a callback to be invoked upon slot updates. {@link SlotUpdate}'s
|
|
@@ -7601,32 +7825,36 @@ class Connection {
|
|
|
7601
7825
|
|
|
7602
7826
|
|
|
7603
7827
|
onSlotUpdate(callback) {
|
|
7604
|
-
|
|
7605
|
-
this._slotUpdateSubscriptions[id] = {
|
|
7828
|
+
return this._makeSubscription({
|
|
7606
7829
|
callback,
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7611
|
-
|
|
7612
|
-
return id;
|
|
7830
|
+
method: 'slotsUpdatesSubscribe',
|
|
7831
|
+
unsubscribeMethod: 'slotsUpdatesUnsubscribe'
|
|
7832
|
+
}, []
|
|
7833
|
+
/* args */
|
|
7834
|
+
);
|
|
7613
7835
|
}
|
|
7614
7836
|
/**
|
|
7615
7837
|
* Deregister a slot update notification callback
|
|
7616
7838
|
*
|
|
7617
|
-
* @param id subscription id to deregister
|
|
7839
|
+
* @param id client subscription id to deregister
|
|
7618
7840
|
*/
|
|
7619
7841
|
|
|
7620
7842
|
|
|
7621
|
-
async removeSlotUpdateListener(
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7843
|
+
async removeSlotUpdateListener(clientSubscriptionId) {
|
|
7844
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'slot update');
|
|
7845
|
+
}
|
|
7846
|
+
/**
|
|
7847
|
+
* @internal
|
|
7848
|
+
*/
|
|
7626
7849
|
|
|
7627
|
-
|
|
7850
|
+
|
|
7851
|
+
async _unsubscribeClientSubscription(clientSubscriptionId, subscriptionName) {
|
|
7852
|
+
const dispose = this._subscriptionDisposeFunctionsByClientSubscriptionId[clientSubscriptionId];
|
|
7853
|
+
|
|
7854
|
+
if (dispose) {
|
|
7855
|
+
await dispose();
|
|
7628
7856
|
} else {
|
|
7629
|
-
console.warn(
|
|
7857
|
+
console.warn('Ignored unsubscribe request because an active subscription with id ' + `\`${clientSubscriptionId}\` for '${subscriptionName}' events ` + 'could not be found.');
|
|
7630
7858
|
}
|
|
7631
7859
|
}
|
|
7632
7860
|
|
|
@@ -7673,30 +7901,34 @@ class Connection {
|
|
|
7673
7901
|
|
|
7674
7902
|
|
|
7675
7903
|
_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
|
-
|
|
7904
|
+
const {
|
|
7905
|
+
result,
|
|
7906
|
+
subscription
|
|
7907
|
+
} = create(notification, SignatureNotificationResult);
|
|
7908
|
+
|
|
7909
|
+
if (result.value !== 'receivedSignature') {
|
|
7910
|
+
/**
|
|
7911
|
+
* Special case.
|
|
7912
|
+
* After a signature is processed, RPCs automatically dispose of the
|
|
7913
|
+
* subscription on the server side. We need to track which of these
|
|
7914
|
+
* subscriptions have been disposed in such a way, so that we know
|
|
7915
|
+
* whether the client is dealing with a not-yet-processed signature
|
|
7916
|
+
* (in which case we must tear down the server subscription) or an
|
|
7917
|
+
* already-processed signature (in which case the client can simply
|
|
7918
|
+
* clear out the subscription locally without telling the server).
|
|
7919
|
+
*
|
|
7920
|
+
* NOTE: There is a proposal to eliminate this special case, here:
|
|
7921
|
+
* https://github.com/solana-labs/solana/issues/18892
|
|
7922
|
+
*/
|
|
7923
|
+
this._subscriptionsAutoDisposedByRpc.add(subscription);
|
|
7924
|
+
}
|
|
7925
|
+
|
|
7926
|
+
this._handleServerNotification(subscription, result.value === 'receivedSignature' ? [{
|
|
7927
|
+
type: 'received'
|
|
7928
|
+
}, result.context] : [{
|
|
7929
|
+
type: 'status',
|
|
7930
|
+
result: result.value
|
|
7931
|
+
}, result.context]);
|
|
7700
7932
|
}
|
|
7701
7933
|
/**
|
|
7702
7934
|
* Register a callback to be invoked upon signature updates
|
|
@@ -7709,23 +7941,26 @@ class Connection {
|
|
|
7709
7941
|
|
|
7710
7942
|
|
|
7711
7943
|
onSignature(signature, callback, commitment) {
|
|
7712
|
-
const
|
|
7713
|
-
|
|
7714
|
-
|
|
7944
|
+
const args = this._buildArgs([signature], commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7945
|
+
);
|
|
7946
|
+
|
|
7947
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
7715
7948
|
callback: (notification, context) => {
|
|
7716
7949
|
if (notification.type === 'status') {
|
|
7717
|
-
callback(notification.result, context);
|
|
7950
|
+
callback(notification.result, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
7951
|
+
// so no need to explicitly send an unsubscribe message.
|
|
7952
|
+
|
|
7953
|
+
try {
|
|
7954
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
7955
|
+
} catch {// Already removed.
|
|
7956
|
+
}
|
|
7718
7957
|
}
|
|
7719
7958
|
},
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
subscriptionId: null
|
|
7724
|
-
};
|
|
7725
|
-
|
|
7726
|
-
this._updateSubscriptions();
|
|
7959
|
+
method: 'signatureSubscribe',
|
|
7960
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
7961
|
+
}, args);
|
|
7727
7962
|
|
|
7728
|
-
return
|
|
7963
|
+
return clientSubscriptionId;
|
|
7729
7964
|
}
|
|
7730
7965
|
/**
|
|
7731
7966
|
* Register a callback to be invoked when a transaction is
|
|
@@ -7740,35 +7975,43 @@ class Connection {
|
|
|
7740
7975
|
|
|
7741
7976
|
|
|
7742
7977
|
onSignatureWithOptions(signature, callback, options) {
|
|
7743
|
-
const
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
options
|
|
7748
|
-
|
|
7978
|
+
const {
|
|
7979
|
+
commitment,
|
|
7980
|
+
...extra
|
|
7981
|
+
} = { ...options,
|
|
7982
|
+
commitment: options && options.commitment || this._commitment || 'finalized' // Apply connection/server default.
|
|
7983
|
+
|
|
7749
7984
|
};
|
|
7750
7985
|
|
|
7751
|
-
this.
|
|
7986
|
+
const args = this._buildArgs([signature], commitment, undefined
|
|
7987
|
+
/* encoding */
|
|
7988
|
+
, extra);
|
|
7989
|
+
|
|
7990
|
+
const clientSubscriptionId = this._makeSubscription({
|
|
7991
|
+
callback: (notification, context) => {
|
|
7992
|
+
callback(notification, context); // Signatures subscriptions are auto-removed by the RPC service
|
|
7993
|
+
// so no need to explicitly send an unsubscribe message.
|
|
7994
|
+
|
|
7995
|
+
try {
|
|
7996
|
+
this.removeSignatureListener(clientSubscriptionId); // eslint-disable-next-line no-empty
|
|
7997
|
+
} catch {// Already removed.
|
|
7998
|
+
}
|
|
7999
|
+
},
|
|
8000
|
+
method: 'signatureSubscribe',
|
|
8001
|
+
unsubscribeMethod: 'signatureUnsubscribe'
|
|
8002
|
+
}, args);
|
|
7752
8003
|
|
|
7753
|
-
return
|
|
8004
|
+
return clientSubscriptionId;
|
|
7754
8005
|
}
|
|
7755
8006
|
/**
|
|
7756
8007
|
* Deregister a signature notification callback
|
|
7757
8008
|
*
|
|
7758
|
-
* @param id subscription id to deregister
|
|
8009
|
+
* @param id client subscription id to deregister
|
|
7759
8010
|
*/
|
|
7760
8011
|
|
|
7761
8012
|
|
|
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
|
-
}
|
|
8013
|
+
async removeSignatureListener(clientSubscriptionId) {
|
|
8014
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'signature result');
|
|
7772
8015
|
}
|
|
7773
8016
|
/**
|
|
7774
8017
|
* @internal
|
|
@@ -7776,14 +8019,12 @@ class Connection {
|
|
|
7776
8019
|
|
|
7777
8020
|
|
|
7778
8021
|
_wsOnRootNotification(notification) {
|
|
7779
|
-
const
|
|
8022
|
+
const {
|
|
8023
|
+
result,
|
|
8024
|
+
subscription
|
|
8025
|
+
} = create(notification, RootNotificationResult);
|
|
7780
8026
|
|
|
7781
|
-
|
|
7782
|
-
if (sub.subscriptionId === res.subscription) {
|
|
7783
|
-
sub.callback(res.result);
|
|
7784
|
-
return;
|
|
7785
|
-
}
|
|
7786
|
-
}
|
|
8027
|
+
this._handleServerNotification(subscription, [result]);
|
|
7787
8028
|
}
|
|
7788
8029
|
/**
|
|
7789
8030
|
* Register a callback to be invoked upon root changes
|
|
@@ -7794,33 +8035,23 @@ class Connection {
|
|
|
7794
8035
|
|
|
7795
8036
|
|
|
7796
8037
|
onRootChange(callback) {
|
|
7797
|
-
|
|
7798
|
-
this._rootSubscriptions[id] = {
|
|
8038
|
+
return this._makeSubscription({
|
|
7799
8039
|
callback,
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
return id;
|
|
8040
|
+
method: 'rootSubscribe',
|
|
8041
|
+
unsubscribeMethod: 'rootUnsubscribe'
|
|
8042
|
+
}, []
|
|
8043
|
+
/* args */
|
|
8044
|
+
);
|
|
7806
8045
|
}
|
|
7807
8046
|
/**
|
|
7808
8047
|
* Deregister a root notification callback
|
|
7809
8048
|
*
|
|
7810
|
-
* @param id subscription id to deregister
|
|
8049
|
+
* @param id client subscription id to deregister
|
|
7811
8050
|
*/
|
|
7812
8051
|
|
|
7813
8052
|
|
|
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
|
-
}
|
|
8053
|
+
async removeRootChangeListener(clientSubscriptionId) {
|
|
8054
|
+
await this._unsubscribeClientSubscription(clientSubscriptionId, 'root change');
|
|
7824
8055
|
}
|
|
7825
8056
|
|
|
7826
8057
|
}
|
|
@@ -7950,7 +8181,7 @@ class Ed25519Program {
|
|
|
7950
8181
|
const signatureOffset = publicKeyOffset + publicKey.length;
|
|
7951
8182
|
const messageDataOffset = signatureOffset + signature.length;
|
|
7952
8183
|
const numSignatures = 1;
|
|
7953
|
-
const instructionData = Buffer.alloc(messageDataOffset + message.length);
|
|
8184
|
+
const instructionData = Buffer$1.alloc(messageDataOffset + message.length);
|
|
7954
8185
|
const index = instructionIndex == null ? 0xffff // An index of `u16::MAX` makes it default to the current instruction.
|
|
7955
8186
|
: instructionIndex;
|
|
7956
8187
|
ED25519_INSTRUCTION_LAYOUT.encode({
|
|
@@ -8821,7 +9052,7 @@ class Secp256k1Program {
|
|
|
8821
9052
|
assert(publicKey.length === PUBLIC_KEY_BYTES, `Public key must be ${PUBLIC_KEY_BYTES} bytes but received ${publicKey.length} bytes`);
|
|
8822
9053
|
|
|
8823
9054
|
try {
|
|
8824
|
-
return Buffer.from(sha3.keccak_256.update(toBuffer(publicKey)).digest()).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
9055
|
+
return Buffer$1.from(sha3.keccak_256.update(toBuffer(publicKey)).digest()).slice(-ETHEREUM_ADDRESS_BYTES);
|
|
8825
9056
|
} catch (error) {
|
|
8826
9057
|
throw new Error(`Error constructing Ethereum address: ${error}`);
|
|
8827
9058
|
}
|
|
@@ -8866,9 +9097,9 @@ class Secp256k1Program {
|
|
|
8866
9097
|
|
|
8867
9098
|
if (typeof rawAddress === 'string') {
|
|
8868
9099
|
if (rawAddress.startsWith('0x')) {
|
|
8869
|
-
ethAddress = Buffer.from(rawAddress.substr(2), 'hex');
|
|
9100
|
+
ethAddress = Buffer$1.from(rawAddress.substr(2), 'hex');
|
|
8870
9101
|
} else {
|
|
8871
|
-
ethAddress = Buffer.from(rawAddress, 'hex');
|
|
9102
|
+
ethAddress = Buffer$1.from(rawAddress, 'hex');
|
|
8872
9103
|
}
|
|
8873
9104
|
} else {
|
|
8874
9105
|
ethAddress = rawAddress;
|
|
@@ -8880,7 +9111,7 @@ class Secp256k1Program {
|
|
|
8880
9111
|
const signatureOffset = dataStart + ethAddress.length;
|
|
8881
9112
|
const messageDataOffset = signatureOffset + signature.length + 1;
|
|
8882
9113
|
const numSignatures = 1;
|
|
8883
|
-
const instructionData = Buffer.alloc(SECP256K1_INSTRUCTION_LAYOUT.span + message.length);
|
|
9114
|
+
const instructionData = Buffer$1.alloc(SECP256K1_INSTRUCTION_LAYOUT.span + message.length);
|
|
8884
9115
|
SECP256K1_INSTRUCTION_LAYOUT.encode({
|
|
8885
9116
|
numSignatures,
|
|
8886
9117
|
signatureOffset,
|
|
@@ -8919,7 +9150,7 @@ class Secp256k1Program {
|
|
|
8919
9150
|
const privateKey = toBuffer(pkey);
|
|
8920
9151
|
const publicKey = publicKeyCreate(privateKey, false).slice(1); // throw away leading byte
|
|
8921
9152
|
|
|
8922
|
-
const messageHash = Buffer.from(sha3.keccak_256.update(toBuffer(message)).digest());
|
|
9153
|
+
const messageHash = Buffer$1.from(sha3.keccak_256.update(toBuffer(message)).digest());
|
|
8923
9154
|
const {
|
|
8924
9155
|
signature,
|
|
8925
9156
|
recid: recoveryId
|
|
@@ -9004,7 +9235,7 @@ class ValidatorInfo {
|
|
|
9004
9235
|
|
|
9005
9236
|
if (configKeys[0].publicKey.equals(VALIDATOR_INFO_KEY)) {
|
|
9006
9237
|
if (configKeys[1].isSigner) {
|
|
9007
|
-
const rawInfo = rustString().decode(Buffer.from(byteArray));
|
|
9238
|
+
const rawInfo = rustString().decode(Buffer$1.from(byteArray));
|
|
9008
9239
|
const info = JSON.parse(rawInfo);
|
|
9009
9240
|
assert$7(info, InfoString);
|
|
9010
9241
|
return new ValidatorInfo(configKeys[1].publicKey, info);
|
|
@@ -9500,5 +9731,5 @@ function clusterApiUrl(cluster, tls) {
|
|
|
9500
9731
|
|
|
9501
9732
|
const LAMPORTS_PER_SOL = 1000000000;
|
|
9502
9733
|
|
|
9503
|
-
export { Account, Authorized, BLOCKHASH_CACHE_TIMEOUT_MS, BPF_LOADER_DEPRECATED_PROGRAM_ID, BPF_LOADER_PROGRAM_ID, BpfLoader, COMPUTE_BUDGET_INSTRUCTION_LAYOUTS, ComputeBudgetInstruction, ComputeBudgetProgram, Connection, Ed25519Program, Enum, EpochSchedule, FeeCalculatorLayout, Keypair, LAMPORTS_PER_SOL, Loader, Lockup, MAX_SEED_LENGTH, Message, NONCE_ACCOUNT_LENGTH, NonceAccount, PublicKey, SOLANA_SCHEMA, STAKE_CONFIG_ID, STAKE_INSTRUCTION_LAYOUTS, SYSTEM_INSTRUCTION_LAYOUTS, SYSVAR_CLOCK_PUBKEY, SYSVAR_EPOCH_SCHEDULE_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_REWARDS_PUBKEY, SYSVAR_SLOT_HASHES_PUBKEY, SYSVAR_SLOT_HISTORY_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, Secp256k1Program, SendTransactionError, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionInstruction, VALIDATOR_INFO_KEY, VOTE_PROGRAM_ID, ValidatorInfo, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
|
|
9734
|
+
export { Account, Authorized, BLOCKHASH_CACHE_TIMEOUT_MS, BPF_LOADER_DEPRECATED_PROGRAM_ID, BPF_LOADER_PROGRAM_ID, BpfLoader, COMPUTE_BUDGET_INSTRUCTION_LAYOUTS, ComputeBudgetInstruction, ComputeBudgetProgram, Connection, Ed25519Program, Enum, EpochSchedule, FeeCalculatorLayout, Keypair, LAMPORTS_PER_SOL, Loader, Lockup, MAX_SEED_LENGTH, Message, NONCE_ACCOUNT_LENGTH, NonceAccount, PACKET_DATA_SIZE, PublicKey, SIGNATURE_LENGTH_IN_BYTES, SOLANA_SCHEMA, STAKE_CONFIG_ID, STAKE_INSTRUCTION_LAYOUTS, SYSTEM_INSTRUCTION_LAYOUTS, SYSVAR_CLOCK_PUBKEY, SYSVAR_EPOCH_SCHEDULE_PUBKEY, SYSVAR_INSTRUCTIONS_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY, SYSVAR_REWARDS_PUBKEY, SYSVAR_SLOT_HASHES_PUBKEY, SYSVAR_SLOT_HISTORY_PUBKEY, SYSVAR_STAKE_HISTORY_PUBKEY, Secp256k1Program, SendTransactionError, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionInstruction, VALIDATOR_INFO_KEY, VOTE_PROGRAM_ID, ValidatorInfo, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
|
|
9504
9735
|
//# sourceMappingURL=index.esm.js.map
|