@solana/web3.js 1.53.0 → 1.54.0

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.
@@ -1769,6 +1769,11 @@ const SOLANA_SCHEMA = new Map();
1769
1769
  */
1770
1770
 
1771
1771
  const MAX_SEED_LENGTH = 32;
1772
+ /**
1773
+ * Size of public key in bytes
1774
+ */
1775
+
1776
+ const PUBLIC_KEY_LENGTH = 32;
1772
1777
  /**
1773
1778
  * Value to be converted into public key
1774
1779
  */
@@ -1799,7 +1804,7 @@ class PublicKey extends Struct {
1799
1804
  // assume base 58 encoding by default
1800
1805
  const decoded = bs58.decode(value);
1801
1806
 
1802
- if (decoded.length != 32) {
1807
+ if (decoded.length != PUBLIC_KEY_LENGTH) {
1803
1808
  throw new Error(`Invalid public key input`);
1804
1809
  }
1805
1810
 
@@ -1852,7 +1857,7 @@ class PublicKey extends Struct {
1852
1857
  toBuffer() {
1853
1858
  const b = this._bn.toArrayLike(Buffer);
1854
1859
 
1855
- if (b.length === 32) {
1860
+ if (b.length === PUBLIC_KEY_LENGTH) {
1856
1861
  return b;
1857
1862
  }
1858
1863
 
@@ -2080,6 +2085,7 @@ const BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey('BPFLoader111111111111111
2080
2085
  * 8 bytes is the size of the fragment header
2081
2086
  */
2082
2087
  const PACKET_DATA_SIZE = 1280 - 40 - 8;
2088
+ const VERSION_PREFIX_MASK = 0x7f;
2083
2089
  const SIGNATURE_LENGTH_IN_BYTES = 64;
2084
2090
 
2085
2091
  class TransactionExpiredBlockheightExceededError extends Error {
@@ -2112,6 +2118,13 @@ Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
2112
2118
  const publicKey = (property = 'publicKey') => {
2113
2119
  return BufferLayout.blob(32, property);
2114
2120
  };
2121
+ /**
2122
+ * Layout for a signature
2123
+ */
2124
+
2125
+ const signature = (property = 'signature') => {
2126
+ return BufferLayout.blob(64, property);
2127
+ };
2115
2128
 
2116
2129
  /**
2117
2130
  * Layout for a Rust String type
@@ -2223,11 +2236,9 @@ function encodeLength(bytes, len) {
2223
2236
  }
2224
2237
  }
2225
2238
 
2226
- const PUBKEY_LENGTH = 32;
2227
2239
  /**
2228
2240
  * List of instructions to be processed atomically
2229
2241
  */
2230
-
2231
2242
  class Message {
2232
2243
  constructor(args) {
2233
2244
  this.header = void 0;
@@ -2242,6 +2253,26 @@ class Message {
2242
2253
  this.instructions.forEach(ix => this.indexToProgramIds.set(ix.programIdIndex, this.accountKeys[ix.programIdIndex]));
2243
2254
  }
2244
2255
 
2256
+ get version() {
2257
+ return 'legacy';
2258
+ }
2259
+
2260
+ get staticAccountKeys() {
2261
+ return this.accountKeys;
2262
+ }
2263
+
2264
+ get compiledInstructions() {
2265
+ return this.instructions.map(ix => ({
2266
+ programIdIndex: ix.programIdIndex,
2267
+ accountKeyIndexes: ix.accounts,
2268
+ data: bs58.decode(ix.data)
2269
+ }));
2270
+ }
2271
+
2272
+ get addressTableLookups() {
2273
+ return [];
2274
+ }
2275
+
2245
2276
  isAccountSigner(index) {
2246
2277
  return index < this.header.numRequiredSignatures;
2247
2278
  }
@@ -2318,19 +2349,24 @@ class Message {
2318
2349
  // Slice up wire data
2319
2350
  let byteArray = [...buffer];
2320
2351
  const numRequiredSignatures = byteArray.shift();
2352
+
2353
+ if (numRequiredSignatures !== (numRequiredSignatures & VERSION_PREFIX_MASK)) {
2354
+ throw new Error('Versioned messages must be deserialized with VersionedMessage.deserialize()');
2355
+ }
2356
+
2321
2357
  const numReadonlySignedAccounts = byteArray.shift();
2322
2358
  const numReadonlyUnsignedAccounts = byteArray.shift();
2323
2359
  const accountCount = decodeLength(byteArray);
2324
2360
  let accountKeys = [];
2325
2361
 
2326
2362
  for (let i = 0; i < accountCount; i++) {
2327
- const account = byteArray.slice(0, PUBKEY_LENGTH);
2328
- byteArray = byteArray.slice(PUBKEY_LENGTH);
2363
+ const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
2364
+ byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
2329
2365
  accountKeys.push(bs58.encode(Buffer.from(account)));
2330
2366
  }
2331
2367
 
2332
- const recentBlockhash = byteArray.slice(0, PUBKEY_LENGTH);
2333
- byteArray = byteArray.slice(PUBKEY_LENGTH);
2368
+ const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
2369
+ byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
2334
2370
  const instructionCount = decodeLength(byteArray);
2335
2371
  let instructions = [];
2336
2372
 
@@ -2371,6 +2407,182 @@ function assert (condition, message) {
2371
2407
  }
2372
2408
  }
2373
2409
 
2410
+ /**
2411
+ * Message constructor arguments
2412
+ */
2413
+
2414
+ class MessageV0 {
2415
+ constructor(args) {
2416
+ this.header = void 0;
2417
+ this.staticAccountKeys = void 0;
2418
+ this.recentBlockhash = void 0;
2419
+ this.compiledInstructions = void 0;
2420
+ this.addressTableLookups = void 0;
2421
+ this.header = args.header;
2422
+ this.staticAccountKeys = args.staticAccountKeys;
2423
+ this.recentBlockhash = args.recentBlockhash;
2424
+ this.compiledInstructions = args.compiledInstructions;
2425
+ this.addressTableLookups = args.addressTableLookups;
2426
+ }
2427
+
2428
+ get version() {
2429
+ return 0;
2430
+ }
2431
+
2432
+ serialize() {
2433
+ const encodedStaticAccountKeysLength = Array();
2434
+ encodeLength(encodedStaticAccountKeysLength, this.staticAccountKeys.length);
2435
+ const serializedInstructions = this.serializeInstructions();
2436
+ const encodedInstructionsLength = Array();
2437
+ encodeLength(encodedInstructionsLength, this.compiledInstructions.length);
2438
+ const serializedAddressTableLookups = this.serializeAddressTableLookups();
2439
+ const encodedAddressTableLookupsLength = Array();
2440
+ encodeLength(encodedAddressTableLookupsLength, this.addressTableLookups.length);
2441
+ const messageLayout = BufferLayout.struct([BufferLayout.u8('prefix'), BufferLayout.struct([BufferLayout.u8('numRequiredSignatures'), BufferLayout.u8('numReadonlySignedAccounts'), BufferLayout.u8('numReadonlyUnsignedAccounts')], 'header'), BufferLayout.blob(encodedStaticAccountKeysLength.length, 'staticAccountKeysLength'), BufferLayout.seq(publicKey(), this.staticAccountKeys.length, 'staticAccountKeys'), publicKey('recentBlockhash'), BufferLayout.blob(encodedInstructionsLength.length, 'instructionsLength'), BufferLayout.blob(serializedInstructions.length, 'serializedInstructions'), BufferLayout.blob(encodedAddressTableLookupsLength.length, 'addressTableLookupsLength'), BufferLayout.blob(serializedAddressTableLookups.length, 'serializedAddressTableLookups')]);
2442
+ const serializedMessage = new Uint8Array(PACKET_DATA_SIZE);
2443
+ const MESSAGE_VERSION_0_PREFIX = 1 << 7;
2444
+ const serializedMessageLength = messageLayout.encode({
2445
+ prefix: MESSAGE_VERSION_0_PREFIX,
2446
+ header: this.header,
2447
+ staticAccountKeysLength: new Uint8Array(encodedStaticAccountKeysLength),
2448
+ staticAccountKeys: this.staticAccountKeys.map(key => key.toBytes()),
2449
+ recentBlockhash: bs58.decode(this.recentBlockhash),
2450
+ instructionsLength: new Uint8Array(encodedInstructionsLength),
2451
+ serializedInstructions,
2452
+ addressTableLookupsLength: new Uint8Array(encodedAddressTableLookupsLength),
2453
+ serializedAddressTableLookups
2454
+ }, serializedMessage);
2455
+ return serializedMessage.slice(0, serializedMessageLength);
2456
+ }
2457
+
2458
+ serializeInstructions() {
2459
+ let serializedLength = 0;
2460
+ const serializedInstructions = new Uint8Array(PACKET_DATA_SIZE);
2461
+
2462
+ for (const instruction of this.compiledInstructions) {
2463
+ const encodedAccountKeyIndexesLength = Array();
2464
+ encodeLength(encodedAccountKeyIndexesLength, instruction.accountKeyIndexes.length);
2465
+ const encodedDataLength = Array();
2466
+ encodeLength(encodedDataLength, instruction.data.length);
2467
+ const instructionLayout = BufferLayout.struct([BufferLayout.u8('programIdIndex'), BufferLayout.blob(encodedAccountKeyIndexesLength.length, 'encodedAccountKeyIndexesLength'), BufferLayout.seq(BufferLayout.u8(), instruction.accountKeyIndexes.length, 'accountKeyIndexes'), BufferLayout.blob(encodedDataLength.length, 'encodedDataLength'), BufferLayout.blob(instruction.data.length, 'data')]);
2468
+ serializedLength += instructionLayout.encode({
2469
+ programIdIndex: instruction.programIdIndex,
2470
+ encodedAccountKeyIndexesLength: new Uint8Array(encodedAccountKeyIndexesLength),
2471
+ accountKeyIndexes: instruction.accountKeyIndexes,
2472
+ encodedDataLength: new Uint8Array(encodedDataLength),
2473
+ data: instruction.data
2474
+ }, serializedInstructions, serializedLength);
2475
+ }
2476
+
2477
+ return serializedInstructions.slice(0, serializedLength);
2478
+ }
2479
+
2480
+ serializeAddressTableLookups() {
2481
+ let serializedLength = 0;
2482
+ const serializedAddressTableLookups = new Uint8Array(PACKET_DATA_SIZE);
2483
+
2484
+ for (const lookup of this.addressTableLookups) {
2485
+ const encodedWritableIndexesLength = Array();
2486
+ encodeLength(encodedWritableIndexesLength, lookup.writableIndexes.length);
2487
+ const encodedReadonlyIndexesLength = Array();
2488
+ encodeLength(encodedReadonlyIndexesLength, lookup.readonlyIndexes.length);
2489
+ const addressTableLookupLayout = BufferLayout.struct([publicKey('accountKey'), BufferLayout.blob(encodedWritableIndexesLength.length, 'encodedWritableIndexesLength'), BufferLayout.seq(BufferLayout.u8(), lookup.writableIndexes.length, 'writableIndexes'), BufferLayout.blob(encodedReadonlyIndexesLength.length, 'encodedReadonlyIndexesLength'), BufferLayout.seq(BufferLayout.u8(), lookup.readonlyIndexes.length, 'readonlyIndexes')]);
2490
+ serializedLength += addressTableLookupLayout.encode({
2491
+ accountKey: lookup.accountKey.toBytes(),
2492
+ encodedWritableIndexesLength: new Uint8Array(encodedWritableIndexesLength),
2493
+ writableIndexes: lookup.writableIndexes,
2494
+ encodedReadonlyIndexesLength: new Uint8Array(encodedReadonlyIndexesLength),
2495
+ readonlyIndexes: lookup.readonlyIndexes
2496
+ }, serializedAddressTableLookups, serializedLength);
2497
+ }
2498
+
2499
+ return serializedAddressTableLookups.slice(0, serializedLength);
2500
+ }
2501
+
2502
+ static deserialize(serializedMessage) {
2503
+ let byteArray = [...serializedMessage];
2504
+ const prefix = byteArray.shift();
2505
+ const maskedPrefix = prefix & VERSION_PREFIX_MASK;
2506
+ assert(prefix !== maskedPrefix, `Expected versioned message but received legacy message`);
2507
+ const version = maskedPrefix;
2508
+ assert(version === 0, `Expected versioned message with version 0 but found version ${version}`);
2509
+ const header = {
2510
+ numRequiredSignatures: byteArray.shift(),
2511
+ numReadonlySignedAccounts: byteArray.shift(),
2512
+ numReadonlyUnsignedAccounts: byteArray.shift()
2513
+ };
2514
+ const staticAccountKeys = [];
2515
+ const staticAccountKeysLength = decodeLength(byteArray);
2516
+
2517
+ for (let i = 0; i < staticAccountKeysLength; i++) {
2518
+ staticAccountKeys.push(new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH)));
2519
+ }
2520
+
2521
+ const recentBlockhash = bs58.encode(byteArray.splice(0, PUBLIC_KEY_LENGTH));
2522
+ const instructionCount = decodeLength(byteArray);
2523
+ const compiledInstructions = [];
2524
+
2525
+ for (let i = 0; i < instructionCount; i++) {
2526
+ const programIdIndex = byteArray.shift();
2527
+ const accountKeyIndexesLength = decodeLength(byteArray);
2528
+ const accountKeyIndexes = byteArray.splice(0, accountKeyIndexesLength);
2529
+ const dataLength = decodeLength(byteArray);
2530
+ const data = new Uint8Array(byteArray.splice(0, dataLength));
2531
+ compiledInstructions.push({
2532
+ programIdIndex,
2533
+ accountKeyIndexes,
2534
+ data
2535
+ });
2536
+ }
2537
+
2538
+ const addressTableLookupsCount = decodeLength(byteArray);
2539
+ const addressTableLookups = [];
2540
+
2541
+ for (let i = 0; i < addressTableLookupsCount; i++) {
2542
+ const accountKey = new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH));
2543
+ const writableIndexesLength = decodeLength(byteArray);
2544
+ const writableIndexes = byteArray.splice(0, writableIndexesLength);
2545
+ const readonlyIndexesLength = decodeLength(byteArray);
2546
+ const readonlyIndexes = byteArray.splice(0, readonlyIndexesLength);
2547
+ addressTableLookups.push({
2548
+ accountKey,
2549
+ writableIndexes,
2550
+ readonlyIndexes
2551
+ });
2552
+ }
2553
+
2554
+ return new MessageV0({
2555
+ header,
2556
+ staticAccountKeys,
2557
+ recentBlockhash,
2558
+ compiledInstructions,
2559
+ addressTableLookups
2560
+ });
2561
+ }
2562
+
2563
+ }
2564
+
2565
+ // eslint-disable-next-line no-redeclare
2566
+ const VersionedMessage = {
2567
+ deserialize: serializedMessage => {
2568
+ const prefix = serializedMessage[0];
2569
+ const maskedPrefix = prefix & VERSION_PREFIX_MASK; // if the highest bit of the prefix is not set, the message is not versioned
2570
+
2571
+ if (maskedPrefix === prefix) {
2572
+ return Message.from(serializedMessage);
2573
+ } // the lower 7 bits of the prefix indicate the message version
2574
+
2575
+
2576
+ const version = maskedPrefix;
2577
+
2578
+ if (version === 0) {
2579
+ return MessageV0.deserialize(serializedMessage);
2580
+ } else {
2581
+ throw new Error(`Transaction message version ${version} deserialization is not supported`);
2582
+ }
2583
+ }
2584
+ };
2585
+
2374
2586
  let TransactionStatus;
2375
2587
  /**
2376
2588
  * Default (empty) signature
@@ -3099,6 +3311,70 @@ class Transaction {
3099
3311
 
3100
3312
  }
3101
3313
 
3314
+ /**
3315
+ * Versioned transaction class
3316
+ */
3317
+ class VersionedTransaction {
3318
+ constructor(message, signatures) {
3319
+ this.signatures = void 0;
3320
+ this.message = void 0;
3321
+
3322
+ if (signatures !== undefined) {
3323
+ assert(signatures.length === message.header.numRequiredSignatures, 'Expected signatures length to be equal to the number of required signatures');
3324
+ this.signatures = signatures;
3325
+ } else {
3326
+ const defaultSignatures = [];
3327
+
3328
+ for (let i = 0; i < message.header.numRequiredSignatures; i++) {
3329
+ defaultSignatures.push(new Uint8Array(SIGNATURE_LENGTH_IN_BYTES));
3330
+ }
3331
+
3332
+ this.signatures = defaultSignatures;
3333
+ }
3334
+
3335
+ this.message = message;
3336
+ }
3337
+
3338
+ serialize() {
3339
+ const serializedMessage = this.message.serialize();
3340
+ const encodedSignaturesLength = Array();
3341
+ encodeLength(encodedSignaturesLength, this.signatures.length);
3342
+ const transactionLayout = BufferLayout.struct([BufferLayout.blob(encodedSignaturesLength.length, 'encodedSignaturesLength'), BufferLayout.seq(signature(), this.signatures.length, 'signatures'), BufferLayout.blob(serializedMessage.length, 'serializedMessage')]);
3343
+ const serializedTransaction = new Uint8Array(2048);
3344
+ const serializedTransactionLength = transactionLayout.encode({
3345
+ encodedSignaturesLength: new Uint8Array(encodedSignaturesLength),
3346
+ signatures: this.signatures,
3347
+ serializedMessage
3348
+ }, serializedTransaction);
3349
+ return serializedTransaction.slice(0, serializedTransactionLength);
3350
+ }
3351
+
3352
+ static deserialize(serializedTransaction) {
3353
+ let byteArray = [...serializedTransaction];
3354
+ const signatures = [];
3355
+ const signaturesLength = decodeLength(byteArray);
3356
+
3357
+ for (let i = 0; i < signaturesLength; i++) {
3358
+ signatures.push(new Uint8Array(byteArray.splice(0, SIGNATURE_LENGTH_IN_BYTES)));
3359
+ }
3360
+
3361
+ const message = VersionedMessage.deserialize(new Uint8Array(byteArray));
3362
+ return new VersionedTransaction(message, signatures);
3363
+ }
3364
+
3365
+ sign(signers) {
3366
+ const messageData = this.message.serialize();
3367
+ const signerPubkeys = this.message.staticAccountKeys.slice(0, this.message.header.numRequiredSignatures);
3368
+
3369
+ for (const signer of signers) {
3370
+ const signerIndex = signerPubkeys.findIndex(pubkey => pubkey.equals(signer.publicKey));
3371
+ assert(signerIndex >= 0, `Cannot sign with non signer key ${signer.publicKey.toBase58()}`);
3372
+ this.signatures[signerIndex] = nacl.sign.detached(messageData, signer.secretKey);
3373
+ }
3374
+ }
3375
+
3376
+ }
3377
+
3102
3378
  const SYSVAR_CLOCK_PUBKEY = new PublicKey('SysvarC1ock11111111111111111111111111111111');
3103
3379
  const SYSVAR_EPOCH_SCHEDULE_PUBKEY = new PublicKey('SysvarEpochSchedu1e111111111111111111111111');
3104
3380
  const SYSVAR_INSTRUCTIONS_PUBKEY = new PublicKey('Sysvar1nstructions1111111111111111111111111');
@@ -4492,24 +4768,26 @@ const LookupTableMetaLayout = {
4492
4768
  BufferLayout.seq(publicKey(), BufferLayout.offset(BufferLayout.u8(), -1), 'authority')])
4493
4769
  };
4494
4770
 
4495
- const URL = globalThis.URL;
4496
-
4771
+ const URL_RE = /^[^:]+:\/\/([^:[]+|\[[^\]]+\])(:\d+)?(.*)/i;
4497
4772
  function makeWebsocketUrl(endpoint) {
4498
- let url = new URL(endpoint);
4499
- const useHttps = url.protocol === 'https:';
4500
- url.protocol = useHttps ? 'wss:' : 'ws:';
4501
- url.host = ''; // Only shift the port by +1 as a convention for ws(s) only if given endpoint
4773
+ const matches = endpoint.match(URL_RE);
4774
+
4775
+ if (matches == null) {
4776
+ throw TypeError(`Failed to validate endpoint URL \`${endpoint}\``);
4777
+ }
4778
+
4779
+ const [_, // eslint-disable-line @typescript-eslint/no-unused-vars
4780
+ hostish, portWithColon, rest] = matches;
4781
+ const protocol = endpoint.startsWith('https:') ? 'wss:' : 'ws:';
4782
+ const startPort = portWithColon == null ? null : parseInt(portWithColon.slice(1), 10);
4783
+ const websocketPort = // Only shift the port by +1 as a convention for ws(s) only if given endpoint
4502
4784
  // is explictly specifying the endpoint port (HTTP-based RPC), assuming
4503
4785
  // we're directly trying to connect to solana-validator's ws listening port.
4504
4786
  // When the endpoint omits the port, we're connecting to the protocol
4505
4787
  // default ports: http(80) or https(443) and it's assumed we're behind a reverse
4506
4788
  // proxy which manages WebSocket upgrade and backend port redirection.
4507
-
4508
- if (url.port !== '') {
4509
- url.port = String(Number(url.port) + 1);
4510
- }
4511
-
4512
- return url.toString();
4789
+ startPort == null ? '' : `:${startPort + 1}`;
4790
+ return `${protocol}//${hostish}${websocketPort}${rest}`;
4513
4791
  }
4514
4792
 
4515
4793
  var _process$env$npm_pack;
@@ -4529,7 +4807,17 @@ const BLOCKHASH_CACHE_TIMEOUT_MS = 30 * 1000;
4529
4807
  * https://gist.github.com/steveluscher/c057eca81d479ef705cdb53162f9971d
4530
4808
  */
4531
4809
 
4810
+ /* @internal */
4811
+ function assertEndpointUrl(putativeUrl) {
4812
+ if (/^https?:/.test(putativeUrl) === false) {
4813
+ throw new TypeError('Endpoint URL must start with `http:` or `https:`.');
4814
+ }
4815
+
4816
+ return putativeUrl;
4817
+ }
4532
4818
  /** @internal */
4819
+
4820
+
4533
4821
  function extractCommitmentFromConfig(commitmentOrConfig) {
4534
4822
  let commitment;
4535
4823
  let config;
@@ -4724,7 +5012,7 @@ const BlockProductionResponseStruct = jsonRpcResultAndContext(type({
4724
5012
  * A performance sample
4725
5013
  */
4726
5014
 
4727
- function createRpcClient(url, useHttps, httpHeaders, customFetch, fetchMiddleware, disableRetryOnRateLimit) {
5015
+ function createRpcClient(url, httpHeaders, customFetch, fetchMiddleware, disableRetryOnRateLimit) {
4728
5016
  const fetch = customFetch ? customFetch : fetchImpl;
4729
5017
 
4730
5018
  let fetchWithMiddleware;
@@ -5530,8 +5818,6 @@ class Connection {
5530
5818
  this._subscriptionCallbacksByServerSubscriptionId = {};
5531
5819
  this._subscriptionsByHash = {};
5532
5820
  this._subscriptionsAutoDisposedByRpc = new Set();
5533
- let url = new URL(endpoint);
5534
- const useHttps = url.protocol === 'https:';
5535
5821
  let wsEndpoint;
5536
5822
  let httpHeaders;
5537
5823
  let fetch;
@@ -5550,9 +5836,9 @@ class Connection {
5550
5836
  disableRetryOnRateLimit = commitmentOrConfig.disableRetryOnRateLimit;
5551
5837
  }
5552
5838
 
5553
- this._rpcEndpoint = endpoint;
5839
+ this._rpcEndpoint = assertEndpointUrl(endpoint);
5554
5840
  this._rpcWsEndpoint = wsEndpoint || makeWebsocketUrl(endpoint);
5555
- this._rpcClient = createRpcClient(url.toString(), useHttps, httpHeaders, fetch, fetchMiddleware, disableRetryOnRateLimit);
5841
+ this._rpcClient = createRpcClient(endpoint, httpHeaders, fetch, fetchMiddleware, disableRetryOnRateLimit);
5556
5842
  this._rpcRequest = createRpcRequest(this._rpcClient);
5557
5843
  this._rpcBatchRequest = createRpcBatchRequest(this._rpcClient);
5558
5844
  this._rpcWebSocket = new Client(this._rpcWsEndpoint, {
@@ -10093,6 +10379,23 @@ class VoteProgram {
10093
10379
  data
10094
10380
  });
10095
10381
  }
10382
+ /**
10383
+ * Generate a transaction to withdraw safely from a Vote account.
10384
+ *
10385
+ * This function was created as a safeguard for vote accounts running validators, `safeWithdraw`
10386
+ * checks that the withdraw amount will not exceed the specified balance while leaving enough left
10387
+ * to cover rent. If you wish to close the vote account by withdrawing the full amount, call the
10388
+ * `withdraw` method directly.
10389
+ */
10390
+
10391
+
10392
+ static safeWithdraw(params, currentVoteAccountBalance, rentExemptMinimum) {
10393
+ if (params.lamports > currentVoteAccountBalance - rentExemptMinimum) {
10394
+ throw new Error('Withdraw will leave vote account with insuffcient funds.');
10395
+ }
10396
+
10397
+ return VoteProgram.withdraw(params);
10398
+ }
10096
10399
 
10097
10400
  }
10098
10401
  VoteProgram.programId = new PublicKey('Vote111111111111111111111111111111111111111');
@@ -10144,15 +10447,14 @@ class ValidatorInfo {
10144
10447
 
10145
10448
 
10146
10449
  static fromConfigData(buffer) {
10147
- const PUBKEY_LENGTH = 32;
10148
10450
  let byteArray = [...buffer];
10149
10451
  const configKeyCount = decodeLength(byteArray);
10150
10452
  if (configKeyCount !== 2) return null;
10151
10453
  const configKeys = [];
10152
10454
 
10153
10455
  for (let i = 0; i < 2; i++) {
10154
- const publicKey = new PublicKey(byteArray.slice(0, PUBKEY_LENGTH));
10155
- byteArray = byteArray.slice(PUBKEY_LENGTH);
10456
+ const publicKey = new PublicKey(byteArray.slice(0, PUBLIC_KEY_LENGTH));
10457
+ byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
10156
10458
  const isSigner = byteArray.slice(0, 1)[0] === 1;
10157
10459
  byteArray = byteArray.slice(1);
10158
10460
  configKeys.push({
@@ -10364,5 +10666,5 @@ async function sendAndConfirmRawTransaction(connection, rawTransaction, confirma
10364
10666
 
10365
10667
  const LAMPORTS_PER_SOL = 1000000000;
10366
10668
 
10367
- export { Account, AddressLookupTableAccount, AddressLookupTableInstruction, AddressLookupTableProgram, 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, LOOKUP_TABLE_INSTRUCTION_LAYOUTS, 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, SolanaJSONRPCError, SolanaJSONRPCErrorCode, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionExpiredBlockheightExceededError, TransactionExpiredTimeoutError, TransactionInstruction, TransactionStatus, VALIDATOR_INFO_KEY, VOTE_PROGRAM_ID, ValidatorInfo, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
10669
+ export { Account, AddressLookupTableAccount, AddressLookupTableInstruction, AddressLookupTableProgram, 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, LOOKUP_TABLE_INSTRUCTION_LAYOUTS, Loader, Lockup, MAX_SEED_LENGTH, Message, MessageV0, NONCE_ACCOUNT_LENGTH, NonceAccount, PACKET_DATA_SIZE, PUBLIC_KEY_LENGTH, 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, SolanaJSONRPCError, SolanaJSONRPCErrorCode, StakeAuthorizationLayout, StakeInstruction, StakeProgram, Struct, SystemInstruction, SystemProgram, Transaction, TransactionExpiredBlockheightExceededError, TransactionExpiredTimeoutError, TransactionInstruction, TransactionStatus, VALIDATOR_INFO_KEY, VERSION_PREFIX_MASK, VOTE_PROGRAM_ID, ValidatorInfo, VersionedMessage, VersionedTransaction, VoteAccount, VoteAuthorizationLayout, VoteInit, VoteInstruction, VoteProgram, clusterApiUrl, sendAndConfirmRawTransaction, sendAndConfirmTransaction };
10368
10670
  //# sourceMappingURL=index.browser.esm.js.map