@solana/web3.js 1.91.1 → 1.91.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/web3.js",
3
- "version": "1.91.1",
3
+ "version": "1.91.3",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
@@ -50,7 +50,7 @@
50
50
  "test:live": "TEST_LIVE=1 pnpm run test:unit:node",
51
51
  "test:live-with-test-validator": "start-server-and-test '../../scripts/start-shared-test-validator.sh' http://127.0.0.1:8899/health test:live",
52
52
  "test:prettier": "prettier --check '{,{src,test}/**/}*.{j,t}s'",
53
- "test:prettier:fix": "prettier --write '{,{src,test}/**/}*.{j,t}s'",
53
+ "test:prettier:fix": "pnpm prettier --write '{,{src,test}/**/}*.{j,t}s'",
54
54
  "test:typecheck": "tsc --noEmit",
55
55
  "test:unit:node": "cross-env NODE_ENV=test TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha --require esm './test/**/*.test.ts'"
56
56
  },
@@ -16,6 +16,7 @@ import {
16
16
  import {TransactionInstruction} from '../transaction';
17
17
  import {CompiledKeys} from './compiled-keys';
18
18
  import {MessageAccountKeys} from './account-keys';
19
+ import {guardedShift, guardedSplice} from '../utils/guarded-array-utils';
19
20
 
20
21
  /**
21
22
  * An instruction to execute by a program
@@ -268,7 +269,7 @@ export class Message {
268
269
  // Slice up wire data
269
270
  let byteArray = [...buffer];
270
271
 
271
- const numRequiredSignatures = byteArray.shift()!;
272
+ const numRequiredSignatures = guardedShift(byteArray);
272
273
  if (
273
274
  numRequiredSignatures !==
274
275
  (numRequiredSignatures & VERSION_PREFIX_MASK)
@@ -278,26 +279,26 @@ export class Message {
278
279
  );
279
280
  }
280
281
 
281
- const numReadonlySignedAccounts = byteArray.shift()!;
282
- const numReadonlyUnsignedAccounts = byteArray.shift()!;
282
+ const numReadonlySignedAccounts = guardedShift(byteArray);
283
+ const numReadonlyUnsignedAccounts = guardedShift(byteArray);
283
284
 
284
285
  const accountCount = shortvec.decodeLength(byteArray);
285
286
  let accountKeys = [];
286
287
  for (let i = 0; i < accountCount; i++) {
287
- const account = byteArray.splice(0, PUBLIC_KEY_LENGTH);
288
+ const account = guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH);
288
289
  accountKeys.push(new PublicKey(Buffer.from(account)));
289
290
  }
290
291
 
291
- const recentBlockhash = byteArray.splice(0, PUBLIC_KEY_LENGTH);
292
+ const recentBlockhash = guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH);
292
293
 
293
294
  const instructionCount = shortvec.decodeLength(byteArray);
294
295
  let instructions: CompiledInstruction[] = [];
295
296
  for (let i = 0; i < instructionCount; i++) {
296
- const programIdIndex = byteArray.shift()!;
297
+ const programIdIndex = guardedShift(byteArray);
297
298
  const accountCount = shortvec.decodeLength(byteArray);
298
- const accounts = byteArray.splice(0, accountCount);
299
+ const accounts = guardedSplice(byteArray, 0, accountCount);
299
300
  const dataLength = shortvec.decodeLength(byteArray);
300
- const dataSlice = byteArray.splice(0, dataLength);
301
+ const dataSlice = guardedSplice(byteArray, 0, dataLength);
301
302
  const data = bs58.encode(Buffer.from(dataSlice));
302
303
  instructions.push({
303
304
  programIdIndex,
package/src/message/v0.ts CHANGED
@@ -16,6 +16,7 @@ import {TransactionInstruction} from '../transaction';
16
16
  import {AddressLookupTableAccount} from '../programs';
17
17
  import {CompiledKeys} from './compiled-keys';
18
18
  import {AccountKeysFromLookups, MessageAccountKeys} from './account-keys';
19
+ import {guardedShift, guardedSplice} from '../utils/guarded-array-utils';
19
20
 
20
21
  /**
21
22
  * Message constructor arguments
@@ -426,7 +427,7 @@ export class MessageV0 {
426
427
  static deserialize(serializedMessage: Uint8Array): MessageV0 {
427
428
  let byteArray = [...serializedMessage];
428
429
 
429
- const prefix = byteArray.shift() as number;
430
+ const prefix = guardedShift(byteArray);
430
431
  const maskedPrefix = prefix & VERSION_PREFIX_MASK;
431
432
  assert(
432
433
  prefix !== maskedPrefix,
@@ -440,29 +441,35 @@ export class MessageV0 {
440
441
  );
441
442
 
442
443
  const header: MessageHeader = {
443
- numRequiredSignatures: byteArray.shift() as number,
444
- numReadonlySignedAccounts: byteArray.shift() as number,
445
- numReadonlyUnsignedAccounts: byteArray.shift() as number,
444
+ numRequiredSignatures: guardedShift(byteArray),
445
+ numReadonlySignedAccounts: guardedShift(byteArray),
446
+ numReadonlyUnsignedAccounts: guardedShift(byteArray),
446
447
  };
447
448
 
448
449
  const staticAccountKeys = [];
449
450
  const staticAccountKeysLength = shortvec.decodeLength(byteArray);
450
451
  for (let i = 0; i < staticAccountKeysLength; i++) {
451
452
  staticAccountKeys.push(
452
- new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH)),
453
+ new PublicKey(guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH)),
453
454
  );
454
455
  }
455
456
 
456
- const recentBlockhash = bs58.encode(byteArray.splice(0, PUBLIC_KEY_LENGTH));
457
+ const recentBlockhash = bs58.encode(
458
+ guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH),
459
+ );
457
460
 
458
461
  const instructionCount = shortvec.decodeLength(byteArray);
459
462
  const compiledInstructions: MessageCompiledInstruction[] = [];
460
463
  for (let i = 0; i < instructionCount; i++) {
461
- const programIdIndex = byteArray.shift() as number;
464
+ const programIdIndex = guardedShift(byteArray);
462
465
  const accountKeyIndexesLength = shortvec.decodeLength(byteArray);
463
- const accountKeyIndexes = byteArray.splice(0, accountKeyIndexesLength);
466
+ const accountKeyIndexes = guardedSplice(
467
+ byteArray,
468
+ 0,
469
+ accountKeyIndexesLength,
470
+ );
464
471
  const dataLength = shortvec.decodeLength(byteArray);
465
- const data = new Uint8Array(byteArray.splice(0, dataLength));
472
+ const data = new Uint8Array(guardedSplice(byteArray, 0, dataLength));
466
473
  compiledInstructions.push({
467
474
  programIdIndex,
468
475
  accountKeyIndexes,
@@ -473,11 +480,21 @@ export class MessageV0 {
473
480
  const addressTableLookupsCount = shortvec.decodeLength(byteArray);
474
481
  const addressTableLookups: MessageAddressTableLookup[] = [];
475
482
  for (let i = 0; i < addressTableLookupsCount; i++) {
476
- const accountKey = new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH));
483
+ const accountKey = new PublicKey(
484
+ guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH),
485
+ );
477
486
  const writableIndexesLength = shortvec.decodeLength(byteArray);
478
- const writableIndexes = byteArray.splice(0, writableIndexesLength);
487
+ const writableIndexes = guardedSplice(
488
+ byteArray,
489
+ 0,
490
+ writableIndexesLength,
491
+ );
479
492
  const readonlyIndexesLength = shortvec.decodeLength(byteArray);
480
- const readonlyIndexes = byteArray.splice(0, readonlyIndexesLength);
493
+ const readonlyIndexes = guardedSplice(
494
+ byteArray,
495
+ 0,
496
+ readonlyIndexesLength,
497
+ );
481
498
  addressTableLookups.push({
482
499
  accountKey,
483
500
  writableIndexes,
@@ -12,6 +12,7 @@ import type {Signer} from '../keypair';
12
12
  import type {Blockhash} from '../blockhash';
13
13
  import type {CompiledInstruction} from '../message';
14
14
  import {sign, verify} from '../utils/ed25519';
15
+ import {guardedSplice} from '../utils/guarded-array-utils';
15
16
 
16
17
  /** @internal */
17
18
  type MessageSignednessErrors = {
@@ -904,7 +905,7 @@ export class Transaction {
904
905
  const signatureCount = shortvec.decodeLength(byteArray);
905
906
  let signatures = [];
906
907
  for (let i = 0; i < signatureCount; i++) {
907
- const signature = byteArray.splice(0, SIGNATURE_LENGTH_IN_BYTES);
908
+ const signature = guardedSplice(byteArray, 0, SIGNATURE_LENGTH_IN_BYTES);
908
909
  signatures.push(bs58.encode(Buffer.from(signature)));
909
910
  }
910
911
 
@@ -8,6 +8,7 @@ import * as shortvec from '../utils/shortvec-encoding';
8
8
  import * as Layout from '../layout';
9
9
  import {sign} from '../utils/ed25519';
10
10
  import {PublicKey} from '../publickey';
11
+ import {guardedSplice} from '../utils/guarded-array-utils';
11
12
 
12
13
  export type TransactionVersion = 'legacy' | 0;
13
14
 
@@ -82,7 +83,7 @@ export class VersionedTransaction {
82
83
  const signaturesLength = shortvec.decodeLength(byteArray);
83
84
  for (let i = 0; i < signaturesLength; i++) {
84
85
  signatures.push(
85
- new Uint8Array(byteArray.splice(0, SIGNATURE_LENGTH_IN_BYTES)),
86
+ new Uint8Array(guardedSplice(byteArray, 0, SIGNATURE_LENGTH_IN_BYTES)),
86
87
  );
87
88
  }
88
89
 
@@ -0,0 +1,34 @@
1
+ const END_OF_BUFFER_ERROR_MESSAGE = 'Reached end of buffer unexpectedly';
2
+
3
+ /**
4
+ * Delegates to `Array#shift`, but throws if the array is zero-length.
5
+ */
6
+ export function guardedShift<T>(byteArray: T[]): T {
7
+ if (byteArray.length === 0) {
8
+ throw new Error(END_OF_BUFFER_ERROR_MESSAGE);
9
+ }
10
+ return byteArray.shift() as T;
11
+ }
12
+
13
+ /**
14
+ * Delegates to `Array#splice`, but throws if the section being spliced out extends past the end of
15
+ * the array.
16
+ */
17
+ export function guardedSplice<T>(
18
+ byteArray: T[],
19
+ ...args:
20
+ | [start: number, deleteCount?: number]
21
+ | [start: number, deleteCount: number, ...items: T[]]
22
+ ): T[] {
23
+ const [start] = args;
24
+ if (
25
+ args.length === 2 // Implies that `deleteCount` was supplied
26
+ ? start + (args[1] ?? 0) > byteArray.length
27
+ : start >= byteArray.length
28
+ ) {
29
+ throw new Error(END_OF_BUFFER_ERROR_MESSAGE);
30
+ }
31
+ return byteArray.splice(
32
+ ...(args as Parameters<typeof Array.prototype.splice>),
33
+ );
34
+ }
@@ -9,6 +9,7 @@ import {
9
9
  import * as Layout from './layout';
10
10
  import * as shortvec from './utils/shortvec-encoding';
11
11
  import {PublicKey, PUBLIC_KEY_LENGTH} from './publickey';
12
+ import {guardedShift, guardedSplice} from './utils/guarded-array-utils';
12
13
 
13
14
  export const VALIDATOR_INFO_KEY = new PublicKey(
14
15
  'Va1idator1nfo111111111111111111111111111111',
@@ -83,8 +84,10 @@ export class ValidatorInfo {
83
84
 
84
85
  const configKeys: Array<ConfigKey> = [];
85
86
  for (let i = 0; i < 2; i++) {
86
- const publicKey = new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH));
87
- const isSigner = byteArray.splice(0, 1)[0] === 1;
87
+ const publicKey = new PublicKey(
88
+ guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH),
89
+ );
90
+ const isSigner = guardedShift(byteArray) === 1;
88
91
  configKeys.push({publicKey, isSigner});
89
92
  }
90
93