@solana/web3.js 1.63.0 → 1.63.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solana/web3.js",
3
- "version": "1.63.0",
3
+ "version": "1.63.2",
4
4
  "description": "Solana Javascript API",
5
5
  "keywords": [
6
6
  "api",
@@ -36,26 +36,6 @@
36
36
  "/lib",
37
37
  "/src"
38
38
  ],
39
- "scripts": {
40
- "build": "npm run clean; cross-env NODE_ENV=production rollup -c; npm run type:gen",
41
- "build:fixtures": "set -ex; ./test/fixtures/noop-program/build.sh",
42
- "clean": "rimraf ./coverage ./lib",
43
- "codecov": "set -ex; npm run test:cover; cat ./coverage/lcov.info | codecov",
44
- "dev": "cross-env NODE_ENV=development rollup -c",
45
- "doc": "set -ex; typedoc --treatWarningsAsErrors",
46
- "type:gen": "./scripts/typegen.sh",
47
- "lint": "set -ex; npm run pretty; eslint . --ext .js,.ts",
48
- "lint:fix": "npm run pretty:fix && eslint . --fix --ext .js,.ts",
49
- "type:check": "tsc -p tsconfig.json --noEmit",
50
- "ok": "run-s lint test doc type:check",
51
- "pretty": "prettier --check '{,{src,test}/**/}*.{j,t}s'",
52
- "pretty:fix": "prettier --write '{,{src,test}/**/}*.{j,t}s'",
53
- "re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",
54
- "test": "cross-env TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha --require esm './test/**/*.test.ts'",
55
- "test:cover": "nyc --reporter=lcov npm run test",
56
- "test:live": "TEST_LIVE=1 npm run test",
57
- "test:live-with-test-validator": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health test:live"
58
- },
59
39
  "dependencies": {
60
40
  "@babel/runtime": "^7.12.5",
61
41
  "@noble/ed25519": "^1.7.0",
@@ -137,5 +117,25 @@
137
117
  },
138
118
  "engines": {
139
119
  "node": ">=12.20.0"
120
+ },
121
+ "scripts": {
122
+ "build": "npm run clean; cross-env NODE_ENV=production rollup -c; npm run type:gen",
123
+ "build:fixtures": "set -ex; ./test/fixtures/noop-program/build.sh",
124
+ "clean": "rimraf ./coverage ./lib",
125
+ "codecov": "set -ex; npm run test:cover; cat ./coverage/lcov.info | codecov",
126
+ "dev": "cross-env NODE_ENV=development rollup -c",
127
+ "doc": "set -ex; typedoc --treatWarningsAsErrors",
128
+ "type:gen": "./scripts/typegen.sh",
129
+ "lint": "set -ex; npm run pretty; eslint . --ext .js,.ts",
130
+ "lint:fix": "npm run pretty:fix && eslint . --fix --ext .js,.ts",
131
+ "type:check": "tsc -p tsconfig.json --noEmit",
132
+ "ok": "run-s lint test doc type:check",
133
+ "pretty": "prettier --check '{,{src,test}/**/}*.{j,t}s'",
134
+ "pretty:fix": "prettier --write '{,{src,test}/**/}*.{j,t}s'",
135
+ "re": "semantic-release --repository-url git@github.com:solana-labs/solana-web3.js.git",
136
+ "test": "cross-env TS_NODE_COMPILER_OPTIONS='{ \"module\": \"commonjs\", \"target\": \"es2019\" }' ts-mocha --require esm './test/**/*.test.ts'",
137
+ "test:cover": "nyc --reporter=lcov npm run test",
138
+ "test:live": "TEST_LIVE=1 npm run test",
139
+ "test:live-with-test-validator": "start-server-and-test 'solana-test-validator --reset --quiet' http://localhost:8899/health test:live"
140
140
  }
141
- }
141
+ }
@@ -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() as number;
272
+ const numRequiredSignatures = guardedShift(byteArray);
272
273
  if (
273
274
  numRequiredSignatures !==
274
275
  (numRequiredSignatures & VERSION_PREFIX_MASK)
@@ -278,31 +279,27 @@ export class Message {
278
279
  );
279
280
  }
280
281
 
281
- const numReadonlySignedAccounts = byteArray.shift() as number;
282
- const numReadonlyUnsignedAccounts = byteArray.shift() as number;
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.slice(0, PUBLIC_KEY_LENGTH);
288
- byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
288
+ const account = guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH);
289
289
  accountKeys.push(new PublicKey(Buffer.from(account)));
290
290
  }
291
291
 
292
- const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
293
- byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
292
+ const recentBlockhash = guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH);
294
293
 
295
294
  const instructionCount = shortvec.decodeLength(byteArray);
296
295
  let instructions: CompiledInstruction[] = [];
297
296
  for (let i = 0; i < instructionCount; i++) {
298
- const programIdIndex = byteArray.shift() as number;
297
+ const programIdIndex = guardedShift(byteArray);
299
298
  const accountCount = shortvec.decodeLength(byteArray);
300
- const accounts = byteArray.slice(0, accountCount);
301
- byteArray = byteArray.slice(accountCount);
299
+ const accounts = guardedSplice(byteArray, 0, accountCount);
302
300
  const dataLength = shortvec.decodeLength(byteArray);
303
- const dataSlice = byteArray.slice(0, dataLength);
301
+ const dataSlice = guardedSplice(byteArray, 0, dataLength);
304
302
  const data = bs58.encode(Buffer.from(dataSlice));
305
- byteArray = byteArray.slice(dataLength);
306
303
  instructions.push({
307
304
  programIdIndex,
308
305
  accounts,
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
@@ -42,10 +43,10 @@ export type CompileV0Args = {
42
43
 
43
44
  export type GetAccountKeysArgs =
44
45
  | {
45
- accountKeysFromLookups: AccountKeysFromLookups;
46
+ accountKeysFromLookups?: AccountKeysFromLookups | null;
46
47
  }
47
48
  | {
48
- addressLookupTableAccounts: AddressLookupTableAccount[];
49
+ addressLookupTableAccounts?: AddressLookupTableAccount[] | null;
49
50
  };
50
51
 
51
52
  export class MessageV0 {
@@ -77,7 +78,11 @@ export class MessageV0 {
77
78
 
78
79
  getAccountKeys(args?: GetAccountKeysArgs): MessageAccountKeys {
79
80
  let accountKeysFromLookups: AccountKeysFromLookups | undefined;
80
- if (args && 'accountKeysFromLookups' in args) {
81
+ if (
82
+ args &&
83
+ 'accountKeysFromLookups' in args &&
84
+ args.accountKeysFromLookups
85
+ ) {
81
86
  if (
82
87
  this.numAccountKeysFromLookups !=
83
88
  args.accountKeysFromLookups.writable.length +
@@ -88,7 +93,11 @@ export class MessageV0 {
88
93
  );
89
94
  }
90
95
  accountKeysFromLookups = args.accountKeysFromLookups;
91
- } else if (args && 'addressLookupTableAccounts' in args) {
96
+ } else if (
97
+ args &&
98
+ 'addressLookupTableAccounts' in args &&
99
+ args.addressLookupTableAccounts
100
+ ) {
92
101
  accountKeysFromLookups = this.resolveAddressTableLookups(
93
102
  args.addressLookupTableAccounts,
94
103
  );
@@ -418,7 +427,7 @@ export class MessageV0 {
418
427
  static deserialize(serializedMessage: Uint8Array): MessageV0 {
419
428
  let byteArray = [...serializedMessage];
420
429
 
421
- const prefix = byteArray.shift() as number;
430
+ const prefix = guardedShift(byteArray);
422
431
  const maskedPrefix = prefix & VERSION_PREFIX_MASK;
423
432
  assert(
424
433
  prefix !== maskedPrefix,
@@ -432,29 +441,35 @@ export class MessageV0 {
432
441
  );
433
442
 
434
443
  const header: MessageHeader = {
435
- numRequiredSignatures: byteArray.shift() as number,
436
- numReadonlySignedAccounts: byteArray.shift() as number,
437
- numReadonlyUnsignedAccounts: byteArray.shift() as number,
444
+ numRequiredSignatures: guardedShift(byteArray),
445
+ numReadonlySignedAccounts: guardedShift(byteArray),
446
+ numReadonlyUnsignedAccounts: guardedShift(byteArray),
438
447
  };
439
448
 
440
449
  const staticAccountKeys = [];
441
450
  const staticAccountKeysLength = shortvec.decodeLength(byteArray);
442
451
  for (let i = 0; i < staticAccountKeysLength; i++) {
443
452
  staticAccountKeys.push(
444
- new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH)),
453
+ new PublicKey(guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH)),
445
454
  );
446
455
  }
447
456
 
448
- const recentBlockhash = bs58.encode(byteArray.splice(0, PUBLIC_KEY_LENGTH));
457
+ const recentBlockhash = bs58.encode(
458
+ guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH),
459
+ );
449
460
 
450
461
  const instructionCount = shortvec.decodeLength(byteArray);
451
462
  const compiledInstructions: MessageCompiledInstruction[] = [];
452
463
  for (let i = 0; i < instructionCount; i++) {
453
- const programIdIndex = byteArray.shift() as number;
464
+ const programIdIndex = guardedShift(byteArray);
454
465
  const accountKeyIndexesLength = shortvec.decodeLength(byteArray);
455
- const accountKeyIndexes = byteArray.splice(0, accountKeyIndexesLength);
466
+ const accountKeyIndexes = guardedSplice(
467
+ byteArray,
468
+ 0,
469
+ accountKeyIndexesLength,
470
+ );
456
471
  const dataLength = shortvec.decodeLength(byteArray);
457
- const data = new Uint8Array(byteArray.splice(0, dataLength));
472
+ const data = new Uint8Array(guardedSplice(byteArray, 0, dataLength));
458
473
  compiledInstructions.push({
459
474
  programIdIndex,
460
475
  accountKeyIndexes,
@@ -465,11 +480,21 @@ export class MessageV0 {
465
480
  const addressTableLookupsCount = shortvec.decodeLength(byteArray);
466
481
  const addressTableLookups: MessageAddressTableLookup[] = [];
467
482
  for (let i = 0; i < addressTableLookupsCount; i++) {
468
- const accountKey = new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH));
483
+ const accountKey = new PublicKey(
484
+ guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH),
485
+ );
469
486
  const writableIndexesLength = shortvec.decodeLength(byteArray);
470
- const writableIndexes = byteArray.splice(0, writableIndexesLength);
487
+ const writableIndexes = guardedSplice(
488
+ byteArray,
489
+ 0,
490
+ writableIndexesLength,
491
+ );
471
492
  const readonlyIndexesLength = shortvec.decodeLength(byteArray);
472
- const readonlyIndexes = byteArray.splice(0, readonlyIndexesLength);
493
+ const readonlyIndexes = guardedSplice(
494
+ byteArray,
495
+ 0,
496
+ readonlyIndexesLength,
497
+ );
473
498
  addressTableLookups.push({
474
499
  accountKey,
475
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
  /**
17
18
  * Transaction signature as base-58 encoded string
@@ -803,8 +804,7 @@ export class Transaction {
803
804
  const signatureCount = shortvec.decodeLength(byteArray);
804
805
  let signatures = [];
805
806
  for (let i = 0; i < signatureCount; i++) {
806
- const signature = byteArray.slice(0, SIGNATURE_LENGTH_IN_BYTES);
807
- byteArray = byteArray.slice(SIGNATURE_LENGTH_IN_BYTES);
807
+ const signature = guardedSplice(byteArray, 0, SIGNATURE_LENGTH_IN_BYTES);
808
808
  signatures.push(bs58.encode(Buffer.from(signature)));
809
809
  }
810
810
 
@@ -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,10 +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.slice(0, PUBLIC_KEY_LENGTH));
87
- byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
88
- const isSigner = byteArray.slice(0, 1)[0] === 1;
89
- byteArray = byteArray.slice(1);
87
+ const publicKey = new PublicKey(
88
+ guardedSplice(byteArray, 0, PUBLIC_KEY_LENGTH),
89
+ );
90
+ const isSigner = guardedShift(byteArray) === 1;
90
91
  configKeys.push({publicKey, isSigner});
91
92
  }
92
93